mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	Merge work:/home/bk/mysql into donna.mysql.com:/home/my/bk/mysql
This commit is contained in:
		@@ -1,25 +1,2 @@
 | 
			
		||||
bk@work.mysql.com
 | 
			
		||||
davida@work.mysql.com
 | 
			
		||||
jamppa@work.mysql.com
 | 
			
		||||
jcole@ham.spaceapes.com
 | 
			
		||||
jcole@jcole.burghcom.com
 | 
			
		||||
jcole@nslinux.bedford.progress.com
 | 
			
		||||
jcole@tetra.bedford.progress.com
 | 
			
		||||
jcole@tetra.spaceapes.com
 | 
			
		||||
matt@work.mysql.com
 | 
			
		||||
monty@tramp.mysql.fi
 | 
			
		||||
monty@donna.mysql.com
 | 
			
		||||
monty@work.mysql.com
 | 
			
		||||
mwagner@evoq.home.mwagner.org
 | 
			
		||||
nusphere@main.burghcom.com
 | 
			
		||||
paul@central.snake.net
 | 
			
		||||
paul@work.mysql.com
 | 
			
		||||
sasha@mysql.sashanet.com
 | 
			
		||||
sasha@work.mysql.com
 | 
			
		||||
serg@infomag.ape.relarn.ru
 | 
			
		||||
serg@work.mysql.com
 | 
			
		||||
sinisa@work.mysql.com
 | 
			
		||||
spurr@nslinux.bedford.progress.com
 | 
			
		||||
tim@localhost.polyesthetic.msg
 | 
			
		||||
tim@threads.polyesthetic.msg
 | 
			
		||||
tim@work.mysql.com
 | 
			
		||||
tonu@work.mysql.com
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										178
									
								
								Docs/manual.texi
									
									
									
									
									
								
							
							
						
						
									
										178
									
								
								Docs/manual.texi
									
									
									
									
									
								
							@@ -305,14 +305,14 @@ Post-installation Setup and Testing
 | 
			
		||||
* Command-line options::        Command-line options
 | 
			
		||||
* Option files::                Option files
 | 
			
		||||
 | 
			
		||||
Is there anything special to do when upgrading/downgrading MySQL?
 | 
			
		||||
Is There Anything Special to Do when Upgrading/Downgrading MySQL?
 | 
			
		||||
 | 
			
		||||
* Upgrading-from-3.22::         Upgrading from a 3.22 version to 3.23
 | 
			
		||||
* Upgrading-from-3.21::         Upgrading from a 3.21 version to 3.22
 | 
			
		||||
* Upgrading-from-3.20::         Upgrading from a 3.20 version to 3.21
 | 
			
		||||
* Upgrading-to-arch::           Upgrading to another architecture
 | 
			
		||||
 | 
			
		||||
How standards-compatible is MySQL?
 | 
			
		||||
How Standards-compatible Is MySQL?
 | 
			
		||||
 | 
			
		||||
* Extensions to ANSI::          @strong{MySQL} extensions to ANSI SQL92
 | 
			
		||||
* Ansi mode::                   Running @strong{MySQL} in ANSI mode
 | 
			
		||||
@@ -321,7 +321,7 @@ How standards-compatible is MySQL?
 | 
			
		||||
* Standards::                   What standards does @strong{MySQL} follow?
 | 
			
		||||
* Commit-rollback::             How to cope without @code{COMMIT}-@code{ROLLBACK}
 | 
			
		||||
 | 
			
		||||
Functionality missing from MySQL
 | 
			
		||||
Functionality Missing from MySQL
 | 
			
		||||
 | 
			
		||||
* Missing Sub-selects::         Sub-selects
 | 
			
		||||
* Missing SELECT INTO TABLE::   @code{SELECT INTO TABLE}
 | 
			
		||||
@@ -335,7 +335,7 @@ Foreign Keys
 | 
			
		||||
 | 
			
		||||
* Broken Foreign KEY::          Reasons NOT to use foreign keys
 | 
			
		||||
 | 
			
		||||
The MySQL access privilege system
 | 
			
		||||
The MySQL Access Privilege System
 | 
			
		||||
 | 
			
		||||
* General security::            General security
 | 
			
		||||
* Security::                    How to make @strong{MySQL} secure against crackers
 | 
			
		||||
@@ -353,7 +353,7 @@ The MySQL access privilege system
 | 
			
		||||
* Passwords::                   How to set up passwords
 | 
			
		||||
* Access denied::               Causes of @code{Access denied} errors
 | 
			
		||||
 | 
			
		||||
MySQL language reference
 | 
			
		||||
MySQL Language Reference
 | 
			
		||||
 | 
			
		||||
* Literals::                    Literals: how to write strings and numbers
 | 
			
		||||
* Variables::                   User variables
 | 
			
		||||
@@ -394,7 +394,7 @@ MySQL language reference
 | 
			
		||||
* CREATE FUNCTION::             @code{CREATE FUNCTION} syntax
 | 
			
		||||
* Reserved words::              Is @strong{MySQL} picky about reserved words?
 | 
			
		||||
 | 
			
		||||
Literals: how to write strings and numbers
 | 
			
		||||
Literals: How to Write Strings and Numbers
 | 
			
		||||
 | 
			
		||||
* String syntax::               Strings
 | 
			
		||||
* Number syntax::               Numbers
 | 
			
		||||
@@ -402,11 +402,11 @@ Literals: how to write strings and numbers
 | 
			
		||||
* NULL values::                 @code{NULL} values
 | 
			
		||||
* Legal names::                 Database, table, index, column and alias names
 | 
			
		||||
 | 
			
		||||
Database, table, index, column and alias names
 | 
			
		||||
Database, Table, Index, Column, and Alias Names
 | 
			
		||||
 | 
			
		||||
* Name case sensitivity::       Case sensitivity in names
 | 
			
		||||
 | 
			
		||||
Column types
 | 
			
		||||
Column Types
 | 
			
		||||
 | 
			
		||||
* Storage requirements::        Column type storage requirements
 | 
			
		||||
* Numeric types::               Numeric types
 | 
			
		||||
@@ -417,21 +417,21 @@ Column types
 | 
			
		||||
* Multiple-column indexes::     Multiple-column indexes
 | 
			
		||||
* Other-vendor column types::   Using column types from other database engines
 | 
			
		||||
 | 
			
		||||
Date and time types
 | 
			
		||||
Date and Time Types
 | 
			
		||||
 | 
			
		||||
* Y2K issues::                  Y2K issues and date types
 | 
			
		||||
* DATETIME::                    The @code{DATETIME}, @code{DATE} and @code{TIMESTAMP} types
 | 
			
		||||
* TIME::                        The @code{TIME} type
 | 
			
		||||
* YEAR::                        The @code{YEAR} type
 | 
			
		||||
 | 
			
		||||
String types
 | 
			
		||||
String Types
 | 
			
		||||
 | 
			
		||||
* CHAR::                        The @code{CHAR} and @code{VARCHAR} types
 | 
			
		||||
* BLOB::                        The @code{BLOB} and @code{TEXT} types
 | 
			
		||||
* ENUM::                        The @code{ENUM} type
 | 
			
		||||
* SET::                         The @code{SET} type
 | 
			
		||||
 | 
			
		||||
Functions for use in @code{SELECT} and @code{WHERE} clauses
 | 
			
		||||
Functions for Use in @code{SELECT} and @code{WHERE} Clauses
 | 
			
		||||
 | 
			
		||||
* Grouping functions::          Grouping functions
 | 
			
		||||
* Arithmetic functions::        Normal arithmetic operations
 | 
			
		||||
@@ -447,7 +447,7 @@ Functions for use in @code{SELECT} and @code{WHERE} clauses
 | 
			
		||||
* Miscellaneous functions::     Miscellaneous functions
 | 
			
		||||
* Group by functions::          Functions for @code{GROUP BY} clause
 | 
			
		||||
 | 
			
		||||
@code{CREATE TABLE} syntax
 | 
			
		||||
@code{CREATE TABLE} Syntax
 | 
			
		||||
 | 
			
		||||
* Silent column changes::       Silent column changes
 | 
			
		||||
 | 
			
		||||
@@ -580,6 +580,7 @@ Speed of queries that access or update data
 | 
			
		||||
* Estimating performance::      Estimating query performance
 | 
			
		||||
* SELECT speed::                Speed of @code{SELECT} queries
 | 
			
		||||
* Where optimizations::         How MySQL optimizes @code{WHERE} clauses
 | 
			
		||||
* DISTINCT optimization::       
 | 
			
		||||
* LEFT JOIN optimization::      How MySQL optimizes @code{LEFT JOIN}
 | 
			
		||||
* LIMIT optimization::          How MySQL optimizes @code{LIMIT}
 | 
			
		||||
* Insert speed::                Speed of @code{INSERT} queries
 | 
			
		||||
@@ -4393,14 +4394,47 @@ last version number is newer than yours).  We have tried to fix only
 | 
			
		||||
fatal bugs and make small, relatively safe changes to that version.
 | 
			
		||||
@end itemize
 | 
			
		||||
 | 
			
		||||
The second decision to make is whether you want to use a source distribution or
 | 
			
		||||
a binary distribution:
 | 
			
		||||
The second decision to make is whether you want to use a source
 | 
			
		||||
distribution or a binary distribution.  In most cases you should probably
 | 
			
		||||
use a binary distribution, if there exist one for your platform, as this
 | 
			
		||||
is generally, it will be easier to install than a source distribution.
 | 
			
		||||
 | 
			
		||||
In the following cases you will probably be better of with a source
 | 
			
		||||
installation:
 | 
			
		||||
 | 
			
		||||
@itemize @bullet
 | 
			
		||||
@item
 | 
			
		||||
If you want to run @strong{MySQL} on a platform for which a current binary
 | 
			
		||||
distribution exists, use that.  Generally, it will be easier to install
 | 
			
		||||
than a source distribution.
 | 
			
		||||
If you want to install @strong{MySQL} at some explicit location. (The standard
 | 
			
		||||
binary distributions are 'ready to run' at any place, but you may want
 | 
			
		||||
to get even more flexibility).
 | 
			
		||||
 | 
			
		||||
@item
 | 
			
		||||
If you want to configure @code{mysqld} with some extra feature that is NOT in
 | 
			
		||||
the standard binary distributions. Here follows a list of the most common
 | 
			
		||||
extra options that you may want to use
 | 
			
		||||
 | 
			
		||||
@itemize @bullet
 | 
			
		||||
@item --with-berkeley-db
 | 
			
		||||
@item --with-raid
 | 
			
		||||
@item --with-libwrap
 | 
			
		||||
@item --with-named-z-lib  (This is done for some of the binaries)
 | 
			
		||||
@item --with-debugging[=full]
 | 
			
		||||
@end itemize
 | 
			
		||||
 | 
			
		||||
@item
 | 
			
		||||
The default binary distribution is normally compiled with support
 | 
			
		||||
for all characters sets and should work on a variety of processors from
 | 
			
		||||
the same processor family.
 | 
			
		||||
 | 
			
		||||
If you want a faster @strong{MySQL} server you may want to recompile it
 | 
			
		||||
with support for only the character sets you need, use a better compiler
 | 
			
		||||
(like pgcc) or use compiler options that are better optimized for your
 | 
			
		||||
processor.
 | 
			
		||||
 | 
			
		||||
@item
 | 
			
		||||
If you have found a bug and reported it to the @strong{MySQL}
 | 
			
		||||
development team you will probably got a patch that you need to apply to
 | 
			
		||||
the source distribution to get the bug fixed.
 | 
			
		||||
 | 
			
		||||
@item
 | 
			
		||||
If you want to read (and/or modify) the C and C++ code that makes up
 | 
			
		||||
@@ -9122,6 +9156,7 @@ for clients from option files.
 | 
			
		||||
@item @strong{Filename} @tab @strong{Purpose}
 | 
			
		||||
@item @code{/etc/my.cnf} @tab Global options
 | 
			
		||||
@item @code{DATADIR/my.cnf} @tab Server-specific options
 | 
			
		||||
@item @code{defaults-extra-file} @tab The file specified with --defaults-extra-file=#
 | 
			
		||||
@item @code{~/.my.cnf} @tab User-specific options
 | 
			
		||||
@end multitable
 | 
			
		||||
 | 
			
		||||
@@ -9233,15 +9268,19 @@ there are sample configuration files for small, medium, large, and very
 | 
			
		||||
large systems.  You can copy @file{my-xxxx.cnf} to your home directory
 | 
			
		||||
(rename the copy to @file{.my.cnf}) to experiment with this.
 | 
			
		||||
 | 
			
		||||
To tell a @strong{MySQL} program not to read any option files, specify
 | 
			
		||||
@code{--no-defaults} as the first option on the command line.  This
 | 
			
		||||
@strong{MUST} be the first option or it will have no effect!
 | 
			
		||||
If you want to check which options are used, you can give the option
 | 
			
		||||
@code{--print-defaults} as the first option.
 | 
			
		||||
All @strong{MySQL} clients that support option files support the
 | 
			
		||||
following options:
 | 
			
		||||
 | 
			
		||||
If you want to force the use of a specific config file, you can use the option
 | 
			
		||||
@code{--defaults-file=full-path-to-default-file}. If you do this, only the
 | 
			
		||||
specified file will be read.
 | 
			
		||||
@multitable @columnfractions .40 .60
 | 
			
		||||
@item --no-defaults @tab Don't read any option files.
 | 
			
		||||
@item --print-defaults @tab Print the program name and all options that it will get.
 | 
			
		||||
@item --defaults-file=full-path-to-default-file @tab Only use the given configuration file.
 | 
			
		||||
@item --defaults-extra-file=full-path-to-default-file @tab Read this configuration file after the global configuration file but before the user configuration file.
 | 
			
		||||
@end multitable
 | 
			
		||||
 | 
			
		||||
Note that the above options must be first on the command line to work!
 | 
			
		||||
@code{--print-defaults} may however be used directly after the
 | 
			
		||||
@code{--defaults-xxx-file} commands.
 | 
			
		||||
 | 
			
		||||
Note for developers:  Option file handling is implemented simply by
 | 
			
		||||
processing all matching options (that is, options in the appropriate group)
 | 
			
		||||
@@ -9252,6 +9291,19 @@ read option files, you need add only two lines to give it that capability.
 | 
			
		||||
Check the source code of any of the standard @strong{MySQL} clients to see
 | 
			
		||||
how to do this.
 | 
			
		||||
 | 
			
		||||
In shell scripts you can use the @file{my_print_defaults} command to parse the
 | 
			
		||||
config files:
 | 
			
		||||
 | 
			
		||||
@example
 | 
			
		||||
 | 
			
		||||
shell> my_print_defaults client mysql
 | 
			
		||||
--port=3306
 | 
			
		||||
--socket=/tmp/mysql.sock
 | 
			
		||||
--no-auto-rehash
 | 
			
		||||
@end example
 | 
			
		||||
 | 
			
		||||
The above output contains all options for the groups 'client' and 'mysql'.
 | 
			
		||||
 | 
			
		||||
@node Upgrade,  , Post-installation, Installing
 | 
			
		||||
@section Is There Anything Special to Do when Upgrading/Downgrading MySQL?
 | 
			
		||||
@cindex upgrading
 | 
			
		||||
@@ -20035,6 +20087,9 @@ resolve the query. Here follows an explanation of the different text
 | 
			
		||||
strings that can be found in this column:
 | 
			
		||||
 | 
			
		||||
@table @code
 | 
			
		||||
@item Distinct
 | 
			
		||||
@strong{MySQL} will not continue searching for more rows for the current row
 | 
			
		||||
combination after it has found the first matching row.
 | 
			
		||||
@item Not exists
 | 
			
		||||
@strong{MySQL} was able to do a @code{LEFT JOIN} optimization on the
 | 
			
		||||
query and will not examine more rows in this table for a row combination
 | 
			
		||||
@@ -20779,9 +20834,28 @@ The biggest differences between the ANSI SQL and @strong{MySQL} versions of
 | 
			
		||||
@code{GRANT} are:
 | 
			
		||||
 | 
			
		||||
@itemize @bullet
 | 
			
		||||
@item
 | 
			
		||||
In @strong{MySQL} privileges are given for an username + hostname combination
 | 
			
		||||
and not only for an username.
 | 
			
		||||
 | 
			
		||||
@item
 | 
			
		||||
ANSI SQL doesn't have global or database-level privileges and ANSI SQL
 | 
			
		||||
doesn't support all privilege types that @strong{MySQL} supports.
 | 
			
		||||
@strong{MySQL} doesn't support the ANSI SQL @code{TRIGGER}, @code{EXECUTE} or
 | 
			
		||||
@code{UNDER} privileges.
 | 
			
		||||
 | 
			
		||||
@item
 | 
			
		||||
ANSI SQL privileges are structured in a hierarchal manner. If you remove
 | 
			
		||||
an user, all privileges the user has granted are revoked. In
 | 
			
		||||
@strong{MySQL} the granted privileges are not automaticly revoked, but
 | 
			
		||||
you have to revoke these yourself if needed.
 | 
			
		||||
 | 
			
		||||
@item
 | 
			
		||||
If you in @code{MySQL} have the @code{INSERT} grant on only part of the
 | 
			
		||||
columns in a table, you can execute @code{INSERT} statements on the
 | 
			
		||||
table; The columns for which you don't have the @code{INSERT} privilege
 | 
			
		||||
will set to their default values. ANSI SQL requires you to have the
 | 
			
		||||
@code{INSERT} privilege on all columns.
 | 
			
		||||
 | 
			
		||||
@item
 | 
			
		||||
When you drop a table in ANSI SQL, all privileges for the table are revoked.
 | 
			
		||||
@@ -26092,6 +26166,7 @@ great tool to find out if this is a problem with your query.
 | 
			
		||||
* Estimating performance::      Estimating query performance
 | 
			
		||||
* SELECT speed::                Speed of @code{SELECT} queries
 | 
			
		||||
* Where optimizations::         How MySQL optimizes @code{WHERE} clauses
 | 
			
		||||
* DISTINCT optimization::       
 | 
			
		||||
* LEFT JOIN optimization::      How MySQL optimizes @code{LEFT JOIN}
 | 
			
		||||
* LIMIT optimization::          How MySQL optimizes @code{LIMIT}
 | 
			
		||||
* Insert speed::                Speed of @code{INSERT} queries
 | 
			
		||||
@@ -26171,7 +26246,7 @@ time for a large table!
 | 
			
		||||
 | 
			
		||||
@cindex optimizations
 | 
			
		||||
@findex WHERE
 | 
			
		||||
@node Where optimizations, LEFT JOIN optimization, SELECT speed, Query Speed
 | 
			
		||||
@node Where optimizations, DISTINCT optimization, SELECT speed, Query Speed
 | 
			
		||||
@subsection How MySQL optimizes @code{WHERE} clauses
 | 
			
		||||
 | 
			
		||||
The @code{WHERE} optimizations are put in the @code{SELECT} part here because
 | 
			
		||||
@@ -26244,18 +26319,14 @@ possibilities. If all columns in @code{ORDER BY} and in @code{GROUP
 | 
			
		||||
BY} come from the same table, then this table is preferred first when
 | 
			
		||||
joining.
 | 
			
		||||
@item
 | 
			
		||||
If there is an @code{ORDER BY} clause and a different @code{GROUP BY} clause,
 | 
			
		||||
or if the @code{ORDER BY} or @code{GROUP BY}
 | 
			
		||||
contains columns from tables other than the first table in the join
 | 
			
		||||
queue, a temporary table is created.
 | 
			
		||||
If there is an @code{ORDER BY} clause and a different @code{GROUP BY}
 | 
			
		||||
clause, or if the @code{ORDER BY} or @code{GROUP BY} contains columns
 | 
			
		||||
from tables other than the first table in the join queue, a temporary
 | 
			
		||||
table is created.
 | 
			
		||||
@item
 | 
			
		||||
If you use @code{SQL_SMALL_RESULT}, @strong{MySQL} will use an in-memory
 | 
			
		||||
temporary table.
 | 
			
		||||
@item
 | 
			
		||||
As @code{DISTINCT} is converted to a @code{GROUP BY} on all columns,
 | 
			
		||||
@code{DISTINCT} combined with @code{ORDER BY} will in many cases also need
 | 
			
		||||
a temporary table.
 | 
			
		||||
@item
 | 
			
		||||
Each table index is queried and the best index that spans fewer than 30% of
 | 
			
		||||
the rows is used. If no such index can be found, a quick table scan is used.
 | 
			
		||||
@item
 | 
			
		||||
@@ -26298,9 +26369,32 @@ mysql> SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,...
 | 
			
		||||
mysql> SELECT ... FROM tbl_name ORDER BY key_part1 DESC,key_part2 DESC,...
 | 
			
		||||
@end example
 | 
			
		||||
 | 
			
		||||
@findex DISTINCT
 | 
			
		||||
@cindex optimizing, DISTINCT
 | 
			
		||||
@node DISTINCT optimization, LEFT JOIN optimization, Where optimizations, Query Speed
 | 
			
		||||
@subsection How MySQL optimizes @code{DISTINCT}
 | 
			
		||||
 | 
			
		||||
@code{DISTINCT} is converted to a @code{GROUP BY} on all columns,
 | 
			
		||||
@code{DISTINCT} combined with @code{ORDER BY} will in many cases also
 | 
			
		||||
need a temporary table.
 | 
			
		||||
 | 
			
		||||
When combining @code{LIMIT #} with @code{DISTINCT}, @strong{MySQL} will stop
 | 
			
		||||
as soon as it finds @code{#} unique rows.
 | 
			
		||||
 | 
			
		||||
If you don't use columns from all used tables, @strong{MySQL} will stop
 | 
			
		||||
the scanning of the not used tables as soon as it has found the first match.
 | 
			
		||||
 | 
			
		||||
@example
 | 
			
		||||
SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;
 | 
			
		||||
@end example
 | 
			
		||||
 | 
			
		||||
In the case, assuming t1 is used before t2 (check with @code{EXPLAIN}), then
 | 
			
		||||
@strong{MySQL} will stop reading from t2 (for that particular row in t1)
 | 
			
		||||
when the first row in t2 is found.
 | 
			
		||||
 | 
			
		||||
@findex LEFT JOIN
 | 
			
		||||
@cindex optimizing, LEFT JOIN
 | 
			
		||||
@node LEFT JOIN optimization, LIMIT optimization, Where optimizations, Query Speed
 | 
			
		||||
@node LEFT JOIN optimization, LIMIT optimization, DISTINCT optimization, Query Speed
 | 
			
		||||
@subsection How MySQL optimizes @code{LEFT JOIN} and @code{RIGHT JOIN}
 | 
			
		||||
 | 
			
		||||
@code{A LEFT JOIN B} is in @strong{MySQL} implemented as follows:
 | 
			
		||||
@@ -31397,6 +31491,10 @@ Load the privilege tables with: @code{mysqladmin -h hostname
 | 
			
		||||
flush-privileges} or with the SQL command @code{FLUSH PRIVILEGES}.
 | 
			
		||||
@end enumerate
 | 
			
		||||
 | 
			
		||||
Note that after you started @code{mysqld} with @code{--skip-grant-tables},
 | 
			
		||||
any usage of @code{GRANT} commands will give you an @code{Unknown command}
 | 
			
		||||
error until you have executed @code{FLUSH PRIVILEGES}.
 | 
			
		||||
 | 
			
		||||
@cindex files, permissions
 | 
			
		||||
@cindex error mesaages, can't find file
 | 
			
		||||
@cindex files, not found message
 | 
			
		||||
@@ -37760,6 +37858,16 @@ though, so 3.23 is not released as a stable version yet.
 | 
			
		||||
@appendixsubsec Changes in release 3.23.26
 | 
			
		||||
@itemize @bullet
 | 
			
		||||
@item
 | 
			
		||||
Added optimization of queries where @code{DISTINCT} is only used on columns
 | 
			
		||||
from some of the tables.
 | 
			
		||||
@item
 | 
			
		||||
Allow floating point numbers where there are no sign after the exponent
 | 
			
		||||
(like 1e1).
 | 
			
		||||
@item
 | 
			
		||||
@code{SHOW GRANTS} didn't always show all column grants.
 | 
			
		||||
@item
 | 
			
		||||
Added @code{--default-extra-file=#} to all @strong{MySQL} clients.
 | 
			
		||||
@item
 | 
			
		||||
Automatic repair of @code{MyISAM} tables.
 | 
			
		||||
@item
 | 
			
		||||
Columns referenced in @code{INSERT} are are now properly initialized.
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,8 @@ static struct option long_options[] =
 | 
			
		||||
{
 | 
			
		||||
  {"config-file",	required_argument, 0,	'c'},
 | 
			
		||||
  {"defaults-file",	required_argument, 0,	'c'},
 | 
			
		||||
  {"defaults-extra-file", required_argument, 0,	'e'},
 | 
			
		||||
  {"extra-file", 	required_argument, 0,	'e'},
 | 
			
		||||
  {"no-defaults",	no_argument,	   0,	'd'},
 | 
			
		||||
  {"help",		no_argument,	   0,	'?'},
 | 
			
		||||
  {"version",		no_argument,	   0,	'V'},
 | 
			
		||||
@@ -40,7 +42,7 @@ static struct option long_options[] =
 | 
			
		||||
 | 
			
		||||
static void usage(my_bool version)
 | 
			
		||||
{
 | 
			
		||||
  printf("%s  Ver 1.1 for %s at %s\n",my_progname,SYSTEM_TYPE,
 | 
			
		||||
  printf("%s  Ver 1.2 for %s at %s\n",my_progname,SYSTEM_TYPE,
 | 
			
		||||
	 MACHINE_TYPE);
 | 
			
		||||
  if (version)
 | 
			
		||||
    return;
 | 
			
		||||
@@ -50,6 +52,9 @@ static void usage(my_bool version)
 | 
			
		||||
  printf("\n\
 | 
			
		||||
  -c, --config-file=#, --defaults-file=#\n\
 | 
			
		||||
	                The config file to use (default '%s')\n\
 | 
			
		||||
  -e, --extra-file=#, --defaults-extra-file=#\n\
 | 
			
		||||
			Read this file after the global /etc config file and\n\
 | 
			
		||||
			before the config file in the users home directory.\n\
 | 
			
		||||
  --no-defaults		Return an empty string (useful for scripts)\n\
 | 
			
		||||
  -?, --help		Display this help message and exit.\n\
 | 
			
		||||
  -V, --version		Output version information and exit.\n",
 | 
			
		||||
@@ -61,13 +66,16 @@ static int get_options(int *argc,char ***argv)
 | 
			
		||||
{
 | 
			
		||||
  int c,option_index;
 | 
			
		||||
 | 
			
		||||
  while ((c=getopt_long(*argc,*argv,"c:V?I",
 | 
			
		||||
  while ((c=getopt_long(*argc,*argv,"c:e:V?I",
 | 
			
		||||
			long_options, &option_index)) != EOF)
 | 
			
		||||
  {
 | 
			
		||||
    switch (c) {
 | 
			
		||||
    case 'c':
 | 
			
		||||
      config_file=optarg;
 | 
			
		||||
      break;
 | 
			
		||||
    case 'e':
 | 
			
		||||
      defaults_extra_file=optarg;		/* Used by the load_defaults */
 | 
			
		||||
      break;
 | 
			
		||||
    case 'n':
 | 
			
		||||
      exit(0);
 | 
			
		||||
    case 'I':
 | 
			
		||||
 
 | 
			
		||||
@@ -206,6 +206,7 @@ extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
 | 
			
		||||
       NEAR my_disable_flush_key_blocks;
 | 
			
		||||
extern char	wild_many,wild_one,wild_prefix;
 | 
			
		||||
extern const char *charsets_dir;
 | 
			
		||||
extern char *defaults_extra_file;
 | 
			
		||||
 | 
			
		||||
typedef struct wild_file_pack	/* Struct to hold info when selecting files */
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -29,8 +29,9 @@
 | 
			
		||||
** The following arguments are handled automaticly;  If used, they must be
 | 
			
		||||
** first argument on the command line!
 | 
			
		||||
** --no-defaults	; no options are read.
 | 
			
		||||
** --print-defaults	; Print the modified command line and exit
 | 
			
		||||
** --defaults-file=full-path-to-default-file	; Only this file will be read.
 | 
			
		||||
** --defaults-extra-file=full-path-to-default-file ; Read this file before ~/
 | 
			
		||||
** --print-defaults	; Print the modified command line and exit
 | 
			
		||||
****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#undef SAFEMALLOC		/* safe_malloc is not yet initailized */
 | 
			
		||||
@@ -39,6 +40,8 @@
 | 
			
		||||
#include "m_string.h"
 | 
			
		||||
#include "m_ctype.h"
 | 
			
		||||
 | 
			
		||||
char *defaults_extra_file=0;
 | 
			
		||||
 | 
			
		||||
/* Which directories are searched for options (and in which order) */
 | 
			
		||||
 | 
			
		||||
const char *default_directories[]= {
 | 
			
		||||
@@ -50,6 +53,7 @@ const char *default_directories[]= {
 | 
			
		||||
#ifdef DATADIR
 | 
			
		||||
DATADIR,
 | 
			
		||||
#endif
 | 
			
		||||
"",					/* Place for defaults_extra_dir */
 | 
			
		||||
#ifndef __WIN__
 | 
			
		||||
"~/",
 | 
			
		||||
#endif
 | 
			
		||||
@@ -71,9 +75,10 @@ void load_defaults(const char *conf_file, const char **groups,
 | 
			
		||||
		   int *argc, char ***argv)
 | 
			
		||||
{
 | 
			
		||||
  DYNAMIC_ARRAY args;
 | 
			
		||||
  const char **dirs, *extra_default_file;
 | 
			
		||||
  const char **dirs, *forced_default_file;
 | 
			
		||||
  TYPELIB group;
 | 
			
		||||
  my_bool found_print_defaults=0;
 | 
			
		||||
  uint args_used=0;
 | 
			
		||||
  MEM_ROOT alloc;
 | 
			
		||||
  char *ptr,**res;
 | 
			
		||||
  DBUG_ENTER("load_defaults");
 | 
			
		||||
@@ -97,9 +102,20 @@ void load_defaults(const char *conf_file, const char **groups,
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Check if we want to force the use a specific default file */
 | 
			
		||||
  extra_default_file=0;
 | 
			
		||||
  if (*argc >= 2 && is_prefix(argv[0][1],"--defaults-file="))
 | 
			
		||||
    extra_default_file=strchr(argv[0][1],'=')+1;
 | 
			
		||||
  forced_default_file=0;
 | 
			
		||||
  if (*argc >= 2)
 | 
			
		||||
  {
 | 
			
		||||
    if (is_prefix(argv[0][1],"--defaults-file="))
 | 
			
		||||
    {
 | 
			
		||||
      forced_default_file=strchr(argv[0][1],'=')+1;
 | 
			
		||||
      args_used++;
 | 
			
		||||
    }
 | 
			
		||||
    else if (is_prefix(argv[0][1],"--defaults-extra-file="))
 | 
			
		||||
    {
 | 
			
		||||
      defaults_extra_file=strchr(argv[0][1],'=')+1;
 | 
			
		||||
      args_used++;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  group.count=0;
 | 
			
		||||
  group.name= "defaults";
 | 
			
		||||
@@ -109,9 +125,9 @@ void load_defaults(const char *conf_file, const char **groups,
 | 
			
		||||
 | 
			
		||||
  if (init_dynamic_array(&args, sizeof(char*),*argc, 32))
 | 
			
		||||
    goto err;
 | 
			
		||||
  if (extra_default_file)
 | 
			
		||||
  if (forced_default_file)
 | 
			
		||||
  {
 | 
			
		||||
    if (search_default_file(&args, &alloc, "", extra_default_file, "",
 | 
			
		||||
    if (search_default_file(&args, &alloc, "", forced_default_file, "",
 | 
			
		||||
			    &group))
 | 
			
		||||
      goto err;
 | 
			
		||||
  }
 | 
			
		||||
@@ -132,8 +148,14 @@ void load_defaults(const char *conf_file, const char **groups,
 | 
			
		||||
#endif
 | 
			
		||||
    for (dirs=default_directories ; *dirs; dirs++)
 | 
			
		||||
    {
 | 
			
		||||
      if (search_default_file(&args, &alloc, *dirs, conf_file, default_ext,
 | 
			
		||||
			      &group))
 | 
			
		||||
      int error;
 | 
			
		||||
      if (**dirs)
 | 
			
		||||
	error=search_default_file(&args, &alloc, *dirs, conf_file,
 | 
			
		||||
				  default_ext, &group);
 | 
			
		||||
      else if (defaults_extra_file)
 | 
			
		||||
	error=search_default_file(&args, &alloc, NullS, defaults_extra_file,
 | 
			
		||||
				  default_ext, &group);
 | 
			
		||||
      if (error)
 | 
			
		||||
	goto err;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@@ -145,11 +167,9 @@ void load_defaults(const char *conf_file, const char **groups,
 | 
			
		||||
  /* copy name + found arguments + command line arguments to new array */
 | 
			
		||||
  res[0]=argv[0][0];
 | 
			
		||||
  memcpy((gptr) (res+1), args.buffer, args.elements*sizeof(char*));
 | 
			
		||||
  if (extra_default_file)
 | 
			
		||||
  {
 | 
			
		||||
    --*argc;					/* Skipp --defaults-file */
 | 
			
		||||
    ++*argv;
 | 
			
		||||
  }
 | 
			
		||||
  /* Skipp --defaults-file and --defaults-extra-file */
 | 
			
		||||
  (*argc)-= args_used;
 | 
			
		||||
  (*argv)+= args_used;
 | 
			
		||||
 | 
			
		||||
  /* Check if we wan't to see the new argument list */
 | 
			
		||||
  if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))
 | 
			
		||||
 
 | 
			
		||||
@@ -2004,6 +2004,8 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
 | 
			
		||||
      want_access &= ~table->grant.privilege;
 | 
			
		||||
      goto err;					// No grants
 | 
			
		||||
    }
 | 
			
		||||
    if (show_table)
 | 
			
		||||
      continue;					// We have some priv on this
 | 
			
		||||
 | 
			
		||||
    table->grant.grant_table=grant_table;	// Remember for column test
 | 
			
		||||
    table->grant.version=grant_version;
 | 
			
		||||
@@ -2013,8 +2015,6 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
 | 
			
		||||
 | 
			
		||||
    if (!(~table->grant.privilege & want_access))
 | 
			
		||||
      continue;
 | 
			
		||||
    if (show_table && table->grant.privilege)
 | 
			
		||||
      continue;					// Test from show tables
 | 
			
		||||
 | 
			
		||||
    if (want_access & ~(grant_table->cols | table->grant.privilege))
 | 
			
		||||
    {
 | 
			
		||||
@@ -2457,18 +2457,18 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
 | 
			
		||||
	!strcmp(lex_user->host.str,host))
 | 
			
		||||
    {
 | 
			
		||||
      want_access=grant_table->privs;
 | 
			
		||||
      if (want_access) 
 | 
			
		||||
      if ((want_access | grant_table->cols) != 0)
 | 
			
		||||
      {
 | 
			
		||||
	String global(buff,sizeof(buff));
 | 
			
		||||
	global.length(0);
 | 
			
		||||
	global.append("GRANT ",6);
 | 
			
		||||
 | 
			
		||||
	if (test_all_bits(want_access,(TABLE_ACLS & ~GRANT_ACL)))
 | 
			
		||||
	if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL)))
 | 
			
		||||
	  global.append("ALL PRIVILEGES",14);
 | 
			
		||||
	else 
 | 
			
		||||
	{
 | 
			
		||||
	  int found=0;
 | 
			
		||||
	  uint j,test_access= want_access & ~GRANT_ACL;
 | 
			
		||||
	  uint j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
 | 
			
		||||
 | 
			
		||||
	  for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
 | 
			
		||||
	  {
 | 
			
		||||
 
 | 
			
		||||
@@ -136,7 +136,8 @@ static void copy_sum_funcs(Item_sum **func_ptr);
 | 
			
		||||
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
 | 
			
		||||
static void init_sum_functions(Item_sum **func);
 | 
			
		||||
static bool update_sum_func(Item_sum **func);
 | 
			
		||||
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order);
 | 
			
		||||
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
 | 
			
		||||
			    bool distinct);
 | 
			
		||||
static void describe_info(const char *info);
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
@@ -171,6 +172,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
 | 
			
		||||
  no_order=0;
 | 
			
		||||
  bzero((char*) &keyuse,sizeof(keyuse));
 | 
			
		||||
  thd->proc_info="init";
 | 
			
		||||
  thd->used_tables=0;				// Updated by setup_fields
 | 
			
		||||
 | 
			
		||||
  if (setup_fields(thd,tables,fields,1,&all_fields) ||
 | 
			
		||||
      setup_conds(thd,tables,&conds) ||
 | 
			
		||||
@@ -261,7 +263,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
 | 
			
		||||
  join.join_tab=0;
 | 
			
		||||
  join.tmp_table_param.copy_field=0;
 | 
			
		||||
  join.sum_funcs=0;
 | 
			
		||||
  join.send_records=0L;
 | 
			
		||||
  join.send_records=join.found_records=0;
 | 
			
		||||
  join.tmp_table_param.end_write_records= HA_POS_ERROR;
 | 
			
		||||
  join.first_record=join.sort_and_group=0;
 | 
			
		||||
  join.select_options=select_options;
 | 
			
		||||
@@ -506,7 +508,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
 | 
			
		||||
      order=0;
 | 
			
		||||
    select_describe(&join,need_tmp,
 | 
			
		||||
		    (order != 0 &&
 | 
			
		||||
		     (!need_tmp || order != group || simple_group)));
 | 
			
		||||
		     (!need_tmp || order != group || simple_group)),
 | 
			
		||||
		    select_distinct);
 | 
			
		||||
    error=0;
 | 
			
		||||
    goto err;
 | 
			
		||||
  }
 | 
			
		||||
@@ -557,6 +560,26 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
 | 
			
		||||
	order=0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
      Optimize distinct when used on some of the tables
 | 
			
		||||
      SELECT DISTINCT t1.a FROM t1,t2 WHERE t1.b=t2.b
 | 
			
		||||
      In this case we can stop scanning t2 when we have found one t1.a
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    if (tmp_table->distinct)
 | 
			
		||||
    {
 | 
			
		||||
      table_map used_tables= thd->used_tables;
 | 
			
		||||
      JOIN_TAB *join_tab=join.join_tab+join.tables-1;
 | 
			
		||||
      do
 | 
			
		||||
      {
 | 
			
		||||
	if (used_tables & join_tab->table->map)
 | 
			
		||||
	  break;
 | 
			
		||||
	join_tab->not_used_in_distinct=1;
 | 
			
		||||
      } while (join_tab-- != join.join_tab);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Copy data to the temporary table */
 | 
			
		||||
    thd->proc_info="Copying to tmp table";
 | 
			
		||||
    if (do_select(&join,(List<Item> *) 0,tmp_table,0))
 | 
			
		||||
      goto err;					/* purecov: inspected */
 | 
			
		||||
@@ -2122,7 +2145,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
 | 
			
		||||
  join->tmp_table_param.copy_field=0;
 | 
			
		||||
  join->first_record=join->sort_and_group=0;
 | 
			
		||||
  join->sum_funcs=0;
 | 
			
		||||
  join->send_records=0L;
 | 
			
		||||
  join->send_records=(ha_rows) 0;
 | 
			
		||||
  join->group=0;
 | 
			
		||||
 | 
			
		||||
  join_tab->cache.buff=0;			/* No cacheing */
 | 
			
		||||
@@ -2130,15 +2153,16 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
 | 
			
		||||
  join_tab->select=0;
 | 
			
		||||
  join_tab->select_cond=0;
 | 
			
		||||
  join_tab->quick=0;
 | 
			
		||||
  bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
 | 
			
		||||
  join_tab->type= JT_ALL;			/* Map through all records */
 | 
			
		||||
  join_tab->keys= (uint) ~0;			/* test everything in quick */
 | 
			
		||||
  join_tab->info=0;
 | 
			
		||||
  join_tab->on_expr=0;
 | 
			
		||||
  join_tab->ref.key = -1;
 | 
			
		||||
  join_tab->not_used_in_distinct=0;
 | 
			
		||||
  join_tab->read_first_record= join_init_read_record;
 | 
			
		||||
  bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
 | 
			
		||||
  tmp_table->status=0;
 | 
			
		||||
  tmp_table->null_row=0;
 | 
			
		||||
  join_tab->read_first_record= join_init_read_record;
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -3256,7 +3280,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
 | 
			
		||||
    if (item->with_sum_func && type != Item::SUM_FUNC_ITEM ||
 | 
			
		||||
	item->const_item())
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
 | 
			
		||||
    {						/* Can't calc group yet */
 | 
			
		||||
      ((Item_sum*) item)->result_field=0;
 | 
			
		||||
@@ -3913,7 +3936,9 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
 | 
			
		||||
 | 
			
		||||
  if (!(error=(*join_tab->read_first_record)(join_tab)))
 | 
			
		||||
  {
 | 
			
		||||
    bool not_exists_optimize=join_tab->table->reginfo.not_exists_optimize;
 | 
			
		||||
    bool not_exists_optimize= join_tab->table->reginfo.not_exists_optimize;
 | 
			
		||||
    bool not_used_in_distinct=join_tab->not_used_in_distinct;
 | 
			
		||||
    ha_rows found_records=join->found_records;
 | 
			
		||||
    READ_RECORD *info= &join_tab->read_record;
 | 
			
		||||
 | 
			
		||||
    do
 | 
			
		||||
@@ -3932,6 +3957,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
 | 
			
		||||
	{
 | 
			
		||||
	  if ((error=(*next_select)(join,join_tab+1,0)) < 0)
 | 
			
		||||
	    return error;
 | 
			
		||||
	  if (not_used_in_distinct && found_records != join->found_records)
 | 
			
		||||
	    return 0;
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
    } while (!(error=info->read_record(info)));
 | 
			
		||||
@@ -4545,23 +4572,21 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 | 
			
		||||
    }
 | 
			
		||||
    if (!join->having || join->having->val_int())
 | 
			
		||||
    {
 | 
			
		||||
      join->found_records++;
 | 
			
		||||
      if ((error=table->file->write_row(table->record[0])))
 | 
			
		||||
      {
 | 
			
		||||
	if (error != HA_ERR_FOUND_DUPP_KEY &&
 | 
			
		||||
	    error != HA_ERR_FOUND_DUPP_UNIQUE)
 | 
			
		||||
	{
 | 
			
		||||
	if (error == HA_ERR_FOUND_DUPP_KEY ||
 | 
			
		||||
	    error == HA_ERR_FOUND_DUPP_UNIQUE)
 | 
			
		||||
	  goto end;
 | 
			
		||||
	if (create_myisam_from_heap(table, &join->tmp_table_param, error,1))
 | 
			
		||||
	  DBUG_RETURN(1);			// Not a table_is_full error
 | 
			
		||||
	table->uniques=0;			// To ensure rows are the same
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
	if (++join->send_records >= join->tmp_table_param.end_write_records)
 | 
			
		||||
	  DBUG_RETURN(-3);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
end:
 | 
			
		||||
  DBUG_RETURN(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -4585,6 +4610,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 | 
			
		||||
    DBUG_RETURN(-2);				/* purecov: inspected */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  join->found_records++;
 | 
			
		||||
  copy_fields(&join->tmp_table_param);		// Groups are copied twice.
 | 
			
		||||
  /* Make a key of group index */
 | 
			
		||||
  for (group=table->group ; group ; group=group->next)
 | 
			
		||||
@@ -6335,12 +6361,13 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
 | 
			
		||||
** Send a description about what how the select will be done to stdout
 | 
			
		||||
****************************************************************************/
 | 
			
		||||
 | 
			
		||||
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order)
 | 
			
		||||
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
 | 
			
		||||
			    bool distinct)
 | 
			
		||||
{
 | 
			
		||||
  DBUG_ENTER("select_describe");
 | 
			
		||||
 | 
			
		||||
  List<Item> field_list;
 | 
			
		||||
  Item *item;
 | 
			
		||||
  THD *thd=join->thd;
 | 
			
		||||
  DBUG_ENTER("select_describe");
 | 
			
		||||
 | 
			
		||||
  field_list.push_back(new Item_empty_string("table",NAME_LEN));
 | 
			
		||||
  field_list.push_back(new Item_empty_string("type",10));
 | 
			
		||||
@@ -6356,11 +6383,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order)
 | 
			
		||||
  item->maybe_null=1;
 | 
			
		||||
  field_list.push_back(new Item_real("rows",0.0,0,10));
 | 
			
		||||
  field_list.push_back(new Item_empty_string("Extra",255));
 | 
			
		||||
  if (send_fields(join->thd,field_list,1))
 | 
			
		||||
  if (send_fields(thd,field_list,1))
 | 
			
		||||
    return; /* purecov: inspected */
 | 
			
		||||
 | 
			
		||||
  char buff[512],*buff_ptr;
 | 
			
		||||
  String tmp(buff,sizeof(buff)),*packet= &join->thd->packet;
 | 
			
		||||
  String tmp(buff,sizeof(buff)),*packet= &thd->packet;
 | 
			
		||||
  table_map used_tables=0;
 | 
			
		||||
  for (uint i=0 ; i < join->tables ; i++)
 | 
			
		||||
  {
 | 
			
		||||
    JOIN_TAB *tab=join->join_tab+i;
 | 
			
		||||
@@ -6473,11 +6501,22 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order)
 | 
			
		||||
      }
 | 
			
		||||
      buff_ptr=strmov(buff_ptr,"Using filesort");
 | 
			
		||||
    }
 | 
			
		||||
    net_store_data(packet,buff,(uint) (buff_ptr - buff));
 | 
			
		||||
    if (my_net_write(&join->thd->net,(char*) packet->ptr(),packet->length()))
 | 
			
		||||
      DBUG_VOID_RETURN;				/* purecov: inspected */
 | 
			
		||||
    if (distinct & test_all_bits(used_tables,thd->used_tables))
 | 
			
		||||
    {
 | 
			
		||||
      if (buff != buff_ptr)
 | 
			
		||||
      {
 | 
			
		||||
	buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
 | 
			
		||||
      }
 | 
			
		||||
  send_eof(&join->thd->net);
 | 
			
		||||
      buff_ptr=strmov(buff_ptr,"Distinct");
 | 
			
		||||
    }
 | 
			
		||||
    net_store_data(packet,buff,(uint) (buff_ptr - buff));
 | 
			
		||||
    if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
 | 
			
		||||
      DBUG_VOID_RETURN;				/* purecov: inspected */
 | 
			
		||||
 | 
			
		||||
    // For next iteration
 | 
			
		||||
    used_tables|=table->map;
 | 
			
		||||
  }
 | 
			
		||||
  send_eof(&thd->net);
 | 
			
		||||
  DBUG_VOID_RETURN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -79,36 +79,36 @@ class JOIN;
 | 
			
		||||
 | 
			
		||||
typedef struct st_join_table {
 | 
			
		||||
  TABLE		*table;
 | 
			
		||||
  int		(*read_first_record)(struct st_join_table *tab);
 | 
			
		||||
  int		(*next_select)(JOIN *,struct st_join_table *,bool);
 | 
			
		||||
  bool		cached_eq_ref_table,eq_ref_table;
 | 
			
		||||
  READ_RECORD	read_record;
 | 
			
		||||
  uint		keys;				/* all keys with can be used */
 | 
			
		||||
  key_map	const_keys;			/* Keys with constant part */
 | 
			
		||||
  key_map	checked_keys;			/* Keys checked in find_best */
 | 
			
		||||
  key_map	needed_reg;
 | 
			
		||||
  ha_rows	records,found_records,read_time;
 | 
			
		||||
  table_map	dependent,key_dependent;
 | 
			
		||||
  uint		use_quick,index;
 | 
			
		||||
  uint		status;				// Save status for cache
 | 
			
		||||
  enum join_type type;
 | 
			
		||||
  JOIN_CACHE	cache;
 | 
			
		||||
  KEYUSE	*keyuse;			/* pointer to first used key */
 | 
			
		||||
  SQL_SELECT	*select;
 | 
			
		||||
  COND		*select_cond;
 | 
			
		||||
  QUICK_SELECT	*quick;
 | 
			
		||||
  Item		*on_expr;
 | 
			
		||||
  uint		used_fields,used_fieldlength,used_blobs;
 | 
			
		||||
  const char	*info;
 | 
			
		||||
  int		(*read_first_record)(struct st_join_table *tab);
 | 
			
		||||
  int		(*next_select)(JOIN *,struct st_join_table *,bool);
 | 
			
		||||
  READ_RECORD	read_record;
 | 
			
		||||
  double	worst_seeks;
 | 
			
		||||
  key_map	const_keys;			/* Keys with constant part */
 | 
			
		||||
  key_map	checked_keys;			/* Keys checked in find_best */
 | 
			
		||||
  key_map	needed_reg;
 | 
			
		||||
  ha_rows	records,found_records,read_time;
 | 
			
		||||
  table_map	dependent,key_dependent;
 | 
			
		||||
  uint		keys;				/* all keys with can be used */
 | 
			
		||||
  uint		use_quick,index;
 | 
			
		||||
  uint		status;				// Save status for cache
 | 
			
		||||
  uint		used_fields,used_fieldlength,used_blobs;
 | 
			
		||||
  enum join_type type;
 | 
			
		||||
  bool		cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
 | 
			
		||||
  TABLE_REF	ref;
 | 
			
		||||
  JOIN_CACHE	cache;
 | 
			
		||||
} JOIN_TAB;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct st_position {			/* Used in find_best */
 | 
			
		||||
  double records_read;
 | 
			
		||||
  JOIN_TAB *table;
 | 
			
		||||
  KEYUSE *key;
 | 
			
		||||
  double records_read;
 | 
			
		||||
} POSITION;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -116,16 +116,16 @@ typedef struct st_position {			/* Used in find_best */
 | 
			
		||||
 | 
			
		||||
class TMP_TABLE_PARAM {
 | 
			
		||||
 public:
 | 
			
		||||
  List<Item> copy_funcs;
 | 
			
		||||
  Copy_field *copy_field;
 | 
			
		||||
  byte	    *group_buff;
 | 
			
		||||
  Item_result_field **funcs;
 | 
			
		||||
  MI_COLUMNDEF *recinfo,*start_recinfo;
 | 
			
		||||
  KEY *keyinfo;
 | 
			
		||||
  ha_rows end_write_records;
 | 
			
		||||
  uint	copy_field_count,field_count,sum_func_count,func_count;
 | 
			
		||||
  uint	group_parts,group_length;
 | 
			
		||||
  uint	quick_group;
 | 
			
		||||
  Copy_field *copy_field;
 | 
			
		||||
  byte	    *group_buff;
 | 
			
		||||
  ha_rows end_write_records;
 | 
			
		||||
  Item_result_field **funcs;
 | 
			
		||||
  List<Item> copy_funcs;
 | 
			
		||||
  MI_COLUMNDEF *recinfo,*start_recinfo;
 | 
			
		||||
  KEY *keyinfo;
 | 
			
		||||
 | 
			
		||||
  TMP_TABLE_PARAM() :group_parts(0),group_length(0),copy_field(0) {}
 | 
			
		||||
  ~TMP_TABLE_PARAM()
 | 
			
		||||
@@ -148,7 +148,7 @@ class JOIN {
 | 
			
		||||
  uint	   send_group_parts;
 | 
			
		||||
  bool	   sort_and_group,first_record,full_join,group, no_field_update;
 | 
			
		||||
  table_map const_table_map;
 | 
			
		||||
  ha_rows  send_records;
 | 
			
		||||
  ha_rows  send_records,found_records;
 | 
			
		||||
  POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
 | 
			
		||||
  double   best_read;
 | 
			
		||||
  List<Item> *fields;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user