developers
Threads by month
- ----- 2025 -----
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 8 participants
- 6853 discussions

Re: [Maria-developers] a bug that affects group commit implementations
by Kristian Nielsen 08 Dec '10
by Kristian Nielsen 08 Dec '10
08 Dec '10
[Cc:ing maria-developers@ as I want us to get into the habbit of discussing
more openly, hope that is ok]
MARK CALLAGHAN <mdcallag(a)gmail.com> writes:
> I think that Mats identified the problem and then Vamsi did a
> reproduction of it.
> http://bugs.mysql.com/58787
Thanks for pointing me to this issue Mark!
I'm wondering what the real bug is here? Can one of you explain?
I suppose it is that we can get in binary log eg. INSERT, ALTER; while in
InnoDB transaction log we get ALTER, INSERT ?
I believe the reason to avoid such inconsistency normally is to allow
something like XtraBackup to get a consistent binlog position that can be used
to provision a slave. However, for DDL this is not enough, as .frm files are
not handled. So ensuring consistent order for DDL between binlog and innodb
transaction log does not really solve the problem.
The bug also suggests that DDL should use 2-phase commit. But 2-phase commit
implies the ability to rollback. I do not know if InnoDB is able to roll back
DDL, but MySQL .frm handling certainly is not. So great care would be needed
to not just introduce different bugs, if this approach was taken. It is also a
non-trivial change of the storage engine API.
There has been talk of making DLL in MySQL (/MariaDB) transactional, or at
least crash-safe. This is something that I would really like to see. I was
told that partitioning already has code for this, by logging .frm changes and
recovering / rolling back after crash. Something similar could work for
general DDL. This would allow a proper solution to the binlog order problem
for DDL.
It does not mean that a partial solution now cannot be an improvement, however
I do not understand from the bug discussion what such improvement would
be. Can you elaborate?
BTW, the purpose of 2-phase commit is to ensure consistency between different
engines/binlog in case of crash, not to ensure consistent ordering of
commits. The fact that it currently _does_ ensure ordering for InnoDB is just
a gross hack with the prepare_commit_mutex. This is so expensive (3 x fsync()
per commit) that I believe most users don't use it anyway (eg. setting
sync_binlog != 1, which defeats the whole purpose of prepare_commit_mutex). I
would really recommend looking at MWL#116
(http://askmonty.org/worklog/Server-Sprint/?tid=116) which solves the
ordering issue in a proper way.
- Kristian.
1
0
"Vladimir Kolesnikov" <vladimir(a)primebase.org> writes:
> I'm trying to reproduce this bug in PBXT:
>
> https://bugs.launchpad.net/pbxt/+bug/668491
Great!
> I use sources from mariadb-5.1.42.tar.gz
That's quite an old version, you should use the latest.
> I got some problems trying to run maria's test suite. What I want is to run
> the pbxt.preload test. I can confirm that PBXT engine is compiled-in. I
> tried several ways like
>
> ./mysql-test-run pbxt.preload
> ./mysql-test-run --do-test=pbxt.preload
> ./mysql-test-run --start-from=pbxt.preload
>
> but every of them failed with some kind of init error... Any ideas of a
> quick-fix?
Using source tarball should work, but I would recommend using the bzr
tree. Here is a step-by-step instruction that works for me:
bzr branch -rtag:mariadb-5.1.53 lp:maria/5.1 work-5.1-bug66849
cd work-5.1-bug668491/
BUILD/compile-pentium64-valgrind-max
(cd mysql-test && ./mtr pbxt.preload)
Note, however, that this failure is hard to re-produce. Usually when the test
is run, it succeeds. Only occasionally on the heavily loaded buildbot machines
does it fail. Here is a search against the database of past failures for this
test:
http://buildbot.askmonty.org/buildbot/reports/cross_reference#branch=5.1&re…
As you can see, the failure is quite rare, only a few failures out of the
hundreds of test runs our Buildbot does each day. But according to the bug
report, I was able to repeat as follows:
(cd mysql-test && for i in `seq 1 1000` ; do ./mtr --parallel=3 pbxt.preload pbxt.preload pbxt.preload || exit 1 ; done)
I just tried it, and I was able to reproduce with above loop, however it takes
several minutes to see the failure.
(I'm using 64-bit Ubuntu 8.04 on a 2.4 GHz Core 2 Duo laptop).
Good luck, and let me know if you need more help.
- Kristian.
1
0

Re: [Maria-developers] [Branch ~maria-captains/maria/5.1] Rev 2988: Fix LP Bug#686184 - merge_debug test fails.
by Oleksandr Byelkin 07 Dec '10
by Oleksandr Byelkin 07 Dec '10
07 Dec '10
Hi!
On 07.12.2010 01:15, noreply(a)launchpad.net wrote:
> ------------------------------------------------------------
> revno: 2988
> fixes bug(s): https://launchpad.net/bugs/686184
> committer: Vladislav Vaintroub<wlad(a)montyprogram.com>
> branch nick: 5.1
> timestamp: Mon 2010-12-06 22:34:50 +0100
> message:
> Fix LP Bug#686184 - merge_debug test fails.
> The reason for failure is that DBUG_EXECUTE_IF in mi_open()
> only worked for Unix-formatted file names, due to strstr(name, "/crashed")
>
> The fix change strstr() above to strstr(name, "crashed"), to it can work with
> Windows file names as well.
> modified:
> storage/myisam/mi_open.c
(M)Aria engine also has code like you fixed above in ma_open.c:
DBUG_EXECUTE_IF("maria_pretend_crashed_table_on_open",
if (strstr(name, "/t1"))
{
my_errno= HA_ERR_CRASHED;
goto err;
});
Should it be also fixed?
1
0
Daniel,
We are now ready to release MariaDB 5.1.53 and MariaDB 5.2.4.
For 5.1.53, the tag is "mariadb-5.1.53" and the tree is:
lp:~maria-captains/maria/5.1-release
Packages should be downloaded from here:
http://knielsen-hq.org/archive/pack/5.1-release/build-660/
For 5.2.4, the tag is "mariadb-5.2.4" and the tree is:
lp:maria/5.2
Packages from here:
http://knielsen-hq.org/archive/pack/5.2/build-661/
Let me know if you need anything else for the release.
- Kristian.
2
2

[Maria-developers] WL#168 New (by Timour): Remove lazy subquery optimization
by worklog-noreply@askmonty.org 06 Dec '10
by worklog-noreply@askmonty.org 06 Dec '10
06 Dec '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Remove lazy subquery optimization
CREATION DATE..: Mon, 06 Dec 2010, 12:55
SUPERVISOR.....: Igor
IMPLEMENTOR....: Timour
COPIES TO......:
CATEGORY.......: Maria-BackLog
TASK ID........: 168 (http://askmonty.org/worklog/?tid=168)
VERSION........: Server-5.3
STATUS.........: Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 16 (hours remain)
ORIG. ESTIMATE.: 16
PROGRESS NOTES:
DESCRIPTION:
Remove all instances of lazy subquery optimization after MWL#89 is complete.
Even after MWL#89, there are certain cases when subquery predicates are
executed without prior optimization. This may result in bugs as well as
high optimization/explain cost. In addition having a mixed subquery
optimization approach results in a more complex architecture and higher
degree of coupling between different query processing phases.
The goal of this task is to investigate all remaining cases of lazy
subquery optimization, and whenever possible change each such case
to utilize the general approach of MWL#89.
Currently known remaining cases:
- sql_select.cc:remove_eq_cond calls cond->const_item() without
checking if cond is expensive.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#167 New (by Sergei): sparse bitmaps
by worklog-noreply@askmonty.org 30 Nov '10
by worklog-noreply@askmonty.org 30 Nov '10
30 Nov '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: sparse bitmaps
CREATION DATE..: Tue, 30 Nov 2010, 11:40
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 167 (http://askmonty.org/worklog/?tid=167)
VERSION........: Benchmarks-3.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 20 (hours remain)
ORIG. ESTIMATE.: 20
PROGRESS NOTES:
DESCRIPTION:
implement sparse bitmaps.
in mysys, as a generic data structure.
preferably with the API compatible to MY_BITMAP.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] New BuildBot tests - compiling the MySQL drivers for PHP and Perl
by Philip Stoev 29 Nov '10
by Philip Stoev 29 Nov '10
29 Nov '10
Hello,
I have installed a new builder "compile-connectors", which will compile the
DBD::mysql and the PHP (5.3) mysql connector (the oldest of them all). The
purpose is to make sure that MariaDB does not break compatibility with MySQL
when it comes to things such as headers, file locations, compilability,
linking and loadability of the compiled module.
I will try to get some more things tested, such as the newer PHP driver, the
C++ connector and drivers containing the embedded server. If you can think
of any other connectors or important applications that link or load
libmysql, let me know and I will try to add them too.
I do not think the new test will catch bugs such as LP#674812, which showed
up when mixing and matching OS packages, downloaded packages and
self-compiled stuff, but we can at least catch the regression if our headers
get modified enough for the third-party drivers to become uncompilable.
My next step will be to automate the testing of the Windows installer and
the installation of MariaDB as a service. Any thoughts you may have in that
area are also appreciated.
Thank you.
Philip Stoev
2
1

29 Nov '10
Hi!
I just merged MySQL 5.1.53 into MariaDB and as part of that, did run
the pbxt test suite.
I encountered this test failure:
mysql-test-run --suite=pbxt
URRENT_TEST: pbxt.insert
--- /home/my/maria-5.1-release/mysql-test/suite/pbxt/r/insert.result 2010-11-25 12:02:26.083226000 +0200
+++ /home/my/maria-5.1-release/mysql-test/suite/pbxt/r/insert.reject 2010-11-25 19:33:48.281738504 +0200
@@ -298,7 +298,7 @@
insert into t2 select t1.* from t1, t2 t, t3 where t1.id1 = t.id2 and t.id2 = t3.id3;
select count(*) from t2;
count(*)
-25500
+25495
drop table t1,t2,t3;
create table t1 (a int, b int);
insert into t1 (a,b) values (a,b);
This only happened once for this test.
(I did get similar failures with one other test for that run, but not
for new runs).
I could not repeat it by running the test or suite again.
I also tested to run the test with valgrind, but not problems found.
I noticed this also happens in buildbot from time to time:
See
http://buildbot.askmonty.org/buildbot/builders/gentoo-x86-dbg/builds/396/st…,
search after pbxt.insert
Paul, have you ever encountered something like this?
Any clues where to start looking?
(The tree I am working with is 5.1-release)
Regards,
Monty
2
1
Hi, 0x00F6!
First: please send questions like this to maria-developers(a)lists.launchpad.net
it's a public mailing list dedicated to MySQL and MariaDB internals, source
code, and related things. I am subscribed, so I'll see you mail there, and you
may be sure I will, because it won't be accidentally catched by my spam filter,
or sorted out in some obscure folder. Furthermore other subscribers will see
your question and could reply if I will be not available (e.g. I could be
travelling).
Thank you.
On Nov 27, 0x00F6 - wrote:
> Hello Sergei,
>
> Would you please help me in one small problem?
> I'm writing MySQL full-text parser plugin and I need to configure it
> by several session-level variables. So I need to execute THDVAR macro
> in my parse function. So how to obtain "thd" variable for this macro?
The server uses 'current_thd' in such a case.
It should probably be in the plugin.h, I'd say. But at the moment it is
not. You can copy the declaration from mysql_priv.h, something like this:
extern pthread_key_t THR_THD;
THD *current_thd() { return (THD*)pthread_getspecific(THR_THD); }
if you want it to work on windows, see mysql_priv.h for the complete
definition of current_thd.
Regards,
Sergei
1
0

Re: [Maria-developers] [Maria-discuss] Problem with MariaDb as a Windows service
by Peter Laursen 25 Nov '10
by Peter Laursen 25 Nov '10
25 Nov '10
Same problem with MariaDB 5.1.51. --Peter
On Sun, Nov 21, 2010 at 02:43, Vladislav Vaintroub <
vladislav.vaintroub(a)oracle.com> wrote:
> Hi,
> It is likely this bug http://bugs.mysql.com/bug.php?id=56821 , was for
> some
> time in MySQL, already fixed.
>
> -----Original Message-----
> From: maria-developers-bounces+wlad=sun.com(a)lists.launchpad.net
> [mailto:maria-developers-bounces+wlad <maria-developers-bounces%2Bwlad>=
> sun.com(a)lists.launchpad.net] On Behalf
> Of Philip Stoev
> Sent: Samstag, 20. November 2010 20:04
> To: Peter Laursen
> Cc: maria-discuss(a)lists.launchpad.net;
> maria-developers(a)lists.launchpad.net
> Subject: Re: [Maria-developers] [Maria-discuss] Problem with MariaDb as a
> Windows service
>
> Hi,
>
> It seems that the service requires the --console option to operate
> properly.
>
> Here is how I could make it work:
>
> 1. In the Services Control panel, open up the properties for the service 2.
> In the "Start Parameters" box, type "--console" without the quotation marks
> 3. In the same dialog box, hit Start
>
> Philip Stoev
>
> ----- Original Message -----
> From: "Peter Laursen" <peter_laursen(a)webyog.com>
> To: <maria-discuss(a)lists.launchpad.net>;
> <maria-developers(a)lists.launchpad.net>
> Sent: Saturday, November 20, 2010 3:36 PM
> Subject: [Maria-discuss] Problem with MariaDb as a Windows service
>
>
> > Some person claimed here around one week ago that MariaDB would not
> > run as service after "mysqld --install".
> > I replied that it worked for me - but it does not with the latest
> > stable version 5.2.3 (it did with the 5.2.3 RC) (so my apology to this
> > person!)
> >
> > Windows console output:
> >
> > C:\maria52\bin>sc delete maria52
> > [SC] DeleteService LYKKEDES
> >
> > C:\maria52\bin>mysqld --install maria52 Service successfully
> > installed.
> >
> > C:\maria52\bin>net start maria52
> > Tjenesten maria52 starter...
> > Tjenesten maria52 kunne ikke startes.
> >
> > Der opstod en systemfejl.
> >
> > Systemfejlen 1067 opstod.
> >
> > (From Danish --> service could not start --> the system error 1067
> > occurred)
> >
> > I have tried with both old datadir and the empty one shipped with
> > mariaDB and also my old my.ini as well as a fresh one.
> > Also I tried to add --defaults-dir to the registry (just in case I had
> > overlooked a my.ini copy in C:\ or C:\Windows) and adding doublequotes
> > key manually like "C:\maria52\bin\mysqld"
> > --defaults-file="C:\maria52\my.ini" maria52
> >
> > I double checked there are no conflicts wit all settings.
> >
> > The command
> > "C:\maria52\bin\mysqld" --defaults-file="C:\maria52\my.ini"
> > .. starts the server (also when --defaults-file is omitted) .. but not
> > as a service of course.
> >
> >
> > Was it tested with the 5.2.3 GA release that it will run as a Windows
> > service?
> > The RC worked as a charm - but the GA will not. Any idea?
> > (I am using Win7, 64 bit, Home Premium)
> >
> >
> > Peter
> > (Webyog)
> >
>
>
>
> ----------------------------------------------------------------------------
> ----
>
>
> > _______________________________________________
> > Mailing list: https://launchpad.net/~maria-discuss
> > Post to : maria-discuss(a)lists.launchpad.net
> > Unsubscribe : https://launchpad.net/~maria-discuss
> > More help : https://help.launchpad.net/ListHelp
> >
>
>
> _______________________________________________
> Mailing list: https://launchpad.net/~maria-developers
> Post to : maria-developers(a)lists.launchpad.net
> Unsubscribe : https://launchpad.net/~maria-developers
> More help : https://help.launchpad.net/ListHelp
>
>
3
2

Re: [Maria-developers] [Maria-discuss] Problem with MariaDb as a Windows service
by Alex Budovski 24 Nov '10
by Alex Budovski 24 Nov '10
24 Nov '10
> Right, this was subsequently fixed in MySQL in
> http://lists.mysql.com/commits/118824
>
Yes, I noticed that too late.
1
0

Re: [Maria-developers] [Commits] Rev 2977: Fix of LP BUG#675248. in file:///home/bell/maria/bzr/work-maria-5.1-lb675248-prep-where/
by Igor Babaev 23 Nov '10
by Igor Babaev 23 Nov '10
23 Nov '10
Sanja.
Ok to push after the required changes in comments
Regards,
Igor.
sanja(a)askmonty.org wrote:
> At file:///home/bell/maria/bzr/work-maria-5.1-lb675248-prep-where/
>
> ------------------------------------------------------------
> revno: 2977
> revision-id: sanja(a)askmonty.org-20101123150005-adpcldzod759jgp1
> parent: sanja(a)askmonty.org-20101118141011-gth6b6pa0w9lyu1b
> committer: sanja(a)askmonty.org
> branch nick: work-maria-5.1-lb675248-prep-where
> timestamp: Tue 2010-11-23 17:00:05 +0200
> message:
> Fix of LP BUG#675248.
>
> Registration of pointer change if we assign it to other pointer which should be identical after statememnt execution (PS/SP).
>
^fix spelling in the comment
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> commits mailing list
> commits(a)mariadb.org
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
+ /**
+ Assigns new value to place and check item tree changes for need of
+ re-registering the change.
Make change in item tree after checking whether it needs registering
+
+ @param place place where we should assign new value
+ @param new_value place of the new value
+
+ @details
+ see check_and_register_item_tree_change details
+ */
+ void check_and_register_item_tree(Item **place, Item **new_value)
+ {
+ if (!stmt_arena->is_conventional())
+ check_and_register_item_tree_change(place, new_value, mem_root);
+ *place= *new_value;
+ }
void nocheck_register_item_tree_change(Item **place, Item *old_value,
MEM_ROOT *runtime_memroot);
+ void check_and_register_item_tree_change(Item **place, Item **new_value,
+ MEM_ROOT *runtime_memroot);
void rollback_item_tree_changes();
1
0

Re: [Maria-developers] really annoying bug in mysql 5.0/5.1 optimiser, opened for more than 2 years, and still present in MariaDB
by Jocelyn Fournier 23 Nov '10
by Jocelyn Fournier 23 Nov '10
23 Nov '10
Hi,
Just FYI, it's created as https://bugs.launchpad.net/maria/+bug/639949
I really hope it could be fixed soon, since it could impact mysql
performances for a lot of customers.
Thanks and regards,
Jocelyn Fournier
Le 15/09/2010 18:43, Igor Babaev a écrit :
> Jocelyn Fournier wrote:
>> Hi Igor,
>>
>> Just curious, is there any bug corresponding to this issue in launchpad ?
> Hi Jocelyn,
>
> No, feel yourself free to add it for MariaDB 5.1. In this case the
> chances are higher that the problem will be fixed in one of the nearest
> releases.
>
> Regards,
> Igor.
>
>> Thanks !
>> Jocelyn
>>
>>
>> Le 27/08/10 18:04, Igor Babaev a écrit :
>>> Jocelyn Fournier wrote:
>>>> Hi,
>>>>
>>>> There's a really annoying bug in the mysql optimiser existing for a
>>>> really long time now, and which has a direct impact on performances :
>>>>
>>>> http://bugs.mysql.com/bug.php?id=36817
>>>>
>>>> Since MySQL definitly doesn't seem to want to fix it, I hope MariaDB
>>>> could do something to help the poor developpers who need to heavily hack
>>>> there apps with USE INDEX ;)
>>>>
>>>> Note I've tested with mariadb 5.2.1-beta, and the bug is still present.
>>>>
>>>> Thanks a lot !
>>>> Jocelyn Fournier
>>> Jocelyn,
>>>
>>> I will take care of this bug.
>>>
>>> Regards,
>>> Igor.
>>>> _______________________________________________
>>>> Mailing list: https://launchpad.net/~maria-developers
>>>> Post to : maria-developers(a)lists.launchpad.net
>>>> Unsubscribe : https://launchpad.net/~maria-developers
>>>> More help : https://help.launchpad.net/ListHelp
>>> _______________________________________________
>>> Mailing list: https://launchpad.net/~maria-developers
>>> Post to : maria-developers(a)lists.launchpad.net
>>> Unsubscribe : https://launchpad.net/~maria-developers
>>> More help : https://help.launchpad.net/ListHelp
>
1
0
Sorry for the delayed notice but adutko-centos5-amd64 will probably be
offline until Wednesday (11/24/10) awaiting a part replacement.
-Adam
<http://buildbot.askmonty.org/buildbot/buildslaves/adutko-centos5-amd64>
1
0

Re: [Maria-developers] [Commits] Rev 2832: Fix for LP BUG#606013: Adding bit field support for heap tables. in file:///home/bell/maria/bzr/work-maria-5.3-lp606013/
by Michael Widenius 22 Nov '10
by Michael Widenius 22 Nov '10
22 Nov '10
Hi!
Here is a review of this
<cut>
> --- a/storage/heap/hp_create.c 2010-08-05 19:56:11 +0000
> +++ b/storage/heap/hp_create.c 2010-11-16 21:03:26 +0000
> @@ -104,6 +104,13 @@ int heap_create(const char *name, uint k
> */
> keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
> break;
> + case HA_KEYTYPE_BIT:
> + /*
> + The odd bits which stored separately (if they are present
> + (bit_pos, bit_length)) are already present in seg[j].length as
> + additional byte.
Add: See field.h, function key_length()
<cut>
> @@ -720,7 +765,8 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, u
> {
> uint length= seg->length;
> uchar *pos= (uchar*) rec + seg->start;
> -
> + DBUG_ASSERT(seg->type != HA_KEYTYPE_BIT);
Add a check in the test suite that one can't create a rb key with bit
fields.
Add also a MRT for this. (you can probable reuse something from
type_bit.test and archive_bitfield.test for this)
Regards,
Monty
1
0

22 Nov '10
Preparation statement for PS looks like this (example uses prep_where,
but we have the same problem for other parts stored in
st_select_lex::fix_prepare_information()):
...
conds->fix_fields(...&conds...) /* (1.1) JOIN::prepare()*/
...
prep_where= *conds; /* (1.2)
st_select_lex::fix_prepare_information() */
*conds= where= prep_where->copy_andor_structure()
...
Then executing of the prepared statement is like this:
where= prep_where->copy_andor_structure() /* (2.1) reinit_stmt_before_use */
...
where->fix_fields() /* (2.2) JOIN::prepare() */
...
The problem is that during (1.1) we could substitute conds with
reference on other item (for example if we change reference on
Item_field on Item_ref* or Item_ref on Item_field). The new item will be
destroyed after preparation (i.e before (2.1)). So during (2.1)
prep_where points on freed memory.
How to solve the problem.
1. Workarounds
1.1. Make changing Items inherited from Item_ident (Item_field and
Item_ref*) during resolving permanent.
Pros:
- Looks logical
- reduce work during second preparation
Cons:
- Play with statement memory usually complex enough.
- have to be sure that there is no any reference on the original Item
1.2 Add new method for Item, which return 'this' pointer but for
Item_idents creating during resolving original Item. (1.2) turns to
something like:
prep_where= (*conds)->original_ident_item();
Pros:
- Looks simple
Cons:
- Item already overloaded with methods like this
1.3 Assign prep_where before (1.1)
Pros:
- Easy to implement
Cons:
- Need changing logic and semantic of some calls and
prep_where/prep_having... class variables.
2. Global solutions for the problem of double/triple/... reference on
transformed expression (it is not applicadle for 5.1-5.3 but could de
universal solution in 5.5 of higher):
2.1 Absolutely transparent wrapper to save only one reference on any
expression which could be transformed:
Pros:
- Could base class for many other wrappers
Cons:
- It is difficult to implement such absolutely transparent wrapper.
- A lot of places where it should be put, make Item tree bigger
2.2 Turn THD::change_list to hash (for example) and chack presence
of assigning variable in the list, if it found, also register changing
for variable we are assigning value now. For example instead of
prep_where= *conds; use thd->assign_changeable(&prep_where, conds), where:
void THD::assign_changeable(void **newref, void **oldref)
{
if (in_changed_references(oldref)
change_item_tree(newref, *oldref);
else
*newref= *oldref;
}
Pros:
- no additional work for usual statements
Cons:
- List supports order of assigments easyly, but hash can't
- time for finding pointers in the hash
2
1

Re: [Maria-developers] [Commits] Rev 89: MBug#674413: better fix following review: clear sql_mode rather than add every column explicitly. in http://bazaar.launchpad.net/~maria-captains/maria/5.1
by Sergei Golubchik 21 Nov '10
by Sergei Golubchik 21 Nov '10
21 Nov '10
Hi, knielsen!
On Nov 20, knielsen(a)knielsen-hq.org wrote:
> At http://bazaar.launchpad.net/~maria-captains/maria/5.1
>
> ------------------------------------------------------------
> revno: 89
> revision-id: knielsen(a)knielsen-hq.org-20101120084531-x0hbb64q9x0yj376
> parent: knielsen(a)knielsen-hq.org-20101119133933-wb5g8sdjynao018w
> committer: knielsen(a)knielsen-hq.org
> branch nick: ourdelta-montyprogram-fixes
> timestamp: Sat 2010-11-20 09:45:31 +0100
> message:
> MBug#674413: better fix following review: clear sql_mode rather than add every column explicitly.
> === modified file 'bakery/debian-5.2/dist/Debian/mariadb-server-5.2.postinst'
> --- a/bakery/debian-5.2/dist/Debian/mariadb-server-5.2.postinst 2010-11-19 13:39:33 +0000
> +++ b/bakery/debian-5.2/dist/Debian/mariadb-server-5.2.postinst 2010-11-20 08:45:31 +0000
> @@ -195,6 +195,7 @@ EOF
> "ALTER TABLE user CHANGE Password Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL"`;
> replace_query=`/bin/echo -e \
> "USE mysql\n" \
> + "SET sql_mode='';\n" \
> "REPLACE INTO user SET " \
> " host='localhost', user='debian-sys-maint', password=password('$pass'), " \
> " Select_priv='Y', Insert_priv='Y', Update_priv='Y', Delete_priv='Y', " \
> @@ -205,9 +206,7 @@ EOF
> " Repl_slave_priv='Y', Repl_client_priv='Y', Create_view_priv='Y', "\
> " Show_view_priv='Y', Create_routine_priv='Y', Alter_routine_priv='Y', "\
> " Create_user_priv='Y', Event_priv='Y', Trigger_priv='Y',"\
> - " ssl_type='', ssl_cipher='', x509_issuer='', x509_subject='',"\
> - " max_questions=0, max_updates=0, max_connections=0,"\
> - " max_user_connections=0, plugin='', auth_string='';"`;
> + " ssl_cipher='', x509_issuer='', x509_subject='';"`;
There's no need to set ssl_cipher and other blob columns - they'll get
the empty string by default anyway.
Regards,
Sergei
2
1
Some person claimed here around one week ago that MariaDB would not run as
service after "mysqld --install".
I replied that it worked for me - but it does not with the latest stable
version 5.2.3 (it did with the 5.2.3 RC)
(so my apology to this person!)
Windows console output:
C:\maria52\bin>sc delete maria52
[SC] DeleteService LYKKEDES
C:\maria52\bin>mysqld --install maria52
Service successfully installed.
C:\maria52\bin>net start maria52
Tjenesten maria52 starter...
Tjenesten maria52 kunne ikke startes.
Der opstod en systemfejl.
Systemfejlen 1067 opstod.
(From Danish --> service could not start --> the system error 1067 occurred)
I have tried with both old datadir and the empty one shipped with mariaDB
and also my old my.ini as well as a fresh one.
Also I tried to add --defaults-dir to the registry (just in case I had
overlooked a my.ini copy in C:\ or C:\Windows) and adding doublequotes key
manually like
"C:\maria52\bin\mysqld" --defaults-file="C:\maria52\my.ini" maria52
I double checked there are no conflicts wit all settings.
The command
"C:\maria52\bin\mysqld" --defaults-file="C:\maria52\my.ini"
.. starts the server (also when --defaults-file is omitted) .. but not as a
service of course.
Was it tested with the 5.2.3 GA release that it will run as a Windows
service?
The RC worked as a charm - but the GA will not. Any idea?
(I am using Win7, 64 bit, Home Premium)
Peter
(Webyog)
2
6
All,
I've created the download, release notes, and changelog pages for
MariaDB 5.1.51:
http://askmonty.org/wiki/MariaDB:Download:MariaDB_5.1.51
http://kb.askmonty.org/v/mariadb-5151-release-notes
http://kb.askmonty.org/v/mariadb-5151-changelog
Apart from the CentOS packages, the mirrors should now have all of the
files for this release. There was an issue with the signing key used on
the CentOS packages. The issue has been fixed and the updated packages
are seeding now. If you can't wait, the osuosl.org mirror is the
primary one and is always up-to-date.
Please let me know if anything is missing from the release notes or
changelog, or if there are any errors. If you have editing rights, feel
free to make the corrections or additions directly; otherwise, please
let me know of needed changes here or on IRC.
Thanks.
--
Daniel Bartholomew
MariaDB - http://mariadb.org
Monty Program - http://montyprogram.com
AskMonty Knowledgebase - http://kb.askmonty.org
2
3

Re: [Maria-developers] Fwd: [Commits] Rev 2860: Fixed LP bug #675922. in file:///home/igor/maria/maria-5.3-mwl128-bug675922/
by Sergey Petrunya 19 Nov '10
by Sergey Petrunya 19 Nov '10
19 Nov '10
Hello Igor,
On Thu, Nov 18, 2010 at 10:04:24PM -0800, Igor Babaev wrote:
> Sergey,
>
> Please review this fix.
>
Ok to push after the irc feedback (lack of comments about JOIN_CACHE format) is
addressed.
>
> -------- Original Message --------
> Subject: [Commits] Rev 2860: Fixed LP bug #675922. in
> file:///home/igor/maria/maria-5.3-mwl128-bug675922/
> Date: Thu, 18 Nov 2010 22:02:41 -0800 (PST)
> From: Igor Babaev <igor(a)askmonty.org>
> Reply-To: maria-developers(a)lists.launchpad.net
> To: <commits(a)mariadb.org>
>
>
>
> At file:///home/igor/maria/maria-5.3-mwl128-bug675922/
>
> ------------------------------------------------------------
> revno: 2860
> revision-id: igor(a)askmonty.org-20101119060240-gzh1k5gxl3aazk45
> parent: igor(a)askmonty.org-20101118221357-zg55d3erru07ugzy
> committer: Igor Babaev <igor(a)askmonty.org>
> branch nick: maria-5.3-mwl128-bug675922
> timestamp: Thu 2010-11-18 22:02:40 -0800
> message:
> Fixed LP bug #675922.
> The bug happened when BKA join algorithm used an incremental buffer
> and some of the fields over which access keys were constructed
> - were allocated in the previous join buffers
> - were non-nullable
> - belonged to inner tables of outer joins.
> For such fields an offset to the field value in the record is saved
> in the postfix of the record, and a zero offset indicates that the value
> is null. Before the key using the field value is constructed the
> value is read into the corresponding field of the record buffer and
> the null bit is set for the field if the offset is 0. However if
> the field is non-nullable the table->null_row must be set to 1
> for null values and to 0 for non-null values to ensure proper reading
> of the value from the record buffer.
>
> === modified file 'mysql-test/r/join_cache.result'
> --- a/mysql-test/r/join_cache.result 2010-11-18 22:13:57 +0000
> +++ b/mysql-test/r/join_cache.result 2010-11-19 06:02:40 +0000
> @@ -6004,4 +6004,56 @@
> SET SESSION optimizer_switch = 'outer_join_with_cache=off';
> SET SESSION join_cache_level = DEFAULT;
> DROP TABLE t1,t2,t3;
> +#
> +# Bug #675922: incremental buffer for BKA with access from previous
> +# buffers from non-nullable columns whose values may be null
> +#
> +CREATE TABLE t1 (a1 varchar(32)) ;
> +INSERT INTO t1 VALUES ('s'),('k');
> +CREATE TABLE t2 (a2 int PRIMARY KEY, b2 varchar(32)) ;
> +INSERT INTO t2 VALUES (7,'s');
> +CREATE TABLE t3 (a3 int PRIMARY KEY, b3 varchar(32)) ;
> +INSERT INTO t3 VALUES (7,'s');
> +CREATE TABLE t4 (a4 int) ;
> +INSERT INTO t4 VALUES (9);
> +CREATE TABLE t5(a5 int PRIMARY KEY, b5 int) ;
> +INSERT INTO t5 VALUES (7,0);
> +SET SESSION optimizer_switch = 'outer_join_with_cache=on';
> +SET SESSION join_cache_level = 0;
> +EXPLAIN
> +SELECT t4.a4, t5.b5
> +FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
> +LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
> +id select_type table type possible_keys key key_len ref rows Extra
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1 Using where
> +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using index
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 1 Using where
> +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using where
> +SELECT t4.a4, t5.b5
> +FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
> +LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
> +a4 b5
> +9 0
> +9 NULL
> +SET SESSION join_cache_level = 6;
> +EXPLAIN
> +SELECT t4.a4, t5.b5
> +FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
> +LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
> +id select_type table type possible_keys key key_len ref rows Extra
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1 Using where
> +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using index
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using where; Using join buffer (incremental, BKA join)
> +SELECT t4.a4, t5.b5
> +FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
> +LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
> +a4 b5
> +9 0
> +9 NULL
> +SET SESSION optimizer_switch = 'outer_join_with_cache=off';
> +SET SESSION join_cache_level = DEFAULT;
> +DROP TABLE t1,t2,t3,t4,t5;
> set @@optimizer_switch=@save_optimizer_switch;
>
> === modified file 'mysql-test/t/join_cache.test'
> --- a/mysql-test/t/join_cache.test 2010-11-18 22:13:57 +0000
> +++ b/mysql-test/t/join_cache.test 2010-11-19 06:02:40 +0000
> @@ -2655,5 +2655,50 @@
>
> DROP TABLE t1,t2,t3;
>
> +--echo #
> +--echo # Bug #675922: incremental buffer for BKA with access from previous
> +--echo # buffers from non-nullable columns whose values may be null
> +--echo #
> +
> +CREATE TABLE t1 (a1 varchar(32)) ;
> +INSERT INTO t1 VALUES ('s'),('k');
> +
> +CREATE TABLE t2 (a2 int PRIMARY KEY, b2 varchar(32)) ;
> +INSERT INTO t2 VALUES (7,'s');
> +
> +CREATE TABLE t3 (a3 int PRIMARY KEY, b3 varchar(32)) ;
> +INSERT INTO t3 VALUES (7,'s');
> +
> +CREATE TABLE t4 (a4 int) ;
> +INSERT INTO t4 VALUES (9);
> +
> +CREATE TABLE t5(a5 int PRIMARY KEY, b5 int) ;
> +INSERT INTO t5 VALUES (7,0);
> +
> +SET SESSION optimizer_switch = 'outer_join_with_cache=on';
> +
> +SET SESSION join_cache_level = 0;
> +EXPLAIN
> +SELECT t4.a4, t5.b5
> + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
> + LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
> +SELECT t4.a4, t5.b5
> + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
> + LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
> +
> +SET SESSION join_cache_level = 6;
> +EXPLAIN
> +SELECT t4.a4, t5.b5
> + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
> + LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
> +SELECT t4.a4, t5.b5
> + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1)
> + LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2;
> +
> +SET SESSION optimizer_switch = 'outer_join_with_cache=off';
> +SET SESSION join_cache_level = DEFAULT;
> +
> +DROP TABLE t1,t2,t3,t4,t5;
> +
> # this must be the last command in the file
> set @@optimizer_switch=@save_optimizer_switch;
>
> === modified file 'sql/sql_join_cache.cc'
> --- a/sql/sql_join_cache.cc 2010-11-13 15:47:43 +0000
> +++ b/sql/sql_join_cache.cc 2010-11-19 06:02:40 +0000
> @@ -1805,14 +1805,21 @@
> size_of_fld_ofs*
> (referenced_fields+1-copy->referenced_field_no));
> bool is_null= FALSE;
> + Field *field= copy->field;
> if (offset == 0 && flag_fields)
> is_null= TRUE;
> if (is_null)
> - copy->field->set_null();
> + {
> + field->set_null();
> + if (!field->real_maybe_null())
> + field->table->null_row= 1;
> + }
> else
> {
> uchar *save_pos= pos;
> - copy->field->set_notnull();
> + field->set_notnull();
> + if (!field->real_maybe_null())
> + field->table->null_row= 0;
> pos= rec_ptr+offset;
> read_record_field(copy, blob_data_is_in_rec_buff(rec_ptr));
> pos= save_pos;
>
> _______________________________________________
> commits mailing list
> commits(a)mariadb.org
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
--
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
0

Re: [Maria-developers] Fwd: [Commits] Rev 2859: Fixed LP #bug 660963. in file:///home/igor/maria/maria-5.3-mwl128-bug660963/
by Sergey Petrunya 19 Nov '10
by Sergey Petrunya 19 Nov '10
19 Nov '10
Hello Igor,
On Thu, Nov 18, 2010 at 02:17:13PM -0800, Igor Babaev wrote:
> Sergey,
>
> Please review this patch ASAP as this bug blocks Philip with testing.
> If you have any questions contact me by skype.
>
Ok to push after the comment below is addressed.
> -------- Original Message --------
> Subject: [Commits] Rev 2859: Fixed LP #bug 660963. in
> file:///home/igor/maria/maria-5.3-mwl128-bug660963/
> Date: Thu, 18 Nov 2010 14:13:58 -0800 (PST)
> From: Igor Babaev <igor(a)askmonty.org>
> Reply-To: maria-developers(a)lists.launchpad.net
> To: <commits(a)mariadb.org>
>
>
>
> At file:///home/igor/maria/maria-5.3-mwl128-bug660963/
>
> ------------------------------------------------------------
> revno: 2859
> revision-id: igor(a)askmonty.org-20101118221357-zg55d3erru07ugzy
> parent: igor(a)askmonty.org-20101116050732-hpbqelsf8nvae4xt
> committer: Igor Babaev <igor(a)askmonty.org>
> branch nick: maria-5.3-mwl128-bug660963
> timestamp: Thu 2010-11-18 14:13:57 -0800
> message:
> Fixed LP #bug 660963.
> The condition that was supposed to check whether a join table
> is an inner table of a nested outer join or semi-join was not
> quite correct in the code of the function check_join_cache_usage.
> That's why some queries with nested outer joins triggered
> an assertion failure.
> Encapsulated this condition in the new method called
> JOIN_TAB::is_nested_inner and provided a proper code for it.
>
> Also corrected a bug in the code of check_join_cache_usage()
> that caused a downgrade of not first join buffers of the
> level 5 and 7 to level 4 and 6 correspondingly.
>
...
> === modified file 'sql/sql_select.cc'
> --- a/sql/sql_select.cc 2010-11-16 05:07:32 +0000
> +++ b/sql/sql_select.cc 2010-11-18 22:13:57 +0000
> @@ -7635,8 +7635,7 @@
> if (cache_level == 0 || i == join->const_tables || !prev_tab)
> return 0;
>
> - if (force_unlinked_cache &&
> - (cache_level & JOIN_CACHE_INCREMENTAL_BIT))
> + if (force_unlinked_cache && (cache_level%2 == 0))
> cache_level--;
>
> if (options & SELECT_NO_JOIN_CACHE)
> @@ -7658,13 +7657,14 @@
> /*
> Non-linked join buffers can't guarantee one match
> */
> - if ((force_unlinked_cache || cache_level == 1) &&
> - ((tab->is_inner_table_of_semi_join_with_first_match() &&
> - !tab->is_single_inner_of_semi_join_with_first_match()) ||
> - (tab->is_inner_table_of_outer_join() &&
> - !tab->is_single_inner_of_outer_join())))
> - goto no_join_cache;
> -
> + if (tab->is_nested_inner())
> + {
> + if (force_unlinked_cache || cache_level == 1)
> + goto no_join_cache;
> + if (cache_level & 1)
> + cache_level--;
> + }
> +
> /*
> Don't use join buffering if we're dictated not to by no_jbuf_after (this
> ...)
> @@ -7757,9 +7757,6 @@
> (cache_level <= 6 || no_hashed_cache))
> goto no_join_cache;
>
> - if (prev_tab->cache && cache_level==7)
> - cache_level= 6;
> -
> if ((rows != HA_POS_ERROR) && !(flags & HA_MRR_USE_DEFAULT_IMPL))
> {
> if (cache_level <= 6 || no_hashed_cache)
>
> === modified file 'sql/sql_select.h'
> --- a/sql/sql_select.h 2010-11-13 14:13:34 +0000
> +++ b/sql/sql_select.h 2010-11-18 22:13:57 +0000
> @@ -359,6 +359,14 @@
> return (first_inner && first_inner->last_inner == this) ||
> last_sj_inner_tab == this;
> }
> + bool is_nested_inner()
Please add a comment clarifying what this function checks.
> + {
> + if (first_inner && (first_inner != last_inner || first_upper))
> + return TRUE;
> + if (first_sj_inner_tab && first_sj_inner_tab != last_sj_inner_tab)
> + return TRUE;
> + return FALSE;
> + }
> struct st_join_table *get_first_inner_table()
> {
> if (first_inner)
>
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
0
Hi,
I have reviewed your demands with respect to the test cases that I file.
Many of those have already been fixed and implemented, however on the items
below I have received contradictory feedback and I can not do anything about
them unless the controversies are resolved:
> When an offending query is found, substitute all JOINs with STRAIGHT_JOINs
> to ensure that the plan is preserved, then continue simplifying,
My impression was that Igor was against STRAIGHT_JOINS. Also, I have reduced
STRAIGHT_JOIN usage in testing because there are various wrong results that
show up when STRAIGHT_JOIN is used. If you are willing to fix those, we can
move forward with this idea. FORCE KEY can also be used to preserve the
original query plan, but only if it is not held against me that it makes the
query unrealistic.
> Test the base/normal cases (what normal users will use) first, by
> negotiating with the feature developer what are the boundaries that define
> "normal".
Unless someone defines "normal" or we obtain data sets and queries from
users, this is not possible.
> For instance set normal buffer sizes, do not use empty/single-row tables
Please make up your mind. Timour has said that both empty and single row
tables are important for testing. What if automatic simplification reduced
some tables to empty or a single row? Should I add some of the rows back?
> Test the boundary cases after the main cases have been fixed
Define "boundary". Huge tables? Huge queries? Huge records? Unrealistic
buffer sizes? I have been informed only about a single bug that can be
called a boundary condition. Have there been any others?
> Generate more realistic data in the sense that the generated data should
> imitate FK relationships, think of real-life distributions of values. For
> instance keys should be sufficiently selective, as they would be for
> real-life data. (Igor: 7)
This implies large data sets, which in turn implies that bugs will have
larger test cases. At this time, what I see is zero tolerance for test cases
larger than 5 rows.
> Include both the original *and* the simplified test case in the bub report
I can do this only if the original query and test case will not be held
against me. We have been through this before and the large queries have
proven to be a source of conflict.
Philip Stoev
1
0
Igor,
Please review the attached patch for LP BUG#641203 we discussed last week.
Since there was no email service, the commit mail didn't get through, so
the commit comment is:
"
Fixed LP BUG#641203: Query returns rows where no result is expected (impossible WHERE)
The cause for the bug was two-fold:
1. Incorrect detection of whether a table is the first one in a query plan -
"used_table & 1" actually checks if used_table is table with number "1".
2. Missing logic to delay the evaluation of (expensive) constant conditions
during the execution phase.
The fix adds/changes:
The patch:
- removes expensive predicate treatment from make_cond_for_table, assuming
that the caller should decide whether to evaluate or not expensive predicates,
and what to do with them.
- saves expensive constant conditions in JOIN::exec_const_cond,
which is evaluated once in the beginning of JOIN::exec.
"
Timour
1
0
Hi!
On Nov 15, Daniel Bartholomew wrote:
> http://kb.askmonty.org/v/no-mariadb-port-in-freebsd
>
> He's asking about getting MariaDB into the ports tree of FreeBSD. Any
> thoughts on an answer to give him?
Rather, do we want a FreeBSD port?
I think we can do that, it is probably not too difficult.
Although, of course, there could be a problem similar to what we have
with debian and dependencies, but we'll never know unless we try :)
I'd suggest to add one FreeBSD VM to buildbot - on that new Intel box
that will host VMs for builbot anyway.
Kristian already has the experience and all the scripts for generating
debs and rpms and installing them on a clean VM - hopefully, that could
be easily adapted to FreeBSD too.
Acording to the FreeBSD porter's handbook
"
In FreeBSD, anyone may submit a new port, or volunteer to maintain an
existing port if it is unmaintained--you do not need any special
commit privileges to do so.
"
So, it should be possible for us to submit a MariaDB port and maintain
it (*). Preferrably even in the source tree.
Regards,
Sergei
(*) MySQL never managed to get that, btw.
1
0

16 Nov '10
Igor,
As you have noticed I have started filing bugs that require 4-5 tables, self
joins, etc. to show up. I continue running the same tests as before, it is
just that the 2-table bugs have all been fixed by now.
While I do consider 4-5 table bugs to still be valid, since they all use
default join cache sizes, we need to discuss and decide how much I am going
to test and how much is going to be fixed before 5.3 is considered stable.
Here is my suggestion:
- I will continue to run the same full grammars and file the bugs regardless
of how many tables are required to reproduce, always trying to find the
smallest reproducible test case;
- Crashes involving up to 5 tables are to be fixed;
- Wrong result bugs involving up to 4 tables are to be fixed.
- outer join + join_cache bugs are acceptable since I assume that the
outer_join_with_cache option will be ON in the final release;
- wrong result bugs requiring a very small join_cache_buffer value can be
(temporarily) fixed by increasing the minimum join_cache_buffer allowed;
- all join cache levels are acceptable targets for testing unless you plan
to disallow certain levels altogether;
If you think otherwise, please suggest an alternative plan. Otherwise I
assume you agree with the above.
Thank you.
Philip Stoev
2
1

12 Nov '10
Hello Igor,
Please find the first batch of comments (more will likely follow):
First, overall comments:
* As already suggested/discussed: the push of this WL is a nice opportunity to
move join buffering-related declarations from sql_select.h into a separate
header file.
* At the moment I don't see any place in the code that would give an overview
of the whole hash join thing, together with its limitations, etc.
* A lot of function comments start from a sentence in form
"This function {does something}" , or "This method {does something}", or
"This implementation of the virtual method X {does something}".
Such wording is unnecessarily verbose and is hard to read. We used to have a
style that function comments start with a verb (look at sha1_reset() comment
in the coding style
http://forge.mysql.com/wiki/MySQL_Internals_Coding_Guidelines)
This convention is widely used in other sources as well, e.g. in java:
http://download.oracle.com/javase/1.5.0/docs/api/java/lang/String.html
I've marked all the cases of "This function {does something}" comments below
with "this_function_syntax".
* EXPLAIN currently shows hash join as follows:
MariaDB [hj1]> explain extended select * from t1 A, t2 B where A.a=B.a;
+----+-------------+-------+------+---------------+------+---------+---------+------+-------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+---------+------+-------------------------------------+
| 1 | SIMPLE | A | ALL | NULL | NULL | NULL | NULL | 10 | Using where |
| 1 | SIMPLE | B | ref | a | a | 13 | hj1.A.a | 4 | Using join buffer (flat, BNLH join) |
+----+-------------+-------+------+---------------+------+---------+---------+------+-------------------------------------+
As I've already complained, this notation completely obscures the part of the
QEP that this query plan involves a full scan of table B (which has 4000 rows,
and that is not shown anywhere either).
I think we can mark this WL as complete only as long as we accept that current
situation with EXPLAIN should be fixed before the release (and file a WL for
addressing this)
* To make it possible for others to debug, it would be very helpful if format
of join buffer records was described in a manner similar to how
KeyTupleFormat was described (including an easily greppable name).
Right now, it is not obvious
- what is "auxiliary buffer", what it holds and where it is located
- where the hash table is located in case of hashed algorithm use
- which part of buffer is given to the storage engine's MRR implementation.
Further comments in the code are marked with 'psergey:'
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/field.h maria-5.3-mwl128-noc/sql/field.h
> --- maria-5.3-mwl128-clean/sql/field.h 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/field.h 2010-11-03 10:29:14.000000000 +0200
> @@ -585,6 +585,10 @@
> }
> /* Hash value */
> virtual void hash(ulong *nr, ulong *nr2);
> +
> + /* Check whether the field can be used as a join attribute in hash join */
> + virtual bool hash_join_is_possible() { return TRUE; }
> +
> friend bool reopen_table(THD *,struct st_table *,bool);
> friend int cre_myisam(char * name, register TABLE *form, uint options,
> ulonglong auto_increment_value);
> @@ -760,6 +764,12 @@
> my_decimal *val_decimal(my_decimal *);
> virtual bool str_needs_quotes() { return TRUE; }
> uint is_equal(Create_field *new_field);
> +
> + bool hash_join_is_possible()
> + {
> + /* TODO: support hash joins for non-binary collations */
> + return (flags & BINARY_FLAG);
> + }
> };
>
>
> @@ -1904,6 +1914,7 @@
> uint size_of() const { return sizeof(*this); }
> int reset(void) { return !maybe_null() || Field_blob::reset(); }
> geometry_type get_geometry_type() { return geom_type; };
> + bool hash_join_is_possible() { return FALSE; }
> };
> #endif /*HAVE_SPATIAL*/
>
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/handler.h maria-5.3-mwl128-noc/sql/handler.h
> --- maria-5.3-mwl128-clean/sql/handler.h 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/handler.h 2010-11-03 10:29:14.000000000 +0200
> @@ -1214,6 +1214,8 @@
> bool (*skip_index_tuple) (range_seq_t seq, char *range_info);
> } RANGE_SEQ_IF;
>
> +typedef bool (*SKIP_INDEX_TUPLE_FUNC) (range_seq_t seq, char *range_info);
> +
psergey: as discussed: the above define is not used anywhere, so please
remove it.
> class COST_VECT
> {
> public:
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/mysqld.cc maria-5.3-mwl128-noc/sql/mysqld.cc
> --- maria-5.3-mwl128-clean/sql/mysqld.cc 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/mysqld.cc 2010-11-10 12:09:51.000000000 +0200
> @@ -345,6 +345,11 @@
> "partial_match_rowid_merge",
> "partial_match_table_scan",
> "subquery_cache",
> + "outer_join_with_cache",
> + "semijoin_with_cache",
> + "join_cache_incremental",
> + "join_cache_hashed",
> + "join_cache_bka",
> #ifndef DBUG_OFF
> "table_elimination",
> #endif
> @@ -366,6 +371,11 @@
> sizeof("partial_match_rowid_merge") - 1,
> sizeof("partial_match_table_scan") - 1,
> sizeof("subquery_cache") - 1,
> + sizeof("outer_join_with_cache") - 1,
> + sizeof("semijoin_with_cache") - 1,
> + sizeof("join_cache_incremental") - 1,
> + sizeof("join_cache_hashed") - 1,
> + sizeof("join_cache_bka") - 1,
> #ifndef DBUG_OFF
> sizeof("table_elimination") - 1,
> #endif
> @@ -464,7 +474,10 @@
> "semijoin=on,"
> "partial_match_rowid_merge=on,"
> "partial_match_table_scan=on,"
> - "subquery_cache=on"
> + "subquery_cache=on,"
> + "join_cache_incremental=on,"
> + "join_cache_hashed=on,"
> + "join_cache_bka=on"
> #ifndef DBUG_OFF
> ",table_elimination=on";
> #else
> @@ -5937,7 +5950,8 @@
> OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
> OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
> OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
> - OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE, OPT_JOIN_CACHE_LEVEL,
> + OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
> + OPT_JOIN_BUFF_SPACE_LIMIT, OPT_JOIN_CACHE_LEVEL,
> OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
> OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
> OPT_KEY_CACHE_PARTITIONS,
> @@ -7085,11 +7099,17 @@
> &max_system_variables.net_interactive_timeout, 0,
> GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
> {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
> - "The size of the buffer that is used for full joins.",
> - &global_system_variables.join_buff_size,
> - &max_system_variables.join_buff_size, 0, GET_ULONG,
> + "The size of the buffer that is used for joins.",
> + &global_system_variables.join_buff_size,
> + &max_system_variables.join_buff_size, 0, GET_ULONG,
> REQUIRED_ARG, 128*1024L, 128+MALLOC_OVERHEAD, (longlong) ULONG_MAX,
> MALLOC_OVERHEAD, 128, 0},
> + {"join_buffer_space_limit", OPT_JOIN_BUFF_SPACE_LIMIT,
> + "The limit of the space for all join buffers used by a query.",
> + &global_system_variables.join_buff_space_limit,
> + &max_system_variables.join_buff_space_limit, 0, GET_ULL,
> + REQUIRED_ARG, 8*128*1024L, 2048+MALLOC_OVERHEAD, (longlong) ULONGLONG_MAX,
> + MALLOC_OVERHEAD, 2048, 0},
> {"join_cache_level", OPT_JOIN_CACHE_LEVEL,
> "Controls what join operations can be executed with join buffers. Odd numbers are used for plain join buffers while even numbers are used for linked buffers",
> &global_system_variables.join_cache_level,
> @@ -7381,7 +7401,8 @@
> "index_merge_union, index_merge_sort_union, index_merge_intersection, "
> "index_condition_pushdown, firstmatch, loosescan, materialization, "
> "semijoin, partial_match_rowid_merge, partial_match_table_scan, "
> - "subquery_cache"
> + "subquery_cache, outer_join_with_cache, semijoin_with_cache, "
> + "join_cache_incremental, join_cache_hashed, join_cache_bka"
> #ifndef DBUG_OFF
> ", table_elimination"
> #endif
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/mysql_priv.h maria-5.3-mwl128-noc/sql/mysql_priv.h
> --- maria-5.3-mwl128-clean/sql/mysql_priv.h 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/mysql_priv.h 2010-11-10 12:09:51.000000000 +0200
> @@ -570,12 +570,17 @@
> #define OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE 512
> #define OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN 1024
> #define OPTIMIZER_SWITCH_SUBQUERY_CACHE (1<<11)
> +#define OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE (1<<12)
> +#define OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE (1<<13)
> +#define OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL (1<<14)
> +#define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1<<15)
> +#define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1<<16)
>
> #ifdef DBUG_OFF
> -# define OPTIMIZER_SWITCH_LAST (1<<12)
> +# define OPTIMIZER_SWITCH_LAST (1<<17)
> #else
> -# define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1<<12)
> -# define OPTIMIZER_SWITCH_LAST (1<<13)
> +# define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1<<17)
> +# define OPTIMIZER_SWITCH_LAST (1<<18)
> #endif
>
> #ifdef DBUG_OFF
> @@ -591,7 +596,10 @@
> OPTIMIZER_SWITCH_SEMIJOIN | \
> OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE|\
> OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN|\
> - OPTIMIZER_SWITCH_SUBQUERY_CACHE)
> + OPTIMIZER_SWITCH_SUBQUERY_CACHE | \
> + OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
> + OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
> + OPTIMIZER_SWITCH_JOIN_CACHE_BKA)
> #else
> # define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
> OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
> @@ -605,7 +613,10 @@
> OPTIMIZER_SWITCH_SEMIJOIN | \
> OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE|\
> OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN|\
> - OPTIMIZER_SWITCH_SUBQUERY_CACHE)
> + OPTIMIZER_SWITCH_SUBQUERY_CACHE | \
> + OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
> + OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
> + OPTIMIZER_SWITCH_JOIN_CACHE_BKA)
> #endif
>
> /*
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/opt_index_cond_pushdown.cc maria-5.3-mwl128-noc/sql/opt_index_cond_pushdown.cc
> --- maria-5.3-mwl128-clean/sql/opt_index_cond_pushdown.cc 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/opt_index_cond_pushdown.cc 2010-10-04 15:01:07.000000000 +0300
> @@ -272,12 +272,14 @@
> in tab->select_cond
> keyno Index for which extract and push the condition
> other_tbls_ok TRUE <=> Fields of other non-const tables are allowed
> + factor_out TRUE <=> Factor out the extracted condition
>
> DESCRIPTION
> Try to extract and push the index condition down to table handler
> */
>
> -void push_index_cond(JOIN_TAB *tab, uint keyno, bool other_tbls_ok)
> +void push_index_cond(JOIN_TAB *tab, uint keyno, bool other_tbls_ok,
> + bool factor_out)
> {
> DBUG_ENTER("push_index_cond");
> Item *idx_cond;
> @@ -350,7 +352,8 @@
> if (idx_remainder_cond != idx_cond)
> tab->ref.disable_cache= TRUE;
>
> - Item *row_cond= make_cond_remainder(tab->select_cond, TRUE);
> + Item *row_cond= factor_out ? make_cond_remainder(tab->select_cond, TRUE) :
> + tab->pre_idx_push_select_cond;
>
> DBUG_EXECUTE("where",
> print_where(row_cond, "remainder cond", QT_ORDINARY););
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/set_var.cc maria-5.3-mwl128-noc/sql/set_var.cc
> --- maria-5.3-mwl128-clean/sql/set_var.cc 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/set_var.cc 2010-11-10 12:09:51.000000000 +0200
> @@ -318,6 +318,9 @@
> &SV::net_interactive_timeout);
> static sys_var_thd_ulong sys_join_buffer_size(&vars, "join_buffer_size",
> &SV::join_buff_size);
> +static sys_var_thd_ulonglong sys_join_buffer_space_limit(&vars,
> + "join_buffer_space_limit",
> + &SV::join_buff_space_limit);
> static sys_var_thd_ulong sys_join_cache_level(&vars, "join_cache_level",
> &SV::join_cache_level);
> static sys_var_key_buffer_size sys_key_buffer_size(&vars, "key_buffer_size");
> @@ -4052,7 +4055,7 @@
> sys_var_thd_optimizer_switch::
> symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
> {
> - char buff[STRING_BUFFER_USUAL_SIZE*8];
> + char buff[STRING_BUFFER_USUAL_SIZE*18];
> String tmp(buff, sizeof(buff), &my_charset_latin1);
> int i;
> ulonglong bit;
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/sql_class.h maria-5.3-mwl128-noc/sql/sql_class.h
> --- maria-5.3-mwl128-clean/sql/sql_class.h 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/sql_class.h 2010-11-10 12:09:51.000000000 +0200
> @@ -380,6 +380,7 @@
> ulonglong max_heap_table_size;
> ulonglong tmp_table_size;
> ulonglong long_query_time;
> + ulonglong join_buff_space_limit;
> ha_rows select_limit;
> ha_rows max_join_size;
> ulong auto_increment_increment, auto_increment_offset;
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/sql_join_cache.cc maria-5.3-mwl128-noc/sql/sql_join_cache.cc
> --- maria-5.3-mwl128-clean/sql/sql_join_cache.cc 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/sql_join_cache.cc 2010-11-10 12:09:51.000000000 +0200
> @@ -57,7 +57,7 @@
> The function ignores the fields 'blob_length' and 'ofset' of the
> descriptor.
>
> - RETURN
> + RETURN VALUE
> the length of the field
> */
>
> @@ -98,7 +98,7 @@
> descriptor while 'descr_ptr' points to the position right after the
> last added pointer.
>
> - RETURN
> + RETURN VALUE
> the total length of the added fields
> */
>
> @@ -137,7 +137,44 @@
> *descr_ptr= copy_ptr;
> return len;
> }
> -
> +
> +/*
> + Get the next table whose records are stored in the join buffer of this cache
> +
> + SYNOPSIS
> + get_next_table()
> + tab the table for which the next table is to be returned
> +
> + DESCRIPTION
> + For a given table whose records are stored in this cache the function
> + returns the next such table if there is any.
> + The function takes into account that the tables whose records are
> + are stored in the same cache now can interleave with tables from
> + materialized semijoin subqueries.
> +
> + TODO
> + This function should be modified/simplified after the new code for
> + materialized semijoins is merged.
> +
> + RETURN
> + The next join table whose records are stored in the buffer of this cache
> + if such table exists, 0 - otherwise
> +*/
> +
> +JOIN_TAB *JOIN_CACHE::get_next_table(JOIN_TAB *tab)
> +{
> +
> + if (++tab == join_tab)
> + return NULL;
> + if (join_tab->first_sjm_sibling)
> + return tab;
> + uint i= tab-join->join_tab;
> + while (sj_is_materialize_strategy(join->best_positions[i].sj_strategy) &&
> + i < join->tables)
> + i+= join->best_positions[i].n_sj_tables;
> + return join->join_tab+i < join_tab ? join->join_tab+i : NULL;
> +}
> +
>
> /*
> Determine different counters of fields associated with a record in the cache
> @@ -152,14 +189,16 @@
> The function sets 'with_match_flag' on if 'join_tab' needs a match flag
> i.e. if it is the first inner table of an outer join or a semi-join.
>
> - RETURN
> + RETURN VALUE
> none
> */
>
> void JOIN_CACHE::calc_record_fields()
> {
> JOIN_TAB *tab = prev_cache ? prev_cache->join_tab :
> - join->join_tab+join->const_tables;
> + (join_tab->first_sjm_sibling ?
> + join_tab->first_sjm_sibling :
> + join->join_tab+join->const_tables);
> tables= join_tab-tab;
>
> fields= 0;
> @@ -169,9 +208,9 @@
> data_field_ptr_count= 0;
> referenced_fields= 0;
>
> - for ( ; tab < join_tab ; tab++)
> + for ( ; tab ; tab= get_next_table(tab))
> {
> - calc_used_field_length(join->thd, tab);
> + tab->calc_used_field_length(FALSE);
> flag_fields+= test(tab->used_null_fields || tab->used_uneven_bit_fields);
> flag_fields+= test(tab->table->maybe_null);
> fields+= tab->used_fields;
> @@ -184,6 +223,73 @@
> fields+= flag_fields;
> }
>
> +
> +/*
> + Collect information on join key arguments
> +
> + SYNOPSIS
> + collect_info_on_key_args()
> +
> + DESCRIPTION
> + The function traverses the ref expressions that are used to access the
> + joined table join_tab. For each table 'tab' whose fields are to be stored
> + in the join buffer of the cache the function finds the fields from 'tab'
> + that occur in the ref expressions and marks these fields in the bitmap
> + tab->table->tmp_set. The function counts the number of them stored
> + in this cache and the total number of them stored in the previous caches
> + and saves the results of the counting in 'local_key_arg_fields' and 'external_key_arg_fields' respectively.
> +
> + NOTES
> + The function does not do anything if no key is used to join the records
> + from join_tab.
> +
> + RETURN VALUE
> + none
> +*/
> +
> +void JOIN_CACHE::collect_info_on_key_args()
> +{
> + JOIN_TAB *tab;
> + JOIN_CACHE *cache;
> + local_key_arg_fields= 0;
> + external_key_arg_fields= 0;
> +
> + if (!is_key_access())
> + return;
> +
> + TABLE_REF *ref= &join_tab->ref;
> + cache= this;
> + do
> + {
> + for (tab= cache->join_tab-cache->tables; tab ;
> + tab= cache->get_next_table(tab))
> + {
> + uint key_args;
> + bitmap_clear_all(&tab->table->tmp_set);
> + for (uint i= 0; i < ref->key_parts; i++)
> + {
> + Item *ref_item= ref->items[i];
> + if (!(tab->table->map & ref_item->used_tables()))
> + continue;
> + ref_item->walk(&Item::add_field_to_set_processor, 1,
> + (uchar *) tab->table);
> + }
> + if ((key_args= bitmap_bits_set(&tab->table->tmp_set)))
> + {
> + if (cache == this)
> + local_key_arg_fields+= key_args;
> + else
> + external_key_arg_fields+= key_args;
> + }
> + }
> + cache= cache->prev_cache;
> + }
> + while (cache);
> +
> + return;
> +}
> +
> +
> /*
> Allocate memory for descriptors and pointers to them associated with the cache
>
> @@ -195,23 +301,22 @@
> and the array of pointers to the field descriptors used to copy
> join record data from record buffers into the join buffer and
> backward. Some pointers refer to the field descriptor associated
> - with previous caches. They are placed at the beginning of the
> - array of pointers and its total number is specified by the parameter
> - 'external fields'.
> - The pointer of the first array is assigned to field_descr and the
> - number of elements is precalculated by the function calc_record_fields.
> + with previous caches. They are placed at the beginning of the array
> + of pointers and its total number is stored in external_key_arg_fields.
> + The pointer of the first array is assigned to field_descr and the number
> + of the elements in it is precalculated by the function calc_record_fields.
> The allocated arrays are adjacent.
>
> NOTES
> The memory is allocated in join->thd->memroot
>
> - RETURN
> + RETURN VALUE
> pointer to the first array
> */
>
> -int JOIN_CACHE::alloc_fields(uint external_fields)
> +int JOIN_CACHE::alloc_fields()
> {
> - uint ptr_cnt= external_fields+blobs+1;
> + uint ptr_cnt= external_key_arg_fields+blobs+1;
> uint fields_size= sizeof(CACHE_FIELD)*fields;
> field_descr= (CACHE_FIELD*) sql_alloc(fields_size +
> sizeof(CACHE_FIELD*)*ptr_cnt);
> @@ -219,6 +324,7 @@
> return (field_descr == NULL);
> }
>
> +
> /*
> Create descriptors of the record flag fields stored in the join buffer
>
> @@ -252,7 +358,7 @@
> The function sets the value of 'length' to the total length of the
> flag fields.
>
> - RETURN
> + RETURN VALUE
> none
> */
>
> @@ -272,7 +378,7 @@
> ©);
>
> /* Create fields for all null bitmaps and null row flags that are needed */
> - for (tab= join_tab-tables; tab < join_tab; tab++)
> + for (tab= join_tab-tables; tab; tab= get_next_table(tab))
> {
> TABLE *table= tab->table;
>
> @@ -295,17 +401,145 @@
>
>
> /*
> + Create descriptors of the fields used to build access keys to the joined table
> +
> + SYNOPSIS
> + create_key_arg_fields()
> +
> + DESCRIPTION
> + The function creates descriptors of the record fields stored in the join
> + buffer that are used to build access keys to the joined table. These
> + fields are put into the buffer ahead of other records fields stored in
> + the buffer. Such placement helps to optimize construction of access keys.
> + For each field that is used to build access keys to the joined table but
> + is stored in some other join cache buffer the function saves a pointer
> + to the the field descriptor. The array of such pointers are placed in the
> + the join cache structure just before the array of pointers to the
> + blob fields blob_ptr.
> + Any field stored in a join cache buffer that is used to construct keys
> + to access tables associated with other join caches is called a referenced
> + field. It receives a unique number that is saved by the function in the
> + member 'referenced_field_no' of the CACHE_FIELD descriptor for the field.
> + This number is used as index to the array of offsets to the referenced
> + fields that are saved and put in the join cache buffer after all record
> + fields.
> + The function also finds out whether that the keys to access join_tab
> + can be considered as embedded and, if so, sets the flag 'use_emb_key' in
> + this join cache appropriately.
> +
> + NOTES.
> + When a key to access the joined table 'join_tab' is constructed the array
> + of pointers to the field descriptors for the external fields is looked
> + through. For each of this pointers we find out in what previous key cache
> + the referenced field is stored. The value of 'referenced_field_no'
> + provides us with the index into the array of offsets for referenced
> + fields stored in the join cache. The offset read by the the index allows
> + us to read the field without reading all other fields of the record
> + stored the join cache buffer. This optimizes the construction of keys
> + to access 'join_tab' when some key arguments are stored in the previous
> + join caches.
> +
> + NOTES
> + The function does not do anything if no key is used to join the records
> + from join_tab.
> +
> + RETURN VALUE
> + none
> +*/
> +void JOIN_CACHE::create_key_arg_fields()
> +{
> + JOIN_TAB *tab;
> + JOIN_CACHE *cache;
> +
> + if (!is_key_access())
> + return;
> +
> + /*
> + Save pointers to the cache fields in previous caches
> + that are used to build keys for this key access.
> + */
> + cache= this;
> + uint ext_key_arg_cnt= external_key_arg_fields;
> + CACHE_FIELD *copy;
> + CACHE_FIELD **copy_ptr= blob_ptr;
> + while (ext_key_arg_cnt)
> + {
> + cache= cache->prev_cache;
> + for (tab= cache->join_tab-cache->tables; tab;
> + tab= cache->get_next_table(tab))
> + {
> + CACHE_FIELD *copy_end;
> + MY_BITMAP *key_read_set= &tab->table->tmp_set;
> + /* key_read_set contains the bitmap of tab's fields referenced by ref */
> + if (bitmap_is_clear_all(key_read_set))
> + continue;
> + copy_end= cache->field_descr+cache->fields;
> + for (copy= cache->field_descr+cache->flag_fields; copy < copy_end; copy++)
> + {
> + /*
> + (1) - when we store rowids for DuplicateWeedout, they have
> + copy->field==NULL
> + */
> + if (copy->field && // (1)
> + copy->field->table == tab->table &&
> + bitmap_is_set(key_read_set, copy->field->field_index))
> + {
> + *copy_ptr++= copy;
> + ext_key_arg_cnt--;
> + if (!copy->referenced_field_no)
> + {
> + /*
> + Register the referenced field 'copy':
> + - set the offset number in copy->referenced_field_no,
> + - adjust the value of the flag 'with_length',
> + - adjust the values of 'pack_length' and
> + of 'pack_length_with_blob_ptrs'.
> + */
> + copy->referenced_field_no= ++cache->referenced_fields;
> + if (!cache->with_length)
> + {
> + cache->with_length= TRUE;
> + uint sz= cache->get_size_of_rec_length();
> + cache->base_prefix_length+= sz;
> + cache->pack_length+= sz;
> + cache->pack_length_with_blob_ptrs+= sz;
> + }
> + cache->pack_length+= cache->get_size_of_fld_offset();
> + cache->pack_length_with_blob_ptrs+= cache->get_size_of_fld_offset();
> + }
> + }
> + }
> + }
> + }
> + /* After this 'blob_ptr' shall not be be changed */
> + blob_ptr= copy_ptr;
> +
> + /* Now create local fields that are used to build ref for this key access */
> + copy= field_descr+flag_fields;
> + for (tab= join_tab-tables; tab; tab= get_next_table(tab))
> + {
> + length+= add_table_data_fields_to_join_cache(tab, &tab->table->tmp_set,
> + &data_field_count, ©,
> + &data_field_ptr_count,
> + ©_ptr);
> + }
> +
> + use_emb_key= check_emb_key_usage();
> +
> + return;
> +}
> +
> +
> +/*
> Create descriptors of all remaining data fields stored in the join buffer
>
> SYNOPSIS
> create_remaining_fields()
> - all_read_fields indicates that descriptors for all read data fields
> - are to be created
>
> DESCRIPTION
> The function creates descriptors for all remaining data fields of a
> - record from the join buffer. If the parameter 'all_read_fields' is
> - true the function creates fields for all read record fields that
> + record from the join buffer. If the value returned by is_key_access() is
> + false the function creates fields for all read record fields that
> comprise the partial join record joined with join_tab. Otherwise,
> for each table tab, the set of the read fields for which the descriptors
> have to be added is determined as the difference between all read fields
> @@ -315,7 +549,7 @@
> the added fields.
>
> NOTES
> - If 'all_read_fields' is false the function modifies the value of
> + If is_key_access() returns true the function modifies the value of
> tab->table->tmp_set for a each table whose fields are stored in the cache.
> The function calls the method Field::fill_cache_field to figure out
> the type of the cache field and the maximal length of its representation
> @@ -327,17 +561,18 @@
> contains the number of the pointers to such descriptors having been
> stored up to the moment.
>
> - RETURN
> + RETURN VALUE
> none
> */
>
> -void JOIN_CACHE:: create_remaining_fields(bool all_read_fields)
> +void JOIN_CACHE:: create_remaining_fields()
> {
> JOIN_TAB *tab;
> + bool all_read_fields= !is_key_access();
> CACHE_FIELD *copy= field_descr+flag_fields+data_field_count;
> CACHE_FIELD **copy_ptr= blob_ptr+data_field_ptr_count;
>
> - for (tab= join_tab-tables; tab < join_tab; tab++)
> + for (tab= join_tab-tables; tab; tab= get_next_table(tab))
> {
> MY_BITMAP *rem_field_set;
> TABLE *table= tab->table;
> @@ -372,6 +607,7 @@
> }
>
>
> +
> /*
> Calculate and set all cache constants
>
> @@ -389,7 +625,7 @@
> making a dicision whether more records should be added into the join
> buffer or not.
>
> - RETURN
> + RETURN VALUE
> none
> */
>
> @@ -424,6 +660,8 @@
> size_of_rec_ofs= offset_size(buff_size);
> size_of_rec_len= blobs ? size_of_rec_ofs : offset_size(len);
> size_of_fld_ofs= size_of_rec_len;
> + base_prefix_length= (with_length ? size_of_rec_len : 0) +
> + (prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
> /*
> The size of the offsets for referenced fields will be added later.
> The values of 'pack_length' and 'pack_length_with_blob_ptrs' are adjusted
> @@ -437,65 +675,322 @@
>
>
> /*
> + Get maximum total length of all affixes of a record in the join cache buffer
psergey: I bet that if we make a poll among the receivers of commits@ emails,
we'll find out that more than half do not know what "affix" is. It's ok to use
the term, but please add an expanation.
> +
> + SYNOPSIS
> + get_record_max_affix_length()
> +
> + DESCRIPTION
> + The function calculates the maximum possible total length of all affixes
> + of a record in the join cache buffer, that is made of:
> + - the length of all prefixes used in this cache,
> + - the length of the match flag if it's needed
> + - the total length of the maximum possible offsets to the fields of
> + a record in the buffer.
> +
> + RETURN VALUE
> + The maximum total length of all affixes of a record in the join buffer
> +*/
> +
> +uint JOIN_CACHE::get_record_max_affix_length()
> +{
> + uint len= get_prefix_length() +
> + test(with_match_flag) +
> + size_of_fld_ofs * data_field_count;
> + return len;
> +}
> +
> +
> +/*
> + Get the minimum possible size of the cache join buffer
> +
> + SYNOPSIS
> + get_min_join_buffer_size()
> +
> + DESCRIPTION
> + At the first its invocation for the cache the function calculates the
> + minimum possible size of the join buffer of the cache. This value depends
> + on the minimal number of records 'min_records' to be stored in the join
> + buffer. The number is supposed to be determined by the procedure that
> + chooses the best access path to the joined table join_tab in the execution
> + plan. After the calculation of the interesting size the function saves it
> + in the field 'min_buff_size' in order to use it directly at the next
> + invocations of the function.
> +
> + NOTES
> + Currently the number of minimal records is just set to 1.
> +
> + RETURN VALUE
> + The minimal possible size of the join buffer of this cache
> +*/
> +
> +ulong JOIN_CACHE::get_min_join_buffer_size()
> +{
> + if (!min_buff_size)
> + {
> + ulong len= 0;
> + for (JOIN_TAB *tab= join_tab-tables; tab < join_tab; tab++)
> + len+= tab->get_max_used_fieldlength();
> + len+= get_record_max_affix_length() + get_max_key_addon_space_per_record();
> + ulong min_sz= len*min_records;
> + ulong add_sz= 0;
> + for (uint i=0; i < min_records; i++)
> + add_sz+= join_tab_scan->aux_buffer_incr(i+1);
> + avg_aux_buffer_incr= add_sz/min_records;
> + min_sz+= add_sz;
> + min_sz+= pack_length_with_blob_ptrs;
> + min_buff_size= min_sz;
> + }
> + return min_buff_size;
> +}
> +
> +
> +/*
> + Get the maximum possible size of the cache join buffer
> +
> + SYNOPSIS
> + get_max_join_buffer_size()
> +
> + DESCRIPTION
> + At the first its invocation for the cache the function calculates the
> + maximum possible size of join buffer for the cache. This value does not
> + exceed the estimate of the number of records 'max_records' in the partial
> + join that joins tables from the first one through join_tab. This value
> + is also capped off by the value of join_tab->join_buffer_size_limit, if it
> + has been set a to non-zero value, and by the value of the system parameter
> + join_buffer_size - otherwise. After the calculation of the interesting size
> + the function saves the value in the field 'max_buff_size' in order to use
> + it directly at the next invocations of the function.
> +
> + NOTES
> + Currently the value of join_tab->join_buffer_size_limit is initialized
> + to 0 and is never reset.
> +
> + RETURN VALUE
> + The maximum possible size of the join buffer of this cache
> +*/
> +
> +ulong JOIN_CACHE::get_max_join_buffer_size()
> +{
> + if (!max_buff_size)
> + {
> + ulong max_sz;
> + ulong min_sz= get_min_join_buffer_size();
> + ulong len= 0;
> + for (JOIN_TAB *tab= join_tab-tables; tab < join_tab; tab++)
> + len+= tab->get_used_fieldlength();
> + len+= get_record_max_affix_length();
> + avg_record_length= len;
> + len+= get_max_key_addon_space_per_record() + avg_aux_buffer_incr;
> + space_per_record= len;
> +
> + ulong limit_sz= join->thd->variables.join_buff_size;
> + if (join_tab->join_buffer_size_limit)
> + set_if_smaller(limit_sz, join_tab->join_buffer_size_limit);
> + if (limit_sz / max_records > space_per_record)
> + max_sz= space_per_record * max_records;
> + else
> + max_sz= limit_sz;
> + max_sz+= pack_length_with_blob_ptrs;
> + set_if_smaller(max_sz, limit_sz);
> + set_if_bigger(max_sz, min_sz);
> + max_buff_size= max_sz;
> + }
> + return max_buff_size;
> +}
> +
> +
> +/*
> Allocate memory for a join buffer
>
> SYNOPSIS
> alloc_buffer()
>
> DESCRIPTION
> - The function allocates a lump of memory for the cache join buffer. The
> - size of the allocated memory is 'buff_size' bytes.
> + The function allocates a lump of memory for the cache join buffer.
> + Initially the function sets the size of the buffer buff_size equal to
> + the value returned by get_max_join_buffer_size(). If the total size of
> + the space intended to be used for the join buffers employed by the
> + tables from the first one through join_tab exceeds the value of the
> + system parameter join_buff_space_limit, then the function first tries
> + to shrink the used buffers to make the occupied space fit the maximum
> + memory allowed to be used for all join buffers in total. After
> + this the function tries to allocate a join buffer for join_tab.
> + If it fails to do so, it decrements the requested size of the join
> + buffer, shrinks proportionally the join buffers used for the previous
> + tables and tries to allocate a buffer for join_tab. In the case of a
> + failure the function repeats its attempts with smaller and smaller
> + requested sizes of the buffer, but not more than 4 times.
>
> - RETURN
> - 0 - if the memory has been successfully allocated
> - 1 - otherwise
> + RETURN VALUE
> + 0 if the memory has been successfully allocated
> + 1 otherwise
> */
>
> int JOIN_CACHE::alloc_buffer()
> {
> - buff= (uchar*) my_malloc(buff_size, MYF(0));
> - return buff == NULL;
> -}
> + JOIN_TAB *tab;
> + JOIN_CACHE *cache;
> + ulonglong curr_buff_space_sz= 0;
> + ulonglong curr_min_buff_space_sz= 0;
> + ulonglong join_buff_space_limit=
> + join->thd->variables.join_buff_space_limit;
> + double partial_join_cardinality= (join_tab-1)->get_partial_join_cardinality();
> + buff= NULL;
> + min_buff_size= 0;
> + max_buff_size= 0;
> + min_records= 1;
> + max_records= partial_join_cardinality <= join_buff_space_limit ?
> + (ulonglong) partial_join_cardinality : join_buff_space_limit;
> + set_if_bigger(max_records, 10);
> + min_buff_size= get_min_join_buffer_size();
> + buff_size= get_max_join_buffer_size();
> + for (tab= join->join_tab+join->const_tables; tab <= join_tab; tab++)
> + {
> + cache= tab->cache;
> + if (cache)
> + {
> + curr_min_buff_space_sz+= cache->get_min_join_buffer_size();
> + curr_buff_space_sz+= cache->get_join_buffer_size();
> + }
> + }
> +
> + if (curr_min_buff_space_sz > join_buff_space_limit ||
> + (curr_buff_space_sz > join_buff_space_limit &&
> + join->shrink_join_buffers(join_tab, curr_buff_space_sz,
> + join_buff_space_limit)))
> + goto fail;
> +
> + for (ulong buff_size_decr= (buff_size-min_buff_size)/4 + 1; ; )
> + {
> + ulong next_buff_size;
> +
> + if ((buff= (uchar*) my_malloc(buff_size, MYF(0))))
> + break;
> +
> + next_buff_size= buff_size > buff_size_decr ? buff_size-buff_size_decr : 0;
> + if (next_buff_size < min_buff_size ||
> + join->shrink_join_buffers(join_tab, curr_buff_space_sz,
> + curr_buff_space_sz-buff_size_decr))
> + goto fail;
> + buff_size= next_buff_size;
> +
> + curr_buff_space_sz= 0;
> + for (tab= join->join_tab+join->const_tables; tab <= join_tab; tab++)
> + {
> + cache= tab->cache;
> + if (cache)
> + curr_buff_space_sz+= cache->get_join_buffer_size();
> + }
> + }
> + return 0;
> +
> +fail:
> + buff_size= 0;
> + return 1;
> +}
> +
> +
> +/*
> + Shrink the size if the cache join buffer in a given ratio
> +
> + SYNOPSIS
> + shrink_join_buffer_in_ratio()
> + n nominator of the ratio to shrink the buffer in
> + d denominator if the ratio
> +
> + DESCRIPTION
> + The function first deallocates the join buffer of the cache. Then
> + it allocates a buffer that is (n/d) times smaller.
> +
> + RETURN VALUE
> + FALSE on success with allocation of the smaller join buffer
> + TRUE otherwise
> +*/
> +
> +bool JOIN_CACHE::shrink_join_buffer_in_ratio(ulonglong n, ulonglong d)
> +{
> + ulonglong next_buff_size;
> + if (n < d)
> + return FALSE;
> + next_buff_size= (ulonglong) ((double) buff_size / n * d);
> + set_if_bigger(next_buff_size, min_buff_size);
> + buff_size= next_buff_size;
> + return realloc_buffer();
> +}
> +
> +
> +/*
> + Reallocate the join buffer of a join cache
> +
> + SYNOPSIS
> + realloc_buffer()
> +
> + DESCRITION
> + The function reallocates the join buffer of the join cache. After this
> + it resets the buffer for writing.
> +
> + NOTES
> + The function assumes that buff_size contains the new value for the join
> + buffer size.
> +
> + RETURN VALUE
> + 0 if the buffer has been successfully reallocated
> + 1 otherwise
> +*/
> +
> +int JOIN_CACHE::realloc_buffer()
> +{
> + int rc;
> + free();
> + rc= test(!(buff= (uchar*) my_malloc(buff_size, MYF(0))));
> + reset(TRUE);
> + return rc;
> +}
>
>
> /*
> - Initialize a BNL cache
> + Initialize a join cache
>
> SYNOPSIS
> init()
>
> DESCRIPTION
> - The function initializes the cache structure. It supposed to be called
> - right after a constructor for the JOIN_CACHE_BNL.
> + The function initializes the join cache structure. It supposed to be called
> + by init methods for classes derived from the JOIN_CACHE.
> The function allocates memory for the join buffer and for descriptors of
> the record fields stored in the buffer.
>
> NOTES
> The code of this function should have been included into the constructor
> - code itself. However the new operator for the class JOIN_CACHE_BNL would
> + code itself. However the new operator for the class JOIN_CACHE would
> never fail while memory allocation for the join buffer is not absolutely
> unlikely to fail. That's why this memory allocation has to be placed in a
> separate function that is called in a couple with a cache constructor.
> It is quite natural to put almost all other constructor actions into
> this function.
>
> - RETURN
> + RETURN VALUE
> 0 initialization with buffer allocations has been succeeded
> 1 otherwise
> */
>
> -int JOIN_CACHE_BNL::init()
> +int JOIN_CACHE::init()
> {
> DBUG_ENTER("JOIN_CACHE::init");
>
> calc_record_fields();
>
> - if (alloc_fields(0))
> + collect_info_on_key_args();
> +
> + if (alloc_fields())
> DBUG_RETURN(1);
>
> create_flag_fields();
> -
> - create_remaining_fields(TRUE);
> +
> + create_key_arg_fields();
> +
> + create_remaining_fields();
>
> set_constants();
>
> @@ -509,166 +1004,9 @@
>
>
> /*
> - Initialize a BKA cache
> -
> + Check the possibility to read the access keys directly from the join buffer
> SYNOPSIS
> - init()
> -
> - DESCRIPTION
> - The function initializes the cache structure. It supposed to be called
> - right after a constructor for the JOIN_CACHE_BKA.
> - The function allocates memory for the join buffer and for descriptors of
> - the record fields stored in the buffer.
> -
> - NOTES
> - The code of this function should have been included into the constructor
> - code itself. However the new operator for the class JOIN_CACHE_BKA would
> - never fail while memory allocation for the join buffer is not absolutely
> - unlikely to fail. That's why this memory allocation has to be placed in a
> - separate function that is called in a couple with a cache constructor.
> - It is quite natural to put almost all other constructor actions into
> - this function.
> -
> - RETURN
> - 0 initialization with buffer allocations has been succeeded
> - 1 otherwise
> -*/
> -
> -int JOIN_CACHE_BKA::init()
> -{
> - JOIN_TAB *tab;
> - JOIN_CACHE *cache;
> - local_key_arg_fields= 0;
> - external_key_arg_fields= 0;
> - DBUG_ENTER("JOIN_CACHE_BKA::init");
> -
> - calc_record_fields();
> -
> - /* Mark all fields that can be used as arguments for this key access */
> - TABLE_REF *ref= &join_tab->ref;
> - cache= this;
> - do
> - {
> - /*
> - Traverse the ref expressions and find the occurrences of fields in them for
> - each table 'tab' whose fields are to be stored in the 'cache' join buffer.
> - Mark these fields in the bitmap tab->table->tmp_set.
> - For these fields count the number of them stored in this cache and the
> - total number of them stored in the previous caches. Save the result
> - of the counting 'in local_key_arg_fields' and 'external_key_arg_fields'
> - respectively.
> - */
> - for (tab= cache->join_tab-cache->tables; tab < cache->join_tab ; tab++)
> - {
> - uint key_args;
> - bitmap_clear_all(&tab->table->tmp_set);
> - for (uint i= 0; i < ref->key_parts; i++)
> - {
> - Item *ref_item= ref->items[i];
> - if (!(tab->table->map & ref_item->used_tables()))
> - continue;
> - ref_item->walk(&Item::add_field_to_set_processor, 1,
> - (uchar *) tab->table);
> - }
> - if ((key_args= bitmap_bits_set(&tab->table->tmp_set)))
> - {
> - if (cache == this)
> - local_key_arg_fields+= key_args;
> - else
> - external_key_arg_fields+= key_args;
> - }
> - }
> - cache= cache->prev_cache;
> - }
> - while (cache);
> -
> - if (alloc_fields(external_key_arg_fields))
> - DBUG_RETURN(1);
> -
> - create_flag_fields();
> -
> - /*
> - Save pointers to the cache fields in previous caches
> - that are used to build keys for this key access.
> - */
> - cache= this;
> - uint ext_key_arg_cnt= external_key_arg_fields;
> - CACHE_FIELD *copy;
> - CACHE_FIELD **copy_ptr= blob_ptr;
> - while (ext_key_arg_cnt)
> - {
> - cache= cache->prev_cache;
> - for (tab= cache->join_tab-cache->tables; tab < cache->join_tab ; tab++)
> - {
> - CACHE_FIELD *copy_end;
> - MY_BITMAP *key_read_set= &tab->table->tmp_set;
> - /* key_read_set contains the bitmap of tab's fields referenced by ref */
> - if (bitmap_is_clear_all(key_read_set))
> - continue;
> - copy_end= cache->field_descr+cache->fields;
> - for (copy= cache->field_descr+cache->flag_fields; copy < copy_end; copy++)
> - {
> - /*
> - (1) - when we store rowids for DuplicateWeedout, they have
> - copy->field==NULL
> - */
> - if (copy->field && // (1)
> - copy->field->table == tab->table &&
> - bitmap_is_set(key_read_set, copy->field->field_index))
> - {
> - *copy_ptr++= copy;
> - ext_key_arg_cnt--;
> - if (!copy->referenced_field_no)
> - {
> - /*
> - Register the referenced field 'copy':
> - - set the offset number in copy->referenced_field_no,
> - - adjust the value of the flag 'with_length',
> - - adjust the values of 'pack_length' and
> - of 'pack_length_with_blob_ptrs'.
> - */
> - copy->referenced_field_no= ++cache->referenced_fields;
> - cache->with_length= TRUE;
> - cache->pack_length+= cache->get_size_of_fld_offset();
> - cache->pack_length_with_blob_ptrs+= cache->get_size_of_fld_offset();
> - }
> - }
> - }
> - }
> - }
> - /* After this 'blob_ptr' shall not be be changed */
> - blob_ptr= copy_ptr;
> -
> - /* Now create local fields that are used to build ref for this key access */
> - copy= field_descr+flag_fields;
> - for (tab= join_tab-tables; tab < join_tab ; tab++)
> - {
> - length+= add_table_data_fields_to_join_cache(tab, &tab->table->tmp_set,
> - &data_field_count, ©,
> - &data_field_ptr_count,
> - ©_ptr);
> - }
> -
> - use_emb_key= check_emb_key_usage();
> -
> - create_remaining_fields(FALSE);
> -
> - set_constants();
> -
> - if (alloc_buffer())
> - DBUG_RETURN(1);
> -
> - reset(TRUE);
> -
> - DBUG_RETURN(0);
> -}
> -
> -
> -/*
> - Check the possibility to read the access keys directly from the join buffer
> -
> - SYNOPSIS
> - check_emb_key_usage()
> + check_emb_key_usage()
>
> DESCRIPTION
> The function checks some conditions at which the key values can be read
> @@ -693,13 +1031,21 @@
> we still do not consider them embedded. In the future we'll expand the
> the class of keys which we identify as embedded.
>
> - RETURN
> - TRUE - key values will be considered as embedded,
> - FALSE - otherwise.
> + NOTES
> + The function returns FALSE if no key is used to join the records
> + from join_tab.
> +
> + RETURN VALUE
> + TRUE key values will be considered as embedded,
> + FALSE otherwise.
> */
>
> -bool JOIN_CACHE_BKA::check_emb_key_usage()
> +bool JOIN_CACHE::check_emb_key_usage()
> {
> +
> + if (!is_key_access())
> + return FALSE;
> +
> uint i;
> Item *item;
> KEY_PART_INFO *key_part;
> @@ -800,110 +1146,6 @@
>
>
> /*
> - Calculate the increment of the MRR buffer for a record write
> -
> - SYNOPSIS
> - aux_buffer_incr()
> -
> - DESCRIPTION
> - This implementation of the virtual function aux_buffer_incr determines
> - for how much the size of the MRR buffer should be increased when another
> - record is added to the cache.
> -
> - RETURN
> - the increment of the size of the MRR buffer for the next record
> -*/
> -
> -uint JOIN_CACHE_BKA::aux_buffer_incr()
> -{
> - uint incr= 0;
> - TABLE_REF *ref= &join_tab->ref;
> - TABLE *tab= join_tab->table;
> - uint rec_per_key= tab->key_info[ref->key].rec_per_key[ref->key_parts-1];
> - set_if_bigger(rec_per_key, 1);
> - if (records == 1)
> - incr= ref->key_length + tab->file->ref_length;
> - incr+= tab->file->stats.mrr_length_per_rec * rec_per_key;
> - return incr;
> -}
> -
> -
> -/*
> - Check if the record combination matches the index condition
> -
> - SYNOPSIS
> - JOIN_CACHE_BKA::skip_index_tuple()
> - rseq Value returned by bka_range_seq_init()
> - range_info MRR range association data
> -
> - DESCRIPTION
> - This function is invoked from MRR implementation to check if an index
> - tuple matches the index condition. It is used in the case where the index
> - condition actually depends on both columns of the used index and columns
> - from previous tables.
> -
> - Accessing columns of the previous tables requires special handling with
> - BKA. The idea of BKA is to collect record combinations in a buffer and
> - then do a batch of ref access lookups, i.e. by the time we're doing a
> - lookup its previous-records-combination is not in prev_table->record[0]
> - but somewhere in the join buffer.
> -
> - We need to get it from there back into prev_table(s)->record[0] before we
> - can evaluate the index condition, and that's why we need this function
> - instead of regular IndexConditionPushdown.
> -
> - NOTE
> - Possible optimization:
> - Before we unpack the record from a previous table
> - check if this table is used in the condition.
> - If so then unpack the record otherwise skip the unpacking.
> - This should be done by a special virtual method
> - get_partial_record_by_pos().
> -
> - RETURN
> - 0 The record combination satisfies the index condition
> - 1 Otherwise
> -*/
> -
> -bool JOIN_CACHE_BKA::skip_index_tuple(range_seq_t rseq, char *range_info)
> -{
> - DBUG_ENTER("JOIN_CACHE_BKA::skip_index_tuple");
> - JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
> - cache->get_record_by_pos((uchar*)range_info);
> - DBUG_RETURN(!join_tab->cache_idx_cond->val_int());
> -}
> -
> -
> -/*
> - Check if the record combination matches the index condition
> -
> - SYNOPSIS
> - bka_skip_index_tuple()
> - rseq Value returned by bka_range_seq_init()
> - range_info MRR range association data
> -
> - DESCRIPTION
> - This is wrapper for JOIN_CACHE_BKA::skip_index_tuple method,
> - see comments there.
> -
> - NOTE
> - This function is used as a RANGE_SEQ_IF::skip_index_tuple callback.
> -
> - RETURN
> - 0 The record combination satisfies the index condition
> - 1 Otherwise
> -*/
> -
> -static
> -bool bka_skip_index_tuple(range_seq_t rseq, char *range_info)
> -{
> - DBUG_ENTER("bka_skip_index_tuple");
> - JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
> - DBUG_RETURN(cache->skip_index_tuple(rseq, range_info));
> -}
> -
> -
> -/*
> Write record fields and their required offsets into the join cache buffer
>
> SYNOPSIS
> @@ -942,9 +1184,11 @@
> The 'last_rec_blob_data_is_in_rec_buff' is set on if the blob data
> remains in the record buffers and not copied to the join buffer. It may
> happen only to the blob data from the last record added into the cache.
> -
> -
> - RETURN
> + If on_precond is attached to join_tab and it is not evaluated to TRUE
> + then MATCH_IMPOSSIBLE is placed in the match flag field of the record
> + written into the join buffer.
> +
> + RETURN VALUE
> length of the written record data
> */
>
> @@ -954,16 +1198,18 @@
> bool last_record;
> CACHE_FIELD *copy;
> CACHE_FIELD *copy_end;
> + uchar *flags_pos;
> uchar *cp= pos;
> uchar *init_pos= cp;
> uchar *rec_len_ptr= 0;
> + uint key_extra= extra_key_length();
>
> records++; /* Increment the counter of records in the cache */
>
> - len= pack_length;
> + len= pack_length + key_extra;
>
> /* Make an adjustment for the size of the auxiliary buffer if there is any */
> - uint incr= aux_buffer_incr();
> + uint incr= aux_buffer_incr(records);
> ulong rem= rem_space();
> aux_buff_size+= len+incr < rem ? incr : rem;
>
> @@ -1000,7 +1246,7 @@
> This function is called only in the case when there is enough space left in
> the cache to store at least non-blob parts of the current record.
> */
> - last_record= (len+pack_length_with_blob_ptrs) > rem_space();
> + last_record= (len+pack_length_with_blob_ptrs+key_extra) > rem_space();
>
> /*
> Save the position for the length of the record in the cache if it's needed.
> @@ -1032,6 +1278,7 @@
>
> /* First put into the cache the values of all flag fields */
> copy_end= field_descr+flag_fields;
> + flags_pos= cp;
> for ( ; copy < copy_end; copy++)
> {
> memcpy(cp, copy->str, copy->length);
> @@ -1134,6 +1381,19 @@
> last_rec_pos= curr_rec_pos;
> end_pos= pos= cp;
> *is_full= last_record;
> +
> + last_written_is_null_compl= 0;
> + if (!join_tab->first_unmatched && join_tab->on_precond)
> + {
> + join_tab->found= 0;
> + join_tab->not_null_compl= 1;
> + if (!join_tab->on_precond->val_int())
> + {
> + flags_pos[0]= MATCH_IMPOSSIBLE;
> + last_written_is_null_compl= 1;
> + }
> + }
> +
> return (uint) (cp-init_pos);
> }
>
> @@ -1158,7 +1418,7 @@
> - the size of the auxiliary buffer is reset to 0,
> - the flag 'last_rec_blob_data_is_in_rec_buff' is set to 0.
>
> - RETURN
> + RETURN VALUE
> none
> */
>
> @@ -1176,6 +1436,7 @@
> }
> }
>
> +
> /*
> Add a record into the join buffer: the default implementation
>
> @@ -1190,7 +1451,7 @@
> The implementation assumes that the function get_curr_link()
> will return exactly the pointer to this matched record.
>
> - RETURN
> + RETURN VALUE
> TRUE if it has been decided that it should be the last record
> in the join buffer,
> FALSE otherwise
> @@ -1227,9 +1488,9 @@
> point to the beginning of the first field of the record in the
> join buffer.
>
> - RETURN
> - TRUE - there are no more records to read from the join buffer
> - FALSE - otherwise
> + RETURN VALUE
> + TRUE there are no more records to read from the join buffer
> + FALSE otherwise
> */
>
> bool JOIN_CACHE::get_record()
> @@ -1268,7 +1529,7 @@
> from the the join buffers of the previous caches. The fields are read
> into the corresponding record buffers.
>
> - RETURN
> + RETURN VALUE
> none
> */
>
> @@ -1287,7 +1548,7 @@
>
>
> /*
> - Test the match flag from the referenced record: the default implementation
> + Get the match flag from the referenced record: the default implementation
>
> SYNOPSIS
> get_match_flag_by_pos()
> @@ -1295,30 +1556,55 @@
>
> DESCRIPTION
> This default implementation of the virtual function get_match_flag_by_pos
> - test the match flag for the record pointed by the reference at the position
> - rec_ptr. If the match flag in placed one of the previous buffers the function
> - first reaches the linked record fields in this buffer.
> + get the match flag for the record pointed by the reference at the position
> + rec_ptr. If the match flag is placed in one of the previous buffers the
> + function first reaches the linked record fields in this buffer.
>
> - RETURN
> - TRUE if the match flag is set on
> - FALSE otherwise
> + RETURN VALUE
> + match flag for the record at the position rec_ptr
> */
>
> -bool JOIN_CACHE::get_match_flag_by_pos(uchar *rec_ptr)
> +enum JOIN_CACHE::Match_flag JOIN_CACHE::get_match_flag_by_pos(uchar *rec_ptr)
> {
> + Match_flag match_fl= MATCH_NOT_FOUND;
> if (with_match_flag)
> - return test(*rec_ptr);
> + {
> + match_fl= (enum Match_flag) rec_ptr[0];
> + return match_fl;
> + }
> if (prev_cache)
> {
> uchar *prev_rec_ptr= prev_cache->get_rec_ref(rec_ptr);
> return prev_cache->get_match_flag_by_pos(prev_rec_ptr);
> }
> DBUG_ASSERT(0);
> - return FALSE;
> + return match_fl;
> }
>
>
> /*
> + Calculate the increment of the auxiliary buffer for a record write
> +
> + SYNOPSIS
> + aux_buffer_incr()
> + recno the number of the record the increment to be calculated for
> +
> + DESCRIPTION
> + This function calls the aux_buffer_incr the method of the
> + companion member join_tab_scan to calculate the growth of the
> + auxiliary buffer when the recno-th record is added to the
> + join_buffer of this cache.
> +
> + RETURN VALUE
> + the number of bytes in the increment
> +*/
> +
> +uint JOIN_CACHE::aux_buffer_incr(ulong recno)
> +{
> + return join_tab_scan->aux_buffer_incr(recno);
> +}
> +
> +/*
> Read all flag and data fields of a record from the join buffer
>
> SYNOPSIS
> @@ -1332,8 +1618,8 @@
> The function increments the value of 'pos' by the length of the
> read data.
>
> - RETURN
> - (-1) - if there is no more records in the join buffer
> + RETURN VALUE
> + (-1) if there is no more records in the join buffer
> length of the data read from the join buffer - otherwise
> */
>
> @@ -1371,7 +1657,7 @@
> The function increments the value of 'pos' by the length of the
> read data.
>
> - RETURN
> + RETURN VALUE
> length of the data read from the join buffer
> */
>
> @@ -1380,6 +1666,12 @@
> uchar *init_pos= pos;
> CACHE_FIELD *copy= field_descr;
> CACHE_FIELD *copy_end= copy+flag_fields;
> + if (with_match_flag)
> + {
> + copy->str[0]= test((Match_flag) pos[0] == MATCH_FOUND);
> + pos+= copy->length;
> + copy++;
> + }
> for ( ; copy < copy_end; copy++)
> {
> memcpy(copy->str, pos, copy->length);
> @@ -1406,7 +1698,7 @@
> The function increments the value of 'pos' by the length of the
> read data.
>
> - RETURN
> + RETURN VALUE
> length of the data read from the join buffer
> */
>
> @@ -1486,7 +1778,7 @@
> values. Otherwise *len is supposed to provide this value that
> has been obtained earlier.
>
> - RETURN
> + RETURN VALUE
> TRUE 'copy' points to a data descriptor of this join cache
> FALSE otherwise
> */
> @@ -1530,30 +1822,69 @@
>
>
> /*
> - Skip record from join buffer if its match flag is on: default implementation
> + Skip record from join buffer if's already matched: default implementation
>
> SYNOPSIS
> - skip_record_if_match()
> + skip_if_matched()
>
> DESCRIPTION
> - This default implementation of the virtual function skip_record_if_match
> - skips the next record from the join buffer if its match flag is set on.
> - If the record is skipped the value of 'pos' is set to points to the position
> + This default implementation of the virtual function skip_if_matched
> + skips the next record from the join buffer if its match flag is set to
> + MATCH_FOUND.
> + If the record is skipped the value of 'pos' is set to point to the position
> right after the record.
>
> - RETURN
> - TRUE - the match flag is on and the record has been skipped
> - FALSE - the match flag is off
> + RETURN VALUE
> + TRUE the match flag is set to MATCH_FOUND and the record has been skipped
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE::skip_if_matched()
> +{
> + DBUG_ASSERT(with_length);
> + uint offset= size_of_rec_len;
> + if (prev_cache)
> + offset+= prev_cache->get_size_of_rec_offset();
> + /* Check whether the match flag is MATCH_FOUND */
> + if (get_match_flag_by_pos(pos+offset) == MATCH_FOUND)
> + {
> + pos+= size_of_rec_len + get_rec_length(pos);
> + return TRUE;
> + }
> + return FALSE;
> +}
> +
> +
> +/*
> + Skip record from join buffer if the match isn't needed: default implementation
> +
> + SYNOPSIS
> + skip_if_not_needed_match()
> +
> + DESCRIPTION
> + This default implementation of the virtual function skip_if_not_needed_match
> + skips the next record from the join buffer if its match flag is not
> + MATCH_NOT_FOUND, and, either its value is MATCH_FOUND and join_tab is the
> + first inner table of an inner join, or, its value is MATCH_IMPOSSIBLE
> + and join_tab is the first inner table of an outer join.
> + If the record is skipped the value of 'pos' is set to point to the position
> + right after the record.
> +
> + RETURN VALUE
> + TRUE the record has to be skipped
> + FALSE otherwise
> */
>
> -bool JOIN_CACHE::skip_record_if_match()
> +bool JOIN_CACHE::skip_if_not_needed_match()
> {
> DBUG_ASSERT(with_length);
> + enum Match_flag match_fl;
> uint offset= size_of_rec_len;
> if (prev_cache)
> offset+= prev_cache->get_size_of_rec_offset();
> - /* Check whether the match flag is on */
> - if (get_match_flag_by_pos(pos+offset))
> +
> + if ((match_fl= get_match_flag_by_pos(pos+offset)) != MATCH_NOT_FOUND &&
> + (join_tab->check_only_first_match() == (match_fl == MATCH_FOUND)) )
> {
> pos+= size_of_rec_len + get_rec_length(pos);
> return TRUE;
> @@ -1617,7 +1948,7 @@
> that have matches, after which null complementing extension for all
> unmatched records from the join buffer are generated.
>
> - RETURN
> + RETURN VALUE
> return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
> */
>
> @@ -1711,16 +2042,16 @@
> }
>
>
> -/*
> - Using BNL find matches from the next table for records from the join buffer
> +/*
> + Find matches from the next table for records from the join buffer
>
> SYNOPSIS
> join_matching_records()
> skip_last do not look for matches for the last partial join record
>
> DESCRIPTION
> - The function retrieves all rows of the join_tab table and check whether
> - they match partial join records from the join buffer. If a match is found
> + The function retrieves rows of the join_tab table and checks whether they
> + match partial join records from the join buffer. If a match is found
> the function will call the sub_select function trying to look for matches
> for the remaining join operations.
> This function currently is called only from the function join_records.
> @@ -1729,27 +2060,46 @@
> the future processing in the caller function.
>
> NOTES
> + If employed by BNL or BNLH join algorithms the function performs a full
> + scan of join_tab for each refill of the join buffer. If BKA or BKAH
> + algorithms are used then the function iterates only over those records
> + from join_tab that can be accessed by keys built over records in the join
> + buffer. To apply a proper method of iteration the function just calls
> + virtual iterator methods (open, next, close) of the member join_tab_scan.
> + The member can be either of the JOIN_TAB_SCAN or JOIN_TAB_SCAN_MMR type.
> + The class JOIN_TAB_SCAN provides the iterator methods for BNL/BNLH join
> + algorithms. The class JOIN_TAB_SCAN_MRR provides the iterator methods
> + for BKA/BKAH join algorithms.
> + When the function looks for records from the join buffer that would
> + match a record from join_tab it iterates either over all records in
> + the buffer or only over selected records. If BNL join operation is
> + performed all records are checked for the match. If BNLH or BKAH
> + algorithm is employed to join join_tab then the function looks only
> + through the records with the same join key as the record from join_tab.
> + With the BKA join algorithm only one record from the join buffer is checked
> + for a match for any record from join_tab. To iterate over the candidates
> + for a match the virtual function get_next_candidate_for_match is used,
> + while the virtual function prepare_look_for_matches is called to prepare
> + for such iteration proccess.
> +
> + NOTES
> The function produces all matching extensions for the records in the
> - join buffer following the path of the Blocked Nested Loops algorithm.
> + join buffer following the path of the employed blocked algorithm.
> When an outer join operation is performed all unmatched records from
> the join buffer must be extended by null values. The function
> 'join_null_complements' serves this purpose.
>
> - RETURN
> - return one of enum_nested_loop_state.
> + RETURN VALUE
> + return one of enum_nested_loop_state
> */
>
> -enum_nested_loop_state JOIN_CACHE_BNL::join_matching_records(bool skip_last)
> +enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
> {
> - uint cnt;
> int error;
> - JOIN_TAB *tab;
> - READ_RECORD *info;
> enum_nested_loop_state rc= NESTED_LOOP_OK;
> - bool check_only_first_match= join_tab->check_only_first_match();
> - SQL_SELECT *select= join_tab->cache_select;
> -
> join_tab->table->null_row= 0;
> + bool check_only_first_match= join_tab->check_only_first_match();
> + bool outer_join_first_inner= join_tab->is_first_inner_for_outer_join();
>
> /* Return at once if there are no records in the join buffer */
> if (!records)
> @@ -1771,25 +2121,12 @@
> join_tab->select->quick= 0;
> }
>
> - for (tab= join->join_tab; tab != join_tab ; tab++)
> - {
> - tab->status= tab->table->status;
> - tab->table->status= 0;
> - }
> -
> - /* Start retrieving all records of the joined table */
> - if ((error= join_init_read_record(join_tab)))
> - {
> - rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
> + /* Prepare to retrieve all records of the joined table */
> + if ((error= join_tab_scan->open()))
> goto finish;
> - }
>
> - info= &join_tab->read_record;
> - do
> + while (!(error= join_tab_scan->next()))
> {
> - if (join_tab->keep_current_rowid)
> - join_tab->table->file->position(join_tab->table->record[0]);
> -
> if (join->thd->killed)
> {
> /* The user has aborted the execution of the query */
> @@ -1797,52 +2134,43 @@
> rc= NESTED_LOOP_KILLED;
> goto finish;
> }
> - int err= 0;
> -
> - if (rc == NESTED_LOOP_OK)
> - update_virtual_fields(join->thd, join_tab->table);
> -
> - /*
> - Do not look for matches if the last read record of the joined table
> - does not meet the conditions that have been pushed to this table
> - */
> - if (rc == NESTED_LOOP_OK &&
> - (!select || (err= select->skip_record(join->thd)) != 0))
> - {
> - if (err < 0)
> - return NESTED_LOOP_ERROR;
> - rc= NESTED_LOOP_OK;
>
> - /* Prepare to read records from the join buffer */
> - reset(FALSE);
> -
> - /* Read each record from the join buffer and look for matches */
> - for (cnt= records - test(skip_last) ; cnt; cnt--)
> - {
> - /*
> - If only the first match is needed and it has been already found for
> - the next record read from the join buffer then the record is skipped.
> - */
> - if (!check_only_first_match || !skip_record_if_match())
> - {
> - get_record();
> - rc= generate_full_extensions(get_curr_rec());
> - if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
> - goto finish;
> - }
> + if (join_tab->keep_current_rowid)
> + join_tab->table->file->position(join_tab->table->record[0]);
> +
> + /* Prepare to read matching candidates from the join buffer */
> + if (prepare_look_for_matches(skip_last))
> + continue;
> +
> + uchar *rec_ptr;
> + /* Read each possible candidate from the buffer and look for matches */
> + while ((rec_ptr= get_next_candidate_for_match()))
> + {
> + /*
> + If only the first match is needed, and, it has been already found for
> + the next record read from the join buffer, then the record is skipped.
> + Also those records that must be null complemented are not considered
> + as candidates for matches.
> + */
> + if ((!check_only_first_match && !outer_join_first_inner) ||
> + !skip_next_candidate_for_match(rec_ptr))
> + {
> + read_next_candidate_for_match(rec_ptr);
> + rc= generate_full_extensions(rec_ptr);
> + if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
> + goto finish;
> }
> }
> - } while (!(error= info->read_record(info)));
> + }
>
> - if (error > 0) // Fatal error
> - rc= NESTED_LOOP_ERROR;
> -finish:
> - for (tab= join->join_tab; tab != join_tab ; tab++)
> - tab->table->status= tab->status;
> +finish:
> + if (error)
> + rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
> + join_tab_scan->close();
> return rc;
> }
>
> -
> +
> /*
> Set match flag for a record in join buffer if it has not been set yet
>
> @@ -1862,7 +2190,7 @@
> The function assumes that the match flag for any record in any cache
> is placed in the first byte occupied by the record fields.
>
> - RETURN
> + RETURN VALUE
> TRUE the match flag is set by this call for the first time
> FALSE the match flag has been set before this call
> */
> @@ -1914,7 +2242,7 @@
> case the function calls the join_tab->next_select method to generate
> all full extension for this partial join match.
>
> - RETURN
> + RETURN VALUE
> return one of enum_nested_loop_state.
> */
>
> @@ -1969,7 +2297,7 @@
> Setting the match flag on can trigger re-evaluation of pushdown conditions
> for the record when join_tab is the last inner table of an outer join.
>
> - RETURN
> + RETURN VALUE
> TRUE there is a match
> FALSE there is no match
> */
> @@ -1977,7 +2305,7 @@
> inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
> {
> /* Check whether pushdown conditions are satisfied */
> - if (join_tab->select && join_tab->select->skip_record(join->thd) < 1)
> + if (join_tab->select && join_tab->select->skip_record(join->thd) <= 0)
> return FALSE;
>
> if (!join_tab->is_last_inner_table())
> @@ -2007,7 +2335,7 @@
> */
> for (JOIN_TAB *tab= first_inner; tab <= join_tab; tab++)
> {
> - if (tab->select && tab->select->skip_record(join->thd) < 1)
> + if (tab->select && tab->select->skip_record(join->thd) <= 0)
> return FALSE;
> }
> }
> @@ -2038,9 +2366,9 @@
>
> NOTES
> The same implementation of the virtual method join_null_complements
> - is used for JOIN_CACHE_BNL and JOIN_CACHE_BKA.
> + is used for BNL/BNLH/BKA/BKA join algorthm.
>
> - RETURN
> + RETURN VALUE
> return one of enum_nested_loop_state.
> */
>
> @@ -2049,7 +2377,6 @@
> uint cnt;
> enum_nested_loop_state rc= NESTED_LOOP_OK;
> bool is_first_inner= join_tab == join_tab->first_unmatched;
> - bool is_last_inner= join_tab == join_tab->first_unmatched->last_inner;
>
> /* Return at once if there are no records in the join buffer */
> if (!records)
> @@ -2070,40 +2397,16 @@
> goto finish;
> }
> /* Just skip the whole record if a match for it has been already found */
> - if (!is_first_inner || !skip_record_if_match())
> + if (!is_first_inner || !skip_if_matched())
> {
> get_record();
> /* The outer row is complemented by nulls for each inner table */
> restore_record(join_tab->table, s->default_values);
> mark_as_null_row(join_tab->table);
> - /* Check all pushdown conditions attached to the inner table */
> - join_tab->first_unmatched->found= 1;
> - if (join_tab->select && join_tab->select->skip_record(join->thd) < 1)
> - continue;
> - if (is_last_inner)
> - {
> - JOIN_TAB *first_upper= join_tab->first_unmatched->first_upper;
> - while (first_upper && first_upper->last_inner == join_tab)
> - {
> - set_match_flag_if_none(first_upper, get_curr_rec());
> - for (JOIN_TAB* tab= first_upper; tab <= join_tab; tab++)
> - {
> - if (tab->select && tab->select->skip_record(join->thd) < 1)
> - goto next;
> - }
> - first_upper= first_upper->first_upper;
> - }
> - }
> - /* Find all matches for the remaining join tables */
> - rc= (*join_tab->next_select)(join, join_tab+1, 0);
> + rc= generate_full_extensions(get_curr_rec());
> if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
> - {
> - reset(TRUE);
> goto finish;
> - }
> }
> - next:
> - ;
> }
>
> finish:
> @@ -2112,867 +2415,1692 @@
>
>
> /*
> - Initialize retrieval of range sequence for BKA algorithm
> -
> + Add a comment on the join algorithm employed by the join cache
> +
> SYNOPSIS
> - bka_range_seq_init()
> - init_params pointer to the BKA join cache object
> - n_ranges the number of ranges obtained
> - flags combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
> + print_explain_comment()
> + str string to add the comment on the employed join algorithm to
>
> DESCRIPTION
> - The function interprets init_param as a pointer to a JOIN_CACHE_BKA
> - object. The function prepares for an iteration over the join keys
> - built for all records from the cache join buffer.
> -
> - NOTE
> - This function are used only as a callback function.
> + This function adds info on the type of the used join buffer (flat or
> + incremental) and on the type of the the employed join algorithm (BNL,
> + BNLH, BKA or BKAH) to the the end of the sring str.
>
> - RETURN
> - init_param value that is to be used as a parameter of bka_range_seq_next()
> -*/
> + RETURN VALUE
> + none
> +*/
>
> -static
> -range_seq_t bka_range_seq_init(void *init_param, uint n_ranges, uint flags)
> +void JOIN_CACHE::print_explain_comment(String *str)
> {
> - DBUG_ENTER("bka_range_seq_init");
> - JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) init_param;
> - cache->reset(0);
> - DBUG_RETURN((range_seq_t) init_param);
> -}
> + str->append(STRING_WITH_LEN(" ("));
> + const char *buffer_type= prev_cache ? "incremental" : "flat";
> + str->append(buffer_type);
> + str->append(STRING_WITH_LEN(", "));
> +
> + const char *join_alg;
> + switch (get_join_alg()) {
> + case BNL_JOIN_ALG:
> + join_alg= "BNL";
> + break;
> + case BNLH_JOIN_ALG:
> + join_alg= "BNLH";
> + break;
> + case BKA_JOIN_ALG:
> + join_alg= "BKA";
> + break;
> + case BKAH_JOIN_ALG:
> + join_alg= "BKAH";
> + break;
> + default:
> + DBUG_ASSERT(0);
> + }
> +
> + str->append(join_alg);
> + str->append(STRING_WITH_LEN(" join"));
> + str->append(STRING_WITH_LEN(")"));
> + }
> +
>
> +/*
> + Initialize a hashed join cache
>
> -/*
> - Get the key over the next record from the join buffer used by BKA
> -
> SYNOPSIS
> - bka_range_seq_next()
> - seq the value returned by bka_range_seq_init
> - range OUT reference to the next range
> -
> + init()
> +
> DESCRIPTION
> - The function interprets seq as a pointer to a JOIN_CACHE_BKA
> - object. The function returns a pointer to the range descriptor
> - for the key built over the next record from the join buffer.
> + The function initializes the cache structure with a hash table in it.
> + The hash table will be used to store key values for the records from
> + the join buffer.
> + The function allocates memory for the join buffer and for descriptors of
> + the record fields stored in the buffer.
> + The function also initializes a hash table for record keys within the join
> + buffer space.
>
> - NOTE
> - This function are used only as a callback function.
> -
> - RETURN
> - 0 ok, the range structure filled with info about the next key
> - 1 no more ranges
> -*/
> + NOTES VALUE
> + The function is supposed to be called by the init methods of the classes
> + derived from JOIN_CACHE_HASHED.
> +
> + RETURN VALUE
> + 0 initialization with buffer allocations has been succeeded
> + 1 otherwise
> +*/
>
> -static
> -uint bka_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
> +int JOIN_CACHE_HASHED::init()
> {
> - DBUG_ENTER("bka_range_seq_next");
> - JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
> - TABLE_REF *ref= &cache->join_tab->ref;
> - key_range *start_key= &range->start_key;
> - if ((start_key->length= cache->get_next_key((uchar **) &start_key->key)))
> - {
> - start_key->keypart_map= (1 << ref->key_parts) - 1;
> - start_key->flag= HA_READ_KEY_EXACT;
> - range->end_key= *start_key;
> - range->end_key.flag= HA_READ_AFTER_KEY;
> - range->ptr= (char *) cache->get_curr_rec();
> - range->range_flag= EQ_RANGE;
> - DBUG_RETURN(0);
> - }
> - DBUG_RETURN(1);
> -}
> + int rc= 0;
> + TABLE_REF *ref= &join_tab->ref;
>
> + DBUG_ENTER("JOIN_CACHE_HASHED::init");
>
> -/*
> - Check whether range_info orders to skip the next record from BKA buffer
> + hash_table= 0;
> + key_entries= 0;
>
> - SYNOPSIS
> - bka_range_seq_skip_record()
> - seq value returned by bka_range_seq_init()
> - range_info information about the next range
> - rowid [NOT USED] rowid of the record to be checked
> + key_length= ref->key_length;
>
> -
> - DESCRIPTION
> - The function interprets seq as a pointer to a JOIN_CACHE_BKA object.
> - The function interprets seq as a pointer to the JOIN_CACHE_BKA_UNIQUE
> - object. The function returns TRUE if the record with this range_info
> - is to be filtered out from the stream of records returned by
> - multi_range_read_next().
> + if ((rc= JOIN_CACHE::init()))
> + DBUG_RETURN (rc);
>
> - NOTE
> - This function are used only as a callback function.
> + if (!(key_buff= (uchar*) sql_alloc(key_length)))
> + DBUG_RETURN(1);
>
> - RETURN
> - 1 record with this range_info is to be filtered out from the stream
> - of records returned by multi_range_read_next()
> - 0 the record is to be left in the stream
> -*/
> + /* Take into account a reference to the next record in the key chain */
> + pack_length+= get_size_of_rec_offset();
> + pack_length_with_blob_ptrs+= get_size_of_rec_offset();
>
> -static
> -bool bka_range_seq_skip_record(range_seq_t rseq, char *range_info, uchar *rowid)
> -{
> - DBUG_ENTER("bka_range_seq_skip_record");
> - JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
> - bool res= cache->get_match_flag_by_pos((uchar *) range_info);
> - DBUG_RETURN(res);
> + init_hash_table();
> +
> + rec_fields_offset= get_size_of_rec_offset()+get_size_of_rec_length()+
> + (prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
> +
> + data_fields_offset= 0;
> + if (use_emb_key)
> + {
> + CACHE_FIELD *copy= field_descr;
> + CACHE_FIELD *copy_end= copy+flag_fields;
> + for ( ; copy < copy_end; copy++)
> + data_fields_offset+= copy->length;
> + }
> +
> + DBUG_RETURN(rc);
> }
>
> -/*
> - Using BKA find matches from the next table for records from the join buffer
> +
> +/*
> + Initialize the hash table of a hashed join cache
>
> SYNOPSIS
> - join_matching_records()
> - skip_last do not look for matches for the last partial join record
> + init_hash_table()
>
> DESCRIPTION
> - This function can be used only when the table join_tab can be accessed
> - by keys built over the fields of previous join tables.
> - The function retrieves all partial join records from the join buffer and
> - for each of them builds the key value to access join_tab, performs index
> - look-up with this key and selects matching records yielded by this look-up
> - If a match is found the function will call the sub_select function trying
> - to look for matches for the remaining join operations.
> - This function currently is called only from the function join_records.
> - It's assumed that this function is always called with the skip_last
> - parameter equal to false.
> + The function estimates the number of hash table entries in the hash
> + table to be used and initializes this hash table within the join buffer
> + space.
>
> - NOTES
> - The function produces all matching extensions for the records in the
> - join buffer following the path of the Batched Key Access algorithm.
> - When an outer join operation is performed all unmatched records from
> - the join buffer must be extended by null values. The function
> - join_null_complements serves this purpose.
> - The Batched Key Access algorithm assumes that key accesses are batched.
> - In other words it assumes that, first, either keys themselves or the
> - corresponding rowids (primary keys) are accumulated in a buffer, then
> - data rows from join_tab are fetched for all of them. When a row is
> - fetched it is always returned with a reference to the key by which it
> - has been accessed.
> - When key values are batched we can save on the number of the server
> - requests for index lookups. For the remote engines, like NDB cluster, it
> - essentially reduces the number of round trips between the server and
> - the engine when performing a join operation.
> - When the rowids for the keys are batched we can optimize the order
> - in what we fetch the data for this rowids. The performance benefits of
> - this optimization can be significant for such engines as MyISAM, InnoDB.
> - What is exactly batched are hidden behind implementations of
> - MRR handler interface that is supposed to be appropriately chosen
> - for each engine. If for a engine no specific implementation of the MRR
> - interface is supllied then the default implementation is used. This
> - implementation actually follows the path of Nested Loops Join algorithm.
> - In this case BKA join surely will demonstrate a worse performance than
> - NL join.
> -
> - RETURN
> - return one of enum_nested_loop_state
> + RETURN VALUE
> + Currently the function always returns 0;
> */
>
> -enum_nested_loop_state JOIN_CACHE_BKA::join_matching_records(bool skip_last)
> +int JOIN_CACHE_HASHED::init_hash_table()
> {
> - int error;
> - handler *file= join_tab->table->file;
> - enum_nested_loop_state rc= NESTED_LOOP_OK;
> - uchar *rec_ptr= 0;
> - bool check_only_first_match= join_tab->check_only_first_match();
> -
> - /* Set functions to iterate over keys in the join buffer */
> + hash_table= 0;
> + key_entries= 0;
>
> - RANGE_SEQ_IF seq_funcs= { bka_range_seq_init,
> - bka_range_seq_next,
> - check_only_first_match ?
> - bka_range_seq_skip_record : 0,
> - join_tab->cache_idx_cond ?
> - bka_skip_index_tuple : 0 };
> + /* Calculate the minimal possible value of size_of_key_ofs greater than 1 */
> + uint max_size_of_key_ofs= max(2, get_size_of_rec_offset());
> + for (size_of_key_ofs= 2;
> + size_of_key_ofs <= max_size_of_key_ofs;
> + size_of_key_ofs+= 2)
> + {
> + key_entry_length= get_size_of_rec_offset() + // key chain header
> + size_of_key_ofs + // reference to the next key
> + (use_emb_key ? get_size_of_rec_offset() : key_length);
>
> - /* The value of skip_last must be always FALSE when this function is called */
> - DBUG_ASSERT(!skip_last);
> + ulong space_per_rec= avg_record_length +
> + avg_aux_buffer_incr +
> + key_entry_length+size_of_key_ofs;
> + uint n= buff_size / space_per_rec;
>
> - /* Return at once if there are no records in the join buffer */
> - if (!records)
> - return NESTED_LOOP_OK;
> -
> - rc= init_join_matching_records(&seq_funcs, records);
> - if (rc != NESTED_LOOP_OK)
> - goto finish;
> -
> - while (!(error= file->multi_range_read_next((char **) &rec_ptr)))
> - {
> - if (join->thd->killed)
> - {
> - /* The user has aborted the execution of the query */
> - join->thd->send_kill_message();
> - rc= NESTED_LOOP_KILLED;
> - goto finish;
> - }
> - if (join_tab->keep_current_rowid)
> - join_tab->table->file->position(join_tab->table->record[0]);
> - /*
> - If only the first match is needed and it has been already found
> - for the associated partial join record then the returned candidate
> - is discarded.
> + /*
> + TODO: Make a better estimate for this upper bound of
> + the number of records in in the join buffer.
> */
> - if (rc == NESTED_LOOP_OK &&
> - (!check_only_first_match || !get_match_flag_by_pos(rec_ptr)))
> - {
> - get_record_by_pos(rec_ptr);
> - update_virtual_fields(join->thd, join_tab->table);
> - rc= generate_full_extensions(rec_ptr);
> - if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
> - goto finish;
> - }
> + uint max_n= buff_size / (pack_length-length+
> + key_entry_length+size_of_key_ofs);
> +
> + hash_entries= (uint) (n / 0.7);
> + set_if_bigger(hash_entries, 1);
> +
> + if (offset_size(max_n*key_entry_length) <=
> + size_of_key_ofs)
> + break;
> }
> +
> + /* Initialize the hash table */
> + hash_table= buff + (buff_size-hash_entries*size_of_key_ofs);
> + cleanup_hash_table();
> + curr_key_entry= hash_table;
>
> - if (error > 0 && error != HA_ERR_END_OF_FILE)
> - return NESTED_LOOP_ERROR;
> -finish:
> - return end_join_matching_records(rc);
> + return 0;
> }
>
>
> +/*
> + Reallocate the join buffer of a hashed join cache
> +
> + SYNOPSIS
> + realloc_buffer()
>
> -/*
> - Prepare to search for records that match records from the join buffer
> + DESCRITION
> + The function reallocates the join buffer of the hashed join cache.
> + After this it initializes a hash table within the buffer space and
> + resets the join cache for writing.
>
> - SYNOPSIS
> - init_join_matching_records()
> - seq_funcs structure of range sequence interface
> - ranges number of keys/ranges in the sequence
> + NOTES
> + The function assumes that buff_size contains the new value for the join
> + buffer size.
>
> - DESCRIPTION
> - This function calls the multi_range_read_init function to set up
> - the BKA process of generating the keys from the records in the join
> - buffer and looking for matching records from the table to be joined.
> - The function passes as a parameter a structure of functions that
> - implement the range sequence interface. This interface is used to
> - enumerate all generated keys and optionally to filter the matching
> - records returned by the multi_range_read_next calls from the
> - intended invocation of the join_matching_records method. The
> - multi_range_read_init function also receives the parameters for
> - MRR buffer to be used and flags specifying the mode in which
> - this buffer will be functioning.
> - The number of keys in the sequence expected by multi_range_read_init
> - is passed through the parameter ranges.
> -
> - RETURN
> - return one of enum_nested_loop_state
> + RETURN VALUE
> + 0 if the buffer has been successfully reallocated
> + 1 otherwise
> */
>
> -enum_nested_loop_state
> -JOIN_CACHE_BKA::init_join_matching_records(RANGE_SEQ_IF *seq_funcs, uint ranges)
> +int JOIN_CACHE_HASHED::realloc_buffer()
> {
> - int error;
> - handler *file= join_tab->table->file;
> - enum_nested_loop_state rc= NESTED_LOOP_OK;
> -
> - join_tab->table->null_row= 0;
> -
> + int rc;
> + free();
> + rc= test(!(buff= (uchar*) my_malloc(buff_size, MYF(0))));
> + init_hash_table();
> + reset(TRUE);
> + return rc;
> +}
>
> - /* Dynamic range access is never used with BKA */
> - DBUG_ASSERT(join_tab->use_quick != 2);
> +/*
> + Get maximum size of the additional space per record used for record keys
>
> - for (JOIN_TAB *tab =join->join_tab; tab != join_tab ; tab++)
> - {
> - tab->status= tab->table->status;
> - tab->table->status= 0;
> - }
> + SYNOPSYS
> + get_max_key_addon_space_per_record()
> +
> + DESCRIPTION
> + The function returns the size of the space occupied by one key entry
> + and one hash table entry.
>
> - init_mrr_buff();
> + RETURN VALUE
> + maximum size of the additional space per record that is used to store
> + record keys in the hash table
> +*/
>
> - /*
> - Prepare to iterate over keys from the join buffer and to get
> - matching candidates obtained with MMR handler functions.
> - */
> - if (!file->inited)
> - file->ha_index_init(join_tab->ref.key, 1);
> - if ((error= file->multi_range_read_init(seq_funcs, (void*) this, ranges,
> - mrr_mode, &mrr_buff)))
> - rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
> -
> - return rc;
> -}
> +uint JOIN_CACHE_HASHED::get_max_key_addon_space_per_record()
> +{
> + ulong len;
> + TABLE_REF *ref= &join_tab->ref;
> + len= (use_emb_key ? get_size_of_rec_offset() : ref->key_length) +
> + size_of_rec_ofs + // size of the key chain header
> + size_of_rec_ofs + // >= size of the reference to the next key
> + size_of_rec_ofs; // >= size of hash table entry
> + return len;
> +}
>
>
> /*
> - Finish searching for records that match records from the join buffer
> + Reset the buffer of a hashed join cache for reading/writing
>
> SYNOPSIS
> - end_join_matching_records()
> - rc return code passed by the join_matching_records function
> + reset()
> + for_writing if it's TRUE the function reset the buffer for writing
>
> DESCRIPTION
> - This function perform final actions on searching for all matches for
> - the records from the join buffer and building all full join extensions
> - of the records with these matches.
> + This implementation of the virtual function reset() resets the join buffer
> + of the JOIN_CACHE_HASHED class for reading or writing.
> + Additionally to what the default implementation does this function
> + cleans up the hash table allocated within the buffer.
>
> - RETURN
> - return code rc passed to the function as a parameter
> + RETURN VALUE
> + none
> */
> -
> -enum_nested_loop_state
> -JOIN_CACHE_BKA::end_join_matching_records(enum_nested_loop_state rc)
> +
> +void JOIN_CACHE_HASHED::reset(bool for_writing)
> {
> - for (JOIN_TAB *tab=join->join_tab; tab != join_tab ; tab++)
> - tab->table->status= tab->status;
> - return rc;
> + this->JOIN_CACHE::reset(for_writing);
> + if (for_writing && hash_table)
> + cleanup_hash_table();
> + curr_key_entry= hash_table;
> }
>
>
> /*
> - Get the key built over the next record from BKA join buffer
> + Add a record into the buffer of a hashed join cache
>
> SYNOPSIS
> - get_next_key()
> - key pointer to the buffer where the key value is to be placed
> + put_record()
>
> DESCRIPTION
> - The function reads key fields from the current record in the join buffer.
> - and builds the key value out of these fields that will be used to access
> - the 'join_tab' table. Some of key fields may belong to previous caches.
> - They are accessed via record references to the record parts stored in the
> - previous join buffers. The other key fields always are placed right after
> - the flag fields of the record.
> - If the key is embedded, which means that its value can be read directly
> - from the join buffer, then *key is set to the beginning of the key in
> - this buffer. Otherwise the key is built in the join_tab->ref->key_buff.
> - The function returns the length of the key if it succeeds ro read it.
> - If is assumed that the functions starts reading at the position of
> - the record length which is provided for each records in a BKA cache.
> - After the key is built the 'pos' value points to the first position after
> - the current record.
> - The function returns 0 if the initial position is after the beginning
> - of the record fields for last record from the join buffer.
> -
> - RETURN
> - length of the key value - if the starting value of 'pos' points to
> - the position before the fields for the last record,
> - 0 - otherwise.
> + This implementation of the virtual function put_record writes the next
> + matching record into the join buffer of the JOIN_CACHE_HASHED class.
> + Additionally to what the default implementation does this function
> + performs the following.
> + It extracts from the record the key value used in lookups for matching
> + records and searches for this key in the hash tables from the join cache.
> + If it finds the key in the hash table it joins the record to the chain
> + of records with this key. If the key is not found in the hash table the
> + key is placed into it and a chain containing only the newly added record
> + is attached to the key entry. The key value is either placed in the hash
> + element added for the key or, if the use_emb_key flag is set, remains in
> + the record from the partial join.
> + If the match flag field of a record contains MATCH_IMPOSSIBLE the key is
> + not created for this record.
> +
> + RETURN VALUE
> + TRUE if it has been decided that it should be the last record
> + in the join buffer,
> + FALSE otherwise
> */
>
> -uint JOIN_CACHE_BKA::get_next_key(uchar ** key)
> +bool JOIN_CACHE_HASHED::put_record()
> {
> - uint len;
> - uint32 rec_len;
> - uchar *init_pos;
> - JOIN_CACHE *cache;
> -
> - if (pos > last_rec_pos || !records)
> - return 0;
> -
> - /* Any record in a BKA cache is prepended with its length */
> - DBUG_ASSERT(with_length);
> -
> - /* Read the length of the record */
> - rec_len= get_rec_length(pos);
> - pos+= size_of_rec_len;
> - init_pos= pos;
> + bool is_full;
> + uchar *key;
> + uint key_len= key_length;
> + uchar *key_ref_ptr;
> + uchar *link= 0;
> + TABLE_REF *ref= &join_tab->ref;
> + uchar *next_ref_ptr= pos;
>
> - /* Read a reference to the previous cache if any */
> + pos+= get_size_of_rec_offset();
> + /* Write the record into the join buffer */
> if (prev_cache)
> - pos+= prev_cache->get_size_of_rec_offset();
> + link= prev_cache->get_curr_rec_link();
> + write_record_data(link, &is_full);
>
> - curr_rec_pos= pos;
> + if (last_written_is_null_compl)
> + return is_full;
>
> - /* Read all flag fields of the record */
> - read_flag_fields();
> -
> if (use_emb_key)
> + key= get_curr_emb_key();
> + else
> {
> - /* An embedded key is taken directly from the join buffer */
> - *key= pos;
> - len= emb_key_length;
> + /* Build the key over the fields read into the record buffers */
> + cp_buffer_from_ref(join->thd, join_tab->table, ref);
> + key= ref->key_buff;
> + }
> +
> + /* Look for the key in the hash table */
> + if (key_search(key, key_len, &key_ref_ptr))
> + {
> + uchar *last_next_ref_ptr;
> + /*
> + The key is found in the hash table.
> + Add the record to the circular list of the records attached to this key.
> + Below 'rec' is the record to be added into the record chain for the found
> + key, 'key_ref' points to a flatten representation of the st_key_entry
> + structure that contains the key and the head of the record chain.
> + */
> + last_next_ref_ptr= get_next_rec_ref(key_ref_ptr+get_size_of_key_offset());
> + /* rec->next_rec= key_entry->last_rec->next_rec */
> + memcpy(next_ref_ptr, last_next_ref_ptr, get_size_of_rec_offset());
> + /* key_entry->last_rec->next_rec= rec */
> + store_next_rec_ref(last_next_ref_ptr, next_ref_ptr);
> + /* key_entry->last_rec= rec */
> + store_next_rec_ref(key_ref_ptr+get_size_of_key_offset(), next_ref_ptr);
> }
> else
> {
> - /* Read key arguments from previous caches if there are any such fields */
> - if (external_key_arg_fields)
> + /*
> + The key is not found in the hash table.
> + Put the key into the join buffer linking it with the keys for the
> + corresponding hash entry. Create a circular list with one element
> + referencing the record and attach the list to the key in the buffer.
> + */
> + uchar *cp= last_key_entry;
> + cp-= get_size_of_rec_offset()+get_size_of_key_offset();
> + store_next_key_ref(key_ref_ptr, cp);
> + store_null_key_ref(cp);
> + store_next_rec_ref(next_ref_ptr, next_ref_ptr);
> + store_next_rec_ref(cp+get_size_of_key_offset(), next_ref_ptr);
> + if (use_emb_key)
> {
> - uchar *rec_ptr= curr_rec_pos;
> - uint key_arg_count= external_key_arg_fields;
> - CACHE_FIELD **copy_ptr= blob_ptr-key_arg_count;
> - for (cache= prev_cache; key_arg_count; cache= cache->prev_cache)
> - {
> - uint len= 0;
> - DBUG_ASSERT(cache);
> - rec_ptr= cache->get_rec_ref(rec_ptr);
> - while (!cache->referenced_fields)
> - {
> - cache= cache->prev_cache;
> - DBUG_ASSERT(cache);
> - rec_ptr= cache->get_rec_ref(rec_ptr);
> - }
> - while (key_arg_count &&
> - cache->read_referenced_field(*copy_ptr, rec_ptr, &len))
> - {
> - copy_ptr++;
> - --key_arg_count;
> - }
> - }
> + cp-= get_size_of_rec_offset();
> + store_emb_key_ref(cp, key);
> }
> -
> - /*
> - Read the other key arguments from the current record. The fields for
> - these arguments are always first in the sequence of the record's fields.
> - */
> - CACHE_FIELD *copy= field_descr+flag_fields;
> - CACHE_FIELD *copy_end= copy+local_key_arg_fields;
> - bool blob_in_rec_buff= blob_data_is_in_rec_buff(curr_rec_pos);
> - for ( ; copy < copy_end; copy++)
> - read_record_field(copy, blob_in_rec_buff);
> -
> - /* Build the key over the fields read into the record buffers */
> - TABLE_REF *ref= &join_tab->ref;
> - cp_buffer_from_ref(join->thd, join_tab->table, ref);
> - *key= ref->key_buff;
> - len= ref->key_length;
> - }
> + else
> + {
> + cp-= key_len;
> + memcpy(cp, key, key_len);
> + }
> + last_key_entry= cp;
> + DBUG_ASSERT(last_key_entry >= end_pos);
> + /* Increment the counter of key_entries in the hash table */
> + key_entries++;
> + }
> + return is_full;
> +}
>
> - pos= init_pos+rec_len;
>
> - return len;
> +/*
> + Read the next record from the buffer of a hashed join cache
> +
> + SYNOPSIS
> + get_record()
> +
> + DESCRIPTION
> + Additionally to what the default implementation of the virtual
> + function get_record does this implementation skips the link element
> + used to connect the records with the same key into a chain.
> +
> + RETURN VALUE
> + TRUE there are no more records to read from the join buffer
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE_HASHED::get_record()
> +{
> + pos+= get_size_of_rec_offset();
> + return this->JOIN_CACHE::get_record();
> +}
> +
> +
> +/*
> + Skip record from a hashed join buffer if its match flag is set to MATCH_FOUND
> +
> + SYNOPSIS
> + skip_if_matched()
> +
> + DESCRIPTION
> + This implementation of the virtual function skip_if_matched does
> + the same as the default implementation does, but it takes into account
> + the link element used to connect the records with the same key into a chain.
> +
> + RETURN VALUE
> + TRUE the match flag is MATCH_FOUND and the record has been skipped
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE_HASHED::skip_if_matched()
> +{
> + uchar *save_pos= pos;
> + pos+= get_size_of_rec_offset();
> + if (!this->JOIN_CACHE::skip_if_matched())
> + {
> + pos= save_pos;
> + return FALSE;
> + }
> + return TRUE;
> +}
> +
> +
> +/*
> + Skip record from a hashed join buffer if its match flag dictates to do so
> +
> + SYNOPSIS
> + skip_if_uneeded_match()
> +
> + DESCRIPTION
> + This implementation of the virtual function skip_if_not_needed_match does
> + the same as the default implementation does, but it takes into account
> + the link element used to connect the records with the same key into a chain.
> +
> + RETURN VALUE
> + TRUE the match flag dictates to skip the record
> + FALSE the match flag is off
> +*/
> +
> +bool JOIN_CACHE_HASHED::skip_if_not_needed_match()
> +{
> + uchar *save_pos= pos;
> + pos+= get_size_of_rec_offset();
> + if (!this->JOIN_CACHE::skip_if_not_needed_match())
> + {
> + pos= save_pos;
> + return FALSE;
> + }
> + return TRUE;
> +}
> +
> +
> +/*
> + Search for a key in the hash table of the join buffer
> +
> + SYNOPSIS
> + key_search()
> + key pointer to the key value
> + key_len key value length
> + key_ref_ptr OUT position of the reference to the next key from
> + the hash element for the found key , or
> + a position where the reference to the the hash
> + element for the key is to be added in the
> + case when the key has not been found
> +
> + DESCRIPTION
> + The function looks for a key in the hash table of the join buffer.
> + If the key is found the functionreturns the position of the reference
> + to the next key from to the hash element for the given key.
> + Otherwise the function returns the position where the reference to the
> + newly created hash element for the given key is to be added.
> +
> + RETURN VALUE
> + TRUE the key is found in the hash table
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE_HASHED::key_search(uchar *key, uint key_len,
> + uchar **key_ref_ptr)
> +{
> + bool is_found= FALSE;
> + uint idx= get_hash_idx(key, key_length);
> + uchar *ref_ptr= hash_table+size_of_key_ofs*idx;
> + while (!is_null_key_ref(ref_ptr))
> + {
> + uchar *next_key;
> + ref_ptr= get_next_key_ref(ref_ptr);
> + next_key= use_emb_key ? get_emb_key(ref_ptr-get_size_of_rec_offset()) :
> + ref_ptr-key_length;
> +
> + if (memcmp(next_key, key, key_len) == 0)
> + {
> + is_found= TRUE;
> + break;
> + }
> + }
> + *key_ref_ptr= ref_ptr;
> + return is_found;
> +}
> +
> +
> +/*
> + Calclulate hash value for a key in the hash table of the join buffer
> +
> + SYNOPSIS
> + get_hash_idx()
> + key pointer to the key value
> + key_len key value length
> +
> + DESCRIPTION
> + The function calculates an index of the hash entry in the hash table
> + of the join buffer for the given key
> +
> + RETURN VALUE
> + the calculated index of the hash entry for the given key.
> +*/
> +
> +uint JOIN_CACHE_HASHED::get_hash_idx(uchar* key, uint key_len)
> +{
> + ulong nr= 1;
> + ulong nr2= 4;
> + uchar *pos= key;
> + uchar *end= key+key_len;
> + for (; pos < end ; pos++)
> + {
> + nr^= (ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
> + nr2+= 3;
> + }
> + return nr % hash_entries;
> +}
> +
> +
> +/*
> + Clean up the hash table of the join buffer
> +
> + SYNOPSIS
> + cleanup_hash_table()
> + key pointer to the key value
> + key_len key value length
> +
> + DESCRIPTION
> + The function cleans up the hash table in the join buffer removing all
> + hash elements from the table.
> +
> + RETURN VALUE
> + none
> +*/
> +
> +void JOIN_CACHE_HASHED:: cleanup_hash_table()
psergey: according to the coding style, there should be no space after "::".
> +{
> + last_key_entry= hash_table;
> + bzero(hash_table, (buff+buff_size)-hash_table);
> + key_entries= 0;
> +}
> +
> +
> +/*
> + Check whether all records in a key chain have their match flags set on
> +
> + SYNOPSIS
> + check_all_match_flags_for_key()
> + key_chain_ptr
> +
> + DESCRIPTION
> + This function retrieves records in the given circular chain and checks
psergey: this_function_syntax
> + whether their match flags are set on. The parameter key_chain_ptr shall
> + point to the position in the join buffer storing the reference to the
> + last element of this chain.
> +
> + RETURN VALUE
> + TRUE if each retrieved record has its match flag set to MATCH_FOUND
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE_HASHED::check_all_match_flags_for_key(uchar *key_chain_ptr)
> +{
> + uchar *last_rec_ref_ptr= get_next_rec_ref(key_chain_ptr);
> + uchar *next_rec_ref_ptr= last_rec_ref_ptr;
> + do
> + {
> + next_rec_ref_ptr= get_next_rec_ref(next_rec_ref_ptr);
> + uchar *rec_ptr= next_rec_ref_ptr+rec_fields_offset;
> + if (get_match_flag_by_pos(rec_ptr) != MATCH_FOUND)
> + return FALSE;
> + }
> + while (next_rec_ref_ptr != last_rec_ref_ptr);
> + return TRUE;
> +}
> +
> +
> +/*
> + Get the next key built for the records from the buffer of a hashed join cache
> +
> + SYNOPSIS
> + get_next_key()
> + key pointer to the buffer where the key value is to be placed
> +
> + DESCRIPTION
> + The function reads the next key value stored in the hash table of the
psergey: this_function_syntax
> + join buffer. Depending on the value of the use_emb_key flag of the
> + join cache the value is read either from the table itself or from
> + the record field where it occurs.
> +
> + RETURN VALUE
> + length of the key value - if the starting value of 'cur_key_entry' refers
> + to the position after that referred by the the value of 'last_key_entry',
> + 0 - otherwise.
> +*/
> +
> +uint JOIN_CACHE_HASHED::get_next_key(uchar ** key)
> +{
> + if (curr_key_entry == last_key_entry)
> + return 0;
> +
> + curr_key_entry-= key_entry_length;
> +
> + *key = use_emb_key ? get_emb_key(curr_key_entry) : curr_key_entry;
> +
> + DBUG_ASSERT(*key >= buff && *key < hash_table);
> +
> + return key_length;
> +}
> +
> +
> +/*
> + Initiate an iteration process over records in the joined table
> +
> + SYNOPSIS
> + open()
> +
> + DESCRIPTION
> + The function initiates the process of iteration over records from the
psergey: this_function_syntax
> + joined table recurrently performed by the BNL/BKLH join algorithm.
> +
> + RETURN VALUE
> + 0 the initiation is a success
> + error code otherwise
> +*/
> +
> +int JOIN_TAB_SCAN::open()
> +{
> + for (JOIN_TAB *tab= join->join_tab; tab != join_tab ; tab++)
> + {
> + tab->status= tab->table->status;
> + tab->table->status= 0;
> + }
> + is_first_record= TRUE;
> + return join_init_read_record(join_tab);
> +}
> +
> +
> +/*
> + Read the next record that can match while scanning the joined table
> +
> + SYNOPSIS
> + next()
> +
> + DESCRIPTION
> + The function reads the next record from the joined table that can
psergey: this_function_syntax
> + match some records in the buffer of the join cache 'cache'. To do
> + this the function calls the function that scans table records and
> + looks for the next one that meets the condition pushed to the
> + joined table join_tab.
> +
> + NOTES
> + The function catches the signal that kills the query.
> +
> + RETURN VALUE
> + 0 the next record exists and has been successfully read
> + error code otherwise
> +*/
> +
> +int JOIN_TAB_SCAN::next()
> +{
> + int err= 0;
> + int skip_rc;
> + READ_RECORD *info= &join_tab->read_record;
> + SQL_SELECT *select= join_tab->cache_select;
> + if (is_first_record)
> + is_first_record= FALSE;
> + else
> + err= info->read_record(info);
> + if (!err)
> + update_virtual_fields(join->thd, join_tab->table);
> + while (!err && select && (skip_rc= select->skip_record(join->thd)) <= 0)
> + {
> + if (join->thd->killed || skip_rc < 0)
> + return 1;
> + /*
> + Move to the next record if the last retrieved record does not
> + meet the condition pushed to the table join_tab.
> + */
> + err= info->read_record(info);
> + if (!err)
> + update_virtual_fields(join->thd, join_tab->table);
> + }
> + return err;
> +}
> +
> +
> +/*
> + Perform finalizing actions for a scan over the table records
> +
> + SYNOPSIS
> + close()
> +
> + DESCRIPTION
> + The function performs the necessary restoring actions after
psergey: this_function_syntax
> + the table scan over the joined table has been finished.
> +
> + RETURN VALUE
> + none
> +*/
> +
> +void JOIN_TAB_SCAN::close()
> +{
> + for (JOIN_TAB *tab= join->join_tab; tab != join_tab ; tab++)
> + tab->table->status= tab->status;
> +}
> +
> +
> +/*
> + Prepare to iterate over the BNL join cache buffer to look for matches
> +
> + SYNOPSIS
> + prepare_look_for_matches()
> + skip_last <-> ignore the last record in the buffer
> +
> + DESCRIPTION
> + The function prepares the join cache for an iteration over the
psergey: this_function_syntax
> + records in the join buffer. The iteration is performed when looking
> + for matches for the record from the joined table join_tab that
> + has been placed into the record buffer of the joined table.
> + If the value of the parameter skip_last is TRUE then the last
> + record from the join buffer is ignored.
> + The function initializes the counter of the records that have been
> + not iterated over yet.
> +
> + RETURN VALUE
> + TRUE there are no records in the buffer to iterate over
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE_BNL::prepare_look_for_matches(bool skip_last)
> +{
> + if (!records)
> + return TRUE;
> + reset(FALSE);
> + rem_records= records-test(skip_last);
> + return rem_records == 0;
> +}
> +
> +
> +/*
> + Get next record from the BNL join cache buffer when looking for matches
> +
> + SYNOPSIS
> + get_next_candidate_for_match
> +
> + DESCRIPTION
> + This method is used for iterations over the records from the join
psergey: this_function_syntax
> + cache buffer when looking for matches for records from join_tab.
> + The methods performs the necessary preparations to read the next record
> + from the join buffer into the record buffer by the method
> + read_next_candidate_for_match, or, to skip the next record from the join
> + buffer by the method skip_recurrent_candidate_for_match.
> + This implementation of the virtual method get_next_candidate_for_match
> + just decrements the counter of the records that are to be iterated over
> + and returns the current value of the cursor 'pos' as the position of
> + the record to be processed.
> +
> + RETURN VALUE
> + pointer to the position right after the prefix of the current record
> + in the join buffer if the there is another record to iterate over,
> + 0 - otherwise.
> +*/
> +
> +uchar *JOIN_CACHE_BNL::get_next_candidate_for_match()
> +{
> + if (!rem_records)
> + return 0;
> + rem_records--;
> + return pos+base_prefix_length;
> +}
> +
> +
> +/*
> + Check whether the matching record from the BNL cache is to be skipped
> +
> + SYNOPSIS
> + skip_next_candidate_for_match
> + rec_ptr pointer to the position in the join buffer right after the prefix
> + of the current record
> +
> + DESCRIPTION
> + This implementation of the virtual function just calls the
psergey: this_function_syntax
> + method skip_if_not_needed_match to check whether the record referenced by
> + ref_ptr has its match flag set either to MATCH_FOUND and join_tab is the
> + first inner table of a semi-join, or it's set to MATCH_IMPOSSIBLE and
> + join_tab is the first inner table of an outer join.
> + If so, the function just skips this record setting the value of the
> + cursor 'pos' to the position right after it.
> +
> + RETURN VALUE
> + TRUE the record referenced by rec_ptr has been skipped
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE_BNL::skip_next_candidate_for_match(uchar *rec_ptr)
> +{
> + pos= rec_ptr-base_prefix_length;
> + return skip_if_not_needed_match();
> +}
> +
> +
> +/*
> + Read next record from the BNL join cache buffer when looking for matches
> +
> + SYNOPSIS
> + read_next_candidate_for_match
> + rec_ptr pointer to the position in the join buffer right after the prefix
> + the current record.
> +
> + DESCRIPTION
> + This implementation of the virtual method read_next_candidate_for_match
psergey: this_function_syntax
> + calls the method get_record to read the record referenced by rec_ptr from
> + the join buffer into the record buffer. If this record refers to the
> + fields in the other join buffers the call of get_record ensures that
> + these fields are read into the corresponding record buffers as well.
> + This function is supposed to be called after a successful call of
> + the method get_next_candidate_for_match.
> +
> + RETURN VALUE
> + none
> +*/
> +
> +void JOIN_CACHE_BNL::read_next_candidate_for_match(uchar *rec_ptr)
> +{
> + pos= rec_ptr-base_prefix_length;
> + get_record();
> +}
> +
> +
> +/*
> + Initialize the BNL join cache
> +
> + SYNOPSIS
> + init
> +
> + DESCRIPTION
> + The function initializes the cache structure. It is supposed to be called
> + right after a constructor for the JOIN_CACHE_BNL.
> +
> + NOTES
> + The function first constructs a companion object of the type JOIN_TAB_SCAN,
> + then it calls the init method of the parent class.
> +
> + RETURN VALUE
> + 0 initialization with buffer allocations has been succeeded
> + 1 otherwise
> +*/
> +
> +int JOIN_CACHE_BNL::init()
> +{
> + DBUG_ENTER("JOIN_CACHE_BNL::init");
> +
> + if (!(join_tab_scan= new JOIN_TAB_SCAN(join, join_tab)))
> + DBUG_RETURN(1);
> +
> + DBUG_RETURN(JOIN_CACHE::init());
> +}
> +
> +
> +/*
> + Get the chain of records from buffer matching the current candidate for join
> +
> + SYNOPSIS
> + get_matching_chain_by_join_key()
> +
> + DESCRIPTION
> + This function first build a join key for the record of join_tab that
psergey: this_function_syntax
> + currently is in the join buffer for this table. Then it looks for
> + the key entry with this key in the hash table of the join cache.
> + If such a key entry is found the function returns the pointer to
> + the head of the chain of records in the join_buffer that match this
> + key.
> +
> + RETURN VALUE
> + The pointer to the corresponding circular list of records if
> + the key entry with the join key is found, 0 - otherwise.
> +*/
> +
> +uchar *JOIN_CACHE_BNLH::get_matching_chain_by_join_key()
> +{
> + uchar *key_ref_ptr;
> + TABLE *table= join_tab->table;
> + TABLE_REF *ref= &join_tab->ref;
> + KEY *keyinfo= table->key_info+ref->key;
> + /* Build the join key value out of the record in the record buffer */
> + key_copy(key_buff, table->record[0], keyinfo, key_length);
> + /* Look for this key in the join buffer */
> + if (!key_search(key_buff, key_length, &key_ref_ptr))
> + return 0;
> + return key_ref_ptr+get_size_of_key_offset();
> +}
> +
> +
> +/*
> + Prepare to iterate over the BNLH join cache buffer to look for matches
> +
> + SYNOPSIS
> + prepare_look_for_matches()
> + skip_last <-> ignore the last record in the buffer
> +
> + DESCRIPTION
> + The function prepares the join cache for an iteration over the
psergey: this_function_syntax
> + records in the join buffer. The iteration is performed when looking
> + for matches for the record from the joined table join_tab that
> + has been placed into the record buffer of the joined table.
> + If the value of the parameter skip_last is TRUE then the last
> + record from the join buffer is ignored.
> + The function builds the hashed key from the join fields of join_tab
> + and uses this key to look in the hash table of the join cache for
> + the chain of matching records in in the join buffer. If it finds
> + such a chain it sets the member last_rec_ref_ptr to point to the
> + last link of the chain while setting the member next_rec_ref_po 0.
> +
> + RETURN VALUE
> + TRUE there are no matching records in the buffer to iterate over
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE_BNLH::prepare_look_for_matches(bool skip_last)
> +{
> + uchar *curr_matching_chain;
> + last_matching_rec_ref_ptr= next_matching_rec_ref_ptr= 0;
> + if (!(curr_matching_chain= get_matching_chain_by_join_key()))
> + return 1;
> + last_matching_rec_ref_ptr= get_next_rec_ref(curr_matching_chain);
> + return 0;
> +}
> +
> +
> +/*
> + Get next record from the BNLH join cache buffer when looking for matches
> +
> + SYNOPSIS
> + get_next_candidate_for_match
> +
> + DESCRIPTION
> + This method is used for iterations over the records from the join
> + cache buffer when looking for matches for records from join_tab.
> + The methods performs the necessary preparations to read the next record
> + from the join buffer into the record buffer by the method
> + read_next_candidate_for_match, or, to skip the next record from the join
> + buffer by the method skip_next_candidate_for_match.
> + This implementation of the virtual method moves to the next record
> + in the chain of all records from the join buffer that are to be
> + equi-joined with the current record from join_tab.
> +
> + RETURN VALUE
> + pointer to the beginning of the record fields in the join buffer
> + if the there is another record to iterate over, 0 - otherwise.
> +*/
> +
> +uchar *JOIN_CACHE_BNLH::get_next_candidate_for_match()
> +{
> + if (next_matching_rec_ref_ptr == last_matching_rec_ref_ptr)
> + return 0;
> + next_matching_rec_ref_ptr= get_next_rec_ref(next_matching_rec_ref_ptr ?
> + next_matching_rec_ref_ptr :
> + last_matching_rec_ref_ptr);
> + return next_matching_rec_ref_ptr+rec_fields_offset;
> +}
> +
> +
> +/*
> + Check whether the matching record from the BNLH cache is to be skipped
> +
> + SYNOPSIS
> + skip_next_candidate_for_match
> + rec_ptr pointer to the position in the join buffer right after
> + the previous record
> +
> + DESCRIPTION
> + This implementation of the virtual function just calls the
psergey: this_function_syntax
> + method get_match_flag_by_pos to check whether the record referenced
> + by ref_ptr has its match flag set to MATCH_FOUND.
> +
> + RETURN VALUE
> + TRUE the record referenced by rec_ptr has its match flag set to
> + MATCH_FOUND
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE_BNLH::skip_next_candidate_for_match(uchar *rec_ptr)
> +{
> + return join_tab->check_only_first_match() &&
> + (get_match_flag_by_pos(rec_ptr) == MATCH_FOUND);
> +}
> +
> +
> +/*
> + Read next record from the BNLH join cache buffer when looking for matches
> +
> + SYNOPSIS
> + read_next_candidate_for_match
> + rec_ptr pointer to the position in the join buffer right after
> + the previous record
> +
> + DESCRIPTION
> + This implementation of the virtual method read_next_candidate_for_match
psergey: this_function_syntax
> + calls the method get_record_by_pos to read the record referenced by rec_ptr
> + from the join buffer into the record buffer. If this record refers to
> + fields in the other join buffers the call of get_record_by_po ensures that
> + these fields are read into the corresponding record buffers as well.
> + This function is supposed to be called after a successful call of
> + the method get_next_candidate_for_match.
> +
> + RETURN VALUE
> + none
> +*/
> +
> +void JOIN_CACHE_BNLH::read_next_candidate_for_match(uchar *rec_ptr)
> +{
> + get_record_by_pos(rec_ptr);
> }
>
>
> -/*
> - Initialize a BKA_UNIQUE cache
> +/*
> + Initialize the BNLH join cache
>
> SYNOPSIS
> - init()
> + init
>
> DESCRIPTION
> - The function initializes the cache structure. It supposed to be called
> - right after a constructor for the JOIN_CACHE_BKA_UNIQUE.
> - The function allocates memory for the join buffer and for descriptors of
> - the record fields stored in the buffer.
> - The function also estimates the number of hash table entries in the hash
> - table to be used and initializes this hash table.
> + The function initializes the cache structure. It is supposed to be called
> + right after a constructor for the JOIN_CACHE_BNLH.
>
> NOTES
> - The code of this function should have been included into the constructor
> - code itself. However the new operator for the class JOIN_CACHE_BKA_UNIQUE
> - would never fail while memory allocation for the join buffer is not
> - absolutely unlikely to fail. That's why this memory allocation has to be
> - placed in a separate function that is called in a couple with a cache
> - constructor.
> - It is quite natural to put almost all other constructor actions into
> - this function.
> -
> - RETURN
> + The function first constructs a companion object of the type JOIN_TAB_SCAN,
> + then it calls the init method of the parent class.
> +
> + RETURN VALUE
> 0 initialization with buffer allocations has been succeeded
> 1 otherwise
> */
>
> -int JOIN_CACHE_BKA_UNIQUE::init()
> +int JOIN_CACHE_BNLH::init()
> {
> - int rc= 0;
> + DBUG_ENTER("JOIN_CACHE_BNLH::init");
> +
> + if (!(join_tab_scan= new JOIN_TAB_SCAN(join, join_tab)))
> + DBUG_RETURN(1);
> +
> + DBUG_RETURN(JOIN_CACHE_HASHED::init());
> +}
> +
> +
> +/*
> + Calculate the increment of the MRR buffer for a record write
> +
> + SYNOPSIS
> + aux_buffer_incr()
> +
> + DESCRIPTION
> + This implementation of the virtual function aux_buffer_incr determines
> + for how much the size of the MRR buffer should be increased when another
> + record is added to the cache.
> +
> + RETURN VALUE
> + the increment of the size of the MRR buffer for the next record
> +*/
> +
> +uint JOIN_TAB_SCAN_MRR::aux_buffer_incr(ulong recno)
> +{
> + uint incr= 0;
> TABLE_REF *ref= &join_tab->ref;
> -
> - DBUG_ENTER("JOIN_CACHE_BKA_UNIQUE::init");
> + TABLE *tab= join_tab->table;
> + uint rec_per_key= tab->key_info[ref->key].rec_per_key[ref->key_parts-1];
> + set_if_bigger(rec_per_key, 1);
> + if (recno == 1)
> + incr= ref->key_length + tab->file->ref_length;
> + incr+= tab->file->stats.mrr_length_per_rec * rec_per_key;
> + return incr;
> +}
>
> - hash_table= 0;
> - key_entries= 0;
>
> - if ((rc= JOIN_CACHE_BKA::init()))
> - DBUG_RETURN (rc);
> +/*
> + Initiate iteration over records returned by MRR for the current join buffer
>
> - key_length= ref->key_length;
> + SYNOPSIS
> + open()
>
> - /* Take into account a reference to the next record in the key chain */
> - pack_length+= get_size_of_rec_offset();
> -
> - /* Calculate the minimal possible value of size_of_key_ofs greater than 1 */
> - uint max_size_of_key_ofs= max(2, get_size_of_rec_offset());
> - for (size_of_key_ofs= 2;
> - size_of_key_ofs <= max_size_of_key_ofs;
> - size_of_key_ofs+= 2)
> - {
> - key_entry_length= get_size_of_rec_offset() + // key chain header
> - size_of_key_ofs + // reference to the next key
> - (use_emb_key ? get_size_of_rec_offset() : key_length);
> + DESCRIPTION
> + The function initiates the process of iteration over the records from
> + join_tab returned by the MRR interface functions for records from
> + the join buffer. Such an iteration is performed by the BKA/BKAH join
> + algorithm for each new refill of the join buffer.
> + The function calls the MRR handler function multi_range_read_init to
> + initiate this process.
>
> - uint n= buff_size / (pack_length+key_entry_length+size_of_key_ofs);
> + RETURN VALUE
> + 0 the initiation is a success
> + error code otherwise
> +*/
>
> - /*
> - TODO: Make a better estimate for this upper bound of
> - the number of records in in the join buffer.
> - */
> - uint max_n= buff_size / (pack_length-length+
> - key_entry_length+size_of_key_ofs);
> +int JOIN_TAB_SCAN_MRR::open()
> +{
> + handler *file= join_tab->table->file;
>
> - hash_entries= (uint) (n / 0.7);
> -
> - if (offset_size(max_n*key_entry_length) <=
> - size_of_key_ofs)
> - break;
> + join_tab->table->null_row= 0;
> +
> +
> + /* Dynamic range access is never used with BKA */
> + DBUG_ASSERT(join_tab->use_quick != 2);
> +
> + for (JOIN_TAB *tab =join->join_tab; tab != join_tab ; tab++)
> + {
> + tab->status= tab->table->status;
> + tab->table->status= 0;
> }
> -
> - /* Initialize the hash table */
> - hash_table= buff + (buff_size-hash_entries*size_of_key_ofs);
> - cleanup_hash_table();
> - curr_key_entry= hash_table;
>
> - pack_length+= key_entry_length;
> - pack_length_with_blob_ptrs+= get_size_of_rec_offset() + key_entry_length;
> + init_mrr_buff();
>
> - rec_fields_offset= get_size_of_rec_offset()+get_size_of_rec_length()+
> - (prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
> + /*
> + Prepare to iterate over keys from the join buffer and to get
> + matching candidates obtained with MMR handler functions.
> + */
> + if (!file->inited)
> + file->ha_index_init(join_tab->ref.key, 1);
> + ranges= cache->get_number_of_ranges_for_mrr();
> + if (!join_tab->cache_idx_cond)
> + range_seq_funcs.skip_index_tuple= 0;
> + return file->multi_range_read_init(&range_seq_funcs, (void*) cache,
> + ranges, mrr_mode, &mrr_buff);
> +}
>
> - data_fields_offset= 0;
> - if (use_emb_key)
> +
> +/*
> + Read the next record returned by MRR for the current join buffer
> +
> + SYNOPSIS
> + next()
> +
> + DESCRIPTION
> + The function reads the next record from the joined table join_tab
psergey: this_function_syntax
> + returned by the MRR handler function multi_range_read_next for
> + the current refill of the join buffer. The record is read into
> + the record buffer used for join_tab records in join operations.
> +
> + RETURN VALUE
> + 0 the next record exists and has been successfully read
> + error code otherwise
> +*/
> +
> +int JOIN_TAB_SCAN_MRR::next()
> +{
> + char **ptr= (char **) cache->get_curr_association_ptr();
> + int rc= join_tab->table->file->multi_range_read_next(ptr) ? -1 : 0;
> + if (!rc)
> {
> - CACHE_FIELD *copy= field_descr;
> - CACHE_FIELD *copy_end= copy+flag_fields;
> - for ( ; copy < copy_end; copy++)
> - data_fields_offset+= copy->length;
> + /*
> + If a record in in an incremental cache contains no fields then the
> + association for the last record in cache will be equal to cache->end_pos
> + */
> + DBUG_ASSERT(cache->buff <= (uchar *) (*ptr) &&
> + (uchar *) (*ptr) <= cache->end_pos);
> + update_virtual_fields(join->thd, join_tab->table);
> + }
> + return rc;
> +}
> +
> +
> +/*
> + Initialize retrieval of range sequence for BKA join algorithm
> +
> + SYNOPSIS
> + bka_range_seq_init()
> + init_params pointer to the BKA join cache object
> + n_ranges the number of ranges obtained
> + flags combination of MRR flags
> +
> + DESCRIPTION
> + The function interprets init_param as a pointer to a JOIN_CACHE_BKA
> + object. The function prepares for an iteration over the join keys
> + built for all records from the cache join buffer.
> +
> + NOTE
> + This function are used only as a callback function.
> +
> + RETURN VALUE
> + init_param value that is to be used as a parameter of bka_range_seq_next()
> +*/
> +
> +static
> +range_seq_t bka_range_seq_init(void *init_param, uint n_ranges, uint flags)
> +{
> + DBUG_ENTER("bka_range_seq_init");
> + JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) init_param;
> + cache->reset(0);
> + DBUG_RETURN((range_seq_t) init_param);
> +}
> +
> +
> +/*
> + Get the next range/key over records from the join buffer used by a BKA cache
> +
> + SYNOPSIS
> + bka_range_seq_next()
> + seq the value returned by bka_range_seq_init
> + range OUT reference to the next range
> +
> + DESCRIPTION
> + The function interprets seq as a pointer to a JOIN_CACHE_BKA
> + object. The function returns a pointer to the range descriptor
> + for the key built over the next record from the join buffer.
> +
> + NOTE
> + This function are used only as a callback function.
> +
> + RETURN VALUE
> + 0 ok, the range structure filled with info about the next range/key
> + 1 no more ranges
> +*/
> +
> +static
> +uint bka_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
> +{
> + DBUG_ENTER("bka_range_seq_next");
> + JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
> + TABLE_REF *ref= &cache->join_tab->ref;
> + key_range *start_key= &range->start_key;
> + if ((start_key->length= cache->get_next_key((uchar **) &start_key->key)))
> + {
> + start_key->keypart_map= (1 << ref->key_parts) - 1;
> + start_key->flag= HA_READ_KEY_EXACT;
> + range->end_key= *start_key;
> + range->end_key.flag= HA_READ_AFTER_KEY;
> + range->ptr= (char *) cache->get_curr_rec();
> + range->range_flag= EQ_RANGE;
> + DBUG_RETURN(0);
> }
> + DBUG_RETURN(1);
> +}
>
> - DBUG_RETURN(rc);
> +
> +/*
> + Check whether range_info orders to skip the next record from BKA buffer
> +
> + SYNOPSIS
> + bka_range_seq_skip_record()
> + seq value returned by bka_range_seq_init()
> + range_info information about the next range
> + rowid [NOT USED] rowid of the record to be checked
> +
> +
> + DESCRIPTION
> + The function interprets seq as a pointer to a JOIN_CACHE_BKA object.
> + The function returns TRUE if the record with this range_info
> + is to be filtered out from the stream of records returned by
> + multi_range_read_next().
> +
> + NOTE
> + This function are used only as a callback function.
> +
> + RETURN VALUE
> + 1 record with this range_info is to be filtered out from the stream
> + of records returned by multi_range_read_next()
> + 0 the record is to be left in the stream
> +*/
> +
> +static
> +bool bka_range_seq_skip_record(range_seq_t rseq, char *range_info, uchar *rowid)
> +{
> + DBUG_ENTER("bka_range_seq_skip_record");
> + JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
> + bool res= cache->get_match_flag_by_pos((uchar *) range_info) ==
> + JOIN_CACHE::MATCH_FOUND;
> + DBUG_RETURN(res);
> +}
> +
> +
> +/*
> + Check if the record combination from BKA cache matches the index condition
> +
> + SYNOPSIS
> + bka_skip_index_tuple()
> + rseq value returned by bka_range_seq_init()
> + range_info record chain for the next range/key returned by MRR
> +
> + DESCRIPTION
> + This is wrapper for JOIN_CACHE_BKA::skip_index_tuple method,
> + see comments there.
> +
> + NOTE
> + This function is used as a RANGE_SEQ_IF::skip_index_tuple callback.
> +
> + RETURN VALUE
> + 0 The record combination satisfies the index condition
> + 1 Otherwise
> +*/
> +
> +static
> +bool bka_skip_index_tuple(range_seq_t rseq, char *range_info)
> +{
> + DBUG_ENTER("bka_skip_index_tuple");
> + JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
> + DBUG_RETURN(cache->skip_index_tuple(range_info));
> }
>
>
> -/*
> - Reset the JOIN_CACHE_BKA_UNIQUE buffer for reading/writing
> +/*
> + Prepare to read the record from BKA cache matching the current joined record
>
> SYNOPSIS
> - reset()
> - for_writing if it's TRUE the function reset the buffer for writing
> + prepare_look_for_matches()
> + skip_last <-> ignore the last record in the buffer (always unused here)
>
> DESCRIPTION
> - This implementation of the virtual function reset() resets the join buffer
> - of the JOIN_CACHE_BKA_UNIQUE class for reading or writing.
> - Additionally to what the default implementation does this function
> - cleans up the hash table allocated within the buffer.
> + The function prepares to iterate over records in the join cache buffer
> + matching the record loaded into the record buffer for join_tab when
> + performing join operation by BKA join algorithm. With BKA algorithms the
> + record loaded into the record buffer for join_tab always has a direct
> + reference to the matching records from the join buffer. When the regular
> + BKA join algorithm is employed the record from join_tab can refer to
> + only one such record.
> + The function sets the counter of the remaining records from the cache
> + buffer that would match the current join_tab record to 1.
>
> - RETURN
> - none
> + RETURN VALUE
> + TRUE there are no records in the buffer to iterate over
> + FALSE otherwise
> */
> -
> -void JOIN_CACHE_BKA_UNIQUE::reset(bool for_writing)
> +
> +bool JOIN_CACHE_BKA::prepare_look_for_matches(bool skip_last)
> {
> - this->JOIN_CACHE::reset(for_writing);
> - if (for_writing && hash_table)
> - cleanup_hash_table();
> - curr_key_entry= hash_table;
> + if (!records)
> + return TRUE;
> + rem_records= 1;
> + return FALSE;
> }
>
> -/*
> - Add a record into the JOIN_CACHE_BKA_UNIQUE buffer
> +
> +/*
> + Get the record from the BKA cache matching the current joined record
>
> SYNOPSIS
> - put_record()
> + get_next_candidate_for_match
>
> DESCRIPTION
> - This implementation of the virtual function put_record writes the next
> - matching record into the join buffer of the JOIN_CACHE_BKA_UNIQUE class.
> - Additionally to what the default implementation does this function
> - performs the following.
> - It extracts from the record the key value used in lookups for matching
> - records and searches for this key in the hash tables from the join cache.
> - If it finds the key in the hash table it joins the record to the chain
> - of records with this key. If the key is not found in the hash table the
> - key is placed into it and a chain containing only the newly added record
> - is attached to the key entry. The key value is either placed in the hash
> - element added for the key or, if the use_emb_key flag is set, remains in
> - the record from the partial join.
> + This method is used for iterations over the records from the join
> + cache buffer when looking for matches for records from join_tab.
> + The method performs the necessary preparations to read the next record
> + from the join buffer into the record buffer by the method
> + read_next_candidate_for_match, or, to skip the next record from the join
> + buffer by the method skip_if_not_needed_match.
> + This implementation of the virtual method get_next_candidate_for_match
> + just decrements the counter of the records that are to be iterated over
> + and returns the value of curr_association as a reference to the position
> + of the beginning of the record fields in the buffer.
>
> - RETURN
> - TRUE if it has been decided that it should be the last record
> - in the join buffer,
> - FALSE otherwise
> + RETURN VALUE
> + pointer to the start of the record fields in the join buffer
> + if the there is another record to iterate over, 0 - otherwise.
> */
>
> -bool JOIN_CACHE_BKA_UNIQUE::put_record()
> +uchar *JOIN_CACHE_BKA::get_next_candidate_for_match()
> {
> - bool is_full;
> - uchar *key;
> - uint key_len= key_length;
> - uchar *key_ref_ptr;
> - uchar *link= 0;
> - TABLE_REF *ref= &join_tab->ref;
> - uchar *next_ref_ptr= pos;
> + if (!rem_records)
> + return 0;
> + rem_records--;
> + return curr_association;
> +}
>
> - pos+= get_size_of_rec_offset();
> - /* Write the record into the join buffer */
> - if (prev_cache)
> - link= prev_cache->get_curr_rec_link();
> - write_record_data(link, &is_full);
>
> - if (use_emb_key)
> - key= get_curr_emb_key();
> - else
> - {
> - /* Build the key over the fields read into the record buffers */
> - cp_buffer_from_ref(join->thd, join_tab->table, ref);
> - key= ref->key_buff;
> - }
> +/*
> + Check whether the matching record from the BKA cache is to be skipped
>
> - /* Look for the key in the hash table */
> - if (key_search(key, key_len, &key_ref_ptr))
> - {
> - uchar *last_next_ref_ptr;
> - /*
> - The key is found in the hash table.
> - Add the record to the circular list of the records attached to this key.
> - Below 'rec' is the record to be added into the record chain for the found
> - key, 'key_ref' points to a flatten representation of the st_key_entry
> - structure that contains the key and the head of the record chain.
> - */
> - last_next_ref_ptr= get_next_rec_ref(key_ref_ptr+get_size_of_key_offset());
> - /* rec->next_rec= key_entry->last_rec->next_rec */
> - memcpy(next_ref_ptr, last_next_ref_ptr, get_size_of_rec_offset());
> - /* key_entry->last_rec->next_rec= rec */
> - store_next_rec_ref(last_next_ref_ptr, next_ref_ptr);
> - /* key_entry->last_rec= rec */
> - store_next_rec_ref(key_ref_ptr+get_size_of_key_offset(), next_ref_ptr);
> - }
> - else
> - {
> - /*
> - The key is not found in the hash table.
> - Put the key into the join buffer linking it with the keys for the
> - corresponding hash entry. Create a circular list with one element
> - referencing the record and attach the list to the key in the buffer.
> - */
> - uchar *cp= last_key_entry;
> - cp-= get_size_of_rec_offset()+get_size_of_key_offset();
> - store_next_key_ref(key_ref_ptr, cp);
> - store_null_key_ref(cp);
> - store_next_rec_ref(next_ref_ptr, next_ref_ptr);
> - store_next_rec_ref(cp+get_size_of_key_offset(), next_ref_ptr);
> - if (use_emb_key)
> - {
> - cp-= get_size_of_rec_offset();
> - store_emb_key_ref(cp, key);
> - }
> - else
> - {
> - cp-= key_len;
> - memcpy(cp, key, key_len);
> - }
> - last_key_entry= cp;
> - /* Increment the counter of key_entries in the hash table */
> - key_entries++;
> - }
> - return is_full;
> + SYNOPSIS
> + skip_next_candidate_for_match
> + rec_ptr pointer to the position in the join buffer right after
> + the previous record
> +
> + DESCRIPTION
> + This implementation of the virtual function just calls the
> + method get_match_flag_by_pos to check whether the record referenced
> + by ref_ptr has its match flag set to MATCH_FOUND.
> +
> + RETURN VALUE
> + TRUE the record referenced by rec_ptr has its match flag set to
> + MATCH_FOUND
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE_BKA::skip_next_candidate_for_match(uchar *rec_ptr)
> +{
> + return join_tab->check_only_first_match() &&
> + (get_match_flag_by_pos(rec_ptr) == MATCH_FOUND);
> }
>
>
> /*
> - Read the next record from the JOIN_CACHE_BKA_UNIQUE buffer
> + Read the next record from the BKA join cache buffer when looking for matches
>
> SYNOPSIS
> - get_record()
> + read_next_candidate_for_match
> + rec_ptr pointer to the position in the join buffer right after
> + the previous record
>
> DESCRIPTION
> - Additionally to what the default implementation of the virtual
> - function get_record does this implementation skips the link element
> - used to connect the records with the same key into a chain.
> -
> - RETURN
> - TRUE - there are no more records to read from the join buffer
> - FALSE - otherwise
> + This implementation of the virtual method read_next_candidate_for_match
> + calls the method get_record_by_pos to read the record referenced by rec_ptr
> + from the join buffer into the record buffer. If this record refers to
> + fields in the other join buffers the call of get_record_by_po ensures that
> + these fields are read into the corresponding record buffers as well.
> + This function is supposed to be called after a successful call of
> + the method get_next_candidate_for_match.
> +
> + RETURN VALUE
> + none
> */
>
> -bool JOIN_CACHE_BKA_UNIQUE::get_record()
> -{
> - pos+= get_size_of_rec_offset();
> - return this->JOIN_CACHE::get_record();
> -}
> +void JOIN_CACHE_BKA::read_next_candidate_for_match(uchar *rec_ptr)
> +{
> + get_record_by_pos(rec_ptr);
> +}
>
>
> -/*
> - Skip record from the JOIN_CACHE_BKA_UNIQUE join buffer if its match flag is on
> +/*
> + Initialize the BKA join cache
>
> SYNOPSIS
> - skip_record_if_match()
> + init
>
> DESCRIPTION
> - This implementation of the virtual function skip_record_if_match does
> - the same as the default implementation does, but it takes into account
> - the link element used to connect the records with the same key into a chain.
> + The function initializes the cache structure. It is supposed to be called
> + right after a constructor for the JOIN_CACHE_BKA.
>
> - RETURN
> - TRUE - the match flag is on and the record has been skipped
> - FALSE - the match flag is off
> + NOTES
> + The function first constructs a companion object of the type
> + JOIN_TAB_SCAN_MRR, then it calls the init method of the parent class.
> +
> + RETURN VALUE
> + 0 initialization with buffer allocations has been succeeded
> + 1 otherwise
> */
>
> -bool JOIN_CACHE_BKA_UNIQUE::skip_record_if_match()
> +int JOIN_CACHE_BKA::init()
> {
> - uchar *save_pos= pos;
> - pos+= get_size_of_rec_offset();
> - if (!this->JOIN_CACHE::skip_record_if_match())
> - {
> - pos= save_pos;
> - return FALSE;
> - }
> - return TRUE;
> + bool check_only_first_match= join_tab->check_only_first_match();
> +
> + RANGE_SEQ_IF rs_funcs= { bka_range_seq_init,
> + bka_range_seq_next,
> + check_only_first_match ?
> + bka_range_seq_skip_record : 0,
> + bka_skip_index_tuple };
> +
> + DBUG_ENTER("JOIN_CACHE_BKA::init");
> +
> + if (!(join_tab_scan= new JOIN_TAB_SCAN_MRR(join, join_tab,
> + mrr_mode, rs_funcs)))
> + DBUG_RETURN(1);
> +
> + DBUG_RETURN(JOIN_CACHE::init());
> }
>
>
> /*
> - Search for a key in the hash table of the join buffer
> + Get the key built over the next record from BKA join buffer
>
> SYNOPSIS
> - key_search()
> - key pointer to the key value
> - key_len key value length
> - key_ref_ptr OUT position of the reference to the next key from
> - the hash element for the found key , or
> - a position where the reference to the the hash
> - element for the key is to be added in the
> - case when the key has not been found
> -
> + get_next_key()
> + key pointer to the buffer where the key value is to be placed
> +
> DESCRIPTION
> - The function looks for a key in the hash table of the join buffer.
> - If the key is found the functionreturns the position of the reference
> - to the next key from to the hash element for the given key.
> - Otherwise the function returns the position where the reference to the
> - newly created hash element for the given key is to be added.
> + The function reads key fields from the current record in the join buffer.
> + and builds the key value out of these fields that will be used to access
> + the 'join_tab' table. Some of key fields may belong to previous caches.
> + They are accessed via record references to the record parts stored in the
> + previous join buffers. The other key fields always are placed right after
> + the flag fields of the record.
> + If the key is embedded, which means that its value can be read directly
> + from the join buffer, then *key is set to the beginning of the key in
> + this buffer. Otherwise the key is built in the join_tab->ref->key_buff.
> + The function returns the length of the key if it succeeds ro read it.
> + If is assumed that the functions starts reading at the position of
> + the record length which is provided for each records in a BKA cache.
> + After the key is built the 'pos' value points to the first position after
> + the current record.
> + The function just skips the records with MATCH_IMPOSSIBLE in the
> + match flag field if there is any.
> + The function returns 0 if the initial position is after the beginning
> + of the record fields for last record from the join buffer.
>
> - RETURN
> - TRUE - the key is found in the hash table
> - FALSE - otherwise
> + RETURN VALUE
> + length of the key value - if the starting value of 'pos' points to
> + the position before the fields for the last record,
> + 0 - otherwise.
> */
>
> -bool JOIN_CACHE_BKA_UNIQUE::key_search(uchar *key, uint key_len,
> - uchar **key_ref_ptr)
> +uint JOIN_CACHE_BKA::get_next_key(uchar ** key)
> {
> - bool is_found= FALSE;
> - uint idx= get_hash_idx(key, key_length);
> - uchar *ref_ptr= hash_table+size_of_key_ofs*idx;
> - while (!is_null_key_ref(ref_ptr))
> - {
> - uchar *next_key;
> - ref_ptr= get_next_key_ref(ref_ptr);
> - next_key= use_emb_key ? get_emb_key(ref_ptr-get_size_of_rec_offset()) :
> - ref_ptr-key_length;
> + uint len;
> + uint32 rec_len;
> + uchar *init_pos;
> + JOIN_CACHE *cache;
> +
> +start:
>
> - if (memcmp(next_key, key, key_len) == 0)
> + /* Any record in a BKA cache is prepended with its length */
> + DBUG_ASSERT(with_length);
> +
> + if ((pos+size_of_rec_len) > last_rec_pos || !records)
> + return 0;
> +
> + /* Read the length of the record */
> + rec_len= get_rec_length(pos);
> + pos+= size_of_rec_len;
> + init_pos= pos;
> +
> + /* Read a reference to the previous cache if any */
> + if (prev_cache)
> + pos+= prev_cache->get_size_of_rec_offset();
> +
> + curr_rec_pos= pos;
> +
> + /* Read all flag fields of the record */
> + read_flag_fields();
> +
> + if (with_match_flag &&
> + (Match_flag) curr_rec_pos[0] == MATCH_IMPOSSIBLE )
> + {
> + pos= init_pos+rec_len;
> + goto start;
> + }
> +
> + if (use_emb_key)
> + {
> + /* An embedded key is taken directly from the join buffer */
> + *key= pos;
> + len= emb_key_length;
> + }
> + else
> + {
> + /* Read key arguments from previous caches if there are any such fields */
> + if (external_key_arg_fields)
> {
> - is_found= TRUE;
> - break;
> + uchar *rec_ptr= curr_rec_pos;
> + uint key_arg_count= external_key_arg_fields;
> + CACHE_FIELD **copy_ptr= blob_ptr-key_arg_count;
> + for (cache= prev_cache; key_arg_count; cache= cache->prev_cache)
> + {
> + uint len= 0;
> + DBUG_ASSERT(cache);
> + rec_ptr= cache->get_rec_ref(rec_ptr);
> + while (!cache->referenced_fields)
> + {
> + cache= cache->prev_cache;
> + DBUG_ASSERT(cache);
> + rec_ptr= cache->get_rec_ref(rec_ptr);
> + }
> + while (key_arg_count &&
> + cache->read_referenced_field(*copy_ptr, rec_ptr, &len))
> + {
> + copy_ptr++;
> + --key_arg_count;
> + }
> + }
> }
> +
> + /*
> + Read the other key arguments from the current record. The fields for
> + these arguments are always first in the sequence of the record's fields.
> + */
> + CACHE_FIELD *copy= field_descr+flag_fields;
> + CACHE_FIELD *copy_end= copy+local_key_arg_fields;
> + bool blob_in_rec_buff= blob_data_is_in_rec_buff(curr_rec_pos);
> + for ( ; copy < copy_end; copy++)
> + read_record_field(copy, blob_in_rec_buff);
> +
> + /* Build the key over the fields read into the record buffers */
> + TABLE_REF *ref= &join_tab->ref;
> + cp_buffer_from_ref(join->thd, join_tab->table, ref);
> + *key= ref->key_buff;
> + len= ref->key_length;
> }
> - *key_ref_ptr= ref_ptr;
> - return is_found;
> -}
> -
>
> -/*
> - Calclulate hash value for a key in the hash table of the join buffer
> -
> - SYNOPSIS
> - get_hash_idx()
> - key pointer to the key value
> - key_len key value length
> -
> - DESCRIPTION
> - The function calculates an index of the hash entry in the hash table
> - of the join buffer for the given key
> -
> - RETURN
> - the calculated index of the hash entry for the given key.
> -*/
> + pos= init_pos+rec_len;
>
> -uint JOIN_CACHE_BKA_UNIQUE::get_hash_idx(uchar* key, uint key_len)
> -{
> - ulong nr= 1;
> - ulong nr2= 4;
> - uchar *pos= key;
> - uchar *end= key+key_len;
> - for (; pos < end ; pos++)
> - {
> - nr^= (ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
> - nr2+= 3;
> - }
> - return nr % hash_entries;
> -}
> + return len;
> +}
>
>
> -/*
> - Clean up the hash table of the join buffer
> +/*
> + Check the index condition of the joined table for a record from the BKA cache
>
> SYNOPSIS
> - cleanup_hash_table()
> - key pointer to the key value
> - key_len key value length
> -
> + skip_index_tuple()
> + range_info pointer to the record returned by MRR
> +
> DESCRIPTION
> - The function cleans up the hash table in the join buffer removing all
> - hash elements from the table.
> + This function is invoked from MRR implementation to check if an index
psergey: this_function_syntax
> + tuple matches the index condition. It is used in the case where the index
> + condition actually depends on both columns of the used index and columns
> + from previous tables.
> +
> + NOTES
> + Accessing columns of the previous tables requires special handling with
> + BKA. The idea of BKA is to collect record combinations in a buffer and
> + then do a batch of ref access lookups, i.e. by the time we're doing a
> + lookup its previous-records-combination is not in prev_table->record[0]
> + but somewhere in the join buffer.
> + We need to get it from there back into prev_table(s)->record[0] before we
> + can evaluate the index condition, and that's why we need this function
> + instead of regular IndexConditionPushdown.
>
> - RETURN
> - none
> + NOTES
> + Possible optimization:
> + Before we unpack the record from a previous table
> + check if this table is used in the condition.
> + If so then unpack the record otherwise skip the unpacking.
> + This should be done by a special virtual method
> + get_partial_record_by_pos().
> +
> + RETURN VALUE
> + 1 the record combination does not satisfies the index condition
> + 0 otherwise
> */
>
> -void JOIN_CACHE_BKA_UNIQUE:: cleanup_hash_table()
> +bool JOIN_CACHE_BKA::skip_index_tuple(char *range_info)
psergey: according to the coding style, there should be no space after "::".
> {
> - last_key_entry= hash_table;
> - bzero(hash_table, (buff+buff_size)-hash_table);
> - key_entries= 0;
> + DBUG_ENTER("JOIN_CACHE_BKA::skip_index_tuple");
> + get_record_by_pos((uchar*)range_info);
> + DBUG_RETURN(!join_tab->cache_idx_cond->val_int());
> }
>
>
> +
> /*
> - Initialize retrieval of range sequence for BKA_UNIQUE algorithm
> + Initialize retrieval of range sequence for the BKAH join algorithm
>
> SYNOPSIS
> - bka_range_seq_init()
> - init_params pointer to the BKA_INIQUE join cache object
> + bkah_range_seq_init()
> + init_params pointer to the BKAH join cache object
> n_ranges the number of ranges obtained
> - flags combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
> + flags combination of MRR flags
>
> DESCRIPTION
> - The function interprets init_param as a pointer to a JOIN_CACHE_BKA_UNIQUE
> - object. The function prepares for an iteration over the unique join keys
> + The function interprets init_param as a pointer to a JOIN_CACHE_BKAH
> + object. The function prepares for an iteration over distinct join keys
> built over the records from the cache join buffer.
>
> NOTE
> This function are used only as a callback function.
>
> - RETURN
> + RETURN VALUE
> init_param value that is to be used as a parameter of
> - bka_unique_range_seq_next()
> + bkah_range_seq_next()
> */
>
> static
> -range_seq_t bka_unique_range_seq_init(void *init_param, uint n_ranges,
> - uint flags)
> +range_seq_t bkah_range_seq_init(void *init_param, uint n_ranges, uint flags)
> {
> - DBUG_ENTER("bka_unique_range_seq_init");
> - JOIN_CACHE_BKA_UNIQUE *cache= (JOIN_CACHE_BKA_UNIQUE *) init_param;
> + DBUG_ENTER("bkah_range_seq_init");
> + JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) init_param;
> cache->reset(0);
> DBUG_RETURN((range_seq_t) init_param);
> }
>
>
> /*
> - Get the key over the next record from the join buffer used by BKA_UNIQUE
> + Get the next range/key over records from the join buffer of a BKAH cache
>
> SYNOPSIS
> - bka_unique_range_seq_next()
> - seq value returned by bka_unique_range_seq_init()
> + bkah_range_seq_next()
> + seq value returned by bkah_range_seq_init()
> range OUT reference to the next range
>
> DESCRIPTION
> - The function interprets seq as a pointer to the JOIN_CACHE_BKA_UNIQUE
> + The function interprets seq as a pointer to a JOIN_CACHE_BKAH
psergey: this_function_syntax
> object. The function returns a pointer to the range descriptor
> for the next unique key built over records from the join buffer.
>
> NOTE
> This function are used only as a callback function.
>
> - RETURN
> - 0 ok, the range structure filled with info about the next key
> + RETURN VALUE
> + 0 ok, the range structure filled with info about the next range/key
> 1 no more ranges
> */
>
> static
> -uint bka_unique_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
> +uint bkah_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
> {
> - DBUG_ENTER("bka_unique_range_seq_next");
> - JOIN_CACHE_BKA_UNIQUE *cache= (JOIN_CACHE_BKA_UNIQUE *) rseq;
> + DBUG_ENTER("bkah_range_seq_next");
> + JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq;
> TABLE_REF *ref= &cache->join_tab->ref;
> key_range *start_key= &range->start_key;
> if ((start_key->length= cache->get_next_key((uchar **) &start_key->key)))
> @@ -2990,16 +4118,16 @@
>
>
> /*
> - Check whether range_info orders to skip the next record from BKA_UNIQUE buffer
> + Check whether range_info orders to skip the next record from BKAH join buffer
>
> SYNOPSIS
> - bka_unique_range_seq_skip_record()
> - seq value returned by bka_unique_range_seq_init()
> - range_info information about the next range
> + bkah_range_seq_skip_record()
> + seq value returned by bkah_range_seq_init()
> + range_info information about the next range/key returned by MRR
> rowid [NOT USED] rowid of the record to be checked (not used)
>
> DESCRIPTION
> - The function interprets seq as a pointer to the JOIN_CACHE_BKA_UNIQUE
> + The function interprets seq as a pointer to a JOIN_CACHE_BKAH
psergey: this_function_syntax
> object. The function returns TRUE if the record with this range_info
> is to be filtered out from the stream of records returned by
> multi_range_read_next().
> @@ -3007,288 +4135,169 @@
> NOTE
> This function are used only as a callback function.
>
> - RETURN
> + RETURN VALUE
> 1 record with this range_info is to be filtered out from the stream
> of records returned by multi_range_read_next()
> 0 the record is to be left in the stream
> */
>
> static
> -bool bka_unique_range_seq_skip_record(range_seq_t rseq, char *range_info,
> - uchar *rowid)
> +bool bkah_range_seq_skip_record(range_seq_t rseq, char *range_info,
> + uchar *rowid)
> {
> - DBUG_ENTER("bka_unique_range_seq_skip_record");
> - JOIN_CACHE_BKA_UNIQUE *cache= (JOIN_CACHE_BKA_UNIQUE *) rseq;
> + DBUG_ENTER("bkah_range_seq_skip_record");
> + JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq;
> bool res= cache->check_all_match_flags_for_key((uchar *) range_info);
> DBUG_RETURN(res);
> }
>
>
> /*
> - Check if the record combination matches the index condition
> + Check if the record combination from BKAH cache matches the index condition
>
> SYNOPSIS
> - JOIN_CACHE_BKA_UNIQUE::skip_index_tuple()
> - rseq Value returned by bka_range_seq_init()
> - range_info MRR range association data
> + bkah_skip_index_tuple()
> + rseq value returned by bka_range_seq_init()
> + range_info record chain for the next range/key returned by MRR
>
> DESCRIPTION
> - See JOIN_CACHE_BKA::skip_index_tuple().
> - This function is the variant for use with
> - JOIN_CACHE_BKA_UNIQUE. The difference from JOIN_CACHE_BKA case is that
> - there may be multiple previous table record combinations that share the
> - same key, i.e. they map to the same MRR range.
> - As a consequence, we need to loop through all previous table record
> - combinations that match the given MRR range key range_info until we find
> - one that satisfies the index condition.
> + This is wrapper for JOIN_CACHE_BKA_UNIQUE::skip_index_tuple method,
> + see comments there.
>
> NOTE
> - Possible optimization:
> - Before we unpack the record from a previous table
> - check if this table is used in the condition.
> - If so then unpack the record otherwise skip the unpacking.
> - This should be done by a special virtual method
> - get_partial_record_by_pos().
> -
> - RETURN
> - 0 The record combination satisfies the index condition
> - 1 Otherwise
> -
> -
> + This function is used as a RANGE_SEQ_IF::skip_index_tuple callback.
> +
> + RETURN VALUE
> + 0 some records from the chain satisfy the index condition
> + 1 otherwise
> */
>
> -bool JOIN_CACHE_BKA_UNIQUE::skip_index_tuple(range_seq_t rseq, char *range_info)
> +static
> +bool bkah_skip_index_tuple(range_seq_t rseq, char *range_info)
> {
> - DBUG_ENTER("JOIN_CACHE_BKA_UNIQUE::skip_index_tuple");
> - JOIN_CACHE_BKA_UNIQUE *cache= (JOIN_CACHE_BKA_UNIQUE *) rseq;
> - uchar *last_rec_ref_ptr= cache->get_next_rec_ref((uchar*) range_info);
> - uchar *next_rec_ref_ptr= last_rec_ref_ptr;
> - do
> - {
> - next_rec_ref_ptr= cache->get_next_rec_ref(next_rec_ref_ptr);
> - uchar *rec_ptr= next_rec_ref_ptr + cache->rec_fields_offset;
> - cache->get_record_by_pos(rec_ptr);
> - if (join_tab->cache_idx_cond->val_int())
> - DBUG_RETURN(FALSE);
> - } while(next_rec_ref_ptr != last_rec_ref_ptr);
> - DBUG_RETURN(TRUE);
> + DBUG_ENTER("bka_unique_skip_index_tuple");
> + JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq;
> + DBUG_RETURN(cache->skip_index_tuple(range_info));
> }
>
>
> /*
> - Check if the record combination matches the index condition
> + Prepare to read record from BKAH cache matching the current joined record
>
> SYNOPSIS
> - bka_unique_skip_index_tuple()
> - rseq Value returned by bka_range_seq_init()
> - range_info MRR range association data
> -
> - DESCRIPTION
> - This is wrapper for JOIN_CACHE_BKA_UNIQUE::skip_index_tuple method,
> - see comments there.
> + prepare_look_for_matches()
> + skip_last <-> ignore the last record in the buffer (always unused here)
>
> - NOTE
> - This function is used as a RANGE_SEQ_IF::skip_index_tuple callback.
> -
> - RETURN
> - 0 The record combination satisfies the index condition
> - 1 Otherwise
> + DESCRIPTION
> + The function prepares to iterate over records in the join cache buffer
> + matching the record loaded into the record buffer for join_tab when
> + performing join operation by BKAH join algorithm. With BKAH algorithm, if
> + association labels are used, then record loaded into the record buffer
> + for join_tab always has a direct reference to the chain of the mathing
> + records from the join buffer. If association labels are not used then
> + then the chain of the matching records is obtained by the call of the
> + get_key_chain_by_join_key function.
> +
> + RETURN VALUE
> + TRUE there are no records in the buffer to iterate over
> + FALSE otherwise
> */
> -
> -static
> -bool bka_unique_skip_index_tuple(range_seq_t rseq, char *range_info)
> +
> +bool JOIN_CACHE_BKAH::prepare_look_for_matches(bool skip_last)
> {
> - DBUG_ENTER("bka_unique_skip_index_tuple");
> - JOIN_CACHE_BKA_UNIQUE *cache= (JOIN_CACHE_BKA_UNIQUE *) rseq;
> - DBUG_RETURN(cache->skip_index_tuple(rseq, range_info));
> + last_matching_rec_ref_ptr= next_matching_rec_ref_ptr= 0;
> + if (no_association &&
> + (curr_matching_chain= get_matching_chain_by_join_key()))
> + return 1;
> + last_matching_rec_ref_ptr= get_next_rec_ref(curr_matching_chain);
> + return 0;
> }
>
> -
> /*
> - Using BKA_UNIQUE find matches from the next table for records from join buffer
> + Initialize the BKAH join cache
>
> SYNOPSIS
> - join_matching_records()
> - skip_last do not look for matches for the last partial join record
> + init
>
> DESCRIPTION
> - This function can be used only when the table join_tab can be accessed
> - by keys built over the fields of previous join tables.
> - The function retrieves all keys from the hash table of the join buffer
> - built for partial join records from the buffer. For each of these keys
> - the function performs an index lookup and tries to match records yielded
> - by this lookup with records from the join buffer attached to the key.
> - If a match is found the function will call the sub_select function trying
> - to look for matches for the remaining join operations.
> - This function does not assume that matching records are necessarily
> - returned with references to the keys by which they were found. If the call
> - of the function multi_range_read_init returns flags with
> - HA_MRR_NO_ASSOCIATION then a search for the key built from the returned
> - record is carried on. The search is performed by probing in in the hash
> - table of the join buffer.
> - This function currently is called only from the function join_records.
> - It's assumed that this function is always called with the skip_last
> - parameter equal to false.
> -
> - RETURN
> - return one of enum_nested_loop_state
> + The function initializes the cache structure. It is supposed to be called
psergey: this_function_syntax
> + right after a constructor for the JOIN_CACHE_BKAH.
> +
> + NOTES
> + The function first constructs a companion object of the type
> + JOIN_TAB_SCAN_MRR, then it calls the init method of the parent class.
> +
> + RETURN VALUE
> + 0 initialization with buffer allocations has been succeeded
> + 1 otherwise
> */
>
> -enum_nested_loop_state
> -JOIN_CACHE_BKA_UNIQUE::join_matching_records(bool skip_last)
> +int JOIN_CACHE_BKAH::init()
> {
> - int error;
> - uchar *key_chain_ptr;
> - handler *file= join_tab->table->file;
> - enum_nested_loop_state rc= NESTED_LOOP_OK;
> bool check_only_first_match= join_tab->check_only_first_match();
> - bool no_association= test(mrr_mode & HA_MRR_NO_ASSOCIATION);
>
> - /* Set functions to iterate over keys in the join buffer */
> - RANGE_SEQ_IF seq_funcs= { bka_unique_range_seq_init,
> - bka_unique_range_seq_next,
> - check_only_first_match && !no_association ?
> - bka_unique_range_seq_skip_record : 0,
> - join_tab->cache_idx_cond ?
> - bka_unique_skip_index_tuple : 0 };
> -
> - /* The value of skip_last must be always FALSE when this function is called */
> - DBUG_ASSERT(!skip_last);
> -
> - /* Return at once if there are no records in the join buffer */
> - if (!records)
> - return NESTED_LOOP_OK;
> -
> - rc= init_join_matching_records(&seq_funcs, key_entries);
> - if (rc != NESTED_LOOP_OK)
> - goto finish;
> + no_association= test(mrr_mode & HA_MRR_NO_ASSOCIATION);
>
> - while (!(error= file->multi_range_read_next((char **) &key_chain_ptr)))
> - {
> - if (no_association)
> - {
> - uchar *key_ref_ptr;
> - TABLE *table= join_tab->table;
> - TABLE_REF *ref= &join_tab->ref;
> - KEY *keyinfo= table->key_info+ref->key;
> - /*
> - Build the key value out of the record returned by the call of
> - multi_range_read_next in the record buffer
> - */
> - key_copy(ref->key_buff, table->record[0], keyinfo, ref->key_length);
> - /* Look for this key in the join buffer */
> - if (!key_search(ref->key_buff, ref->key_length, &key_ref_ptr))
> - continue;
> - key_chain_ptr= key_ref_ptr+get_size_of_key_offset();
> - }
> + RANGE_SEQ_IF rs_funcs= { bkah_range_seq_init,
> + bkah_range_seq_next,
> + check_only_first_match && !no_association ?
> + bkah_range_seq_skip_record : 0,
> + bkah_skip_index_tuple };
>
> - uchar *last_rec_ref_ptr= get_next_rec_ref(key_chain_ptr);
> - uchar *next_rec_ref_ptr= last_rec_ref_ptr;
> - do
> - {
> - next_rec_ref_ptr= get_next_rec_ref(next_rec_ref_ptr);
> - uchar *rec_ptr= next_rec_ref_ptr+rec_fields_offset;
> + DBUG_ENTER("JOIN_CACHE_BKAH::init");
>
> - if (join->thd->killed)
> - {
> - /* The user has aborted the execution of the query */
> - join->thd->send_kill_message();
> - rc= NESTED_LOOP_KILLED;
> - goto finish;
> - }
> - /*
> - If only the first match is needed and it has been already found
> - for the associated partial join record then the returned candidate
> - is discarded.
> - */
> - if (rc == NESTED_LOOP_OK &&
> - (!check_only_first_match || !get_match_flag_by_pos(rec_ptr)))
> - {
> - get_record_by_pos(rec_ptr);
> - update_virtual_fields(join->thd, join_tab->table);
> - rc= generate_full_extensions(rec_ptr);
> - if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
> - goto finish;
> - }
> - }
> - while (next_rec_ref_ptr != last_rec_ref_ptr);
> - }
> + if (!(join_tab_scan= new JOIN_TAB_SCAN_MRR(join, join_tab,
> + mrr_mode, rs_funcs)))
> + DBUG_RETURN(1);
>
> - if (error > 0 && error != HA_ERR_END_OF_FILE)
> - return NESTED_LOOP_ERROR;
> -finish:
> - return end_join_matching_records(rc);
> + DBUG_RETURN(JOIN_CACHE_HASHED::init());
> }
>
>
> /*
> - Check whether all records in a key chain have their match flags set on
> + Check the index condition of the joined table for a record from the BKA cache
>
> SYNOPSIS
> - check_all_match_flags_for_key()
> - key_chain_ptr
> -
> + skip_index_tuple()
> + range_info record chain returned by MRR
> +
> DESCRIPTION
> - This function retrieves records in the given circular chain and checks
> - whether their match flags are set on. The parameter key_chain_ptr shall
> - point to the position in the join buffer storing the reference to the
> - last element of this chain.
> -
> - RETURN
> - TRUE if each retrieved record has its match flag set on
> - FALSE otherwise
> + See JOIN_CACHE_BKA::skip_index_tuple().
> + This function is the variant for use with rhe class JOIN_CACHE_BKAH.
> + The difference from JOIN_CACHE_BKA case is that there may be multiple
> + previous table record combinations that share the same key(MRR range).
> + As a consequence, we need to loop through the chain of all table record
> + combinations that match the given MRR range key range_info until we find
> + one that satisfies the index condition.
> +
> + NOTE
> + Possible optimization:
> + Before we unpack the record from a previous table
> + check if this table is used in the condition.
> + If so then unpack the record otherwise skip the unpacking.
> + This should be done by a special virtual method
> + get_partial_record_by_pos().
> +
> + RETURN VALUE
> + 1 any record combination from the chain referred by range_info
> + does not satisfy the index condition
> + 0 otherwise
> +
> +
> */
>
> -bool JOIN_CACHE_BKA_UNIQUE::check_all_match_flags_for_key(uchar *key_chain_ptr)
> +bool JOIN_CACHE_BKAH::skip_index_tuple(char *range_info)
> {
> - uchar *last_rec_ref_ptr= get_next_rec_ref(key_chain_ptr);
> + uchar *last_rec_ref_ptr= get_next_rec_ref((uchar*) range_info);
> uchar *next_rec_ref_ptr= last_rec_ref_ptr;
> + DBUG_ENTER("JOIN_CACHE_BKAH::skip_index_tuple");
> do
> {
> next_rec_ref_ptr= get_next_rec_ref(next_rec_ref_ptr);
> - uchar *rec_ptr= next_rec_ref_ptr+rec_fields_offset;
> - if (!get_match_flag_by_pos(rec_ptr))
> - return FALSE;
> - }
> - while (next_rec_ref_ptr != last_rec_ref_ptr);
> - return TRUE;
> -}
> -
> -
> -/*
> - Get the next key built for the records from BKA_UNIQUE join buffer
> -
> - SYNOPSIS
> - get_next_key()
> - key pointer to the buffer where the key value is to be placed
> -
> - DESCRIPTION
> - The function reads the next key value stored in the hash table of the
> - join buffer. Depending on the value of the use_emb_key flag of the
> - join cache the value is read either from the table itself or from
> - the record field where it occurs.
> -
> - RETURN
> - length of the key value - if the starting value of 'cur_key_entry' refers
> - to the position after that referred by the the value of 'last_key_entry'
> - 0 - otherwise.
> -*/
> -
> -uint JOIN_CACHE_BKA_UNIQUE::get_next_key(uchar ** key)
> -{
> - if (curr_key_entry == last_key_entry)
> - return 0;
> -
> - curr_key_entry-= key_entry_length;
> -
> - *key = use_emb_key ? get_emb_key(curr_key_entry) : curr_key_entry;
> -
> - DBUG_ASSERT(*key >= buff && *key < hash_table);
> -
> - return key_length;
> + uchar *rec_ptr= next_rec_ref_ptr + rec_fields_offset;
> + get_record_by_pos(rec_ptr);
> + if (join_tab->cache_idx_cond->val_int())
> + DBUG_RETURN(FALSE);
> + } while(next_rec_ref_ptr != last_rec_ref_ptr);
> + DBUG_RETURN(TRUE);
> }
> -
> -
> -/****************************************************************************
> - * Join cache module end
> - ****************************************************************************/
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/sql_select.cc maria-5.3-mwl128-noc/sql/sql_select.cc
> --- maria-5.3-mwl128-clean/sql/sql_select.cc 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/sql_select.cc 2010-11-10 12:09:51.000000000 +0200
> @@ -100,6 +100,7 @@
> static Item*
> make_cond_after_sjm(Item *root_cond, Item *cond, table_map tables, table_map sjm_tables);
> static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
> +static void revise_cache_usage(JOIN_TAB *join_tab);
> static bool make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after);
> static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables);
> static void update_depend_map(JOIN *join);
> @@ -178,12 +179,14 @@
> int join_read_always_key_or_null(JOIN_TAB *tab);
> int join_read_next_same_or_null(READ_RECORD *info);
> static COND *make_cond_for_table(Item *cond,table_map table,
> - table_map used_table,
> - bool exclude_expensive_cond);
> + table_map used_table,
> + bool exclude_expensive_cond,
> + bool retain_ref_cond);
> static COND *make_cond_for_table_from_pred(Item *root_cond, Item *cond,
> table_map tables,
> table_map used_table,
> - bool exclude_expensive_cond);
> + bool exclude_expensive_cond,
> + bool retain_ref_cond);
>
> static Item* part_of_refkey(TABLE *form,Field *field);
> uint find_shortest_key(TABLE *table, const key_map *usable_keys);
> @@ -926,7 +929,7 @@
> if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
> {
> COND *table_independent_conds=
> - make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, FALSE);
> + make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, FALSE, FALSE);
> DBUG_EXECUTE("where",
> print_where(table_independent_conds,
> "where after opt_sum_query()",
> @@ -1631,6 +1634,62 @@
> }
>
>
> +/*
> + Shrink join buffers used for preceding tables to reduce the occupied space
> +
> + SYNOPSIS
> + shrink_join_buffers()
> + jt table up to which the buffers are to be shrunk
> + curr_space the size of the space used by the buffers for tables 1..jt
> + needed_space the size of the space that has to be used by these buffers
> +
> + DESCRIPTION
> + The function makes an attempt to shrink all join buffers used for the
> + tables starting from the first up to jt to reduce the total size of the
> + space occupied by the buffers used for tables 1,...,jt from curr_space
> + to needed_space.
> + The function assumes that the buffer for the table jt has not been
> + allocated yet.
> +
> + RETURN
> + FALSE if all buffer have been successfully shrunk
> + TRUE otherwise
> +*/
> +
> +bool JOIN::shrink_join_buffers(JOIN_TAB *jt,
> + ulonglong curr_space,
> + ulonglong needed_space)
> +{
> + JOIN_CACHE *cache;
> + for (JOIN_TAB *tab= join_tab+const_tables; tab < jt; tab++)
> + {
> + cache= tab->cache;
> + if (cache)
> + {
> + ulong buff_size;
> + if (needed_space < cache->get_min_join_buffer_size())
> + return TRUE;
> + if (cache->shrink_join_buffer_in_ratio(curr_space, needed_space))
> + {
> + revise_cache_usage(tab);
> + return TRUE;
> + }
> + buff_size= cache->get_join_buffer_size();
> + curr_space-= buff_size;
> + needed_space-= buff_size;
> + }
> + }
> +
> + cache= jt->cache;
> + DBUG_ASSERT(cache);
> + if (needed_space < cache->get_min_join_buffer_size())
> + return TRUE;
> + cache->set_join_buffer_size(needed_space);
> +
> + return FALSE;
> +}
> +
> +
> int
> JOIN::reinit()
> {
> @@ -2197,7 +2256,7 @@
>
> Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having,
> used_tables,
> - (table_map)0, FALSE);
> + (table_map)0, FALSE, FALSE);
> if (sort_table_cond)
> {
> if (!curr_table->select)
> @@ -2220,7 +2279,7 @@
> QT_ORDINARY););
> curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having,
> ~ (table_map) 0,
> - ~used_tables, FALSE);
> + ~used_tables, FALSE, FALSE);
> DBUG_EXECUTE("where",print_where(curr_join->tmp_having,
> "having after sort",
> QT_ORDINARY););
> @@ -5836,15 +5895,15 @@
> Find how much space the prevous read not const tables takes in cache.
> */
>
> -void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
> +void JOIN_TAB::calc_used_field_length(bool max_fl)
> {
> uint null_fields,blobs,fields,rec_length;
> Field **f_ptr,*field;
> uint uneven_bit_fields;
> - MY_BITMAP *read_set= join_tab->table->read_set;
> + MY_BITMAP *read_set= table->read_set;
>
> uneven_bit_fields= null_fields= blobs= fields= rec_length=0;
> - for (f_ptr=join_tab->table->field ; (field= *f_ptr) ; f_ptr++)
> + for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
> {
> if (bitmap_is_set(read_set, field->field_index))
> {
> @@ -5861,24 +5920,104 @@
> }
> }
> if (null_fields || uneven_bit_fields)
> - rec_length+=(join_tab->table->s->null_fields+7)/8;
> - if (join_tab->table->maybe_null)
> + rec_length+=(table->s->null_fields+7)/8;
> + if (table->maybe_null)
> rec_length+=sizeof(my_bool);
> - if (blobs)
> + if (max_fl)
> {
> - uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
> - (join_tab->table->s->reclength-rec_length));
> - rec_length+=(uint) max(4,blob_length);
> - }
> + // TODO: to improve this estimate for max expected length if the record
> + if (blobs)
> + {
> + uint blob_length=(uint) (table->file->stats.mean_rec_length-
> + (table->s->reclength-rec_length));
> + rec_length+=(uint) max(4,blob_length);
> + }
> + }
> + else
> + rec_length= table->file->stats.mean_rec_length;
> +
> /*
> psergey-todo: why we don't count here rowid that we might need to store
> when using DuplicateElimination?
> */
> - join_tab->used_fields=fields;
> - join_tab->used_fieldlength=rec_length;
> - join_tab->used_blobs=blobs;
> - join_tab->used_null_fields= null_fields;
> - join_tab->used_uneven_bit_fields= uneven_bit_fields;
> + used_fields=fields;
> + used_fieldlength=rec_length;
> + used_blobs=blobs;
> + used_null_fields= null_fields;
> + used_uneven_bit_fields= uneven_bit_fields;
> +}
> +
> +
> +/**
> + @brief
> + Check whether hash join algorithm can be used to join this table
> +
> + @details
> + This function finds out whether the ref items that have been chosen
psergey: this_function_syntax
> + by the planner to access this table can be used for hash join algorithms.
> + The answer depends on a certain property of the the fields of the
> + joined tables on which the hash join key is built. If hash join is
> + allowed for all these fields the answer is positive.
> +
> + @note
> + The function is supposed to be called now only after the function
> + get_best_combination has been called.
> +
> + @retval TRUE it's possible to use hash join to join this table
> + @retval FALSE otherwise
> +*/
> +
> +bool JOIN_TAB::hash_join_is_possible()
> +{
> + if (type != JT_REF && type != JT_EQ_REF)
> + return FALSE;
> + KEY *keyinfo= &table->key_info[ref.key];
> + for (uint i= 0; i < ref.key_parts; i++)
> + {
> + if (!keyinfo->key_part[i].field->hash_join_is_possible())
> + return FALSE;
> + }
> + return TRUE;
> +}
> +
> +
> +/*
> + @brief
> + Extract pushdown conditions for a table scan
> +
> + @details
> + This functions extracts pushdown conditions usable when this table is scanned.
psergey: this_function_syntax
> + The conditions are extracted either from WHERE or from ON expressions.
> + The conditions are attached to the field cache_select of this table.
> +
> + @note
> + Currently the extracted conditions are used only by BNL and BNLH join.
> + algorithms.
> +
> + @retval 0 on success
> + 1 otherwise
> +*/
> +
> +int JOIN_TAB::make_scan_filter()
> +{
> + COND *tmp;
> + DBUG_ENTER("make_join_select");
> +
> + Item *cond= is_last_inner_table() ?
> + *get_first_inner_table()->on_expr_ref : join->conds;
> +
> + if (cond &&
> + (tmp=make_cond_for_table(cond, join->const_table_map | table->map,
> + table->map, FALSE, TRUE)))
> + {
> + DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
> + if (!(cache_select=
> + (SQL_SELECT*) join->thd->memdup((uchar*) select, sizeof(SQL_SELECT))))
> + DBUG_RETURN(1);
> + cache_select->cond= tmp;
> + cache_select->read_tables=join->const_table_map;
> + }
> + DBUG_RETURN(0);
> }
>
>
> @@ -5887,16 +6026,13 @@
> {
> uint length=0;
> JOIN_TAB **pos,**end;
> - THD *thd=join->thd;
>
> for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
> pos != end ;
> pos++)
> {
> JOIN_TAB *join_tab= *pos;
> - if (!join_tab->used_fieldlength) /* Not calced yet */
> - calc_used_field_length(thd, join_tab);
> - length+=join_tab->used_fieldlength;
> + length+= join_tab->get_used_fieldlength();
> }
> return length;
> }
> @@ -6366,6 +6502,8 @@
> {
> if (*e1)
> {
> + if (!e2)
> + return;
> Item *res;
> if ((res= new Item_cond_and(*e1, e2)))
> {
> @@ -6436,9 +6574,8 @@
> for (uint i=join->const_tables ; i < join->tables ; i++)
> {
> JOIN_TAB *tab=join->join_tab+i;
> - if ((tab->type == JT_REF || tab->type == JT_EQ_REF ||
> - tab->type == JT_REF_OR_NULL) &&
> - !tab->table->maybe_null)
> + if (tab->type == JT_REF || tab->type == JT_EQ_REF ||
> + tab->type == JT_REF_OR_NULL)
> {
> for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++)
> {
> @@ -6470,9 +6607,14 @@
> DBUG_EXECUTE("where",print_where(notnull,
> referred_tab->table->alias,
> QT_ORDINARY););
> - COND *new_cond= referred_tab->select_cond;
> - add_cond_and_fix(&new_cond, notnull);
> - referred_tab->set_select_cond(new_cond, __LINE__);
> + if (!tab->first_inner)
> + {
> + COND *new_cond= referred_tab->select_cond;
> + add_cond_and_fix(&new_cond, notnull);
> + referred_tab->set_select_cond(new_cond, __LINE__);
> + }
> + else
> + add_cond_and_fix(tab->first_inner->on_expr_ref, notnull);
> }
> }
> }
> @@ -6651,7 +6793,11 @@
> COND *const_cond=
> make_cond_for_table(cond,
> join->const_table_map,
> - (table_map) 0, TRUE);
> + (table_map) 0, TRUE, FALSE);
> + /* Add conditions added by add_not_null_conds(). */
> + for (uint i= 0 ; i < join->const_tables ; i++)
> + add_cond_and_fix(&const_cond, join->join_tab[i].select_cond);
> +
> DBUG_EXECUTE("where",print_where(const_cond,"constants", QT_ORDINARY););
> for (JOIN_TAB *tab= join->join_tab+join->const_tables;
> tab < join->join_tab+join->tables ; tab++)
> @@ -6661,7 +6807,7 @@
> JOIN_TAB *cond_tab= tab->first_inner;
> COND *tmp= make_cond_for_table(*tab->on_expr_ref,
> join->const_table_map,
> - ( table_map) 0, FALSE);
> + (table_map) 0, FALSE, FALSE);
> if (!tmp)
> continue;
> tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
> @@ -6749,7 +6895,10 @@
>
> tmp= NULL;
> if (cond)
> - tmp= make_cond_for_table(cond, used_tables, current_map, FALSE);
> + tmp= make_cond_for_table(cond, used_tables, current_map, FALSE, FALSE);
> + /* Add conditions added by add_not_null_conds(). */
> + if (tab->select_cond)
> + add_cond_and_fix(&tmp, tab->select_cond);
> if (cond && !tmp && tab->quick)
> { // Outer join
> if (tab->type != JT_ALL)
> @@ -6805,7 +6954,7 @@
> if (thd->variables.engine_condition_pushdown && !first_inner_tab)
> {
> COND *push_cond=
> - make_cond_for_table(tmp, current_map, current_map, FALSE);
> + make_cond_for_table(tmp, current_map, current_map, FALSE, FALSE);
> if (push_cond)
> {
> /* Push condition to handler */
> @@ -6930,19 +7079,9 @@
> if (i != join->const_tables && tab->use_quick != 2 &&
> !tab->first_inner)
> { /* Read with cache */
> - if (cond &&
> - (tmp=make_cond_for_table(cond,
> - join->const_table_map |
> - current_map,
> - current_map, FALSE)))
> - {
> - DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
> - tab->cache_select=(SQL_SELECT*)
> - thd->memdup((uchar*) sel, sizeof(SQL_SELECT));
> - tab->cache_select->cond=tmp;
> - tab->cache_select->read_tables=join->const_table_map;
> - }
> - }
> + if (tab->make_scan_filter())
> + DBUG_RETURN(1);
> + }
> }
> }
>
> @@ -6964,7 +7103,7 @@
> JOIN_TAB *cond_tab= join_tab->first_inner;
> COND *tmp= make_cond_for_table(*join_tab->on_expr_ref,
> join->const_table_map,
> - (table_map) 0, FALSE);
> + (table_map) 0, FALSE, FALSE);
> if (!tmp)
> continue;
> tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
> @@ -6999,10 +7138,14 @@
> current_map= tab->table->map;
> used_tables2|= current_map;
> COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
> - current_map, FALSE);
> + current_map, FALSE, FALSE);
> + add_cond_and_fix(&tmp_cond, tab->on_precond);
> if (tmp_cond)
> {
> JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
> + Item **sel_cond_ref= tab < first_inner_tab ?
> + &first_inner_tab->on_precond :
> + &tab->select_cond;
> /*
> First add the guards for match variables of
> all embedding outer join operations.
> @@ -7025,15 +7168,15 @@
> tmp_cond->quick_fix_field();
> /* Add the predicate to other pushed down predicates */
> DBUG_PRINT("info", ("Item_cond_and"));
> - cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
> - new Item_cond_and(cond_tab->select_cond,
> - tmp_cond);
> + *sel_cond_ref= !(*sel_cond_ref) ?
> + tmp_cond :
> + new Item_cond_and(*sel_cond_ref, tmp_cond);
> DBUG_PRINT("info", ("Item_cond_and 0x%lx",
> - (ulong)cond_tab->select_cond));
> - if (!cond_tab->select_cond)
> - DBUG_RETURN(1);
> - cond_tab->select_cond->quick_fix_field();
> - cond_tab->select_cond->update_used_tables();
> + (ulong)(*sel_cond_ref)));
> + if (!(*sel_cond_ref))
> + DBUG_RETURN(1);
> + (*sel_cond_ref)->quick_fix_field();
> + (*sel_cond_ref)->update_used_tables();
> if (cond_tab->select)
> cond_tab->select->cond= cond_tab->select_cond;
> }
> @@ -7125,6 +7268,19 @@
> {
> if (join_tab->cache)
> {
> + /*
> + If there is a previous cache linked to this cache through the
> + next_cache pointer: remove the link.
> + */
> + if (join_tab->cache->prev_cache)
> + join_tab->cache->prev_cache->next_cache= 0;
> + /*
> + No need to do the same for next_cache since cache denial is done
> + backwards starting from the latest cache in the linked list (see
> + revise_cache_usage()).
> + */
> + DBUG_ASSERT(!join_tab->cache->next_cache);
> +
> join_tab->cache->free();
> join_tab->cache= 0;
> }
> @@ -7317,8 +7473,11 @@
> join join for which the check is performed
> options options of the join
> no_jbuf_after don't use join buffering after table with this number
> + prev_tab previous join table
> icp_other_tables_ok OUT TRUE if condition pushdown supports
> other tables presence
> + idx_cond_fact_out OUT TRUE if condition pushed to the index is factored
> + out of the condition pushed to the table
>
> DESCRIPTION
> The function finds out whether the table 'tab' can be joined using a join
> @@ -7330,24 +7489,66 @@
> depend on:
> - the access method to access rows of the joined table
> - whether the join table is an inner table of an outer join or semi-join
> + - whether the optimizer switches
> + outer_join_with_cache, semijoin_with_cache, join_cache_incremental,
> + join_cache_hashed, join_cache_bka,
> + are set on or off
> - the join cache level set for the query
> - the join 'options'.
> +
> In any case join buffer is not used if the number of the joined table is
> greater than 'no_jbuf_after'. It's also never used if the value of
> join_cache_level is equal to 0.
> - The other valid settings of join_cache_level lay in the interval 1..8.
> - If join_cache_level==1|2 then join buffer is used only for inner joins
> - with 'JT_ALL' access method.
> - If join_cache_level==3|4 then join buffer is used for any join operation
> - (inner join, outer join, semi-join) with 'JT_ALL' access method.
> - If 'JT_ALL' access method is used to read rows of the joined table then
> - always a JOIN_CACHE_BNL object is employed.
> + If the optimizer switch outer_join_with_cache is off no join buffer is
> + used for outer join operations.
> + If the optimizer switch semijoin_with_cache is off no join buffer is used
> + for semi-join operations.
> + If the optimizer switch join_cache_incremental is off no incremental join
> + buffers are used.
> + If the optimizer switch join_cache_hashed is off then the optimizer does
> + not use neither BNLH algorithm, nor BKAH algorithm to perform join
> + operations.
> +
> + If the optimizer switch join_cache_bka is off then the optimizer does not
> + use neither BKA algprithm, nor BKAH algorithm to perform join operation.
> + The valid settings for join_cache_level lay in the interval 0..8.
> + If it set to 0 no join buffers are used to perform join operations.
> + Currently we differentiate between join caches of 8 levels:
> + 1 : non-incremental join cache used for BNL join algorithm
> + 2 : incremental join cache used for BNL join algorithm
> + 3 : non-incremental join cache used for BNLH join algorithm
> + 4 : incremental join cache used for BNLH join algorithm
> + 5 : non-incremental join cache used for BKA join algorithm
> + 6 : incremental join cache used for BKA join algorithm
> + 7 : non-incremental join cache used for BKAH join algorithm
> + 8 : incremental join cache used for BKAH join algorithm
psergey:
The above will be much easier to read if it was presented in a tabular form,
like this:
cache_level Incremental? Join algorithm
1 NO BNL
2 YES BNL
3 NO BNLH
4 YES BNLH
5 NO BKA
6 YES BKA
7 NO BKAH
8 YES BKAH
> + If the value of join_cache_level is set to n then no join caches of
> + levels higher than n can be employed.
> +
> + If the optimizer switches outer_join_with_cache, semijoin_with_cache,
> + join_cache_incremental, join_cache_hashed, join_cache_bka are all on
> + the following rules are applied.
> + If join_cache_level==1|2 then join buffer is used for inner joins, outer
> + joins and semi-joins with 'JT_ALL' access method. In this case a
> + JOIN_CACHE_BNL object is employed.
> + If join_cache_level==3|4 and then join buffer is used for a join operation
> + (inner join, outer join, semi-join) with 'JT_REF'/'JT_EQREF' access method
> + then a JOIN_CACHE_BNLH object is employed.
> If an index is used to access rows of the joined table and the value of
> join_cache_level==5|6 then a JOIN_CACHE_BKA object is employed.
> If an index is used to access rows of the joined table and the value of
> - join_cache_level==7|8 then a JOIN_CACHE_BKA_UNIQUE object is employed.
> + join_cache_level==7|8 then a JOIN_CACHE_BKAH object is employed.
> If the value of join_cache_level is odd then creation of a non-linked
> join cache is forced.
> +
> + Currently for any join operation a join cache of the level of the
> + highest allowed and applicable level is used.
> + For example, if join_cache_level is set to 6 and the optimizer switch
> + join_cache_bka is off, while the optimizer switch join_cache_hashed is
> + on then for any inner join operation with JT_REF/JT_EQREF access method
> + to the joined table the BNLH join algorithm will be used, while for
> + the table accessed by the JT_ALL methods the BNL algorithm will be used.
> +
> If the function decides that a join buffer can be used to join the table
> 'tab' then it sets the value of tab->use_join_buffer to TRUE and assigns
> the selected join cache object to the field 'cache' of the previous
> @@ -7364,10 +7565,13 @@
> For a nested outer join/semi-join, currently, we either use join buffers for
> all inner tables or for none of them.
> Some engines (e.g. Falcon) currently allow to use only a join cache
> - of the type JOIN_CACHE_BKA_UNIQUE when the joined table is accessed through
> + of the type JOIN_CACHE_BKAH when the joined table is accessed through
> an index. For these engines setting the value of join_cache_level to 5 or 6
> results in that no join buffer is used to join the table.
>
> + RETURN VALUE
> + cache level if cache is used, otherwise returns 0
> +
> TODO
> Support BKA inside SJ-Materialization nests. When doing this, we'll need
> to only store sj-inner tables in the join buffer.
> @@ -7391,17 +7595,15 @@
> first_tab= join->join_tab + first_sjm_table;
> }
> #endif
> -
> - RETURN
> -
> - cache level if cache is used, otherwise returns 0
> */
>
> static
> uint check_join_cache_usage(JOIN_TAB *tab,
> JOIN *join, ulonglong options,
> uint no_jbuf_after,
> - bool *icp_other_tables_ok)
> + JOIN_TAB *prev_tab,
> + bool *icp_other_tables_ok,
> + bool *idx_cond_fact_out)
> {
> uint flags;
> COST_VECT cost;
> @@ -7409,11 +7611,17 @@
> uint bufsz= 4096;
> JOIN_CACHE *prev_cache=0;
> uint cache_level= join->thd->variables.join_cache_level;
> - bool force_unlinked_cache= test(cache_level & 1);
> + bool force_unlinked_cache=
> + !optimizer_flag(join->thd, OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL);
> + bool no_hashed_cache=
> + !optimizer_flag(join->thd, OPTIMIZER_SWITCH_JOIN_CACHE_HASHED);
> + bool no_bka_cache=
> + !optimizer_flag(join->thd, OPTIMIZER_SWITCH_JOIN_CACHE_BKA);
> uint i= tab - join->join_tab;
>
> *icp_other_tables_ok= TRUE;
> - if (cache_level == 0 || i == join->const_tables)
> + *idx_cond_fact_out= TRUE;
> + if (cache_level == 0 || i == join->const_tables || !prev_tab)
> return 0;
>
> if (options & SELECT_NO_JOIN_CACHE)
> @@ -7424,16 +7632,23 @@
> */
> if (tab->use_quick == 2)
> goto no_join_cache;
> +
> + if (tab->is_inner_table_of_semi_join_with_first_match() &&
> + !optimizer_flag(join->thd, OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE))
> + goto no_join_cache;
> + if (tab->is_inner_table_of_outer_join() &&
> + !optimizer_flag(join->thd, OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE))
> + goto no_join_cache;
> +
> /*
> Non-linked join buffers can't guarantee one match
> */
> - if (force_unlinked_cache &&
> - (!tab->type == JT_ALL || cache_level <= 4) &&
> - ((tab->is_inner_table_of_semi_join_with_first_match() &&
> - !tab->is_single_inner_of_semi_join_with_first_match()) ||
> - (tab->is_inner_table_of_outer_join() &&
> - !tab->is_single_inner_of_outer_join())))
> - goto no_join_cache;
> + if (force_unlinked_cache &&
> + ((tab->is_inner_table_of_semi_join_with_first_match() &&
> + !tab->is_single_inner_of_semi_join_with_first_match()) ||
> + (tab->is_inner_table_of_outer_join() &&
> + !tab->is_single_inner_of_outer_join())))
> + goto no_join_cache;
>
> /*
> Don't use join buffering if we're dictated not to by no_jbuf_after (this
> @@ -7452,7 +7667,7 @@
> if (tab->first_sj_inner_tab && tab->first_sj_inner_tab != tab &&
> !tab->first_sj_inner_tab->use_join_cache)
> goto no_join_cache;
> - if (!tab[-1].use_join_cache)
> + if (!prev_tab->use_join_cache)
> {
> /*
> Check whether table tab and the previous one belong to the same nest of
> @@ -7474,47 +7689,85 @@
> }
>
> if (!force_unlinked_cache)
> - prev_cache= tab[-1].cache;
> + prev_cache= prev_tab->cache;
>
> switch (tab->type) {
> case JT_ALL:
> - if (cache_level <= 2 && (tab->first_inner || tab->first_sj_inner_tab))
> - goto no_join_cache;
> - if ((options & SELECT_DESCRIBE) ||
> - (((tab->cache= new JOIN_CACHE_BNL(join, tab, prev_cache))) &&
> - !tab->cache->init()))
> + if (cache_level == 1)
> + prev_cache= 0;
> + if ((tab->cache= new JOIN_CACHE_BNL(join, tab, prev_cache)) &&
> + ((options & SELECT_DESCRIBE) || !tab->cache->init()))
> {
> *icp_other_tables_ok= FALSE;
> - return cache_level;
> + return (2-test(!prev_cache));
> }
> goto no_join_cache;
> case JT_SYSTEM:
> case JT_CONST:
> case JT_REF:
> case JT_EQ_REF:
> - if (cache_level <= 4)
> - return 0;
> + if (cache_level <=2 || (no_hashed_cache && no_bka_cache))
> + goto no_join_cache;
> +
> flags= HA_MRR_NO_NULL_ENDPOINTS;
> if (tab->table->covering_keys.is_set(tab->ref.key))
> flags|= HA_MRR_INDEX_ONLY;
> rows= tab->table->file->multi_range_read_info(tab->ref.key, 10, 20,
> &bufsz, &flags, &cost);
> - if ((rows != HA_POS_ERROR) && !(flags & HA_MRR_USE_DEFAULT_IMPL) &&
> - (!(flags & HA_MRR_NO_ASSOCIATION) || cache_level > 6) &&
> - ((options & SELECT_DESCRIBE) ||
> - (((cache_level <= 6 &&
> - (tab->cache= new JOIN_CACHE_BKA(join, tab, flags, prev_cache))) ||
> - (cache_level > 6 &&
> - (tab->cache= new JOIN_CACHE_BKA_UNIQUE(join, tab, flags, prev_cache)))
> - ) && !tab->cache->init())))
> - return cache_level;
> +
> + if ((cache_level <=4 && !no_hashed_cache) || no_bka_cache ||
> + ((flags & HA_MRR_NO_ASSOCIATION) && cache_level <=6))
> + {
> + if (!tab->hash_join_is_possible() ||
> + tab->make_scan_filter())
> + goto no_join_cache;
> + if (cache_level == 3)
> + prev_cache= 0;
> + if ((tab->cache= new JOIN_CACHE_BNLH(join, tab, prev_cache)) &&
> + ((options & SELECT_DESCRIBE) || !tab->cache->init()))
> + {
> + *icp_other_tables_ok= FALSE;
> + return (4-test(!prev_cache));
> + }
> + goto no_join_cache;
> + }
> + if (cache_level > 4 && no_bka_cache)
> + goto no_join_cache;
> +
> + if ((flags & HA_MRR_NO_ASSOCIATION) &&
> + (cache_level <= 6 || no_hashed_cache))
> + goto no_join_cache;
> +
> + if ((rows != HA_POS_ERROR) && !(flags & HA_MRR_USE_DEFAULT_IMPL))
> + {
> + if (cache_level <= 6 || no_hashed_cache)
> + {
> + if (cache_level == 5)
> + prev_cache= 0;
> + if ((tab->cache= new JOIN_CACHE_BKA(join, tab, flags, prev_cache)) &&
> + ((options & SELECT_DESCRIBE) || !tab->cache->init()))
> + return (6-test(!prev_cache));
> + goto no_join_cache;
> + }
> + else
> + {
> + if (cache_level == 7)
> + prev_cache= 0;
> + if ((tab->cache= new JOIN_CACHE_BKAH(join, tab, flags, prev_cache)) &&
> + ((options & SELECT_DESCRIBE) || !tab->cache->init()))
> + {
> + *idx_cond_fact_out= FALSE;
> + return (8-test(!prev_cache));
> + }
> + goto no_join_cache;
> + }
> + }
> goto no_join_cache;
> default : ;
> }
>
> no_join_cache:
> - if (cache_level>2)
> - revise_cache_usage(tab);
> + revise_cache_usage(tab);
> return 0;
> }
>
> @@ -7545,6 +7798,7 @@
> make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
> {
> uint i;
> + uint jcl;
> bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
> bool sorted= 1;
> uint first_sjm_table= MAX_TABLES;
> @@ -7556,17 +7810,31 @@
> setup_semijoin_dups_elimination(join, options, no_jbuf_after))
> DBUG_RETURN(TRUE); /* purecov: inspected */
>
> + for (i= 0; i < join->const_tables; i++)
> + join->join_tab[i].partial_join_cardinality= 1;
> +
> for (i=join->const_tables ; i < join->tables ; i++)
> {
> JOIN_TAB *tab=join->join_tab+i;
> TABLE *table=tab->table;
> bool icp_other_tables_ok;
> + bool idx_cond_fact_out;
> tab->read_record.table= table;
> tab->read_record.file=table->file;
> tab->read_record.unlock_row= rr_unlock_row;
> tab->next_select=sub_select; /* normal select */
> tab->sorted= sorted;
> sorted= 0; // only first must be sorted
> +
> + /*
> + The approximation below for partial join cardinality is not good because
> + - it does not take into account some pushdown predicates
> + - it does not differentiate between inner joins, outer joins and semi-joins.
> + Later it should be improved.
> + */
> + tab->partial_join_cardinality= join->best_positions[i].records_read *
> + (i ? (tab-1)->partial_join_cardinality : 1);
> +
> if (tab->loosescan_match_tab)
> {
> if (!(tab->loosescan_buf= (uchar*)join->thd->alloc(tab->
> @@ -7574,6 +7842,12 @@
> return TRUE; /* purecov: inspected */
> tab->sorted= TRUE;
> }
> +
> + /*
> + SJ-Materialization
> + */
> + if (!(i >= first_sjm_table && i < last_sjm_table))
> + tab->first_sjm_sibling= NULL;
> if (sj_is_materialize_strategy(join->best_positions[i].sj_strategy))
> {
> /* This is a start of semi-join nest */
> @@ -7586,49 +7860,74 @@
>
> if (setup_sj_materialization(tab))
> return TRUE;
> + for (uint j= first_sjm_table; j != last_sjm_table; j++)
> + join->join_tab[j].first_sjm_sibling= join->join_tab + first_sjm_table;
> }
> table->status=STATUS_NO_RECORD;
> pick_table_access_method (tab);
>
> + /*
> + This loop currently can be executed only once as the function
> + check_join_cache_usage does not change the value of tab->type.
> + It won't be true for the future code.
> + */
> + for ( ; ; )
> + {
> + enum join_type tab_type= tab->type;
> + switch (tab->type) {
> + case JT_SYSTEM:
> + case JT_CONST:
> + case JT_EQ_REF:
> + case JT_REF:
> + case JT_REF_OR_NULL:
> + case JT_ALL:
> + if ((jcl= check_join_cache_usage(tab, join, options,
> + no_jbuf_after,
> + i == last_sjm_table ?
> + join->join_tab+first_sjm_table :
> + tab-1,
> + &icp_other_tables_ok,
> + &idx_cond_fact_out)))
> + {
> + tab->use_join_cache= TRUE;
> + tab[-1].next_select=sub_select_cache;
> + }
> + break;
> + default:
> + ;
> + }
> + if (tab->type == tab_type)
> + break;
> + }
> +
> switch (tab->type) {
> case JT_SYSTEM: // Only happens with left join
> case JT_CONST: // Only happens with left join
> /* Only happens with outer joins */
> tab->read_first_record= tab->type == JT_SYSTEM ?
> join_read_system :join_read_const;
> - if (check_join_cache_usage(tab, join, options, no_jbuf_after,
> - &icp_other_tables_ok))
> - {
> - tab->use_join_cache= TRUE;
> - tab[-1].next_select=sub_select_cache;
> - }
> - else
> if (table->covering_keys.is_set(tab->ref.key) &&
> !table->no_keyread)
> {
> table->key_read=1;
> table->file->extra(HA_EXTRA_KEYREAD);
> }
> - else
> - push_index_cond(tab, tab->ref.key, icp_other_tables_ok);
> + else if (!jcl || jcl > 4)
> + push_index_cond(tab, tab->ref.key,
> + icp_other_tables_ok, idx_cond_fact_out);
> break;
> case JT_EQ_REF:
> tab->read_record.unlock_row= join_read_key_unlock_row;
> /* fall through */
> - if (check_join_cache_usage(tab, join, options, no_jbuf_after,
> - &icp_other_tables_ok))
> - {
> - tab->use_join_cache= TRUE;
> - tab[-1].next_select=sub_select_cache;
> - }
> if (table->covering_keys.is_set(tab->ref.key) &&
> !table->no_keyread)
> {
> table->key_read=1;
> table->file->extra(HA_EXTRA_KEYREAD);
> }
> - else
> - push_index_cond(tab, tab->ref.key, icp_other_tables_ok );
> + else if (!jcl || jcl > 4)
> + push_index_cond(tab, tab->ref.key,
> + icp_other_tables_ok, idx_cond_fact_out);
> break;
> case JT_REF_OR_NULL:
> case JT_REF:
> @@ -7639,17 +7938,12 @@
> }
> delete tab->quick;
> tab->quick=0;
> - if (check_join_cache_usage(tab, join, options, no_jbuf_after,
> - &icp_other_tables_ok))
> - {
> - tab->use_join_cache= TRUE;
> - tab[-1].next_select=sub_select_cache;
> - }
> if (table->covering_keys.is_set(tab->ref.key) &&
> !table->no_keyread)
> table->enable_keyread();
> - else
> - push_index_cond(tab, tab->ref.key, icp_other_tables_ok);
> + else if (!jcl || jcl > 4)
> + push_index_cond(tab, tab->ref.key,
> + icp_other_tables_ok, idx_cond_fact_out);
> break;
> case JT_ALL:
> /*
> @@ -7658,12 +7952,6 @@
> Also don't use cache if this is the first table in semi-join
> materialization nest.
> */
> - if (check_join_cache_usage(tab, join, options, no_jbuf_after,
> - &icp_other_tables_ok))
> - {
> - tab->use_join_cache= TRUE;
> - tab[-1].next_select=sub_select_cache;
> - }
> /* These init changes read_record */
> if (tab->use_quick == 2)
> {
> @@ -7736,7 +8024,8 @@
> }
> if (tab->select && tab->select->quick &&
> tab->select->quick->index != MAX_KEY && ! tab->table->key_read)
> - push_index_cond(tab, tab->select->quick->index, icp_other_tables_ok);
> + push_index_cond(tab, tab->select->quick->index,
> + icp_other_tables_ok, idx_cond_fact_out);
> }
> break;
> case JT_FT:
> @@ -7760,8 +8049,11 @@
> JOIN_TAB *tab=join->join_tab+i;
> if (tab->use_join_cache)
> {
> - JOIN_TAB *sort_by_tab= join->get_sort_by_join_tab();
> - if (sort_by_tab && !join->need_tmp)
> + JOIN_TAB *sort_by_tab= join->group && join->simple_group &&
> + join->group_list ?
> + join->join_tab+join->const_tables :
> + join->get_sort_by_join_tab();
> + if (sort_by_tab)
> {
> join->need_tmp= 1;
> join->simple_order= join->simple_group= 0;
> @@ -9321,6 +9613,11 @@
> Item_equal *upper= item_field->find_item_equal(upper_levels);
> Item_field *item= item_field;
> TABLE_LIST *field_sjm= embedding_sjm(item_field);
> + if (!field_sjm)
> + {
> + current_sjm= NULL;
> + current_sjm_head= NULL;
> + }
>
> /*
> Check if "item_field=head" equality is already guaranteed to be true
> @@ -10387,7 +10684,7 @@
> {
> /* Find the best access method that would not use join buffering */
> best_access_path(join, rs, reopt_remaining_tables, i,
> - test(i < no_jbuf_before), rec_count,
> + TRUE, rec_count,
> &pos, &loose_scan_pos);
> }
> else
> @@ -13079,7 +13376,7 @@
> DBUG_RETURN(nls);
> }
> int error;
> - enum_nested_loop_state rc;
> + enum_nested_loop_state rc= NESTED_LOOP_OK;
> READ_RECORD *info= &join_tab->read_record;
>
> if (join_tab->flush_weedout_table)
> @@ -13112,18 +13409,21 @@
>
> /* Set first_unmatched for the last inner table of this group */
> join_tab->last_inner->first_unmatched= join_tab;
> - }
> + if (join_tab->on_precond && !join_tab->on_precond->val_int())
> + rc= NESTED_LOOP_NO_MORE_ROWS;
> + }
> join->thd->row_count= 0;
>
> if (join_tab->loosescan_match_tab)
> join_tab->loosescan_match_tab->found_match= FALSE;
>
> - error= (*join_tab->read_first_record)(join_tab);
> -
> - if (join_tab->keep_current_rowid)
> - join_tab->table->file->position(join_tab->table->record[0]);
> -
> - rc= evaluate_join_record(join, join_tab, error);
> + if (rc != NESTED_LOOP_NO_MORE_ROWS)
> + {
> + error= (*join_tab->read_first_record)(join_tab);
> + if (join_tab->keep_current_rowid)
> + join_tab->table->file->position(join_tab->table->record[0]);
> + rc= evaluate_join_record(join, join_tab, error);
> + }
> }
>
> /*
> @@ -13415,27 +13715,6 @@
> return (*join_tab->next_select)(join, join_tab+1, 0);
> }
>
> -#ifdef MERGE_JUNK
> -//psergey3-merge: remove:
> - SQL_SELECT *select;
> - select= join_tab->select;
> -
> - int err= 0;
> - (err= join_tab->cache.select->skip_record(join->thd)) != 0 ))
> - {
> - reset_cache_write(&join_tab->cache);
> - return NESTED_LOOP_ERROR;
> - }
> -
> - if (!select || (err= select->skip_record(join->thd)) != 0)
> - if (err < 0)
> - {
> - reset_cache_write(&join_tab->cache);
> - return NESTED_LOOP_ERROR;
> - }
> -
> - rc= NESTED_LOOP_OK;
> -#endif
> /*****************************************************************************
> The different ways to read a record
> Returns -1 if row was not found, 0 if row was found and 1 on errors
> @@ -13774,13 +14053,6 @@
> }
> }
>
> - /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
> - for (uint i= 0 ; i < tab->ref.key_parts ; i++)
> - {
> - if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
> - return -1;
> - }
> -
> if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
> return -1;
> if ((error= table->file->ha_index_read_map(table->record[0],
> @@ -14635,6 +14907,7 @@
> used_table Table that we're extracting the condition for (may
> also include PSEUDO_TABLE_BITS
> exclude_expensive_cond Do not push expensive conditions
> + retain_ref_cond Retain ref conditions
>
> DESCRIPTION
> Extract the condition that can be checked after reading the table
> @@ -14660,16 +14933,18 @@
>
> static Item *
> make_cond_for_table(Item *cond, table_map tables, table_map used_table,
> - bool exclude_expensive_cond)
> + bool exclude_expensive_cond, bool retain_ref_cond)
> {
> return make_cond_for_table_from_pred(cond, cond, tables, used_table,
> - exclude_expensive_cond);
> + exclude_expensive_cond,
> + retain_ref_cond);
> }
>
> static Item *
> make_cond_for_table_from_pred(Item *root_cond, Item *cond,
> table_map tables, table_map used_table,
> - bool exclude_expensive_cond)
> + bool exclude_expensive_cond,
> + bool retain_ref_cond)
>
> {
> if (used_table && !(cond->used_tables() & used_table) &&
> @@ -14700,7 +14975,8 @@
> {
> Item *fix=make_cond_for_table_from_pred(root_cond, item,
> tables, used_table,
> - exclude_expensive_cond);
> + exclude_expensive_cond,
> + retain_ref_cond);
> if (fix)
> new_cond->argument_list()->push_back(fix);
> }
> @@ -14732,7 +15008,8 @@
> {
> Item *fix=make_cond_for_table_from_pred(root_cond, item,
> tables, 0L,
> - exclude_expensive_cond);
> + exclude_expensive_cond,
> + retain_ref_cond);
> if (!fix)
> return (COND*) 0; // Always true
> new_cond->argument_list()->push_back(fix);
> @@ -14753,7 +15030,8 @@
> table_count times, we mark each item that we have examined with the result
> of the test
> */
> - if (cond->marker == 3 || (cond->used_tables() & ~tables) ||
> + if ((cond->marker == 3 && !retain_ref_cond) ||
> + (cond->used_tables() & ~tables) ||
> /*
> When extracting constant conditions, treat expensive conditions as
> non-constant, so that they are not evaluated at optimization time.
> @@ -14768,13 +15046,13 @@
> {
> Item *left_item= ((Item_func*) cond)->arguments()[0]->real_item();
> Item *right_item= ((Item_func*) cond)->arguments()[1]->real_item();
> - if (left_item->type() == Item::FIELD_ITEM &&
> + if (left_item->type() == Item::FIELD_ITEM && !retain_ref_cond &&
> test_if_ref(root_cond, (Item_field*) left_item,right_item))
> {
> cond->marker=3; // Checked when read
> return (COND*) 0;
> }
> - if (right_item->type() == Item::FIELD_ITEM &&
> + if (right_item->type() == Item::FIELD_ITEM && !retain_ref_cond &&
> test_if_ref(root_cond, (Item_field*) right_item,left_item))
> {
> cond->marker=3; // Checked when read
> @@ -15959,7 +16237,7 @@
>
> DBUG_EXECUTE("where",print_where(*having,"having", QT_ORDINARY););
> Item* sort_table_cond=make_cond_for_table(*having, used_tables, used_tables,
> - FALSE);
> + FALSE, FALSE);
> if (sort_table_cond)
> {
> if (!table->select)
> @@ -15977,7 +16255,8 @@
> DBUG_EXECUTE("where",print_where(table->select_cond,
> "select and having",
> QT_ORDINARY););
> - *having= make_cond_for_table(*having,~ (table_map) 0,~used_tables, FALSE);
> + *having= make_cond_for_table(*having,~ (table_map) 0,~used_tables,
> + FALSE, FALSE);
> DBUG_EXECUTE("where",
> print_where(*having,"having after make_cond", QT_ORDINARY););
> }
> @@ -18418,8 +18697,8 @@
> item_list.push_back(new Item_string("func", strlen("func"), cs));
> }
> /* rows */
> - ha_rows rows= (sj_strategy == SJ_OPT_MATERIALIZE_SCAN)?
> - tab->emb_sj_nest->sj_mat_info->rows : 1;
> + ha_rows rows= (ha_rows) ((sj_strategy == SJ_OPT_MATERIALIZE_SCAN)?
> + tab->emb_sj_nest->sj_mat_info->rows : 1);
> item_list.push_back(new Item_int((longlong)rows,
> MY_INT64_NUM_DECIMAL_DIGITS));
> /* filtered */
> @@ -18827,8 +19106,11 @@
> }
> }
>
> - if (i > 0 && tab[-1].next_select == sub_select_cache)
> + if (tab->cache)
> + {
> extra.append(STRING_WITH_LEN("; Using join buffer"));
> + tab->cache->print_explain_comment(&extra);
> + }
>
> /* Skip initial "; "*/
> const char *str= extra.ptr();
> diff -urN --exclude='.*' maria-5.3-mwl128-clean/sql/sql_select.h maria-5.3-mwl128-noc/sql/sql_select.h
> --- maria-5.3-mwl128-clean/sql/sql_select.h 2010-11-10 12:11:51.000000000 +0200
> +++ maria-5.3-mwl128-noc/sql/sql_select.h 2010-11-10 12:09:51.000000000 +0200
> @@ -160,7 +160,9 @@
> TABLE *table;
> KEYUSE *keyuse; /**< pointer to first used key */
> SQL_SELECT *select;
> - COND *select_cond;
> + COND *select_cond;
> + COND *on_precond; /**< part of on condition to check before
> + accessing the first inner table */
> QUICK_SELECT_I *quick;
> /*
> The value of select_cond before we've attempted to do Index Condition
> @@ -216,11 +218,16 @@
> E(#records) is in found_records.
> */
> ha_rows read_time;
> -
> +
> + double partial_join_cardinality;
psergey: please add a comment for the above new member variable
> table_map dependent,key_dependent;
> uint use_quick,index;
> uint status; ///< Save status for cache
> - uint used_fields,used_fieldlength,used_blobs;
> + uint used_fields;
> + ulong used_fieldlength;
> + ulong max_used_fieldlength;
psergey: please add a comment for the above new member variable
> + uint used_blobs;
> uint used_null_fields;
> uint used_rowid_fields;
> uint used_uneven_bit_fields;
> @@ -235,6 +242,7 @@
> ha_rows limit;
> TABLE_REF ref;
> bool use_join_cache;
> + ulong join_buffer_size_limit;
> JOIN_CACHE *cache;
> /*
> Index condition for BKA access join
> @@ -298,6 +306,8 @@
> */
> uint sj_strategy;
>
> + struct st_join_table *first_sjm_sibling;
> +
> void cleanup();
> inline bool is_using_loose_index_scan()
> {
> @@ -369,6 +379,22 @@
> select->cond= new_cond;
> return tmp_select_cond;
> }
> + void calc_used_field_length(bool max_fl);
> + ulong get_used_fieldlength()
> + {
> + if (!used_fieldlength)
> + calc_used_field_length(FALSE);
> + return used_fieldlength;
> + }
> + ulong get_max_used_fieldlength()
> + {
> + if (!max_used_fieldlength)
> + calc_used_field_length(TRUE);
> + return max_used_fieldlength;
> + }
> + double get_partial_join_cardinality() { return partial_join_cardinality; }
> + bool hash_join_is_possible();
> + int make_scan_filter();
> } JOIN_TAB;
>
>
> @@ -409,20 +435,25 @@
> } CACHE_FIELD;
>
>
> +class JOIN_TAB_SCAN;
> +
> +
> /*
> - JOIN_CACHE is the base class to support the implementations of both
> - Blocked-Based Nested Loops (BNL) Join Algorithm and Batched Key Access (BKA)
> - Join Algorithm. The first algorithm is supported by the derived class
> - JOIN_CACHE_BNL, while the second algorithm is supported by the derived
> - class JOIN_CACHE_BKA.
> - These two algorithms have a lot in common. Both algorithms first
> - accumulate the records of the left join operand in a join buffer and
> - then search for matching rows of the second operand for all accumulated
> - records.
> - For the first algorithm this strategy saves on logical I/O operations:
> + JOIN_CACHE is the base class to support the implementations of
> + - Block Nested Loop (BNL) Join Algorithm,
> + - Block Nested Loop Hash (BNLH) Join Algorithm,
> + - Batched Key Access (BKA) Join Algorithm.
> + The first algorithm is supported by the derived class JOIN_CACHE_BNL,
> + the second algorithm is supported by the derived class JOIN_CACHE_BNLH,
> + while the third algorithm is implemented in two variant supported by
> + the classes JOIN_CACHE_BKA and JOIN_CACHE_BKAH.
> + These three algorithms have a lot in common. Each of them first accumulates
> + the records of the left join operand in a join buffer and then searches for
> + matching rows of the second operand for all accumulated records.
> + For the first two algorithms this strategy saves on logical I/O operations:
> the entire set of records from the join buffer requires only one look-through
> - the records provided by the second operand.
> - For the second algorithm the accumulation of records allows to optimize
> + of the records provided by the second operand.
> + For the third algorithm the accumulation of records allows to optimize
> fetching rows of the second operand from disk for some engines (MyISAM,
> InnoDB), or to minimize the number of round-trips between the Server and
> the engine nodes (NDB Cluster).
> @@ -470,7 +501,7 @@
> }
>
> /*
> - The total maximal length of the fields stored for a record in the cache.
> + The maximum total length of the fields stored for a record in the cache.
> For blob fields only the sizes of the blob lengths are taken into account.
> */
> uint length;
> @@ -483,7 +514,7 @@
>
> /*
> Cardinality of the range of join tables whose fields can be put into the
> - cache. (A table from the range not necessarily contributes to the cache.)
> + cache. A table from the range not necessarily contributes to the cache.
> */
> uint tables;
>
> @@ -507,9 +538,11 @@
>
> /*
> The total number of fields referenced from field descriptors for other join
> - caches. These fields are used to construct key values to access matching
> - rows with index lookups. Currently the fields can be referenced only from
> - descriptors for bka caches. However they may belong to a cache of any type.
> + caches. These fields are used to construct key values.
> + When BKA join algorithm is employed the constructed key values serve to
> + access matching rows with index lookups.
> + The key values are put into a hash table when the BNLH join algorithm
> + is employed and when BKAH is used for the join operation.
> */
> uint referenced_fields;
>
> @@ -524,7 +557,8 @@
> descriptors. This number can be useful for implementations of
> the init methods.
> */
> - uint data_field_ptr_count;
> + uint data_field_ptr_count;
> +
> /*
> Array of the descriptors of fields containing 'fields' elements.
> These are all fields that are stored for a record in the cache.
> @@ -560,6 +594,27 @@
> */
> uint pack_length_with_blob_ptrs;
>
> + /*
> + The total size of the record base prefix. The base prefix of record may
> + include the following components:
> + - the length of the record
> + - the link to a record in a previous buffer.
> + Each record in the buffer are supplied with the same set of the components.
> + */
> + uint base_prefix_length;
> +
> + /*
> + The expected length of a record in the join buffer together with
> + all prefixes and postfixes
> + */
> + ulong avg_record_length;
> +
> + /* The expected size of the space per record in the auxiliary buffer */
> + ulong avg_aux_buffer_incr;
> +
> + /* Expected join buffer space used for one record */
> + ulong space_per_record;
> +
> /* Pointer to the beginning of the join buffer */
> uchar *buff;
> /*
> @@ -567,11 +622,25 @@
> Part of this memory may be reserved for the auxiliary buffer.
> */
> ulong buff_size;
> - /* Size of the auxiliary buffer. */
> + /* The minimal join buffer size when join buffer still makes sense to use */
> + ulong min_buff_size;
> + /* The maximum expected size if the join buffer to be used */
> + ulong max_buff_size;
> + /* Size of the auxiliary buffer */
> ulong aux_buff_size;
>
> /* The number of records put into the join buffer */
> - uint records;
> + ulong records;
> + /*
> + The number of records in the fully refilled join buffer of
> + the minimal size equal to min_buff_size
> + */
> + ulong min_records;
> + /*
> + The maximum expected number of records to be put in the join buffer
> + at one refill
> + */
> + ulong max_records;
>
> /*
> Pointer to the current position in the join buffer.
> @@ -586,13 +655,13 @@
> uchar *end_pos;
>
> /*
> - Pointer to the beginning of first field of the current read/write record
> - from the join buffer. The value is adjusted by the get_record/put_record
> - functions.
> + Pointer to the beginning of the first field of the current read/write
> + record from the join buffer. The value is adjusted by the
> + get_record/put_record functions.
> */
> uchar *curr_rec_pos;
> /*
> - Pointer to the beginning of first field of the last record
> + Pointer to the beginning of the first field of the last record
> from the join buffer.
> */
> uchar *last_rec_pos;
> @@ -611,16 +680,63 @@
> In the simplest case a record link is just a pointer to the beginning of
> the record stored in the buffer.
> In a more general case a link could be a reference to an array of pointers
> - to records in the buffer. */
> + to records in the buffer.
> + */
> uchar *curr_rec_link;
>
> + /*
> + This flag is set to TRUE if join_tab is the first inner table of an outer
> + join and the latest record written to the join buffer is detected to be
> + null complemented after checking on conditions over the outer tables for
> + this outer join operation
> + */
> + bool last_written_is_null_compl;
> +
> + /*
> + The number of fields put in the join buffer of the join cache that are
> + used in building keys to access the table join_tab
> + */
> + uint local_key_arg_fields;
> + /*
> + The total number of the fields in the previous caches that are used
> + in building keys to access the table join_tab
> + */
> + uint external_key_arg_fields;
> +
> + /*
> + This flag indicates that the key values will be read directly from the join
> + buffer. It will save us building key values in the key buffer.
> + */
> + bool use_emb_key;
> + /* The length of an embedded key value */
> + uint emb_key_length;
> +
> + /*
> + This object provides the methods to iterate over records of
> + the joined table join_tab when looking for join matches between
> + records from join buffer and records from join_tab.
> + BNL and BNLH join algorithms retrieve all records from join_tab,
> + while BKA/BKAH algorithm iterates only over those records from
> + join_tab that can be accessed by look-ups with join keys built
> + from records in join buffer.
> + */
> + JOIN_TAB_SCAN *join_tab_scan;
> +
> void calc_record_fields();
> - int alloc_fields(uint external_fields);
> + void collect_info_on_key_args();
> + int alloc_fields();
> void create_flag_fields();
> - void create_remaining_fields(bool all_read_fields);
> + void create_key_arg_fields();
> + void create_remaining_fields();
> void set_constants();
> int alloc_buffer();
>
> + /* Shall reallocate the join buffer */
> + virtual int realloc_buffer();
> +
> + /* Check the possibility to read the access keys directly from join buffer */
> + bool check_emb_key_usage();
> +
> uint get_size_of_rec_offset() { return size_of_rec_ofs; }
> uint get_size_of_rec_length() { return size_of_rec_len; }
> uint get_size_of_fld_offset() { return size_of_fld_ofs; }
> @@ -642,7 +758,6 @@
> {
> store_offset(size_of_rec_ofs, ptr-size_of_rec_ofs, (ulong) (ref-buff));
> }
> -
> void store_rec_length(uchar *ptr, ulong len)
> {
> store_offset(size_of_rec_len, ptr, len);
> @@ -655,12 +770,23 @@
> /* Write record fields and their required offsets into the join buffer */
> uint write_record_data(uchar *link, bool *is_full);
>
> + /* Get the total length of all prefixes of a record in the join buffer */
> + virtual uint get_prefix_length() { return base_prefix_length; }
> + /* Get maximum total length of all affixes of a record in the join buffer */
> + virtual uint get_record_max_affix_length();
> +
> + /*
> + Shall get maximum size of the additional space per record used for
> + record keys
> + */
> + virtual uint get_max_key_addon_space_per_record() { return 0; }
> +
> /*
> This method must determine for how much the auxiliary buffer should be
> incremented when a new record is added to the join buffer.
> If no auxiliary buffer is needed the function should return 0.
> */
> - virtual uint aux_buffer_incr() { return 0; }
> + virtual uint aux_buffer_incr(ulong recno);
>
> /* Shall calculate how much space is remaining in the join buffer */
> virtual ulong rem_space()
> @@ -668,8 +794,11 @@
> return max(buff_size-(end_pos-buff)-aux_buff_size,0);
> }
>
> - /* Shall skip record from the join buffer if its match flag is on */
> - virtual bool skip_record_if_match();
> + /*
> + Shall calculate how much space is taken by allocation of the key
> + for a record in the join buffer
> + */
> + virtual uint extra_key_length() { return 0; }
>
> /* Read all flag and data fields of a record from the join buffer */
> uint read_all_record_fields();
> @@ -684,6 +813,18 @@
> bool read_referenced_field(CACHE_FIELD *copy, uchar *rec_ptr, uint *len);
>
> /*
> + Shall skip record from the join buffer if its match flag
> + is set to MATCH_FOUND
> + */
> + virtual bool skip_if_matched();
> +
> + /*
> + Shall skip record from the join buffer if its match flag
> + commands to do so
> + */
> + virtual bool skip_if_not_needed_match();
> +
> + /*
> True if rec_ptr points to the record whose blob data stay in
> record buffers
> */
> @@ -692,16 +833,61 @@
> return rec_ptr == last_rec_pos && last_rec_blob_data_is_in_rec_buff;
> }
>
> - /* Find matches from the next table for records from the join buffer */
> - virtual enum_nested_loop_state join_matching_records(bool skip_last)=0;
> + /* Find matches from the next table for records from the join buffer */
> + virtual enum_nested_loop_state join_matching_records(bool skip_last);
> +
> + /* Shall set an auxiliary buffer up (currently used only by BKA joins) */
> + virtual int setup_aux_buffer(HANDLER_BUFFER &aux_buff)
> + {
> + DBUG_ASSERT(0);
> + return 0;
> + }
> +
> + /*
> + Shall get the number of ranges in the cache buffer passed
> + to the MRR interface
> + */
> + virtual uint get_number_of_ranges_for_mrr() { return 0; };
> +
> + /*
> + Shall prepare to look for records from the join cache buffer that would
> + match the record of the joined table read into the record buffer
> + */
> + virtual bool prepare_look_for_matches(bool skip_last)= 0;
> + /*
> + Shall return a pointer to the record from join buffer that is checked
> + as the next candidate for a match with the current record from join_tab.
> + Each implementation of this virtual function should bare in mind
> + that the record position it returns shall be exactly the position
> + passed as the parameter to the implementations of the virtual functions
> + skip_next_candidate_for_match and read_next_candidate_for_match.
> + */
> + virtual uchar *get_next_candidate_for_match()= 0;
> + /*
> + Shall check whether the given record from the join buffer has its match
> + flag settings commands to skip the record in the buffer.
> + */
> + virtual bool skip_next_candidate_for_match(uchar *rec_ptr)= 0;
> + /*
> + Shall read the given record from the join buffer into the
> + the corresponding record buffer
> + */
> + virtual void read_next_candidate_for_match(uchar *rec_ptr)= 0;
> +
> + /*
> + Shall return the location of the association label returned by
> + the multi_read_range_next function for the current record loaded
> + into join_tab's record buffer
> + */
> + virtual uchar **get_curr_association_ptr() { return 0; };
>
> - /* Add null complements for unmatched outer records from buffer */
> + /* Add null complements for unmatched outer records from the join buffer */
> virtual enum_nested_loop_state join_null_complements(bool skip_last);
>
> /* Restore the fields of the last record from the join buffer */
> virtual void restore_last_record();
>
> - /*Set match flag for a record in join buffer if it has not been set yet */
> + /* Set match flag for a record in join buffer if it has not been set yet */
> bool set_match_flag_if_none(JOIN_TAB *first_inner, uchar *rec_ptr);
>
> enum_nested_loop_state generate_full_extensions(uchar *rec_ptr);
> @@ -709,7 +895,65 @@
> /* Check matching to a partial join record from the join buffer */
> bool check_match(uchar *rec_ptr);
>
> + /*
> + This constructor creates an unlinked join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter.
> + */
> + JOIN_CACHE(JOIN *j, JOIN_TAB *tab)
> + {
> + join= j;
> + join_tab= tab;
> + prev_cache= next_cache= 0;
> + buff= 0;
> + }
> +
> + /*
> + This constructor creates a linked join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter. The parameter 'prev' specifies the previous
> + cache object to which this cache is linked.
> + */
> + JOIN_CACHE(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> + {
> + join= j;
> + join_tab= tab;
> + next_cache= 0;
> + prev_cache= prev;
> + buff= 0;
> + if (prev)
> + prev->next_cache= this;
> + }
> +
> public:
> +
> + /*
> + The enumeration type Join_algorithm includes a mnemonic constant for
> + each join algorithm that employs join buffers
> + */
> +
> + enum Join_algorithm
> + {
> + BNL_JOIN_ALG, /* Block Nested Loop Join algorithm */
> + BNLH_JOIN_ALG, /* Block Nested Loop Hash Join algorithm */
> + BKA_JOIN_ALG, /* Batched Key Access Join algorithm */
> + BKAH_JOIN_ALG, /* Batched Key Access with Hash Table Join Algorithm */
> + };
> +
> + /*
> + The enumeration type Match_flag describes possible states of the match flag
> + field stored for the records of the first inner tables of outer joins and
> + semi-joins in the cases when the first match strategy is used for them.
> + When a record with match flag field is written into the join buffer the
> + state of the field usually is MATCH_NOT_FOUND unless this is a record of the
> + first inner table of the outer join for which the on precondition (the
> + condition from on expression over outer tables) has turned out not to be
> + true. In the last case the state of the match flag is MATCH_IMPOSSIBLE.
> + The state of the match flag field is changed to MATCH_FOUND as soon as
> + the first full matching combination of inner tables of the outer join or
> + the semi-join is discovered.
> + */
> + enum Match_flag { MATCH_NOT_FOUND, MATCH_FOUND, MATCH_IMPOSSIBLE };
>
> /* Table to be joined with the partial join records from the cache */
> JOIN_TAB *join_tab;
> @@ -720,10 +964,29 @@
> JOIN_CACHE *next_cache;
>
> /* Shall initialize the join cache structure */
> - virtual int init()=0;
> + virtual int init();
> +
> + /* Get the current size of the cache join buffer */
> + ulong get_join_buffer_size() { return buff_size; }
> + /* Set the size of the cache join buffer to a new value */
> + void set_join_buffer_size(ulong sz) { buff_size= sz; }
> +
> + /* Get the minimum possible size of the cache join buffer */
> + virtual ulong get_min_join_buffer_size();
> + /* Get the maximum possible size of the cache join buffer */
> + virtual ulong get_max_join_buffer_size();
> +
> + /* Shrink the size if the cache join buffer in a given ratio */
> + bool shrink_join_buffer_in_ratio(ulonglong n, ulonglong d);
> +
> + /* Shall return the type of the employed join algorithm */
> + virtual enum Join_algorithm get_join_alg()= 0;
>
> - /* The function shall return TRUE only for BKA caches */
> - virtual bool is_key_access() { return FALSE; }
> + /*
> + The function shall return TRUE only when there is a key access
> + to the join table
> + */
> + virtual bool is_key_access()= 0;
>
> /* Shall reset the join buffer for reading/writing */
> virtual void reset(bool for_writing);
> @@ -747,7 +1010,7 @@
> virtual void get_record_by_pos(uchar *rec_ptr);
>
> /* Shall return the value of the match flag for the positioned record */
> - virtual bool get_match_flag_by_pos(uchar *rec_ptr);
> + virtual enum Match_flag get_match_flag_by_pos(uchar *rec_ptr);
>
> /* Shall return the position of the current record */
> virtual uchar *get_curr_rec() { return curr_rec_pos; }
> @@ -761,9 +1024,12 @@
> return (curr_rec_link ? curr_rec_link : get_curr_rec());
> }
>
> - /* Join records from the join buffer with records from the next join table */
> + /* Join records from the join buffer with records from the next join table */
> enum_nested_loop_state join_records(bool skip_last);
>
> + /* Add a comment on the join algorithm employed by the join cache */
> + void print_explain_comment(String *str);
> +
> virtual ~JOIN_CACHE() {}
> void reset_join(JOIN *j) { join= j; }
> void free()
> @@ -772,59 +1038,531 @@
> buff= 0;
> }
>
> + JOIN_TAB *get_next_table(JOIN_TAB *tab);
> +
> + friend class JOIN_CACHE_HASHED;
> friend class JOIN_CACHE_BNL;
> friend class JOIN_CACHE_BKA;
> - friend class JOIN_CACHE_BKA_UNIQUE;
> + friend class JOIN_TAB_SCAN;
> + friend class JOIN_TAB_SCAN_MRR;
> +
> };
>
>
> -class JOIN_CACHE_BNL :public JOIN_CACHE
> +/*
> + The class JOIN_CACHE_HASHED is the base class for the classes
> + JOIN_CACHE_HASHED_BNL and JOIN_CACHE_HASHED_BKA. The first of them supports
> + an implementation of Block Nested Loop Hash (BNLH) Join Algorithm,
> + while the second is used for a variant of the BKA Join algorithm that performs
> + only one lookup for any records from join buffer with the same key value.
> + For a join cache of this class the records from the join buffer that have
> + the same access key are linked into a chain attached to a key entry structure
> + that either itself contains the key value, or, in the case when the keys are
> + embedded, refers to its occurrence in one of the records from the chain.
> + To build the chains with the same keys a hash table is employed. It is placed
> + at the very end of the join buffer. The array of hash entries is allocated
> + first at the very bottom of the join buffer, while key entries are placed
> + before this array.
> + A hash entry contains a header of the list of the key entries with the same
> + hash value.
> + Each key entry is a structure of the following type:
> + struct st_join_cache_key_entry {
> + union {
> + uchar[] value;
> + cache_ref *value_ref; // offset from the beginning of the buffer
> + } hash_table_key;
> + key_ref next_key; // offset backward from the beginning of hash table
> + cache_ref *last_rec // offset from the beginning of the buffer
Why use "cache_ref *last_rec"? AFAIU the above variable is an offset (and not a
pointer to offset). If it's offset, then "cache_ref last_rec" should be
sufficient.
> + }
> + The references linking the records in a chain are always placed at the very
> + beginning of the record info stored in the join buffer. The records are
> + linked in a circular list. A new record is always added to the end of this
> + list.
> +
> + The following picture represents a typical layout for the info stored in the
> + join buffer of a join cache object of the JOIN_CACHE_HASHED class.
> +
> + buff
> + V
> + +----------------------------------------------------------------------------+
> + | |[*]record_1_1| |
> + | ^ | |
> + | | +--------------------------------------------------+ |
> + | | |[*]record_2_1| | |
> + | | ^ | V |
> + | | | +------------------+ |[*]record_1_2| |
> + | | +--------------------+-+ | |
> + |+--+ +---------------------+ | | +-------------+ |
> + || | | V | | |
> + |||[*]record_3_1| |[*]record_1_3| |[*]record_2_2| | |
> + ||^ ^ ^ | |
> + ||+----------+ | | | |
> + ||^ | |<---------------------------+-------------------+ |
> + |++ | | ... mrr | buffer ... ... | | |
> + | | | | |
> + | +-----+--------+ | +-----|-------+ |
> + | V | | | V | | |
> + ||key_3|[/]|[*]| | | |key_2|[/]|[*]| | |
> + | +-+---|-----------------------+ | |
> + | V | | | | |
> + | |key_1|[*]|[*]| | | ... |[*]| ... |[*]| ... | |
> + +----------------------------------------------------------------------------+
> + ^ ^ ^
> + | i-th entry j-th entry
> + hash table
> +
> + i-th hash entry:
> + circular record chain for key_1:
> + record_1_1
> + record_1_2
> + record_1_3 (points to record_1_1)
> + circular record chain for key_3:
> + record_3_1 (points to itself)
> +
> + j-th hash entry:
> + circular record chain for key_2:
> + record_2_1
> + record_2_2 (points to record_2_1)
> +
> +*/
> +
> +class JOIN_CACHE_HASHED: public JOIN_CACHE
> {
>
> +private:
> +
> + /* Size of the offset of a key entry in the hash table */
> + uint size_of_key_ofs;
> +
> + /*
> + Length of the key entry in the hash table.
> + A key entry either contains the key value, or it contains a reference
> + to the key value if use_emb_key flag is set for the cache.
> + */
> + uint key_entry_length;
> +
> + /* The beginning of the hash table in the join buffer */
> + uchar *hash_table;
> + /* Number of hash entries in the hash table */
> + uint hash_entries;
> +
> +
> + /* The position of the currently retrieved key entry in the hash table */
> + uchar *curr_key_entry;
> +
> + /* The offset of the data fields from the beginning of the record fields */
> + uint data_fields_offset;
> +
> + uint get_hash_idx(uchar* key, uint key_len);
> +
> + int init_hash_table();
> + void cleanup_hash_table();
> +
> protected:
>
> - /* Using BNL find matches from the next table for records from join buffer */
> - enum_nested_loop_state join_matching_records(bool skip_last);
> + /*
> + Length of a key value.
> + It is assumed that all key values have the same length.
> + */
> + uint key_length;
> + /* Buffer to store key values for probing */
> + uchar *key_buff;
>
> -public:
> + /* Number of key entries in the hash table (number of distinct keys) */
> + uint key_entries;
> +
> + /* The position of the last key entry in the hash table */
> + uchar *last_key_entry;
>
> /*
> - This constructor creates an unlinked BNL join cache. The cache is to be
> + The offset of the record fields from the beginning of the record
> + representation. The record representation starts with a reference to
> + the next record in the key record chain followed by the length of
> + the trailing record data followed by a reference to the record segment
> + in the previous cache, if any, followed by the record fields.
> + */
> + uint rec_fields_offset;
> +
> + uint get_size_of_key_offset() { return size_of_key_ofs; }
> +
> + /*
> + Get the position of the next_key_ptr field pointed to by
> + a linking reference stored at the position key_ref_ptr.
> + This reference is actually the offset backward from the
> + beginning of hash table.
> + */
> + uchar *get_next_key_ref(uchar *key_ref_ptr)
> + {
> + return hash_table-get_offset(size_of_key_ofs, key_ref_ptr);
> + }
> +
> + /*
> + Store the linking reference to the next_key_ptr field at
> + the position key_ref_ptr. The position of the next_key_ptr
> + field is pointed to by ref. The stored reference is actually
> + the offset backward from the beginning of the hash table.
> + */
> + void store_next_key_ref(uchar *key_ref_ptr, uchar *ref)
> + {
> + store_offset(size_of_key_ofs, key_ref_ptr, (ulong) (hash_table-ref));
> + }
> +
> + /*
> + Check whether the reference to the next_key_ptr field at the position
> + key_ref_ptr contains a nil value.
> + */
> + bool is_null_key_ref(uchar *key_ref_ptr)
> + {
> + ulong nil= 0;
> + return memcmp(key_ref_ptr, &nil, size_of_key_ofs ) == 0;
> + }
> +
> + /*
> + Set the reference to the next_key_ptr field at the position
> + key_ref_ptr equal to nil.
> + */
> + void store_null_key_ref(uchar *key_ref_ptr)
> + {
> + ulong nil= 0;
> + store_offset(size_of_key_ofs, key_ref_ptr, nil);
> + }
> +
> + uchar *get_next_rec_ref(uchar *ref_ptr)
> + {
> + return buff+get_offset(get_size_of_rec_offset(), ref_ptr);
> + }
> +
> + void store_next_rec_ref(uchar *ref_ptr, uchar *ref)
> + {
> + store_offset(get_size_of_rec_offset(), ref_ptr, (ulong) (ref-buff));
> + }
> +
> + /*
> + Get the position of the embedded key value for the current
> + record pointed to by get_curr_rec().
> + */
> + uchar *get_curr_emb_key()
> + {
> + return get_curr_rec()+data_fields_offset;
> + }
> +
> + /*
> + Get the position of the embedded key value pointed to by a reference
> + stored at ref_ptr. The stored reference is actually the offset from
> + the beginning of the join buffer.
> + */
> + uchar *get_emb_key(uchar *ref_ptr)
> + {
> + return buff+get_offset(get_size_of_rec_offset(), ref_ptr);
> + }
> +
> + /*
> + Store the reference to an embedded key at the position key_ref_ptr.
> + The position of the embedded key is pointed to by ref. The stored
> + reference is actually the offset from the beginning of the join buffer.
> + */
> + void store_emb_key_ref(uchar *ref_ptr, uchar *ref)
> + {
> + store_offset(get_size_of_rec_offset(), ref_ptr, (ulong) (ref-buff));
> + }
> +
> + /* Get the total length of all prefixes of a record in hashed join buffer */
> + uint get_prefix_length()
> + {
> + return base_prefix_length + get_size_of_rec_offset();
> + }
> +
> + /*
> + Get maximum size of the additional space per record used for
> + the hash table with record keys
> + */
> + uint get_max_key_addon_space_per_record();
> +
> + /*
> + Calculate how much space in the buffer would not be occupied by
> + records, key entries and additional memory for the MMR buffer.
> + */
> + ulong rem_space()
> + {
> + return max(last_key_entry-end_pos-aux_buff_size,0);
> + }
> +
> + /*
> + Calculate how much space is taken by allocation of the key
> + entry for a record in the join buffer
> + */
> + uint extra_key_length() { return key_entry_length; }
> +
> + /*
> + Skip record from a hashed join buffer if its match flag
> + is set to MATCH_FOUND
> + */
> + bool skip_if_matched();
> +
> + /*
> + Skip record from a hashed join buffer if its match flag setting
> + commands to do so
> + */
> + bool skip_if_not_needed_match();
> +
> + /* Search for a key in the hash table of the join buffer */
> + bool key_search(uchar *key, uint key_len, uchar **key_ref_ptr);
> +
> + /* Reallocate the join buffer of a hashed join cache */
> + int realloc_buffer();
> +
> + /*
> + This constructor creates an unlinked hashed join cache. The cache is to be
> used to join table 'tab' to the result of joining the previous tables
> specified by the 'j' parameter.
> */
psergey: is it possible to make the above comment list parameters in doxygen or
old-mysql-coding-style format?
> - JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab)
> - {
> + JOIN_CACHE_HASHED(JOIN *j, JOIN_TAB *tab) :JOIN_CACHE(j, tab) {}
> +
> + /*
> + This constructor creates a linked hashed join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter. The parameter 'prev' specifies the previous
> + cache object to which this cache is linked.
> + */
> + JOIN_CACHE_HASHED(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> + :JOIN_CACHE(j, tab, prev) {}
> +
> +public:
> +
> + /* Initialize a hashed join cache */
> + int init();
> +
> + /* Reset the buffer of a hashed join cache for reading/writing */
> + void reset(bool for_writing);
> +
> + /* Add a record into the buffer of a hashed join cache */
> + bool put_record();
> +
> + /* Read the next record from the buffer of a hashed join cache */
> + bool get_record();
> +
> + /*
> + Shall check whether all records in a key chain have
> + their match flags set on
> + */
> + virtual bool check_all_match_flags_for_key(uchar *key_chain_ptr);
> +
> + uint get_next_key(uchar **key);
> +
> + /* Get the head of the record chain attached to the current key entry */
> + uchar *get_curr_key_chain()
> + {
> + return get_next_rec_ref(curr_key_entry+key_entry_length-
> + get_size_of_rec_offset());
> + }
> +
> +};
> +
> +
> +/*
> + The class JOIN_TAB_SCAN is a companion class for the classes JOIN_CACHE_BNL
> + and JOIN_CACHE_BNLH. Actually the class implements the iterator over the
> + table joinded by BNL/BNLH join algorithm.
psergey: ^^^^^^ typo
> + The virtual functions open, next and close are called for any iteration over
> + the table. The function open is called to initiate the process of the
> + iteration. The function next shall read the next record from the joined
> + table. The record is read into the record buffer of the joined table.
> + The record is to be matched with records from the join cache buffer.
> + The function close shall perform the finalizing actions for the iteration.
psergey: won't it be easier to read if the text had more structure:
/*
JOIN_TAB_SCAN is a companion class for the classes JOIN_CACHE_BNL and
JOIN_CACHE_BNLH. The class implements an iterator over the table joined by BNL/BNLH
join algorithm. Iteration is done by calling open(), next(), and close()
functions:
- open() is called to initiate the process of the iteration.
- next() shall read the next record from the joined table. The record is
read into the record buffer of the table. The record is to be matched
with records from the join cache buffer.
- close() shall perform the finalizing actions for the iteration.
*/
> +*/
> +
> +class JOIN_TAB_SCAN: public Sql_alloc
> +{
> +
> +private:
> + /* TRUE if this is the first record from the joined table to iterate over */
> + bool is_first_record;
> +
> +protected:
> +
> + /* The joined table to be iterated over */
> + JOIN_TAB *join_tab;
> + /* The join cache used to join the table join_tab */
> + JOIN_CACHE *cache;
> + /*
> + Representation of the executed multi-way join through which
> + all needed context can be accessed.
> + */
> + JOIN *join;
> +
> +public:
> +
> + JOIN_TAB_SCAN(JOIN *j, JOIN_TAB *tab)
> + {
> join= j;
> join_tab= tab;
> - prev_cache= next_cache= 0;
> + cache= join_tab->cache;
> }
>
> + virtual ~JOIN_TAB_SCAN() {}
> +
> + /*
> + Shall calculate the increment of the auxiliary buffer for a record
> + write if such a buffer is used by the table scan object
> + */
> + virtual uint aux_buffer_incr(ulong recno) { return 0; }
> +
> + /* Initiate the process of iteration over the joined table */
> + virtual int open();
> + /*
> + Shall read the next candidate for matches with records from
> + the join buffer.
> + */
> + virtual int next();
> + /*
> + Perform the finalizing actions for the process of iteration
> + over the joined_table.
> + */
> + virtual void close();
> +
> +};
> +
> +/*
> + The class JOIN_CACHE_BNL is used when the BNL join algorithm is
> + employed to perform a join operation
> +*/
> +
> +class JOIN_CACHE_BNL :public JOIN_CACHE
> +{
> +private:
> + /*
> + The number of the records in the join buffer that have to be
> + checked yet for a match with the current record of join_tab
> + read into the record buffer.
> + */
> + uint rem_records;
> +
> +protected:
> +
> + bool prepare_look_for_matches(bool skip_last);
> +
> + uchar *get_next_candidate_for_match();
> +
> + bool skip_next_candidate_for_match(uchar *rec_ptr);
> +
> + void read_next_candidate_for_match(uchar *rec_ptr);
> +
> +public:
> +
> + /*
> + This constructor creates an unlinked BNL join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter.
> + */
> + JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab) :JOIN_CACHE(j, tab) {}
> +
> /*
> This constructor creates a linked BNL join cache. The cache is to be
> used to join table 'tab' to the result of joining the previous tables
> specified by the 'j' parameter. The parameter 'prev' specifies the previous
> cache object to which this cache is linked.
> */
> - JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> - {
> - join= j;
> - join_tab= tab;
> - prev_cache= prev;
> - next_cache= 0;
> - if (prev)
> - prev->next_cache= this;
> - }
> + JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> + :JOIN_CACHE(j, tab, prev) {}
>
> /* Initialize the BNL cache */
> int init();
>
> + enum Join_algorithm get_join_alg() { return BNL_JOIN_ALG; }
> +
> + bool is_key_access() { return FALSE; }
> +
> };
>
> -class JOIN_CACHE_BKA :public JOIN_CACHE
> +
> +/*
> + The class JOIN_CACHE_BNLH is used when the BNLH join algorithm is
> + employed to perform a join operation
> +*/
> +
> +class JOIN_CACHE_BNLH :public JOIN_CACHE_HASHED
> {
> +
> protected:
>
> + /*
> + The pointer to the last record from the circular list of the records
> + that match the join key built out of the record in the join buffer for
> + the join_tab table
> + */
> + uchar *last_matching_rec_ref_ptr;
> + /*
> + The pointer to the next current record from the circular list of the
> + records that match the join key built out of the record in the join buffer
> + for the join_tab table. This pointer is used by the class method
> + get_next_candidate_for_match to iterate over records from the circular
> + list.
> + */
> + uchar *next_matching_rec_ref_ptr;
> +
> + /*
> + Get the chain of records from buffer matching the current candidate
> + record for join
> + */
> + uchar *get_matching_chain_by_join_key();
> +
> + bool prepare_look_for_matches(bool skip_last);
> +
> + uchar *get_next_candidate_for_match();
> +
> + bool skip_next_candidate_for_match(uchar *rec_ptr);
> +
> + void read_next_candidate_for_match(uchar *rec_ptr);
> +
> +public:
> +
> + /*
> + This constructor creates an unlinked BNLH join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter.
> + */
> + JOIN_CACHE_BNLH(JOIN *j, JOIN_TAB *tab) : JOIN_CACHE_HASHED(j, tab) {}
> +
> + /*
> + This constructor creates a linked BNLH join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter. The parameter 'prev' specifies the previous
> + cache object to which this cache is linked.
> + */
> + JOIN_CACHE_BNLH(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> + : JOIN_CACHE_HASHED(j, tab, prev) {}
> +
> + /* Initialize the BNLH cache */
> + int init();
> +
> + enum Join_algorithm get_join_alg() { return BNLH_JOIN_ALG; }
> +
> + bool is_key_access() { return TRUE; }
> +
> +};
> +
> +
> +/*
> + The class JOIN_TAB_SCAN_MRR is a companion class for the classes
> + JOIN_CACHE_BKA and JOIN_CACHE_BKAH. Actually the class implements the
> + iterator over the records from join_tab selected by BKA/BKAH join
> + algorithm as the candidates to be joined.
> + The virtual functions open, next and close are called for any iteration over
> + join_tab record candidates. The function open is called to initiate the
> + process of the iteration. The function next shall read the next record from
> + the set of the record candidates. The record is read into the record buffer
> + of the joined table. The function close shall perform the finalizing actions
> + for the iteration.
> +*/
> +
> +class JOIN_TAB_SCAN_MRR: public JOIN_TAB_SCAN
> +{
> + /* Interface object to generate key ranges for MRR */
> + RANGE_SEQ_IF range_seq_funcs;
> +
> + /* Number of ranges to be processed by the MRR interface */
> + uint ranges;
> +
> /* Flag to to be passed to the MRR interface */
> uint mrr_mode;
>
> @@ -834,47 +1572,76 @@
> /* Shall initialize the MRR buffer */
> virtual void init_mrr_buff()
> {
> - mrr_buff.buffer= end_pos;
> - mrr_buff.buffer_end= buff+buff_size;
> + cache->setup_aux_buffer(mrr_buff);
> }
>
> - /*
> - The number of the cache fields that are used in building keys to access
> - the table join_tab
> - */
> - uint local_key_arg_fields;
> +public:
> +
> + JOIN_TAB_SCAN_MRR(JOIN *j, JOIN_TAB *tab, uint flags, RANGE_SEQ_IF rs_funcs)
> + :JOIN_TAB_SCAN(j, tab), range_seq_funcs(rs_funcs), mrr_mode(flags) {}
> +
> + uint aux_buffer_incr(ulong recno);
> +
> + int open();
> +
> + int next();
> +
> +};
> +
> +/*
> + The class JOIN_CACHE_BKA is used when the BKA join algorithm is
> + employed to perform a join operation
> +*/
> +
> +class JOIN_CACHE_BKA :public JOIN_CACHE
> +{
> +private:
> +
> + /* Flag to to be passed to the companion JOIN_TAB_SCAN_MRR object */
> + uint mrr_mode;
> +
> /*
> - The total number of the fields in the previous caches that are used
> - in building keys t access the table join_tab
> + This value is set to 1 by the class prepare_look_for_matches method
> + and back to 0 by the class get_next_candidate_for_match method
> */
> - uint external_key_arg_fields;
> + uint rem_records;
>
> - /*
> - This flag indicates that the key values will be read directly from the join
> - buffer. It will save us building key values in the key buffer.
> + /*
> + This field contains the current association label set by a call of
> + the multi_range_read_next handler function.
> + See the function JOIN_CACHE_BKA::get_curr_key_association()
> + */
> + uchar *curr_association;
> +
> +protected:
> +
> + /*
> + Get the number of ranges in the cache buffer passed to the MRR
> + interface. For each record its own range is passed.
> */
> - bool use_emb_key;
> - /* The length of an embedded key value */
> - uint emb_key_length;
> + uint get_number_of_ranges_for_mrr() { return records; }
>
> - /* Check the possibility to read the access keys directly from join buffer */
> - bool check_emb_key_usage();
> + /*
> + Setup the MRR buffer as the space between the last record put
> + into the join buffer and the very end of the join buffer
> + */
> + int setup_aux_buffer(HANDLER_BUFFER &aux_buff)
> + {
> + aux_buff.buffer= end_pos;
> + aux_buff.buffer_end= buff+buff_size;
> + return 0;
> + }
>
> - /* Calculate the increment of the MM buffer for a record write */
> - uint aux_buffer_incr();
> + bool prepare_look_for_matches(bool skip_last);
>
> - /* Using BKA find matches from the next table for records from join buffer */
> - enum_nested_loop_state join_matching_records(bool skip_last);
> + uchar *get_next_candidate_for_match();
>
> - /* Prepare to search for records that match records from the join buffer */
> - enum_nested_loop_state init_join_matching_records(RANGE_SEQ_IF *seq_funcs,
> - uint ranges);
> + bool skip_next_candidate_for_match(uchar *rec_ptr);
>
> - /* Finish searching for records that match records from the join buffer */
> - enum_nested_loop_state end_join_matching_records(enum_nested_loop_state rc);
> + void read_next_candidate_for_match(uchar *rec_ptr);
>
> public:
> -
> +
> /*
> This constructor creates an unlinked BKA join cache. The cache is to be
> used to join table 'tab' to the result of joining the previous tables
> @@ -882,335 +1649,121 @@
> The MRR mode initially is set to 'flags'.
> */
> JOIN_CACHE_BKA(JOIN *j, JOIN_TAB *tab, uint flags)
> - {
> - join= j;
> - join_tab= tab;
> - prev_cache= next_cache= 0;
> - mrr_mode= flags;
> - }
> -
> + :JOIN_CACHE(j, tab), mrr_mode(flags) {}
> /*
> This constructor creates a linked BKA join cache. The cache is to be
> used to join table 'tab' to the result of joining the previous tables
> - specified by the 'j' parameter. The parameter 'prev' specifies the cache
> - object to which this cache is linked.
> + specified by the 'j' parameter. The parameter 'prev' specifies the previous
> + cache object to which this cache is linked.
> The MRR mode initially is set to 'flags'.
> */
> - JOIN_CACHE_BKA(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE* prev)
> - {
> - join= j;
> - join_tab= tab;
> - prev_cache= prev;
> - next_cache= 0;
> - if (prev)
> - prev->next_cache= this;
> - mrr_mode= flags;
> - }
> + JOIN_CACHE_BKA(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE *prev)
> + :JOIN_CACHE(j, tab, prev), mrr_mode(flags) {}
> +
> + uchar **get_curr_association_ptr() { return &curr_association; }
>
> /* Initialize the BKA cache */
> int init();
>
> - bool is_key_access() { return TRUE; }
> + enum Join_algorithm get_join_alg() { return BKA_JOIN_ALG; }
>
> - /* Shall get the key built over the next record from the join buffer */
> - virtual uint get_next_key(uchar **key);
> + bool is_key_access() { return TRUE; }
>
> - /* Check if the record combination matches the index condition */
> - bool skip_index_tuple(range_seq_t rseq, char *range_info);
> -};
> + /* Get the key built over the next record from the join buffer */
> + uint get_next_key(uchar **key);
>
> -/*
> - The class JOIN_CACHE_BKA_UNIQUE supports the variant of the BKA join algorithm
> - that submits only distinct keys to the MRR interface. The records in the join
> - buffer of a cache of this class that have the same access key are linked into
> - a chain attached to a key entry structure that either itself contains the key
> - value, or, in the case when the keys are embedded, refers to its occurance in
> - one of the records from the chain.
> - To build the chains with the same keys a hash table is employed. It is placed
> - at the very end of the join buffer. The array of hash entries is allocated
> - first at the very bottom of the join buffer, then go key entries. A hash entry
> - contains a header of the list of the key entries with the same hash value.
> - Each key entry is a structure of the following type:
> - struct st_join_cache_key_entry {
> - union {
> - uchar[] value;
> - cache_ref *value_ref; // offset from the beginning of the buffer
> - } hash_table_key;
> - key_ref next_key; // offset backward from the beginning of hash table
> - cache_ref *last_rec // offset from the beginning of the buffer
> - }
> - The references linking the records in a chain are always placed at the very
> - beginning of the record info stored in the join buffer. The records are
> - linked in a circular list. A new record is always added to the end of this
> - list. When a key is passed to the MRR interface it can be passed either with
> - an association link containing a reference to the header of the record chain
> - attached to the corresponding key entry in the hash table, or without any
> - association link. When the next record is returned by a call to the MRR
> - function multi_range_read_next without any association (because if was not
> - passed together with the key) then the key value is extracted from the
> - returned record and searched for it in the hash table. If there is any records
> - with such key the chain of them will be yielded as the result of this search.
> + /* Check index condition of the joined table for a record from BKA cache */
> + bool skip_index_tuple(char *range_info);
>
> - The following picture represents a typical layout for the info stored in the
> - join buffer of a join cache object of the JOIN_CACHE_BKA_UNIQUE class.
> -
> - buff
> - V
> - +----------------------------------------------------------------------------+
> - | |[*]record_1_1| |
> - | ^ | |
> - | | +--------------------------------------------------+ |
> - | | |[*]record_2_1| | |
> - | | ^ | V |
> - | | | +------------------+ |[*]record_1_2| |
> - | | +--------------------+-+ | |
> - |+--+ +---------------------+ | | +-------------+ |
> - || | | V | | |
> - |||[*]record_3_1| |[*]record_1_3| |[*]record_2_2| | |
> - ||^ ^ ^ | |
> - ||+----------+ | | | |
> - ||^ | |<---------------------------+-------------------+ |
> - |++ | | ... mrr | buffer ... ... | | |
> - | | | | |
> - | +-----+--------+ | +-----|-------+ |
> - | V | | | V | | |
> - ||key_3|[/]|[*]| | | |key_2|[/]|[*]| | |
> - | +-+---|-----------------------+ | |
> - | V | | | | |
> - | |key_1|[*]|[*]| | | ... |[*]| ... |[*]| ... | |
> - +----------------------------------------------------------------------------+
> - ^ ^ ^
> - | i-th entry j-th entry
> - hash table
> +};
>
> - i-th hash entry:
> - circular record chain for key_1:
> - record_1_1
> - record_1_2
> - record_1_3 (points to record_1_1)
> - circular record chain for key_3:
> - record_3_1 (points to itself)
>
> - j-th hash entry:
> - circular record chain for key_2:
> - record_2_1
> - record_2_2 (points to record_2_1)
>
> +/*
> + The class JOIN_CACHE_BKAH is used when the BKAH join algorithm is
> + employed to perform a join operation
> */
>
> -class JOIN_CACHE_BKA_UNIQUE :public JOIN_CACHE_BKA
> +class JOIN_CACHE_BKAH :public JOIN_CACHE_BNLH
> {
>
> private:
> + /* Flag to to be passed to the companion JOIN_TAB_SCAN_MRR object */
> + uint mrr_mode;
>
> - /* Size of the offset of a key entry in the hash table */
> - uint size_of_key_ofs;
> -
> - /*
> - Length of a key value.
> - It is assumed that all key values have the same length.
> - */
> - uint key_length;
> - /*
> - Length of the key entry in the hash table.
> - A key entry either contains the key value, or it contains a reference
> - to the key value if use_emb_key flag is set for the cache.
> - */
> - uint key_entry_length;
> -
> - /* The beginning of the hash table in the join buffer */
> - uchar *hash_table;
> - /* Number of hash entries in the hash table */
> - uint hash_entries;
> -
> - /* Number of key entries in the hash table (number of distinct keys) */
> - uint key_entries;
> -
> - /* The position of the last key entry in the hash table */
> - uchar *last_key_entry;
> -
> - /* The position of the currently retrieved key entry in the hash table */
> - uchar *curr_key_entry;
> -
> - /*
> - The offset of the record fields from the beginning of the record
> - representation. The record representation starts with a reference to
> - the next record in the key record chain followed by the length of
> - the trailing record data followed by a reference to the record segment
> - in the previous cache, if any, followed by the record fields.
> - */
> - uint rec_fields_offset;
> - /* The offset of the data fields from the beginning of the record fields */
> - uint data_fields_offset;
> -
> - uint get_hash_idx(uchar* key, uint key_len);
> -
> - void cleanup_hash_table();
> -
> -protected:
> -
> - uint get_size_of_key_offset() { return size_of_key_ofs; }
> -
> - /*
> - Get the position of the next_key_ptr field pointed to by
> - a linking reference stored at the position key_ref_ptr.
> - This reference is actually the offset backward from the
> - beginning of hash table.
> - */
> - uchar *get_next_key_ref(uchar *key_ref_ptr)
> - {
> - return hash_table-get_offset(size_of_key_ofs, key_ref_ptr);
> - }
> -
> - /*
> - Store the linking reference to the next_key_ptr field at
> - the position key_ref_ptr. The position of the next_key_ptr
> - field is pointed to by ref. The stored reference is actually
> - the offset backward from the beginning of the hash table.
> - */
> - void store_next_key_ref(uchar *key_ref_ptr, uchar *ref)
> - {
> - store_offset(size_of_key_ofs, key_ref_ptr, (ulong) (hash_table-ref));
> - }
> -
> /*
> - Check whether the reference to the next_key_ptr field at the position
> - key_ref_ptr contains a nil value.
> - */
> - bool is_null_key_ref(uchar *key_ref_ptr)
> - {
> - ulong nil= 0;
> - return memcmp(key_ref_ptr, &nil, size_of_key_ofs ) == 0;
> - }
> + This flag is set to TRUE if the implementation of the MRR interface cannot
> + handle range association labels and does not return them to the caller of
> + the multi_range_read_next handler function. E.g. the implementation of
> + the MRR inteface for the Falcon engine could not return association
> + labels to the caller of multi_range_read_next.
> + The flag is set by JOIN_CACHE_BKA::init() and is not ever changed.
> + */
> + bool no_association;
>
> /*
> - Set the reference to the next_key_ptr field at the position
> - key_ref_ptr equal to nil.
> + This field contains the association label returned by the
> + multi_range_read_next function.
> + See the function JOIN_CACHE_BKAH::get_curr_key_association()
> */
> - void store_null_key_ref(uchar *key_ref_ptr)
> - {
> - ulong nil= 0;
> - store_offset(size_of_key_ofs, key_ref_ptr, nil);
> - }
> -
> - uchar *get_next_rec_ref(uchar *ref_ptr)
> - {
> - return buff+get_offset(get_size_of_rec_offset(), ref_ptr);
> - }
> -
> - void store_next_rec_ref(uchar *ref_ptr, uchar *ref)
> - {
> - store_offset(get_size_of_rec_offset(), ref_ptr, (ulong) (ref-buff));
> - }
> -
> - /*
> - Get the position of the embedded key value for the current
> - record pointed to by get_curr_rec().
> - */
> - uchar *get_curr_emb_key()
> - {
> - return get_curr_rec()+data_fields_offset;
> - }
> + uchar *curr_matching_chain;
>
> - /*
> - Get the position of the embedded key value pointed to by a reference
> - stored at ref_ptr. The stored reference is actually the offset from
> - the beginning of the join buffer.
> - */
> - uchar *get_emb_key(uchar *ref_ptr)
> - {
> - return buff+get_offset(get_size_of_rec_offset(), ref_ptr);
> - }
> +protected:
>
> - /*
> - Store the reference to an embedded key at the position key_ref_ptr.
> - The position of the embedded key is pointed to by ref. The stored
> - reference is actually the offset from the beginning of the join buffer.
> - */
> - void store_emb_key_ref(uchar *ref_ptr, uchar *ref)
> - {
> - store_offset(get_size_of_rec_offset(), ref_ptr, (ulong) (ref-buff));
> - }
> -
> - /*
> - Calculate how much space in the buffer would not be occupied by
> - records, key entries and additional memory for the MMR buffer.
> - */
> - ulong rem_space()
> - {
> - return max(last_key_entry-end_pos-aux_buff_size,0);
> - }
> + uint get_number_of_ranges_for_mrr() { return key_entries; }
>
> /*
> Initialize the MRR buffer allocating some space within the join buffer.
> The entire space between the last record put into the join buffer and the
> last key entry added to the hash table is used for the MRR buffer.
> */
> - void init_mrr_buff()
> + int setup_aux_buffer(HANDLER_BUFFER &aux_buff)
> {
> - mrr_buff.buffer= end_pos;
> - mrr_buff.buffer_end= last_key_entry;
> + aux_buff.buffer= end_pos;
> + aux_buff.buffer_end= last_key_entry;
> + return 0;
> }
>
> - /* Skip record from JOIN_CACHE_BKA_UNIQUE buffer if its match flag is on */
> - bool skip_record_if_match();
> -
> - /* Using BKA_UNIQUE find matches for records from join buffer */
> - enum_nested_loop_state join_matching_records(bool skip_last);
> + bool prepare_look_for_matches(bool skip_last);
>
> - /* Search for a key in the hash table of the join buffer */
> - bool key_search(uchar *key, uint key_len, uchar **key_ref_ptr);
> + /*
> + The implementations of the methods
> + - get_next_candidate_for_match
> + - skip_recurrent_candidate_for_match
> + - read_next_candidate_for_match
> + are inherited from the JOIN_CACHE_BNLH class
> + */
>
> public:
>
> /*
> - This constructor creates an unlinked BKA_UNIQUE join cache. The cache is
> - to be used to join table 'tab' to the result of joining the previous tables
> + This constructor creates an unlinked BKAH join cache. The cache is to be
psergey: this_function_syntax
> + used to join table 'tab' to the result of joining the previous tables
> specified by the 'j' parameter.
> The MRR mode initially is set to 'flags'.
> */
> - JOIN_CACHE_BKA_UNIQUE(JOIN *j, JOIN_TAB *tab, uint flags)
> - :JOIN_CACHE_BKA(j, tab, flags) {}
> + JOIN_CACHE_BKAH(JOIN *j, JOIN_TAB *tab, uint flags)
> + :JOIN_CACHE_BNLH(j, tab), mrr_mode(flags) {}
>
> /*
> - This constructor creates a linked BKA_UNIQUE join cache. The cache is
> - to be used to join table 'tab' to the result of joining the previous tables
> - specified by the 'j' parameter. The parameter 'prev' specifies the cache
> - object to which this cache is linked.
> + This constructor creates a linked BKAH join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter. The parameter 'prev' specifies the previous
> + cache object to which this cache is linked.
> The MRR mode initially is set to 'flags'.
> */
> - JOIN_CACHE_BKA_UNIQUE(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE* prev)
> - :JOIN_CACHE_BKA(j, tab, flags, prev) {}
> -
> - /* Initialize the BKA_UNIQUE cache */
> - int init();
> + JOIN_CACHE_BKAH(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE *prev)
> + :JOIN_CACHE_BNLH(j, tab, prev), mrr_mode(flags) {}
>
> - /* Reset the JOIN_CACHE_BKA_UNIQUE buffer for reading/writing */
> - void reset(bool for_writing);
> -
> - /* Add a record into the JOIN_CACHE_BKA_UNIQUE buffer */
> - bool put_record();
> + uchar **get_curr_association_ptr() { return &curr_matching_chain; }
>
> - /* Read the next record from the JOIN_CACHE_BKA_UNIQUE buffer */
> - bool get_record();
> + /* Initialize the BKAH cache */
> + int init();
>
> - /*
> - Shall check whether all records in a key chain have
> - their match flags set on
> - */
> - virtual bool check_all_match_flags_for_key(uchar *key_chain_ptr);
> + enum Join_algorithm get_join_alg() { return BKAH_JOIN_ALG; }
>
> - uint get_next_key(uchar **key);
> -
> - /* Get the head of the record chain attached to the current key entry */
> - uchar *get_curr_key_chain()
> - {
> - return get_next_rec_ref(curr_key_entry+key_entry_length-
> - get_size_of_rec_offset());
> - }
> -
> - /* Check if the record combination matches the index condition */
> - bool skip_index_tuple(range_seq_t rseq, char *range_info);
> + /* Check index condition of the joined table for a record from BKAH cache */
> + bool skip_index_tuple(char *range_info);
> };
>
>
> @@ -1745,6 +2298,10 @@
> NULL : join_tab+const_tables;
> }
> bool setup_subquery_caches();
> + bool shrink_join_buffers(JOIN_TAB *jt,
> + ulonglong curr_space,
> + ulonglong needed_space);
> +
> private:
> /**
> TRUE if the query contains an aggregate function but has no GROUP
> @@ -1874,6 +2431,15 @@
> TABLE *table= copy_field.to_field->table;
> my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
> table->write_set);
> +
> + /*
> + It looks like the next statement is needed only for a simplified
> + hash function over key values used now in BNLH join.
> + When the implementation of this function will be replaced for a proper
> + full version this statement probably should be removed.
> + */
> + bzero(copy_field.to_ptr,copy_field.to_length);
> +
> copy_field.do_copy(©_field);
> dbug_tmp_restore_column_map(table->write_set, old_map);
> null_key= to_field->is_null();
> @@ -1907,6 +2473,15 @@
> my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
> table->write_set);
> int res= FALSE;
> +
> + /*
> + It looks like the next statement is needed only for a simplified
> + hash function over key values used now in BNLH join.
> + When the implementation of this function will be replaced for a proper
> + full version this statement probably should be removed.
> + */
> + to_field->reset();
> +
> if (use_value)
> item->save_val(to_field);
> else
> @@ -1969,7 +2544,6 @@
> int safe_index_read(JOIN_TAB *tab);
> COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value);
> int test_if_item_cache_changed(List<Cached_item> &list);
> -void calc_used_field_length(THD *thd, JOIN_TAB *join_tab);
> int join_init_read_record(JOIN_TAB *tab);
> void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key);
> inline Item * and_items(Item* cond, Item *item)
> @@ -1998,7 +2572,8 @@
> void eliminate_tables(JOIN *join);
>
> /* Index Condition Pushdown entry point function */
> -void push_index_cond(JOIN_TAB *tab, uint keyno, bool other_tbls_ok);
> +void push_index_cond(JOIN_TAB *tab, uint keyno, bool other_tbls_ok,
> + bool factor_out);
>
> /****************************************************************************
> Temporary table support for SQL Runtime
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
1
All,
I've created the download, release notes, and changelog pages for
MariaDB 5.2.3:
http://askmonty.org/wiki/MariaDB:Download:MariaDB_5.2.3
http://kb.askmonty.org/v/mariadb-523-release-notes
http://kb.askmonty.org/v/mariadb-523-changelog
The mirrors are still updating currently but all of them should
have the release soon. If you can't wait, the osuosl.org mirror is the
primary one and is always up-to-date.
Please let me know if anything is missing from the release notes or
changelog or if there are any errors. If you have editing rights, feel
free to make the corrections or additions directly.
Thanks.
--
Daniel Bartholomew
Monty Program - http://askmonty.org
3
3

Re: [Maria-developers] [Commits] Rev 2971: MBug#643463: Slow XtraDB shutdown: Fix more sleeps delaying shutdown. in http://bazaar.launchpad.net/~maria-captains/maria/5.1
by Kristian Nielsen 10 Nov '10
by Kristian Nielsen 10 Nov '10
10 Nov '10
Hi Codership,
Can you do a review of this patch for InnoDB (XtraDB)?
It is https://bugs.launchpad.net/percona-server/+bug/643463, it fixes a
problem that a number of threads in the InnoDB code used sleep() for several
seconds, which unnecessarily delays shutdown (this is especially annoying when
doing testing, eg. the test suite).
- Kristian.
knielsen(a)knielsen-hq.org writes:
> At http://bazaar.launchpad.net/~maria-captains/maria/5.1
>
> ------------------------------------------------------------
> revno: 2971
> revision-id: knielsen(a)knielsen-hq.org-20101109140357-2obql1onnmjg6to9
> parent: monty(a)askmonty.org-20101107122529-sl5sup1m9gjxlzte
> committer: knielsen(a)knielsen-hq.org
> branch nick: mariadb-5.1
> timestamp: Tue 2010-11-09 15:03:57 +0100
> message:
> MBug#643463: Slow XtraDB shutdown: Fix more sleeps delaying shutdown.
>
> This patch removes most remaining delays due to uninteruptible sleep()
> during shutdown, as found using PMP. This makes standard test run very
> close in speed to with --loose-innodb-fast-shutdown=2, and greatly
> speeds up running the test suite.
> === modified file 'storage/xtradb/include/srv0srv.h'
> --- a/storage/xtradb/include/srv0srv.h 2010-11-03 21:40:53 +0000
> +++ b/storage/xtradb/include/srv0srv.h 2010-11-09 14:03:57 +0000
> @@ -57,8 +57,8 @@ extern const char srv_mysql50_table_name
> thread starts running */
> extern os_event_t srv_lock_timeout_thread_event;
>
> -/* This event is set to tell the purge thread to shut down */
> -extern os_event_t srv_purge_thread_event;
> +/* This event is set at shutdown to wakeup threads from sleep */
> +extern os_event_t srv_shutdown_event;
>
> /* If the last data file is auto-extended, we add this many pages to it
> at a time */
>
> === modified file 'storage/xtradb/log/log0log.c'
> --- a/storage/xtradb/log/log0log.c 2010-11-03 21:40:53 +0000
> +++ b/storage/xtradb/log/log0log.c 2010-11-09 14:03:57 +0000
> @@ -3102,7 +3102,7 @@ logs_empty_and_mark_files_at_shutdown(vo
> algorithm only works if the server is idle at shutdown */
>
> srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
> - os_event_set(srv_purge_thread_event);
> + os_event_set(srv_shutdown_event);
> loop:
> os_thread_sleep(100000);
>
>
> === modified file 'storage/xtradb/srv/srv0srv.c'
> --- a/storage/xtradb/srv/srv0srv.c 2010-11-03 21:40:53 +0000
> +++ b/storage/xtradb/srv/srv0srv.c 2010-11-09 14:03:57 +0000
> @@ -704,7 +704,7 @@ UNIV_INTERN srv_slot_t* srv_mysql_table
>
> UNIV_INTERN os_event_t srv_lock_timeout_thread_event;
>
> -UNIV_INTERN os_event_t srv_purge_thread_event;
> +UNIV_INTERN os_event_t srv_shutdown_event;
>
> UNIV_INTERN srv_sys_t* srv_sys = NULL;
>
> @@ -1011,7 +1011,7 @@ srv_init(void)
> }
>
> srv_lock_timeout_thread_event = os_event_create(NULL);
> - srv_purge_thread_event = os_event_create(NULL);
> + srv_shutdown_event = os_event_create(NULL);
>
> for (i = 0; i < SRV_MASTER + 1; i++) {
> srv_n_threads_active[i] = 0;
> @@ -2239,7 +2239,7 @@ loop:
> /* Wake up every 5 seconds to see if we need to print
> monitor information. */
>
> - os_thread_sleep(5000000);
> + os_event_wait_time(srv_shutdown_event, 5000000);
>
> current_time = time(NULL);
>
> @@ -2381,7 +2381,7 @@ loop:
> /* When someone is waiting for a lock, we wake up every second
> and check if a timeout has passed for a lock wait */
>
> - os_thread_sleep(1000000);
> + os_event_wait_time(srv_shutdown_event, 1000000);
>
> srv_lock_timeout_active = TRUE;
>
> @@ -2546,7 +2546,7 @@ loop:
>
> fflush(stderr);
>
> - os_thread_sleep(1000000);
> + os_event_wait_time(srv_shutdown_event, 1000000);
>
> if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
>
> @@ -2590,7 +2590,7 @@ srv_LRU_dump_restore_thread(
> last_dump_time = time(NULL);
>
> loop:
> - os_thread_sleep(5000000);
> + os_event_wait_time(srv_shutdown_event, 5000000);
>
> if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
> goto exit_func;
> @@ -2754,7 +2754,7 @@ loop:
>
> if (!skip_sleep) {
>
> - os_thread_sleep(1000000);
> + os_event_wait_time(srv_shutdown_event, 1000000);
> srv_main_sleeps++;
>
> /*
> @@ -3340,10 +3340,10 @@ loop:
> mutex_exit(&kernel_mutex);
>
> sleep_ms = 10;
> - os_event_reset(srv_purge_thread_event);
> + os_event_reset(srv_shutdown_event);
> }
>
> - os_event_wait_time(srv_purge_thread_event, sleep_ms * 1000);
> + os_event_wait_time(srv_shutdown_event, sleep_ms * 1000);
>
> history_len = trx_sys->rseg_history_len;
> if (history_len > 1000)
>
> _______________________________________________
> commits mailing list
> commits(a)mariadb.org
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
1
0

09 Nov '10
Hi Philip,
I've been fixing bugs in maria-5.3-mwl128-dsmrr-cpk tree, fixed two of the four
problems so far. My general impression is that crashes are easier to fix than
wrong results. Is it possible to run RQG in a mode that will cause it to ignore
the difference in query results, and stop only on crashes?
if yes, I'd like to get a command/grammar that were used to test the
-mwl128-dsmrr-cpk tree.
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
1

Re: [Maria-developers] [Commits] Rev 2845: Fixed LP bug #668644. in file:///home/igor/maria/maria-5.3-bug668644/
by Sergey Petrunya 08 Nov '10
by Sergey Petrunya 08 Nov '10
08 Nov '10
Ok to push.
On Mon, Nov 08, 2010 at 08:36:33PM -0800, Igor Babaev wrote:
> At file:///home/igor/maria/maria-5.3-bug668644/
>
> ------------------------------------------------------------
> revno: 2845
> revision-id: igor(a)askmonty.org-20101109043632-s053dbydv48cr9nz
> parent: monty(a)askmonty.org-20101105103751-09kb6rx5tvpyywen
> committer: Igor Babaev <igor(a)askmonty.org>
> branch nick: maria-5.3-bug668644
> timestamp: Mon 2010-11-08 20:36:32 -0800
> message:
> Fixed LP bug #668644.
> The pushdown condition for the sorted table in a query can be complemented
> by the conditions from HAVING. This transformation is done in JOIN::exec
> pretty late after the original pushdown condition have been saved in the
> field pre_idx_push_select_cond for the sorted table. So this field must
> be updated after the inclusion of the condition from HAVING.
> === modified file 'mysql-test/suite/innodb/r/innodb_mysql.result'
> --- a/mysql-test/suite/innodb/r/innodb_mysql.result 2010-10-28 17:04:23 +0000
> +++ b/mysql-test/suite/innodb/r/innodb_mysql.result 2010-11-09 04:36:32 +0000
> @@ -2609,5 +2609,41 @@
> rows 3
> Extra Using index
> DROP TABLE t1;
> -#
> End of 5.1 tests
> +#
> +# Bug#668644: HAVING + ORDER BY
> +#
> +CREATE TABLE t1 (
> +pk int NOT NULL PRIMARY KEY, i int DEFAULT NULL,
> +INDEX idx (i)
> +) ENGINE=INNODB;
> +INSERT INTO t1 VALUES
> +(6,-1636630528),(2,-1097924608),(1,6),(3,6),(4,1148715008),(5,1541734400);
> +CREATE TABLE t2 (
> +i int DEFAULT NULL,
> +pk int NOT NULL PRIMARY KEY,
> +INDEX idx (i)
> +) ENGINE= INNODB;
> +INSERT INTO t2 VALUES
> +(-1993998336,20),(-1036582912,1),(-733413376,5),(-538247168,16),
> +(-514260992,4),(-249561088,9),(1,2),(1,6),(2,10),(2,19),(4,17),
> +(5,14),(5,15),(6,8),(7,13),(8,18),(9,11),(9,12),(257425408,7),
> +(576061440,3);
> +EXPLAIN
> +SELECT t1 .i AS f FROM t1, t2
> +WHERE t2.i = t1.pk AND t1.pk BETWEEN 0 AND 224
> +HAVING f > 7
> +ORDER BY f;
> +id select_type table type possible_keys key key_len ref rows Extra
> +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort
> +1 SIMPLE t2 ref idx idx 5 test.t1.pk 1 Using index
> +SELECT t1 .i AS f FROM t1, t2
> +WHERE t2.i = t1.pk AND t1.pk BETWEEN 0 AND 224
> +HAVING f > 7
> +ORDER BY f;
> +f
> +1148715008
> +1541734400
> +1541734400
> +DROP TABLE t1, t2;
> +End of 5.3 tests
>
> === modified file 'mysql-test/suite/innodb/t/innodb_mysql.test'
> --- a/mysql-test/suite/innodb/t/innodb_mysql.test 2010-10-19 13:58:35 +0000
> +++ b/mysql-test/suite/innodb/t/innodb_mysql.test 2010-11-09 04:36:32 +0000
> @@ -840,7 +840,41 @@
>
> DROP TABLE t1;
>
> ---echo #
> -
> -
> --echo End of 5.1 tests
> +
> +--echo #
> +--echo # Bug#668644: HAVING + ORDER BY
> +--echo #
> +
> +CREATE TABLE t1 (
> + pk int NOT NULL PRIMARY KEY, i int DEFAULT NULL,
> + INDEX idx (i)
> +) ENGINE=INNODB;
> +INSERT INTO t1 VALUES
> + (6,-1636630528),(2,-1097924608),(1,6),(3,6),(4,1148715008),(5,1541734400);
> +
> +CREATE TABLE t2 (
> + i int DEFAULT NULL,
> + pk int NOT NULL PRIMARY KEY,
> + INDEX idx (i)
> +) ENGINE= INNODB;
> +INSERT INTO t2 VALUES
> + (-1993998336,20),(-1036582912,1),(-733413376,5),(-538247168,16),
> + (-514260992,4),(-249561088,9),(1,2),(1,6),(2,10),(2,19),(4,17),
> + (5,14),(5,15),(6,8),(7,13),(8,18),(9,11),(9,12),(257425408,7),
> + (576061440,3);
> +
> +EXPLAIN
> +SELECT t1 .i AS f FROM t1, t2
> + WHERE t2.i = t1.pk AND t1.pk BETWEEN 0 AND 224
> + HAVING f > 7
> + ORDER BY f;
> +SELECT t1 .i AS f FROM t1, t2
> + WHERE t2.i = t1.pk AND t1.pk BETWEEN 0 AND 224
> + HAVING f > 7
> + ORDER BY f;
> +
> +DROP TABLE t1, t2;
> +
> +
> +--echo End of 5.3 tests
>
> === modified file 'sql/opt_index_cond_pushdown.cc'
> --- a/sql/opt_index_cond_pushdown.cc 2009-12-22 12:49:15 +0000
> +++ b/sql/opt_index_cond_pushdown.cc 2010-11-09 04:36:32 +0000
> @@ -318,7 +318,7 @@
> if (idx_cond)
> {
> Item *idx_remainder_cond= 0;
> - tab->pre_idx_push_select_cond= tab->select_cond;
> + tab->pre_idx_push_select_cond= tab->select->cond;
> /*
> For BKA cache we store condition to special BKA cache field
> because evaluation of the condition requires additional operations
>
> === modified file 'sql/sql_select.cc'
> --- a/sql/sql_select.cc 2010-10-28 17:04:23 +0000
> +++ b/sql/sql_select.cc 2010-11-09 04:36:32 +0000
> @@ -2213,6 +2213,14 @@
> DBUG_VOID_RETURN;
> curr_table->select->cond->fix_fields(thd, 0);
> }
> + if (curr_table->pre_idx_push_select_cond)
> + {
> + if (!(curr_table->pre_idx_push_select_cond=
> + new Item_cond_and(curr_table->pre_idx_push_select_cond,
> + sort_table_cond)))
> + DBUG_VOID_RETURN;
> + curr_table->pre_idx_push_select_cond->fix_fields(thd, 0);
> + }
> curr_table->set_select_cond(curr_table->select->cond, __LINE__);
> curr_table->select_cond->top_level_item();
> DBUG_EXECUTE("where",print_where(curr_table->select->cond,
> @@ -6355,6 +6363,7 @@
> join_tab->do_firstmatch= NULL;
> join_tab->loosescan_match_tab= NULL;
> join_tab->emb_sj_nest= NULL;
> + join_tab->pre_idx_push_select_cond= NULL;
> bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
> temp_table->status=0;
> temp_table->null_row=0;
>
> _______________________________________________
> commits mailing list
> commits(a)mariadb.org
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
--
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
0

07 Nov '10
We discussed this in Istanbul but were vague. Domas has provided more
details on the problem. Fixing this will make high-concurrency results
much better.
http://bugs.mysql.com/bug.php?id=58037&thanks=4
--
Mark Callaghan
mdcallag(a)gmail.com
1
0

[Maria-developers] WL#166 New (by Dreas): Add server hostname/IP when access is denied
by worklog-noreply@askmonty.org 07 Nov '10
by worklog-noreply@askmonty.org 07 Nov '10
07 Nov '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Add server hostname/IP when access is denied
CREATION DATE..: Sun, 07 Nov 2010, 16:17
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 166 (http://askmonty.org/worklog/?tid=166)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
If you're trying to access MariaDB without correct grants, it returns "Access
denied for user 'user'@'ip' to database 'database'". It would be VERY useful to
have the actual server hostname/IP that is trying to connect to included in the
message, so it can be seen which server is missing the grant. Often when called
from a script, handling a large MySQL cluster this is not directly obvious.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

05 Nov '10
Hi Philip,
The combined tree with DS-MRR improvements and MWL#128 is ready for testing. It
is located at lp:~maria-captains/maria/maria-5.3-mwl128-dsmrr-cpk/ .
I don't know how hard that is for you, but it would be useful to check the failures
- against 5.3-main tree (to see whether the problem is in the new code or not)
- against lp:~maria-captains/maria-5.3-mwl128 (to see whether the problem is
in MWL#128 or in the DS-MRR code)
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
1

[Maria-developers] Transactional INFORMATION_SCHEMA / status variables?
by Kristian Nielsen 05 Nov '10
by Kristian Nielsen 05 Nov '10
05 Nov '10
Would it make sense to have transactional behaviour for status variables,
and/or information_schema tables? Or does this break the code and/or user
expectations too much?
The motivation is to follow up on MWL#116, group commit, which introduces
consistent commit order between storage engines and binary log.
I want to use this to get a consistent binlog position for START TRANSACTION
WITH CONSISTENT SNAPSHOT, without taking any additional locks. Currently, I
believe it is common (eg. mysqlbinlog --master-data --single-transaction) to
do something like this:
FLUSH TABLES WITH READ LOCK;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
UNLOCK TABLES
<take consistent backup by dumping tables using the consistent snapshot>
and this takes a lock that can depending on circumstances severely affect the
server:
http://www.mysqlperformanceblog.com/2010/04/24/how-fast-is-flush-tables-wit…
One idea is to let the binlog storage engine participate in START TRANSACTION
WITH CONSISTENT SNAPSHOT, by installing a start_consistent_snapshot() method
in its handlerton. And then do something like this:
START TRANSACTION WITH CONSISTENT SNAPSHOT;
SELECT variable_value FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE
variable_name IN ('binlog_master_file', 'binlog_master_position');
<dump other transactional tables>
If the SELECT of binlog_master_file and binlog_master_position could be
transactional, then the binlog engine could return the correct values
associated with the consistent snapshot, without blocking any other
transactions.
I like the simplicity of this idea, but I do not understand server transaction
handling enough to be sure it will work well, some concerns:
- Using SHOW STATUS / INFORMATION_SCHEMA.SESSION_STATUS like this could be
surprising to people that do not expect different parts of the results to
display different kinds of transactional behaviour. This could be helped by
using instead a separate INFORMATION_SCHEMA table for the binlog position.
- But this raises another concern, if an INFORMATION_SCHEMA can be
transactional in this respect?
- Also, it seems to me that merely selecting from such transactional
INFORMATION_SCHEMA table would then start a new transaction inside the
binlog engine. I wonder if this would cause any unpleasant side effects?
Any suggestions or comments?
----
If this does not work, I have another idea, which I think is more general, but
also more complicated to implement.
The idea is that every transaction has a local transaction ID, assigned at the
start (we already have this, in thd->transaction.xid_state.xid).
Each engine will transactionally store the local transaction ID of the last
transaction committed. The binary log will similarly store this ID along with
every transaction that is binlogged.
Then START TRANSACTION WITH CONSISTENT SNAPSHOT could optionally return the
local transaction ID of the last committed transaction visible in the snapshot
obtained. This local transaction ID could then be mapped to binlog position
(with eg. mysqldump), and more generally any binlog plugin could provide a way
to map such local transaction ID into its own global transaction ID.
Similarly, after restore of InnoDB hot backup or LVM snapshot, one could ask
the engine for last committed local transaction ID, and map this to binlog
position / global transaction ID to be able to use the restored backup to
provision a new slave.
This would work with any storage engine and any binlog/replication
implementation, without any need for FLUSH TABLES WITH READ LOCK.
- Kristian.
3
3

Re: [Maria-developers] [Commits] Rev 2845: Fixed LP bug #664594 and other bugs leading to invalid execution in file:///home/igor/maria/maria-5.3-mwl128/
by Sergey Petrunya 03 Nov '10
by Sergey Petrunya 03 Nov '10
03 Nov '10
Hello Igor,
Ok to push.
On Wed, Nov 03, 2010 at 12:26:19PM -0700, Igor Babaev wrote:
> At file:///home/igor/maria/maria-5.3-mwl128/
>
> ------------------------------------------------------------
> revno: 2845
> revision-id: igor(a)askmonty.org-20101103192618-17ii8dyn1h2qzdy8
> parent: igor(a)askmonty.org-20101102235032-vh451jmuugv1gsr2
> committer: Igor Babaev <igor(a)askmonty.org>
> branch nick: maria-5.3-mwl128
> timestamp: Wed 2010-11-03 12:26:18 -0700
> message:
> Fixed LP bug #664594 and other bugs leading to invalid execution
> plans or wrong results due to the fact that JOIN_CACHE functions
> ignored the possibility of interleaving materialized semijoin
> tables with tables whose records were stored in join buffers.
> This fixes would become mostly unnecessary if the new code of
> mwl 90 was merged into 5.3 right now.
> Yet the fix the code of optimize_wo_join_buffering was needed
> in any case.
> === modified file 'mysql-test/r/explain.result'
> --- a/mysql-test/r/explain.result 2010-10-27 23:31:22 +0000
> +++ b/mysql-test/r/explain.result 2010-11-03 19:26:18 +0000
> @@ -195,16 +195,16 @@
> flush tables;
> EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where
> -1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; FirstMatch(OUTR)
> +1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where; Start temporary
> +1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
> flush tables;
> SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
> dt
> flush tables;
> EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where
> -1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; FirstMatch(OUTR)
> +1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where; Start temporary
> +1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
> flush tables;
> SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
> dt
>
> === modified file 'mysql-test/r/group_by.result'
> --- a/mysql-test/r/group_by.result 2010-10-27 23:31:22 +0000
> +++ b/mysql-test/r/group_by.result 2010-11-03 19:26:18 +0000
> @@ -1543,7 +1543,8 @@
> (SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 index PRIMARY,i2 PRIMARY 4 NULL 144 Using index
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 144 Using where; FirstMatch(t1)
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 4 func 1
> +2 SUBQUERY t1 ALL NULL NULL NULL NULL 144
> CREATE TABLE t2 (a INT, b INT, KEY(a));
> INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
> EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2;
>
> === modified file 'mysql-test/r/subselect.result'
> --- a/mysql-test/r/subselect.result 2010-10-27 23:31:22 +0000
> +++ b/mysql-test/r/subselect.result 2010-11-03 19:26:18 +0000
> @@ -2831,9 +2831,10 @@
> explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; FirstMatch(t1)
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1 1.00
> +2 SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
> Warnings:
> -Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`two` = `test`.`t1`.`two`) and (`test`.`t2`.`one` = `test`.`t1`.`one`) and (`test`.`t2`.`flag` = 'N'))
> +Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
> explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
> @@ -4203,8 +4204,8 @@
> CREATE INDEX I2 ON t1 (b);
> EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan
> -1 PRIMARY t1 ref I2 I2 13 test.t1.a 2 Using index condition
> +1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
> +1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1)
> SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
> a b
> CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
> @@ -4213,15 +4214,15 @@
> CREATE INDEX I2 ON t2 (b);
> EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t2 index I1 I1 4 NULL 2 Using where; Using index; LooseScan
> -1 PRIMARY t2 ref I2 I2 13 test.t2.a 2 Using index condition
> +1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where
> +1 PRIMARY t2 ref I1 I1 4 test.t2.b 2 Using where; Using index; FirstMatch(t2)
> SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
> a b
> EXPLAIN
> SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan
> -1 PRIMARY t1 ref I2 I2 13 test.t1.a 2 Using index condition
> +1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
> +1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1)
> SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
> a b
> DROP TABLE t1,t2;
>
> === modified file 'mysql-test/r/subselect3.result'
> --- a/mysql-test/r/subselect3.result 2010-10-27 23:31:22 +0000
> +++ b/mysql-test/r/subselect3.result 2010-11-03 19:26:18 +0000
> @@ -103,7 +103,7 @@
> 1 1
> show status like '%Handler_read_rnd_next';
> Variable_name Value
> -Handler_read_rnd_next 5
> +Handler_read_rnd_next 11
> delete from t2;
> insert into t2 values (NULL, 0),(NULL, 0), (NULL, 0), (NULL, 0);
> set optimizer_switch='subquery_cache=off';
> @@ -1112,7 +1112,8 @@
> explain select * from (select a from t0) X where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>)
> +1 PRIMARY subselect3 eq_ref unique_key unique_key 5 func 1
> +3 SUBQUERY t1 ALL NULL NULL NULL NULL 20
> 2 DERIVED t0 ALL NULL NULL NULL NULL 11
> drop table t0, t1;
> create table t0 (a int);
> @@ -1124,16 +1125,18 @@
> insert into t3 select A.a + 10*B.a from t0 A, t0 B;
> explain select * from t3 where a in (select kp1 from t1 where kp1<20);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 100
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
> +2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using where; Using index
> create table t4 (pk int primary key);
> insert into t4 select a from t3;
> explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20
> and t4.pk=t1.c);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR; LooseScan
> -1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t1)
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 100
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
> +2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR
> +2 SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index
> drop table t1, t3, t4;
> create table t1 (a int) as select * from t0 where a < 5;
> set @save_max_heap_table_size=@@max_heap_table_size;
> @@ -1261,12 +1264,14 @@
> create table t2 as select * from t1;
> explain select * from t2 where a in (select b from t1 where a=3);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
> +2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
> explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
> +2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
> drop table t1,t2;
> create table t1 (a int, b int);
> insert into t1 select a,a from t0;
> @@ -1295,7 +1300,8 @@
> explain select * from t0 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 2
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0)
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
> +2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
> select * from t0 where a in (select a from t1);
> a
> 10.24
> @@ -1308,7 +1314,8 @@
> explain select * from t0 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 2
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0)
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 4 func 1
> +2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
> select * from t0 where a in (select a from t1);
> a
> 2008-01-01
>
> === modified file 'mysql-test/r/subselect3_jcl6.result'
> --- a/mysql-test/r/subselect3_jcl6.result 2010-10-27 23:31:22 +0000
> +++ b/mysql-test/r/subselect3_jcl6.result 2010-11-03 19:26:18 +0000
> @@ -110,7 +110,7 @@
> 1 1
> show status like '%Handler_read_rnd_next';
> Variable_name Value
> -Handler_read_rnd_next 5
> +Handler_read_rnd_next 11
> delete from t2;
> insert into t2 values (NULL, 0),(NULL, 0), (NULL, 0), (NULL, 0);
> set optimizer_switch='subquery_cache=off';
> @@ -1031,7 +1031,7 @@
> t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
> -1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (incremental, BNL join)
> +1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
> 1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (incremental, BNL join)
> 2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
> 2 SUBQUERY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
> @@ -1039,7 +1039,6 @@
> t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
> a b c
> 256 67 NULL
> -256 67 NULL
> drop table t1, t11, t12, t21, t22;
> create table t1(a int);
> insert into t1 values (0),(1);
> @@ -1120,7 +1119,8 @@
> explain select * from (select a from t0) X where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>); Using join buffer (flat, BNL join)
> +1 PRIMARY subselect3 eq_ref unique_key unique_key 5 func 1
> +3 SUBQUERY t1 ALL NULL NULL NULL NULL 20
> 2 DERIVED t0 ALL NULL NULL NULL NULL 11
> drop table t0, t1;
> create table t0 (a int);
> @@ -1132,16 +1132,18 @@
> insert into t3 select A.a + 10*B.a from t0 A, t0 B;
> explain select * from t3 where a in (select kp1 from t1 where kp1<20);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 100
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
> +2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using where; Using index
> create table t4 (pk int primary key);
> insert into t4 select a from t3;
> explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20
> and t4.pk=t1.c);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR; LooseScan
> -1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t1)
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 100
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
> +2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR
> +2 SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index
> drop table t1, t3, t4;
> create table t1 (a int) as select * from t0 where a < 5;
> set @save_max_heap_table_size=@@max_heap_table_size;
> @@ -1269,12 +1271,14 @@
> create table t2 as select * from t1;
> explain select * from t2 where a in (select b from t1 where a=3);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
> +2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
> explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
> +2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
> drop table t1,t2;
> create table t1 (a int, b int);
> insert into t1 select a,a from t0;
> @@ -1303,7 +1307,8 @@
> explain select * from t0 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 2
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
> +2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
> select * from t0 where a in (select a from t1);
> a
> 10.24
> @@ -1316,7 +1321,8 @@
> explain select * from t0 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 2
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 4 func 1
> +2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
> select * from t0 where a in (select a from t1);
> a
> 2008-01-01
> @@ -1404,7 +1410,7 @@
> );
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2 1.00
> -1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
> +1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
> 2 SUBQUERY cona ALL NULL NULL NULL NULL 2 100.00 Using where
> 2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using join buffer (flat, BKA join)
> Warnings:
>
> === modified file 'mysql-test/r/subselect_no_mat.result'
> --- a/mysql-test/r/subselect_no_mat.result 2010-10-27 23:31:22 +0000
> +++ b/mysql-test/r/subselect_no_mat.result 2010-11-03 19:26:18 +0000
> @@ -4207,8 +4207,8 @@
> CREATE INDEX I2 ON t1 (b);
> EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan
> -1 PRIMARY t1 ref I2 I2 13 test.t1.a 2 Using index condition
> +1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
> +1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1)
> SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
> a b
> CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
> @@ -4217,15 +4217,15 @@
> CREATE INDEX I2 ON t2 (b);
> EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t2 index I1 I1 4 NULL 2 Using where; Using index; LooseScan
> -1 PRIMARY t2 ref I2 I2 13 test.t2.a 2 Using index condition
> +1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where
> +1 PRIMARY t2 ref I1 I1 4 test.t2.b 2 Using where; Using index; FirstMatch(t2)
> SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
> a b
> EXPLAIN
> SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
> id select_type table type possible_keys key key_len ref rows Extra
> -1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan
> -1 PRIMARY t1 ref I2 I2 13 test.t1.a 2 Using index condition
> +1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
> +1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1)
> SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
> a b
> DROP TABLE t1,t2;
>
> === modified file 'mysql-test/r/subselect_sj.result'
> --- a/mysql-test/r/subselect_sj.result 2010-10-27 23:31:22 +0000
> +++ b/mysql-test/r/subselect_sj.result 2010-11-03 19:26:18 +0000
> @@ -1062,8 +1062,10 @@
> WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 5
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; FirstMatch(t1)
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t3)
> +1 PRIMARY subselect3 eq_ref unique_key unique_key 14 func 1
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 14 func 1
> +3 SUBQUERY t3 ALL NULL NULL NULL NULL 5 Using where
> +2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> SELECT *
> FROM t1
> WHERE t1.val IN (SELECT t2.val FROM t2
>
> === modified file 'mysql-test/r/subselect_sj2.result'
> --- a/mysql-test/r/subselect_sj2.result 2010-10-18 20:33:05 +0000
> +++ b/mysql-test/r/subselect_sj2.result 2010-11-03 19:26:18 +0000
> @@ -52,7 +52,8 @@
> explain select * from t3 where b in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t3 ALL b NULL NULL NULL 10
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t3)
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
> +2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
> select * from t3 where b in (select a from t1);
> a b pk1 pk2 pk3
> 1 1 1 1 1
>
> === modified file 'mysql-test/r/subselect_sj2_jcl6.result'
> --- a/mysql-test/r/subselect_sj2_jcl6.result 2010-10-18 20:33:05 +0000
> +++ b/mysql-test/r/subselect_sj2_jcl6.result 2010-11-03 19:26:18 +0000
> @@ -59,7 +59,8 @@
> explain select * from t3 where b in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t3 ALL b NULL NULL NULL 10
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t3); Using join buffer (flat, BNL join)
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
> +2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
> select * from t3 where b in (select a from t1);
> a b pk1 pk2 pk3
> 1 1 1 1 1
>
> === modified file 'mysql-test/r/subselect_sj_jcl6.result'
> --- a/mysql-test/r/subselect_sj_jcl6.result 2010-10-27 23:31:22 +0000
> +++ b/mysql-test/r/subselect_sj_jcl6.result 2010-11-03 19:26:18 +0000
> @@ -1069,8 +1069,10 @@
> WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 5
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t3); Using join buffer (incremental, BNL join)
> +1 PRIMARY subselect3 eq_ref unique_key unique_key 14 func 1
> +1 PRIMARY subselect2 eq_ref unique_key unique_key 14 func 1
> +3 SUBQUERY t3 ALL NULL NULL NULL NULL 5 Using where
> +2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> SELECT *
> FROM t1
> WHERE t1.val IN (SELECT t2.val FROM t2
>
> === modified file 'mysql-test/r/type_datetime.result'
> --- a/mysql-test/r/type_datetime.result 2010-06-26 10:05:41 +0000
> +++ b/mysql-test/r/type_datetime.result 2010-11-03 19:26:18 +0000
> @@ -537,8 +537,8 @@
> select * from t1
> where id in (select id from t1 as x1 where (t1.cur_date is null));
> id select_type table type possible_keys key key_len ref rows filtered Extra
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
> -1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t1)
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary
> +1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
> Warnings:
> Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
> Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where ((`test`.`x1`.`id` = `test`.`t1`.`id`) and (`test`.`t1`.`cur_date` = 0))
> @@ -549,8 +549,8 @@
> select * from t2
> where id in (select id from t2 as x1 where (t2.cur_date is null));
> id select_type table type possible_keys key key_len ref rows filtered Extra
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
> -1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t2)
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary
> +1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
> Warnings:
> Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
> Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where ((`test`.`x1`.`id` = `test`.`t2`.`id`) and (`test`.`t2`.`cur_date` = 0))
>
> === modified file 'sql/sql_join_cache.cc'
> --- a/sql/sql_join_cache.cc 2010-10-27 23:37:33 +0000
> +++ b/sql/sql_join_cache.cc 2010-11-03 19:26:18 +0000
> @@ -137,7 +137,44 @@
> *descr_ptr= copy_ptr;
> return len;
> }
> -
> +
> +/*
> + Get the next table whose records are stored in the join buffer of this cache
> +
> + SYNOPSIS
> + get_next_table()
> + tab the table for which the next table is to be returned
> +
> + DESCRIPTION
> + For a given table whose records are stored in this cache the function
> + returns the next such table if there is any.
> + The function takes into account that the tables whose records are
> + are stored in the same cache now can interleave with tables from
> + materialized semijoin subqueries.
> +
> + TODO
> + This function should be modified/simplified after the new code for
> + materialized semijoins is merged.
> +
> + RETURN
> + The next join table whose records are stored in the buffer of this cache
> + if such table exists, 0 - otherwise
> +*/
> +
> +JOIN_TAB *JOIN_CACHE::get_next_table(JOIN_TAB *tab)
> +{
> +
> + if (++tab == join_tab)
> + return NULL;
> + if (join_tab->first_sjm_sibling)
> + return tab;
> + uint i= tab-join->join_tab;
> + while (sj_is_materialize_strategy(join->best_positions[i].sj_strategy) &&
> + i < join->tables)
> + i+= join->best_positions[i].n_sj_tables;
> + return join->join_tab+i < join_tab ? join->join_tab+i : NULL;
> +}
> +
>
> /*
> Determine different counters of fields associated with a record in the cache
> @@ -159,7 +196,9 @@
> void JOIN_CACHE::calc_record_fields()
> {
> JOIN_TAB *tab = prev_cache ? prev_cache->join_tab :
> - join->join_tab+join->const_tables;
> + (join_tab->first_sjm_sibling ?
> + join_tab->first_sjm_sibling :
> + join->join_tab+join->const_tables);
> tables= join_tab-tab;
>
> fields= 0;
> @@ -169,7 +208,7 @@
> data_field_ptr_count= 0;
> referenced_fields= 0;
>
> - for ( ; tab < join_tab ; tab++)
> + for ( ; tab ; tab= get_next_table(tab))
> {
> tab->calc_used_field_length(FALSE);
> flag_fields+= test(tab->used_null_fields || tab->used_uneven_bit_fields);
> @@ -222,7 +261,8 @@
> cache= this;
> do
> {
> - for (tab= cache->join_tab-cache->tables; tab < cache->join_tab ; tab++)
> + for (tab= cache->join_tab-cache->tables; tab ;
> + tab= cache->get_next_table(tab))
> {
> uint key_args;
> bitmap_clear_all(&tab->table->tmp_set);
> @@ -338,7 +378,7 @@
> ©);
>
> /* Create fields for all null bitmaps and null row flags that are needed */
> - for (tab= join_tab-tables; tab < join_tab; tab++)
> + for (tab= join_tab-tables; tab; tab= get_next_table(tab))
> {
> TABLE *table= tab->table;
>
> @@ -425,7 +465,8 @@
> while (ext_key_arg_cnt)
> {
> cache= cache->prev_cache;
> - for (tab= cache->join_tab-cache->tables; tab < cache->join_tab ; tab++)
> + for (tab= cache->join_tab-cache->tables; tab;
> + tab= cache->get_next_table(tab))
> {
> CACHE_FIELD *copy_end;
> MY_BITMAP *key_read_set= &tab->table->tmp_set;
> @@ -475,7 +516,7 @@
>
> /* Now create local fields that are used to build ref for this key access */
> copy= field_descr+flag_fields;
> - for (tab= join_tab-tables; tab < join_tab ; tab++)
> + for (tab= join_tab-tables; tab; tab= get_next_table(tab))
> {
> length+= add_table_data_fields_to_join_cache(tab, &tab->table->tmp_set,
> &data_field_count, ©,
> @@ -531,7 +572,7 @@
> CACHE_FIELD *copy= field_descr+flag_fields+data_field_count;
> CACHE_FIELD **copy_ptr= blob_ptr+data_field_ptr_count;
>
> - for (tab= join_tab-tables; tab < join_tab; tab++)
> + for (tab= join_tab-tables; tab; tab= get_next_table(tab))
> {
> MY_BITMAP *rem_field_set;
> TABLE *table= tab->table;
> @@ -1341,6 +1382,7 @@
> end_pos= pos= cp;
> *is_full= last_record;
>
> + last_written_is_null_compl= 0;
> if (!join_tab->first_unmatched && join_tab->on_precond)
> {
> join_tab->found= 0;
> @@ -1351,8 +1393,6 @@
> last_written_is_null_compl= 1;
> }
> }
> - else
> - last_written_is_null_compl= 0;
>
> return (uint) (cp-init_pos);
> }
>
> === modified file 'sql/sql_select.cc'
> --- a/sql/sql_select.cc 2010-10-30 22:14:36 +0000
> +++ b/sql/sql_select.cc 2010-11-03 19:26:18 +0000
> @@ -7441,6 +7441,7 @@
> join join for which the check is performed
> options options of the join
> no_jbuf_after don't use join buffering after table with this number
> + prev_tab previous join table
> icp_other_tables_ok OUT TRUE if condition pushdown supports
> other tables presence
> idx_cond_fact_out OUT TRUE if condition pushed to the index is factored
> @@ -7568,6 +7569,7 @@
> uint check_join_cache_usage(JOIN_TAB *tab,
> JOIN *join, ulonglong options,
> uint no_jbuf_after,
> + JOIN_TAB *prev_tab,
> bool *icp_other_tables_ok,
> bool *idx_cond_fact_out)
> {
> @@ -7587,7 +7589,7 @@
>
> *icp_other_tables_ok= TRUE;
> *idx_cond_fact_out= TRUE;
> - if (cache_level == 0 || i == join->const_tables)
> + if (cache_level == 0 || i == join->const_tables || !prev_tab)
> return 0;
>
> if (options & SELECT_NO_JOIN_CACHE)
> @@ -7633,7 +7635,7 @@
> if (tab->first_sj_inner_tab && tab->first_sj_inner_tab != tab &&
> !tab->first_sj_inner_tab->use_join_cache)
> goto no_join_cache;
> - if (!tab[-1].use_join_cache)
> + if (!prev_tab->use_join_cache)
> {
> /*
> Check whether table tab and the previous one belong to the same nest of
> @@ -7655,7 +7657,7 @@
> }
>
> if (!force_unlinked_cache)
> - prev_cache= tab[-1].cache;
> + prev_cache= prev_tab->cache;
>
> switch (tab->type) {
> case JT_ALL:
> @@ -7807,6 +7809,12 @@
> return TRUE; /* purecov: inspected */
> tab->sorted= TRUE;
> }
> +
> + /*
> + SJ-Materialization
> + */
> + if (!(i >= first_sjm_table && i < last_sjm_table))
> + tab->first_sjm_sibling= NULL;
> if (sj_is_materialize_strategy(join->best_positions[i].sj_strategy))
> {
> /* This is a start of semi-join nest */
> @@ -7819,23 +7827,52 @@
>
> if (setup_sj_materialization(tab))
> return TRUE;
> + for (uint j= first_sjm_table; j != last_sjm_table; j++)
> + join->join_tab[j].first_sjm_sibling= join->join_tab + first_sjm_table;
> }
> table->status=STATUS_NO_RECORD;
> pick_table_access_method (tab);
>
> + /*
> + This loop currently can be executed only once as the function
> + check_join_cache_usage does not change the value of tab->type.
> + It won't be true for the future code.
> + */
> + for ( ; ; )
> + {
> + enum join_type tab_type= tab->type;
> + switch (tab->type) {
> + case JT_SYSTEM:
> + case JT_CONST:
> + case JT_EQ_REF:
> + case JT_REF:
> + case JT_REF_OR_NULL:
> + case JT_ALL:
> + if ((jcl= check_join_cache_usage(tab, join, options,
> + no_jbuf_after,
> + i == last_sjm_table ?
> + join->join_tab+first_sjm_table :
> + tab-1,
> + &icp_other_tables_ok,
> + &idx_cond_fact_out)))
> + {
> + tab->use_join_cache= TRUE;
> + tab[-1].next_select=sub_select_cache;
> + }
> + break;
> + default:
> + ;
> + }
> + if (tab->type == tab_type)
> + break;
> + }
> +
> switch (tab->type) {
> case JT_SYSTEM: // Only happens with left join
> case JT_CONST: // Only happens with left join
> /* Only happens with outer joins */
> tab->read_first_record= tab->type == JT_SYSTEM ?
> join_read_system :join_read_const;
> - if ((jcl= check_join_cache_usage(tab, join, options,
> - no_jbuf_after, &icp_other_tables_ok,
> - &idx_cond_fact_out)))
> - {
> - tab->use_join_cache= TRUE;
> - tab[-1].next_select=sub_select_cache;
> - }
> if (table->covering_keys.is_set(tab->ref.key) &&
> !table->no_keyread)
> {
> @@ -7849,13 +7886,6 @@
> case JT_EQ_REF:
> tab->read_record.unlock_row= join_read_key_unlock_row;
> /* fall through */
> - if ((jcl= check_join_cache_usage(tab, join, options,
> - no_jbuf_after, &icp_other_tables_ok,
> - &idx_cond_fact_out)))
> - {
> - tab->use_join_cache= TRUE;
> - tab[-1].next_select=sub_select_cache;
> - }
> if (table->covering_keys.is_set(tab->ref.key) &&
> !table->no_keyread)
> {
> @@ -7875,13 +7905,6 @@
> }
> delete tab->quick;
> tab->quick=0;
> - if ((jcl= check_join_cache_usage(tab, join, options,
> - no_jbuf_after, &icp_other_tables_ok,
> - &idx_cond_fact_out)))
> - {
> - tab->use_join_cache= TRUE;
> - tab[-1].next_select=sub_select_cache;
> - }
> if (table->covering_keys.is_set(tab->ref.key) &&
> !table->no_keyread)
> table->enable_keyread();
> @@ -7896,12 +7919,6 @@
> Also don't use cache if this is the first table in semi-join
> materialization nest.
> */
> - if (check_join_cache_usage(tab, join, options, no_jbuf_after,
> - &icp_other_tables_ok, &idx_cond_fact_out))
> - {
> - tab->use_join_cache= TRUE;
> - tab[-1].next_select=sub_select_cache;
> - }
> /* These init changes read_record */
> if (tab->use_quick == 2)
> {
> @@ -9563,6 +9580,11 @@
> Item_equal *upper= item_field->find_item_equal(upper_levels);
> Item_field *item= item_field;
> TABLE_LIST *field_sjm= embedding_sjm(item_field);
> + if (!field_sjm)
> + {
> + current_sjm= NULL;
> + current_sjm_head= NULL;
> + }
>
> /*
> Check if "item_field=head" equality is already guaranteed to be true
> @@ -10629,7 +10651,7 @@
> {
> /* Find the best access method that would not use join buffering */
> best_access_path(join, rs, reopt_remaining_tables, i,
> - test(i < no_jbuf_before), rec_count,
> + TRUE, rec_count,
> &pos, &loose_scan_pos);
> }
> else
>
> === modified file 'sql/sql_select.h'
> --- a/sql/sql_select.h 2010-10-30 22:14:36 +0000
> +++ b/sql/sql_select.h 2010-11-03 19:26:18 +0000
> @@ -306,6 +306,8 @@
> */
> uint sj_strategy;
>
> + struct st_join_table *first_sjm_sibling;
> +
> void cleanup();
> inline bool is_using_loose_index_scan()
> {
> @@ -1035,6 +1037,8 @@
> buff= 0;
> }
>
> + JOIN_TAB *get_next_table(JOIN_TAB *tab);
> +
> friend class JOIN_CACHE_HASHED;
> friend class JOIN_CACHE_BNL;
> friend class JOIN_CACHE_BKA;
>
> _______________________________________________
> commits mailing list
> commits(a)mariadb.org
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
--
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
0

Re: [Maria-developers] [Commits] Rev 2953: Mess in types fixed. in file:///home/bell/maria/bzr/work-maria-5.1-itemtype-bugs2/
by Michael Widenius 03 Nov '10
by Michael Widenius 03 Nov '10
03 Nov '10
>>>>> "sanja" == sanja <sanja(a)askmonty.org> writes:
sanja> At file:///home/bell/maria/bzr/work-maria-5.1-itemtype-bugs2/
sanja> ------------------------------------------------------------
sanja> revno: 2953
sanja> revision-id: sanja(a)askmonty.org-20101019101449-g36e3lwnqy7qbmos
sanja> parent: igor(a)askmonty.org-20101014214738-zvj7tbol145ohz2z
sanja> committer: sanja(a)askmonty.org
sanja> branch nick: work-maria-5.1-itemtype-bugs2
sanja> timestamp: Tue 2010-10-19 13:14:49 +0300
sanja> message:
sanja> Mess in types fixed.
> === modified file 'sql/item.h'
> --- a/sql/item.h 2010-09-21 04:22:00 +0000
> +++ b/sql/item.h 2010-10-19 10:14:49 +0000
> @@ -488,8 +488,7 @@ public:
> FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
> SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
> PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
> - XPATH_NODESET, XPATH_NODESET_CMP,
> - VIEW_FIXER_ITEM};
> + XPATH_NODESET, XPATH_NODESET_CMP};
>
> enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
>
> @@ -2908,7 +2907,8 @@ public:
> {
> return Item_field::save_in_field(field_arg, no_conversions);
> }
> - /*
> + enum Type type() const { return INSERT_VALUE_ITEM; }
> + /*
> We use RAND_TABLE_BIT to prevent Item_insert_value from
> being treated as a constant and precalculated before execution
> */
ok.
(I assume this is only for Item_insert_value::eq()).
Regards,
Monty
1
0

03 Nov '10
Hello Igor,
Please find attached the combined patch that addresses all of the review
feedback provided so far.
The tree is in launchpad and buildbot also:
https://code.launchpad.net/~maria-captains/maria/5.3-dsmrr-cpk
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
3

[Maria-developers] review: [Commits] Rev 2819: Fixed LP BUG#615378 Incorrect processing of NULL result in Item_cache fixed. in file:///home/bell/maria/bzr/work-maria-5.3-lb615378/
by Michael Widenius 02 Nov '10
by Michael Widenius 02 Nov '10
02 Nov '10
>>>>> "sanja" == sanja <sanja(a)askmonty.org> writes:
sanja> At file:///home/bell/maria/bzr/work-maria-5.3-lb615378/
sanja> ------------------------------------------------------------
sanja> revno: 2819
sanja> revision-id: sanja(a)askmonty.org-20101004100050-q1e95qec7288qkdo
sanja> parent: sanja(a)askmonty.org-20100914134341-voquimk50t20zuiy
sanja> committer: sanja(a)askmonty.org
sanja> branch nick: work-maria-5.3-lb615378
sanja> timestamp: Mon 2010-10-04 13:00:50 +0300
sanja> message:
sanja> Fixed LP BUG#615378 Incorrect processing of NULL result in Item_cache fixed.
<cut>
> === modified file 'sql/item.cc'
> --- a/sql/item.cc 2010-09-06 12:34:24 +0000
> +++ b/sql/item.cc 2010-10-04 10:00:50 +0000
> @@ -7750,8 +7750,11 @@ void Item_cache_int::store_longlong(Item
> String *Item_cache_int::val_str(String *str)
> {
> DBUG_ASSERT(fixed == 1);
> - if (!value_cached && !cache_value())
> + if ((!value_cached && !cache_value()) || null_value)
> + {
> + null_value= TRUE;
> return NULL;
> + }
> str->set(value, default_charset());
> return str;
> }
<cut> (All other fixes are the same).
Ok to push.
Just a note about the item_cache code.
If you would inherit Item_cache from Item_func_numhybrid, you
could get away with having just 4 val methods, not 16 as you have now.
For example:
class Item_cache_int : public Item_func_numhybrid
{
longlong int_op()
{
if ((!value_cached && !cache_value()) || null_value)
return 0;
return value;
}
longlong val_int() { return int_op(); } /* Optimize default case */
}
And that's about it. (Except that item_cache would need to provide
dummy functions that just aborts for all xxx_op() functions).
As a separate note, you can remove the following code from class
Item_cache as 'Item_basic_constant' already provides it:
table_map used_table_map;
...
void set_used_tables(table_map map) { used_table_map= map; }
...
table_map used_tables() const { return used_table_map; }
Regards,
Monty
1
0
Hi Philip,
On Tue, Oct 26, 2010 at 03:34:41PM +0300, Philip Stoev wrote:
>> - Our chances of making Random Query Generator a little bit friendlier for
>> bug analyzers/fixers.
>
> Hi,
>
> Can you list specific issues that you are having or specific bug numbers
> that were not filed properly?
I can't say that any bugs were filed improperly. All ones I've dealt with so
far were 'proper', i.e. contained sufficient amount of info for me to
reproduce and work on the bug. However, it seems there are some possible
improvements that could be made (and it makes sense to do them because
currently bugfixing is the bottleneck, not testing)
> I already have a list of things from Igor, so if you give me your list, I
> will try to dedicate specific time to make things more user-friendly.
Here it goes:
- Backtick quotes are redundant and must be gone. I've never seen a single
RQG-reported bug where the quotes were really necessary. Yet, they are there
and make the queries longer than necessary. We have to manually delete them.
- Redundant spaces are also annoying, a typical excerpt looks like (all spaces
kept):
table1 . `col_varchar_key` )
which, again, also forces developer to delete all of the spaces manually.
- It would be nice if tables were called t0,t1,t2,... as mysql-test-run
guidelines specify
- It would be nice if testcase simplification removed irrelevant columns from
the tables. If it is not possible to remove them (I guess the reason is that
the table size changes and the optimizer choses different QEP), then they
should be replaced with one CHAR(N) column.
- I understand the following might be difficult to achieve: it would be
extremely nice if the SELECT statement that caused the crash is was
pretty-printed (i.e. with identation that would make the structure of
FROM/WHERE clauses apparent).
If this is too difficult, no need to spend time on this.
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
1
Hi Timour,
When one compiles 5.3, it produces the following warnings which I believe fall
into your turf. Could you please fix them:
item_subselect.cc: In member function ‘bool subselect_rowid_merge_engine::init(MY_BITMAP*, MY_BITMAP*)’:
item_subselect.cc:4826: warning: ignoring return value of ‘int handler::ha_rnd_init(bool)’, declared with attribute warn_unused_result
item_subselect.cc: In member function ‘virtual bool subselect_rowid_merge_engine::partial_match()’:
item_subselect.cc:5007: warning: ignoring return value of ‘int handler::ha_rnd_init(bool)’, declared with attribute warn_unused_result
item_subselect.cc: In member function ‘virtual bool subselect_table_scan_engine::partial_match()’:
item_subselect.cc:5174: warning: ignoring return value of ‘int handler::ha_rnd_init(bool)’, declared with attribute warn_unused_result
sql_class.cc: In member function ‘virtual bool select_materialize_with_stats::create_result_table(THD*, List<Item>*, bool, ulonglong, const char*, bool)’:
sql_class.cc:3020: warning: the address of ‘int stat(const char*, stat*)’ will always evaluate as ‘true’
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
3
2

[Maria-developers] MWL#132: TC plugin, patch for (possible) code review
by Kristian Nielsen 01 Nov '10
by Kristian Nielsen 01 Nov '10
01 Nov '10
Hi Serg,
And here is the patch for MWL#132, TC plugin.
The patch is fairly short, as most of the real code changes are included in
MWL#116. This patch is mainly about introducing a new plugin interface for
transaction coordinators, and making the three existing TCs in log.cc into
built-in plugins.
My main motivation for this work was Galera, but when I discussed with them at
the Istanbul meeting, I learned that they are not so interested in internal
2-phase commit (instead they download a complete database snapshot at node
recovery after a node crash).
So now I do not have an example of an external TC plugin implementation. My
idea is to implement the MWL#120: stacked event generators. I could then use
this to implement a simple TC example that does (very) basic synchroneous
replication (eg. maybe insert-only with little error handling or
something). This could be a nice example of how to use the facilities that TC
plugins provide for controlling the commit process etc.
So I would like your opinion as to whether this should be pushed to 5.3 now or
wait for MWL#120 (assuming you think it can be made suitable for pushing at
all, of course :-).
- Kristian.
1
0
Hi,
Just noticed that gcc has a warning option -Wframe-larger-than=LEN
that makes gcc to warn about functions with stack frames larger
than LEN.
Considering a recent issue when we had a 130K structure on the stack
(which did overflow the stack in some cases), it may be a good idea to
enable this warning with a reasonably conservative threshold, say, 16K
or 32K.
Regards,
Sergei
2
1

[Maria-developers] WL#165 New (by Knielsen): Extend group commit to also handle non-transactional events
by worklog-noreply@askmonty.org 01 Nov '10
by worklog-noreply@askmonty.org 01 Nov '10
01 Nov '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Extend group commit to also handle non-transactional events
CREATION DATE..: Mon, 01 Nov 2010, 12:09
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-RawIdeaBin
TASK ID........: 165 (http://askmonty.org/worklog/?tid=165)
VERSION........: Server-9.x
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
The MWL#116 implements group commit for the binary log.
The work in MWL#116 only facilitates group commit for transactional commit
events. Non-transactional events like DDL or updates to MyISAM tables are not
improved. This is mainly an issue when running with sync_binlog=1
This worklog is for extending the optimisation to also do group commit for
these non-transactional event writes.
The basic way to implement this is described in the low-level design of
MWL#116, section 2.3.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

Re: [Maria-developers] [Commits] Rev 2951: WL#12 - MariaDB User Feedback (a.k.a. Phone Home) plugin
by Sergei Golubchik 31 Oct '10
by Sergei Golubchik 31 Oct '10
31 Oct '10
Hi, Michael!
On Oct 27, Michael Widenius wrote:
> >>>>> "Sergei" == Sergei Golubchik <serg(a)askmonty.org> writes:
>
> >> +++ b/plugin/feedback/sender_thread.cc 2010-09-30 14:24:31 +0000
> > ...
> >> + if (thd) // for nicer SHOW PROCESSLIST
> >> + thd->set_query(const_cast<char*>(url->url()), url->url_length());
> >>
> >> Wouldn't it be better if url->url() would return const char * ?
>
> > It does return const char*, but thd->set_query() wants char* (for no
> > good reason), so I need to cast const away.
>
> Should we change set_query() to take const char * ?
I can do that, yes, but this plugin will need a cast anyway to work with
MySQL sources.
> >> +Url* http_create(const char *url, size_t url_length)
> >> +{
> >> + const char *s;
> >> + LEX_STRING full_url= {const_cast<char*>(url), url_length};
> >> + LEX_STRING host, port, path;
> >>
> >> Would it not be better to introduce LEX_CONS_STRING and use these to
> >> avoid const away casts?
>
> > Perhaps, if I'd have more casts because of that. But just because of one
> > or two - I'd rather keep the code uniform instead and use LEX_STRING
> > everywhere.
>
> I tink there is many cases in the code where we have to cast const
> away just becasue we don't have LEX_CONST_STRING. Don't you think it's
> time to introduce it ?
Not in the plugin.
Btw, MariaDB already has LEX_CUSTRING (const unsigned) variant.
Regards,
Sergei
2
1

Re: [Maria-developers] [Commits] Rev 2840: Fixed LP bug #668290. in file:///home/igor/maria/maria-5.3-mwl128-bug668290/
by Sergey Petrunya 30 Oct '10
by Sergey Petrunya 30 Oct '10
30 Oct '10
Hello Igor,
Plese find the comments below.
On Sat, Oct 30, 2010 at 12:56:10PM -0700, Igor Babaev wrote:
> At file:///home/igor/maria/maria-5.3-mwl128-bug668290/
>
> ------------------------------------------------------------
> revno: 2840
> revision-id: igor(a)askmonty.org-20101030195609-h53be2cdzjlz38bz
> parent: igor(a)askmonty.org-20101030130745-563ypxtkcwv4vbfg
> committer: Igor Babaev <igor(a)askmonty.org>
> branch nick: maria-5.3-mwl128-bug668290
> timestamp: Sat 2010-10-30 12:56:09 -0700
> message:
> Fixed LP bug #668290.
> Prohibited to use hash join algorithm BNLH if join attributes
> need non-binary collations. It has to be done because BNLH does
> not support join for such attributes yet.
> Later this limitations will be lifted.
>
> Changed default collations for the schemes of some test cases
> to preserve the old execution plans.
...
> === modified file 'sql/field.h'
> --- a/sql/field.h 2010-09-23 22:00:32 +0000
> +++ b/sql/field.h 2010-10-30 19:56:09 +0000
> @@ -585,6 +585,12 @@
> }
> /* Hash value */
> virtual void hash(ulong *nr, ulong *nr2);
> +
> + virtual bool hash_join_is_possible(bool globally_allowed)
> + {
> + return globally_allowed;
> + }
Is there any partiular reason why have this globally_allowed parameter?
In my understanding, a field either allows hash or not, and that is
regardless of whether it was "globally allowed", so the check of whether
hash join is globally allowed should be done outside of the function.
Also, it would be nice to have here a comment specifying the meaning of this
function. (I know all this is supposed to be temporary, but expirience shows
that often supposedly temporary things stay for a long time, that's why it's
nice to put a comment).
> +
> friend bool reopen_table(THD *,struct st_table *,bool);
> friend int cre_myisam(char * name, register TABLE *form, uint options,
> ulonglong auto_increment_value);
> @@ -760,6 +766,12 @@
> my_decimal *val_decimal(my_decimal *);
> virtual bool str_needs_quotes() { return TRUE; }
> uint is_equal(Create_field *new_field);
> +
> + bool hash_join_is_possible(bool globally_allowed)
> + {
> + /* TODO: support hash joins for non-binary collations */
> + return globally_allowed && (flags & BINARY_FLAG);
> + }
> };
>
>
> @@ -1904,6 +1916,7 @@
> uint size_of() const { return sizeof(*this); }
> int reset(void) { return !maybe_null() || Field_blob::reset(); }
> geometry_type get_geometry_type() { return geom_type; };
> + bool hash_join_is_possible(bool globally_allowed) { return FALSE; }
> };
> #endif /*HAVE_SPATIAL*/
>
>
> === modified file 'sql/sql_select.cc'
> --- a/sql/sql_select.cc 2010-10-30 13:07:45 +0000
> +++ b/sql/sql_select.cc 2010-10-30 19:56:09 +0000
> @@ -3547,7 +3547,7 @@
> /*
> Additional optimization: if we're processing
> "t.key BETWEEN c1 AND c1" then proceed as if we were processing
> - "t.key = c1".
> + "t.key = c1".sis
> TODO: This is a very limited fix. A more generic fix is possible.
Is the above a meaningful change?
> There are 2 options:
> A) Make equality propagation code be able to handle BETWEEN
> @@ -5946,6 +5946,44 @@
> }
>
>
> +/**
> + @brief
> + Check whether hash join algorithm can be used to join this table
> +
> + @param is_allowed usage of hash join is allowed
> +
> + @details
> + This function finds out whether the ref items that have been chosen
> + by the planner to access this table can be used for hash join algorithms.
> + The answer depends on a certain property of the the fields of the
> + joined tables on which the hash join key is built. If hash join is
> + allowed for all these fields the answer is positive unless hash join
> + algorithms are not allowed for the query at all.
> +
> + @note
> + The function is supposed to be called now only after the function
> + get_best_combination has been called.
> +
> + @retval TRUE it's possible to use hash join to join this table
> + @retval FALSE otherwise
> +*/
> +
> +bool JOIN_TAB::hash_join_is_possible(bool is_allowed)
> +{
> + if (!is_allowed)
> + return FALSE;
Same as with globally_allowed. I think the parameter is redundant and rather
confusing.
> + if (type != JT_REF && type != JT_EQ_REF)
> + return FALSE;
> + KEY *keyinfo= &table->key_info[ref.key];
> + for (uint i= 0; i < ref.key_parts; i++)
> + {
> + if (!(keyinfo->key_part[i].field->hash_join_is_possible(TRUE)))
> + return FALSE;
> + }
> + return TRUE;
> +}
> +
> +
> static uint
> cache_record_length(JOIN *join,uint idx)
> {
> @@ -7649,8 +7687,10 @@
> &bufsz, &flags, &cost);
>
> if ((cache_level <=4 && !no_hashed_cache) || no_bka_cache ||
> - (flags & HA_MRR_NO_ASSOCIATION) && cache_level <=6)
> + ((flags & HA_MRR_NO_ASSOCIATION) && cache_level <=6))
> {
> + if (!tab->hash_join_is_possible(TRUE))
> + goto no_join_cache;
> if (cache_level == 3)
> prev_cache= 0;
> if ((tab->cache= new JOIN_CACHE_BNLH(join, tab, prev_cache)) &&
>
> === modified file 'sql/sql_select.h'
> --- a/sql/sql_select.h 2010-10-30 13:07:45 +0000
> +++ b/sql/sql_select.h 2010-10-30 19:56:09 +0000
> @@ -391,6 +391,7 @@
> return max_used_fieldlength;
> }
> double get_partial_join_cardinality() { return partial_join_cardinality; }
> + bool hash_join_is_possible(bool is_allowed);
> } JOIN_TAB;
>
>
>
B8R
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
0

[Maria-developers] support-files/my-xxx.cnf templates cause warning when used
by Oli Sennhauser 30 Oct '10
by Oli Sennhauser 30 Oct '10
30 Oct '10
Hello all,
The support-files/my-xxx.cnf templates have an old value in it and thus
give a nasty Warning message when used:
101029 21:06:04 [Warning] '--skip-locking' is deprecated and will be
removed in a future release. Please use '--skip-external-locking' instead.
So I have changed it. The patch should work for MariaDB 5.1 AND 5.2...
Can somebody please put it into the trees when acceptable?
Thanks,
Oli
--- support-files/my-huge.cnf.sh.orig 2010-10-29 21:09:24.000000000 +0200
+++ support-files/my-huge.cnf.sh 2010-10-29 21:10:47.000000000 +0200
@@ -25,7 +25,7 @@ socket = @MYSQL_UNIX_ADDR@
[mysqld]
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@
-skip-locking
+skip-external-locking
key_buffer_size = 384M
max_allowed_packet = 1M
table_open_cache = 512
--- support-files/my-large.cnf.sh.orig 2010-10-29 21:09:22.000000000 +0200
+++ support-files/my-large.cnf.sh 2010-10-29 21:10:33.000000000 +0200
@@ -25,7 +25,7 @@ socket = @MYSQL_UNIX_ADDR@
[mysqld]
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@
-skip-locking
+skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache = 256
--- support-files/my-medium.cnf.sh.orig 2010-10-29 21:09:20.000000000 +0200
+++ support-files/my-medium.cnf.sh 2010-10-29 21:10:05.000000000 +0200
@@ -26,7 +26,7 @@ socket = @MYSQL_UNIX_ADDR@
[mysqld]
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@
-skip-locking
+skip-external-locking
key_buffer_size = 16M
max_allowed_packet = 1M
table_open_cache = 64
--- support-files/my-small.cnf.sh.orig 2010-10-29 21:09:17.000000000 +0200
+++ support-files/my-small.cnf.sh 2010-10-29 21:09:45.000000000 +0200
@@ -26,7 +26,7 @@ socket = @MYSQL_UNIX_ADDR@
[mysqld]
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@
-skip-locking
+skip-external-locking
key_buffer_size = 16K
max_allowed_packet = 1M
table_open_cache = 4
--
FromDual - Vendor independent and neutral MySQL consulting.
Oli Sennhauser
Rebenweg 6
CH - 8610 Uster / Switzerland
Phone +41 44 940 24 82
Mobile +41 79 830 09 33
e-Mail oli.sennhauser(a)fromdual.com
Website http://www.fromdual.com/
Skype fromdual
Jabber fromdual(a)swissjabber.ch
Yahoo IM fromdual
Xing https://www.xing.com/profile/Oliver_Sennhauser
LinkedIn http://ch.linkedin.com/in/shinguz
Twitter http://twitter.com/shinguz
2
1

29 Oct '10
Hi Timour,
Answers to irc questions:
<timour> spetrunia, I found a problem in get_partial_join_cost(), could you please look at this:
<timour> for (uint i= join->const_tables; i < n_tables + join->const_tables ; i++)
<timour> spetrunia, why "i < n_tables + join->const_tables" ? isn't the number
of tables always the same?
<timour> That is, shouldn't we just skip the constant tables assuming they are
in the beginning of join->best_positions ?
Yes we should skip the constant tables, and they are at the beginning of
best_positions.
The number of tables passed as n_tables varies across different invocations of
get_partial_join_cost():
uint n_tables= my_count_bits(sj_nest->sj_inner_tables & ~join->const_table_map);
SJ_MATERIALIZATION_INFO* sjm;
if (!(sjm= new SJ_MATERIALIZATION_INFO) ||
!(sjm->positions= (POSITION*)join->thd->alloc(sizeof(POSITION)*
n_tables)))
DBUG_RETURN(TRUE); /* purecov: inspected */
sjm->tables= n_tables;
sjm->is_used= FALSE;
double subjoin_out_rows, subjoin_read_time;
get_partial_join_cost(join, n_tables,
&subjoin_read_time, &subjoin_out_rows);
Here one can see that n_tables is "number of non-constant tables within an
SJ-Materialization nest". Different nests will contain different numbers of
tables.
<timour> spetrunia, I changed the loop upper boundary to n_tables, then I get
few improved EXPLAINS, and got a crash, then I had to leave.
I think the change is wrong: if you stop at n_tables, that means that
partial_join_cost() has done optimization for the first
(n_tables - join->const_tables)
non-constant tables, which is not right. If you need further help, could you
give a concrete example that causes the problem?
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
0

[Maria-developers] WL#164 New (by Knielsen): Extend crash recovery to recover non-prepared transactions from binlog
by worklog-noreply@askmonty.org 27 Oct '10
by worklog-noreply@askmonty.org 27 Oct '10
27 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Extend crash recovery to recover non-prepared transactions from binlog
CREATION DATE..: Wed, 27 Oct 2010, 13:08
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 164 (http://askmonty.org/worklog/?tid=164)
VERSION........: Server-9.x
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
Currently, when an xa-capable storage engine commits a transaction that is
also written to the binary log, we do three fsync() calls, which is
expensive. One in prepare(), one for binlog write(), and one for commit().
These multiple fsync()'s are needed to ensure that crash recovery can recover
into a consistent state after a crash that happens during commit, so that any
transaction that becomes committed in the storage engine is also committed in
the binlog, and vice versa. This is essential for replication, as otherwise a
crashed master may not be able to recover into a usable state without a full
restore from backup.
The fsync()s are also needed to ensure durability, that is, any transaction
that is reported to the client as having committed, will also remain committed
after a crash.
This worklog is about optimising this so that we can reliably recover into a
consistent state (and preserve durability) with just a single fsync(), the one
for the binary log. In effect, this will allow to run with
--innodb-flush-log-at-trx-commit=2, or even =0, and still preserve both
durability of InnoDB commits and consistent crash recovery.
The idea is that along with every commit, InnoDB will store also an
identification of the transactions associated with that commit (in a
transaction-safe way, eg. using the InnoDB transaction log). In fact, InnoDB
already does this, since it records the binlog position of the last commit
done at any point in time.
Then during crash recovery, we can do as follows:
- First let each engine recover into an engine-consistent state. This may
be missing some transactions due to --innodb-flush-log-at-trx-commit=0.
- Ask each transactional engine for the ID of the last transaction committed.
- By virtue of MWL#116, we know that the order of commits in the storage
engine and in the binlog is the same. Thus, the transactions missing in the
engine is exactly those that are written in the binlog after the last
transaction committed in the engine.
- Recover the missing transactions in the engine by re-playing the binary log
from that point to the end (similar to how it would be applied on a slave.)
There are some restrictions/requirements:
- This will only work for engines that implement the MWL#116 commit_ordered()
handlerton method.
- After a crash, different engines (eg. PBXT vs. InnoDB) may be in different
states (different last transaction committed). It will be necessary to
recover each engine separately, at least up to a point where they are
consistent. This should be simple enough for transactions that only involve
tables for one engine. For cross-engine transactions, it can probably work
for row-based replication, simply by ignoring updates to tables in other
engines when applying the binlog events. But for statement-based
replication it will not work easily [*].
This way, it should be possible to greatly reduce the fsync() overhead when
using the binlog with a transactional engine.
[*] One could imagine trying to make it work even for statement-based binlog
events, at least for MVCC engines. When running the updates against one
engine, any select against the other engine could try to use an MVCC snapshow
corresponding to the transaction that corresponds to the appropriate
transaction back in time. But I think this is not realistic / worth it to
implement.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#163 New (by Knielsen): Implement release of row locks in InnoDB during prepare() phase
by worklog-noreply@askmonty.org 27 Oct '10
by worklog-noreply@askmonty.org 27 Oct '10
27 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Implement release of row locks in InnoDB during prepare() phase
CREATION DATE..: Wed, 27 Oct 2010, 12:38
SUPERVISOR.....: Sergei
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 163 (http://askmonty.org/worklog/?tid=163)
VERSION........: Server-9.x
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
This is a feature implemented in the Facebook patch[1]. It is intended to
improve performance in the presence of hotspot rows in high-concurrency
applications.
When binlog is enabled and a transaction is committed in InnoDB, there are
three fsync()s done (in prepare(), in binlog write, and in commit()), and
InnoDB row locks are only released after the second of them (or third, not
100% sure).
If many transactions are updating the same rows, this becomes a point of
contention, and may also limit the opportunity for the group commit
optimisation. The idea of the Facebook patch is to release the locks earlier,
in the prepare phase, to reduce the impact of this problem.
In order to preserve correctness (eg. of statement-based replication), it is
necessary that locks are released for transactions in the order that these
transactions commit. So when we release locks during transaction A's prepare
phase, we must ensure that A will commit earlier than any other transaction
that might be waiting for those locks.
There are two kinds of row locks in InnoDB. There are explicit locks, like the
gap locks in higher isolation levels and SELECT FOR UPDATE locks. And implicit
locks, which is when one transaction modifies a row; such modification will
update the row with the id of the modifying transaction, and another
transaction will treat such row as effectively locked if the modifying
transaction has not yet committed (this is how I understand it, though I'm not
100% sure of the details).
The question is to what extend it is safe/correct to release the locks early.
I believe the release of implicit locks is safe during prepare(). Such locks
serve only the purpose of making sure that other transactions will not commit
before us, eg. because they will touch rows that were invisible to our
transaction, and thus must also be invisible on a replication slave (gap
locks). If we already decided to commit ourself before such other transaction,
then that purpose is already fulfilled.
I talked to Mark Callaghan about the Facebook patch for this problem. He told
me that they now also release explicit locks early, and furthermore also make
changes done by the releasing transaction visible to other transactions. In
effect, the transaction is committed (to memory) during prepare. This has some
more severe implications:
- Since the changes done by transaction A are visible to transaction B, A can
no longer safely rollback. In the facebook patch, they kill the server if A
needs to roll back after prepare().
- In the case of a server crash, the transaction A may not be recovered (if
it was never written to the binary log), yet may have been seen by the
application. This means that a change was observed in the database that in
effect never took place.
Still, such even more aggressive early release might be useful to enable with
an option that is off by default.
I think some more work is needed to fully access the implications and safety
of such early lock release.
References:
[1] https://launchpad.net/mysqlatfacebook
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

Re: [Maria-developers] [Commits] Rev 2958: better fix for MySQL bugs in http://bazaar.launchpad.net/~maria-captains/maria/5.1/
by Sergei Golubchik 26 Oct '10
by Sergei Golubchik 26 Oct '10
26 Oct '10
Hi, Zardosht!
First: please send questions like this to the list, not only to me.
I wanted to discuss this with Sergey Petrunia and had to paste this on
irc.
Anyway,
On Oct 22, Zardosht Kasheff wrote:
> Hello Sergei,
>
> One of the problems we at Tokutek have run into with the optimizer
> many times is that the optimizer does not always use these functions
> to estimate costs. I think I have found a couple of places in the
> code, and want to verify that my understanding is correct.
>
> In best_access_path in sql_select.cc, I see the following code in two places:
> if (table->covering_keys.is_set(key))
> {
> /* we can use only index tree */
> uint keys_per_block= table->file->stats.block_size/2/
> (keyinfo->key_length+table->file->ref_length)+1;
> tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
> }
> else
> tmp= record_count*min(tmp,s->worst_seeks);
>
> is there a reason why tmp cannot be evaluated using the functions
> keyread_time and read_time? If so, is there any reason why MariaDB or
> MySQL cannot use the functions in this place?
I cannot fix it in 5.1, unfortunately.
The code should probably be rewritten as
if (table->covering_keys.is_set(key))
{
tmp= record_count*table->file->keyread_time(key, 1, tmp);
}
else
tmp= record_count*table->file->read_time(key, 1, min(tmp,s->worst_seeks));
but tmp is double, while the third argument of keyread_time and
read_time is ha_rows - an integer. That is, this change causes a small
precision loss, and it is enough for optimizer to start generating
different query plans. I've got quite a few test failures because
EXPLAIN output changed. We cannot do changes that affect query plans in
a stable version. One thing I've learned in MySQL - no matter how
correct and good such a change is, there will always be queries that it
will affect adversely. And it won't matter that the new plan is
correct, and the old plan was completely illogical and caused by a bug
in the optimizer or something - they'll say that their queries were
faster that way.
I'll see about doing this change it 5.2 though.
Regards,
Sergei
2
2

[Maria-developers] Please review: Rev 2959: MWL#152: Show database name in error messages in file:///home/psergey/dev2/5.1/]
by Sergey Petrunya 26 Oct '10
by Sergey Petrunya 26 Oct '10
26 Oct '10
Hello,
Could somebody please review the below? It's a very simple patch.
I also need comments about which version this should go into. I've made the
patch againist 5.1 just in case, but my opinion is that this should go into
5.2 (under rationale that 5.1 is stable and one can live without this patch).
----- Forwarded message from Sergey Petrunya <psergey(a)askmonty.org> -----
From: Sergey Petrunya <psergey(a)askmonty.org>
To: commits(a)mariadb.org
X-Mailer: mail (GNU Mailutils 1.2)
Date: Sat, 23 Oct 2010 19:38:04 +0300 (EEST)
Subject: [Commits] Rev 2959: MWL#152: Show database name in error messages
in file:///home/psergey/dev2/5.1/
At file:///home/psergey/dev2/5.1/
------------------------------------------------------------
revno: 2959
revision-id: psergey(a)askmonty.org-20101023163755-j8ghe2s4udpoc97g
parent: sergii(a)pisem.net-20101020105843-7ybuqyc9n5328tie
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: 5.1
timestamp: Sat 2010-10-23 20:37:55 +0400
message:
MWL#152: Show database name in error messages
- Add database name to ER_TABLEACCESS_DENIED_ERROR and ER_COLUMNACCESS_DENIED_ERROR message strings.
- Amend the code to provide db name
- Update test results
=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result 2010-09-03 16:20:30 +0000
+++ b/mysql-test/r/grant.result 2010-10-23 16:37:55 +0000
@@ -405,15 +405,15 @@
GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE
'mysqltest_3'@'localhost' NULL USAGE NO
update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1;
-ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for column 'q' in table 't1'
+ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for column 'q' in table 'mysqltest_1'.'t1'
update mysqltest_1.t2, mysqltest_2.t2 set d=20 where d=1;
-ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'd' in table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'd' in table 'mysqltest_2'.'t2'
update mysqltest_1.t1, mysqltest_2.t2 set d=20 where d=1;
-ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 'mysqltest_1'.'t1'
update mysqltest_2.t1, mysqltest_1.t2 set c=20 where b=1;
-ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 't1'
+ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 'mysqltest_2'.'t1'
update mysqltest_2.t1, mysqltest_2.t2 set d=10 where s=2;
-ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 's' in table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 's' in table 'mysqltest_2'.'t1'
update mysqltest_1.t1, mysqltest_2.t2 set a=10,d=10;
update mysqltest_1.t1, mysqltest_2.t1 set a=20 where c=20;
select t1.*,t2.* from mysqltest_1.t1,mysqltest_1.t2;
@@ -433,14 +433,14 @@
use mysqltest_1;
update mysqltest_2.t1, mysqltest_2.t2 set c=500,d=600;
update mysqltest_1.t1, mysqltest_1.t2 set a=100,b=200;
-ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 't1'
+ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 'mysqltest_1'.'t1'
use mysqltest_2;
update mysqltest_1.t1, mysqltest_1.t2 set a=100,b=200;
-ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 't1'
+ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 'mysqltest_1'.'t1'
update mysqltest_2.t1, mysqltest_1.t2 set c=100,b=200;
-ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 't2'
+ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 'mysqltest_1'.'t2'
update mysqltest_1.t1, mysqltest_2.t2 set a=100,d=200;
-ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 't1'
+ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for table 'mysqltest_1'.'t1'
select t1.*,t2.* from mysqltest_1.t1,mysqltest_1.t2;
a q b r
10 2 1 2
@@ -489,7 +489,7 @@
create table mysqltest.t1 (a int,b int,c int);
grant all on mysqltest.t1 to mysqltest_1@localhost;
alter table t1 rename t2;
-ERROR 42000: INSERT,CREATE command denied to user 'mysqltest_1'@'localhost' for table 't2'
+ERROR 42000: INSERT,CREATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'t2'
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
delete from mysql.user where user=_binary'mysqltest_1';
drop database mysqltest;
@@ -667,7 +667,7 @@
grant alter on db27515.t1 to user27515@localhost;
grant insert, create on db27515.t2 to user27515@localhost;
rename table t1 to t2;
-ERROR 42000: DROP command denied to user 'user27515'@'localhost' for table 't1'
+ERROR 42000: DROP command denied to user 'user27515'@'localhost' for table 'db27515'.'t1'
revoke all privileges, grant option from user27515@localhost;
drop user user27515@localhost;
drop database db27515;
@@ -900,13 +900,13 @@
GRANT SELECT ON mysqltest2.* TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1';
GRANT SHOW VIEW,SELECT ON mysqltest2.v_yy TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1';
SHOW CREATE VIEW mysqltest2.v_nn;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v_nn'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest2'.'v_nn'
SHOW CREATE TABLE mysqltest2.v_nn;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v_nn'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest2'.'v_nn'
SHOW CREATE VIEW mysqltest2.v_yn;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v_yn'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest2'.'v_yn'
SHOW CREATE TABLE mysqltest2.v_yn;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v_yn'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest2'.'v_yn'
SHOW CREATE TABLE mysqltest2.v_ny;
View Create View character_set_client collation_connection
v_ny CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_ny` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` latin1 latin1_swedish_ci
@@ -914,13 +914,13 @@
View Create View character_set_client collation_connection
v_ny CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_ny` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` latin1 latin1_swedish_ci
SHOW CREATE TABLE mysqltest3.t_nn;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't_nn'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest3'.'t_nn'
SHOW CREATE VIEW mysqltest3.t_nn;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't_nn'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest3'.'t_nn'
SHOW CREATE VIEW mysqltest3.v_nn;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v_nn'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest3'.'v_nn'
SHOW CREATE TABLE mysqltest3.v_nn;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v_nn'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest3'.'v_nn'
SHOW CREATE TABLE mysqltest2.t_nn;
Table Create Table
t_nn CREATE TABLE `t_nn` (
@@ -980,23 +980,23 @@
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT SELECT ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost'
RENAME TABLE t1 TO t2;
-ERROR 42000: DROP,ALTER command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: DROP,ALTER command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest1'.'t1'
ALTER TABLE t1 RENAME TO t2;
-ERROR 42000: DROP,ALTER command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: DROP,ALTER command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest1'.'t1'
GRANT DROP ON mysqltest1.t1 TO mysqltest_1@localhost;
RENAME TABLE t1 TO t2;
-ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest1'.'t1'
ALTER TABLE t1 RENAME TO t2;
-ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest1'.'t1'
GRANT ALTER ON mysqltest1.t1 TO mysqltest_1@localhost;
SHOW GRANTS;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT SELECT, DROP, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost'
RENAME TABLE t1 TO t2;
-ERROR 42000: INSERT,CREATE command denied to user 'mysqltest_1'@'localhost' for table 't2'
+ERROR 42000: INSERT,CREATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest1'.'t2'
ALTER TABLE t1 RENAME TO t2;
-ERROR 42000: INSERT,CREATE command denied to user 'mysqltest_1'@'localhost' for table 't2'
+ERROR 42000: INSERT,CREATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest1'.'t2'
GRANT INSERT, CREATE ON mysqltest1.t1 TO mysqltest_1@localhost;
SHOW GRANTS;
Grants for mysqltest_1@localhost
@@ -1021,9 +1021,9 @@
GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost'
GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
RENAME TABLE t1 TO t2;
-ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest1'.'t1'
ALTER TABLE t1 RENAME TO t2;
-ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest1'.'t1'
DROP USER mysqltest_1@localhost;
DROP DATABASE mysqltest1;
USE test;
@@ -1060,7 +1060,7 @@
GRANT DELETE ON t1 TO bug23556@localhost;
USE bug23556;
TRUNCATE t1;
-ERROR 42000: DROP command denied to user 'bug23556'@'localhost' for table 't1'
+ERROR 42000: DROP command denied to user 'bug23556'@'localhost' for table 'bug23556'.'t1'
USE bug23556;
REVOKE DELETE ON t1 FROM bug23556@localhost;
GRANT DROP ON t1 TO bug23556@localhost;
@@ -1131,16 +1131,16 @@
---> connection: bug27337_con1
CREATE TABLE t1(c INT);
-ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest2'.'t1'
CALL mysqltest1.p1();
1
1
CREATE TABLE t1(c INT);
-ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest2'.'t1'
---> connection: bug27337_con2
CREATE TABLE t1(c INT);
-ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest2'.'t1'
SHOW TABLES;
Tables_in_mysqltest2
@@ -1187,9 +1187,9 @@
---> connection: bug27337_con2
SHOW COLUMNS FROM mysqltest2.t2;
-ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 'mysqltest2'.'t2'
EXECUTE stmt2;
-ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 'mysqltest2'.'t2'
---> connection: default
DROP DATABASE mysqltest1;
@@ -1267,7 +1267,7 @@
grant create on mysqltest.* to mysqltest@localhost;
create table t1 (i INT);
insert into t1 values (1);
-ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 't1'
+ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 'mysqltest'.'t1'
create table t2 (i INT);
create table t4 (i INT);
grant select, insert on mysqltest.t2 to mysqltest@localhost;
@@ -1277,20 +1277,20 @@
flush privileges;
insert into t2 values (1);
create table if not exists t1 select * from t2;
-ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 't1'
+ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 'mysqltest'.'t1'
create table if not exists t3 select * from t2;
-ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 't3'
+ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 'mysqltest'.'t3'
create table if not exists t4 select * from t2;
Warnings:
Note 1050 Table 't4' already exists
create table if not exists t5 select * from t2;
create table t6 select * from t2;
create table t7 select * from t2;
-ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 't7'
+ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 'mysqltest'.'t7'
create table t4 select * from t2;
ERROR 42S01: Table 't4' already exists
create table t1 select * from t2;
-ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 't1'
+ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 'mysqltest'.'t1'
drop table t1,t2,t4,t5,t6;
revoke create on mysqltest.* from mysqltest@localhost;
revoke select, insert on mysqltest.t2 from mysqltest@localhost;
@@ -1422,7 +1422,7 @@
SELECT * FROM `../db2/tb2`;
ERROR 42S02: Table 'db1.../db2/tb2' doesn't exist
SELECT * FROM `../db2`.tb2;
-ERROR 42000: SELECT command denied to user 'testbug'@'localhost' for table 'tb2'
+ERROR 42000: SELECT command denied to user 'testbug'@'localhost' for table '../db2'.'tb2'
SELECT * FROM `#mysql50#/../db2/tb2`;
ERROR 42000: Incorrect table name '#mysql50#/../db2/tb2'
DROP USER 'testbug'@localhost;
=== modified file 'mysql-test/r/grant2.result'
--- a/mysql-test/r/grant2.result 2009-10-30 05:06:10 +0000
+++ b/mysql-test/r/grant2.result 2010-10-23 16:37:55 +0000
@@ -83,9 +83,9 @@
GRANT SELECT, INSERT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
insert into t1 values (1, 'I can''t change it!');
update t1 set data='I can change it!' where id = 1;
-ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'t1'
insert into t1 values (1, 'XXX') on duplicate key update data= 'I can change it!';
-ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'t1'
select * from t1;
id data
1 I can't change it!
@@ -96,9 +96,9 @@
create table t1 (a int, b int);
grant select (a) on t1 to mysqltest_1@localhost with grant option;
grant select (a,b) on t1 to mysqltest_2@localhost;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 'mysqltest'.'t1'
grant select on t1 to mysqltest_3@localhost;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'t1'
drop table t1;
delete from mysql.user where user like 'mysqltest\_%';
delete from mysql.db where user like 'mysqltest\_%';
@@ -269,7 +269,7 @@
create user mysqltest_2@localhost;
grant create user on *.* to mysqltest_2@localhost;
select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password;
-ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 'user'
+ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 'mysql'.'user'
create user mysqltest_A@'%';
rename user mysqltest_A@'%' to mysqltest_B@'%';
drop user mysqltest_B@'%';
@@ -281,7 +281,7 @@
GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost'
GRANT INSERT, UPDATE, DELETE ON `mysql`.* TO 'mysqltest_3'@'localhost'
select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password;
-ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 'user'
+ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 'mysql'.'user'
insert into mysql.user set host='%', user='mysqltest_B';
Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
@@ -391,9 +391,9 @@
use mysqltest_2;
create table t1 (i int);
show create table mysqltest_2.t1;
-ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'mysqltest_2'.'t1'
create table t1 like mysqltest_2.t1;
-ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'mysqltest_2'.'t1'
grant select on mysqltest_2.t1 to mysqltest_u1@localhost;
show create table mysqltest_2.t1;
Table Create Table
@@ -433,11 +433,11 @@
GRANT SELECT (b) ON t2 TO mysqltest1@localhost;
USE db1;
SELECT c FROM t2;
-ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 'db1'.'t2'
SELECT * FROM t2;
-ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for table 'db1'.'t2'
SELECT * FROM t1 JOIN t2 USING (b);
-ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 'db1'.'t2'
USE test;
DROP TABLE db1.t1, db1.t2;
DROP USER mysqltest1@localhost;
=== modified file 'mysql-test/r/grant3.result'
--- a/mysql-test/r/grant3.result 2009-10-20 06:17:57 +0000
+++ b/mysql-test/r/grant3.result 2010-10-23 16:37:55 +0000
@@ -189,7 +189,7 @@
# non privileged column. We shouldn't be able to
# access this column.
SELECT b FROM temp.t1;
-ERROR 42000: SELECT command denied to user 'user2'@'localhost' for column 'b' in table 't1'
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for column 'b' in table 'temp'.'t1'
DROP USER 'user2'@'%';
DROP DATABASE temp;
End of 5.0 tests
=== modified file 'mysql-test/r/grant_cache_no_prot.result'
--- a/mysql-test/r/grant_cache_no_prot.result 2009-05-20 13:27:44 +0000
+++ b/mysql-test/r/grant_cache_no_prot.result 2010-10-23 16:37:55 +0000
@@ -140,7 +140,7 @@
1 1 1 test.t1
2 2 2 test.t1
select * from t2;
-ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 'mysqltest'.'t2'
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 6
@@ -155,17 +155,17 @@
user3
user3
select * from t1;
-ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 'mysqltest'.'t1'
select a from t1;
a
1
2
select c from t1;
-ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 'mysqltest'.'t1'
select * from t2;
-ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 'mysqltest'.'t2'
select mysqltest.t1.c from test.t1,mysqltest.t1;
-ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 'mysqltest'.'t1'
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 6
=== modified file 'mysql-test/r/information_schema_db.result'
--- a/mysql-test/r/information_schema_db.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/r/information_schema_db.result 2010-10-23 16:37:55 +0000
@@ -144,17 +144,17 @@
use testdb_1;
revoke show view on v6 from testdb_2@localhost;
show fields from testdb_1.v5;
-ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v5'
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'testdb_1'.'v5'
show create view testdb_1.v5;
-ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v5'
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'testdb_1'.'v5'
show fields from testdb_1.v6;
-ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v6'
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'testdb_1'.'v6'
show create view testdb_1.v6;
-ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v6'
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'testdb_1'.'v6'
show fields from testdb_1.v7;
-ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'testdb_1'.'v7'
show create view testdb_1.v7;
-ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'testdb_1'.'v7'
show create view v4;
View Create View character_set_client collation_connection
v4 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `v3`.`f1` AS `f1`,`v3`.`f2` AS `f2` from `testdb_1`.`v3` latin1 latin1_swedish_ci
@@ -172,7 +172,7 @@
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `v1`.`f1` AS `f1` from `testdb_1`.`v1` latin1 latin1_swedish_ci
show create view testdb_1.v1;
-ERROR 42000: SHOW VIEW command denied to user 'testdb_2'@'localhost' for table 'v1'
+ERROR 42000: SHOW VIEW command denied to user 'testdb_2'@'localhost' for table 'testdb_1'.'v1'
select table_name from information_schema.columns a
where a.table_name = 'v2';
table_name
@@ -209,6 +209,6 @@
table_schema table_name view_definition
testdb_1 v1
show create view testdb_1.v1;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'testdb_1'.'v1'
drop user mysqltest_1@localhost;
drop database testdb_1;
=== modified file 'mysql-test/r/insert_notembedded.result'
--- a/mysql-test/r/insert_notembedded.result 2007-09-06 16:22:34 +0000
+++ b/mysql-test/r/insert_notembedded.result 2010-10-23 16:37:55 +0000
@@ -32,7 +32,7 @@
ON table_source.id = stations.icao
LEFT JOIN table_target AS old
USING (mexs_id);
-ERROR 42000: INSERT,DELETE command denied to user 'user20989'@'localhost' for table 'table_target'
+ERROR 42000: INSERT,DELETE command denied to user 'user20989'@'localhost' for table 'meow'.'table_target'
REPLACE INTO view_target2
SELECT stations.mexs_id AS mexs_id, datetime AS messzeit
FROM table_source
@@ -40,7 +40,7 @@
ON table_source.id = stations.icao
LEFT JOIN view_target2 AS old
USING (mexs_id);
-ERROR 42000: INSERT,DELETE command denied to user 'user20989'@'localhost' for table 'view_target2'
+ERROR 42000: INSERT,DELETE command denied to user 'user20989'@'localhost' for table 'meow'.'view_target2'
REPLACE INTO view_target3
SELECT stations.mexs_id AS mexs_id, datetime AS messzeit
FROM table_source
@@ -60,7 +60,7 @@
LEFT JOIN table_target AS old
USING (mexs_id);
REPLACE INTO table_target2 VALUES ('00X45Y78','2006-07-12 07:50:00');
-ERROR 42000: INSERT,DELETE command denied to user 'user20989'@'localhost' for table 'table_target2'
+ERROR 42000: INSERT,DELETE command denied to user 'user20989'@'localhost' for table 'meow'.'table_target2'
REPLACE INTO view_target2 VALUES ('12X45Y78','2006-07-12 07:50:00');
SELECT stations.mexs_id AS mexs_id, datetime AS messzeit
FROM table_source
=== modified file 'mysql-test/r/lowercase_fs_off.result'
--- a/mysql-test/r/lowercase_fs_off.result 2009-10-27 08:09:19 +0000
+++ b/mysql-test/r/lowercase_fs_off.result 2010-10-23 16:37:55 +0000
@@ -16,7 +16,7 @@
CREATE TABLE t1(f1 INT);
GRANT SELECT ON T1 to user_1@localhost;
select * from t1;
-ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 'd1'.'t1'
select * from T1;
f1
GRANT SELECT ON t1 to user_1@localhost;
=== modified file 'mysql-test/r/mysqlbinlog.result'
--- a/mysql-test/r/mysqlbinlog.result 2010-03-28 11:57:33 +0000
+++ b/mysql-test/r/mysqlbinlog.result 2010-10-23 16:37:55 +0000
@@ -432,7 +432,7 @@
mysqlbinlog var/log/master-bin.000017 > var/tmp/bug31611.sql
mysql mysqltest1 -uuntrusted < var/tmp/bug31611.sql
INSERT INTO t1 VALUES (1,USER());
-ERROR 42000: INSERT command denied to user 'untrusted'@'localhost' for table 't1'
+ERROR 42000: INSERT command denied to user 'untrusted'@'localhost' for table 'mysqltest1'.'t1'
SELECT * FROM t1;
a b
1 root@localhost
=== modified file 'mysql-test/r/openssl_1.result'
--- a/mysql-test/r/openssl_1.result 2010-06-13 22:13:32 +0000
+++ b/mysql-test/r/openssl_1.result 2010-10-23 16:37:55 +0000
@@ -16,31 +16,31 @@
f1
5
delete from t1;
-ERROR 42000: DELETE command denied to user 'ssl_user1'@'localhost' for table 't1'
-SHOW STATUS LIKE 'Ssl_cipher';
-Variable_name Value
-Ssl_cipher DHE-RSA-AES256-SHA
-select * from t1;
-f1
-5
-delete from t1;
-ERROR 42000: DELETE command denied to user 'ssl_user2'@'localhost' for table 't1'
-SHOW STATUS LIKE 'Ssl_cipher';
-Variable_name Value
-Ssl_cipher DHE-RSA-AES256-SHA
-select * from t1;
-f1
-5
-delete from t1;
-ERROR 42000: DELETE command denied to user 'ssl_user3'@'localhost' for table 't1'
-SHOW STATUS LIKE 'Ssl_cipher';
-Variable_name Value
-Ssl_cipher DHE-RSA-AES256-SHA
-select * from t1;
-f1
-5
-delete from t1;
-ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1'
+ERROR 42000: DELETE command denied to user 'ssl_user1'@'localhost' for table 'test'.'t1'
+SHOW STATUS LIKE 'Ssl_cipher';
+Variable_name Value
+Ssl_cipher DHE-RSA-AES256-SHA
+select * from t1;
+f1
+5
+delete from t1;
+ERROR 42000: DELETE command denied to user 'ssl_user2'@'localhost' for table 'test'.'t1'
+SHOW STATUS LIKE 'Ssl_cipher';
+Variable_name Value
+Ssl_cipher DHE-RSA-AES256-SHA
+select * from t1;
+f1
+5
+delete from t1;
+ERROR 42000: DELETE command denied to user 'ssl_user3'@'localhost' for table 'test'.'t1'
+SHOW STATUS LIKE 'Ssl_cipher';
+Variable_name Value
+Ssl_cipher DHE-RSA-AES256-SHA
+select * from t1;
+f1
+5
+delete from t1;
+ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 'test'.'t1'
drop user ssl_user1@localhost, ssl_user2@localhost,
ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost;
drop table t1;
=== modified file 'mysql-test/r/partition_grant.result'
--- a/mysql-test/r/partition_grant.result 2007-04-04 09:01:47 +0000
+++ b/mysql-test/r/partition_grant.result 2010-10-23 16:37:55 +0000
@@ -12,12 +12,12 @@
GRANT SELECT, ALTER ON `mysqltest_1`.* TO 'mysqltest_1'@'localhost'
alter table t1 add b int;
alter table t1 drop partition p2;
-ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest_1'.'t1'
grant drop on mysqltest_1.* to mysqltest_1@localhost;
alter table t1 drop partition p2;
revoke alter on mysqltest_1.* from mysqltest_1@localhost;
alter table t1 drop partition p3;
-ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest_1'.'t1'
revoke select,alter,drop on mysqltest_1.* from mysqltest_1@localhost;
drop table t1;
create table t1 (s1 int);
=== modified file 'mysql-test/r/plugin_not_embedded.result'
--- a/mysql-test/r/plugin_not_embedded.result 2010-03-13 21:32:42 +0000
+++ b/mysql-test/r/plugin_not_embedded.result 2010-10-23 16:37:55 +0000
@@ -4,7 +4,7 @@
GRANT INSERT ON mysql.plugin TO bug51770@localhost;
INSTALL PLUGIN example SONAME 'ha_example.so';
UNINSTALL PLUGIN example;
-ERROR 42000: DELETE command denied to user 'bug51770'@'localhost' for table 'plugin'
+ERROR 42000: DELETE command denied to user 'bug51770'@'localhost' for table 'mysql'.'plugin'
GRANT DELETE ON mysql.plugin TO bug51770@localhost;
UNINSTALL PLUGIN example;
DROP USER bug51770@localhost;
=== modified file 'mysql-test/r/ps_grant.result'
--- a/mysql-test/r/ps_grant.result 2009-10-27 10:09:36 +0000
+++ b/mysql-test/r/ps_grant.result 2010-10-23 16:37:55 +0000
@@ -26,7 +26,7 @@
my_col
1
select a as my_col from t1;
-ERROR 42000: SELECT command denied to user 'second_user'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'second_user'@'localhost' for table 'mysqltest'.'t1'
grant select on mysqltest.t1 to second_user@localhost
identified by 'looser' ;
show grants for second_user@localhost ;
@@ -66,7 +66,7 @@
GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
execute s_t1 ;
-ERROR 42000: SELECT command denied to user 'second_user'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'second_user'@'localhost' for table 'mysqltest'.'t1'
revoke all privileges, grant option from second_user@localhost ;
show grants for second_user@localhost ;
Grants for second_user@localhost
=== modified file 'mysql-test/r/show_check.result'
--- a/mysql-test/r/show_check.result 2010-09-03 16:20:30 +0000
+++ b/mysql-test/r/show_check.result 2010-10-23 16:37:55 +0000
@@ -524,19 +524,19 @@
Database Create Database
mysqltest CREATE DATABASE `mysqltest` /*!40100 DEFAULT CHARACTER SET latin1 */
drop table t1;
-ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'t1'
drop database mysqltest;
ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest'
select * from mysqltest.t1;
-ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 'mysqltest'.'t1'
show create database mysqltest;
ERROR 42000: Access denied for user 'mysqltest_2'@'localhost' to database 'mysqltest'
drop table mysqltest.t1;
-ERROR 42000: DROP command denied to user 'mysqltest_2'@'localhost' for table 't1'
+ERROR 42000: DROP command denied to user 'mysqltest_2'@'localhost' for table 'mysqltest'.'t1'
drop database mysqltest;
ERROR 42000: Access denied for user 'mysqltest_2'@'localhost' to database 'mysqltest'
select * from mysqltest.t1;
-ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 'mysqltest'.'t1'
show create database mysqltest;
Database Create Database
mysqltest CREATE DATABASE `mysqltest` /*!40100 DEFAULT CHARACTER SET latin1 */
=== modified file 'mysql-test/r/sp-security.result'
--- a/mysql-test/r/sp-security.result 2010-02-26 13:16:46 +0000
+++ b/mysql-test/r/sp-security.result 2010-10-23 16:37:55 +0000
@@ -40,7 +40,7 @@
db1_secret.db()
test
select * from db1_secret.t1;
-ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table 'db1_secret'.'t1'
create procedure db1_secret.dummy() begin end;
ERROR 42000: Access denied for user 'user1'@'localhost' to database 'db1_secret'
drop procedure db1_secret.dummy;
@@ -54,7 +54,7 @@
db1_secret.db()
test
select * from db1_secret.t1;
-ERROR 42000: SELECT command denied to user ''@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user ''@'localhost' for table 'db1_secret'.'t1'
create procedure db1_secret.dummy() begin end;
ERROR 42000: Access denied for user ''@'%' to database 'db1_secret'
drop procedure db1_secret.dummy;
@@ -89,13 +89,13 @@
db()
test
call db1_secret.stamp(5);
-ERROR 42000: INSERT command denied to user 'user1'@'localhost' for table 't1'
+ERROR 42000: INSERT command denied to user 'user1'@'localhost' for table 'db1_secret'.'t1'
select db1_secret.db();
-ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table 'db1_secret'.'t1'
call db1_secret.stamp(6);
-ERROR 42000: INSERT command denied to user ''@'localhost' for table 't1'
+ERROR 42000: INSERT command denied to user ''@'localhost' for table 'db1_secret'.'t1'
select db1_secret.db();
-ERROR 42000: SELECT command denied to user ''@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user ''@'localhost' for table 'db1_secret'.'t1'
drop database if exists db2;
create database db2;
use db2;
@@ -110,7 +110,7 @@
use db2;
create procedure p () insert into t2 values (1);
call p();
-ERROR 42000: INSERT command denied to user 'user1'@'localhost' for table 't2'
+ERROR 42000: INSERT command denied to user 'user1'@'localhost' for table 'db2'.'t2'
use db2;
call p();
ERROR 42000: execute command denied to user 'user2'@'localhost' for routine 'db2.p'
@@ -326,9 +326,9 @@
call db_bug14533.bug14533_2();
id
desc db_bug14533.t1;
-ERROR 42000: SELECT command denied to user 'user_bug14533'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'user_bug14533'@'localhost' for table 'db_bug14533'.'t1'
select * from db_bug14533.t1;
-ERROR 42000: SELECT command denied to user 'user_bug14533'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'user_bug14533'@'localhost' for table 'db_bug14533'.'t1'
drop user user_bug14533@localhost;
drop database db_bug14533;
@@ -483,24 +483,24 @@
END|
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT f_evil();
SELECT COUNT(*) FROM t1;
-ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'test'.'t1'
SELECT f_evil();
-ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'test'.'t1'
SELECT @a, @b;
@a @b
mysqltest_u1@localhost NULL
SELECT f_suid(f_evil());
-ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'test'.'t1'
SELECT @a, @b;
@a @b
mysqltest_u1@localhost NULL
CALL p_suid(f_evil());
-ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'test'.'t1'
SELECT @a, @b;
@a @b
mysqltest_u1@localhost NULL
SELECT * FROM v1;
-ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'v1'
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'test'.'v1'
SELECT @a, @b;
@a @b
mysqltest_u1@localhost NULL
=== modified file 'mysql-test/r/status.result'
--- a/mysql-test/r/status.result 2009-06-10 08:58:36 +0000
+++ b/mysql-test/r/status.result 2010-10-23 16:37:55 +0000
@@ -201,13 +201,13 @@
create function func37908() returns int sql security invoker
return (select * from db37908.t1 limit 1)|
select * from db37908.t1;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'db37908'.'t1'
show status where variable_name ='uptime' and 2 in (select * from db37908.t1);
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'db37908'.'t1'
show procedure status where name ='proc37908' and 1 in (select f1 from db37908.t1);
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'db37908'.'t1'
show function status where name ='func37908' and 1 in (select func37908());
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'db37908'.'t1'
drop database db37908;
drop procedure proc37908;
drop function func37908;
=== modified file 'mysql-test/r/timezone_grant.result'
--- a/mysql-test/r/timezone_grant.result 2006-04-25 14:20:49 +0000
+++ b/mysql-test/r/timezone_grant.result 2010-10-23 16:37:55 +0000
@@ -22,9 +22,9 @@
update t1, t2 set t1.b = convert_tz('2004-10-21 19:00:00', 'Europe/Moscow', 'UTC')
where t1.a = t2.c and t2.d = (select max(d) from t2);
select * from mysql.time_zone_name;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysql'.'time_zone_name'
select Name, convert_tz('2004-10-21 19:00:00', Name, 'UTC') from mysql.time_zone_name;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysql'.'time_zone_name'
delete from mysql.db where user like 'mysqltest\_%';
flush privileges;
grant all privileges on test.t1 to mysqltest_1@localhost;
@@ -46,9 +46,9 @@
update t1, t2 set t1.b = convert_tz('2004-11-30 12:00:00', 'Europe/Moscow', 'UTC')
where t1.a = t2.c and t2.d = (select max(d) from t2);
select * from mysql.time_zone_name;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysql'.'time_zone_name'
select Name, convert_tz('2004-11-30 12:00:00', Name, 'UTC') from mysql.time_zone_name;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysql'.'time_zone_name'
drop table t1, t2;
create table t1 (a int, b datetime);
create table t2 (a int, b varchar(40));
@@ -70,9 +70,9 @@
1 2001-01-01 03:00:00
2 2002-01-01 03:00:00
select * from v1, mysql.time_zone;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'mysql'.'time_zone'
drop view v1;
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1, mysql.time_zone;
-ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 'time_zone'
+ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 'mysql'.'time_zone'
drop table t1;
drop user mysqltest_1@localhost;
=== modified file 'mysql-test/r/trigger_notembedded.result'
--- a/mysql-test/r/trigger_notembedded.result 2010-01-12 08:19:48 +0000
+++ b/mysql-test/r/trigger_notembedded.result 2010-10-23 16:37:55 +0000
@@ -24,7 +24,7 @@
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
-ERROR 42000: TRIGGER command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
+ERROR 42000: TRIGGER command denied to user 'mysqltest_dfn'@'localhost' for table 'mysqltest_db1'.'t1'
---> connection: default
GRANT TRIGGER ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
@@ -39,11 +39,11 @@
---> connection: wl2818_definer_con
DROP TRIGGER trg1;
-ERROR 42000: TRIGGER command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
+ERROR 42000: TRIGGER command denied to user 'mysqltest_dfn'@'localhost' for table 'mysqltest_db1'.'t1'
---> connection: wl2818_definer_con
INSERT INTO t1 VALUES(0);
-ERROR 42000: TRIGGER command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
+ERROR 42000: TRIGGER command denied to user 'mysqltest_dfn'@'localhost' for table 'mysqltest_db1'.'t1'
---> connection: default
GRANT TRIGGER ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
@@ -99,7 +99,7 @@
---> connection: wl2818_invoker_con
use mysqltest_db1;
INSERT INTO t1 VALUES(3);
-ERROR 42000: INSERT command denied to user 'mysqltest_dfn'@'localhost' for table 't2'
+ERROR 42000: INSERT command denied to user 'mysqltest_dfn'@'localhost' for table 'mysqltest_db1'.'t2'
SELECT * FROM t1;
num_value
1
@@ -296,7 +296,7 @@
GRANT UPDATE(col) ON mysqltest_db1.t3 TO mysqltest_u1@localhost;
GRANT UPDATE(col) ON mysqltest_db1.t4 TO mysqltest_u1@localhost;
INSERT INTO t1 VALUES('line1');
-ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 'mysqltest_db1'.'t1'
SELECT * FROM t1;
col
line1
@@ -308,7 +308,7 @@
col
t2_trg_before_insert
INSERT INTO t3 VALUES('t3_line1');
-ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 't3'
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 'mysqltest_db1'.'t3'
SELECT * FROM t3;
col
t3_line1
@@ -339,7 +339,7 @@
@mysqltest_var
line3
INSERT INTO t2 VALUES('line4');
-ERROR 42000: UPDATE command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 't2'
+ERROR 42000: UPDATE command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 'mysqltest_db1'.'t2'
SELECT * FROM t2;
col
t2_trg_before_insert
@@ -352,7 +352,7 @@
@mysqltest_var
t3_line2
INSERT INTO t4 VALUES('t4_line2');
-ERROR 42000: UPDATE command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 't4'
+ERROR 42000: UPDATE command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 'mysqltest_db1'.'t4'
SELECT * FROM t4;
col
t4_trg_before_insert
@@ -383,9 +383,9 @@
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
CALL p2(NEW.i1);
INSERT INTO t1 VALUES (7);
-ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 'mysqltest_db1'.'t1'
INSERT INTO t2 VALUES (11);
-ERROR 42000: SELECT,UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
+ERROR 42000: SELECT,UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 'mysqltest_db1'.'t2'
DROP TRIGGER t2_bi;
DROP TRIGGER t1_bi;
GRANT SELECT ON mysqltest_db1.* TO mysqltest_dfn@localhost;
@@ -394,9 +394,9 @@
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
CALL p2(NEW.i1);
INSERT INTO t1 VALUES (13);
-ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 'mysqltest_db1'.'t1'
INSERT INTO t2 VALUES (17);
-ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
+ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 'mysqltest_db1'.'t2'
REVOKE SELECT ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
DROP TRIGGER t2_bi;
DROP TRIGGER t1_bi;
@@ -407,7 +407,7 @@
CALL p2(NEW.i1);
INSERT INTO t1 VALUES (19);
INSERT INTO t2 VALUES (23);
-ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 'mysqltest_db1'.'t2'
REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
DROP TRIGGER t2_bi;
DROP TRIGGER t1_bi;
@@ -431,11 +431,11 @@
DROP PROCEDURE p1;
CREATE PROCEDURE p1(IN i INT) DETERMINISTIC NO SQL SET @v1 = i + 43;
INSERT INTO t1 VALUES (47);
-ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 'mysqltest_db1'.'t1'
DROP PROCEDURE p1;
CREATE PROCEDURE p1(INOUT i INT) DETERMINISTIC NO SQL SET i = i + 51;
INSERT INTO t1 VALUES (53);
-ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 'mysqltest_db1'.'t1'
DROP PROCEDURE p1;
REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
DROP TRIGGER t1_bi;
=== modified file 'mysql-test/r/view_grant.result'
--- a/mysql-test/r/view_grant.result 2010-02-12 02:54:14 +0000
+++ b/mysql-test/r/view_grant.result 2010-10-23 16:37:55 +0000
@@ -19,13 +19,13 @@
ERROR 42000: Access denied; you need the SUPER privilege for this operation
create view v1 as select * from mysqltest.t1;
alter view v1 as select * from mysqltest.t1;
-ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'test'.'v1'
create or replace view v1 as select * from mysqltest.t1;
-ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'test'.'v1'
create view mysqltest.v2 as select * from mysqltest.t1;
-ERROR 42000: CREATE VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2'
+ERROR 42000: CREATE VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v2'
create view v2 as select * from mysqltest.t2;
-ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 't2'
+ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'t2'
show create view v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1` latin1 latin1_swedish_ci
@@ -44,7 +44,7 @@
select c from mysqltest.v1;
c
select d from mysqltest.v1;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 'v1'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 'mysqltest'.'v1'
revoke all privileges on mysqltest.v1 from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
drop database mysqltest;
@@ -55,7 +55,7 @@
select c from mysqltest.v1;
c
select d from mysqltest.v1;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 'v1'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 'mysqltest'.'v1'
revoke all privileges on mysqltest.v1 from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
drop database mysqltest;
@@ -89,39 +89,39 @@
explain select c from mysqltest.v1;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v1;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v1'
explain select c from mysqltest.v2;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v2;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v2'
explain select c from mysqltest.v3;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v3;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v3'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v3'
explain select c from mysqltest.v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v4;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v4'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v4'
grant select on mysqltest.t1 to mysqltest_1@localhost;
explain select c from mysqltest.v1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
show create view mysqltest.v1;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v1'
explain select c from mysqltest.v2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
show create view mysqltest.v2;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v2'
explain select c from mysqltest.v3;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v3;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v3'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v3'
explain select c from mysqltest.v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v4;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v4'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v4'
grant show view on mysqltest.* to mysqltest_1@localhost;
explain select c from mysqltest.v1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -197,13 +197,13 @@
62 5
71 10
update t2,v2 set v2.c=v2.a+v2.c where t2.x=v2.c;
-ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for column 'c' in table 'v2'
+ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for column 'c' in table 'mysqltest'.'v2'
update v2 set c=a+c;
-ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for column 'c' in table 'v2'
+ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for column 'c' in table 'mysqltest'.'v2'
update t2,v3 set v3.a=v3.a+v3.c where t2.x=v3.c;
-ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 'v3'
+ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v3'
update v3 set a=a+c;
-ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 'v3'
+ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v3'
use test;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
drop database mysqltest;
@@ -229,9 +229,9 @@
a b
5 10
delete v2 from t2,v2 where t2.x=v2.c;
-ERROR 42000: DELETE command denied to user 'mysqltest_1'@'localhost' for table 'v2'
+ERROR 42000: DELETE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v2'
delete from v2 where c < 4;
-ERROR 42000: DELETE command denied to user 'mysqltest_1'@'localhost' for table 'v2'
+ERROR 42000: DELETE command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v2'
use test;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
drop database mysqltest;
@@ -259,9 +259,9 @@
5 6
3 4
insert into v2 values (5,6);
-ERROR 42000: INSERT command denied to user 'mysqltest_1'@'localhost' for table 'v2'
+ERROR 42000: INSERT command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v2'
insert into v2 select x,y from t2;
-ERROR 42000: INSERT command denied to user 'mysqltest_1'@'localhost' for table 'v2'
+ERROR 42000: INSERT command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v2'
use test;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
drop database mysqltest;
@@ -274,9 +274,9 @@
create view v1 as select * from mysqltest.t1;
create view v2 as select b from mysqltest.t2;
create view mysqltest.v1 as select * from mysqltest.t1;
-ERROR 42000: CREATE VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+ERROR 42000: CREATE VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v1'
create view v3 as select a from mysqltest.t2;
-ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for column 'a' in table 't2'
+ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for column 'a' in table 'mysqltest'.'t2'
create table mysqltest.v3 (b int);
grant create view on mysqltest.v3 to mysqltest_1@localhost;
drop table mysqltest.v3;
@@ -285,10 +285,10 @@
drop view mysqltest.v3;
create view mysqltest.v3 as select b from mysqltest.t2;
create view v4 as select b+1 from mysqltest.t2;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 'mysqltest'.'t2'
grant create view,update,select on test.* to mysqltest_1@localhost;
create view v4 as select b+1 from mysqltest.t2;
-ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 'mysqltest'.'t2'
grant update,select(b) on mysqltest.t2 to mysqltest_1@localhost;
create view v4 as select b+1 from mysqltest.t2;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
@@ -507,7 +507,7 @@
use mysqltest;
LOCK TABLES v1 READ;
SHOW CREATE TABLE v1;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'mysqltest'.'v1'
UNLOCK TABLES;
use test;
use test;
@@ -560,31 +560,31 @@
SELECT 1 FROM mysqltest1.v_t1;
ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
SELECT * FROM mysqltest1.t1;
-ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 'mysqltest1'.'t1'
SELECT * FROM mysqltest1.v_ts;
x
1
2
SELECT * FROM mysqltest1.v_ts, mysqltest1.t1 WHERE mysqltest1.t1.x = mysqltest1.v_ts.x;
-ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 'mysqltest1'.'t1'
SELECT * FROM mysqltest1.v_ti;
-ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 'v_ti'
+ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 'mysqltest1'.'v_ti'
INSERT INTO mysqltest1.v_ts VALUES (100);
-ERROR 42000: INSERT command denied to user 'readonly'@'localhost' for table 'v_ts'
+ERROR 42000: INSERT command denied to user 'readonly'@'localhost' for table 'mysqltest1'.'v_ts'
INSERT INTO mysqltest1.v_ti VALUES (100);
UPDATE mysqltest1.v_ts SET x= 200 WHERE x = 100;
-ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'v_ts'
+ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'mysqltest1'.'v_ts'
UPDATE mysqltest1.v_ts SET x= 200;
-ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'v_ts'
+ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'mysqltest1'.'v_ts'
UPDATE mysqltest1.v_tu SET x= 200 WHERE x = 100;
UPDATE mysqltest1.v_tus SET x= 200 WHERE x = 100;
UPDATE mysqltest1.v_tu SET x= 200;
DELETE FROM mysqltest1.v_ts WHERE x= 200;
-ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'v_ts'
+ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'mysqltest1'.'v_ts'
DELETE FROM mysqltest1.v_ts;
-ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'v_ts'
+ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'mysqltest1'.'v_ts'
DELETE FROM mysqltest1.v_td WHERE x= 200;
-ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for column 'x' in table 'v_td'
+ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for column 'x' in table 'mysqltest1'.'v_td'
DELETE FROM mysqltest1.v_tds WHERE x= 200;
DELETE FROM mysqltest1.v_td;
DROP VIEW mysqltest1.v_tds;
@@ -719,7 +719,7 @@
DROP USER def_17254@localhost;
for a user
SELECT * FROM v1;
-ERROR 42000: SELECT command denied to user 'inv_17254'@'localhost' for table 'v1'
+ERROR 42000: SELECT command denied to user 'inv_17254'@'localhost' for table 'db17254'.'v1'
for a superuser
SELECT * FROM v1;
ERROR HY000: The user specified as a definer ('def_17254'@'localhost') does not exist
@@ -756,11 +756,11 @@
REVOKE SELECT ON t2 FROM mysqltest_u2@localhost;
UPDATE t2 SET s = 'private' WHERE s = 'public';
SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2;
-ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 'mysqltest_db1'.'t2'
EXECUTE stmt1;
-ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 'mysqltest_db1'.'t2'
EXECUTE stmt2;
-ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2'
+ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 'mysqltest_db1'.'t2'
REVOKE ALL ON mysqltest_db1.* FROM mysqltest_u1@localhost;
REVOKE ALL ON mysqltest_db2.* FROM mysqltest_u2@localhost;
DROP DATABASE mysqltest_db1;
@@ -875,22 +875,22 @@
UPDATE v3 SET c3 = 332 WHERE c3 = 32;
DELETE FROM v4 WHERE c4 = 43;
CREATE VIEW v12 AS SELECT c1, c2 FROM mysqltest1.t1, mysqltest1.t2;
-ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'v12'
+ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'mysqltest2'.'v12'
CREATE VIEW v13 AS SELECT c1, c3 FROM mysqltest1.t1, mysqltest1.t3;
CREATE VIEW v14 AS SELECT c1, c4 FROM mysqltest1.t1, mysqltest1.t4;
CREATE VIEW v21 AS SELECT c2, c1 FROM mysqltest1.t2, mysqltest1.t1;
-ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c1' in table 'v21'
+ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c1' in table 'mysqltest2'.'v21'
CREATE VIEW v23 AS SELECT c2, c3 FROM mysqltest1.t2, mysqltest1.t3;
-ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c3' in table 'v23'
+ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c3' in table 'mysqltest2'.'v23'
CREATE VIEW v24 AS SELECT c2, c4 FROM mysqltest1.t2, mysqltest1.t4;
-ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c4' in table 'v24'
+ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c4' in table 'mysqltest2'.'v24'
CREATE VIEW v31 AS SELECT c3, c1 FROM mysqltest1.t3, mysqltest1.t1;
CREATE VIEW v32 AS SELECT c3, c2 FROM mysqltest1.t3, mysqltest1.t2;
-ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'v32'
+ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'mysqltest2'.'v32'
CREATE VIEW v34 AS SELECT c3, c4 FROM mysqltest1.t3, mysqltest1.t4;
CREATE VIEW v41 AS SELECT c4, c1 FROM mysqltest1.t4, mysqltest1.t1;
CREATE VIEW v42 AS SELECT c4, c2 FROM mysqltest1.t4, mysqltest1.t2;
-ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'v42'
+ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'mysqltest2'.'v42'
CREATE VIEW v43 AS SELECT c4, c3 FROM mysqltest1.t4, mysqltest1.t3;
---> connection: default
@@ -931,15 +931,15 @@
SELECT f1 FROM t1;
f1
SELECT f2 FROM t1;
-ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 't1'
+ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 'db1'.'t1'
SELECT * FROM t1;
-ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
+ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 'db1'.'t1'
SELECT f1 FROM v1;
f1
SELECT f2 FROM v1;
-ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 'v1'
+ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 'db1'.'v1'
SELECT * FROM v1;
-ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 'v1'
+ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 'db1'.'v1'
USE test;
REVOKE SELECT (f1) ON db1.t1 FROM foo;
REVOKE SELECT (f1) ON db1.v1 FROM foo;
@@ -995,9 +995,9 @@
This would lead to failed assertion.
CREATE VIEW v1 AS SELECT a, b FROM t1, t2;
SELECT * FROM v1;
-ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v1'
+ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'mysqltest1'.'v1'
SELECT b FROM v1;
-ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v1'
+ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'mysqltest1'.'v1'
DROP TABLE t1, t2;
DROP VIEW v1;
DROP DATABASE mysqltest1;
@@ -1013,9 +1013,9 @@
GRANT SELECT( a ) ON v1 TO mysqluser1@localhost;
GRANT UPDATE( b ) ON t2 TO mysqluser1@localhost;
SELECT * FROM mysqltest1.v1;
-ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v1'
+ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'mysqltest1'.'v1'
CREATE VIEW v1 AS SELECT * FROM mysqltest1.t2;
-ERROR 42000: ANY command denied to user 'mysqluser1'@'localhost' for table 't2'
+ERROR 42000: ANY command denied to user 'mysqluser1'@'localhost' for table 'mysqltest1'.'t2'
DROP TABLE t1, t2;
DROP VIEW v1;
DROP DATABASE mysqltest1;
@@ -1032,9 +1032,9 @@
PREPARE stmt_v2 FROM "SELECT * FROM mysqltest1.v2";
REVOKE SELECT ON mysqltest1.* FROM mysqluser1@localhost;
EXECUTE stmt_v1;
-ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v1'
+ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'mysqltest1'.'v1'
EXECUTE stmt_v2;
-ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v2'
+ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'mysqltest1'.'v2'
PREPARE stmt FROM "SELECT a FROM v3";
EXECUTE stmt;
a
@@ -1183,11 +1183,11 @@
REVOKE SHOW VIEW ON v_f1 FROM mysqluser1@localhost;
REVOKE SHOW VIEW ON v_v1 FROM mysqluser1@localhost;
SHOW CREATE VIEW mysqltest1.v_t1;
-ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_t1'
+ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'mysqltest1'.'v_t1'
SHOW CREATE VIEW mysqltest1.v_f1;
-ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_f1'
+ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'mysqltest1'.'v_f1'
SHOW CREATE VIEW mysqltest1.v_v1;
-ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_v1'
+ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'mysqltest1'.'v_v1'
SHOW CREATE VIEW v_mysqluser1_t1;
View Create View character_set_client collation_connection
v_mysqluser1_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
=== modified file 'mysql-test/suite/rpl/r/rpl_sp.result'
--- a/mysql-test/suite/rpl/r/rpl_sp.result 2010-05-24 13:54:08 +0000
+++ b/mysql-test/suite/rpl/r/rpl_sp.result 2010-10-23 16:37:55 +0000
@@ -281,7 +281,7 @@
20
100
create trigger trg before insert on t1 for each row set new.a= 10;
-ERROR 42000: TRIGGER command denied to user 'zedjzlcsjhd'@'localhost' for table 't1'
+ERROR 42000: TRIGGER command denied to user 'zedjzlcsjhd'@'localhost' for table 'mysqltest1'.'t1'
delete from t1;
create trigger trg before insert on t1 for each row set new.a= 10;
insert into t1 values (1);
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2010-09-03 16:20:30 +0000
+++ b/sql/item.cc 2010-10-23 16:37:55 +0000
@@ -4428,7 +4428,7 @@
{
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
"ANY", thd->security_ctx->priv_user,
- thd->security_ctx->host_or_ip, field_name, tab);
+ thd->security_ctx->host_or_ip, field_name, db, tab);
goto error;
}
}
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2010-04-28 12:52:24 +0000
+++ b/sql/share/errmsg.txt 2010-10-23 16:37:55 +0000
@@ -3288,45 +3288,45 @@
swe "Det finns inget privilegium definierat f�r anv�ndare '%-.48s' p� '%-.64s'"
ukr "����������� �� ��������� ��� ����������� '%-.48s' � ����� '%-.64s'"
ER_TABLEACCESS_DENIED_ERROR 42000
- cze "%-.16s p-B��kaz nep��stupn� pro u�ivatele: '%-.48s'@'%-.64s' pro tabulku '%-.192s'"
- dan "%-.16s-kommandoen er ikke tilladt for brugeren '%-.48s'@'%-.64s' for tabellen '%-.192s'"
- nla "%-.16s commando geweigerd voor gebruiker: '%-.48s'@'%-.64s' voor tabel '%-.192s'"
- eng "%-.16s command denied to user '%-.48s'@'%-.64s' for table '%-.192s'"
- jps "�R�}���h %-.16s �� ���[�U�[ '%-.48s'@'%-.64s' ,�e�[�u�� '%-.192s' �ɑ��ċ�����Ă��܂���",
- est "%-.16s k�sk ei ole lubatud kasutajale '%-.48s'@'%-.64s' tabelis '%-.192s'"
- fre "La commande '%-.16s' est interdite � l'utilisateur: '%-.48s'@'@%-.64s' sur la table '%-.192s'"
- ger "%-.16s Befehl nicht erlaubt f�r Benutzer '%-.48s'@'%-.64s' auf Tabelle '%-.192s'"
- hun "%-.16s parancs a '%-.48s'@'%-.64s' felhasznalo szamara nem engedelyezett a '%-.192s' tablaban"
- ita "Comando %-.16s negato per l'utente: '%-.48s'@'%-.64s' sulla tabella '%-.192s'"
- jpn "���ޥ�� %-.16s �� �桼���� '%-.48s'@'%-.64s' ,�ơ��֥� '%-.192s' ���Ф��Ƶ��Ĥ���Ƥ��ޤ���"
- kor "'%-.16s' ������ ���� ����ڿ��� �źεǾ����ϴ�. : '%-.48s'@'%-.64s' for ���̺� '%-.192s'"
- por "Comando '%-.16s' negado para o usu�rio '%-.48s'@'%-.64s' na tabela '%-.192s'"
- rum "Comanda %-.16s interzisa utilizatorului: '%-.48s'@'%-.64s' pentru tabela '%-.192s'"
- rus "������� %-.16s ��������� ������������ '%-.48s'@'%-.64s' ��� ������� '%-.192s'"
- serbian "%-.16s komanda zabranjena za korisnika '%-.48s'@'%-.64s' za tabelu '%-.192s'"
- spa "%-.16s comando negado para usuario: '%-.48s'@'%-.64s' para tabla '%-.192s'"
- swe "%-.16s ej till�tet f�r '%-.48s'@'%-.64s' f�r tabell '%-.192s'"
- ukr "%-.16s ������� ���������� �����������: '%-.48s'@'%-.64s' � �����æ '%-.192s'"
+ cze "%-.16s p-B��kaz nep��stupn� pro u�ivatele: '%-.48s'@'%-.64s' pro tabulku '%-.192s'.'%-.192s'"
+ dan "%-.16s-kommandoen er ikke tilladt for brugeren '%-.48s'@'%-.64s' for tabellen '%-.192s'.'%-.192s'"
+ nla "%-.16s commando geweigerd voor gebruiker: '%-.48s'@'%-.64s' voor tabel '%-.192s'.'%-.192s'"
+ eng "%-.16s command denied to user '%-.48s'@'%-.64s' for table '%-.192s'.'%-.192s'"
+ jps "�R�}���h %-.16s �� ���[�U�[ '%-.48s'@'%-.64s' ,�e�[�u�� '%-.192s'.'%-.192s' �ɑ��ċ�����Ă��܂���",
+ est "%-.16s k�sk ei ole lubatud kasutajale '%-.48s'@'%-.64s' tabelis '%-.192s'.'%-.192s'"
+ fre "La commande '%-.16s' est interdite � l'utilisateur: '%-.48s'@'@%-.64s' sur la table '%-.192s'.'%-.192s'"
+ ger "%-.16s Befehl nicht erlaubt f�r Benutzer '%-.48s'@'%-.64s' auf Tabelle '%-.192s'.'%-.192s'"
+ hun "%-.16s parancs a '%-.48s'@'%-.64s' felhasznalo szamara nem engedelyezett a '%-.192s'.'%-.192s' tablaban"
+ ita "Comando %-.16s negato per l'utente: '%-.48s'@'%-.64s' sulla tabella '%-.192s'.'%-.192s'"
+ jpn "���ޥ�� %-.16s �� �桼���� '%-.48s'@'%-.64s' ,�ơ��֥� '%-.192s'.'%-.192s' ���Ф��Ƶ��Ĥ���Ƥ��ޤ���"
+ kor "'%-.16s' ������ ���� ����ڿ��� �źεǾ����ϴ�. : '%-.48s'@'%-.64s' for ���̺� '%-.192s'.'%-.192s'"
+ por "Comando '%-.16s' negado para o usu�rio '%-.48s'@'%-.64s' na tabela '%-.192s'.'%-.192s'"
+ rum "Comanda %-.16s interzisa utilizatorului: '%-.48s'@'%-.64s' pentru tabela '%-.192s'.'%-.192s'"
+ rus "������� %-.16s ��������� ������������ '%-.48s'@'%-.64s' ��� ������� '%-.192s'.'%-.192s'"
+ serbian "%-.16s komanda zabranjena za korisnika '%-.48s'@'%-.64s' za tabelu '%-.192s'.'%-.192s'"
+ spa "%-.16s comando negado para usuario: '%-.48s'@'%-.64s' para tabla '%-.192s'.'%-.192s'"
+ swe "%-.16s ej till�tet f�r '%-.48s'@'%-.64s' f�r tabell '%-.192s'.'%-.192s'"
+ ukr "%-.16s ������� ���������� �����������: '%-.48s'@'%-.64s' � �����æ '%-.192s'.'%-.192s'"
ER_COLUMNACCESS_DENIED_ERROR 42000
- cze "%-.16s p-B��kaz nep��stupn� pro u�ivatele: '%-.48s'@'%-.64s' pro sloupec '%-.192s' v tabulce '%-.192s'"
- dan "%-.16s-kommandoen er ikke tilladt for brugeren '%-.48s'@'%-.64s' for kolonne '%-.192s' in tabellen '%-.192s'"
- nla "%-.16s commando geweigerd voor gebruiker: '%-.48s'@'%-.64s' voor kolom '%-.192s' in tabel '%-.192s'"
- eng "%-.16s command denied to user '%-.48s'@'%-.64s' for column '%-.192s' in table '%-.192s'"
- jps "�R�}���h %-.16s �� ���[�U�[ '%-.48s'@'%-.64s'\n �J���� '%-.192s' �e�[�u�� '%-.192s' �ɑ��ċ�����Ă��܂���",
- est "%-.16s k�sk ei ole lubatud kasutajale '%-.48s'@'%-.64s' tulbale '%-.192s' tabelis '%-.192s'"
- fre "La commande '%-.16s' est interdite � l'utilisateur: '%-.48s'@'@%-.64s' sur la colonne '%-.192s' de la table '%-.192s'"
- ger "%-.16s Befehl nicht erlaubt f�r Benutzer '%-.48s'@'%-.64s' und Feld '%-.192s' in Tabelle '%-.192s'"
- hun "%-.16s parancs a '%-.48s'@'%-.64s' felhasznalo szamara nem engedelyezett a '%-.192s' mezo eseten a '%-.192s' tablaban"
- ita "Comando %-.16s negato per l'utente: '%-.48s'@'%-.64s' sulla colonna '%-.192s' della tabella '%-.192s'"
- jpn "���ޥ�� %-.16s �� �桼���� '%-.48s'@'%-.64s'\n ����� '%-.192s' �ơ��֥� '%-.192s' ���Ф��Ƶ��Ĥ���Ƥ��ޤ���"
- kor "'%-.16s' ������ ���� ����ڿ��� �źεǾ����ϴ�. : '%-.48s'@'%-.64s' for Į�� '%-.192s' in ���̺� '%-.192s'"
- por "Comando '%-.16s' negado para o usu�rio '%-.48s'@'%-.64s' na coluna '%-.192s', na tabela '%-.192s'"
- rum "Comanda %-.16s interzisa utilizatorului: '%-.48s'@'%-.64s' pentru coloana '%-.192s' in tabela '%-.192s'"
- rus "������� %-.16s ��������� ������������ '%-.48s'@'%-.64s' ��� ������� '%-.192s' � ������� '%-.192s'"
- serbian "%-.16s komanda zabranjena za korisnika '%-.48s'@'%-.64s' za kolonu '%-.192s' iz tabele '%-.192s'"
- spa "%-.16s comando negado para usuario: '%-.48s'@'%-.64s' para columna '%-.192s' en la tabla '%-.192s'"
- swe "%-.16s ej till�tet f�r '%-.48s'@'%-.64s' f�r kolumn '%-.192s' i tabell '%-.192s'"
- ukr "%-.16s ������� ���������� �����������: '%-.48s'@'%-.64s' ��� ������� '%-.192s' � �����æ '%-.192s'"
+ cze "%-.16s p-B��kaz nep��stupn� pro u�ivatele: '%-.48s'@'%-.64s' pro sloupec '%-.192s' v tabulce '%-.192s'.'%-.192s'"
+ dan "%-.16s-kommandoen er ikke tilladt for brugeren '%-.48s'@'%-.64s' for kolonne '%-.192s' in tabellen '%-.192s'.'%-.192s'"
+ nla "%-.16s commando geweigerd voor gebruiker: '%-.48s'@'%-.64s' voor kolom '%-.192s' in tabel '%-.192s'.'%-.192s'"
+ eng "%-.16s command denied to user '%-.48s'@'%-.64s' for column '%-.192s' in table '%-.192s'.'%-.192s'"
+ jps "�R�}���h %-.16s �� ���[�U�[ '%-.48s'@'%-.64s'\n �J���� '%-.192s' �e�[�u�� '%-.192s'.'%-.192s' �ɑ��ċ�����Ă��܂���",
+ est "%-.16s k�sk ei ole lubatud kasutajale '%-.48s'@'%-.64s' tulbale '%-.192s' tabelis '%-.192s'.'%-.192s'"
+ fre "La commande '%-.16s' est interdite � l'utilisateur: '%-.48s'@'@%-.64s' sur la colonne '%-.192s' de la table '%-.192s'.'%-.192s'"
+ ger "%-.16s Befehl nicht erlaubt f�r Benutzer '%-.48s'@'%-.64s' und Feld '%-.192s' in Tabelle '%-.192s'.'%-.192s'"
+ hun "%-.16s parancs a '%-.48s'@'%-.64s' felhasznalo szamara nem engedelyezett a '%-.192s' mezo eseten a '%-.192s'.'%-.192s' tablaban"
+ ita "Comando %-.16s negato per l'utente: '%-.48s'@'%-.64s' sulla colonna '%-.192s' della tabella '%-.192s'.'%-.192s'"
+ jpn "���ޥ�� %-.16s �� �桼���� '%-.48s'@'%-.64s'\n ����� '%-.192s' �ơ��֥� '%-.192s'.'%-.192s' ���Ф��Ƶ��Ĥ���Ƥ��ޤ���"
+ kor "'%-.16s' ������ ���� ����ڿ��� �źεǾ����ϴ�. : '%-.48s'@'%-.64s' for Į�� '%-.192s' in ���̺� '%-.192s'.'%-.192s'"
+ por "Comando '%-.16s' negado para o usu�rio '%-.48s'@'%-.64s' na coluna '%-.192s', na tabela '%-.192s'.'%-.192s'"
+ rum "Comanda %-.16s interzisa utilizatorului: '%-.48s'@'%-.64s' pentru coloana '%-.192s' in tabela '%-.192s'.'%-.192s'"
+ rus "������� %-.16s ��������� ������������ '%-.48s'@'%-.64s' ��� ������� '%-.192s' � ������� '%-.192s'.'%-.192s'"
+ serbian "%-.16s komanda zabranjena za korisnika '%-.48s'@'%-.64s' za kolonu '%-.192s' iz tabele '%-.192s'.'%-.192s'"
+ spa "%-.16s comando negado para usuario: '%-.48s'@'%-.64s' para columna '%-.192s' en la tabla '%-.192s'.'%-.192s'"
+ swe "%-.16s ej till�tet f�r '%-.48s'@'%-.64s' f�r kolumn '%-.192s' i tabell '%-.192s'.'%-.192s'"
+ ukr "%-.16s ������� ���������� �����������: '%-.48s'@'%-.64s' ��� ������� '%-.192s' � �����æ '%-.192s'.'%-.192s'"
ER_ILLEGAL_GRANT_FOR_TABLE 42000
cze "Neplatn-B� p��kaz GRANT/REVOKE. Pros�m, p�e�t�te si v manu�lu, jak� privilegia je mo�n� pou��t."
dan "Forkert GRANT/REVOKE kommando. Se i brugervejledningen hvilke privilegier der kan specificeres."
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-09-03 16:20:30 +0000
+++ b/sql/sp_head.cc 2010-10-23 16:37:55 +0000
@@ -1545,7 +1545,7 @@
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), priv_desc,
thd->security_ctx->priv_user, thd->security_ctx->host_or_ip,
- table_name->str);
+ db_name->str, table_name->str);
m_security_ctx.restore_security_context(thd, save_ctx);
DBUG_RETURN(TRUE);
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-09-03 16:20:30 +0000
+++ b/sql/sql_acl.cc 2010-10-23 16:37:55 +0000
@@ -3059,7 +3059,7 @@
table_list->grant.want_privilege);
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
command, thd->security_ctx->priv_user,
- thd->security_ctx->host_or_ip, table_list->alias);
+ thd->security_ctx->host_or_ip, table_list->db, table_list->alias);
DBUG_RETURN(-1);
}
}
@@ -4044,6 +4044,7 @@
command,
sctx->priv_user,
sctx->host_or_ip,
+ table ? table->get_db_name() : "unknown",
table ? table->get_table_name() : "unknown");
}
DBUG_RETURN(1);
@@ -4112,6 +4113,7 @@
sctx->priv_user,
sctx->host_or_ip,
name,
+ db_name,
table_name);
DBUG_RETURN(1);
}
@@ -4275,13 +4277,14 @@
if (using_column_privileges)
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
command, sctx->priv_user,
- sctx->host_or_ip, table_name);
+ sctx->host_or_ip, db_name, table_name);
else
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
command,
sctx->priv_user,
sctx->host_or_ip,
fields->name(),
+ db_name,
table_name);
return 1;
}
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2010-09-03 16:20:30 +0000
+++ b/sql/sql_base.cc 2010-10-23 16:37:55 +0000
@@ -7992,7 +7992,7 @@
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), "ANY",
thd->security_ctx->priv_user,
thd->security_ctx->host_or_ip,
- field_table_name);
+ field_iterator.get_db_name(), field_table_name);
DBUG_RETURN(TRUE);
}
}
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-10-19 13:58:35 +0000
+++ b/sql/sql_show.cc 2010-10-23 16:37:55 +0000
@@ -651,7 +651,9 @@
my_snprintf(m_view_access_denied_message, MYSQL_ERRMSG_SIZE,
ER(ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW",
m_sctx->priv_user,
- m_sctx->host_or_ip, m_top_view->get_table_name());
+ m_sctx->host_or_ip,
+ m_top_view->get_db_name(),
+ m_top_view->get_table_name());
}
return m_view_access_denied_message_ptr;
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-09-03 16:20:30 +0000
+++ b/sql/sql_view.cc 2010-10-23 16:37:55 +0000
@@ -317,7 +317,7 @@
{
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
"ANY", thd->security_ctx->priv_user,
- thd->security_ctx->priv_host, tbl->table_name);
+ thd->security_ctx->priv_host, tbl->db, tbl->table_name);
goto err;
}
/*
@@ -637,7 +637,7 @@
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
"create view", thd->security_ctx->priv_user,
thd->security_ctx->priv_host, report_item->name,
- view->table_name);
+ view->db, view->table_name);
res= TRUE;
goto err;
}
_______________________________________________
commits mailing list
commits(a)mariadb.org
https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
----- End forwarded message -----
--
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
1

[Maria-developers] Why do we need fsync() in commit() in internal two-phase commit?
by Kristian Nielsen 26 Oct '10
by Kristian Nielsen 26 Oct '10
26 Oct '10
Currently, when an InnoDB/XtraDB transaction is committed with the binlog
enabled, we do three fsync()'s:
1. Inside prepare() in InnoDB
2. When writing to the binlog
3. Inside commit() in InnoDB
The fsync()s are done when --innodb-flush-log-at-trx-commit=1 and
sync_binlog=1; these settings are needed to be able to recover into a
consistent state between binlog and InnoDB after a crash during commit.
This got me thinking why this is really needed?
- I understand why we need the fsync() in prepare(): otherwise we might after
crash have a transaction in the binlog that is missing in InnoDB and that
we cannot (currently) recover.
- I understand why we need the fsync() in binlog write; otherwise the commit
in InnoDB may reach the disk before the binlog write, and after a crash we
might have a transaction in InnoDB missing in the binlog that cannot be
recovered.
But why do we need the fsync() in commit()?
We do not need it to ensure durability or consistency. If we crash after
commit() returns (or just binlog write finishes), but before the InnoDB commit
reaches disk, the crash recovery at next server start will re-commit the
transaction inside InnoDB.
In fact, it seems to me the only reason for the third fsync() is that we call
TC_LOG_BINLOG::unlog() after InnoDB commit() returns. And unlog() may decide
to rotate the binlog once it has been called for all transactions written to
the current log file. And during recovery, we only read the latest binlog, so
transactions in older binlogs must have reached disk for recovery to work.
Do you agree that this is the only reason the third fsync() is needed?
If so, it seems it would not be too hard to avoid that fsync(). Eg. we could
recover from the last two binlog files instead of only one. We would need a
mechanism for InnoDB to tell the binlog that transaction `Xid' reached the
disk, in an asynchronous way (after returning from commit()).
[Just wanted to confirm (or the opposite) this reasoning... as we have been
talking about a way to avoid both the fsync() in prepare() /and/ the fsync()
in commit(), that may be a better project to implement that just avoiding the
one in commit().]
- Kristian.
2
1

23 Oct '10
Philip, Igor
Why is ExtractValue() not allowed for a virtual column?
Why can't I do this:
CREATE TABLE sbtest (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
doc TEXT,
username varchar(10) as (ExtractValue(doc, '/user/username')) virtual,
PRIMARY KEY (id),
)
...but can do this:
CREATE TABLE sbtest (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
doc TEXT,
username varchar(10) as (ExtractValue(doc, '/user/username')) virtual,
PRIMARY KEY (id)
)
(Just for fun, imagine "doc" containing an xml document like
<user>
<id>1</id>
<username>hingo</username>
<name>Henrik Ingo</name>
<status time="2010-21-10 13:16">I'm writing an example XML document</status>
<friends>
<friend_id>9</friend_id>
<friend_id>91</friend_id>
<friend_id>92</friend_id>
<friend_id>93</friend_id>
<friend_id>94</friend_id>
<friend_id>95</friend_id>
<friend_id>96</friend_id>
<friend_id>97</friend_id>
<friend_id>98</friend_id>
<friend_id>99</friend_id>
</friend>
</user>
)
I don't see ExtractValue being in any way undeterministic or anything.
henrik
--
henrik.ingo(a)avoinelama.fi
+358-40-5697354
www.openlife.cc
2
2

[Maria-developers] Buildbot builds/tests innodb_plugin.so, is that intentional?
by Sergey Petrunya 19 Oct '10
by Sergey Petrunya 19 Oct '10
19 Oct '10
Hello,
I've noticed that centos5-amd64-minimal builds innodb plugin for MariaDB 5.2
and 5.3 (didn't check 5.1)
For example, if one takes this build
http://buildbot.askmonty.org/buildbot/builders/centos5-amd64-minimal/builds…
and looks at compliation log
http://buildbot.askmonty.org/buildbot/builders/centos5-amd64-minimal/builds…
they'll find:
(cd .libs && rm -f ha_innodb_plugin.so.0 && ln -s ha_innodb_plugin.so.0.0.0 ha_innodb_plugin.so.0)
(cd .libs && rm -f ha_innodb_plugin.so && ln -s ha_innodb_plugin.so.0.0.0 ha_innodb_plugin.so)
ar cru .libs/ha_innodb_plugin.a ...
ranlib .libs/ha_innodb_plugin.a
creating ha_innodb_plugin.la
(cd .libs && rm -f ha_innodb_plugin.la && ln -s ../ha_innodb_plugin.la ha_innodb_plugin.la)
make[2]: Leaving directory `/home/buildbot/maria-slave/centos5-amd64-minimal/build/mysql-5.3.0-MariaDB-alpha/storage/innodb_plugin'
Which shows we're building the plugin. Do we really need this?
(I've discovered this by accident - in 5.3 it now runs innodb_plugin testsuite both with
xtradb and innodb_plugin, and we've got a problem as xtradb includes index condition pushdown and
xtradb doesn't, which causes them to produce different EXPLAIN outputs: when the test is run with
xtradb, we get 'Using index condition', and with innodb_plugin we get 'Using where').
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
1

19 Oct '10
shell> diff mysqld.cc.orig mysqld.cc
7503a7504
> {"Key_blocks_warm", (char*) offsetof(KEY_CACHE,
warm_blocks), SHOW_KEY_CACHE_LONG},
For explanation see: http://www.fromdual.com/warm-myisam-key-blocks
--
FromDual - Vendor independent and neutral MySQL consulting.
Oli Sennhauser
Rebenweg 6
CH - 8610 Uster / Switzerland
Phone +41 44 940 24 82
Mobile +41 79 830 09 33
e-Mail oli.sennhauser(a)fromdual.com
Website http://www.fromdual.com/
Skype fromdual
Jabber fromdual(a)swissjabber.ch
Yahoo IM fromdual
Xing https://www.xing.com/profile/Oliver_Sennhauser
LinkedIn http://ch.linkedin.com/in/shinguz
2
1

Re: [Maria-developers] [Commits] Rev 2951: WL#12 - MariaDB User Feedback (a.k.a. Phone Home) plugin in http://bazaar.launchpad.net/~maria-captains/maria/5.1/
by Sergei Golubchik 18 Oct '10
by Sergei Golubchik 18 Oct '10
18 Oct '10
Hi, Michael!
On Oct 18, Michael Widenius wrote:
> +
> + // create a background thread to handle urls, if any
> + if (url_count)
> + {
> + pthread_mutex_init(&sleep_mutex, 0);
> + pthread_cond_init(&sleep_condition, 0);
> + shutdown_plugin= false;
>
> Please add a comment why you set 'shutdown_plugin' to false (as this
> is not a variable only for the feedback plugin).
This is a variable only for the feedback plugin.
> + pthread_attr_t attr;
> + pthread_attr_init(&attr);
> + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
> + if (pthread_create(&sender_thread, &attr, background_thread, 0) != 0)
> + {
>
> --- a/plugin/feedback/sender_thread.cc 1970-01-01 00:00:00 +0000
> +++ b/plugin/feedback/sender_thread.cc 2010-09-30 14:24:31 +0000
...
> + if (thd) // for nicer SHOW PROCESSLIST
> + thd->set_query(const_cast<char*>(url->url()), url->url_length());
>
> Wouldn't it be better if url->url() would return const char * ?
It does return const char*, but thd->set_query() wants char* (for no
good reason), so I need to cast const away.
> +
> + if (url->send(str.c_ptr(), str.length()))
>
> Use str.ptr() instead of str,c_ptr() (We already checked that this is ok)
Why?
> === added file 'plugin/feedback/url_base.cc'
>
> +Url* Url::create(const char *url, size_t url_length)
> +{
> + url= my_strndup(url, url_length, MYF(MY_WME));
>
> my_strndup() -> my_strmake()
Pardon me?
There's no such a function as my_strmake(). And strmake() only copies the
string, while my_strndup() allocates and copies. I need the latter.
> + if (!url)
> + return NULL;
> +
> --- a/plugin/feedback/url_http.cc 1970-01-01 00:00:00 +0000
> +++ a/plugin/feedback/url_http.cc 1970-01-01 00:00:00 +0000
> <cut>
>
> +Url* http_create(const char *url, size_t url_length)
> +{
> + const char *s;
> + LEX_STRING full_url= {const_cast<char*>(url), url_length};
> + LEX_STRING host, port, path;
>
> Would it not be better to introduce LEX_CONS_STRING and use these to
> avoid const away casts?
Perhaps, if I'd have more casts because of that. But just because of one
or two - I'd rather keep the code uniform instead and use LEX_STRING
everywhere.
> + bool ssl= false;
> +
> <cut>
>
> + /*
> + if the data were send successfully, read the reply.
> + Extract the first string between <h1>...</h1> tags
> + and put it as a server reply into the error log.
> + */
> + len= vio_read(vio, (uchar*)buf, sizeof(buf)-1);
> + if (len && len < sizeof(buf))
>
> Isn't len guaranteed to be < sizeof(buf) here ?
> I would change the check to 'if (len > 0)'
len is unsigned. vio_read() can return (uint)-1
which indicates and error and is certainly > sizeof(buf)
> + {
> + char *from;
> +
> + buf[len+1]= 0; // safety
> +
>
> Other ideas and suggestions:
>
> - It would be very imporant for us to know which plugins are
> loaded in the feedback. How can we do that ? (I assume we can't get
> that information with the current code)
We do it. fill_plugin_version() function in the utils.cc gets the list
of installed plugins and their versions.
By the way, I've added few more lines of information to the report -
after you've seen the code. On my computer they contain:
Uname_sysname Linux
Uname_release 2.6.34-gentoo-r6
Uname_version #1 SMP Mon Sep 6 15:26:42 CEST 2010
Uname_machine x86_64
Uname_distribution Gentoo Base System release 1.12.13
> From my point of view, when you have fixed the bugs and considered the
> suggestions it's ok to push in 5.1.
Thanks for the review! You've catched quite a few problems in the code.
Regards,
Sergei
1
0
Hi Sanja,
subselect_cache fails on sol-sparc-32 in current 5.3-merge-from-5.2:
http://buildbot.askmonty.org/buildbot/builders/sol-sparc-32/builds/575/step…
Any idea about this? Have we observed such failure before or it has appeared in
the merge?
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
1

Re: [Maria-developers] [Commits] Rev 2828: MWL#128: Added into EXPLAIN output info about types of the used join buffers and in file:///home/igor/maria/maria-5.3-mwl128-names/
by Sergey Petrunya 18 Oct '10
by Sergey Petrunya 18 Oct '10
18 Oct '10
Hello Igor,
Ok to push (.result differences checked), with exception that change to
Makefile.am must not be pushed.
On Fri, Oct 08, 2010 at 12:30:18PM -0700, Igor Babaev wrote:
> At file:///home/igor/maria/maria-5.3-mwl128-names/
>
> ------------------------------------------------------------
> revno: 2828
> revision-id: igor(a)askmonty.org-20101008193016-r9cuu8bvkpa1bmxg
> parent: igor(a)askmonty.org-20101006202712-ehecsi9kc0tj52jc
> committer: Igor Babaev <igor(a)askmonty.org>
> branch nick: maria-5.3-mwl128-names
> timestamp: Fri 2010-10-08 12:30:16 -0700
> message:
> MWL#128: Added into EXPLAIN output info about types of the used join buffers and
> about the employed join algorithms.
> Refactored constructors of the JOIN_CACHE* classes.
> === modified file 'Makefile.am'
> --- a/Makefile.am 2010-03-29 15:13:53 +0000
> +++ b/Makefile.am 2010-10-08 19:30:16 +0000
> @@ -317,10 +317,15 @@
> #
>
> abi_check: $(API_PREPROCESSOR_HEADER)
> - $(MAKE) abi_headers="$^" do_abi_check
> + echo "OK"
> +
> +#$(MAKE) abi_headers="$^" do_abi_check
>
> abi_check_all: $(TEST_PREPROCESSOR_HEADER)
> - $(MAKE) abi_headers="$^" do_abi_check
> + echo "OK"
> +
> +
> +# $(MAKE) abi_headers="$^" do_abi_check
>
> do_abi_check:
> set -ex; \
>
> === modified file 'mysql-test/r/archive_gis.result'
> --- a/mysql-test/r/archive_gis.result 2009-02-10 13:27:35 +0000
> +++ b/mysql-test/r/archive_gis.result 2010-10-08 19:30:16 +0000
> @@ -403,7 +403,7 @@
> FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> -1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> +1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid`
> DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
>
> === modified file 'mysql-test/r/compress.result'
> --- a/mysql-test/r/compress.result 2009-12-15 07:16:46 +0000
> +++ b/mysql-test/r/compress.result 2010-10-08 19:30:16 +0000
> @@ -1435,7 +1435,7 @@
> explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
> fld1 companynr fld3 period
> 038008 37 reporters 1008
>
> === modified file 'mysql-test/r/ctype_utf8.result'
> --- a/mysql-test/r/ctype_utf8.result 2010-03-04 08:03:07 +0000
> +++ b/mysql-test/r/ctype_utf8.result 2010-10-08 19:30:16 +0000
> @@ -1537,7 +1537,7 @@
> select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Y ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
> -1 SIMPLE Z ALL NULL NULL NULL NULL 2 Using where; Using join buffer
> +1 SIMPLE Z ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
> select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
> substr(Z.a,-1) a
> 3 123
>
> === modified file 'mysql-test/r/derived.result'
> --- a/mysql-test/r/derived.result 2009-07-11 18:44:29 +0000
> +++ b/mysql-test/r/derived.result 2010-10-08 19:30:16 +0000
> @@ -58,7 +58,7 @@
> explain select * from t1 as x1, (select * from t1) as x2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY x1 ALL NULL NULL NULL NULL 4
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
> 2 DERIVED t1 ALL NULL NULL NULL NULL 4
> drop table if exists t2,t3;
> select * from (select 1) as a;
> @@ -189,13 +189,13 @@
> explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY m2 ALL NULL NULL NULL NULL 9
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
> 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
> explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY m2 ALL NULL NULL NULL NULL 9
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
> 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
> drop table t1,t2;
> @@ -246,7 +246,7 @@
> explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
> -1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer
> +1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
> 4 DERIVED t1 ALL NULL NULL NULL NULL 2
> 5 UNION t1 ALL NULL NULL NULL NULL 2
> NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
> @@ -313,7 +313,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
> 2 DERIVED x ALL NULL NULL NULL NULL 17 Using temporary; Using filesort
> -2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer
> +2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer (flat, BNL join)
> drop table t1;
> create table t2 (a int, b int, primary key (a));
> insert into t2 values (1,7),(2,7);
>
> === modified file 'mysql-test/r/distinct.result'
> --- a/mysql-test/r/distinct.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/distinct.result 2010-10-08 19:30:16 +0000
> @@ -175,7 +175,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 4 Using where; Using temporary
> 1 SIMPLE t3 ref a a 5 test.t1.b 2 Using index
> -1 SIMPLE t2 index a a 4 NULL 5 Using where; Using index; Distinct; Using join buffer
> +1 SIMPLE t2 index a a 4 NULL 5 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
> SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
> a
> 1
> @@ -300,11 +300,11 @@
> AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 index id id 4 NULL 2 Using index; Using temporary
> -1 SIMPLE t2 index id id 8 NULL 1 Using index; Distinct; Using join buffer
> -1 SIMPLE t3 index id id 8 NULL 1 Using index; Distinct; Using join buffer
> -1 SIMPLE j_lj_t2 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer
> +1 SIMPLE t2 index id id 8 NULL 1 Using index; Distinct; Using join buffer (flat, BNL join)
> +1 SIMPLE t3 index id id 8 NULL 1 Using index; Distinct; Using join buffer (flat, BNL join)
> +1 SIMPLE j_lj_t2 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
> 1 SIMPLE t2_lj ref id id 4 test.j_lj_t2.id 1 Using where; Using index; Distinct
> -1 SIMPLE j_lj_t3 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer
> +1 SIMPLE j_lj_t3 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
> 1 SIMPLE t3_lj ref id id 4 test.j_lj_t3.id 1 Using where; Using index; Distinct
> SELECT DISTINCT
> t1.id
> @@ -515,7 +515,7 @@
> EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1_1 ALL NULL NULL NULL NULL 3 Using temporary
> -1 SIMPLE t1_2 index NULL PRIMARY 4 NULL 3 Using index; Distinct; Using join buffer
> +1 SIMPLE t1_2 index NULL PRIMARY 4 NULL 3 Using index; Distinct; Using join buffer (flat, BNL join)
> EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2
> WHERE t1_1.a = t1_2.a;
> id select_type table type possible_keys key key_len ref rows Extra
>
> === modified file 'mysql-test/r/explain.result'
> --- a/mysql-test/r/explain.result 2010-06-26 10:05:41 +0000
> +++ b/mysql-test/r/explain.result 2010-10-08 19:30:16 +0000
> @@ -116,7 +116,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
> 2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> -2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> +2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
> EXPLAIN EXTENDED SELECT 1
> @@ -124,34 +124,34 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
> 2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> -2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> -Warnings:
> -Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
> -prepare s1 from
> -'EXPLAIN EXTENDED SELECT 1
> - FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
> -execute s1;
> -id select_type table type possible_keys key key_len ref rows filtered Extra
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
> -2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> -2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> -Warnings:
> -Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
> -prepare s1 from
> -'EXPLAIN EXTENDED SELECT 1
> - FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
> -execute s1;
> -id select_type table type possible_keys key key_len ref rows filtered Extra
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
> -2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> -2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> -Warnings:
> -Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
> -execute s1;
> -id select_type table type possible_keys key key_len ref rows filtered Extra
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
> -2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> -2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> +2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> +Warnings:
> +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
> +prepare s1 from
> +'EXPLAIN EXTENDED SELECT 1
> + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
> +execute s1;
> +id select_type table type possible_keys key key_len ref rows filtered Extra
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
> +2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> +2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> +Warnings:
> +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
> +prepare s1 from
> +'EXPLAIN EXTENDED SELECT 1
> + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
> +execute s1;
> +id select_type table type possible_keys key key_len ref rows filtered Extra
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
> +2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> +2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> +Warnings:
> +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
> +execute s1;
> +id select_type table type possible_keys key key_len ref rows filtered Extra
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
> +2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> +2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
> DROP TABLE t1,t2;
>
> === modified file 'mysql-test/r/func_gconcat.result'
> --- a/mysql-test/r/func_gconcat.result 2010-03-31 13:00:56 +0000
> +++ b/mysql-test/r/func_gconcat.result 2010-10-08 19:30:16 +0000
> @@ -986,7 +986,7 @@
> 1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> 2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort; Distinct
> -2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 Distinct; Using join buffer
> +2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 Distinct; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select 1 AS `1` from (select distinct group_concat(`test`.`td`.`f1` separator ',') AS `GROUP_CONCAT(td.f1)` from `test`.`t1` join `test`.`t1` `td` group by `test`.`td`.`f1`) `d` join `test`.`t1`
> SELECT 1 FROM
> @@ -1006,7 +1006,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
> 2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> -2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> +2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select 1 AS `1` from (select group_concat(`test`.`t1`.`a` order by `test`.`t1`.`a` ASC separator ',') AS `GROUP_CONCAT(t1.a ORDER BY t1.a ASC)` from `test`.`t1` `t2` join `test`.`t1` group by `test`.`t1`.`a`) `d`
> DROP TABLE t1;
>
> === modified file 'mysql-test/r/func_group.result'
> --- a/mysql-test/r/func_group.result 2010-03-20 12:01:47 +0000
> +++ b/mysql-test/r/func_group.result 2010-10-08 19:30:16 +0000
> @@ -614,7 +614,7 @@
> select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'MIN' and t2.a3 > 'CA';
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range k1 k1 7 NULL 1 Using where; Using index
> -1 SIMPLE t2 range k1 k1 3 NULL 4 Using where; Using index; Using join buffer
> +1 SIMPLE t2 range k1 k1 3 NULL 4 Using where; Using index; Using join buffer (flat, BNL join)
> explain
> select min(a4 - 0.01) from t1;
> id select_type table type possible_keys key key_len ref rows Extra
> @@ -651,7 +651,7 @@
> select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME';
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 range k2 k2 4 NULL 6 Using where; Using index
> -1 SIMPLE t1 index NULL PRIMARY 3 NULL 15 Using index; Using join buffer
> +1 SIMPLE t1 index NULL PRIMARY 3 NULL 15 Using index; Using join buffer (flat, BNL join)
> drop table t1, t2;
> create table t1 (a char(10));
> insert into t1 values ('a'),('b'),('c');
>
> === modified file 'mysql-test/r/func_group_innodb.result'
> --- a/mysql-test/r/func_group_innodb.result 2007-05-29 12:58:18 +0000
> +++ b/mysql-test/r/func_group_innodb.result 2010-10-08 19:30:16 +0000
> @@ -79,7 +79,7 @@
> explain select min(7) from t2i join t1i;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2i ALL NULL NULL NULL NULL 1
> -1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
> +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
> select min(7) from t2i join t1i;
> min(7)
> NULL
> @@ -95,7 +95,7 @@
> explain select max(7) from t2i join t1i;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2i ALL NULL NULL NULL NULL 1
> -1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
> +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
> select max(7) from t2i join t1i;
> max(7)
> NULL
>
> === modified file 'mysql-test/r/func_str.result'
> --- a/mysql-test/r/func_str.result 2010-03-26 05:49:35 +0000
> +++ b/mysql-test/r/func_str.result 2010-10-08 19:30:16 +0000
> @@ -2550,12 +2550,12 @@
> explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
> 2 DERIVED t1 ALL NULL NULL NULL NULL 2
> explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
> 2 DERIVED t1 ALL NULL NULL NULL NULL 2
> drop table t1;
> #
>
> === modified file 'mysql-test/r/gis.result'
> --- a/mysql-test/r/gis.result 2010-02-26 13:16:46 +0000
> +++ b/mysql-test/r/gis.result 2010-10-08 19:30:16 +0000
> @@ -395,7 +395,7 @@
> FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> -1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> +1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid`
> DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
>
> === modified file 'mysql-test/r/greedy_optimizer.result'
> --- a/mysql-test/r/greedy_optimizer.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/greedy_optimizer.result 2010-10-08 19:30:16 +0000
> @@ -121,11 +121,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -133,11 +133,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -145,11 +145,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -157,11 +157,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -169,11 +169,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -181,11 +181,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -201,11 +201,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -213,11 +213,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -225,11 +225,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -237,11 +237,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -249,11 +249,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -261,11 +261,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -277,11 +277,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -289,11 +289,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -304,9 +304,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 794.837037
> @@ -316,9 +316,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 794.837037
> @@ -328,9 +328,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 794.837037
> @@ -340,9 +340,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 794.837037
> @@ -353,11 +353,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -365,11 +365,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -377,11 +377,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -389,11 +389,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -401,11 +401,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -413,11 +413,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -433,11 +433,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -445,11 +445,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -457,11 +457,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -469,11 +469,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -481,11 +481,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -493,11 +493,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -509,11 +509,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -521,11 +521,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -536,9 +536,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 794.837037
> @@ -548,9 +548,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 794.837037
> @@ -560,9 +560,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 794.837037
> @@ -572,9 +572,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 794.837037
> @@ -585,11 +585,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -597,11 +597,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -609,11 +609,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -621,11 +621,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -633,11 +633,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -645,11 +645,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
>
> === modified file 'mysql-test/r/group_by.result'
> --- a/mysql-test/r/group_by.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/group_by.result 2010-10-08 19:30:16 +0000
> @@ -537,11 +537,11 @@
> explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
> -1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary
> -1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> drop table t1,t2;
> create table t1 (a int, b int);
> insert into t1 values (1, 4),(10, 40),(1, 4),(10, 43),(1, 4),(10, 41),(1, 4),(10, 43),(1, 4);
>
> === modified file 'mysql-test/r/group_min_max.result'
> --- a/mysql-test/r/group_min_max.result 2010-06-26 10:05:41 +0000
> +++ b/mysql-test/r/group_min_max.result 2010-10-08 19:30:16 +0000
> @@ -2267,7 +2267,7 @@
> AND t1_outer1.b = t1_outer2.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index
> -1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer
> +1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer (flat, BNL join)
> 2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
> EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x
> FROM t1 AS t1_outer) x2 FROM t1 AS t1_outer2;
>
> === modified file 'mysql-test/r/index_merge_myisam.result'
> --- a/mysql-test/r/index_merge_myisam.result 2010-07-16 08:58:24 +0000
> +++ b/mysql-test/r/index_merge_myisam.result 2010-10-08 19:30:16 +0000
> @@ -271,7 +271,7 @@
> (t1.key1 = t0.key1 or t1.key8 = t0.key1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t0 ref i1 i1 4 const 1
> -1 SIMPLE t1 index_merge i1,i8 i1,i8 4,4 NULL 2 Using union(i1,i8); Using where; Using join buffer
> +1 SIMPLE t1 index_merge i1,i8 i1,i8 4,4 NULL 2 Using union(i1,i8); Using where; Using join buffer (flat, BNL join)
> explain select * from t0,t1 where t0.key1 < 3 and
> (t1.key1 = t0.key1 or t1.key8 = t0.key1);
> id select_type table type possible_keys key key_len ref rows Extra
> @@ -348,7 +348,7 @@
> and (B.key1 < 500000 or B.key2 < 3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE A index_merge i1,i2 i1,i2 4,4 NULL 1013 Using sort_union(i1,i2); Using where
> -1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1013 Using sort_union(i1,i2); Using where; Using join buffer
> +1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1013 Using sort_union(i1,i2); Using where; Using join buffer (flat, BNL join)
> select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
> from t0 as A force index(i1,i2), t0 as B force index (i1,i2)
> where (A.key1 < 500000 or A.key2 < 3)
> @@ -362,7 +362,7 @@
> and (B.key1 = 1 or B.key2 = 1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE A index_merge i1,i2 i1,i2 4,4 NULL 1020 Using union(i1,i2); Using where
> -1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1020 Using union(i1,i2); Using where; Using join buffer
> +1 SIMPLE B index_merge i1,i2 i1,i2 4,4 NULL 1020 Using union(i1,i2); Using where; Using join buffer (flat, BNL join)
> select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
> from t0 as A force index(i1,i2), t0 as B force index (i1,i2)
> where (A.key1 = 1 or A.key2 = 1)
> @@ -377,7 +377,7 @@
> and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7 = 1 or B.key8=1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE A index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where
> -1 SIMPLE B index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where; Using join buffer
> +1 SIMPLE B index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where; Using join buffer (flat, BNL join)
> select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
> from t0 as A, t0 as B
> where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1)
>
> === modified file 'mysql-test/r/information_schema.result'
> --- a/mysql-test/r/information_schema.result 2010-06-07 21:53:25 +0000
> +++ b/mysql-test/r/information_schema.result 2010-10-08 19:30:16 +0000
> @@ -323,7 +323,7 @@
> a.ROUTINE_SCHEMA = b.SCHEMA_NAME;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE # ALL NULL NULL NULL NULL NULL
> -1 SIMPLE # ALL NULL NULL NULL NULL NULL Using where; Using join buffer
> +1 SIMPLE # ALL NULL NULL NULL NULL NULL Using where; Using join buffer (flat, BNL join)
> select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a,
> mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8) AND a.ROUTINE_SCHEMA='test' order by 1;
> ROUTINE_NAME name
> @@ -1450,7 +1450,7 @@
> where a.table_name='t1' and a.table_schema='test' and b.table_name=a.table_name;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE a ALL NULL TABLE_SCHEMA,TABLE_NAME NULL NULL NULL Using where; Skip_open_table; Scanned 0 databases
> -1 SIMPLE b ALL NULL NULL NULL NULL NULL Using where; Open_frm_only; Scanned all databases; Using join buffer
> +1 SIMPLE b ALL NULL NULL NULL NULL NULL Using where; Open_frm_only; Scanned all databases; Using join buffer (flat, BNL join)
> SELECT * FROM INFORMATION_SCHEMA.SCHEMATA
> WHERE SCHEMA_NAME = 'mysqltest';
> CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
>
> === modified file 'mysql-test/r/innodb_gis.result'
> --- a/mysql-test/r/innodb_gis.result 2009-02-10 13:27:35 +0000
> +++ b/mysql-test/r/innodb_gis.result 2010-10-08 19:30:16 +0000
> @@ -403,7 +403,7 @@
> FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
> -1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> +1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid`
> DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
>
> === modified file 'mysql-test/r/innodb_mysql.result'
> --- a/mysql-test/r/innodb_mysql.result 2010-06-26 10:05:41 +0000
> +++ b/mysql-test/r/innodb_mysql.result 2010-10-08 19:30:16 +0000
> @@ -187,7 +187,7 @@
> explain select min(7) from t2i join t1i;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2i ALL NULL NULL NULL NULL 1
> -1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
> +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
> select min(7) from t2i join t1i;
> min(7)
> NULL
> @@ -203,7 +203,7 @@
> explain select max(7) from t2i join t1i;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2i ALL NULL NULL NULL NULL 1
> -1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer
> +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
> select max(7) from t2i join t1i;
> max(7)
> NULL
>
> === modified file 'mysql-test/r/join.result'
> --- a/mysql-test/r/join.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/join.result 2010-10-08 19:30:16 +0000
> @@ -404,7 +404,7 @@
> ORDER BY t1.b, t1.c;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using temporary; Using filesort
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 16 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 16 Using where; Using join buffer (flat, BNL join)
> SELECT STRAIGHT_JOIN t2.e FROM t1,t2 WHERE t2.d=1 AND t1.b=t2.e
> ORDER BY t1.b, t1.c;
> e
> @@ -1099,7 +1099,7 @@
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 0 Using where
> 1 SIMPLE t5 ALL NULL NULL NULL NULL 0 Using where
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 0 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
> SELECT *
> FROM
> t1 JOIN t2 ON t1.a = t2.a
>
> === modified file 'mysql-test/r/join_cache.result'
> --- a/mysql-test/r/join_cache.result 2010-10-04 01:45:46 +0000
> +++ b/mysql-test/r/join_cache.result 2010-10-08 19:30:16 +0000
> @@ -45,7 +45,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer
> +1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -74,8 +74,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer
> -1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer
> +1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -233,7 +233,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer
> +1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -262,8 +262,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer
> -1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer
> +1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (incremental, BNL join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -425,7 +425,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer
> +1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -454,8 +454,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer
> -1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer
> +1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -613,7 +613,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer
> +1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -642,8 +642,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer
> -1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer
> +1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (incremental, BNL join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -840,7 +840,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -869,8 +869,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BNLH join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -1024,7 +1024,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -1052,7 +1052,7 @@
> Country.Population > 10000000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer
> +1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BNLH join)
> SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
> FROM Country LEFT JOIN CountryLanguage ON
> (CountryLanguage.Country=Country.Code AND Language='English')
> @@ -1150,7 +1150,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -1179,8 +1179,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BNLH join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer (incremental, BNLH join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -1334,7 +1334,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -1362,7 +1362,7 @@
> Country.Population > 10000000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer
> +1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BNLH join)
> SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
> FROM Country LEFT JOIN CountryLanguage ON
> (CountryLanguage.Country=Country.Code AND Language='English')
> @@ -1460,7 +1460,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -1489,8 +1489,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (flat, BKA join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -1644,7 +1644,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -1672,7 +1672,7 @@
> Country.Population > 10000000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer
> +1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BKA join)
> SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
> FROM Country LEFT JOIN CountryLanguage ON
> (CountryLanguage.Country=Country.Code AND Language='English')
> @@ -1767,7 +1767,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -1796,8 +1796,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (incremental, BKA join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -1951,7 +1951,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -1979,7 +1979,7 @@
> Country.Population > 10000000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer
> +1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BKA join)
> SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
> FROM Country LEFT JOIN CountryLanguage ON
> (CountryLanguage.Country=Country.Code AND Language='English')
> @@ -2074,7 +2074,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -2103,8 +2103,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKAH join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -2258,7 +2258,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -2286,7 +2286,7 @@
> Country.Population > 10000000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer
> +1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BKAH join)
> SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
> FROM Country LEFT JOIN CountryLanguage ON
> (CountryLanguage.Country=Country.Code AND Language='English')
> @@ -2381,7 +2381,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -2410,8 +2410,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKAH join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (incremental, BKAH join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -2565,7 +2565,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -2593,7 +2593,7 @@
> Country.Population > 10000000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where
> -1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer
> +1 SIMPLE CountryLanguage eq_ref PRIMARY PRIMARY 33 world.Country.Code,const 1 Using where; Using join buffer (flat, BKAH join)
> SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage)
> FROM Country LEFT JOIN CountryLanguage ON
> (CountryLanguage.Country=Country.Code AND Language='English')
> @@ -2692,7 +2692,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -2721,8 +2721,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BNLH join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -2876,7 +2876,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -2906,7 +2906,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -2935,8 +2935,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BNLH join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using where; Using join buffer (incremental, BNLH join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -3090,7 +3090,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BNLH join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -3120,7 +3120,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -3149,8 +3149,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (flat, BKA join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -3304,7 +3304,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -3334,7 +3334,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -3363,8 +3363,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (incremental, BKA join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -3518,7 +3518,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -3548,7 +3548,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -3577,8 +3577,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKAH join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -3732,7 +3732,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -3762,7 +3762,7 @@
> Country.Name LIKE 'L%' AND City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND
> Country.Name LIKE 'L%' AND City.Population > 100000;
> @@ -3791,8 +3791,8 @@
> CountryLanguage.Percentage > 50;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE CountryLanguage ALL PRIMARY,Percentage NULL NULL NULL 984 Using where
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer
> -1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where; Using join buffer (flat, BKAH join)
> +1 SIMPLE City ref Country Country 3 world.Country.Code 18 Using index condition(BKA); Using where; Using join buffer (incremental, BKAH join)
> SELECT City.Name, Country.Name, CountryLanguage.Language
> FROM City,Country,CountryLanguage
> WHERE City.Country=Country.Code AND
> @@ -3946,7 +3946,7 @@
> City.Population > 100000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR
> -1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer
> +1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join)
> SELECT Name FROM City
> WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND
> City.Population > 100000;
> @@ -4031,7 +4031,7 @@
> WHERE City.Country=Country.Code AND City.Population > 3000000;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE City range Population,Country Population 4 NULL # Using index condition; Using MRR
> -1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country # Using join buffer
> +1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country # Using join buffer (flat, BKAH join)
> SELECT City.Name, Country.Name FROM City,Country
> WHERE City.Country=Country.Code AND City.Population > 3000000;
> Name Name
> @@ -4320,15 +4320,15 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t6 system PRIMARY NULL NULL NULL 1
> 1 SIMPLE t1 ref t1_affiliateid,t1_metaid t1_affiliateid 4 const 1
> -1 SIMPLE t4 ref PRIMARY,t4_formatclassid,t4_formats_idx t4_formats_idx 1 const 1 Using index condition; Using where; Using join buffer
> -1 SIMPLE t5 eq_ref PRIMARY,t5_formattypeid PRIMARY 4 test.t4.formatclassid 1 Using where; Using join buffer
> -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using join buffer
> +1 SIMPLE t4 ref PRIMARY,t4_formatclassid,t4_formats_idx t4_formats_idx 1 const 1 Using index condition; Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE t5 eq_ref PRIMARY,t5_formattypeid PRIMARY 4 test.t4.formatclassid 1 Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using join buffer (incremental, BKA join)
> 1 SIMPLE t7 ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using index
> -1 SIMPLE t3 ref t3_metaid,t3_formatid,t3_metaidformatid t3_metaid 4 test.t1.metaid 2 Using where; Using join buffer
> -1 SIMPLE t8 eq_ref PRIMARY PRIMARY 4 test.t7.artistid 1 Using join buffer
> -1 SIMPLE t9 index PRIMARY,t9_subgenreid,t9_metaid PRIMARY 8 NULL 2 Using where; Using index; Using join buffer
> -1 SIMPLE t10 eq_ref PRIMARY,t10_genreid PRIMARY 4 test.t9.subgenreid 1 Using join buffer
> -1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t10.genreid 1 Using join buffer
> +1 SIMPLE t3 ref t3_metaid,t3_formatid,t3_metaidformatid t3_metaid 4 test.t1.metaid 2 Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE t8 eq_ref PRIMARY PRIMARY 4 test.t7.artistid 1 Using join buffer (incremental, BKA join)
> +1 SIMPLE t9 index PRIMARY,t9_subgenreid,t9_metaid PRIMARY 8 NULL 2 Using where; Using index; Using join buffer (incremental, BNL join)
> +1 SIMPLE t10 eq_ref PRIMARY,t10_genreid PRIMARY 4 test.t9.subgenreid 1 Using join buffer (incremental, BKA join)
> +1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t10.genreid 1 Using join buffer (incremental, BKA join)
> SELECT t1.uniquekey, t1.xml AS affiliateXml,
> t8.name AS artistName, t8.artistid,
> t11.name AS genreName, t11.genreid, t11.priority AS genrePriority,
> @@ -4409,7 +4409,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using where
> 1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a1 1 Using index
> -1 SIMPLE t3 ref idx idx 5 test.t2.b2 5 Using where; Using join buffer
> +1 SIMPLE t3 ref idx idx 5 test.t2.b2 5 Using where; Using join buffer (flat, BKA join)
> SELECT a1<>a2, a1, a2, b2, b3, c3,
> SUBSTR(filler1,1,1) AS s1, SUBSTR(filler2,1,1) AS s2
> FROM t1,t2,t3 WHERE a1=a2 AND b2=b3 AND MOD(c3,10)>7;
> @@ -4441,7 +4441,7 @@
> EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL idx NULL NULL NULL 7 Using where
> -1 SIMPLE t2 ref idx idx 5 test.t1.a 2 Using join buffer
> +1 SIMPLE t2 ref idx idx 5 test.t1.a 2 Using join buffer (flat, BKAH join)
> SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30;
> a b a b
> 7 40 7 10
> @@ -4474,7 +4474,7 @@
> SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 5
> -1 SIMPLE t2 ref i_a i_a 4 test.t1.a 2 Using where; Not exists; Using join buffer
> +1 SIMPLE t2 ref i_a i_a 4 test.t1.a 2 Using where; Not exists; Using join buffer (flat, BKA join)
> SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
> a a b
> 3 NULL NULL
> @@ -4501,7 +4501,7 @@
> from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort
> -1 SIMPLE t2 ref i_a i_a 5 test.t1.a 2 Using where; Using join buffer
> +1 SIMPLE t2 ref i_a i_a 5 test.t1.a 2 Using where; Using join buffer (flat, BKA join)
> select t1.a, count(t2.p) as count
> from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a;
> a count
> @@ -4553,7 +4553,7 @@
> explain select * from t1 left join t2 on t1.a=t2.a where t2.c=102 or t2.c is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> select * from t1 left join t2 on t1.a=t2.a where t2.c=102 or t2.c is null;
> a b a c
> 3 30 3 102
> @@ -4576,7 +4576,7 @@
> explain select * from t1 left join t2 on (1=0) where a=40;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
> select * from t1 left join t2 on (1=0) where a=40;
> a b
> 40 NULL
> @@ -4620,7 +4620,7 @@
> EXPLAIN SELECT AVG(c) FROM t1,t2 WHERE t1.a=t2.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2050 Using where
> -1 SIMPLE t2 ref idx idx 5 test.t1.a 640 Using join buffer
> +1 SIMPLE t2 ref idx idx 5 test.t1.a 640 Using join buffer (flat, BKA join)
> SELECT AVG(c) FROM t1,t2 WHERE t1.a=t2.b;
> AVG(c)
> 5.0000
> @@ -4660,8 +4660,8 @@
> t1.b IS NULL AND t2.b IS NULL AND t3.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 16384 Using where
> -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer
> -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer
> +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (flat, BKAH join)
> +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (flat, BKAH join)
> SELECT COUNT(*) FROM t1,t2,t3
> WHERE t1.a=t2.a AND t2.a=t3.a AND
> t1.b IS NULL AND t2.b IS NULL AND t3.b IS NULL;
> @@ -4726,7 +4726,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 2 Using index
> 1 SIMPLE t2 ref PRIMARY PRIMARY 8 test.t1.a 1 Using index
> -1 SIMPLE t3 ref idx idx 16 test.t1.a,test.t2.b 2 Using join buffer
> +1 SIMPLE t3 ref idx idx 16 test.t1.a,test.t2.b 2 Using join buffer (flat, BKA join)
> SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
> FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
> WHERE t1.a=t2.a;
> @@ -4751,7 +4751,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 2 Using index
> 1 SIMPLE t2 ref PRIMARY PRIMARY 8 test.t1.a 1 Using index
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 24 Using where; Using join buffer
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 24 Using where; Using join buffer (flat, BNL join)
> SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val
> FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b)
> WHERE t1.a=t2.a;
> @@ -4797,7 +4797,7 @@
> where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer
> +1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join)
> set join_cache_level=6;
> select t2.f1, t2.f2, t2.f3 from t1,t2
> where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
> @@ -4810,7 +4810,7 @@
> where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer
> +1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join)
> set join_cache_level=7;
> select t2.f1, t2.f2, t2.f3 from t1,t2
> where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
> @@ -4823,7 +4823,7 @@
> where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
> set join_cache_level=8;
> select t2.f1, t2.f2, t2.f3 from t1,t2
> where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
> @@ -4836,7 +4836,7 @@
> where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
> drop table t1,t2;
> set join_cache_level=default;
> #
> @@ -4855,7 +4855,7 @@
> where t1.d=3 group by t1.id1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref idx1 idx1 5 const 4 Using where; Using index; Using temporary; Using filesort
> -1 SIMPLE t2 ref idx2 idx2 5 test.t1.id1 2 Using join buffer
> +1 SIMPLE t2 ref idx2 idx2 5 test.t1.id1 2 Using join buffer (flat, BKA join)
> select t1.id1, sum(t2.id2) from t1 join t2 on t1.id1=t2.id1
> where t1.d=3 group by t1.id1;
> id1 sum(t2.id2)
> @@ -4867,7 +4867,7 @@
> where t1.d=3 and t2.id2 > 200 order by t1.id1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref idx1 idx1 5 const 4 Using where; Using index; Using temporary; Using filesort
> -1 SIMPLE t2 ref idx2 idx2 5 test.t1.id1 2 Using where; Using join buffer
> +1 SIMPLE t2 ref idx2 idx2 5 test.t1.id1 2 Using where; Using join buffer (flat, BKA join)
> select t1.id1 from t1 join t2 on t1.id1=t2.id1
> where t1.d=3 and t2.id2 > 200 order by t1.id1;
> id1
> @@ -4924,9 +4924,9 @@
> where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where
> -1 SIMPLE t2 ref idx idx 5 test.t1.b 1 Using join buffer
> -1 SIMPLE t3 ref idx idx 5 test.t1.d 1 Using join buffer
> -1 SIMPLE t4 ref idx idx 5 test.t1.c 1 Using join buffer
> +1 SIMPLE t2 ref idx idx 5 test.t1.b 1 Using join buffer (flat, BKA join)
> +1 SIMPLE t3 ref idx idx 5 test.t1.d 1 Using join buffer (incremental, BKA join)
> +1 SIMPLE t4 ref idx idx 5 test.t1.c 1 Using join buffer (incremental, BKA join)
> select t1.a, t1.b, t1.c, t1.d, t2.e, t3.f, t4.g from t1,t2,t3,t4
> where t2.b=t1.b and t3.d=t1.d and t4.c=t1.c;
> a b c d e f g
> @@ -4975,10 +4975,10 @@
> t5.enum2='Active' AND t3.id4=t2.id4 AND t2.id3=t1.id3 AND t3.text1<'D';
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 349 Using where
> -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.id3 1 Using where; Using join buffer
> -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t2.id4 1 Using where; Using join buffer
> -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t1.id2 1 Using join buffer
> -1 SIMPLE t5 eq_ref PRIMARY PRIMARY 16 test.t1.id1,test.t1.id2 1 Using where; Using join buffer
> +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.id3 1 Using where; Using join buffer (flat, BKAH join)
> +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t2.id4 1 Using where; Using join buffer (incremental, BKAH join)
> +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t1.id2 1 Using join buffer (incremental, BKAH join)
> +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 16 test.t1.id1,test.t1.id2 1 Using where; Using join buffer (incremental, BKAH join)
> SELECT STRAIGHT_JOIN t1.id1, t1.num3, t3.text1, t3.id4, t2.id3, t4.dummy
> FROM t1 JOIN t2 JOIN t3 JOIN t4 JOIN t5
> WHERE t1.id1=t5.id1 AND t1.id2=t5.id2 and t4.id2=t1.id2 AND
> @@ -5075,7 +5075,7 @@
> ORDER BY t1.int_key;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 index NULL int_key 4 NULL 14 Using index
> -1 SIMPLE t2 index NULL int_key 4 NULL 2 Using index; Using join buffer
> +1 SIMPLE t2 index NULL int_key 4 NULL 2 Using index; Using join buffer (flat, BNL join)
>
> DROP TABLE t1,t2;
> SET join_cache_level=default;
> @@ -5109,7 +5109,7 @@
> ORDER BY t2.v;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
> -1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 Using index; Using join buffer
> +1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 Using index; Using join buffer (flat, BNL join)
>
> DROP TABLE t1,t2;
> #
> @@ -5143,8 +5143,8 @@
> explain select t1.* from t1,t2,t3;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
> select t1.* from t1,t2,t3;
> a b
> 1 1
> @@ -5159,8 +5159,8 @@
> explain select t1.* from t1,t2,t3;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join)
> select t1.* from t1,t2,t3;
> a b
> 1 1
> @@ -5190,8 +5190,8 @@
> SELECT t3.a FROM t1,t2,t3 WHERE t1.a = t3.a AND t1.b = t3.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using join buffer
> -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
> +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (incremental, BKA join)
> SELECT t3.a FROM t1,t2,t3 WHERE t1.a = t3.a AND t1.b = t3.b;
> a
> 27
> @@ -5237,7 +5237,7 @@
> ON t3.carrier = t1.carrier;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.carrier 1 Using where
> 1 SIMPLE t4 ref carrier_id carrier_id 5 test.t3.id 2 Using index
> SET join_cache_level=default;
> @@ -5253,7 +5253,7 @@
> explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer
> +1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer (flat, BKA join)
> SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> a
> NULL
> @@ -5262,7 +5262,7 @@
> explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer
> +1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer (flat, BKAH join)
> SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> a
> NULL
> @@ -5273,7 +5273,7 @@
> explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer
> +1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer (flat, BKA join)
> SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> a
> NULL
> @@ -5287,7 +5287,7 @@
> explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ref b b 103 test.t1.b 2 Using where; Using join buffer
> +1 SIMPLE t2 ref b b 103 test.t1.b 2 Using where; Using join buffer (flat, BKA join)
> SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> a
> NULL
> @@ -5296,7 +5296,7 @@
> explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ref b b 103 test.t1.b 2 Using where; Using join buffer
> +1 SIMPLE t2 ref b b 103 test.t1.b 2 Using where; Using join buffer (flat, BKAH join)
> SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
> a
> NULL
> @@ -5322,7 +5322,7 @@
> WHERE s.pk AND s.a >= t.pk AND s.b = t.c;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t ALL NULL NULL NULL NULL 2 Using where
> -1 SIMPLE s ref idx idx 19 test.t.c 1 Using index condition(BKA); Using where; Using join buffer
> +1 SIMPLE s ref idx idx 19 test.t.c 1 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join)
> SELECT t.a FROM t1 t, t1 s FORCE INDEX(idx)
> WHERE s.pk AND s.a >= t.pk AND s.b = t.c;
> a
> @@ -5345,8 +5345,8 @@
> WHERE t1.a OR t3.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 4
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join)
> SELECT t1.a
> FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0
> WHERE t1.a OR t3.a;
> @@ -5359,9 +5359,9 @@
> WHERE t1.a OR t4.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 4
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join)
> SELECT t1.a
> FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0
> WHERE t1.a OR t4.a;
>
> === modified file 'mysql-test/r/join_nested.result'
> --- a/mysql-test/r/join_nested.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/join_nested.result 2010-10-08 19:30:16 +0000
> @@ -229,7 +229,7 @@
> ON t7.b=t8.b AND t6.b < 10;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
> 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
> Warnings:
> Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10))) where 1
> @@ -544,7 +544,7 @@
> (t2.a >= 4 OR t2.c IS NULL);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
> @@ -639,7 +639,7 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
> @@ -647,7 +647,7 @@
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> SELECT t9.a,t9.b
> @@ -836,7 +836,7 @@
> WHERE t1.a <= 2;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
> Warnings:
> @@ -850,7 +850,7 @@
> ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2 100.00 Using where
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
> Warnings:
> @@ -906,7 +906,7 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
> @@ -914,7 +914,7 @@
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> CREATE INDEX idx_b ON t4(b);
> @@ -956,7 +956,7 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
> @@ -964,7 +964,7 @@
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> CREATE INDEX idx_b ON t8(b);
> @@ -1005,7 +1005,7 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
> @@ -1013,7 +1013,7 @@
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> CREATE INDEX idx_b ON t1(b);
> @@ -1063,7 +1063,7 @@
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
>
> === modified file 'mysql-test/r/join_nested_jcl6.result'
> --- a/mysql-test/r/join_nested_jcl6.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/join_nested_jcl6.result 2010-10-08 19:30:16 +0000
> @@ -80,8 +80,8 @@
> WHERE t3.a=1 OR t3.c IS NULL;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` = 1) or isnull(`test`.`t3`.`c`))
> SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
> @@ -156,9 +156,9 @@
> WHERE t3.a>1 OR t3.c IS NULL;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`))
> SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
> @@ -186,9 +186,9 @@
> (t5.a<3 OR t5.c IS NULL);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where (((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`)) and ((`test`.`t5`.`a` < 3) or isnull(`test`.`t5`.`c`)))
> SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
> @@ -236,8 +236,8 @@
> ON t7.b=t8.b AND t6.b < 10;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
> -1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
> +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10))) where 1
> SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
> @@ -551,14 +551,14 @@
> (t2.a >= 4 OR t2.c IS NULL);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
> -1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
> +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
> SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
> @@ -646,15 +646,15 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> SELECT t9.a,t9.b
> @@ -843,9 +843,9 @@
> WHERE t1.a <= 2;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) where (`test`.`t1`.`a` <= 2)
> CREATE INDEX idx_b ON t2(b);
> @@ -857,9 +857,9 @@
> ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> -1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2 100.00 Using where; Using join buffer
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> +1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on((((`test`.`t3`.`a` = 1) and (`test`.`t3`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` = `test`.`t4`.`b`)) and (`test`.`t3`.`b` is not null))) where 1
> SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
> @@ -913,15 +913,15 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> CREATE INDEX idx_b ON t4(b);
> @@ -963,15 +963,15 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer
> -1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> CREATE INDEX idx_b ON t8(b);
> @@ -1012,15 +1012,15 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer
> -1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> CREATE INDEX idx_b ON t1(b);
> @@ -1062,15 +1062,15 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ref idx_a idx_a 5 const 1 100.00 Using where
> -1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 2 100.00 Using join buffer
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer
> -1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> -1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 2 100.00 Using join buffer (flat, BKA join)
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
> @@ -1324,8 +1324,8 @@
> EXPLAIN SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join)
> DROP TABLE t1,t2,t3;
> CREATE TABLE t1 (goods int(12) NOT NULL, price varchar(128) NOT NULL);
> INSERT INTO t1 VALUES (23, 2340), (26, 9900);
> @@ -1452,27 +1452,27 @@
> t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL X
> -1 SIMPLE t3 ref a a 5 test.t2.b X Using where; Using join buffer
> -1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer
> -1 SIMPLE t4 ref a a 5 test.t3.b X Using index condition(BKA); Using join buffer
> +1 SIMPLE t3 ref a a 5 test.t2.b X Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer (incremental, BKA join)
> +1 SIMPLE t4 ref a a 5 test.t3.b X Using index condition(BKA); Using join buffer (incremental, BKA join)
> explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b
> join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL X
> -1 SIMPLE t3 ref a a 5 test.t2.b X Using index condition(BKA); Using join buffer
> -1 SIMPLE t4 ref a a 5 test.t3.b X Using where; Using join buffer
> -1 SIMPLE t6 ref a a 5 test.t4.b X Using join buffer
> -1 SIMPLE t5 ref a a 5 test.t2.b X Using where; Using join buffer
> -1 SIMPLE t7 ref a a 5 test.t5.b X Using join buffer
> +1 SIMPLE t3 ref a a 5 test.t2.b X Using index condition(BKA); Using join buffer (flat, BKA join)
> +1 SIMPLE t4 ref a a 5 test.t3.b X Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t6 ref a a 5 test.t4.b X Using join buffer (incremental, BKA join)
> +1 SIMPLE t5 ref a a 5 test.t2.b X Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t7 ref a a 5 test.t5.b X Using join buffer (incremental, BKA join)
> explain select * from t2 left join
> (t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b
> join t5 on t5.a=t3.b) on t3.a=t2.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL X
> -1 SIMPLE t3 ref a a 5 test.t2.b X Using where; Using join buffer
> -1 SIMPLE t4 ref a a 5 test.t3.b X Using where; Using join buffer
> -1 SIMPLE t6 ref a a 5 test.t4.b X Using join buffer
> -1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer
> +1 SIMPLE t3 ref a a 5 test.t2.b X Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE t4 ref a a 5 test.t3.b X Using where; Using join buffer (incremental, BKA join)
> +1 SIMPLE t6 ref a a 5 test.t4.b X Using join buffer (incremental, BKA join)
> +1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer (incremental, BKA join)
> drop table t0, t1, t2, t3, t4, t5, t6, t7;
> create table t1 (a int);
> insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
> @@ -1485,8 +1485,8 @@
> on (t1.a = t2.a);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 10
> -1 SIMPLE t2 ref a a 5 test.t1.a 1 Using where; Using join buffer
> -1 SIMPLE t3 ref a a 5 test.t2.a 1 Using where; Using join buffer
> +1 SIMPLE t2 ref a a 5 test.t1.a 1 Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE t3 ref a a 5 test.t2.a 1 Using where; Using join buffer (incremental, BKA join)
> drop table t1, t2, t3;
> CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, type varchar(10));
> CREATE TABLE t2 (pid int NOT NULL PRIMARY KEY, type varchar(10));
> @@ -1737,7 +1737,7 @@
> ON t4.carrier = t1.carrier;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index package_id package_id 5 NULL 45 Using where; Using index
> -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.package_id 1 Using join buffer
> +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.package_id 1 Using join buffer (flat, BKA join)
> 1 SIMPLE t4 eq_ref PRIMARY,id PRIMARY 2 test.t1.carrier 1 Using where
> 1 SIMPLE t5 ref carrier_id carrier_id 5 test.t4.id 22 Using index
> 1 SIMPLE t3 ref package_id package_id 5 test.t1.id 1 Using where; Using index
> @@ -1773,9 +1773,9 @@
> (t8.a > 0 OR t8.c IS NULL);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t5 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t7 ref b_i b_i 5 test.t5.b 2 Using where; Using join buffer
> -1 SIMPLE t6 ALL b_i NULL NULL NULL 3 Using where; Using join buffer
> -1 SIMPLE t8 ref b_i b_i 5 test.t7.b 2 Using where; Using join buffer
> +1 SIMPLE t7 ref b_i b_i 5 test.t5.b 2 Using where; Using join buffer (flat, BKA join)
> +1 SIMPLE t6 ALL b_i NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join)
> +1 SIMPLE t8 ref b_i b_i 5 test.t7.b 2 Using where; Using join buffer (incremental, BKA join)
> SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
> FROM t5
> LEFT JOIN
> @@ -1808,9 +1808,9 @@
> ON (t5.b=t8.b);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t5 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer
> -1 SIMPLE t7 const PRIMARY PRIMARY 4 const 1 Using join buffer
> -1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
> +1 SIMPLE t7 const PRIMARY PRIMARY 4 const 1 Using join buffer (incremental, BKA join)
> +1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
> SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
> FROM t5 LEFT JOIN
> (t6 LEFT JOIN t7 ON t7.a=1, t8)
> @@ -1825,9 +1825,9 @@
> ON (t5.b=t8.b);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t5 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer
> -1 SIMPLE t7 ref b_i b_i 5 const 0 Using join buffer
> -1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
> +1 SIMPLE t7 ref b_i b_i 5 const 0 Using join buffer (incremental, BKA join)
> +1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
> SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
> FROM t5 LEFT JOIN
> (t6 LEFT JOIN t7 ON t7.b=2, t8)
> @@ -1842,9 +1842,9 @@
> ON (t5.b=t8.b);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t5 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer
> -1 SIMPLE t7 const PRIMARY PRIMARY 4 const 1 Using join buffer
> +1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join)
> +1 SIMPLE t7 const PRIMARY PRIMARY 4 const 1 Using join buffer (incremental, BKA join)
> SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
> FROM t5 LEFT JOIN
> (t8, t6 LEFT JOIN t7 ON t7.a=1)
>
> === modified file 'mysql-test/r/join_outer_jcl6.result'
> --- a/mysql-test/r/join_outer_jcl6.result 2010-10-06 20:27:12 +0000
> +++ b/mysql-test/r/join_outer_jcl6.result 2010-10-08 19:30:16 +0000
> @@ -102,7 +102,7 @@
> explain select t1.*,t2.* from t1 left join t2 on t1.a=t2.a where isnull(t2.a)=1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 7
> -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.a 1 Using where; Using join buffer
> +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.a 1 Using where; Using join buffer (flat, BKA join)
> select t1.*,t2.*,t3.a from t1 left join t2 on (t1.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
> grp a c id a c d a
> 1 1 a 1 1 a 1 1
> @@ -319,11 +319,11 @@
> explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists; Using join buffer (flat, BNL join)
> explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.name is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> select count(*) from t1 left join t2 on (t1.id = t2.owner);
> count(*)
> 4
> @@ -339,11 +339,11 @@
> explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists; Using join buffer (flat, BNL join)
> explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.name is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> select count(*) from t2 right join t1 on (t1.id = t2.owner);
> count(*)
> 4
> @@ -695,8 +695,8 @@
> explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
> drop table t1, t2, t3;
> create table t1 (
> a int(11),
> @@ -745,13 +745,13 @@
> order by m.match_id desc;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
> -1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 Using join buffer
> +1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 Using join buffer (flat, BKA join)
> explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from
> (t2 s left join t1 m on m.match_id = 1)
> order by UUX desc;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
> -1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 Using join buffer
> +1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 Using join buffer (flat, BKA join)
> select s.*, '*', m.*, (s.match_1_h - m.home) UUX from
> (t2 s left join t1 m on m.match_id = 1)
> order by UUX desc;
> @@ -771,7 +771,7 @@
> order by UUX desc;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
> -1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 Using join buffer
> +1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 Using join buffer (flat, BKA join)
> select s.*, '*', m.*, (s.match_1_h - m.home) UUX from
> t2 s straight_join t1 m where m.match_id = 1
> order by UUX desc;
> @@ -1134,15 +1134,15 @@
> EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t1.a = t2.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where
> -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using join buffer
> +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using join buffer (flat, BKA join)
> EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a IN(t2.a, t2.b);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where
> -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using join buffer
> +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using join buffer (flat, BKA join)
> EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a > IF(t1.a = t2.b-2, t2.b, t2.b-1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where
> -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using join buffer
> +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using join buffer (flat, BKA join)
> DROP TABLE t1,t2;
> DROP VIEW IF EXISTS v1,v2;
> DROP TABLE IF EXISTS t1,t2;
> @@ -1231,7 +1231,7 @@
> SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 5
> -1 SIMPLE t2 ref idx idx 4 test.t1.id 2 Using where; Not exists; Using join buffer
> +1 SIMPLE t2 ref idx idx 4 test.t1.id 2 Using where; Not exists; Using join buffer (flat, BKA join)
> flush status;
> SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL;
> id a
>
> === modified file 'mysql-test/r/key_diff.result'
> --- a/mysql-test/r/key_diff.result 2007-05-29 12:58:18 +0000
> +++ b/mysql-test/r/key_diff.result 2010-10-08 19:30:16 +0000
> @@ -36,7 +36,7 @@
> explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL a NULL NULL NULL 5
> -1 SIMPLE t2 ALL b NULL NULL NULL 5 Using where; Using join buffer
> +1 SIMPLE t2 ALL b NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a;
> a b a b
> A B a a
>
> === modified file 'mysql-test/r/myisam.result'
> --- a/mysql-test/r/myisam.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/myisam.result 2010-10-08 19:30:16 +0000
> @@ -346,11 +346,11 @@
> explain select * from t1,t2 where t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL a NULL NULL NULL 2
> -1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer
> +1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> explain select * from t1,t2 force index(a) where t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL a NULL NULL NULL 2
> -1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer
> +1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL a NULL NULL NULL 2
> @@ -362,7 +362,7 @@
> explain select * from t1,t2 force index(c) where t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer
> +1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> explain select * from t1 where a=0 or a=2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where
>
> === modified file 'mysql-test/r/order_by.result'
> --- a/mysql-test/r/order_by.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/order_by.result 2010-10-08 19:30:16 +0000
> @@ -1608,18 +1608,18 @@
> SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Using MRR; Using temporary; Using filesort
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> # should have "using filesort"
> EXPLAIN
> SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Using MRR; Using temporary; Using filesort
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> # should have "using filesort"
> EXPLAIN
> SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Using MRR; Using temporary; Using filesort
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> DROP TABLE t1, t2;
> End of 5.1 tests
>
> === modified file 'mysql-test/r/pool_of_threads.result'
> --- a/mysql-test/r/pool_of_threads.result 2009-12-15 07:16:46 +0000
> +++ b/mysql-test/r/pool_of_threads.result 2010-10-08 19:30:16 +0000
> @@ -1429,7 +1429,7 @@
> explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
> fld1 companynr fld3 period
> 038008 37 reporters 1008
>
> === modified file 'mysql-test/r/range.result'
> --- a/mysql-test/r/range.result 2010-03-20 12:01:47 +0000
> +++ b/mysql-test/r/range.result 2010-10-08 19:30:16 +0000
> @@ -221,27 +221,27 @@
> explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Using MRR; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Using MRR; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Using MRR; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Using MRR; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Using MRR; Using join buffer (flat, BNL join)
> explain select count(*) from t1 where x in (1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref x x 5 const 1 Using index
> @@ -256,12 +256,12 @@
> explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ref j1 j1 4 const 1 Using index
> -1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer
> +1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer (flat, BNL join)
> explain select * from t1 force index(i1), t2 force index(j1) where
> (t1.key1 <t2.keya + 1) and t2.keya=3;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ref j1 j1 4 const 1 Using index
> -1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer
> +1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer (flat, BNL join)
> DROP TABLE t1,t2;
> CREATE TABLE t1 (
> a int(11) default NULL,
>
> === modified file 'mysql-test/r/row.result'
> --- a/mysql-test/r/row.result 2010-04-16 11:42:34 +0000
> +++ b/mysql-test/r/row.result 2010-10-08 19:30:16 +0000
> @@ -377,7 +377,7 @@
> EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE (t1.a-1,t1.b)=(t2.a-1,t2.b+1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t1 index NULL PRIMARY 8 NULL 6 100.00 Using index
> -1 SIMPLE t2 index NULL PRIMARY 12 NULL 7 100.00 Using where; Using index; Using join buffer
> +1 SIMPLE t2 index NULL PRIMARY 12 NULL 7 100.00 Using where; Using index; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where (((`test`.`t1`.`a` - 1) = (`test`.`t2`.`a` - 1)) and (`test`.`t1`.`b` = (`test`.`t2`.`b` + 1)))
> SELECT * FROM t1,t2 WHERE (t1.a-1,t1.b)=(t2.a-1,t2.b+1);
>
> === modified file 'mysql-test/r/select.result'
> --- a/mysql-test/r/select.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/select.result 2010-10-08 19:30:16 +0000
> @@ -1431,7 +1431,7 @@
> explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
> fld1 companynr fld3 period
> 038008 37 reporters 1008
> @@ -2363,7 +2363,7 @@
> explain select * from t1 left join t2 on a=c where d in (4);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ref c,d d 5 const 2
> -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> select * from t1 left join t2 on a=c where d in (4);
> a b c d
> 3 2 3 4
> @@ -2371,7 +2371,7 @@
> explain select * from t1 left join t2 on a=c where d = 4;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ref c,d d 5 const 2
> -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> select * from t1 left join t2 on a=c where d = 4;
> a b c d
> 3 2 3 4
> @@ -2717,7 +2717,7 @@
> t2.b like '%%' order by t2.b limit 0,1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref b,c b 5 const 1 Using temporary; Using filesort
> -1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer
> +1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
> DROP TABLE t1,t2,t3;
> CREATE TABLE t1 (a int, INDEX idx(a));
> @@ -2738,7 +2738,7 @@
> EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index b b 5 NULL 2 Using index
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> a b a b
> 1 NULL 1 1
> @@ -2748,7 +2748,7 @@
> EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index b b 5 NULL 2 Using index
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> a b a b
> 1 NULL 1 1
> @@ -2910,11 +2910,11 @@
> EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 5
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> DROP TABLE t1,t2;
> select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
> x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
>
> === modified file 'mysql-test/r/select_jcl6.result'
> --- a/mysql-test/r/select_jcl6.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/select_jcl6.result 2010-10-08 19:30:16 +0000
> @@ -611,15 +611,15 @@
> explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
> -1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using join buffer
> +1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using join buffer (flat, BKA join)
> explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
> -1 SIMPLE t1 ref period period 4 test.t3.period 4181 Using join buffer
> +1 SIMPLE t1 ref period period 4 test.t3.period 4181 Using join buffer (flat, BKA join)
> explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
> -1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using join buffer
> +1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using join buffer (flat, BKA join)
> select period from t1;
> period
> 9410
> @@ -1366,11 +1366,11 @@
> explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 1200
> -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists; Using join buffer
> +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists; Using join buffer (flat, BKA join)
> explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 12
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists; Using join buffer (flat, BNL join)
> select companynr,companyname from t2 left join t4 using (companynr) where companynr is null;
> companynr companyname
> select count(*) from t2 left join t4 using (companynr) where companynr is not null;
> @@ -1386,51 +1386,51 @@
> explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
> -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer
> +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer (flat, BKA join)
> explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
> -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer
> +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer (flat, BKA join)
> explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
> -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer
> +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer (flat, BKA join)
> explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 12
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 12
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
> companynr companynr
> 37 36
> @@ -1438,7 +1438,7 @@
> explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
> fld1 companynr fld3 period
> 038008 37 reporters 1008
> @@ -2337,7 +2337,7 @@
> 1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
> 1 SIMPLE t4 const id4 NULL NULL NULL 1
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
> select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
> left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
> id1 id2 id3 id4 id44
> @@ -2370,7 +2370,7 @@
> explain select * from t1 left join t2 on a=c where d in (4);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ref c,d d 5 const 2
> -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> select * from t1 left join t2 on a=c where d in (4);
> a b c d
> 3 2 3 4
> @@ -2378,7 +2378,7 @@
> explain select * from t1 left join t2 on a=c where d = 4;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ref c,d d 5 const 2
> -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> select * from t1 left join t2 on a=c where d = 4;
> a b c d
> 3 2 3 4
> @@ -2724,7 +2724,7 @@
> t2.b like '%%' order by t2.b limit 0,1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref b,c b 5 const 1 Using temporary; Using filesort
> -1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer
> +1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
> DROP TABLE t1,t2,t3;
> CREATE TABLE t1 (a int, INDEX idx(a));
> @@ -2745,7 +2745,7 @@
> EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index b b 5 NULL 2 Using index
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> a b a b
> 1 NULL 1 1
> @@ -2755,7 +2755,7 @@
> EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index b b 5 NULL 2 Using index
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> a b a b
> 1 NULL 1 1
> @@ -2917,11 +2917,11 @@
> EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 5
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> DROP TABLE t1,t2;
> select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
> x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
> @@ -3461,7 +3461,7 @@
> and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using index condition; Using where; Using MRR
> -1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10 Using join buffer
> +1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10 Using join buffer (flat, BKA join)
> drop table t1, t2;
> CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b));
> INSERT INTO t1 VALUES (1, 3), (9,4), (7,5), (4,5), (6,2),
> @@ -3475,12 +3475,12 @@
> SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using MRR
> -1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer
> +1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join)
> EXPLAIN
> SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Using MRR
> -1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer
> +1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join)
> DROP TABLE t1, t2;
> create table t1 (
> a int unsigned not null auto_increment primary key,
> @@ -3570,19 +3570,19 @@
> WHERE t2.fk < 'c' AND t2.pk=t1.fk;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using index condition; Using where; Using MRR
> -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer
> +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join)
> EXPLAIN SELECT t2.*
> FROM t1 JOIN t2 ON t2.fk=t1.pk
> WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Using MRR
> -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer
> +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join)
> EXPLAIN SELECT t2.*
> FROM t1 JOIN t2 ON t2.fk=t1.pk
> WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Using MRR
> -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer
> +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join)
> DROP TABLE t1,t2;
> CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a));
> CREATE TABLE t2 (a int, b varchar(20) NOT NULL,
> @@ -3616,7 +3616,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
> 1 SIMPLE t2 range si si 5 NULL 4 Using index condition; Using where; Using MRR
> -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer
> +1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join)
> EXPLAIN
> SELECT t3.a FROM t1,t2,t3
> WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
> @@ -3624,7 +3624,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
> 1 SIMPLE t2 range si,ai si 5 NULL 4 Using index condition; Using where; Using MRR
> -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer
> +1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join)
> EXPLAIN
> SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
> WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
> @@ -3632,7 +3632,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
> 1 SIMPLE t2 range si si 5 NULL 2 Using index condition; Using where; Using MRR
> -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer
> +1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join)
> EXPLAIN
> SELECT t3.a FROM t1,t2,t3
> WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
> @@ -3640,7 +3640,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
> 1 SIMPLE t2 range si,ai si 5 NULL 2 Using index condition; Using where; Using MRR
> -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer
> +1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join)
> DROP TABLE t1,t2,t3;
> CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
> CREATE TABLE t2 ( f11 int PRIMARY KEY );
> @@ -4403,7 +4403,7 @@
> EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ALL a NULL NULL NULL 2 Using where; Using join buffer
> +1 SIMPLE t2 ALL a NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
> SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
> 1
> 1
> @@ -4413,7 +4413,7 @@
> EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
> -1 SIMPLE t2 ALL a NULL NULL NULL 2 Using where; Using join buffer
> +1 SIMPLE t2 ALL a NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
> SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
> 1
> 1
>
> === modified file 'mysql-test/r/select_pkeycache.result'
> --- a/mysql-test/r/select_pkeycache.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/select_pkeycache.result 2010-10-08 19:30:16 +0000
> @@ -1431,7 +1431,7 @@
> explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
> fld1 companynr fld3 period
> 038008 37 reporters 1008
> @@ -2363,7 +2363,7 @@
> explain select * from t1 left join t2 on a=c where d in (4);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ref c,d d 5 const 2
> -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> select * from t1 left join t2 on a=c where d in (4);
> a b c d
> 3 2 3 4
> @@ -2371,7 +2371,7 @@
> explain select * from t1 left join t2 on a=c where d = 4;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ref c,d d 5 const 2
> -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> select * from t1 left join t2 on a=c where d = 4;
> a b c d
> 3 2 3 4
> @@ -2717,7 +2717,7 @@
> t2.b like '%%' order by t2.b limit 0,1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref b,c b 5 const 1 Using temporary; Using filesort
> -1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer
> +1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
> DROP TABLE t1,t2,t3;
> CREATE TABLE t1 (a int, INDEX idx(a));
> @@ -2738,7 +2738,7 @@
> EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index b b 5 NULL 2 Using index
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> a b a b
> 1 NULL 1 1
> @@ -2748,7 +2748,7 @@
> EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index b b 5 NULL 2 Using index
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> a b a b
> 1 NULL 1 1
> @@ -2910,11 +2910,11 @@
> EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 5
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> DROP TABLE t1,t2;
> select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
> x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
>
> === modified file 'mysql-test/r/ssl.result'
> --- a/mysql-test/r/ssl.result 2009-12-15 07:16:46 +0000
> +++ b/mysql-test/r/ssl.result 2010-10-08 19:30:16 +0000
> @@ -1432,7 +1432,7 @@
> explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
> fld1 companynr fld3 period
> 038008 37 reporters 1008
>
> === modified file 'mysql-test/r/ssl_compress.result'
> --- a/mysql-test/r/ssl_compress.result 2009-12-15 07:16:46 +0000
> +++ b/mysql-test/r/ssl_compress.result 2010-10-08 19:30:16 +0000
> @@ -1435,7 +1435,7 @@
> explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
> select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
> fld1 companynr fld3 period
> 038008 37 reporters 1008
>
> === modified file 'mysql-test/r/subselect.result'
> --- a/mysql-test/r/subselect.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/subselect.result 2010-10-08 19:30:16 +0000
> @@ -906,7 +906,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
> 2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using index
> -2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
> drop table t1,t2,t3;
> @@ -1296,7 +1296,7 @@
> explain extended select * from t2 where t2.a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
> -1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer
> +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)
> select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
> @@ -1306,7 +1306,7 @@
> explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
> -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer
> +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
> select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
> @@ -1316,7 +1316,7 @@
> explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
> -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer
> +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
> 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
>
> === modified file 'mysql-test/r/subselect3.result'
> --- a/mysql-test/r/subselect3.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/subselect3.result 2010-10-08 19:30:16 +0000
> @@ -261,7 +261,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
> 2 DEPENDENT SUBQUERY t1 ref_or_null a a 5 func 2 100.00 Using where; Full scan on NULL key
> -2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 100 100.00 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 100 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
> Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))) AS `Z` from `test`.`t2`
> @@ -1024,10 +1024,10 @@
> t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
> -1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer
> -1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer
> +1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
> +1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
> 2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
> -2 SUBQUERY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer
> +2 SUBQUERY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
> select t21.* from t21,t22 where t21.a = t22.a and
> t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
> a b c
> @@ -1058,7 +1058,7 @@
> explain select * from t1 where 2 in (select a from t0);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; Start temporary; End temporary
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
> select * from t1 where 2 in (select a from t0);
> a
> 0
> @@ -1085,7 +1085,7 @@
> explain select * from t1 where 2 in (select a from t0);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; FirstMatch
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
> select * from t1 where 2 in (select a from t0);
> a
> 0
> @@ -1125,7 +1125,7 @@
> explain select * from t3 where a in (select kp1 from t1 where kp1<20);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> create table t4 (pk int primary key);
> insert into t4 select a from t3;
> explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20
> @@ -1133,7 +1133,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR; LooseScan
> 1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t1)
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> drop table t1, t3, t4;
> create table t1 (a int) as select * from t0 where a < 5;
> set @save_max_heap_table_size=@@max_heap_table_size;
> @@ -1142,10 +1142,10 @@
> explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary
> -1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer
> -1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer
> -1 PRIMARY C ALL NULL NULL NULL NULL 10 Using join buffer
> -1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer
> +1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> +1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> +1 PRIMARY C ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> +1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (flat, BNL join)
> flush status;
> select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
> count(*)
> @@ -1183,26 +1183,26 @@
> explain select * from t2 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
> explain select * from t2 where a in (select a from t2);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
> explain select * from t2 where a in (select a from t3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
> explain select * from t1 where a in (select a from t3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
> drop table t1, t2, t3;
> create table t1 (a decimal);
> insert into t1 values (1),(2);
> explain select * from t1 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
> drop table t1;
> set @@optimizer_switch=@save_optimizer_switch;
> create table t1 (a int);
> @@ -1219,25 +1219,25 @@
> explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY A ALL NULL NULL NULL NULL 10 Using where
> -1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer
> +1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
> explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
> 2 SUBQUERY A ALL NULL NULL NULL NULL 10
> -2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
> +2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
> 2 SUBQUERY A ALL NULL NULL NULL NULL 10
> -2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
> +2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> explain select straight_join * from t2 X, t2 Y
> where X.a in (select straight_join A.a from t1 A, t1 B);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY X ALL NULL NULL NULL NULL 10 Using where
> -1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer
> +1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> 2 SUBQUERY A ALL NULL NULL NULL NULL 10
> -2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
> +2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> create table t0 (a int, b int);
> insert into t0 values(1,1);
> explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
> @@ -1262,11 +1262,11 @@
> explain select * from t2 where a in (select b from t1 where a=3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> drop table t1,t2;
> create table t1 (a int, b int);
> insert into t1 select a,a from t0;
> @@ -1324,8 +1324,8 @@
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 3
> 1 PRIMARY subselect2 eq_ref unique_key unique_key 15 func 1
> 2 SUBQUERY X ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer
> -2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer
> +2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
> +2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
> drop table t0,t1,t2;
>
> BUG#37842: Assertion in DsMrr_impl::dsmrr_init, at handler.cc:4307
> @@ -1396,7 +1396,7 @@
> );
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2 1.00
> -1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer
> +1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
> 2 SUBQUERY cona ALL NULL NULL NULL NULL 2 100.00 Using where
> 2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00
> Warnings:
>
> === modified file 'mysql-test/r/subselect3_jcl6.result'
> --- a/mysql-test/r/subselect3_jcl6.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/subselect3_jcl6.result 2010-10-08 19:30:16 +0000
> @@ -167,7 +167,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
> 2 DEPENDENT SUBQUERY t1 ref_or_null a a 5 func 4 100.00 Using where; Full scan on NULL key
> -2 DEPENDENT SUBQUERY t2 ref a a 5 test.t1.b 1 100.00 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY t2 ref a a 5 test.t1.b 1 100.00 Using where; Using join buffer (flat, BKA join)
> Warnings:
> Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1
> Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<in_optimizer>(`test`.`t3`.`a`,<exists>(select 1 from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`)))) having trigcond(<is_not_null_test>(`test`.`t1`.`a`)))) AS `Z` from `test`.`t3`
> @@ -195,7 +195,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
> 2 DEPENDENT SUBQUERY t1 ref a a 4 func 2 100.00 Using where; Full scan on NULL key
> -2 DEPENDENT SUBQUERY t2 ref a a 4 test.t1.b 1 100.00 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY t2 ref a a 4 test.t1.b 1 100.00 Using where; Using join buffer (flat, BKA join)
> Warnings:
> Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1
> Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<in_optimizer>(`test`.`t3`.`a`,<exists>(select 1 from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`))))) AS `Z` from `test`.`t3`
> @@ -268,7 +268,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
> 2 DEPENDENT SUBQUERY t1 ref_or_null a a 5 func 2 100.00 Using where; Full scan on NULL key
> -2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 100 100.00 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 100 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
> Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))) AS `Z` from `test`.`t2`
> @@ -739,7 +739,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
> 2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 func 1 Using where; Using index; Full scan on NULL key
> -2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 Using index condition(BKA); Using where; Full scan on NULL key; Using join buffer
> +2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 Using index condition(BKA); Using where; Full scan on NULL key; Using join buffer (flat, BKA join)
> SELECT * FROM t1
> WHERE t1.id NOT IN (SELECT t2.id FROM t2,t3
> WHERE t3.name='xxx' AND t2.id=t3.id);
> @@ -1031,10 +1031,10 @@
> t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
> -1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer
> -1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer
> +1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (incremental, BNL join)
> +1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (incremental, BNL join)
> 2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
> -2 SUBQUERY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer
> +2 SUBQUERY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
> select t21.* from t21,t22 where t21.a = t22.a and
> t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
> a b c
> @@ -1066,7 +1066,7 @@
> explain select * from t1 where 2 in (select a from t0);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; Start temporary; End temporary
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
> select * from t1 where 2 in (select a from t0);
> a
> 0
> @@ -1093,7 +1093,7 @@
> explain select * from t1 where 2 in (select a from t0);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; FirstMatch
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
> select * from t1 where 2 in (select a from t0);
> a
> 0
> @@ -1120,7 +1120,7 @@
> explain select * from (select a from t0) X where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>); Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>); Using join buffer (flat, BNL join)
> 2 DERIVED t0 ALL NULL NULL NULL NULL 11
> drop table t0, t1;
> create table t0 (a int);
> @@ -1133,7 +1133,7 @@
> explain select * from t3 where a in (select kp1 from t1 where kp1<20);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> create table t4 (pk int primary key);
> insert into t4 select a from t3;
> explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20
> @@ -1141,7 +1141,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR; LooseScan
> 1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t1)
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> drop table t1, t3, t4;
> create table t1 (a int) as select * from t0 where a < 5;
> set @save_max_heap_table_size=@@max_heap_table_size;
> @@ -1150,10 +1150,10 @@
> explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary
> -1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer
> -1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer
> -1 PRIMARY C ALL NULL NULL NULL NULL 10 Using join buffer
> -1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer
> +1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> +1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join)
> +1 PRIMARY C ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join)
> +1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (incremental, BNL join)
> flush status;
> select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
> count(*)
> @@ -1173,7 +1173,7 @@
> explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
> -1 PRIMARY t3 ref a a 5 test.t2.a 1 Using join buffer
> +1 PRIMARY t3 ref a a 5 test.t2.a 1 Using join buffer (flat, BKA join)
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
> select * from t3 where a in (select a from t2);
> a filler
> @@ -1191,26 +1191,26 @@
> explain select * from t2 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
> explain select * from t2 where a in (select a from t2);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
> explain select * from t2 where a in (select a from t3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
> explain select * from t1 where a in (select a from t3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
> drop table t1, t2, t3;
> create table t1 (a decimal);
> insert into t1 values (1),(2);
> explain select * from t1 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
> drop table t1;
> set @@optimizer_switch=@save_optimizer_switch;
> create table t1 (a int);
> @@ -1222,44 +1222,44 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
> -1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer
> +1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer (flat, BKA join)
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
> explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY A ALL NULL NULL NULL NULL 10 Using where
> -1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer
> +1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
> explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
> 2 SUBQUERY A ALL NULL NULL NULL NULL 10
> -2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
> +2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
> 2 SUBQUERY A ALL NULL NULL NULL NULL 10
> -2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
> +2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> explain select straight_join * from t2 X, t2 Y
> where X.a in (select straight_join A.a from t1 A, t1 B);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY X ALL NULL NULL NULL NULL 10 Using where
> -1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer
> +1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> 2 SUBQUERY A ALL NULL NULL NULL NULL 10
> -2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
> +2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
> create table t0 (a int, b int);
> insert into t0 values(1,1);
> explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 system NULL NULL NULL NULL 1
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
> -1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer
> +1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer (flat, BKA join)
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
> create table t4 as select a as x, a as y from t1;
> explain select * from t0, t3 where (t3.a, t3.b) in (select x,y from t4) and (t3.a < 10 or t3.a >30);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 system NULL NULL NULL NULL 1
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
> -1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where; Using join buffer
> +1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where; Using join buffer (flat, BKA join)
> 2 SUBQUERY t4 ALL NULL NULL NULL NULL 10 Using where
> drop table t0,t1,t2,t3,t4;
> create table t0 (a int);
> @@ -1270,11 +1270,11 @@
> explain select * from t2 where a in (select b from t1 where a=3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 range a a 5 NULL 8 Using where; Using index; LooseScan
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
> drop table t1,t2;
> create table t1 (a int, b int);
> insert into t1 select a,a from t0;
> @@ -1303,7 +1303,7 @@
> explain select * from t0 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 2
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
> select * from t0 where a in (select a from t1);
> a
> 10.24
> @@ -1316,7 +1316,7 @@
> explain select * from t0 where a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 2
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
> select * from t0 where a in (select a from t1);
> a
> 2008-01-01
> @@ -1332,8 +1332,8 @@
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 3
> 1 PRIMARY subselect2 eq_ref unique_key unique_key 15 func 1
> 2 SUBQUERY X ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer
> -2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer
> +2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
> +2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer (incremental, BNL join)
> drop table t0,t1,t2;
>
> BUG#37842: Assertion in DsMrr_impl::dsmrr_init, at handler.cc:4307
> @@ -1404,9 +1404,9 @@
> );
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2 1.00
> -1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer
> +1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
> 2 SUBQUERY cona ALL NULL NULL NULL NULL 2 100.00 Using where
> -2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using join buffer
> +2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using join buffer (flat, BKA join)
> Warnings:
> Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where ((`test`.`c`.`idContact` = `test`.`cona`.`idContact`) and (`test`.`a`.`idIndividual` = `test`.`c`.`idObj`) and (`test`.`cona`.`postalStripped` = 'T2H3B2'))
> drop table t1,t2,t3;
>
> === modified file 'mysql-test/r/subselect4.result'
> --- a/mysql-test/r/subselect4.result 2010-06-26 10:05:41 +0000
> +++ b/mysql-test/r/subselect4.result 2010-10-08 19:30:16 +0000
> @@ -51,7 +51,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
> 2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2 Using index
> -2 DEPENDENT SUBQUERY t2 index b b 5 NULL 2 Using where; Using index; Using join buffer
> +2 DEPENDENT SUBQUERY t2 index b b 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
> # should return 0 rows
> SELECT
> (SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
> @@ -218,7 +218,7 @@
> 1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
> 1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
> FROM t1
> WHERE EMPNUM IN
> @@ -233,13 +233,13 @@
> 1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
> 1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> EXECUTE stmt;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
> 1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> DEALLOCATE PREPARE stmt;
> DROP INDEX t1_IDX ON t1;
> CREATE INDEX t1_IDX ON t1(EMPNUM);
> @@ -256,7 +256,7 @@
> 1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
> 1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
> FROM t1
> WHERE EMPNUM IN
> @@ -271,13 +271,13 @@
> 1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
> 1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> EXECUTE stmt;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
> 1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> DEALLOCATE PREPARE stmt;
> DROP INDEX t1_IDX ON t1;
> EXPLAIN SELECT EMPNAME
> @@ -293,7 +293,7 @@
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 5
> 1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
> FROM t1
> WHERE EMPNUM IN
> @@ -308,13 +308,13 @@
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 5
> 1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> EXECUTE stmt;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 5
> 1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
> -2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> DEALLOCATE PREPARE stmt;
> SET SESSION optimizer_switch = @old_optimizer_switch;
> SET SESSION join_cache_level = @old_join_cache_level;
>
> === modified file 'mysql-test/r/subselect_mat.result'
> --- a/mysql-test/r/subselect_mat.result 2010-07-16 11:02:15 +0000
> +++ b/mysql-test/r/subselect_mat.result 2010-10-08 19:30:16 +0000
> @@ -423,7 +423,7 @@
> a1 = c1;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
> 4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
> 5 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
> 2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
> @@ -659,7 +659,7 @@
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
> 2 DEPENDENT SUBQUERY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
> 3 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
> -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer
> +3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
> 4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
> Warnings:
> Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select 1 from `test`.`t1_16` where (<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` join `test`.`t2` where ((`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and <in_optimizer>(`test`.`t2`.`b1`,`test`.`t2`.`b1` in ( <materialize> (select `test`.`t3`.`c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0') ), <primary_index_lookup>(`test`.`t2`.`b1` in <temporary table> on distinct_key where ((`test`.`t2`.`b1` = `materialized subselect`.`c1`))))) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))) and (<cache>(concat(`test`.`t1`.`a1`,'x')) = left(`test`.`t1_16`.`a1`,8)))))
> @@ -1191,7 +1191,7 @@
> EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> 2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
> SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
> COUNT(*)
>
> === modified file 'mysql-test/r/subselect_no_mat.result'
> --- a/mysql-test/r/subselect_no_mat.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/subselect_no_mat.result 2010-10-08 19:30:16 +0000
> @@ -910,7 +910,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
> 2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using index
> -2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
> drop table t1,t2,t3;
> @@ -1300,7 +1300,7 @@
> explain extended select * from t2 where t2.a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
> -1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer
> +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)
> select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
> @@ -1310,7 +1310,7 @@
> explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
> -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer
> +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
> select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
> @@ -1320,7 +1320,7 @@
> explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
> -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer
> +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
> 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
>
> === modified file 'mysql-test/r/subselect_no_opts.result'
> --- a/mysql-test/r/subselect_no_opts.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/subselect_no_opts.result 2010-10-08 19:30:16 +0000
> @@ -907,7 +907,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
> 2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using index
> -2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
> drop table t1,t2,t3;
> @@ -1361,7 +1361,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
> 2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 100.00 Using index
> -2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 100.00 Using where; Using index; Using join buffer
> +2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
> insert into t1 values (3,31);
>
> === modified file 'mysql-test/r/subselect_no_semijoin.result'
> --- a/mysql-test/r/subselect_no_semijoin.result 2010-07-16 08:58:24 +0000
> +++ b/mysql-test/r/subselect_no_semijoin.result 2010-10-08 19:30:16 +0000
> @@ -907,7 +907,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
> 2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using index
> -2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
> drop table t1,t2,t3;
> @@ -1318,7 +1318,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
> 2 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using index
> -2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer
> +2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`)))))
> drop table t1, t2, t3;
> @@ -1361,7 +1361,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
> 2 SUBQUERY t3 index a a 5 NULL 3 100.00 Using index
> -2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index; Using join buffer
> +2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`)))))
> insert into t1 values (3,31);
>
> === modified file 'mysql-test/r/subselect_sj.result'
> --- a/mysql-test/r/subselect_sj.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/subselect_sj.result 2010-10-08 19:30:16 +0000
> @@ -101,75 +101,75 @@
> );
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY s00 ALL NULL NULL NULL NULL 3 Using where
> -1 PRIMARY s01 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s02 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s03 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s04 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s05 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s06 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s07 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s08 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s09 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s10 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s11 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s12 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s13 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s14 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s15 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s16 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s17 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s18 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s19 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s20 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s21 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s22 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s23 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s24 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s25 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s26 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s27 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s28 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s29 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s30 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s31 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s32 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s33 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s34 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s35 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s36 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s37 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s38 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s39 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s40 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s41 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s42 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s43 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s44 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s45 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s46 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s47 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s48 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s49 ALL NULL NULL NULL NULL 3 Using join buffer
> +1 PRIMARY s01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s02 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s03 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s04 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s05 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s06 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s07 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s08 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s09 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s10 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s11 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s12 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s13 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s14 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s15 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s16 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s17 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s18 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s19 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s20 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s21 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s22 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s23 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s24 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s25 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s26 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s27 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s28 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s29 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s30 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s31 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s32 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s33 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s34 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s35 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s36 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s37 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s38 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s39 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s40 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s41 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s42 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s43 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s44 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s45 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s46 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s47 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s48 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s49 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> 2 DEPENDENT SUBQUERY m00 ALL NULL NULL NULL NULL 3 Using where
> -2 DEPENDENT SUBQUERY m01 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m02 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m03 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m04 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m05 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m06 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m07 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m08 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m09 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m10 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m11 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m12 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m13 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m14 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m15 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m16 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m17 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m18 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m19 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY m01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m02 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m03 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m04 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m05 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m06 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m07 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m08 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m09 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m10 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m11 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m12 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m13 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m14 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m15 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m16 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m17 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m18 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m19 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> select * from
> t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
> where t1.a < 5;
> @@ -195,7 +195,7 @@
> explain extended select * from t1 where a in (select pk from t10 where pk<3);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t10 range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer (flat, BNL join)
> 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))
> drop table t0, t1, t2;
> @@ -738,7 +738,7 @@
> FROM it1 LEFT JOIN it2 ON it2.datetime_key);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY it1 index NULL int_key 4 NULL 2 Using index; Start temporary
> -1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using join buffer
> +1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
> 1 PRIMARY it2 ALL NULL NULL NULL NULL 20 Using where; End temporary
> DROP TABLE ot1, it1, it2;
> # End of BUG#38075
> @@ -770,7 +770,7 @@
> where a in (select c from t2 where d >= some(select e from t3 where b=e));
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Start temporary
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where; End temporary; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
> 3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
> Warnings:
> Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
>
> === modified file 'mysql-test/r/subselect_sj2.result'
> --- a/mysql-test/r/subselect_sj2.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/subselect_sj2.result 2010-10-08 19:30:16 +0000
> @@ -130,7 +130,7 @@
> from t1 ot where a in (select a from t2 it);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
> -1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer
> +1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer (flat, BNL join)
> 2 SUBQUERY it ALL NULL NULL NULL NULL 22
> select
> a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
> @@ -198,7 +198,7 @@
> from t1 ot where a in (select a from t2 it);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
> -1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer
> +1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer (flat, BNL join)
> 2 SUBQUERY it ALL NULL NULL NULL NULL 22
> select
> a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
> @@ -272,7 +272,7 @@
> (select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Start temporary
> -1 PRIMARY t1 index NULL a 5 NULL 10 Using index; Using join buffer
> +1 PRIMARY t1 index NULL a 5 NULL 10 Using index; Using join buffer (flat, BNL join)
> 1 PRIMARY t2 ref a a 5 test.t1.a 1 Using where; Using index
> 1 PRIMARY t3 ref a a 5 test.t1.a 1 Using where; Using index; End temporary
> drop table t0, t1,t2,t3;
>
> === modified file 'mysql-test/r/subselect_sj2_jcl6.result'
> --- a/mysql-test/r/subselect_sj2_jcl6.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/subselect_sj2_jcl6.result 2010-10-08 19:30:16 +0000
> @@ -40,7 +40,7 @@
> explain select * from t2 where b in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 3
> -1 PRIMARY t2 ref b b 5 test.t1.a 2 Using join buffer
> +1 PRIMARY t2 ref b b 5 test.t1.a 2 Using join buffer (flat, BKA join)
> 2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
> select * from t2 where b in (select a from t1);
> a b
> @@ -59,7 +59,7 @@
> explain select * from t3 where b in (select a from t1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t3 ALL b NULL NULL NULL 10
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t3); Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t3); Using join buffer (flat, BNL join)
> select * from t3 where b in (select a from t1);
> a b pk1 pk2 pk3
> 1 1 1 1 1
> @@ -82,7 +82,7 @@
> explain select * from t3 where b in (select a from t0);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
> -1 PRIMARY t3 ref b b 5 test.t0.a 1 Using join buffer
> +1 PRIMARY t3 ref b b 5 test.t0.a 1 Using join buffer (flat, BKA join)
> 2 SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
> set @save_ecp= @@engine_condition_pushdown;
> set engine_condition_pushdown=0;
> @@ -137,7 +137,7 @@
> from t1 ot where a in (select a from t2 it);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
> -1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer
> +1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer (flat, BNL join)
> 2 SUBQUERY it ALL NULL NULL NULL NULL 22
> select
> a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
> @@ -205,7 +205,7 @@
> from t1 ot where a in (select a from t2 it);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
> -1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer
> +1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer (flat, BNL join)
> 2 SUBQUERY it ALL NULL NULL NULL NULL 22
> select
> a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
> @@ -279,7 +279,7 @@
> (select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Start temporary
> -1 PRIMARY t1 index NULL a 5 NULL 10 Using index; Using join buffer
> +1 PRIMARY t1 index NULL a 5 NULL 10 Using index; Using join buffer (flat, BNL join)
> 1 PRIMARY t2 ref a a 5 test.t1.a 1 Using where; Using index
> 1 PRIMARY t3 ref a a 5 test.t1.a 1 Using where; Using index; End temporary
> drop table t0, t1,t2,t3;
> @@ -318,8 +318,8 @@
> t2.Population > 100000);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Using MRR
> -1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; Using join buffer
> -1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t3.Country 1 Using index condition(BKA); Using where; Using join buffer
> +1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; Using join buffer (flat, BKA join)
> +1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t3.Country 1 Using index condition(BKA); Using where; Using join buffer (incremental, BKA join)
> DROP TABLE t1,t2,t3;
> CREATE TABLE t1 (
> Code char(3) NOT NULL DEFAULT '',
> @@ -433,8 +433,8 @@
> t1.b=t2.b);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary
> -1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Using join buffer
> -1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00 Using where; End temporary; Using join buffer
> +1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Using join buffer (flat, BKA join)
> +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00 Using where; End temporary; Using join buffer (incremental, BKA join)
> Warnings:
> Note 1276 Field or reference 'test.t0.a' of SELECT #2 was resolved in SELECT #1
> Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t2`.`a` = `test`.`t0`.`a`))
> @@ -587,7 +587,7 @@
> select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 3
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> 2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY PRIMARY 4 func 1 Using index
> drop table t0, t1, t2, t3;
> create table t1 (a int);
> @@ -728,9 +728,9 @@
> c1 in (select convert(c6,char(1)) from t2);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch(t2); Using join buffer
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch(t2); Using join buffer (incremental, BNL join)
> drop table t2, t3;
> set join_cache_level=default;
> show variables like 'join_cache_level';
>
> === modified file 'mysql-test/r/subselect_sj_jcl6.result'
> --- a/mysql-test/r/subselect_sj_jcl6.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/subselect_sj_jcl6.result 2010-10-08 19:30:16 +0000
> @@ -59,7 +59,7 @@
> explain select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
> -1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer
> +1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (flat, BKA join)
> 1 PRIMARY t12 eq_ref PRIMARY PRIMARY 4 test.t10.a 1 Using index
> select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
> a b
> @@ -70,7 +70,7 @@
> explain extended select * from t1 where a in (select t10.pk from t10, t12 where t12.pk=t10.a);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using where; Using join buffer
> +1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using where; Using join buffer (flat, BKA join)
> 1 PRIMARY t12 eq_ref PRIMARY PRIMARY 4 test.t10.a 1 100.00 Using index
> Warnings:
> Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where ((`test`.`t10`.`pk` = `test`.`t1`.`a`) and (`test`.`t12`.`pk` = `test`.`t10`.`a`))
> @@ -79,8 +79,8 @@
> select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
> id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
> -1 PRIMARY A ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer
> -1 PRIMARY B ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer
> +1 PRIMARY A ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (flAt, BNL join)
> +1 PRIMARY B ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (incrementAl, BNL join)
> 2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index
> Warnings:
> Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
> @@ -89,7 +89,7 @@
> select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
> id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (flAt, BNL join)
> 2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index
> Warnings:
> Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
> @@ -108,75 +108,75 @@
> );
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY s00 ALL NULL NULL NULL NULL 3 Using where
> -1 PRIMARY s01 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s02 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s03 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s04 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s05 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s06 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s07 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s08 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s09 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s10 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s11 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s12 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s13 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s14 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s15 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s16 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s17 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s18 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s19 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s20 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s21 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s22 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s23 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s24 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s25 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s26 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s27 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s28 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s29 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s30 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s31 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s32 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s33 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s34 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s35 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s36 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s37 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s38 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s39 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s40 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s41 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s42 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s43 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s44 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s45 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s46 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s47 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s48 ALL NULL NULL NULL NULL 3 Using join buffer
> -1 PRIMARY s49 ALL NULL NULL NULL NULL 3 Using join buffer
> +1 PRIMARY s01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +1 PRIMARY s02 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s03 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s04 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s05 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s06 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s07 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s08 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s09 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s10 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s11 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s12 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s13 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s14 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s15 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s16 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s17 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s18 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s19 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s20 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s21 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s22 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s23 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s24 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s25 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s26 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s27 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s28 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s29 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s30 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s31 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s32 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s33 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s34 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s35 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s36 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s37 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s38 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s39 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s40 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s41 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s42 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s43 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s44 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s45 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s46 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s47 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s48 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +1 PRIMARY s49 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> 2 DEPENDENT SUBQUERY m00 ALL NULL NULL NULL NULL 3 Using where
> -2 DEPENDENT SUBQUERY m01 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m02 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m03 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m04 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m05 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m06 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m07 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m08 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m09 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m10 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m11 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m12 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m13 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m14 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m15 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m16 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m17 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m18 ALL NULL NULL NULL NULL 3 Using join buffer
> -2 DEPENDENT SUBQUERY m19 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY m01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> +2 DEPENDENT SUBQUERY m02 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m03 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m04 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m05 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m06 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m07 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m08 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m09 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m10 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m11 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m12 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m13 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m14 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m15 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m16 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m17 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m18 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join)
> +2 DEPENDENT SUBQUERY m19 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join)
> select * from
> t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
> where t1.a < 5;
> @@ -202,7 +202,7 @@
> explain extended select * from t1 where a in (select pk from t10 where pk<3);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t10 range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 103 100.00 Using where; Using join buffer (flat, BNL join)
> 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))
> drop table t0, t1, t2;
> @@ -340,8 +340,8 @@
> (SELECT PNUM FROM PROJ));
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY STAFF ALL NULL NULL NULL NULL 5
> -1 PRIMARY PROJ ALL NULL NULL NULL NULL 6 Using join buffer
> -1 PRIMARY WORKS ALL NULL NULL NULL NULL 12 Using where; FirstMatch(STAFF); Using join buffer
> +1 PRIMARY PROJ ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
> +1 PRIMARY WORKS ALL NULL NULL NULL NULL 12 Using where; FirstMatch(STAFF); Using join buffer (incremental, BNL join)
> SELECT EMPNUM, EMPNAME
> FROM STAFF
> WHERE EMPNUM IN
> @@ -515,7 +515,7 @@
> (SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t0 ALL PRIMARY NULL NULL NULL 5 100.00
> -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t0.pk 1 100.00 Using where; Using join buffer
> +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t0.pk 1 100.00 Using where; Using join buffer (flat, BKA join)
> 1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 2 100.00 Using index; FirstMatch(t1)
> Warnings:
> Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where ((`test`.`t2`.`vkey` = `test`.`t1`.`vnokey`) and (`test`.`t1`.`pk` = `test`.`t0`.`pk`))
> @@ -745,8 +745,8 @@
> FROM it1 LEFT JOIN it2 ON it2.datetime_key);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY it1 index NULL int_key 4 NULL 2 Using index; Start temporary
> -1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using join buffer
> -1 PRIMARY it2 ALL NULL NULL NULL NULL 20 Using where; End temporary; Using join buffer
> +1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
> +1 PRIMARY it2 ALL NULL NULL NULL NULL 20 Using where; End temporary; Using join buffer (incremental, BNL join)
> DROP TABLE ot1, it1, it2;
> # End of BUG#38075
> #
> @@ -777,7 +777,7 @@
> where a in (select c from t2 where d >= some(select e from t3 where b=e));
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Start temporary
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where; End temporary; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
> 3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
> Warnings:
> Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
> @@ -828,7 +828,7 @@
> EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer
> +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`c` = `test`.`t1`.`c`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
> SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
> @@ -838,7 +838,7 @@
> EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer
> +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`d` = `test`.`t1`.`d`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
> SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
> @@ -847,7 +847,7 @@
> EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer
> +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`e` = `test`.`t1`.`e`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
> SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
> @@ -857,7 +857,7 @@
> EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer
> +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`f` = `test`.`t1`.`f`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
> SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
> @@ -867,7 +867,7 @@
> EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer
> +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`g` = `test`.`t1`.`g`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
> SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
> @@ -877,7 +877,7 @@
> EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer
> +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`h` = `test`.`t1`.`h`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
> SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
> @@ -887,7 +887,7 @@
> EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer
> +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`i` = `test`.`t1`.`i`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
> SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
> @@ -897,7 +897,7 @@
> EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer
> +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`j` = `test`.`t1`.`j`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
> SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
> @@ -907,7 +907,7 @@
> EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
> -1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer
> +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Using MRR; FirstMatch(t1); Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`k` = `test`.`t1`.`k`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
> SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
> @@ -1069,8 +1069,8 @@
> WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1 ALL NULL NULL NULL NULL 5
> -1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; FirstMatch(t1); Using join buffer
> -1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t3); Using join buffer
> +1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
> +1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t3); Using join buffer (incremental, BNL join)
> SELECT *
> FROM t1
> WHERE t1.val IN (SELECT t2.val FROM t2
> @@ -1104,8 +1104,8 @@
> (SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t0 ALL NULL NULL NULL NULL 5 Using where; Start temporary
> -1 PRIMARY t1 ref a a 5 test.t0.a 1 Using join buffer
> -1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using where; End temporary; Using join buffer
> +1 PRIMARY t1 ref a a 5 test.t0.a 1 Using join buffer (flat, BKA join)
> +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using where; End temporary; Using join buffer (incremental, BKA join)
> SELECT * FROM t0 WHERE t0.a IN
> (SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
> a
>
> === modified file 'mysql-test/r/union.result'
> --- a/mysql-test/r/union.result 2010-06-26 10:05:41 +0000
> +++ b/mysql-test/r/union.result 2010-10-08 19:30:16 +0000
> @@ -542,7 +542,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
> 2 UNION t1 index PRIMARY PRIMARY 4 NULL 4 Using index
> -2 UNION t2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index; Using join buffer
> +2 UNION t2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index; Using join buffer (flat, BNL join)
> NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
> explain (select * from t1 where a=1) union (select * from t1 where b=1);
> id select_type table type possible_keys key key_len ref rows Extra
>
> === modified file 'mysql-test/r/view.result'
> --- a/mysql-test/r/view.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/r/view.result 2010-10-08 19:30:16 +0000
> @@ -2350,7 +2350,7 @@
> EXPLAIN SELECT * FROM v2 WHERE a=1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref a a 5 const 1 Using index
> -1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> DROP VIEW v1,v2;
> DROP TABLE t1,t2,t3;
> create table t1 (f1 int);
>
> === modified file 'mysql-test/suite/pbxt/r/derived.result'
> --- a/mysql-test/suite/pbxt/r/derived.result 2009-04-02 10:03:14 +0000
> +++ b/mysql-test/suite/pbxt/r/derived.result 2010-10-08 19:30:16 +0000
> @@ -58,7 +58,7 @@
> explain select * from t1 as x1, (select * from t1) as x2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY x1 ALL NULL NULL NULL NULL 4
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
> 2 DERIVED t1 ALL NULL NULL NULL NULL 4
> drop table if exists t2,t3;
> select * from (select 1) as a;
> @@ -115,7 +115,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY <derived2> system NULL NULL NULL NULL 1
> 2 DERIVED t2 ALL NULL NULL NULL NULL 1
> -2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer
> +2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> drop table t1, t2;
> create table t1(a int not null, t char(8), index(a));
> SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
> @@ -143,7 +143,7 @@
> explain select count(*) from t1 as tt1, (select * from t1) as tt2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY tt1 index NULL a 4 NULL 10000 Using index
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 Using join buffer
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 Using join buffer (flat, BNL join)
> 2 DERIVED t1 ALL NULL NULL NULL NULL 10000
> drop table t1;
> SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
> @@ -190,13 +190,13 @@
> explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY m2 ALL NULL NULL NULL NULL 9
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
> 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
> explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY m2 ALL NULL NULL NULL NULL 9
> -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
> 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
> drop table t1,t2;
> @@ -250,7 +250,7 @@
> explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
> -1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer
> +1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
> 4 DERIVED t1 ALL NULL NULL NULL NULL 2
> 5 UNION t1 ALL NULL NULL NULL NULL 2
> NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
> @@ -317,7 +317,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
> 2 DERIVED x ALL NULL NULL NULL NULL 17 Using temporary; Using filesort
> -2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer
> +2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer (flat, BNL join)
> drop table t1;
> create table t2 (a int, b int, primary key (a));
> insert into t2 values (1,7),(2,7);
>
> === modified file 'mysql-test/suite/pbxt/r/distinct.result'
> --- a/mysql-test/suite/pbxt/r/distinct.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/suite/pbxt/r/distinct.result 2010-10-08 19:30:16 +0000
> @@ -300,11 +300,11 @@
> AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 index id id 4 NULL 2 Using index; Using temporary
> -1 SIMPLE t2 index id id 8 NULL 1 Using index; Distinct; Using join buffer
> -1 SIMPLE t3 index id id 8 NULL 1 Using index; Distinct; Using join buffer
> -1 SIMPLE j_lj_t2 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer
> +1 SIMPLE t2 index id id 8 NULL 1 Using index; Distinct; Using join buffer (flat, BNL join)
> +1 SIMPLE t3 index id id 8 NULL 1 Using index; Distinct; Using join buffer (flat, BNL join)
> +1 SIMPLE j_lj_t2 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
> 1 SIMPLE t2_lj ref id id 4 test.j_lj_t2.id 1 Using where; Using index; Distinct
> -1 SIMPLE j_lj_t3 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer
> +1 SIMPLE j_lj_t3 index id id 4 NULL 2 Using where; Using index; Distinct; Using join buffer (flat, BNL join)
> 1 SIMPLE t3_lj ref id id 4 test.j_lj_t3.id 1 Using where; Using index; Distinct
> SELECT DISTINCT
> t1.id
> @@ -515,7 +515,7 @@
> EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1_1 ALL NULL NULL NULL NULL 3 Using temporary
> -1 SIMPLE t1_2 index NULL PRIMARY 4 NULL 3 Using index; Distinct; Using join buffer
> +1 SIMPLE t1_2 index NULL PRIMARY 4 NULL 3 Using index; Distinct; Using join buffer (flat, BNL join)
> EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2
> WHERE t1_1.a = t1_2.a;
> id select_type table type possible_keys key key_len ref rows Extra
>
> === modified file 'mysql-test/suite/pbxt/r/func_group.result'
> --- a/mysql-test/suite/pbxt/r/func_group.result 2010-01-16 05:12:57 +0000
> +++ b/mysql-test/suite/pbxt/r/func_group.result 2010-10-08 19:30:16 +0000
> @@ -614,7 +614,7 @@
> select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'MIN' and t2.a3 > 'CA';
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 range k1 k1 7 NULL 1 Using where; Using index
> -1 SIMPLE t2 range k1 k1 3 NULL 1 Using where; Using index; Using join buffer
> +1 SIMPLE t2 range k1 k1 3 NULL 1 Using where; Using index; Using join buffer (flat, BNL join)
> explain
> select min(a4 - 0.01) from t1;
> id select_type table type possible_keys key key_len ref rows Extra
> @@ -651,7 +651,7 @@
> select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME';
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index k2 k2 4 NULL 7 Using where; Using index
> -1 SIMPLE t1 index NULL PRIMARY 3 NULL 15 Using index; Using join buffer
> +1 SIMPLE t1 index NULL PRIMARY 3 NULL 15 Using index; Using join buffer (flat, BNL join)
> drop table t1, t2;
> create table t1 (a char(10));
> insert into t1 values ('a'),('b'),('c');
>
> === modified file 'mysql-test/suite/pbxt/r/greedy_optimizer.result'
> --- a/mysql-test/suite/pbxt/r/greedy_optimizer.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/suite/pbxt/r/greedy_optimizer.result 2010-10-08 19:30:16 +0000
> @@ -121,11 +121,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -133,11 +133,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -145,11 +145,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -157,11 +157,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -169,11 +169,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -181,11 +181,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -201,11 +201,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -213,11 +213,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -225,11 +225,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -237,11 +237,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -249,11 +249,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -261,11 +261,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -277,11 +277,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -289,11 +289,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -304,9 +304,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 795.625316
> @@ -316,9 +316,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 795.625316
> @@ -328,9 +328,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 795.625316
> @@ -340,9 +340,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 795.625316
> @@ -353,11 +353,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -365,11 +365,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -377,11 +377,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -389,11 +389,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -401,11 +401,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -413,11 +413,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -433,11 +433,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -445,11 +445,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -457,11 +457,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -469,11 +469,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -481,11 +481,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -493,11 +493,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -509,11 +509,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -521,11 +521,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -536,9 +536,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 795.625316
> @@ -548,9 +548,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 795.625316
> @@ -560,9 +560,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 795.625316
> @@ -572,9 +572,9 @@
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> show status like 'Last_query_cost';
> Variable_name Value
> Last_query_cost 795.625316
> @@ -585,11 +585,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -597,11 +597,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -609,11 +609,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -621,11 +621,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -633,11 +633,11 @@
> explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
> @@ -645,11 +645,11 @@
> explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
> show status like 'Last_query_cost';
> Variable_name Value
>
> === modified file 'mysql-test/suite/pbxt/r/group_by.result'
> --- a/mysql-test/suite/pbxt/r/group_by.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/suite/pbxt/r/group_by.result 2010-10-08 19:30:16 +0000
> @@ -537,11 +537,11 @@
> explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
> -1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary
> -1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer
> +1 SIMPLE t2 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
> drop table t1,t2;
> create table t1 (a int, b int);
> insert into t1 values (1, 4),(10, 40),(1, 4),(10, 43),(1, 4),(10, 41),(1, 4),(10, 43),(1, 4);
>
> === modified file 'mysql-test/suite/pbxt/r/group_min_max.result'
> --- a/mysql-test/suite/pbxt/r/group_min_max.result 2010-06-26 10:05:41 +0000
> +++ b/mysql-test/suite/pbxt/r/group_min_max.result 2010-10-08 19:30:16 +0000
> @@ -2268,7 +2268,7 @@
> AND t1_outer1.b = t1_outer2.b;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index
> -1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer
> +1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer (flat, BNL join)
> 2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
> EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x
> FROM t1 AS t1_outer) x2 FROM t1 AS t1_outer2;
>
> === modified file 'mysql-test/suite/pbxt/r/join_nested.result'
> --- a/mysql-test/suite/pbxt/r/join_nested.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/suite/pbxt/r/join_nested.result 2010-10-08 19:30:16 +0000
> @@ -229,7 +229,7 @@
> ON t7.b=t8.b AND t6.b < 10;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00
> -1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
> +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
> 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
> Warnings:
> Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10))) where 1
> @@ -544,7 +544,7 @@
> (t2.a >= 4 OR t2.c IS NULL);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
> @@ -639,7 +639,7 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
> @@ -647,7 +647,7 @@
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> SELECT t9.a,t9.b
> @@ -836,7 +836,7 @@
> WHERE t1.a <= 2;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
> Warnings:
> @@ -850,7 +850,7 @@
> ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00
> -1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
> +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 1 100.00 Using where
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
> Warnings:
> @@ -906,7 +906,7 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
> @@ -914,7 +914,7 @@
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> CREATE INDEX idx_b ON t4(b);
> @@ -956,7 +956,7 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where
> @@ -964,7 +964,7 @@
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
> 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
> CREATE INDEX idx_b ON t8(b);
> @@ -1005,7 +1005,7 @@
> (t9.a=1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t0 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3
> 1 SIMPLE t3 ALL NULL NULL NULL NULL 2
> 1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1
> @@ -1013,7 +1013,7 @@
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2
> 1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> ATTENTION: the above EXPLAIN has several competing QEPs with identical
> . costs. To combat the plan change it uses --sorted_result and
> . and --replace tricks
> @@ -1064,7 +1064,7 @@
> 1 SIMPLE t6 ALL NULL NULL NULL NULL 3
> 1 SIMPLE t7 ALL NULL NULL NULL NULL 2
> 1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1
> -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using join buffer
> +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
> ATTENTION: the above EXPLAIN has several competing QEPs with identical
> . costs. To combat the plan change it uses --sorted_result
> . and --replace tricks
>
> === modified file 'mysql-test/suite/pbxt/r/range.result'
> --- a/mysql-test/suite/pbxt/r/range.result 2010-06-26 10:05:41 +0000
> +++ b/mysql-test/suite/pbxt/r/range.result 2010-10-08 19:30:16 +0000
> @@ -222,27 +222,27 @@
> explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
> explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref y y 5 const 1
> -1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer
> +1 SIMPLE t2 range x x 5 NULL 1 Using where; Using join buffer (flat, BNL join)
> explain select count(*) from t1 where x in (1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref x x 5 const 1 Using index
> @@ -422,20 +422,20 @@
> test.t2 analyze status OK
> explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
> id select_type table type possible_keys key key_len ref rows Extra
> -1 SIMPLE t1 range uid_index uid_index 4 NULL 1 Using where
> -1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 1
> +1 SIMPLE t2 range uid_index uid_index 4 NULL 1 Using where
> +1 SIMPLE t1 ref uid_index uid_index 4 test.t2.uid 1
> explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
> id select_type table type possible_keys key key_len ref rows Extra
> -1 SIMPLE t1 range uid_index uid_index 4 NULL 1 Using where
> -1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 1
> +1 SIMPLE t2 range uid_index uid_index 4 NULL 1 Using where
> +1 SIMPLE t1 ref uid_index uid_index 4 test.t2.uid 1
> explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
> id select_type table type possible_keys key key_len ref rows Extra
> -1 SIMPLE t1 range uid_index uid_index 4 NULL 2 Using where
> -1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 1
> +1 SIMPLE t2 range uid_index uid_index 4 NULL 2 Using where
> +1 SIMPLE t1 ref uid_index uid_index 4 test.t2.uid 1
> explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
> id select_type table type possible_keys key key_len ref rows Extra
> -1 SIMPLE t1 range uid_index uid_index 4 NULL 2 Using where
> -1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 1
> +1 SIMPLE t2 range uid_index uid_index 4 NULL 2 Using where
> +1 SIMPLE t1 ref uid_index uid_index 4 test.t2.uid 1
> select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
> id name uid id name uid
> 1001 A 1 1001 A 1
>
> === modified file 'mysql-test/suite/pbxt/r/select.result'
> --- a/mysql-test/suite/pbxt/r/select.result 2010-09-28 19:39:33 +0000
> +++ b/mysql-test/suite/pbxt/r/select.result 2010-10-08 19:30:16 +0000
> @@ -1437,7 +1437,7 @@
> explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Using join buffer (flat, BNL join)
> select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
> fld1 companynr fld3 period
> 038008 37 reporters 1008
> @@ -2723,7 +2723,7 @@
> t2.b like '%%' order by t2.b limit 0,1;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ref b,c b 5 const 1 Using temporary; Using filesort
> -1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer
> +1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer (flat, BNL join)
> 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
> DROP TABLE t1,t2,t3;
> CREATE TABLE t1 (a int, INDEX idx(a));
> @@ -2746,7 +2746,7 @@
> EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index b b 5 NULL 2 Using index
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> a b a b
> 1 NULL 1 1
> @@ -2756,7 +2756,7 @@
> EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 index b b 5 NULL 2 Using index
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
> a b a b
> 1 NULL 1 1
> @@ -2910,11 +2910,11 @@
> EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 5
> -1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
> +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
> EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON t1.a=t2.a;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t2 ALL NULL NULL NULL NULL 3
> -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
> +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> DROP TABLE t1,t2;
> select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
> x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
>
> === modified file 'mysql-test/suite/pbxt/r/subselect.result'
> --- a/mysql-test/suite/pbxt/r/subselect.result 2010-10-02 16:46:27 +0000
> +++ b/mysql-test/suite/pbxt/r/subselect.result 2010-10-08 19:30:16 +0000
> @@ -906,7 +906,7 @@
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
> 2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using index
> -2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
> +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
> drop table t1,t2,t3;
> @@ -1296,7 +1296,7 @@
> explain extended select * from t2 where t2.a in (select a from t1);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
> -1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer
> +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)
> select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
> @@ -1306,7 +1306,7 @@
> explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
> -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer
> +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
> select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
> @@ -1316,7 +1316,7 @@
> explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
> id select_type table type possible_keys key key_len ref rows filtered Extra
> 1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
> -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer
> +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
> 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index
> Warnings:
> Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
> @@ -3554,7 +3554,7 @@
> ORDER BY t1.t DESC LIMIT 1);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t2 ALL NULL NULL NULL NULL 1
> -1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index; Using join buffer
> +1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index; Using join buffer (flat, BNL join)
> 2 DEPENDENT SUBQUERY t1 ref PRIMARY PRIMARY 8 test.t2.i1,const 1 Using where; Using index; Using filesort
> SELECT * FROM t1,t2
> WHERE t1.t = (SELECT t1.t FROM t1
>
> === modified file 'mysql-test/suite/pbxt/r/union.result'
> --- a/mysql-test/suite/pbxt/r/union.result 2009-12-16 09:28:51 +0000
> +++ b/mysql-test/suite/pbxt/r/union.result 2010-10-08 19:30:16 +0000
> @@ -500,7 +500,7 @@
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
> 2 UNION t1 index PRIMARY PRIMARY 4 NULL 4 Using index
> -2 UNION t2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index; Using join buffer
> +2 UNION t2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index; Using join buffer (flat, BNL join)
> NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
> explain (select * from t1 where a=1) union (select * from t1 where b=1);
> id select_type table type possible_keys key key_len ref rows Extra
>
> === modified file 'mysql-test/suite/vcol/r/vcol_misc.result'
> --- a/mysql-test/suite/vcol/r/vcol_misc.result 2010-10-02 16:46:27 +0000
> +++ b/mysql-test/suite/vcol/r/vcol_misc.result 2010-10-08 19:30:16 +0000
> @@ -10,7 +10,7 @@
> select * from t1,t2 where t1.b=t2.c and d <= 100;
> id select_type table type possible_keys key key_len ref rows Extra
> 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
> -1 SIMPLE t2 ref idx idx 5 test.t1.b 2 Using where; Using join buffer
> +1 SIMPLE t2 ref idx idx 5 test.t1.b 2 Using where; Using join buffer (flat, BKA join)
> select * from t1,t2 where t1.b=t2.c and d <= 100;
> a b c d v
> 4 20 20 100 101
>
> === modified file 'mysql-test/suite/vcol/r/vcol_select_innodb.result'
> --- a/mysql-test/suite/vcol/r/vcol_select_innodb.result 2010-06-26 19:33:16 +0000
> +++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result 2010-10-08 19:30:16 +0000
> @@ -64,7 +64,7 @@
> explain select * from t1 where b in (select c from t3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t3 index c c 5 NULL 3 Using index
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> # select_type=PRIMARY, type=range,ref
> select * from t1 where c in (select c from t3 where c between -2 and -1);
> a b c
>
> === modified file 'mysql-test/suite/vcol/r/vcol_select_myisam.result'
> --- a/mysql-test/suite/vcol/r/vcol_select_myisam.result 2010-06-26 19:33:16 +0000
> +++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result 2010-10-08 19:30:16 +0000
> @@ -64,7 +64,7 @@
> explain select * from t1 where b in (select c from t3);
> id select_type table type possible_keys key key_len ref rows Extra
> 1 PRIMARY t3 index c c 5 NULL 3 Using index
> -1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
> +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
> # select_type=PRIMARY, type=range,ref
> select * from t1 where c in (select c from t3 where c between -2 and -1);
> a b c
>
> === modified file 'sql/sql_join_cache.cc'
> --- a/sql/sql_join_cache.cc 2010-10-06 20:27:12 +0000
> +++ b/sql/sql_join_cache.cc 2010-10-08 19:30:16 +0000
> @@ -2372,6 +2372,54 @@
> return rc;
> }
>
> +
> +/*
> + Add a comment on the join algorithm employed by the join cache
> +
> + SYNOPSIS
> + print_explain_comment()
> + str string to add the comment on the employed join algorithm to
> +
> + DESCRIPTION
> + This function adds info on the type of the used join buffer (flat or
> + incremental) and on the type of the the employed join algorithm (BNL,
> + BNLH, BKA or BKAH) to the the end of the sring str.
> +
> + RETURN VALUE
> + none
> +*/
> +
> +void JOIN_CACHE::print_explain_comment(String *str)
> +{
> + str->append(STRING_WITH_LEN(" ("));
> + const char *buffer_type= prev_cache ? "incremental" : "flat";
> + str->append(buffer_type);
> + str->append(STRING_WITH_LEN(", "));
> +
> + const char *join_alg;
> + switch (get_join_alg()) {
> + case BNL_JOIN_ALG:
> + join_alg= "BNL";
> + break;
> + case BNLH_JOIN_ALG:
> + join_alg= "BNLH";
> + break;
> + case BKA_JOIN_ALG:
> + join_alg= "BKA";
> + break;
> + case BKAH_JOIN_ALG:
> + join_alg= "BKAH";
> + break;
> + default:
> + DBUG_ASSERT(0);
> + }
> +
> + str->append(join_alg);
> + str->append(STRING_WITH_LEN(" join"));
> + str->append(STRING_WITH_LEN(")"));
> + }
> +
> +
> /*
> Initialize a hashed join cache
>
>
> === modified file 'sql/sql_select.cc'
> --- a/sql/sql_select.cc 2010-10-06 20:27:12 +0000
> +++ b/sql/sql_select.cc 2010-10-08 19:30:16 +0000
> @@ -7644,9 +7644,8 @@
> case JT_ALL:
> if (cache_level == 1)
> prev_cache= 0;
> - if ((options & SELECT_DESCRIBE) ||
> - (((tab->cache= new JOIN_CACHE_BNL(join, tab, prev_cache))) &&
> - !tab->cache->init()))
> + if ((tab->cache= new JOIN_CACHE_BNL(join, tab, prev_cache)) &&
> + ((options & SELECT_DESCRIBE) || !tab->cache->init()))
> {
> *icp_other_tables_ok= FALSE;
> return (2-test(!prev_cache));
> @@ -7670,9 +7669,8 @@
> {
> if (cache_level == 3)
> prev_cache= 0;
> - if ((options & SELECT_DESCRIBE) ||
> - ((tab->cache= new JOIN_CACHE_BNLH(join, tab, prev_cache)) &&
> - !tab->cache->init()))
> + if ((tab->cache= new JOIN_CACHE_BNLH(join, tab, prev_cache)) &&
> + ((options & SELECT_DESCRIBE) || !tab->cache->init()))
> {
> *icp_other_tables_ok= FALSE;
> return (4-test(!prev_cache));
> @@ -7692,9 +7690,8 @@
> {
> if (cache_level == 5)
> prev_cache= 0;
> - if ((options & SELECT_DESCRIBE) ||
> - ((tab->cache= new JOIN_CACHE_BKA(join, tab, flags, prev_cache)) &&
> - !tab->cache->init()))
> + if ((tab->cache= new JOIN_CACHE_BKA(join, tab, flags, prev_cache)) &&
> + ((options & SELECT_DESCRIBE) || !tab->cache->init()))
> return (6-test(!prev_cache));
> goto no_join_cache;
> }
> @@ -7702,9 +7699,8 @@
> {
> if (cache_level == 7)
> prev_cache= 0;
> - if ((options & SELECT_DESCRIBE) ||
> - ((tab->cache= new JOIN_CACHE_BKAH(join, tab, flags, prev_cache)) &&
> - !tab->cache->init()))
> + if ((tab->cache= new JOIN_CACHE_BKAH(join, tab, flags, prev_cache)) &&
> + ((options & SELECT_DESCRIBE) || !tab->cache->init()))
> {
> *idx_cond_fact_out= FALSE;
> return (8-test(!prev_cache));
> @@ -18923,8 +18919,11 @@
> }
> }
>
> - if (i > 0 && tab[-1].next_select == sub_select_cache)
> + if (tab->cache)
> + {
> extra.append(STRING_WITH_LEN("; Using join buffer"));
> + tab->cache->print_explain_comment(&extra);
> + }
>
> /* Skip initial "; "*/
> const char *str= extra.ptr();
>
> === modified file 'sql/sql_select.h'
> --- a/sql/sql_select.h 2010-10-06 20:27:12 +0000
> +++ b/sql/sql_select.h 2010-10-08 19:30:16 +0000
> @@ -885,7 +885,50 @@
> /* Check matching to a partial join record from the join buffer */
> bool check_match(uchar *rec_ptr);
>
> + /*
> + This constructor creates an unlinked join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter.
> + */
> + JOIN_CACHE(JOIN *j, JOIN_TAB *tab)
> + {
> + join= j;
> + join_tab= tab;
> + prev_cache= next_cache= 0;
> + buff= 0;
> + }
> +
> + /*
> + This constructor creates a linked join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter. The parameter 'prev' specifies the previous
> + cache object to which this cache is linked.
> + */
> + JOIN_CACHE(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> + {
> + join= j;
> + join_tab= tab;
> + next_cache= 0;
> + prev_cache= prev;
> + buff= 0;
> + if (prev)
> + prev->next_cache= this;
> + }
> +
> public:
> +
> + /*
> + The enumeration type Join_algorithm includes a mnemonic constant for
> + each join algorithm that employs join buffers
> + */
> +
> + enum Join_algorithm
> + {
> + BNL_JOIN_ALG, /* Block Nested Loop Join algorithm */
> + BNLH_JOIN_ALG, /* Block Nested Loop Hash Join algorithm */
> + BKA_JOIN_ALG, /* Batched Key Access Join algorithm */
> + BKAH_JOIN_ALG, /* Batched Key Access with Hash Table Join Algorithm */
> + };
>
> /*
> The enumeration type Match_flag describes possible states of the match flag
> @@ -926,6 +969,9 @@
> /* Shrink the size if the cache join buffer in a given ratio */
> bool shrink_join_buffer_in_ratio(ulonglong n, ulonglong d);
>
> + /* Shall return the type of the employed join algorithm */
> + virtual enum Join_algorithm get_join_alg()= 0;
> +
> /*
> The function shall return TRUE only when there is a key access
> to the join table
> @@ -971,6 +1017,9 @@
> /* Join records from the join buffer with records from the next join table */
> enum_nested_loop_state join_records(bool skip_last);
>
> + /* Add a comment on the join algorithm employed by the join cache */
> + void print_explain_comment(String *str);
> +
> virtual ~JOIN_CACHE() {}
> void reset_join(JOIN *j) { join= j; }
> void free()
> @@ -1241,6 +1290,22 @@
> /* Reallocate the join buffer of a hashed join cache */
> int realloc_buffer();
>
> + /*
> + This constructor creates an unlinked hashed join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter.
> + */
> + JOIN_CACHE_HASHED(JOIN *j, JOIN_TAB *tab) :JOIN_CACHE(j, tab) {}
> +
> + /*
> + This constructor creates a linked hashed join cache. The cache is to be
> + used to join table 'tab' to the result of joining the previous tables
> + specified by the 'j' parameter. The parameter 'prev' specifies the previous
> + cache object to which this cache is linked.
> + */
> + JOIN_CACHE_HASHED(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> + :JOIN_CACHE(j, tab, prev) {}
> +
> public:
>
> /* Initialize a hashed join cache */
> @@ -1368,12 +1433,7 @@
> used to join table 'tab' to the result of joining the previous tables
> specified by the 'j' parameter.
> */
> - JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab)
> - {
> - join= j;
> - join_tab= tab;
> - prev_cache= next_cache= 0;
> - }
> + JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab) :JOIN_CACHE(j, tab) {}
>
> /*
> This constructor creates a linked BNL join cache. The cache is to be
> @@ -1381,19 +1441,14 @@
> specified by the 'j' parameter. The parameter 'prev' specifies the previous
> cache object to which this cache is linked.
> */
> - JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> - {
> - join= j;
> - join_tab= tab;
> - prev_cache= prev;
> - next_cache= 0;
> - if (prev)
> - prev->next_cache= this;
> - }
> + JOIN_CACHE_BNL(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> + :JOIN_CACHE(j, tab, prev) {}
>
> /* Initialize the BNL cache */
> int init();
>
> + enum Join_algorithm get_join_alg() { return BNL_JOIN_ALG; }
> +
> bool is_key_access() { return FALSE; }
>
> };
> @@ -1445,12 +1500,7 @@
> used to join table 'tab' to the result of joining the previous tables
> specified by the 'j' parameter.
> */
> - JOIN_CACHE_BNLH(JOIN *j, JOIN_TAB *tab)
> - {
> - join= j;
> - join_tab= tab;
> - prev_cache= next_cache= 0;
> - }
> + JOIN_CACHE_BNLH(JOIN *j, JOIN_TAB *tab) : JOIN_CACHE_HASHED(j, tab) {}
>
> /*
> This constructor creates a linked BNLH join cache. The cache is to be
> @@ -1458,19 +1508,14 @@
> specified by the 'j' parameter. The parameter 'prev' specifies the previous
> cache object to which this cache is linked.
> */
> - JOIN_CACHE_BNLH(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> - {
> - join= j;
> - join_tab= tab;
> - prev_cache= prev;
> - next_cache= 0;
> - if (prev)
> - prev->next_cache= this;
> - }
> + JOIN_CACHE_BNLH(JOIN *j, JOIN_TAB *tab, JOIN_CACHE *prev)
> + : JOIN_CACHE_HASHED(j, tab, prev) {}
>
> /* Initialize the BNLH cache */
> int init();
>
> + enum Join_algorithm get_join_alg() { return BNLH_JOIN_ALG; }
> +
> bool is_key_access() { return TRUE; }
>
> };
> @@ -1583,13 +1628,7 @@
> The MRR mode initially is set to 'flags'.
> */
> JOIN_CACHE_BKA(JOIN *j, JOIN_TAB *tab, uint flags)
> - {
> - join= j;
> - join_tab= tab;
> - prev_cache= next_cache= 0;
> - mrr_mode= flags;
> - }
> -
> + :JOIN_CACHE(j, tab), mrr_mode(flags) {}
> /*
> This constructor creates a linked BKA join cache. The cache is to be
> used to join table 'tab' to the result of joining the previous tables
> @@ -1598,21 +1637,15 @@
> The MRR mode initially is set to 'flags'.
> */
> JOIN_CACHE_BKA(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE *prev)
> - {
> - join= j;
> - join_tab= tab;
> - prev_cache= prev;
> - next_cache= 0;
> - if (prev)
> - prev->next_cache= this;
> - mrr_mode= flags;
> - }
> + :JOIN_CACHE(j, tab, prev), mrr_mode(flags) {}
>
> uchar **get_curr_association_ptr() { return &curr_association; }
>
> /* Initialize the BKA cache */
> int init();
>
> + enum Join_algorithm get_join_alg() { return BKA_JOIN_ALG; }
> +
> bool is_key_access() { return TRUE; }
>
> /* Get the key built over the next record from the join buffer */
> @@ -1688,10 +1721,8 @@
> specified by the 'j' parameter.
> The MRR mode initially is set to 'flags'.
> */
> - JOIN_CACHE_BKAH(JOIN *j, JOIN_TAB *tab, uint flags) :JOIN_CACHE_BNLH(j, tab)
> - {
> - mrr_mode= flags;
> - }
> + JOIN_CACHE_BKAH(JOIN *j, JOIN_TAB *tab, uint flags)
> + :JOIN_CACHE_BNLH(j, tab), mrr_mode(flags) {}
>
> /*
> This constructor creates a linked BKAH join cache. The cache is to be
> @@ -1701,16 +1732,15 @@
> The MRR mode initially is set to 'flags'.
> */
> JOIN_CACHE_BKAH(JOIN *j, JOIN_TAB *tab, uint flags, JOIN_CACHE *prev)
> - :JOIN_CACHE_BNLH(j, tab, prev)
> - {
> - mrr_mode= flags;
> - }
> + :JOIN_CACHE_BNLH(j, tab, prev), mrr_mode(flags) {}
>
> uchar **get_curr_association_ptr() { return &curr_matching_chain; }
>
> /* Initialize the BKAH cache */
> int init();
>
> + enum Join_algorithm get_join_alg() { return BKAH_JOIN_ALG; }
> +
> /* Check index condition of the joined table for a record from BKAH cache */
> bool skip_index_tuple(char *range_info);
> };
>
> _______________________________________________
> commits mailing list
> commits(a)mariadb.org
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
--
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
0

[Maria-developers] Discussion on more unified development of MySQL(MariaDB) code base (Re: Live Schema Changes)
by Henrik Ingo 15 Oct '10
by Henrik Ingo 15 Oct '10
15 Oct '10
> On Fri, Sep 24, 2010 at 12:51 AM, Kristian Nielsen
> <knielsen(a)knielsen-hq.org> wrote:
>> MARK CALLAGHAN <mdcallag(a)gmail.com> writes:
>>
>>> Define "properly"? I suspect you mean that you want us to spend the
>>> time to get our changes into MariaDB.
>>
>> No, that is not what I meant. I meant write code, tests, etc. like what you
>> and I want to see in the MySQL source. You have often voiced opinions on
>> quality of code, tests, etc., and I believe we think very much alike in this
>> respect.
>>
>> The concrete example was extending the alter table API to better support
>> online schema changes. When we did this at MySQL for online add column in NDB
>> Cluster, we designed it as a general extension to the storage engine API, not
>> as some special case. I think this is what everyone would expect from MySQL
>> sources.
>>
>> But doing such features in a general way, thinking about all use cases and
>> corner cases, can be _much_ more work than making something work well for a
>> given problem at hand. I fully understand the temptation, or even need, to
>> solve the smaller problem instead.
>>
>> My motivation is that I want to see the MySQL source base (under whatever
>> name), see revolutionary improvements long-term. I want to see full parallel
>> replication working with any engine that implements the necessary storage
>> engine API. I want to see a good backup solution that works with different
>> engines. I want to see replication that recovers reliably from crashes and has
>> robust and easy master promotion capabilities. Etc.
>>
>> And I believe to get this we will need not just to add isolated features
>> (whether as individual patches or collected in bzr branches); we will also
>> eventually have to evolve the storage engine API, add new plugin interfaces,
>> etc. That is a lot of work, which is hard to justify for an individual
>> MySQL-using organisation. So I want to encourage everyone to participate in
>> this who might be able to.
On Fri, Sep 24, 2010 at 6:11 PM, MARK CALLAGHAN <mdcallag(a)gmail.com> wrote:
> I agree with you about that being the proper way to advance the MySQL
> family and that the MariaDB project has been open and inclusive
> towards external developers like myself. Hopefully, more can come from
> this and this is a topic to discuss in Istanbul.
On Mon, Oct 4, 2010 at 1:34 PM, Henrik Ingo <henrik.ingo(a)avoinelama.fi> wrote:
> This is something I'm always interested in. It seems most of us
> understand where we need to go, but we don't know yet how to get
> there... How do we convince Mark/Mark's boss that this is the best way
> to develop MySQL codebase also from Facebook's point of view? (long
> term we can make much bigger advances?) Where should this unified
> development happen? (MariaDB? Is Maria open enough, responsive enough?
> fast enough?)
>
> Kristian, do you want to schedule a "hacking in groups" / unconference
> time slot for this?
We agreed with Kristian that I will host this and I probably have more
bandwidth anyway...
...so the invitation is now set for the Saturday evening unconference
slot to anyone who wants to spend 30 minutes discussing how we could
work in a more unified and collaborative way (like Linux or many other
FOSS projects do), rather than each entity having its own branch.
http://askmonty.org/wiki/Istanbul2010_Program
Let me know if the time is bad for you. Note that I'm not a developer
so I'm just hosting it, you guys need to figure out how this should
work.
If you won't be in Istanbul but are interested in this topic, you can
be in touch with me via email (or irc, skype, phone) beforehand.
henrik
--
henrik.ingo(a)avoinelama.fi
+358-40-5697354
www.openlife.cc
1
1

[Maria-developers] WL#161 New (by Sergei): Global PS cache
by worklog-noreply@askmonty.org 14 Oct '10
by worklog-noreply@askmonty.org 14 Oct '10
14 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Global PS cache
CREATION DATE..: Thu, 14 Oct 2010, 10:02
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-RawIdeaBin
TASK ID........: 161 (http://askmonty.org/worklog/?tid=161)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
This task was requested by connector developers - presumably, prepared
statements will be faster, if there will be no need to re-prepare them for every
new connection. In other words, we may want to implement a global cache for
prepared statements.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#160 New (by Sergei): Array binding/bulk operations
by worklog-noreply@askmonty.org 14 Oct '10
by worklog-noreply@askmonty.org 14 Oct '10
14 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Array binding/bulk operations
CREATION DATE..: Thu, 14 Oct 2010, 09:58
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-RawIdeaBin
TASK ID........: 160 (http://askmonty.org/worklog/?tid=160)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
This is a task from MySQL Worklog
(http://forge.mysql.com/worklog/task.php?id=881) that was requested many times
by connector developers.
If MySQL won't get it, we may consider implementing it in MariaDB.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#159 New (by Sergei): New api functions: mysql_stmt_get_data, mysql_stmt_get_column_length
by worklog-noreply@askmonty.org 14 Oct '10
by worklog-noreply@askmonty.org 14 Oct '10
14 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: New api functions: mysql_stmt_get_data, mysql_stmt_get_column_length
CREATION DATE..: Thu, 14 Oct 2010, 09:58
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-RawIdeaBin
TASK ID........: 159 (http://askmonty.org/worklog/?tid=159)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
This is a task from MySQL Worklog
(http://forge.mysql.com/worklog/task.php?id=3191) that was requested many times
by connector developers.
If MySQL won't get it, we may consider implementing it in MariaDB.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#158 New (by Sergei): Prepare any SQL
by worklog-noreply@askmonty.org 14 Oct '10
by worklog-noreply@askmonty.org 14 Oct '10
14 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Prepare any SQL
CREATION DATE..: Thu, 14 Oct 2010, 09:56
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 158 (http://askmonty.org/worklog/?tid=158)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
This is a task from MySQL Worklog
(http://forge.mysql.com/worklog/task.php?id=2871) that was requested many times
by connector developers.
If MySQL won't get it, we may consider implementing it in MariaDB
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] Performance problem: need index-based access when have only non-sargable conditions
by Sergey Petrunya 13 Oct '10
by Sergey Petrunya 13 Oct '10
13 Oct '10
Hi!
I was asked about this performance problem: consider a query
select * from tbl where tbl.key like '%foo%'
Table records are big, much larger than the length of the key. LIKE condition
is very selective, however its pattern starts with '%', so we can't construct
range access (and they are really searching for matches in word
suffixes/infixes, so fulltext index isn't an option).
The desired execution strategy is:
- Scan the index on tbl.key and collect index tuples that match the LIKE
condition.
- For those index tuples, retrieve full records.
One can simulate it by rewriting the query as a self join:
select * from tbl A, tbl B
where
B.primary_key = A.primary_key AND B.key LIKE '%foo%';
However, in this particular case they have a problem doing such rewrites
because the queries are generated by some ORM tool.
Proposed solution from our side
-------------------------------
It is not difficult to add an execution strategy like this
get_next_record()
{
read index tuple;
if (condition satisified)
{
read full record
}
}
(with optional rowid-ordered retrieval for full records).
The difficult part is to find a way to decided whether this strategy should be
used. We have no meaningful selectivity estimates for 'column LIKE '%foo%'.
The only way we could achieve this is by having the user manually specify
condition selectivities. I can see one way to achieve this without getting into
painful syntax modifications:
select * from tbl where selectivity(tbl.key like '%foo%', 0.05)
here 'selectivity(X,y)' will evaluate to value of X, but will also inform the
optimizer that P(X is true)=y.
Any thoughts about this?
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
1

[Maria-developers] WL#157 New (by Frank): Option to show all (currently) marked as crashed tables
by worklog-noreply@askmonty.org 11 Oct '10
by worklog-noreply@askmonty.org 11 Oct '10
11 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Option to show all (currently) marked as crashed tables
CREATION DATE..: Mon, 11 Oct 2010, 09:10
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 157 (http://askmonty.org/worklog/?tid=157)
VERSION........: Server-9.x
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
We'd like to have a way to retrieve the currently "marked as crashed" tables.
At the moment we're parsing the error log, but there should be an easier way of
doing this.
Parsing the log is not 100%, since the log may still contain tables already
repaired. A command ("show crashed tables") could just show the currently
crashed tables.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#156 New (by Dreas): Add mysqlcheck option to directly repair
by worklog-noreply@askmonty.org 10 Oct '10
by worklog-noreply@askmonty.org 10 Oct '10
10 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Add mysqlcheck option to directly repair
CREATION DATE..: Sun, 10 Oct 2010, 12:58
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-BackLog
TASK ID........: 156 (http://askmonty.org/worklog/?tid=156)
VERSION........: Benchmarks-3.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
Currently when there are corrupt MyISAM tables, you need to run mysqlcheck with --
auto-repair to get the broken tables fixed. The repair action however occurs at
the end, after ALL tables have first been checked. This is inconvenient cause you
want to repair any broken tables ideally as soon as the corruption is detected so
the table becomes fixed and accessible. So I'd like to get an option which will
directly run the repair when corruption is detected, instead of waiting until all
tables are checked.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] I am more than happy to test aria with large databases
by Mark Nielsen 09 Oct '10
by Mark Nielsen 09 Oct '10
09 Oct '10
I am not a coder, but I can probably help anyways for development.
I have CentOS systems at work which I can happily run tests against with
large real-world data. They are development systems I can trash.
i can't change CentOS that easily (maybe I can use virtual machines), but I
can put whatever version of MariaDB on my systems and runs tests against
it.
If someone wants me to run tests, let me know.
When the Aria tables can be used with MERGE, I will be very very happy to
test it using a terabyte of data. The Aria engine has some some advantages
over MyISAM and InnoDB for some report servers I wish to setup. MERGE is one
of the last things for me to recommend it.
Anyways, any testing is fine with me. I only have CentOS systems though.
Mark
2
2

[Maria-developers] WL#155 New (by Dreas): MariaDB loop with MyISAM tables marked as crashed
by worklog-noreply@askmonty.org 08 Oct '10
by worklog-noreply@askmonty.org 08 Oct '10
08 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: MariaDB loop with MyISAM tables marked as crashed
CREATION DATE..: Fri, 08 Oct 2010, 19:54
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 155 (http://askmonty.org/worklog/?tid=155)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
On several servers (3) MariaDB 5.1 crashed after an upgrade from from MySQL 5.0.
Log shows:
===
Version: '5.1.50-MariaDB-mariadb84-log' socket: '/var/run/mysqld/mysqld.sock'
port: 3306 (MariaDB - http://mariadb.com/)
101008 14:35:17 [ERROR] mysqld: Table './database123/table123' is marked as
crashed and should be repaired
101008 14:35:17 [Warning] Checking table: './database123/table123'
101008 14:35:17 mysqld_safe Number of processes running now: 0
101008 14:35:17 mysqld_safe mysqld restarted
===
This is looping, so things only get worse every time with more crashed tables.
Using myisamchk to repair all MYI tables actually "fixes" the issue, but I guess
it can come back after an unclean shutdown. This appears to be a major bug. I have
a copy of such corrupt database available on request (information is
confidential).
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#154 New (by Dreas): Replication breaks when upgrading to MariaDB
by worklog-noreply@askmonty.org 08 Oct '10
by worklog-noreply@askmonty.org 08 Oct '10
08 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Replication breaks when upgrading to MariaDB
CREATION DATE..: Fri, 08 Oct 2010, 06:08
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 154 (http://askmonty.org/worklog/?tid=154)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
When upgrading a MySQL 5.0 master to MariaDB 5.1, replication breaks on the
slave(s):
Last_Error: Error 'Table 'tablename' already exists' on query. Default database:
'greylist'. Query: 'RENAME TABLE `#mysql50#tablename` TO `tablename`'
The RENAME TABLE shouldn't be replicated.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

Re: [Maria-developers] [Commits] Rev 2827: Ported the fix for bug #57024 (a performance issue for outer joins). in file:///home/igor/maria/maria-5.3-mwl128-bug57024/
by Sergey Petrunya 06 Oct '10
by Sergey Petrunya 06 Oct '10
06 Oct '10
Hello Igor,
Please find some minor comments below. Ok to push after they are addressed.
On Wed, Oct 06, 2010 at 05:14:08AM -0700, Igor Babaev wrote:
> At file:///home/igor/maria/maria-5.3-mwl128-bug57024/
>
> ------------------------------------------------------------
> revno: 2827
> revision-id: igor(a)askmonty.org-20101006121408-ra44i6o7eich5hrf
> parent: igor(a)askmonty.org-20101004014546-xirepv04xs7txxhw
> committer: Igor Babaev <igor(a)askmonty.org>
> branch nick: maria-5.3-mwl128-bug57024
> timestamp: Wed 2010-10-06 05:14:08 -0700
> message:
> Ported the fix for bug #57024 (a performance issue for outer joins).
> Employed the same kind of optimization as in the fix for the cases
> when join buffer is used.
> The optimization performs early evaluation of the conditions from
> on expression with table references to only outer tables of
> an outer join.
...
> === modified file 'sql/sql_join_cache.cc'
> @@ -1604,6 +1625,12 @@
> uchar *init_pos= pos;
> CACHE_FIELD *copy= field_descr;
> CACHE_FIELD *copy_end= copy+flag_fields;
> + if (with_match_flag)
> + {
> + copy->str[0]= test((Match_flag) pos[0] == MATCH_FOUND);
> + pos+= copy->length;
> + copy++;
> + }
> for ( ; copy < copy_end; copy++)
> {
> memcpy(copy->str, pos, copy->length);
TODO where does the above copy to?
> @@ -1754,30 +1781,68 @@
>
>
> /*
> - Skip record from join buffer if its match flag is on: default implementation
> -
> - SYNOPSIS
> - skip_recurrent_match()
> -
> - DESCRIPTION
> - This default implementation of the virtual function skip_record_if_match
> - skips the next record from the join buffer if its match flag is set on.
> - If the record is skipped the value of 'pos' is set to points to the position
> - right after the record.
> -
> - RETURN VALUE
> - TRUE the match flag is on and the record has been skipped
> - FALSE the match flag is off
> -*/
> -
> -bool JOIN_CACHE::skip_recurrent_match()
> -{
> - DBUG_ASSERT(with_length);
> - uint offset= size_of_rec_len;
> - if (prev_cache)
> - offset+= prev_cache->get_size_of_rec_offset();
> - /* Check whether the match flag is on */
> - if (get_match_flag_by_pos(pos+offset))
> + Skip record from join buffer if's already matched: default implementation
> +
> + SYNOPSIS
> + skip_as_matched()
> +
> + DESCRIPTION
> + This default implementation of the virtual function skip_as_matched
> + skips the next record from the join buffer if its match flag is set to 1.
> + If the record is skipped the value of 'pos' is set to points to the position
> + right after the record.
> +
> + RETURN VALUE
> + TRUE the match flag is set to 1 and the record has been skipped
> + FALSE the match flag is not 1
Please s/1/MATCH_FOUND/
> +*/
> +
> +bool JOIN_CACHE::skip_as_matched()
Please rename the function to skip_if_matched(), because that what it actually
does: checks *if* the records is matched and skips it if it is so.
> +{
> + DBUG_ASSERT(with_length);
> + uint offset= size_of_rec_len;
> + if (prev_cache)
> + offset+= prev_cache->get_size_of_rec_offset();
> + /* Check whether the match flag is MATCH_FOUND */
> + if (get_match_flag_by_pos(pos+offset) == MATCH_FOUND)
> + {
> + pos+= size_of_rec_len + get_rec_length(pos);
> + return TRUE;
> + }
> + return FALSE;
> +}
> +
> +
> +/*
> + Skip record from join buffer if the match isn't needed: default implementation
> +
> + SYNOPSIS
> + skip_as_unneeded_match()
> +
> + DESCRIPTION
> + This default implementation of the virtual function skip_as_unneeded_match
> + skips the next record from the join buffer if its match flag is not
> + MATCH_NOT_FOUND, and, either its value is MATCH_FOUND and join_tab is the
> + first inner table of an inner join, or, its value is MATCH_IMPOSSIBLE
> + and join_tab is the first inner table of an outer join.
> + If the record is skipped the value of 'pos' is set to points to the position
Typo, s/points/point/
> + right after the record.
> +
> + RETURN VALUE
> + TRUE the record has to be been skipped
^^^^^^^^^^^
wrong grammar.
> + FALSE otherwise
> +*/
> +
> +bool JOIN_CACHE::skip_as_unneeded_match()
> +{
> + DBUG_ASSERT(with_length);
> + enum Match_flag match_fl;
> + uint offset= size_of_rec_len;
> + if (prev_cache)
> + offset+= prev_cache->get_size_of_rec_offset();
> +
> + if ((match_fl= get_match_flag_by_pos(pos+offset)) != MATCH_NOT_FOUND &&
> + (join_tab->check_only_first_match() == (match_fl == MATCH_FOUND)) )
> {
> pos+= size_of_rec_len + get_rec_length(pos);
> return TRUE;
> @@ -1990,9 +2055,9 @@
> {
> int error;
> enum_nested_loop_state rc= NESTED_LOOP_OK;
> + join_tab->table->null_row= 0;
> bool check_only_first_match= join_tab->check_only_first_match();
> -
> - join_tab->table->null_row= 0;
> + bool outer_join_first_inner= join_tab->is_first_inner_for_outer_join();
>
> /* Return at once if there are no records in the join buffer */
> if (!records)
> @@ -2042,9 +2107,11 @@
> /*
> If only the first match is needed, and, it has been already found for
> the next record read from the join buffer, then the record is skipped.
> + Also those records that must be null complemented are not considered
> + as candidates for matches.
> */
> - if (!(check_only_first_match &&
> - skip_recurrent_candidate_for_match(rec_ptr)))
> + if ((!check_only_first_match && !outer_join_first_inner) ||
> + !skip_next_candidate_for_match(rec_ptr))
> {
> read_next_candidate_for_match(rec_ptr);
> rc= generate_full_extensions(rec_ptr);
> @@ -2268,7 +2335,6 @@
> uint cnt;
> enum_nested_loop_state rc= NESTED_LOOP_OK;
> bool is_first_inner= join_tab == join_tab->first_unmatched;
> - bool is_last_inner= join_tab == join_tab->first_unmatched->last_inner;
>
> /* Return at once if there are no records in the join buffer */
> if (!records)
> @@ -2289,7 +2355,7 @@
> goto finish;
> }
> /* Just skip the whole record if a match for it has been already found */
> - if (!is_first_inner || !skip_recurrent_match())
> + if (!is_first_inner || !skip_as_matched())
> {
> get_record();
> /* The outer row is complemented by nulls for each inner table */
> @@ -2527,6 +2593,8 @@
> is attached to the key entry. The key value is either placed in the hash
> element added for the key or, if the use_emb_key flag is set, remains in
> the record from the partial join.
> + If the match flag field of a record contains MATCH_IMPOSSIBLE the key is
> + not created for this record.
>
> RETURN VALUE
> TRUE if it has been decided that it should be the last record
> @@ -2550,6 +2618,9 @@
> link= prev_cache->get_curr_rec_link();
> write_record_data(link, &is_full);
>
> + if (last_written_is_null_compl)
> + return is_full;
> +
> if (use_emb_key)
> key= get_curr_emb_key();
> else
> @@ -2634,26 +2705,55 @@
>
>
> /*
> - Skip record from a hashed join buffer if its match flag is on
> -
> - SYNOPSIS
> - skip_recurrent_match()
> -
> - DESCRIPTION
> - This implementation of the virtual function skip_recurrent_match does
> - the same as the default implementation does, but it takes into account
> - the link element used to connect the records with the same key into a chain.
> -
> - RETURN VALUE
> - TRUE the match flag is on and the record has been skipped
> + Skip record from a hashed join buffer if its match flag is set to 1
> +
> + SYNOPSIS
> + skip_as_matched()
> +
> + DESCRIPTION
> + This implementation of the virtual function skip_as_matched does
> + the same as the default implementation does, but it takes into account
> + the link element used to connect the records with the same key into a chain.
> +
> + RETURN VALUE
> + TRUE the match flag is MATCH_FOUND and the record has been skipped
> + FALSE the match flag is not MATCH_FOUND
> +*/
> +
> +bool JOIN_CACHE_HASHED::skip_as_matched()
> +{
> + uchar *save_pos= pos;
> + pos+= get_size_of_rec_offset();
> + if (!this->JOIN_CACHE::skip_as_matched())
> + {
> + pos= save_pos;
> + return FALSE;
> + }
> + return TRUE;
> +}
> +
> +
> +/*
> + Skip record from a hashed join buffer if its match flag dictates to do so
> +
> + SYNOPSIS
> + skip_as_uneeded_match()
> +
> + DESCRIPTION
> + This implementation of the virtual function skip_as_uneeded_match does
> + the same as the default implementation does, but it takes into account
> + the link element used to connect the records with the same key into a chain.
> +
> + RETURN VALUE
> + TRUE the match flag dictates to skip the record
> FALSE the match flag is off
> */
>
> -bool JOIN_CACHE_HASHED::skip_recurrent_match()
> +bool JOIN_CACHE_HASHED::skip_as_unneeded_match()
> {
> uchar *save_pos= pos;
> pos+= get_size_of_rec_offset();
> - if (!this->JOIN_CACHE::skip_recurrent_match())
> + if (!this->JOIN_CACHE::skip_as_unneeded_match())
> {
> pos= save_pos;
> return FALSE;
> @@ -2780,7 +2880,7 @@
> last element of this chain.
>
> RETURN VALUE
> - TRUE if each retrieved record has its match flag set on
> + TRUE if each retrieved record has its match flag set to MATCH_FOUND
> FALSE otherwise
> */
>
> @@ -2792,7 +2892,7 @@
> {
> next_rec_ref_ptr= get_next_rec_ref(next_rec_ref_ptr);
> uchar *rec_ptr= next_rec_ref_ptr+rec_fields_offset;
> - if (!get_match_flag_by_pos(rec_ptr))
> + if (get_match_flag_by_pos(rec_ptr) != MATCH_FOUND)
> return FALSE;
> }
> while (next_rec_ref_ptr != last_rec_ref_ptr);
> @@ -3000,25 +3100,28 @@
> Check whether the matching record from the BNL cache is to be skipped
>
> SYNOPSIS
> - skip_recurrent_candidate_for_match
> + skip_next_candidate_for_match
> rec_ptr pointer to the position in the join buffer right after the prefix
> of the current record
>
> DESCRIPTION
> This implementation of the virtual function just calls the
> - method skip_recurrent_match to check whether the record referenced by
> - ref_ptr has its match flag set on and, if so, just skips this record
> - setting the value of the cursor 'pos' to the position right after it.
> + method skip_as_unneded_match to check whether the record referenced by
> + ref_ptr has its match flag set either to MATCH_FOUND and join_tab is the
> + first inner table of a semi-join, or it's set to MATCH_IMPOSSIBLE and
> + join_tab is the first inner table of an outer join.
> + If so, the function just skips this record setting the value of the
> + cursor 'pos' to the position right after it.
>
> RETURN VALUE
> TRUE the record referenced by rec_ptr has been skipped
> FALSE otherwise
> */
>
> -bool JOIN_CACHE_BNL::skip_recurrent_candidate_for_match(uchar *rec_ptr)
> +bool JOIN_CACHE_BNL::skip_next_candidate_for_match(uchar *rec_ptr)
> {
> pos= rec_ptr-base_prefix_length;
> - return skip_recurrent_match();
> + return skip_as_unneeded_match();
> }
>
>
> @@ -3162,7 +3265,7 @@
> The methods performs the necessary preparations to read the next record
> from the join buffer into the record buffer by the method
> read_next_candidate_for_match, or, to skip the next record from the join
> - buffer by the method skip_recurrent_candidate_for_match.
> + buffer by the method skip_next_candidate_for_match.
> This implementation of the virtual method moves to the next record
> in the chain of all records from the join buffer that are to be
> equi-joined with the current record from join_tab.
> @@ -3187,23 +3290,25 @@
> Check whether the matching record from the BNLH cache is to be skipped
>
> SYNOPSIS
> - skip_recurrent_candidate_for_match
> + skip_next_candidate_for_match
> rec_ptr pointer to the position in the join buffer right after
> the previous record
>
> DESCRIPTION
> This implementation of the virtual function just calls the
> method get_match_flag_by_pos to check whether the record referenced
> - by ref_ptr has its match flag set on.
> + by ref_ptr has its match flag set to MATCH_FOUND.
>
> RETURN VALUE
> - TRUE the record referenced by rec_ptr has its match flag set on
> + TRUE the record referenced by rec_ptr has its match flag set to
> + MATCH_FOUND
> FALSE otherwise
> */
>
> -bool JOIN_CACHE_BNLH::skip_recurrent_candidate_for_match(uchar *rec_ptr)
> +bool JOIN_CACHE_BNLH::skip_next_candidate_for_match(uchar *rec_ptr)
> {
> - return get_match_flag_by_pos(rec_ptr);
> + return join_tab->check_only_first_match() &&
> + (get_match_flag_by_pos(rec_ptr) == MATCH_FOUND);
> }
>
>
> @@ -3364,7 +3469,7 @@
> int JOIN_TAB_SCAN_MRR::next()
> {
> char **ptr= (char **) cache->get_curr_association_ptr();
> - uint rc= join_tab->table->file->multi_range_read_next(ptr) ? -1 : 0;
> + int rc= join_tab->table->file->multi_range_read_next(ptr) ? -1 : 0;
> if (!rc)
> {
> /*
> @@ -3482,7 +3587,8 @@
> {
> DBUG_ENTER("bka_range_seq_skip_record");
> JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
> - bool res= cache->get_match_flag_by_pos((uchar *) range_info);
> + bool res= cache->get_match_flag_by_pos((uchar *) range_info) ==
> + JOIN_CACHE::MATCH_FOUND;
> DBUG_RETURN(res);
> }
>
> @@ -3560,7 +3666,7 @@
> The method performs the necessary preparations to read the next record
> from the join buffer into the record buffer by the method
> read_next_candidate_for_match, or, to skip the next record from the join
> - buffer by the method skip_recurrent_match.
> + buffer by the method skip_as_unneeded_match.
> This implementation of the virtual method get_next_candidate_for_match
> just decrements the counter of the records that are to be iterated over
> and returns the value of curr_association as a reference to the position
> @@ -3584,23 +3690,25 @@
> Check whether the matching record from the BKA cache is to be skipped
>
> SYNOPSIS
> - skip_recurrent_candidate_for_match
> + skip_next_candidate_for_match
> rec_ptr pointer to the position in the join buffer right after
> the previous record
>
> DESCRIPTION
> This implementation of the virtual function just calls the
> method get_match_flag_by_pos to check whether the record referenced
> - by ref_ptr has its match flag set on.
> + by ref_ptr has its match flag set to MATCH_FOUND.
>
> RETURN VALUE
> - TRUE the record referenced by rec_ptr has its match flag set on
> + TRUE the record referenced by rec_ptr has its match flag set to
> + MATCH_FOUND
> FALSE otherwise
> */
>
> -bool JOIN_CACHE_BKA::skip_recurrent_candidate_for_match(uchar *rec_ptr)
> +bool JOIN_CACHE_BKA::skip_next_candidate_for_match(uchar *rec_ptr)
> {
> - return get_match_flag_by_pos(rec_ptr);
> + return join_tab->check_only_first_match() &&
> + (get_match_flag_by_pos(rec_ptr) == MATCH_FOUND);
> }
>
>
> @@ -3691,7 +3799,9 @@
> If is assumed that the functions starts reading at the position of
> the record length which is provided for each records in a BKA cache.
> After the key is built the 'pos' value points to the first position after
> - the current record.
> + the current record.
> + The function just skips the records with MATCH_IMPOSSIBLE in the
> + match flag field if there is any.
> The function returns 0 if the initial position is after the beginning
> of the record fields for last record from the join buffer.
>
> @@ -3708,6 +3818,8 @@
> uchar *init_pos;
> JOIN_CACHE *cache;
>
> +start:
> +
> /* Any record in a BKA cache is prepended with its length */
> DBUG_ASSERT(with_length);
>
> @@ -3727,6 +3839,13 @@
>
> /* Read all flag fields of the record */
> read_flag_fields();
> +
> + if (with_match_flag &&
> + (Match_flag) curr_rec_pos[0] == MATCH_IMPOSSIBLE )
> + {
> + pos= init_pos+rec_len;
> + goto start;
> + }
>
> if (use_emb_key)
> {
>
> === modified file 'sql/sql_select.cc'
> --- a/sql/sql_select.cc 2010-10-01 18:05:27 +0000
> +++ b/sql/sql_select.cc 2010-10-06 12:14:08 +0000
> @@ -7090,9 +7090,13 @@
> used_tables2|= current_map;
> COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
> current_map, FALSE);
> + add_cond_and_fix(&tmp_cond, tab->on_precond);
> if (tmp_cond)
> {
> JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
> + Item **sel_cond_ref= tab < first_inner_tab ?
> + &first_inner_tab->on_precond :
> + &tab->select_cond;
> /*
> First add the guards for match variables of
> all embedding outer join operations.
> @@ -7115,15 +7119,15 @@
> tmp_cond->quick_fix_field();
> /* Add the predicate to other pushed down predicates */
> DBUG_PRINT("info", ("Item_cond_and"));
> - cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
> - new Item_cond_and(cond_tab->select_cond,
> - tmp_cond);
> + *sel_cond_ref= !(*sel_cond_ref) ?
> + tmp_cond :
> + new Item_cond_and(*sel_cond_ref, tmp_cond);
> DBUG_PRINT("info", ("Item_cond_and 0x%lx",
> - (ulong)cond_tab->select_cond));
> - if (!cond_tab->select_cond)
> - DBUG_RETURN(1);
> - cond_tab->select_cond->update_used_tables();
> - cond_tab->select_cond->quick_fix_field();
> + (ulong)(*sel_cond_ref)));
> + if (!(*sel_cond_ref))
> + DBUG_RETURN(1);
> + (*sel_cond_ref)->quick_fix_field();
> + (*sel_cond_ref)->update_used_tables();
> if (cond_tab->select)
> cond_tab->select->cond= cond_tab->select_cond;
> }
> @@ -13246,7 +13250,7 @@
> DBUG_RETURN(nls);
> }
> int error;
> - enum_nested_loop_state rc;
> + enum_nested_loop_state rc= NESTED_LOOP_OK;
> READ_RECORD *info= &join_tab->read_record;
>
> if (join_tab->flush_weedout_table)
> @@ -13279,18 +13283,21 @@
>
> /* Set first_unmatched for the last inner table of this group */
> join_tab->last_inner->first_unmatched= join_tab;
> - }
> + if (join_tab->on_precond && !join_tab->on_precond->val_int())
> + rc= NESTED_LOOP_NO_MORE_ROWS;
> + }
> join->thd->row_count= 0;
>
> if (join_tab->loosescan_match_tab)
> join_tab->loosescan_match_tab->found_match= FALSE;
>
> - error= (*join_tab->read_first_record)(join_tab);
> -
> - if (join_tab->keep_current_rowid)
> - join_tab->table->file->position(join_tab->table->record[0]);
> -
> - rc= evaluate_join_record(join, join_tab, error);
> + if (rc != NESTED_LOOP_NO_MORE_ROWS)
> + {
> + error= (*join_tab->read_first_record)(join_tab);
> + if (join_tab->keep_current_rowid)
> + join_tab->table->file->position(join_tab->table->record[0]);
> + rc= evaluate_join_record(join, join_tab, error);
> + }
> }
>
> /*
>
> === modified file 'sql/sql_select.h'
> --- a/sql/sql_select.h 2010-10-01 18:05:27 +0000
> +++ b/sql/sql_select.h 2010-10-06 12:14:08 +0000
> @@ -161,6 +161,8 @@
> KEYUSE *keyuse; /**< pointer to first used key */
> SQL_SELECT *select;
> COND *select_cond;
> + COND *on_precond; /**< part of on condition to check before
> + accessing the first inner table */
> QUICK_SELECT_I *quick;
> /*
> The value of select_cond before we've attempted to do Index Condition
> @@ -678,6 +680,14 @@
> */
> uchar *curr_rec_link;
>
> + /*
> + This flag is set to TRUE if join_tab is the first inner table of an outer
> + join and the latest record written to the join buffer is detected to be
> + null complemented after checking on conditions over the outer tables for
> + this outer join operation
> + */
> + bool last_written_is_null_compl;
> +
> /*
> The number of fields put in the join buffer of the join cache that are
> used in building keys to access the table join_tab
> @@ -792,8 +802,11 @@
> /* Read a referenced field from the join buffer */
> bool read_referenced_field(CACHE_FIELD *copy, uchar *rec_ptr, uint *len);
>
> - /* Shall skip record from the join buffer if its match flag is on */
> - virtual bool skip_recurrent_match();
> + /* Shall skip record from the join buffer if its match flag is set to 1 */
> + virtual bool skip_as_matched();
Please s/1/MATCH_FOUND/;
> +
> + /* Shall skip record from the join buffer if its match flag is not-zero */
> + virtual bool skip_as_unneeded_match();
>
> /*
> True if rec_ptr points to the record whose blob data stay in
> @@ -836,11 +849,11 @@
> virtual uchar *get_next_candidate_for_match()= 0;
> /*
> Shall check whether the given record from the join buffer has its match
> - flag set on and, if so, skip the record in the buffer.
> + flag settings commands to skip the record in the buffer.
> */
> - virtual bool skip_recurrent_candidate_for_match(uchar *rec_ptr)= 0;
> + virtual bool skip_next_candidate_for_match(uchar *rec_ptr)= 0;
> /*
> - Shall read the given record from the join buffer into the
> + Shall read the given record from the join buffer intTCo the
Is the above change a typo ^^
> the corresponding record buffer
> */
> virtual void read_next_candidate_for_match(uchar *rec_ptr)= 0;
> @@ -868,6 +881,21 @@
>
> public:
>
> + /*
> + The enumeration type Match_flag describes possible states of the match flag
> + field stored for the records of the first inner tables of outer joins and
> + semi-joins in the cases when the first match strategy is used for them.
> + When a record with match flag field is written into the join buffer the
> + state of the field usually is MATCH_NOT_FOUND unless this is a record of the
> + first inner table of the outer join for which the on precondition (the
> + condition from on expression over outer tables) has turned out not to be
> + true. In the last case the state of the match flag is MATCH_IMPOSSIBLE.
> + The state of the match flag field is changed to MATCH_FOUND as soon as
> + the first full matching combination of inner tables of the outer join or
> + the semi-join is discovered.
> + */
> + enum Match_flag { MATCH_NOT_FOUND, MATCH_FOUND, MATCH_IMPOSSIBLE };
> +
> /* Table to be joined with the partial join records from the cache */
> JOIN_TAB *join_tab;
>
> @@ -920,7 +948,7 @@
> virtual void get_record_by_pos(uchar *rec_ptr);
>
> /* Shall return the value of the match flag for the positioned record */
> - virtual bool get_match_flag_by_pos(uchar *rec_ptr);
> + virtual enum Match_flag get_match_flag_by_pos(uchar *rec_ptr);
>
> /* Shall return the position of the current record */
> virtual uchar *get_curr_rec() { return curr_rec_pos; }
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
1
Sergei Golubchik <serg(a)askmonty.org> writes:
Thanks for review!
What I would now like to do is to discuss how to proceeed (where to push this
basically).
On the one hand, the patch got rather more intrusive than I first wanted. The
main issue is that now the mysys/mystrings/dbug code is linked dynamically by
default, so these additional libmysys.so etc. libraries must be installed by
packagers etc. for things to work; similarly extra -lmysys etc. is needed when
using libmysqld.a.
On the other hand, I think this is generally an improvement, linking code
dynamically rather than statically. Saves duplicating code and so on, and
dynamic linking is where the world is moving (has moved, really).
I even tested the overhead of dynamic linking, it is two clock cycles per
function call into a different library (I plan to write a short blog about
that).
So I think it is mainly a question on where we want to risk pushing this: 5.1,
5.2, or 5.3? We could even add it to the list of patches in the .debs for 5.1.
(BTW, Gentoo people seems to have picked up the patch already in their MySQL
and MariaDB 5.1 packages).
And btw, I would like your help/hints on how to extend mysql_config to provide
the right information for how to link.
With those general remarks, here follow comments, inline:
> Can I branch this your tree from somewhere ?
bzr+ssh://bazaar.launchpad.net/~knielsen/maria/mariadb-5.1-mwl74-libmysqld.…
>> The plugin may optionally specify @plugin_static_if_no_embedded@ in
>> CFLAGS/CXXFLAGS for the static target; this will avoid needlessly
>> compiling with -fPIC if no libmysqld is being built.
>
> I failed to understand this paragraph :(
With this patch, every source file for a plugin is compiled twice, once with
-fPIC and once without.
However, if we are not building libmysqld, then the -fPIC versions will never
be used.
In this case, @plugin_static_if_no_embedded@ will add -static to CFLAGS,
avoiding the needless compilations with -fPIC. Otherwise it will be empty.
Hope this was clearer.
[There is BTW another similar issue: when building a convenience library,
libtool will again compile sources both with and without -fPIC. But it only
ever uses the -fPIC objects in the convenience library, the objects without
-fPIC are not used. I even tested the newest libtool version, and also found
an email thread discussing this (and agreeing that the problem is there)].
>> This patch only does what is necessary to build libmysqld.so. There
>> are some more cleanups that are possible now that we are using libtool
>> more fully, which will be done in subsequent patches:
>>
>> - In libmysql_r/, we should be able to just link libmysys.la etc,
>> instead of symlinking and re-compiling sources into the directory.
>>
>> - In libmysql/, we can similarly avoid symlinking and recompiling
>> sources if we instead build a libmysys_nothread.la library with
>> appropriate CFLAGS and link that.
>
> I'd rather not build libmysql at all.
> Or, at least, not by default.
Right, let's add this on top of this patch once we find out where we want to
push it?
If we link libmysql_r with libmysys, it will also solve another issue I have (with
conflicts between C and assembler versions of bmovXXX); I postponed this issue
until we decided about linking libmysql_r with mysys etc (it seems you agree
we should do this).
>> === modified file 'config/ac-macros/plugins.m4'
>> --- config/ac-macros/plugins.m4 2010-09-18 07:53:48 +0000
>> +++ config/ac-macros/plugins.m4 2010-09-27 12:41:05 +0000
>> @@ -115,18 +115,32 @@ dnl ------------------------------------
>> dnl Macro: MYSQL_PLUGIN_STATIC
>> dnl
>> dnl SYNOPSIS
>> -dnl MYSQL_PLUGIN_STATIC([name],[libmyplugin.a])
>> +dnl MYSQL_PLUGIN_STATIC([name],[libmyplugin.a],[libmyplugin_embedded.a])
>> dnl
>> dnl DESCRIPTION
>> -dnl Declare the name for the static library
>> +dnl Declare the name for the static library
>> +dnl
>> +dnl Third argument is optional, only needed for special plugins that depend
>> +dnl on server internals and have source files that must be compiled specially
>> +dnl with -DEMBEDDED_LIBRARY for embedded server. If specified, the third
>> +dnl argument is used to link embedded server instead of the second.
>
> Does that mean that all plugin files will be rebuilt with
> -DEMBEDDED_LIBRARY if libmyplugin_embedded.a is specified ?
No. It means that the plugin Makefile.am has the possibility to specify a
different library to be used for embedded.
Later in the patch I modify all plugins that need it (ie. they before
specified MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS) so that they build a
convenience library (once) with all the source files that do not depend on
internals. And compile the few source files that do depend on internals in two
versions with or without -DEMBEDDED_LIBRARY. And then link those together to
two different libraries, one for server, one for embedded.
With this, it's basically up to the plugin Makefile.am to do what it wants.
>> -AC_DEFUN([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS],[
>> - MYSQL_REQUIRE_PLUGIN([$1])
>> - m4_define([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS_]AS_TR_CPP([$1]), [$2])
>> -])
>
> I thought we agreed on IRC to keep it.
> Do you mean, you tried it and it didn't work?
Yes.
I tried quite hard to find a way to keep compatibility. But failed :-(
In the end I could not think of anything sensible to do for
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(), so I removed it.
This is related to your question below, about keeping compatibility so that
eg. PBXT could still work unmodified between MySQL and MariaDB.
I thought a lot about how to do this, but in the end failed. The hardest
problem is that to link libmysqld.so with libtool, we need plugins to provide
libXXX.la files in MYSQL_PLUGIN_STATIC(). And those libXXX.la simply will not
work with the magic loop in MySQL sources that extracts objects from libXXX.a,
removes duplicates, and links them back again. At least I couldn't see how to
do it.
So in the end I gave up on this compatibility. Sad, however a small comfort is
that
- This only hits plugins that say MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(),
which ideally they shouldn't anyway.
- This only hits static plugins, which in any case need an incompatible
maria_declare_plugin() added in the source (though this can be handled with
#ifdef; I wonder if there is m4/automake equivalent ifdef that could help
here?)
If you have an idea on how to achieve compatibility and do something sensible
for MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(), then let me know ...
>> +# __MYSQL_EMIT_CHECK_PLUGIN arguments:
>> +#
>> +# 1 - plugin identifying name
>> +# 2 - plugin identifying name, with `-' replaced by `_'
>> +# 3 - plugin long name
>> +# 4 - plugin description
>> +# 5 - mysql_plugin_define (eg. WITH_xxx_STORAGE_ENGINE)
>> +# 6 - directory
>> +# 7 - static target (if supports static build)
>> +# 8 - dynamic target (if supports dynamic build)
>> +# 9 - mandatory flag
>> +# 10 - disabled flag
>> +# 11 - static target for libmysqld (if different from mysqld)
>
> perhaps "if different from $7" ?
Fixed, thanks.
>> +# 12 - actions
>
> better use 'dnl' here, not '#'
>
> because '#'-lines will go into configure script, where they will mean
> nothing, as the macro will be already expanded.
Fixed
>> +dnl If not building libmysqld embedded server, then there is no need to build
>> +dnl shared object versions of static plugins.
>
> heh :)
> There, on the contrary, I'd rather use '#' for comments, not 'dnl'
Ok, I see, thanks for helping an m4 newbee :-)
Fixed.
>> === modified file 'configure.in'
>> --- configure.in 2010-08-27 14:12:44 +0000
>> +++ configure.in 2010-09-13 20:17:09 +0000
>> @@ -2846,9 +2845,6 @@ if test "$with_server" != "no" -o "$THRE
>> then
>> AC_DEFINE([THREAD], [1],
>> [Define if you want to have threaded code. This may be undef on client code])
>> - # Avoid _PROGRAMS names
>> - THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o mf_keycache.o mf_keycaches.o waiting_threads.o"
>> - AC_SUBST(THREAD_LOBJECTS)
>
> What was that? Definitions for mysys/Makefile.am to know what to build
> (or not) depending on whether threads are enabled ?
Yes. This is fixing an inconsistency in the original sources.
These source files should only be compiled when threads are enabled. There was
code to deal with this in two places: here in configure.in, and in
mysys/Makefile.am. Each place handled a different set of files, and there was
overlap (maybe due to merge error?)
Anyway, with pure static libraries, this overlap did not cause problems
apparently, but with libtool and .so linking, it caused a failure. So I
decided to clean it up to be done in one place only.
>> === modified file 'dbug/Makefile.am'
>> --- dbug/Makefile.am 2010-08-27 14:12:44 +0000
>> +++ dbug/Makefile.am 2010-09-28 11:23:14 +0000
>> @@ -16,10 +16,10 @@
>> # MA 02111-1307, USA
>>
>> INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
>> -LDADD = libdbug.a ../mysys/libmysys.a ../strings/libmystrings.a
>> -pkglib_LIBRARIES = libdbug.a
>> +LDADD = libdbug.la ../mysys/libmysys.la ../strings/libmystrings.la
>
> better to use $(top_builddir)/libmysys.la etc
> (here and below)
Fixed (throughout the patch)
> How's the build time - new, libmysql.so vs. the old libmysqld.a ?
Thanks for remind me, I checked. These are on a quad-core with no ccache:
BUILD/compile-pentium64-valgrind-max:
Before: 3m19.454s
After: 4m18.947s
So build time _is_ increased somewhat ...
> Paul would apparently want his engine to work both with MySQL and
> MariaDB. Could we somehow make it possible (applies to other engines
> too)?
(See discussion above)
Thanks,
- Kristian.
2
1

[Maria-developers] MWL#89 "Cost-based choice between Materialization and IN->EXISTS" rev1 for review
by Timour Katchaounov 05 Oct '10
by Timour Katchaounov 05 Oct '10
05 Oct '10
Igor,
Please find attached a combined patch for the first implementation of:
MWL#89 Cost-based choice between Materialization and IN->EXISTS
The tree is in Lanunchpad under buildbot:
https://code.launchpad.net/~maria-captains/maria/5.3-mwl89
Timour
1
0

[Maria-developers] WL#153 New (by Dreas): Permission denied message doesn't tell which database was involved
by worklog-noreply@askmonty.org 05 Oct '10
by worklog-noreply@askmonty.org 05 Oct '10
05 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Permission denied message doesn't tell which database was involved
CREATION DATE..: Tue, 05 Oct 2010, 08:43
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 153 (http://askmonty.org/worklog/?tid=153)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
When there are grants missing, the output shows for example: SELECT command denied
to user 'user'@'localhost' for table 'my_test_table'
This doesn't tell you what current database was involved, making it hard(er) to
find out which grant is exactly missing. Would be great if the relevant database
is also shown in the error response.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#152 New (by Frank): Show database name in error messages
by worklog-noreply@askmonty.org 05 Oct '10
by worklog-noreply@askmonty.org 05 Oct '10
05 Oct '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Show database name in error messages
CREATION DATE..: Tue, 05 Oct 2010, 08:30
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 152 (http://askmonty.org/worklog/?tid=152)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 1 (hours remain)
ORIG. ESTIMATE.: 1
PROGRESS NOTES:
DESCRIPTION:
It would be useful if the error messages (such as "INSERT denied to user@host
for table 'blah') to include database names.
The output could be:
1) ("INSERT denied to user@host for table 'databasename.blah'"
2) ("INSERT denied to user@host for table 'blah' in database 'databasename'"
This would save a lot of time of searching in which database this was.
Especially in applications using multiple databases.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

Re: [Maria-developers] [Commits] Rev 2851: MWL#132: Transaction coordinator plugin. in http://bazaar.launchpad.net/~maria-captains/maria/5.1
by Michael Widenius 04 Oct '10
by Michael Widenius 04 Oct '10
04 Oct '10
Hi!
>>>>> "knielsen" == knielsen <knielsen(a)knielsen-hq.org> writes:
knielsen> At http://bazaar.launchpad.net/~maria-captains/maria/5.1
knielsen> ------------------------------------------------------------
knielsen> revno: 2851
knielsen> revision-id: knielsen(a)knielsen-hq.org-20101004104808-asb7wcxoeg417j7d
knielsen> parent: knielsen(a)knielsen-hq.org-20101001084957-02tl9sdzevoaiao7
knielsen> committer: knielsen(a)knielsen-hq.org
knielsen> branch nick: work-5.1-mwl132
knielsen> timestamp: Mon 2010-10-04 12:48:08 +0200
knielsen> message:
knielsen> MWL#132: Transaction coordinator plugin.
<cut
knielsen> +++ b/sql/log.cc 2010-10-04 10:48:08 +0000
knielsen> @@ -6531,6 +6531,39 @@ err1:
knielsen> "--tc-heuristic-recover={commit|rollback}");
knielsen> return 1;
knielsen> }
knielsen> +
knielsen> +static TC_LOG *
knielsen> +tc_log_mmap_register(void *arg __attribute__((unused)), int yield)
knielsen> +{
knielsen> + if (yield || total_ha_2pc <= 1)
knielsen> + return NULL;
knielsen> +
knielsen> + return &tc_log_mmap;
knielsen> +}
<cut>
knielsen> +++ b/sql/mysqld.cc 2010-10-04 10:48:08 +0000
knielsen> @@ -4283,10 +4283,11 @@ a file name for --log-bin-index option",
knielsen> }
knielsen> #endif
knielsen> - tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
knielsen> - (TC_LOG *) &mysql_bin_log :
knielsen> - (TC_LOG *) &tc_log_mmap) :
knielsen> - (TC_LOG *) &tc_log_dummy);
According to the old code, the tc_log_mmap_register() should use:
if (yield || total_ha_2pc <= 1 || opt_bin_log)
return NULL;
Was this an intentional change ?
If yes, there should have been a comment about it.
Regards,
Monty
2
1
I'm sure you have all read
http://bazaar.launchpad.net/~mysqlatfacebook/mysqlatfacebook/tools/annotate…
already,
but if you haven't, it might be neat to look at evaluating and possibly
integrating it into MariaDB.
5
9

04 Oct '10
Hello everyone,
I have now managed to make buildbot produce automatic LCOV reports for
MariaDB. You can view them here
http://fedora13.selfip.org/lcov/
and get statistics down to directory/file level or open an individual file
and see an annotated listing showing lines that were not covered.
The report is calculated based on a default MTR test run, plus PBXT and the
funcs_x and other smaller test suites. No --big or binlog combinations are
being used. RQG tests are not included, since the idea is to *always* have
decent MTR coverage, with the RQG being used a secondary line of defense.
My idea is to monitor the report periodically and look for considerable
regressions in code coverage, which would include:
- pushing new code or major patches to the core server that reduce the code
coverage within the existing files
- adding new subdirectories, modules or storage engines that do not come
with new tests to cover the new ground
Regardless of those reports, everyone is encouraged to use the personal code
coverage tools, including mtr.pl --gcov and the DGcov script
(http://forge.mysql.com/wiki/DGCov) to check the coverage of patches and
commits before they are pushed. This will avoid painful scenarios where
people are asked to provide code coverage later in the development process,
which is always a bigger pain.
The buildbot host is capable of building any other launchpad-based tree, so
if you require lcov reports for a particular feature or storage engine that
you are developing, please drop me a note and I will configure reports to be
generated for your tree as well.
Thank you.
Philip Stoev
2
1

01 Oct '10
Here's a question that was posted yesterday to the KB:
Does MariaDB support IPV6?
http://kb.askmonty.org/v/does-mariadb-support-ipv6
Thanks.
--
Daniel Bartholomew
Monty Program - http://askmonty.org
1
0

29 Sep '10
All,
I'm preparing the release notes for MariaDB 5.2.2 Gamma. Is there
anything in particular I should mention?
As usual I'll be picking stuff out of the changelog to put into the
release notes, but if there's something I should make sure to mention,
let me know.
Thanks.
--
Daniel Bartholomew
Monty Program - http://askmonty.org
1
1

[Maria-developers] WL#150 New (by Sergei): Phone home: more data
by worklog-noreply@askmonty.org 26 Sep '10
by worklog-noreply@askmonty.org 26 Sep '10
26 Sep '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Phone home: more data
CREATION DATE..: Sun, 26 Sep 2010, 13:54
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......: Sergei
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 150 (http://askmonty.org/worklog/?tid=150)
VERSION........: Server-5.3
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
This task is about collecting more information in the server (and presenting it
via status variables or somehow) that is useful for phone home feature.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

24 Sep '10
Hello,
It is known that the MySQL codebase suffers from numerous unforseen
interactions between components, so that if we have a query X that works
when executed stand-alone, it may still break if it is executed as, for
example, INSERT ... SELECT .
So, the Random Query Generator has a module that runs each generated query
into different contexts. Here is the current list:
- as CREATE|INSERT|REPLACE ... SELECT
- as a prepared statement, twice
- as a stored procedure, twice
- as a UNION
- converted into a VIEW
The question is, what else is missing? I know about the following:
- DELETE/UPDATE, etc. operations that involve the query as a subquery
- triggers
but what about trying to evaluate the query inside an IF, CASE, FOR , or
anything else? If you have any suspicion that any of the code handles a
particular situation or context differently, please let me know so that I
can add it to the RQG.
Thank you.
Philip Stoev
1
0
Hi,
As you know, MySQL is no longer working on the old MySQL 6.0 codebase. I
noticed that the mysql-6.0-backup and mysql-6.0-codebase trees are no longer
in ~mysql-server on Launchpad.
Since there has been talk about backporting from 6.0 the backup and/or other
features not yet in MySQL 5.5/5.6, I thought it might be useful for people to
still have easy access to these trees, so I pushed them to ~maria on
Launchpad:
lp:~maria-captains/maria/mysql-6.0-backup
lp:~maria-captains/maria/mysql-6.0-codebase
- Kristian.
1
0

[Maria-developers] Removing very old options for --old, --new, --safe-mode
by Michael Widenius 23 Sep '10
by Michael Widenius 23 Sep '10
23 Sep '10
Hi!
I did notice that we haven't cleaned up the usage of the
--old, --new, --safe-mode and --skip-new options in a long time.
Here is a cleanup of this for MariaDB 5.2 (soon to be made gamma).
After this suggested change, here is how the options would work:
--new Use new functionality that will exist in next version of
MariaDB. This function exist to make it easier to prepare for an
upgrade. For version 5.1 this functions enables the LIST and RANGE
partitions functions for ndbcluster.
--old Use compatible behavior with previous main version for some
functionality. For MariaDB 5.1 this means that we are using the old,
MySQL 5.1 compatible, way to calculate checksums for records. If you
are using --old, CHECKSUM TABLE will always do a full table scan.
--safe_mode
Disable some potential unsafe optimization. For 5.2 these are:
INSERT DELAYED is disabled, myisam_recover_options is set to
DEFAULT (automatically recover crashed MyISAM files). For Aria
table, disable bulk insert optimization to enable one to use
maria_read_log to recover tables even if tables are deleted
(good for testing recovery).
--skip-new
Skip some new potentially unsafe functions. For 5.2 these are:
INSERT DELAYED is disabled, Query cache size is reset.
Here is the patch against MariaDB 5.2:
=== modified file 'sql/field.cc'
--- sql/field.cc 2010-08-05 19:56:11 +0000
+++ sql/field.cc 2010-09-14 15:45:01 +0000
@@ -6703,8 +6703,7 @@ void Field_string::sql_type(String &res)
length= cs->cset->snprintf(cs,(char*) res.ptr(),
res.alloced_length(), "%s(%d)",
- ((type() == MYSQL_TYPE_VAR_STRING &&
- !thd->variables.new_mode) ?
+ (type() == MYSQL_TYPE_VAR_STRING ?
(has_charset() ? "varchar" : "varbinary") :
(has_charset() ? "char" : "binary")),
(int) field_length / charset()->mbmaxlen);
=== modified file 'sql/item_cmpfunc.cc'
--- sql/item_cmpfunc.cc 2010-08-05 19:56:11 +0000
+++ sql/item_cmpfunc.cc 2010-09-14 16:41:01 +0000
@@ -4683,8 +4683,7 @@ bool Item_func_like::fix_fields(THD *thd
We could also do boyer-more for non-const items, but as we would have to
recompute the tables for each row it's not worth it.
*/
- if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
- !(specialflag & SPECIAL_NO_NEW_FUNC))
+ if (args[1]->const_item() && !use_strnxfrm(collation.collation))
{
String* res2 = args[1]->val_str(&cmp.value2);
if (!res2)
=== modified file 'sql/mysqld.cc'
--- sql/mysqld.cc 2010-08-24 22:44:50 +0000
+++ sql/mysqld.cc 2010-09-14 16:40:09 +0000
@@ -8725,11 +8725,7 @@ mysqld_get_one_option(int optid,
case (int) OPT_SKIP_NEW:
opt_specialflag|= SPECIAL_NO_NEW_FUNC;
delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
- myisam_concurrent_insert=0;
- myisam_recover_options= HA_RECOVER_NONE;
- sp_automatic_privileges=0;
- my_use_symdir=0;
- ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
+ ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
#ifdef HAVE_QUERY_CACHE
query_cache_size=0;
#endif
=== modified file 'sql/records.cc'
--- sql/records.cc 2010-07-17 19:58:08 +0000
+++ sql/records.cc 2010-09-14 16:40:09 +0000
@@ -216,7 +216,6 @@ bool init_read_record(READ_RECORD *info,
*/
if (!disable_rr_cache &&
!table->sort.addon_field &&
- ! (specialflag & SPECIAL_SAFE_MODE) &&
thd->variables.read_rnd_buff_size &&
!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
(table->db_stat & HA_READ_ONLY ||
=== modified file 'sql/sql_delete.cc'
--- sql/sql_delete.cc 2010-08-05 19:56:11 +0000
+++ sql/sql_delete.cc 2010-09-14 16:40:10 +0000
@@ -130,7 +130,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *
- there should be no delete triggers associated with the table.
*/
if (!using_limit && const_cond_result &&
- !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
(thd->lex->sql_command == SQLCOM_TRUNCATE ||
(!thd->current_stmt_binlog_row_based &&
!(table->triggers && table->triggers->has_delete_triggers()))))
=== modified file 'sql/sql_parse.cc'
--- sql/sql_parse.cc 2010-08-05 19:56:11 +0000
+++ sql/sql_parse.cc 2010-09-14 16:40:09 +0000
@@ -3086,9 +3086,7 @@ end_with_restore_list:
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
thd->query_plan_flags|= QPLAN_ADMIN;
- res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
- mysql_recreate_table(thd, first_table) :
- mysql_optimize_table(thd, first_table, &lex->check_opt);
+ res= mysql_optimize_table(thd, first_table, &lex->check_opt);
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
{
=== modified file 'sql/sql_select.cc'
--- sql/sql_select.cc 2010-08-24 22:44:50 +0000
+++ sql/sql_select.cc 2010-09-14 16:39:57 +0000
@@ -7187,8 +7187,6 @@ eq_ref_table(JOIN *join, ORDER *start_or
static bool
only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
{
- if (specialflag & SPECIAL_SAFE_MODE)
- return 0; // skip this optimize /* purecov: inspected */
tables&= ~PSEUDO_TABLE_BITS;
for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1)
{
-------------
Any comments ?
Regards,
Monty
2
2

Re: [Maria-developers] [Commits] Rev 2939: Fixed bug #53161. in file:///home/igor/maria/maria-5.1-bug53161/
by Oleksandr Byelkin 23 Sep '10
by Oleksandr Byelkin 23 Sep '10
23 Sep '10
Hi!
On 21.09.2010 07:22, igor(a)askmonty.org wrote:
> At file:///home/igor/maria/maria-5.1-bug53161/
>
> ------------------------------------------------------------
> revno: 2939
> revision-id: igor(a)askmonty.org-20100921042200-o52vwhnkz6kuwrcn
> parent: monty(a)askmonty.org-20100915130103-x6i3x2mjc5gxsu77
> committer: Igor Babaev<igor(a)askmonty.org>
> branch nick: maria-5.1-bug53161
> timestamp: Mon 2010-09-20 21:22:00 -0700
> message:
> Fixed bug #53161.
> The implementation of the virtual method not_null_tables for the class
> Item_outer_ref must always return 0.
>
Patch looks OK, thanks.
1
0

21 Sep '10
Hello Igor,
Please find attached the combined patch that addresses all of the review
feedback.
The tree is in launchpad and buildbot also:
https://code.launchpad.net/~maria-captains/maria/5.3-dsmrr-cpk
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
0

[Maria-developers] WL#149 New (by Dreas): Add inet6_ntop() and inet6_pton()
by worklog-noreply@askmonty.org 20 Sep '10
by worklog-noreply@askmonty.org 20 Sep '10
20 Sep '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Add inet6_ntop() and inet6_pton()
CREATION DATE..: Mon, 20 Sep 2010, 13:38
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 149 (http://askmonty.org/worklog/?tid=149)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
It would be nice if this is supported by MariaDB 5.1. UDFs are available at
http://labs.watchmouse.com/2009/10/extending-mysql-5-with-ipv6-functions/
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0
Hello all,
I saw the following on planet mysql today,
http://www.facebook.com/note.php?note_id=430801045932, and it got me
thinking. I remember at the 2010 storage engine summit, we discussed
having more types of alter table be done online. Here are the meeting
notes on that topic:
Smarter "ALTER TABLE"
Comment: Need to fix ALTER TABLE to fully support online operations.
Jonas: This is already implemented, but currently only in the
-telco cluster trees.
Antony is willing to look into backporting new ALTER TABLE to MariaDB
Does anyone know if any investigation has been done? I am curious to
learn about people's findings. I have done a little poking at the
mysql cluster code that has this feature, but I do not understand it
well enough to know integration risk and complexity.
Does anyone have any thoughts? I am curious to learn more.
Thanks
-Zardosht
2
1
Hi.
So, "Phone Home" or "MySQL feedback daemon" or "better name wanted"
feature.
It is something that can be installed together with MariaDB, it will
gather different statistic about how MariaDB is used and will send this
information anonymously to mariadb.org.
Not unlike the Uptimes Project or Debian Popularity Contest.
The complete specs will be here:
http://askmonty.org/worklog/Server-Sprint/?tid=12
There are basically four questions I'm thinking on.
1. Should that be a MariaDB plugin or a separate executable ?
I tend to prefer a separate executable. There is no need to keep it in
memory constantly - cron job can do. Being separate its bugs won't
affect the server. Being separate one instance can monitor many MariaDB
servers. It can be upgraded separately - and it's not tied to the server
release schedule.
The drawback - it won't be able to grab MariaDB internals easily, which
means it may not report some data that are worth reporting. But to solve
this we can add an I_S table that provides this information. This way
there's no "hidden" data to report, everything is available from the
SQL. Which is good :)
2. How to send the data.
We'll use HTTP. Seems to be the most universally working transport.
That's what other projects are using too - Uptimes Project uses UDP or
HTTP, Debian Popularity Contest - SMTP or HTTP.
We *may* want to add SMTP later, if needed.
3. Auditing.
How can we prove to paranoid users that we only send what we are saying
we send, and none of potentially private information.
Possible solution:
http sending should support a proxy (to work behind firewalls), so one
can install a logging proxy and record all the data sent. On the other
hand, we'd like to use SSL too.
We can support, besides direct http, a "wget mode" where the data are
sent by invoking wget (which supports proxies, SSL and --post-file)
and one could easily replace wget with a simple script that logs
all the data.
4. What to report.
That's the most interesting part :)
note that not everything from below is collected in MariaDB now, but I
describe the ideal case, what would be useful to know to steer MariaDB
development in the right direction.
The principle I used was not "let's grab as much as we can" but "on a
need-to-know basis". For example, we may need to decide whether to
optimize huge IN (...) lists or GIS first. Knowing what is used more
often would help to make a correct decision.
hardware: CPU, RAM
OS (linux distribution, kernel)
mariadb version, memory usage
parts of config (e.g. buffer sizes)
list of installed plugins
number of databases, max/avg number of tables in a database,
max/avg db/table size
uptime
something that indicates the load, e.g. average qps
how much a particular feature is used:
Com_ counters from SHOW STATUS
plugin usage counters
per feature, like GIS, replication, etc.
per query parts, like ORDER BY, subquery in the FROM, IN subquery ...
how useful is query cache (hit ratio?)
What else ?
Regards,
Sergei
2
5

Re: [Maria-developers] Seeking command syntax feedback (Still Re: Per-db binlogging)
by Weldon Whipple 16 Sep '10
by Weldon Whipple 16 Sep '10
16 Sep '10
On Wed, Sep 15, 2010 at 2:00 PM, Sergei Golubchik <serg(a)askmonty.org> wrote:
> Hi, Weldon!
Hi, Sergei!
>
> On Sep 15, Weldon Whipple wrote:
<snip/>
>> 2. FLUSH TABLES WITH READ LOCK FOR DATABASE dbname;
>>
>> (I just added an optional 'FOR DATABASE dbname' to the already
>> existing command--which still works, BTW. Is this a misuse of the word
>> "FOR"?)
>> This is the command that locks the tables before someone (some
>> program) dumps/copies the tables that will be moved to another server.
>> It flushes and locks only one database.
>
> This would be difficult to implement.
>
> FLUSH TABLES WITH READ LOCK is not implemented in a way that can be
> generalized to support per-database locks :(
I had guessed as much. (The method in my DB_BINLOG_MGR method that
implements that functionality consists of a mutex lock, a comment
about some sort of miracle happening, then a mutex unlock.)
I wonder if there might be a way of inhibiting some user database
(temporarily) from changing ...
Alternately, I suppose we could do a global FLUSH TABLE WITH READ
LOCK/ UNLOCK TABLES.
Or ... (???)
> Besides, I personally wouldn't worry much about the syntax. It's
> something you can easily change anytime - e.g. replace BINLOG with
> BINLOGGING or FOR with something else.
Yeah, every time I write a new prototype I tweak the syntax a bit.
At the moment I'm just trying to settle on an implementation that
would work for our company (and still be of some sort of general use).
>
> Regards,
> Sergei
>
Thanks,
Weldon
2
1
On Tue, Sep 14, 2010 at 3:02 AM, MARK CALLAGHAN <mdcallag(a)gmail.com> wrote:
> +maria-discuss as they are working in replication too
To be exact, maria-developers@ is the counterpart to internals@mysql,
although everyone should be reading maria-discuss@ too. I'm now
leaving both in CC.
> On Mon, Sep 13, 2010 at 1:52 PM, Weldon Whipple <weldon(a)whipple.org> wrote:
>> Greetings!
>>
>> My employer has asked me to implement per-DB binlogging for
>> MySQL. I've been working on prototypes for 3-4 weeks now, and decided
>> it's time to post to this list to ask for comments, suggestions,
>> condolences, etc. (I've been a "lurker" for quite awhile. I hope this
>> post isn't too far off the mark) The assignment is *only* for master-side
>> binlogging. (It doesn't require a slave/replication-side implementation.)
>>
>>
>> Why I Want to Do It.
>> -------------------
>>
>> I work for an ISP that hosts (last I heard--I HOPE I'm not lying) over
>> 2 million domains. Customers are allowed to have (almost) unlimited
>> MySQL databases. Migrating an account from one physical server to
>> another is a daunting task. (A typical server has easily 2000+
>> [sometimes far more] databases.) Global mysqld binlogging isn't
>> feasible when we want to migrate (for example) a single account to
>> another server.
>>
>> Our proposed scenario goes something like this:
<cut>
Do I understand correctly, that in the normal case you do not run with
binlog on at all? You would only turn on this kind of per-database
binlog when needed?
If that would be the case, then I don't see why --binlog-do-db
wouldn't already do exactly what you want, except that you'd require a
restart to change it. So all you need to implement would be the
ability to set it as a system variable and not just in the conf file.
(http://dev.mysql.com/doc/refman/5.1/en/replication-options-binary-log.html#…)
Alternatively, if you are also running a "global" binlog, then as Mark
suggested, don't write additional per database binlogs, rather get
your information from the "global" binlog and filter out what should
be replicated instead by using --replicate-do-db. Again, it is not
currently possible to set this on/off without restart.
(http://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.html#optio…)
Finally, for anyone wishing to implement their own binlogging and
replication, I should advertise our work in MariaDB on a generic
"replication plugin API". Using this you could implement your own
replication plugin that would do precisely what you want, but you
could still leave the original replication code untouched. (You could
of course "fork" it to make your own plugin if you wanted.)
Kristian Nielsen in CC is working on that, and you can read about it here:
http://askmonty.org/wiki/ReplicationProject
http://askmonty.org/worklog/?tid=107
http://askmonty.org/worklog/?tid=120
henrik
PS: It is not exactly the same use case, but also see mine and Igor's
presentation from last years MySQL user conference.
http://assets.en.oreilly.com/1/event/36/Valuable%20MariaDB%20Features%20Tha…
...from slide 10 onwards. Summary: You can use mysqlbinlog instead of
replication and this allows all kinds of scriptable hacks to occur
between master and slave.
henrik
--
henrik.ingo(a)avoinelama.fi
+358-40-5697354
www.openlife.cc
2
1
Regarding http://askmonty.org/worklog/Client-RawIdeaBin/?tid=39
...user "Guest" in June has deleted all the dependencies on a group of
mysqlbinlog tasks. Why? MWL#39 existed to act as an entry point to
some interrelated mysqlbinlog tasks. Now there is no simple way for me
to look the up all at once.
*grumble*
henrik
--
henrik.ingo(a)avoinelama.fi
+358-40-5697354
www.openlife.cc
1
0
Hi.
For a while, I had a small personal gripe that it is not easy to see
what plugins are configured to be built and how. That is, I know where
to look (configure prints all that when working, but not
alphabetically, so a particular plugin name isn't easy to spot) but I
had to explain this to other often enough to realize that it's not at
all obvious.
The configure script prints at the end the small configuration report.
I've extended it from
--< cut >------------------------------------
config.status: executing my_config.h commands
You can find information about MariaDB at
http://askmonty.org/wiki/index.php/MariaDB
Remember to check the platform specific part of the reference manual for
hints about installing MariaDB on your platform. Also have a look at the
files in the Docs directory.
---
Configuration summary for MariaDB Server version 5.1.50-MariaDB
* Installation prefix: /usr/local
* System type: unknown-linux-gnu
* Host CPU: x86_64
* C Compiler: gcc (Gentoo 4.4.3-r2 p1.2) 4.4.3
* C++ Compiler: g++ (Gentoo 4.4.3-r2 p1.2) 4.4.3
* Debug enabled: no
* Community Features: yes
---
Thank you for choosing MariaDB!
--< cut >------------------------------------
to include all plugins in alphabetical order
(and moved informational text down to improve its visibility,
as the plugin list is long):
--< cut >------------------------------------
config.status: executing my_config.h commands
---
Configuration summary for MariaDB Server version 5.2.2-MariaDB-gamma
* Archive Storage Engine: plugin
* Aria Storage Engine: yes
* Blackhole Storage Engine: plugin
* CSV Storage Engine: yes
* Cluster Storage Engine: no
* Collection of Authentication Plugins: plugin
* Daemon Example Plugin: plugin
* Example Storage Engine: plugin
* Federated Storage Engine: plugin
* FederatedX Storage Engine: plugin
* Graph Storage Engine: plugin
* IBM DB2 for i Storage Engine: no
* InnoDB Storage Engine: plugin
* Memory Storage Engine: yes
* MyISAM MERGE Engine: yes
* MyISAM Storage Engine: yes
* PBXT Storage Engine: no
* Partition Support: no
* Simple Parser: plugin
* Sphinx Storage Engine: plugin
* XtraDB Storage Engine: plugin
* Installation prefix: /usr/local
* System type: unknown-linux-gnu
* Host CPU: x86_64
* C Compiler: gcc (Gentoo 4.4.3-r2 p1.2) 4.4.3
* C++ Compiler: g++ (Gentoo 4.4.3-r2 p1.2) 4.4.3
* Debug enabled: no
* Community Features: yes
---
You can find information about MariaDB at
http://askmonty.org/wiki/index.php/MariaDB
Remember to check the platform specific part of the reference manual for
hints about installing MariaDB on your platform. Also have a look at the
files in the Docs directory.
Thank you for choosing MariaDB!
--< cut >------------------------------------
So, what do you think? Too long to be useful?
Or shall I push ?
Need to reorder sections? (yes, it's a bikeshed color question, I know)
Regards,
Sergei
2
1

[Maria-developers] really annoying bug in mysql 5.0/5.1 optimiser, opened for more than 2 years, and still present in MariaDB
by Jocelyn Fournier 15 Sep '10
by Jocelyn Fournier 15 Sep '10
15 Sep '10
Hi,
There's a really annoying bug in the mysql optimiser existing for a
really long time now, and which has a direct impact on performances :
http://bugs.mysql.com/bug.php?id=36817
Since MySQL definitly doesn't seem to want to fix it, I hope MariaDB
could do something to help the poor developpers who need to heavily hack
there apps with USE INDEX ;)
Note I've tested with mariadb 5.2.1-beta, and the bug is still present.
Thanks a lot !
Jocelyn Fournier
2
3

[Maria-developers] WL#148 New (by Sanja): Move the transformations for inequality predicates with ALL/ANY subqueries from the prepare phase into the optimization phase.
by worklog-noreply@askmonty.org 15 Sep '10
by worklog-noreply@askmonty.org 15 Sep '10
15 Sep '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Move the transformations for inequality predicates with ALL/ANY
subqueries from the prepare phase into the optimization
phase.
CREATION DATE..: Wed, 15 Sep 2010, 07:25
SUPERVISOR.....: Igor
IMPLEMENTOR....: Sanja
COPIES TO......: Monty
CATEGORY.......: Server-Sprint
TASK ID........: 148 (http://askmonty.org/worklog/?tid=148)
VERSION........: Benchmarks-3.0
STATUS.........: Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 64 (hours remain)
ORIG. ESTIMATE.: 64
PROGRESS NOTES:
DESCRIPTION:
Move the transformations for inequality predicates with ALL/ANY subqueries from
the prepare phase into the optimization phase from preparation phase.
It could be done in any place of the optimisation.
Now there is 2 kind of the MAX/MIN optimisation for non-correlated subqueries:
If it is possible (there is no aggregate functions in the subquery) ALL/ANY
converted to
<LEFT> <comp> (SELECT <min/max>(<select_list>) ...)
Otherwise:
<LEFT> <comp> (MAX/MIN_SELECT <select_list> ...)
Where MAX/MIN_SELECT is special subquery which returns max or min result of all
found by the subquery.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#147 New (by Dreas): Support native IPv6
by worklog-noreply@askmonty.org 13 Sep '10
by worklog-noreply@askmonty.org 13 Sep '10
13 Sep '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Support native IPv6
CREATION DATE..: Mon, 13 Sep 2010, 11:10
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 147 (http://askmonty.org/worklog/?tid=147)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
IPv6 is quickly gaining popularity. Unfortunately MySQL 5.0/5.1 do not support
IPv6. It appears that for MySQL 6 they work on IPv6 support
(http://forge.mysql.com/worklog/task.php?id=798) however since that release will
still be far away it may be good to backport the IPv6 changes to MariaDB 5.1
already. It would definitely add another clear advantage of MariaDB over MySQL
(5.1).
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0
This release should be uploaded to the OSUOSL mirror within a few
hours. I'll check when I get up and if things look good I'll activate
the download, release notes, and changelog pages.
One thing that hasn't been done (that I can see) is for a
"mariadb-5.1.50" tag to be added to the 5.1 tree on launchpad as per
the release process ( http://kb.askmonty.org/v/release-process ).
Monty: can you or one of the other devs add the tag?
Looking at the release process just now I see several steps that need
to be updated. I'll do so after this release is out.
One last question: What are the highlights of this release (other than
the merge with MySQL 5.1.50)?
Thanks.
--
Daniel Bartholomew
Monty Program - http://askmonty.org
2
1

[Maria-developers] WL#145 New (by Sergei): user defined data types
by worklog-noreply@askmonty.org 09 Sep '10
by worklog-noreply@askmonty.org 09 Sep '10
09 Sep '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: user defined data types
CREATION DATE..: Thu, 09 Sep 2010, 08:46
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 145 (https://askmonty.org/worklog/?tid=145)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 40
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
soften we get requests for new data types like timestamps with microsecond
precision or ipv4/ipv6. This could be solved with user defined types -
implemented via plugins or special SQL syntax, whatever is appropriate.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#144 New (by Sergei): query rewrite api
by worklog-noreply@askmonty.org 09 Sep '10
by worklog-noreply@askmonty.org 09 Sep '10
09 Sep '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: query rewrite api
CREATION DATE..: Thu, 09 Sep 2010, 08:14
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 144 (https://askmonty.org/worklog/?tid=144)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
An API for query rewrites.
It may be a special rewrite plugin or part of the storage engine or some other
API. Preferably it should not force plugin to parse or work with the sql string,
but it may provide a DOM-like representation of the query and let the plugin to
manipulate the tree nodes. Perhaps this needs the "Abstract Query Tree" task to
be done first.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

[Maria-developers] WL#143 New (by Sergei): full-text search engine plugin
by worklog-noreply@askmonty.org 09 Sep '10
by worklog-noreply@askmonty.org 09 Sep '10
09 Sep '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: full-text search engine plugin
CREATION DATE..: Thu, 09 Sep 2010, 07:38
SUPERVISOR.....: Sergei
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 143 (https://askmonty.org/worklog/?tid=143)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 80
WORKED HOURS...: 0
ESTIMATE.......: 320 (hours remain)
ORIG. ESTIMATE.: 320
PROGRESS NOTES:
DESCRIPTION:
A new plugin type - "full-text search engine".
Ideally, it'll allow to add full-text search to any table, independently from
the storage engine, providing fully integrated SQL syntax, still allowing to
chose different underlying FTS implementations
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0

Re: [Maria-developers] Architecture review of MWL#132 Transaction coordinator plugin
by Sergei Golubchik 08 Sep '10
by Sergei Golubchik 08 Sep '10
08 Sep '10
Hi, Kristian!
Now, WL#132 - Transaction coordinator plugin
> ============= High-Level Specification
...
> In current MariaDB, we have two different TC implementations (as well
> as a "dummy" empty implementation that I do not know if is used).
The code in mysqld.cc is
tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
(TC_LOG *) &mysql_bin_log :
(TC_LOG *) &tc_log_mmap) :
(TC_LOG *) &tc_log_dummy);
so, tc_log_dummy is used when there's at most one xa-capable engine.
But MySQL does not use 2pc for a transaction unless it has at least two
xa-capable participants. In other words, tc_log_dummy is never used.
> Binary log
> ----------
>
> The binary log implements also a "fake" storage engine, mainly to hook
> into the commit (and prepare) phase of transaction processing. This is
> mainly used for statements in non-transactional engines, which are
> "committed" and written to the binary log outside of the TC and
> log_xid() framework.
No, this is used to make the number of xa-capable transaction
participants more than one and to force MySQL to use 2PC.
> TC interface subclasses
> -----------------------
>
> The MWL#116 has two different algorithms for handling commit order and
> invoking prepare_ordered() and commit_ordered() handler methods:
>
> - One used with TC_MMAP, which needs no correspondance between
> engines and TC. This uses the existing log_xid() interface.
>
> - One used with the binary log TC, which ensures same commit order in
> engines and binary log, and which uses a new single-threaded
> group_log_xid() TC interface to efficiently do group commit.
>
> In the prototype patch for MWL#116, these two methods are mixed with
> each other in the function ha_commit_trans(), and the logic is quite
> complex. Using the log_and_order() TC generalisation provides a nice
> cleanup of this.
>
> We implement two subclasses of the TC interface:
>
> - One class TC_LOG_unordered for the method used with TC_MMAP. This
> implements the old log_xid() interface.
>
> - One class TC_LOG_group_commit for the method used for the binary
> log. This implements the new group_log_xid() interface.
>
> Each subclass implements the corresponding algorithm for invoking
> prepare_ordered() and commit_ordered(), using the same mechanisms as
> in MWL#116, but implemented in a cleaner way. The ha_commit_trans()
> function then has no details about prepare_ordered() or
> commit_ordered(), it just calls into tc_log->log_and_order(), which
> handles the necessary details.
>
> Thus a simple TC plugin similar to the binary log or TC_MMAP can
> implement one of the simple interfaces log_xid() or group_log_xid(),
> without having to worry about prepare_ordered() and commit_ordered().
> But a plugin like Galera that needs to do more can implement the more
> general interface.
I still see no real value in keeping or supporting log_xid() interface.
I think we can only implement one interface - group_log_xid() - and
that's enough.
> ============= Low-Level Design
...
> log_and_order()
> Requests a decision to commit (non-zero return) or rollback (zero
> return) of the transaction. At this point, the transaction has
> been successfully prepared in all engines.
>
> The method must call run_prepare_ordered(), in a way so that calls
> in different threads happen in the order that the transactions are
> committed. This call must be protected by the global
> LOCK_prepare_ordered mutex.
>
> The method must then call run_commit_ordered(), protected by
> LOCK_commit_ordered, again so that different threads are called in
> the order that transactions are committed.
>
> The idea with prepare_ordered() is to call it as early as possible
> after commit order has been decided, for example to release locks
> early. In particular, a transaction can still be rolled back after
> prepare_ordered() (for example in case of a crash). In contrast,
> commit_ordered() may only be called after the transaction is
> durably committed in the TC.
>
> If need_prepare_ordered or need_commit_ordered is passed as FALSE,
> then the corresponding call need not be done. It is safe to do it
> anyway, however omitting it avoids the need to take a global
> mutex.
Why would this ever be needed ?
(I mean need_prepare_ordered or need_commit_ordered being FALSE)
...
> A TC based on this interface overrides group_log_xid() and
> xid_log_after() instead of log_and_order(), and again does not need to
> deal with any {prepare,commit}_ordered().
Why do you need xid_log_after here ?
General comment:
Wouldn't it be simpler to create only group_log_xid() interface, no
log_and_order() or log_xid() ? The tc plugin gets the list in
group_log_xid() - it can reorder the list any way it wants, call
prepare_ordered() and commit_ordered() as needed and so on.
In this interpretation, group_log_xid() can meet all the use cases.
And there's no need to create a multitude of methods that one
needs to get familiar with before implementing a TC plugin.
Regards,
Sergei
P.S. Minor detail - there could be helper functions like
iterate_the_list_and_call_prepare_ordered(), that the plugin can use.
2
2