mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge mysql.com:/home/pz/mysql/mysql-4.1-root
into mysql.com:/home/pz/mysql/mysql-4.1 sql/mysql_priv.h: Auto merged
This commit is contained in:
364
Docs/manual.texi
364
Docs/manual.texi
@ -6957,21 +6957,30 @@ Follow the instructions to install it.
|
||||
|
||||
@item
|
||||
After @code{BitKeeper} is installed, first go to the directory you
|
||||
want to work from, and then use this command if you want to clone
|
||||
the MySQL 3.23 branch:
|
||||
want to work from, and then use one of the following commands to clone
|
||||
the MySQL version branch of your choice:
|
||||
|
||||
To clone the 3.23 branch, use this command:
|
||||
|
||||
@example
|
||||
shell> bk clone bk://work.mysql.com:7000 mysql
|
||||
shell> bk clone bk://work.mysql.com:7000 mysql-3.23
|
||||
@end example
|
||||
|
||||
To clone the 4.0 branch, use this command instead:
|
||||
To clone the 4.0 branch, use this command:
|
||||
|
||||
@example
|
||||
shell> bk clone bk://work.mysql.com:7001 mysql-4.0
|
||||
@end example
|
||||
|
||||
In the preceding examples the source tree will be set up in the @file{mysql/}
|
||||
or @file{mysql-4.0/} subdirectory of your current directory.
|
||||
To clone the 4.1 branch, use this command:
|
||||
|
||||
@example
|
||||
shell> bk clone bk://work.mysql.com:7004 mysql-4.1
|
||||
@end example
|
||||
|
||||
In the preceding examples the source tree will be set up in the
|
||||
@file{mysql-3.23/}, @file{mysql-4.0/}, or @file{mysql-4.1/}
|
||||
subdirectory of your current directory.
|
||||
|
||||
The initial download of the source tree may take a while, depending on the
|
||||
speed of your connection; be patient.
|
||||
@ -8400,7 +8409,7 @@ or @code{myisamchk} for @code{MyISAM} tables (@file{.MYI}) and
|
||||
@item
|
||||
If you want your @code{mysqldump} files to be compatible between
|
||||
MySQL Version 3.22 and Version 3.23, you should not use the
|
||||
@code{--opt} or @code{--full} option to @code{mysqldump}.
|
||||
@code{--opt} or @code{--all} option to @code{mysqldump}.
|
||||
|
||||
@item
|
||||
Check all your calls to @code{DATE_FORMAT()} to make sure there is a
|
||||
@ -16051,7 +16060,9 @@ Values in the scope fields may be specified as follows:
|
||||
@itemize @bullet
|
||||
@item
|
||||
The wildcard characters @samp{%} and @samp{_} can be used in the @code{Host}
|
||||
and @code{Db} fields of either table.
|
||||
and @code{Db} fields of either table. If you wish to use for instance a
|
||||
@samp{_} character as part of a database name, specify it as @samp{\_} in
|
||||
the @code{GRANT} command.
|
||||
|
||||
@item
|
||||
A @code{'%'} @code{Host} value in the @code{db} table means ``any host.'' A
|
||||
@ -16676,6 +16687,13 @@ database privileges by using @code{ON db_name.*} syntax. If you specify
|
||||
that database. (@strong{Warning}: if you specify @code{ON *} and you
|
||||
@strong{don't} have a current database, you will affect the global privileges!)
|
||||
|
||||
@strong{Please note}: the @samp{_} and @samp{%} wildcards are allowed when
|
||||
specifying database names in @code{GRANT} commands. This means that if you
|
||||
wish to use for instance a @samp{_} character as part of a database name,
|
||||
you should specify it as @samp{\_} in the @code{GRANT} command, to prevent
|
||||
the user from being able to access additional databases matching the
|
||||
wildcard pattern, e.g., @code{GRANT ... ON `foo\_bar`.* TO ...}.
|
||||
|
||||
In order to accommodate granting rights to users from arbitrary hosts,
|
||||
MySQL supports specifying the @code{user_name} value in the form
|
||||
@code{user@@host}. If you want to specify a @code{user} string
|
||||
@ -16684,8 +16702,8 @@ containing special characters or wildcard characters (such as @samp{%}), you
|
||||
can quote the user or host name (for example, @code{'test-user'@@'test-hostname'}).
|
||||
|
||||
You can specify wildcards in the hostname. For example,
|
||||
@code{user@@"%.loc.gov"} applies to @code{user} for any host in the
|
||||
@code{loc.gov} domain, and @code{user@@"144.155.166.%"} applies to @code{user}
|
||||
@code{user@@'%.loc.gov'} applies to @code{user} for any host in the
|
||||
@code{loc.gov} domain, and @code{user@@'144.155.166.%'} applies to @code{user}
|
||||
for any host in the @code{144.155.166} class C subnet.
|
||||
|
||||
The simple form @code{user} is a synonym for @code{user@@"%"}.
|
||||
@ -17703,7 +17721,7 @@ the @code{mysqlhotcopy script}. @xref{mysqldump, , @code{mysqldump}}.
|
||||
Do a full backup of your databases:
|
||||
|
||||
@example
|
||||
shell> mysqldump --tab=/path/to/some/dir --opt --full
|
||||
shell> mysqldump --tab=/path/to/some/dir --opt --all
|
||||
|
||||
or
|
||||
|
||||
@ -19931,7 +19949,7 @@ cache.
|
||||
The value of the @code{--bdb-home} option.
|
||||
|
||||
@item @code{bdb_max_lock}
|
||||
The maximum number of locks (1000 by default) you can have active on a
|
||||
The maximum number of locks (10,000 by default) you can have active on a
|
||||
BDB table. You should increase this if you get errors of type @code{bdb:
|
||||
Lock table is out of available locks} or @code{Got error 12 from ...}
|
||||
when you have do long transactions or when @code{mysqld} has to examine
|
||||
@ -20030,15 +20048,15 @@ The maximum length of the word to be included in a @code{FULLTEXT} index.
|
||||
@strong{Note: @code{FULLTEXT} indexes must be rebuilt after changing
|
||||
this variable.} (This option is new for MySQL 4.0.)
|
||||
|
||||
@item @code{ft_max_word_len_sort}
|
||||
@item @code{ft_max_word_len_for_sort}
|
||||
The maximum length of the word in a @code{FULLTEXT} index
|
||||
to be used in fast index recreation method in @code{REPAIR},
|
||||
@code{CREATE INDEX}, or @code{ALTER TABLE}. Longer words are inserted the
|
||||
slow way. The rule of the thumb is as follows: with
|
||||
@code{ft_max_word_len_sort} increasing, @strong{MySQL} will create bigger
|
||||
@code{ft_max_word_len_for_sort} increasing, @strong{MySQL} will create bigger
|
||||
temporary files (thus slowing the process down, due to disk I/O), and will put
|
||||
fewer keys in one sort block (again, decreasing the efficiency). When
|
||||
@code{ft_max_word_len_sort} is too small, instead, @strong{MySQL} will insert a
|
||||
@code{ft_max_word_len_for_sort} is too small, instead, @strong{MySQL} will insert a
|
||||
lot of words into index the slow way, but short words will be inserted very
|
||||
quickly.
|
||||
|
||||
@ -23324,7 +23342,7 @@ If you need better performance when you start using MySQL in a production
|
||||
environment, you can remove the @code{--log} option from @code{mysql.server}
|
||||
or change it to @code{--log-bin}. @xref{Binary log}.
|
||||
|
||||
The entries in this log are written as @code{mysqld} receives the queries.
|
||||
The entries in this log are written as @code{mysqld} receives the questions.
|
||||
This may be different from the order in which the statements are executed.
|
||||
This is in contrast to the update log and the binary log which are written
|
||||
after the query is executed, but before any locks are released.
|
||||
@ -23337,7 +23355,7 @@ after the query is executed, but before any locks are released.
|
||||
@cindex files, update log
|
||||
|
||||
@strong{Note}: the update log is replaced by the binary
|
||||
log. @xref{Binary log}. You can do anything with the binary log that you can do
|
||||
log. @xref{Binary log}. With this you can do anything that you can do
|
||||
with the update log.
|
||||
|
||||
When started with the @code{--log-update[=file_name]} option,
|
||||
@ -23352,7 +23370,7 @@ flush-logs}, execute the @code{FLUSH LOGS} statement, or restart the server.
|
||||
|
||||
@strong{Note}: for the above scheme to work, you must not create
|
||||
your own files with the same filename as the update log + some extensions
|
||||
that may be regarded as a number in the directory used by the update log!
|
||||
that may be regarded as a number, in the directory used by the update log!
|
||||
|
||||
If you use the @code{--log} or @code{-l} options, @code{mysqld} writes a
|
||||
general log with a filename of @file{hostname.log}, and restarts and
|
||||
@ -23396,8 +23414,8 @@ and the crash.
|
||||
@cindex binary log
|
||||
@cindex files, binary log
|
||||
|
||||
The binary log will replace the now deprecated update log, so
|
||||
we recommend you to switch to this log format as soon as possible.
|
||||
The intention is that the binary log should replace the update log, so
|
||||
we recommend you to switch to this log format as soon as possible!
|
||||
|
||||
The binary log contains all information that is available in the update
|
||||
log in a more efficient format. It also contains information about how long
|
||||
@ -23408,10 +23426,10 @@ find a problem query) you should use the general query log. @xref{Query log}.
|
||||
The binary log is also used when you are replicating a slave from a master.
|
||||
@xref{Replication}.
|
||||
|
||||
When started with the @code{--log-bin[=file_name]} option @code{mysqld}
|
||||
When started with the @code{--log-bin[=file_name]} option, @code{mysqld}
|
||||
writes a log file containing all SQL commands that update data. If no
|
||||
file name is given it defaults to the name of the host machine followed
|
||||
by @code{-bin}. If a file name is given, but doesn't contain a path, the
|
||||
file name is given, it defaults to the name of the host machine followed
|
||||
by @code{-bin}. If file name is given, but it doesn't contain a path, the
|
||||
file is written in the data directory.
|
||||
|
||||
If you supply an extension to @code{--log-bin=filename.extension}, the
|
||||
@ -23431,9 +23449,14 @@ to the binary log:
|
||||
@multitable @columnfractions .38 .62
|
||||
@item @strong{Option} @tab @strong{Description}
|
||||
|
||||
@item @code{binlog-do-db=database_name} @tab Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned. (Example: @code{binlog-do-db=some_database})
|
||||
@item @code{binlog-do-db=database_name} @tab
|
||||
Tells the master it should log updates for the specified database, and
|
||||
exclude all others not explicitly mentioned.
|
||||
(Example: @code{binlog-do-db=some_database})
|
||||
|
||||
@item @code{binlog-ignore-db=database_name} @tab Tells the master that updates to the given database should not be logged to the binary log (Example: @code{binlog-ignore-db=some_database})
|
||||
@item @code{binlog-ignore-db=database_name} @tab
|
||||
Tells the master that updates to the given database should not be logged
|
||||
to the binary log (Example: @code{binlog-ignore-db=some_database})
|
||||
@end multitable
|
||||
|
||||
To be able to know which different binary log files have been used,
|
||||
@ -23458,10 +23481,10 @@ shell> mysqlbinlog log-file | mysql -h server_name
|
||||
@end example
|
||||
|
||||
You can also use the @code{mysqlbinlog} program to read the binary log
|
||||
directly from a remote MySQL server.
|
||||
directly from a remote MySQL server!
|
||||
|
||||
@code{mysqlbinlog --help} will give you more information of how to use
|
||||
this program.
|
||||
this program!
|
||||
|
||||
If you are using @code{BEGIN [WORK]} or @code{SET AUTOCOMMIT=0}, you must
|
||||
use the MySQL binary log for backups instead of the old update log.
|
||||
@ -23470,13 +23493,14 @@ The binary logging is done immediately after a query completes but before
|
||||
any locks are released or any commit is done. This ensures that the log
|
||||
will be logged in the execution order.
|
||||
|
||||
Updates to a non-transactional table are stored in the binary log at
|
||||
once. For transactional tables such as @code{BDB} ! or @code{InnoDB}
|
||||
tables, all updates are cached until a @code{COMMIT}. Every thread
|
||||
will, on start, allocate a buffer of @code{binlog_cache_size} to buffer
|
||||
queries. If a query is bigger than this, the thread will open a
|
||||
temporary file to handle the bigger cache. The temporary file will be
|
||||
deleted when the thread ends.
|
||||
Updates to non-transactional tables are stored in the binary log
|
||||
immediately after execution. For transactional tables such as @code{BDB}
|
||||
or @code{InnoDB} tables, all updates (@code{UPDATE}, @code{DELETE}
|
||||
or @code{INSERT}) that change tables are cached until a @code{COMMIT}.
|
||||
Every thread will, on start, allocate a buffer of @code{binlog_cache_size}
|
||||
to buffer queries. If a query is bigger than this, the thread will open
|
||||
a temporary file to handle the bigger cache. The temporary file will
|
||||
be deleted when the thread ends.
|
||||
|
||||
The @code{max_binlog_cache_size} can be used to restrict the total size used
|
||||
to cache a multi-query transaction.
|
||||
@ -23499,10 +23523,10 @@ more than @code{long_query_time} to execute. The time to get the initial
|
||||
table locks are not counted as execution time.
|
||||
|
||||
The slow query log is logged after the query is executed and after all
|
||||
locks have been released. This may be different from the order in which
|
||||
locks has been released. This may be different from the order in which
|
||||
the statements are executed.
|
||||
|
||||
If no filename is given, it defaults to the name of the host machine
|
||||
If no file name is given, it defaults to the name of the host machine
|
||||
suffixed with @code{-slow.log}. If a filename is given, but doesn't
|
||||
contain a path, the file is written in the data directory.
|
||||
|
||||
@ -23512,8 +23536,8 @@ can become a difficult task. You can pipe the slow query log through the
|
||||
@code{mysqldumpslow} command to get a summary of the queries which
|
||||
appear in the log.
|
||||
|
||||
If you use @code{--log-long-format} also, then queries that do not
|
||||
use indexes are logged as well. @xref{Command-line options}.
|
||||
You are using @code{--log-long-format} then also queries that are not
|
||||
using indexes are printed. @xref{Command-line options}.
|
||||
|
||||
|
||||
@node Log file maintenance, , Slow query log, Log Files
|
||||
@ -23523,19 +23547,22 @@ use indexes are logged as well. @xref{Command-line options}.
|
||||
@cindex maintaining, log files
|
||||
@cindex log files, maintaining
|
||||
|
||||
MySQL has many log files which makes it easy to see what is going on.
|
||||
@xref{Log Files}. One must, however, occasionally clean up
|
||||
after @code{MySQL} to ensure that the logs don't take up too much disk
|
||||
space by either removing or backing up old log files and then telling MySQL
|
||||
to start logging to new files. @xref{Backup}.
|
||||
The MySQL Server can create a number of different log files, which make
|
||||
it easy to see what is going on. @xref{Log Files}. One must however
|
||||
regularly clean up these files, to ensure that the logs don't take up
|
||||
too much disk space.
|
||||
|
||||
On a Linux (@code{Redhat}) installation you can use the
|
||||
When using MySQL with log files, you will, from time to time,
|
||||
want to remove/backup old log files and tell MySQL to start
|
||||
logging on new files. @xref{Backup}.
|
||||
|
||||
On a Linux (@code{Redhat}) installation, you can use the
|
||||
@code{mysql-log-rotate} script for this. If you installed MySQL
|
||||
from an RPM distribution the script should have been installed
|
||||
automatically. @strong{Note}: you should be careful with this if you are
|
||||
using the logs for replication.
|
||||
from an RPM distribution, the script should have been installed
|
||||
automatically. Note that you should be careful with this if you are using
|
||||
the log for replication!
|
||||
|
||||
On other systems you must install a short script yourself that you can
|
||||
On other systems you must install a short script yourself that you
|
||||
start from @code{cron} to handle log files.
|
||||
|
||||
You can force MySQL to start using new log files by using
|
||||
@ -24203,7 +24230,7 @@ ignore, use the directive multiple times, once for each database.
|
||||
You should not use this directive if you are using cross table updates
|
||||
and you don't want these update to be replicated.
|
||||
|
||||
The main reason for this behavior is that it's hard from the command
|
||||
The main reason for this behaviour is that it's hard from the command
|
||||
alone know if a query should be replicated or not; For example if you
|
||||
are using multi-table-delete or multi-table-update commands in MySQL 4.x
|
||||
that goes across multiple databases. It's also very fast to just check
|
||||
@ -24294,10 +24321,16 @@ summary of commands:
|
||||
@item @strong{Command} @tab @strong{Description}
|
||||
|
||||
@item @code{SLAVE START}
|
||||
@tab Starts the slave thread. (Slave)
|
||||
@tab Starts the slave thread.
|
||||
As of MySQL 4.0.2, you can add @code{IO_THREAD} or @code{SQL_THREAD}
|
||||
options to the statement to start the I/O thread or the SQL thread.
|
||||
The I/O thread reads queries from the master server and stores them in the
|
||||
relay log. The SQL thread reads the relay log and executes the queries.
|
||||
(Slave)
|
||||
|
||||
@item @code{SLAVE STOP}
|
||||
@tab Stops the slave thread. (Slave)
|
||||
@tab Stops the slave thread. Like @code{SLAVE START}, this statement
|
||||
may be used with @code{IO_THREAD} and @code{SQL_THREAD} options. (Slave)
|
||||
|
||||
@item @code{SET SQL_LOG_BIN=0}
|
||||
@tab Disables update logging if the user has the @code{SUPER} privilege.
|
||||
@ -28951,7 +28984,7 @@ A few are reserved because MySQL needs them and is
|
||||
|
||||
@c START_OF_RESERVED_WORDS
|
||||
|
||||
@c Reserved word list updated Tue Jul 23 20:41:20 2002 by monty.
|
||||
@c Reserved word list updated Tue Oct 8 13:03:34 2002 by arjen.
|
||||
@c To regenerate, use Support/update-reserved-words.pl.
|
||||
|
||||
@multitable @columnfractions .33 .33 .34
|
||||
@ -28973,38 +29006,41 @@ A few are reserved because MySQL needs them and is
|
||||
@item @code{BINARY}
|
||||
@tab @code{BLOB}
|
||||
@tab @code{BOTH}
|
||||
@item @code{BY}
|
||||
@item @code{BTREE}
|
||||
@tab @code{BY}
|
||||
@tab @code{CASCADE}
|
||||
@tab @code{CASE}
|
||||
@item @code{CHANGE}
|
||||
@item @code{CASE}
|
||||
@tab @code{CHANGE}
|
||||
@tab @code{CHAR}
|
||||
@tab @code{CHARACTER}
|
||||
@item @code{COLUMN}
|
||||
@tab @code{COLUMNS}
|
||||
@item @code{CHARACTER}
|
||||
@tab @code{COLLATE}
|
||||
@tab @code{COLUMN}
|
||||
@item @code{COLUMNS}
|
||||
@tab @code{CONSTRAINT}
|
||||
@item @code{CREATE}
|
||||
@tab @code{CROSS}
|
||||
@tab @code{CREATE}
|
||||
@item @code{CROSS}
|
||||
@tab @code{CURRENT_DATE}
|
||||
@item @code{CURRENT_TIME}
|
||||
@tab @code{CURRENT_TIMESTAMP}
|
||||
@tab @code{CURRENT_TIME}
|
||||
@item @code{CURRENT_TIMESTAMP}
|
||||
@tab @code{DATABASE}
|
||||
@item @code{DATABASES}
|
||||
@tab @code{DAY_HOUR}
|
||||
@tab @code{DATABASES}
|
||||
@item @code{DAY_HOUR}
|
||||
@tab @code{DAY_MINUTE}
|
||||
@item @code{DAY_SECOND}
|
||||
@tab @code{DEC}
|
||||
@tab @code{DAY_SECOND}
|
||||
@item @code{DEC}
|
||||
@tab @code{DECIMAL}
|
||||
@item @code{DEFAULT}
|
||||
@tab @code{DELAYED}
|
||||
@tab @code{DEFAULT}
|
||||
@item @code{DELAYED}
|
||||
@tab @code{DELETE}
|
||||
@item @code{DESC}
|
||||
@tab @code{DESCRIBE}
|
||||
@tab @code{DESC}
|
||||
@item @code{DESCRIBE}
|
||||
@tab @code{DISTINCT}
|
||||
@item @code{DISTINCTROW}
|
||||
@tab @code{DOUBLE}
|
||||
@tab @code{DISTINCTROW}
|
||||
@item @code{DOUBLE}
|
||||
@tab @code{DROP}
|
||||
@item @code{ELSE}
|
||||
@tab @code{ENCLOSED}
|
||||
@tab @code{ELSE}
|
||||
@item @code{ENCLOSED}
|
||||
@tab @code{ERRORS}
|
||||
@tab @code{ESCAPED}
|
||||
@item @code{EXISTS}
|
||||
@tab @code{EXPLAIN}
|
||||
@ -29015,83 +29051,86 @@ A few are reserved because MySQL needs them and is
|
||||
@item @code{FROM}
|
||||
@tab @code{FULLTEXT}
|
||||
@tab @code{FUNCTION}
|
||||
@item @code{GRANT}
|
||||
@item @code{GEOMETRY}
|
||||
@tab @code{GRANT}
|
||||
@tab @code{GROUP}
|
||||
@item @code{HASH}
|
||||
@tab @code{HAVING}
|
||||
@item @code{HIGH_PRIORITY}
|
||||
@tab @code{HOUR_MINUTE}
|
||||
@tab @code{HIGH_PRIORITY}
|
||||
@item @code{HOUR_MINUTE}
|
||||
@tab @code{HOUR_SECOND}
|
||||
@item @code{IF}
|
||||
@tab @code{IGNORE}
|
||||
@tab @code{IF}
|
||||
@item @code{IGNORE}
|
||||
@tab @code{IN}
|
||||
@item @code{INDEX}
|
||||
@tab @code{INFILE}
|
||||
@tab @code{INDEX}
|
||||
@item @code{INFILE}
|
||||
@tab @code{INNER}
|
||||
@item @code{INNODB}
|
||||
@tab @code{INSERT}
|
||||
@tab @code{INNODB}
|
||||
@item @code{INSERT}
|
||||
@tab @code{INT}
|
||||
@item @code{INTEGER}
|
||||
@tab @code{INTERVAL}
|
||||
@tab @code{INTEGER}
|
||||
@item @code{INTERVAL}
|
||||
@tab @code{INTO}
|
||||
@item @code{IS}
|
||||
@tab @code{JOIN}
|
||||
@tab @code{IS}
|
||||
@item @code{JOIN}
|
||||
@tab @code{KEY}
|
||||
@item @code{KEYS}
|
||||
@tab @code{KILL}
|
||||
@tab @code{KEYS}
|
||||
@item @code{KILL}
|
||||
@tab @code{LEADING}
|
||||
@item @code{LEFT}
|
||||
@tab @code{LIKE}
|
||||
@tab @code{LEFT}
|
||||
@item @code{LIKE}
|
||||
@tab @code{LIMIT}
|
||||
@item @code{LINES}
|
||||
@tab @code{LOAD}
|
||||
@tab @code{LINES}
|
||||
@item @code{LOAD}
|
||||
@tab @code{LOCK}
|
||||
@item @code{LONG}
|
||||
@tab @code{LONGBLOB}
|
||||
@tab @code{LONG}
|
||||
@item @code{LONGBLOB}
|
||||
@tab @code{LONGTEXT}
|
||||
@item @code{LOW_PRIORITY}
|
||||
@tab @code{MASTER_SERVER_ID}
|
||||
@tab @code{LOW_PRIORITY}
|
||||
@item @code{MASTER_SERVER_ID}
|
||||
@tab @code{MATCH}
|
||||
@item @code{MEDIUMBLOB}
|
||||
@tab @code{MEDIUMINT}
|
||||
@tab @code{MEDIUMBLOB}
|
||||
@item @code{MEDIUMINT}
|
||||
@tab @code{MEDIUMTEXT}
|
||||
@item @code{MIDDLEINT}
|
||||
@tab @code{MINUTE_SECOND}
|
||||
@tab @code{MIDDLEINT}
|
||||
@item @code{MINUTE_SECOND}
|
||||
@tab @code{MRG_MYISAM}
|
||||
@item @code{NATURAL}
|
||||
@tab @code{NOT}
|
||||
@tab @code{NATURAL}
|
||||
@item @code{NOT}
|
||||
@tab @code{NULL}
|
||||
@item @code{NUMERIC}
|
||||
@tab @code{ON}
|
||||
@tab @code{NUMERIC}
|
||||
@item @code{ON}
|
||||
@tab @code{OPTIMIZE}
|
||||
@item @code{OPTION}
|
||||
@tab @code{OPTIONALLY}
|
||||
@tab @code{OPTION}
|
||||
@item @code{OPTIONALLY}
|
||||
@tab @code{OR}
|
||||
@item @code{ORDER}
|
||||
@tab @code{OUTER}
|
||||
@tab @code{ORDER}
|
||||
@item @code{OUTER}
|
||||
@tab @code{OUTFILE}
|
||||
@item @code{PARTIAL}
|
||||
@tab @code{PRECISION}
|
||||
@tab @code{PRIMARY}
|
||||
@item @code{PRIVILEGES}
|
||||
@item @code{PRIMARY}
|
||||
@tab @code{PRIVILEGES}
|
||||
@tab @code{PROCEDURE}
|
||||
@tab @code{PURGE}
|
||||
@item @code{READ}
|
||||
@item @code{PURGE}
|
||||
@tab @code{READ}
|
||||
@tab @code{REAL}
|
||||
@tab @code{REFERENCES}
|
||||
@item @code{REGEXP}
|
||||
@item @code{REFERENCES}
|
||||
@tab @code{REGEXP}
|
||||
@tab @code{RENAME}
|
||||
@tab @code{REPLACE}
|
||||
@item @code{REQUIRE}
|
||||
@item @code{REPLACE}
|
||||
@tab @code{REQUIRE}
|
||||
@tab @code{RESTRICT}
|
||||
@tab @code{RETURNS}
|
||||
@item @code{REVOKE}
|
||||
@item @code{RETURNS}
|
||||
@tab @code{REVOKE}
|
||||
@tab @code{RIGHT}
|
||||
@tab @code{RLIKE}
|
||||
@item @code{SELECT}
|
||||
@tab @code{SET}
|
||||
@item @code{RLIKE}
|
||||
@tab @code{RTREE}
|
||||
@tab @code{SELECT}
|
||||
@item @code{SET}
|
||||
@tab @code{SHOW}
|
||||
@item @code{SMALLINT}
|
||||
@tab @code{SONAME}
|
||||
@tab @code{SMALLINT}
|
||||
@item @code{SONAME}
|
||||
@tab @code{SPATIAL}
|
||||
@tab @code{SQL_BIG_RESULT}
|
||||
@item @code{SQL_CALC_FOUND_ROWS}
|
||||
@tab @code{SQL_SMALL_RESULT}
|
||||
@ -29108,26 +29147,29 @@ A few are reserved because MySQL needs them and is
|
||||
@item @code{TINYTEXT}
|
||||
@tab @code{TO}
|
||||
@tab @code{TRAILING}
|
||||
@item @code{UNION}
|
||||
@item @code{TYPES}
|
||||
@tab @code{UNION}
|
||||
@tab @code{UNIQUE}
|
||||
@tab @code{UNLOCK}
|
||||
@item @code{UNSIGNED}
|
||||
@item @code{UNLOCK}
|
||||
@tab @code{UNSIGNED}
|
||||
@tab @code{UPDATE}
|
||||
@tab @code{USAGE}
|
||||
@item @code{USE}
|
||||
@item @code{USAGE}
|
||||
@tab @code{USE}
|
||||
@tab @code{USER_RESOURCES}
|
||||
@tab @code{USING}
|
||||
@item @code{VALUES}
|
||||
@item @code{USING}
|
||||
@tab @code{VALUES}
|
||||
@tab @code{VARBINARY}
|
||||
@tab @code{VARCHAR}
|
||||
@item @code{VARYING}
|
||||
@tab @code{WHEN}
|
||||
@item @code{VARCHAR}
|
||||
@tab @code{VARYING}
|
||||
@tab @code{WARNINGS}
|
||||
@item @code{WHEN}
|
||||
@tab @code{WHERE}
|
||||
@item @code{WITH}
|
||||
@tab @code{WRITE}
|
||||
@tab @code{WITH}
|
||||
@item @code{WRITE}
|
||||
@tab @code{XOR}
|
||||
@item @code{YEAR_MONTH}
|
||||
@tab @code{ZEROFILL}
|
||||
@tab @code{YEAR_MONTH}
|
||||
@item @code{ZEROFILL}
|
||||
@tab
|
||||
@tab
|
||||
@end multitable
|
||||
|
||||
@ -31225,7 +31267,7 @@ mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
|
||||
|
||||
If @code{expr2} or @code{expr3} is explicitely @code{NULL} then the
|
||||
result type of the @code{IF()} function is the type of the not
|
||||
@code{NULL} column. (This behavior is new in MySQL 4.0.3).
|
||||
@code{NULL} column. (This behaviour is new in MySQL 4.0.3).
|
||||
|
||||
@code{expr1} is evaluated as an integer value, which means that if you are
|
||||
testing floating-point or string values, you should do so using a comparison
|
||||
@ -35001,6 +35043,7 @@ DELAYED} when you are really sure you need it!
|
||||
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
|
||||
SET col_name1=expr1 [, col_name2=expr2, ...]
|
||||
[WHERE where_definition]
|
||||
[ORDER BY ...]
|
||||
[LIMIT #]
|
||||
@end example
|
||||
|
||||
@ -36226,10 +36269,8 @@ mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
|
||||
|
||||
This will create a @code{MyISAM} table with three columns, a, b, and c.
|
||||
Notice that the columns from the @code{SELECT} statement are appended to
|
||||
the right side of the table, not overlapped onto it.
|
||||
Still, the column from the @code{SELECT} will overlap the column from
|
||||
the @code{CREATE} clause if they both have the same name. Take the following
|
||||
examples:
|
||||
the right side of the table, not overlapped onto it. Take the following
|
||||
example:
|
||||
|
||||
@example
|
||||
mysql> SELECT * FROM foo;
|
||||
@ -36250,18 +36291,6 @@ mysql> SELECT * FROM bar;
|
||||
| NULL | 1 |
|
||||
+------+---+
|
||||
1 row in set (0.00 sec)
|
||||
|
||||
mysql> CREATE TABLE foobar (n FLOAT(3,2), m INT) SELECT n FROM foo;
|
||||
Query OK, 1 row affected (0.02 sec)
|
||||
Records: 1 Duplicates: 0 Warnings: 0
|
||||
|
||||
mysql> SELECT * FROM foobar;
|
||||
+------+------+
|
||||
| n | m |
|
||||
+------+------+
|
||||
| 1.00 | NULL |
|
||||
+------+------+
|
||||
1 row in set (0.00 sec)
|
||||
@end example
|
||||
|
||||
For each row in table @code{foo}, a row is inserted in @code{bar} with
|
||||
@ -36615,7 +36644,7 @@ deleted due to duplication of unique key values.
|
||||
The @code{FOREIGN KEY}, @code{CHECK}, and @code{REFERENCES} clauses don't
|
||||
actually do anything, except for InnoDB type tables which support
|
||||
@code{ADD CONSTRAINT FOREIGN KEY (...) REFERENCES ... (...)}.
|
||||
Note that InnoDB does not allow a constraint @code{symbol} or @code{index_name}
|
||||
Note that InnoDB does not allow an @code{index_name}
|
||||
to be specified. @xref{InnoDB}.
|
||||
The syntax for other table types is provided only for compatibility,
|
||||
to make it easier to port code from other SQL servers and to run applications
|
||||
@ -39268,7 +39297,7 @@ constraints to guard the integrity of your data.
|
||||
|
||||
The syntax of a foreign key constraint definition in InnoDB:
|
||||
@example
|
||||
FOREIGN KEY (index_col_name, ...)
|
||||
[CONSTRAINT symbol] FOREIGN KEY (index_col_name, ...)
|
||||
REFERENCES table_name (index_col_name, ...)
|
||||
[ON DELETE CASCADE | ON DELETE SET NULL]
|
||||
@end example
|
||||
@ -39327,7 +39356,7 @@ Starting from version 3.23.50 InnoDB allows you to add a new
|
||||
foreign key constraint to a table through
|
||||
@example
|
||||
ALTER TABLE yourtablename
|
||||
ADD CONSTRAINT FOREIGN KEY (...) REFERENCES anothertablename(...)
|
||||
ADD [CONSTRAINT symbol] FOREIGN KEY (...) REFERENCES anothertablename(...)
|
||||
@end example
|
||||
Remember to create the required indexes first, though.
|
||||
|
||||
@ -50833,8 +50862,10 @@ each individual 4.0.x release.
|
||||
@appendixsubsec Changes in release 4.0.5
|
||||
@itemize
|
||||
@item
|
||||
Give error if one has more than 2 ^ 32 rows in a MyISAM MERGE file and one
|
||||
has not compiled MySQL with @code{-DBIG_TABLES}.
|
||||
Small fix in @code{mysqld_safe} for some shells.
|
||||
@item
|
||||
Give error if a @code{MyISAM} @code{MERGE} table has more than 2 ^ 32 rows and
|
||||
MySQL was not compiled with with @code{-DBIG_TABLES}.
|
||||
@item
|
||||
Fixed some @code{ORDER BY ... DESC} problems with InnoDB.
|
||||
@item
|
||||
@ -50854,7 +50885,7 @@ Fixed bug where @code{GRANT}/@code{REVOKE} failed if hostname was given in
|
||||
not matching case.
|
||||
@item
|
||||
Don't give warning in @code{LOAD DATA INFILE} when setting a
|
||||
@code{timestamp} to a string of '0'.
|
||||
@code{timestamp} to a string value of @code{'0'}.
|
||||
@item
|
||||
Fixed bug in @code{myisamchk -R} mode.
|
||||
@item
|
||||
@ -50927,7 +50958,7 @@ output in @code{SHOW GRANTS}.
|
||||
Fixed that @code{mysqld --help} reports correct values for @code{--datadir}
|
||||
and @code{--bind-address}.
|
||||
@item
|
||||
Fixed that one can drop UDFs that didn't exist when mysqld was started.
|
||||
Fixed that one can drop UDFs that didn't exist when @code{mysqld} was started.
|
||||
@item
|
||||
Fixed core dump problem with @code{SHOW VARIABLES} on some 64 bit systems
|
||||
(like Solaris sparc).
|
||||
@ -51009,7 +51040,7 @@ that can be used as data values in queries.
|
||||
Changed variable @code{DELAY_KEY_WRITE} to an enum to allow one set
|
||||
@code{DELAY_KEY_WRITE} for all tables without taking down the server.
|
||||
@item
|
||||
Changed behavior of @code{IF(condition,column,NULL)} so that it returns
|
||||
Changed behaviour of @code{IF(condition,column,NULL)} so that it returns
|
||||
the value of the column type.
|
||||
@item
|
||||
Made @code{safe_mysqld} a symlink to @code{mysqld_safe} in binary distribution.
|
||||
@ -51281,6 +51312,9 @@ Fixed bug in truncation operator for boolean full-text search.
|
||||
Allow value of @code{--user=#} option for @code{mysqld} to be specified
|
||||
as a numeric user ID.
|
||||
@item
|
||||
Fixed a bug where @code{SQL_CALC_ROWS} returned an incorrect value when used
|
||||
with one table and @code{ORDER BY} and with @code{InnoDB} tables.
|
||||
@item
|
||||
Fixed that @code{SELECT 0 LIMIT 0} doesn't hang thread.
|
||||
@item
|
||||
Fixed some problems with @code{USE/IGNORE INDEX} when using
|
||||
@ -51667,6 +51701,8 @@ not yet 100% confident in this code.
|
||||
@appendixsubsec Changes in release 3.23.53
|
||||
@itemize @bullet
|
||||
@item
|
||||
Small fix in @code{safe_mysqld} for some shells.
|
||||
@item
|
||||
Fixed that @code{SHOW STATUS} doesn't reset @code{Delayed_insert_threads}.
|
||||
@item
|
||||
Fixed core dump bug when using the @code{BINARY} cast on a @code{NULL} value.
|
||||
|
@ -21,7 +21,8 @@ static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
|
||||
ulong max_records);
|
||||
|
||||
int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
|
||||
uint reclength, ulong max_records, ulong min_records)
|
||||
uint reclength, ulong max_records, ulong min_records,
|
||||
HP_CREATE_INFO *create_info)
|
||||
{
|
||||
uint i, j, key_segs, max_length, length;
|
||||
HP_SHARE *share;
|
||||
@ -120,6 +121,9 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
|
||||
share->keys= keys;
|
||||
share->max_key_length= max_length;
|
||||
share->changed= 0;
|
||||
share->auto_key= create_info->auto_key;
|
||||
share->auto_key_type= create_info->auto_key_type;
|
||||
share->auto_increment= create_info->auto_increment;
|
||||
if (!(share->name= my_strdup(name,MYF(0))))
|
||||
{
|
||||
my_free((gptr) share,MYF(0));
|
||||
|
@ -537,3 +537,51 @@ my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void heap_update_auto_increment(HP_INFO *info, const byte *record)
|
||||
{
|
||||
ulonglong value;
|
||||
HA_KEYSEG *keyseg= info->s->keydef[info->s->auto_key - 1].seg;
|
||||
const uchar *key= (uchar*) record + keyseg->start;
|
||||
|
||||
switch (info->s->auto_key_type) {
|
||||
case HA_KEYTYPE_INT8:
|
||||
case HA_KEYTYPE_BINARY:
|
||||
value= (ulonglong) *(uchar*) key;
|
||||
break;
|
||||
case HA_KEYTYPE_SHORT_INT:
|
||||
case HA_KEYTYPE_USHORT_INT:
|
||||
value= (ulonglong) uint2korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_LONG_INT:
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
value= (ulonglong) uint4korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_INT24:
|
||||
case HA_KEYTYPE_UINT24:
|
||||
value= (ulonglong) uint3korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
|
||||
{
|
||||
float f_1;
|
||||
float4get(f_1, key);
|
||||
value= (ulonglong) f_1;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
|
||||
{
|
||||
double f_1;
|
||||
float8get(f_1, key);
|
||||
value= (ulonglong) f_1;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_LONGLONG:
|
||||
case HA_KEYTYPE_ULONGLONG:
|
||||
value= uint8korr(key);
|
||||
break;
|
||||
default:
|
||||
value= 0; /* Error */
|
||||
break;
|
||||
}
|
||||
set_if_bigger(info->s->auto_increment, value);
|
||||
}
|
||||
|
@ -55,5 +55,7 @@ int heap_info(reg1 HP_INFO *info,reg2 HEAPINFO *x,
|
||||
x->index_length= info->s->index_length;
|
||||
x->max_records = info->s->max_records;
|
||||
x->errkey = info->errkey;
|
||||
if (flag & HA_STATUS_AUTO)
|
||||
x->auto_increment= info->s->auto_increment + 1;
|
||||
DBUG_RETURN(0);
|
||||
} /* heap_info */
|
||||
|
@ -37,11 +37,14 @@ int main(int argc, char **argv)
|
||||
const char *filename;
|
||||
HP_KEYDEF keyinfo[10];
|
||||
HA_KEYSEG keyseg[4];
|
||||
HP_CREATE_INFO hp_create_info;
|
||||
MY_INIT(argv[0]);
|
||||
|
||||
filename= "test1";
|
||||
get_options(argc,argv);
|
||||
|
||||
bzero(&hp_create_info, sizeof(hp_create_info));
|
||||
|
||||
keyinfo[0].keysegs=1;
|
||||
keyinfo[0].seg=keyseg;
|
||||
keyinfo[0].algorithm= HA_KEY_ALG_HASH;
|
||||
@ -55,7 +58,8 @@ int main(int argc, char **argv)
|
||||
bzero((gptr) flags,sizeof(flags));
|
||||
|
||||
printf("- Creating heap-file\n");
|
||||
if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000l,10l) ||
|
||||
if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000l,10l,
|
||||
&hp_create_info) ||
|
||||
!(file= heap_open(filename, 2)))
|
||||
goto err;
|
||||
printf("- Writing records:s\n");
|
||||
|
@ -63,6 +63,7 @@ int main(int argc, char *argv[])
|
||||
HP_KEYDEF keyinfo[MAX_KEYS];
|
||||
HA_KEYSEG keyseg[MAX_KEYS*5];
|
||||
HEAP_PTR position;
|
||||
HP_CREATE_INFO hp_create_info;
|
||||
MY_INIT(argv[0]); /* init my_sys library & pthreads */
|
||||
LINT_INIT(position);
|
||||
|
||||
@ -71,6 +72,8 @@ int main(int argc, char *argv[])
|
||||
file=file2=0;
|
||||
get_options(argc,argv);
|
||||
|
||||
bzero(&hp_create_info, sizeof(hp_create_info));
|
||||
|
||||
write_count=update=opt_delete=0;
|
||||
key_check=0;
|
||||
|
||||
@ -122,7 +125,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
printf("- Creating heap-file\n");
|
||||
if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L,
|
||||
(ulong) recant/2) ||
|
||||
(ulong) recant/2, &hp_create_info) ||
|
||||
!(file= heap_open(filename, 2)))
|
||||
goto err;
|
||||
signal(SIGINT,endprog);
|
||||
@ -557,7 +560,7 @@ int main(int argc, char *argv[])
|
||||
heap_close(file2);
|
||||
|
||||
printf("- Creating output heap-file 2\n");
|
||||
if (heap_create(filename2,1,keyinfo,reclength,0L,0L) ||
|
||||
if (heap_create(filename2,1,keyinfo,reclength,0L,0L,&hp_create_info) ||
|
||||
!(file2= heap_open(filename2, 2)))
|
||||
goto err;
|
||||
|
||||
|
@ -22,7 +22,8 @@ int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
|
||||
{
|
||||
HP_KEYDEF *keydef, *end, *p_lastinx;
|
||||
byte *pos;
|
||||
HP_SHARE *share=info->s;
|
||||
bool auto_key_changed= 0;
|
||||
HP_SHARE *share= info->s;
|
||||
DBUG_ENTER("heap_update");
|
||||
|
||||
test_active(info);
|
||||
@ -33,20 +34,23 @@ int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
|
||||
if (--(share->records) < share->blength >> 1) share->blength>>= 1;
|
||||
share->changed=1;
|
||||
|
||||
p_lastinx = share->keydef + info->lastinx;
|
||||
for (keydef = share->keydef, end = keydef + share->keys; keydef < end;
|
||||
keydef++)
|
||||
p_lastinx= share->keydef + info->lastinx;
|
||||
for (keydef= share->keydef, end= keydef + share->keys; keydef < end; keydef++)
|
||||
{
|
||||
if (hp_rec_key_cmp(keydef, old, heap_new))
|
||||
{
|
||||
if ((*keydef->delete_key)(info, keydef, old, pos, keydef == p_lastinx) ||
|
||||
(*keydef->write_key)(info, keydef, heap_new, pos))
|
||||
goto err;
|
||||
if (share->auto_key == (uint) (keydef - share->keydef + 1))
|
||||
auto_key_changed= 1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(pos,heap_new,(size_t) share->reclength);
|
||||
if (++(share->records) == share->blength) share->blength+= share->blength;
|
||||
if (auto_key_changed)
|
||||
heap_update_auto_increment(info, heap_new);
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err:
|
||||
|
@ -61,6 +61,8 @@ int heap_write(HP_INFO *info, const byte *record)
|
||||
info->current_ptr=pos;
|
||||
info->current_hash_ptr=0;
|
||||
info->update|=HA_STATE_AKTIV;
|
||||
if (share->auto_key)
|
||||
heap_update_auto_increment(info, record);
|
||||
DBUG_RETURN(0);
|
||||
err:
|
||||
DBUG_PRINT("info",("Duplicate key: %d", keydef - share->keydef));
|
||||
|
@ -50,6 +50,7 @@ typedef struct st_heapinfo /* Struct from heap_info */
|
||||
ulong index_length;
|
||||
uint reclength; /* Length of one record */
|
||||
int errkey;
|
||||
ulonglong auto_increment;
|
||||
} HEAPINFO;
|
||||
|
||||
|
||||
@ -115,6 +116,9 @@ typedef struct st_heap_share
|
||||
#endif
|
||||
my_bool delete_on_close;
|
||||
LIST open_list;
|
||||
uint auto_key;
|
||||
uint auto_key_type; /* real type of the auto key segment */
|
||||
ulonglong auto_increment;
|
||||
} HP_SHARE;
|
||||
|
||||
struct st_hp_hash_info;
|
||||
@ -140,6 +144,13 @@ typedef struct st_heap_info
|
||||
LIST open_list;
|
||||
} HP_INFO;
|
||||
|
||||
typedef struct st_heap_create_info
|
||||
{
|
||||
uint auto_key;
|
||||
uint auto_key_type;
|
||||
ulonglong auto_increment;
|
||||
} HP_CREATE_INFO;
|
||||
|
||||
/* Prototypes for heap-functions */
|
||||
|
||||
extern HP_INFO *heap_open(const char *name, int mode);
|
||||
@ -152,7 +163,8 @@ extern int heap_scan(register HP_INFO *info, byte *record);
|
||||
extern int heap_delete(HP_INFO *info,const byte *buff);
|
||||
extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag);
|
||||
extern int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
|
||||
uint reclength, ulong max_records, ulong min_records);
|
||||
uint reclength, ulong max_records, ulong min_records,
|
||||
HP_CREATE_INFO *create_info);
|
||||
extern int heap_delete_table(const char *name);
|
||||
extern int heap_extra(HP_INFO *info,enum ha_extra_function function);
|
||||
extern int heap_rename(const char *old_name,const char *new_name);
|
||||
@ -163,7 +175,7 @@ extern int heap_rprev(HP_INFO *info,byte *record);
|
||||
extern int heap_rfirst(HP_INFO *info,byte *record,int inx);
|
||||
extern int heap_rlast(HP_INFO *info,byte *record,int inx);
|
||||
extern void heap_clear(HP_INFO *info);
|
||||
|
||||
extern void heap_update_auto_increment(HP_INFO *info, const byte *record);
|
||||
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key,
|
||||
uint start_key_len,
|
||||
enum ha_rkey_function start_search_flag,
|
||||
|
@ -139,14 +139,14 @@ id parent_id level
|
||||
1015 102 2
|
||||
1010 102 2
|
||||
explain select level from t1 where level=1;
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 ref level level 1 const 1 where used; Using index
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref level level 1 const 1 where used; Using index
|
||||
explain select level,id from t1 where level=1;
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 ref level level 1 const 1 where used; Using index
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref level level 1 const 1 where used; Using index
|
||||
explain select level,id,parent_id from t1 where level=1;
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 ref level level 1 const 1 where used
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref level level 1 const 1 where used
|
||||
select level,id from t1 where level=1;
|
||||
level id
|
||||
1 1002
|
||||
@ -624,8 +624,8 @@ id parent_id level
|
||||
1025 102 2
|
||||
1016 102 2
|
||||
explain select level from t1 where level=1;
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 ref level level 1 const 1 where used; Using index
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref level level 1 const 1 where used; Using index
|
||||
select level,id from t1 where level=1;
|
||||
level id
|
||||
1 1004
|
||||
|
@ -22,14 +22,13 @@ drop table if exists t1,t2;
|
||||
create table t1 (b char(0) not null, index(b));
|
||||
The used table handler can't index column 'b'
|
||||
create table t1 (a int not null auto_increment,primary key (a)) type=heap;
|
||||
The used table type doesn't support AUTO_INCREMENT columns
|
||||
create table t1 (a int not null,b text) type=heap;
|
||||
The used table type doesn't support BLOB/TEXT columns
|
||||
create table t1 (a int ,primary key(a)) type=heap;
|
||||
All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead
|
||||
drop table if exists t1;
|
||||
create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
|
||||
The used table type doesn't support AUTO_INCREMENT columns
|
||||
Incorrect table definition; There can only be one auto column and it must be defined as a key
|
||||
create table t1 (ordid int(8), primary key (ordid));
|
||||
All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead
|
||||
create table not_existing_database.test (a int);
|
||||
|
41
mysql-test/r/heap_auto_increment.result
Normal file
41
mysql-test/r/heap_auto_increment.result
Normal file
@ -0,0 +1,41 @@
|
||||
drop table if exists t1;
|
||||
create table t1 (a int not null auto_increment,b int, primary key (a)) type=heap auto_increment=3;
|
||||
insert into t1 values (1,1),(NULL,3),(NULL,4);
|
||||
delete from t1 where a=4;
|
||||
insert into t1 values (NULL,5),(NULL,6);
|
||||
select * from t1;
|
||||
a b
|
||||
1 1
|
||||
3 3
|
||||
5 5
|
||||
6 6
|
||||
delete from t1 where a=6;
|
||||
replace t1 values (3,1);
|
||||
ALTER TABLE t1 add c int;
|
||||
replace t1 values (3,3,3);
|
||||
insert into t1 values (NULL,7,7);
|
||||
update t1 set a=8,b=b+1,c=c+1 where a=7;
|
||||
insert into t1 values (NULL,9,9);
|
||||
select * from t1;
|
||||
a b c
|
||||
1 1 NULL
|
||||
3 3 3
|
||||
5 5 NULL
|
||||
8 8 8
|
||||
9 9 9
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
skey tinyint unsigned NOT NULL auto_increment PRIMARY KEY,
|
||||
sval char(20)
|
||||
) type=heap;
|
||||
insert into t1 values (NULL, "hello");
|
||||
insert into t1 values (NULL, "hey");
|
||||
select * from t1;
|
||||
skey sval
|
||||
1 hello
|
||||
2 hey
|
||||
select _rowid,t1._rowid,skey,sval from t1;
|
||||
_rowid _rowid skey sval
|
||||
1 1 1 hello
|
||||
2 2 2 hey
|
||||
drop table t1;
|
@ -1,7 +1,7 @@
|
||||
select (select 2);
|
||||
(select 2)
|
||||
2
|
||||
drop table if exists t1,t2,t3,t4,t5,attend,clinic;
|
||||
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
|
||||
create table t1 (a int);
|
||||
create table t2 (a int, b int);
|
||||
create table t3 (a int);
|
||||
@ -131,6 +131,8 @@ patient_uq clinic_uq
|
||||
1 1
|
||||
1 2
|
||||
2 2
|
||||
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
|
||||
Column: 'a' in field list is ambiguous
|
||||
drop table if exists t1,t2,t3;
|
||||
CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0');
|
||||
INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b');
|
||||
@ -147,4 +149,16 @@ W 1
|
||||
SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3);
|
||||
a b
|
||||
W a
|
||||
drop table t1,t2,t3,t4,t5,attend,clinic;
|
||||
drop table if exists inscrit;
|
||||
CREATE TABLE `inscrit` (
|
||||
`pseudo` varchar(35) character set latin1 NOT NULL default '',
|
||||
`email` varchar(60) character set latin1 NOT NULL default '',
|
||||
PRIMARY KEY (`pseudo`),
|
||||
UNIQUE KEY `email` (`email`)
|
||||
) TYPE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
|
||||
INSERT INTO inscrit (pseudo,email) VALUES ('joce','test');
|
||||
INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1');
|
||||
INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1');
|
||||
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%');
|
||||
Subselect returns more than 1 record
|
||||
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
|
||||
|
@ -22,12 +22,12 @@ drop table if exists t1;
|
||||
!$1146 create table t2 select auto+1 from t1;
|
||||
drop table if exists t1,t2;
|
||||
!$1167 create table t1 (b char(0) not null, index(b));
|
||||
!$1164 create table t1 (a int not null auto_increment,primary key (a)) type=heap;
|
||||
create table t1 (a int not null auto_increment,primary key (a)) type=heap;
|
||||
!$1163 create table t1 (a int not null,b text) type=heap;
|
||||
!$1171 create table t1 (a int ,primary key(a)) type=heap;
|
||||
drop table if exists t1;
|
||||
|
||||
!$1164 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
|
||||
!$1075 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
|
||||
!$1171 create table t1 (ordid int(8), primary key (ordid));
|
||||
|
||||
-- error 1044,1
|
||||
|
30
mysql-test/t/heap_auto_increment.test
Normal file
30
mysql-test/t/heap_auto_increment.test
Normal file
@ -0,0 +1,30 @@
|
||||
#
|
||||
# Test of auto_increment; The test for BDB tables is in bdb.test
|
||||
#
|
||||
|
||||
drop table if exists t1;
|
||||
create table t1 (a int not null auto_increment,b int, primary key (a)) type=heap auto_increment=3;
|
||||
insert into t1 values (1,1),(NULL,3),(NULL,4);
|
||||
delete from t1 where a=4;
|
||||
insert into t1 values (NULL,5),(NULL,6);
|
||||
select * from t1;
|
||||
delete from t1 where a=6;
|
||||
#show table status like "t1";
|
||||
replace t1 values (3,1);
|
||||
ALTER TABLE t1 add c int;
|
||||
replace t1 values (3,3,3);
|
||||
insert into t1 values (NULL,7,7);
|
||||
update t1 set a=8,b=b+1,c=c+1 where a=7;
|
||||
insert into t1 values (NULL,9,9);
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
create table t1 (
|
||||
skey tinyint unsigned NOT NULL auto_increment PRIMARY KEY,
|
||||
sval char(20)
|
||||
) type=heap;
|
||||
insert into t1 values (NULL, "hello");
|
||||
insert into t1 values (NULL, "hey");
|
||||
select * from t1;
|
||||
select _rowid,t1._rowid,skey,sval from t1;
|
||||
drop table t1;
|
@ -1,6 +1,6 @@
|
||||
|
||||
select (select 2);
|
||||
drop table if exists t1,t2,t3,t4,t5,attend,clinic;
|
||||
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
|
||||
create table t1 (a int);
|
||||
create table t2 (a int, b int);
|
||||
create table t3 (a int);
|
||||
@ -53,6 +53,10 @@ insert into clinic values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta"
|
||||
insert into attend values (1,1),(1,2),(2,2),(1,3);
|
||||
select * from attend where exists (select * from clinic where uq = clinic_uq);
|
||||
|
||||
# not unique fields
|
||||
-- error 1052
|
||||
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
|
||||
|
||||
# different tipes & group functions
|
||||
drop table if exists t1,t2,t3;
|
||||
|
||||
@ -66,4 +70,19 @@ SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1);
|
||||
SELECT * FROM t2 WHERE b = (SELECT MIN(b) FROM t2);
|
||||
SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3);
|
||||
|
||||
drop table t1,t2,t3,t4,t5,attend,clinic;
|
||||
drop table if exists inscrit;
|
||||
|
||||
CREATE TABLE `inscrit` (
|
||||
`pseudo` varchar(35) character set latin1 NOT NULL default '',
|
||||
`email` varchar(60) character set latin1 NOT NULL default '',
|
||||
PRIMARY KEY (`pseudo`),
|
||||
UNIQUE KEY `email` (`email`)
|
||||
) TYPE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
|
||||
|
||||
INSERT INTO inscrit (pseudo,email) VALUES ('joce','test');
|
||||
INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1');
|
||||
INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1');
|
||||
-- error 1240
|
||||
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%');
|
||||
|
||||
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
|
@ -35,7 +35,9 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
|
||||
{
|
||||
if (!(file= heap_open(name, mode)) && my_errno == ENOENT)
|
||||
{
|
||||
if (!create(name, table, NULL))
|
||||
HA_CREATE_INFO create_info;
|
||||
bzero(&create_info, sizeof(create_info));
|
||||
if (!create(name, table, &create_info))
|
||||
file= heap_open(name, mode);
|
||||
}
|
||||
return (file ? 0 : 1);
|
||||
@ -51,6 +53,8 @@ int ha_heap::write_row(byte * buf)
|
||||
statistic_increment(ha_write_count,&LOCK_status);
|
||||
if (table->time_stamp)
|
||||
update_timestamp(buf+table->time_stamp-1);
|
||||
if (table->next_number_field && buf == table->record[0])
|
||||
update_auto_increment();
|
||||
return heap_write(file,buf);
|
||||
}
|
||||
|
||||
@ -161,6 +165,8 @@ void ha_heap::info(uint flag)
|
||||
index_file_length=info.index_length;
|
||||
max_data_file_length= info.max_records* info.reclength;
|
||||
delete_length= info.deleted * info.reclength;
|
||||
if (flag & HA_STATUS_AUTO)
|
||||
auto_increment_value= info.auto_increment;
|
||||
}
|
||||
|
||||
int ha_heap::extra(enum ha_extra_function operation)
|
||||
@ -234,11 +240,11 @@ ha_rows ha_heap::records_in_range(int inx,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ha_heap::create(const char *name, TABLE *table,
|
||||
HA_CREATE_INFO *create_info)
|
||||
{
|
||||
uint key, parts, mem_per_row= 0;
|
||||
uint auto_key= 0, auto_key_type= 0;
|
||||
ulong max_rows;
|
||||
HP_KEYDEF *keydef;
|
||||
HA_KEYSEG *seg;
|
||||
@ -296,19 +302,42 @@ int ha_heap::create(const char *name, TABLE *table,
|
||||
seg->null_bit= 0;
|
||||
seg->null_pos= 0;
|
||||
}
|
||||
if (field->flags & AUTO_INCREMENT_FLAG)
|
||||
{
|
||||
auto_key= key + 1;
|
||||
auto_key_type= field->key_type();
|
||||
}
|
||||
}
|
||||
}
|
||||
mem_per_row+= MY_ALIGN(table->reclength + 1, sizeof(char*));
|
||||
max_rows = (ulong) (current_thd->variables.max_heap_table_size /
|
||||
mem_per_row);
|
||||
HP_CREATE_INFO hp_create_info;
|
||||
hp_create_info.auto_key= auto_key;
|
||||
hp_create_info.auto_key_type= auto_key_type;
|
||||
hp_create_info.auto_increment= (create_info->auto_increment_value ?
|
||||
create_info->auto_increment_value - 1 : 0);
|
||||
error= heap_create(fn_format(buff,name,"","",4+2),
|
||||
table->keys,keydef, table->reclength,
|
||||
((table->max_rows < max_rows && table->max_rows) ?
|
||||
table->max_rows : max_rows),
|
||||
table->min_rows);
|
||||
table->min_rows, &hp_create_info);
|
||||
my_free((gptr) keydef, MYF(0));
|
||||
if (file)
|
||||
info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
|
||||
ref_length= sizeof(HEAP_PTR);
|
||||
return (error);
|
||||
}
|
||||
|
||||
void ha_heap::update_create_info(HA_CREATE_INFO *create_info)
|
||||
{
|
||||
table->file->info(HA_STATUS_AUTO);
|
||||
if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
|
||||
create_info->auto_increment_value= auto_increment_value;
|
||||
}
|
||||
|
||||
longlong ha_heap::get_auto_increment()
|
||||
{
|
||||
ha_heap::info(HA_STATUS_AUTO);
|
||||
return auto_increment_value;
|
||||
}
|
||||
|
@ -40,8 +40,7 @@ class ha_heap: public handler
|
||||
ulong table_flags() const
|
||||
{
|
||||
return (HA_READ_RND_SAME | HA_NO_INDEX | HA_KEYPOS_TO_RNDPOS |
|
||||
HA_NO_BLOBS | HA_NULL_KEY | HA_REC_NOT_IN_SEQ |
|
||||
HA_NO_AUTO_INCREMENT);
|
||||
HA_NO_BLOBS | HA_NULL_KEY | HA_REC_NOT_IN_SEQ);
|
||||
}
|
||||
ulong index_flags(uint inx) const
|
||||
{
|
||||
@ -63,6 +62,7 @@ class ha_heap: public handler
|
||||
int write_row(byte * buf);
|
||||
int update_row(const byte * old_data, byte * new_data);
|
||||
int delete_row(const byte * buf);
|
||||
longlong get_auto_increment();
|
||||
int index_read(byte * buf, const byte * key,
|
||||
uint key_len, enum ha_rkey_function find_flag);
|
||||
int index_read_idx(byte * buf, uint idx, const byte * key,
|
||||
@ -87,6 +87,7 @@ class ha_heap: public handler
|
||||
int delete_table(const char *from);
|
||||
int rename_table(const char * from, const char * to);
|
||||
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
|
||||
void update_create_info(HA_CREATE_INFO *create_info);
|
||||
|
||||
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
||||
enum thr_lock_type lock_type);
|
||||
|
41
sql/item.cc
41
sql/item.cc
@ -432,7 +432,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
if (!field) // If field is not checked
|
||||
{
|
||||
Field *tmp;
|
||||
if (!(tmp=find_field_in_tables(thd, this, tables, 0)))
|
||||
if ((tmp= find_field_in_tables(thd, this, tables, 0)) == not_found_field)
|
||||
{
|
||||
/*
|
||||
We can't find table field in table list of current select,
|
||||
@ -445,14 +445,18 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
*/
|
||||
SELECT_LEX *last= 0;
|
||||
for (SELECT_LEX *sl= thd->lex.select->outer_select();
|
||||
sl && !tmp;
|
||||
sl;
|
||||
sl= sl->outer_select())
|
||||
tmp=find_field_in_tables(thd, this,
|
||||
(TABLE_LIST*)(last= sl)->table_list.first,
|
||||
0);
|
||||
if ((tmp= find_field_in_tables(thd, this,
|
||||
(TABLE_LIST*)
|
||||
(last= sl)->table_list.first,
|
||||
0)) != not_found_field)
|
||||
break;
|
||||
if (!tmp)
|
||||
return -1;
|
||||
else if (tmp == not_found_field)
|
||||
{
|
||||
// Call to produce appropriate error message
|
||||
// call to return error code
|
||||
find_field_in_tables(thd, this, tables, 1);
|
||||
return -1;
|
||||
}
|
||||
@ -479,6 +483,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!tmp)
|
||||
return -1;
|
||||
|
||||
set_field(tmp);
|
||||
}
|
||||
else if (thd && thd->set_query_id && field->query_id != thd->query_id)
|
||||
@ -786,7 +793,9 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
{
|
||||
if (!ref)
|
||||
{
|
||||
if (!(ref= find_item_in_list(this, thd->lex.select->item_list, 0)))
|
||||
if ((ref= find_item_in_list(this, thd->lex.select->item_list,
|
||||
REPORT_EXCEPT_NOT_FOUND)) ==
|
||||
(Item **)not_found_item)
|
||||
{
|
||||
/*
|
||||
We can't find table field in table list of current select,
|
||||
@ -795,17 +804,25 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
of view rules. For example if both tables (outer & current) have
|
||||
field 'field' it is not mistake to refer to this field without
|
||||
mention of table name, but if we join tables in one list it will
|
||||
cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
|
||||
cause error ER_NON_UNIQ_ERROR in find_item_in_list.
|
||||
*/
|
||||
SELECT_LEX *last=0;
|
||||
for (SELECT_LEX *sl= thd->lex.select->outer_select();
|
||||
sl && !ref;
|
||||
sl;
|
||||
sl= sl->outer_select())
|
||||
ref= find_item_in_list(this, (last= sl)->item_list, 0);
|
||||
if((ref= find_item_in_list(this, (last= sl)->item_list,
|
||||
REPORT_EXCEPT_NOT_FOUND)) !=
|
||||
(Item **)not_found_item)
|
||||
break;
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (ref == (Item **)not_found_item)
|
||||
{
|
||||
// Call to report error
|
||||
find_item_in_list(this, thd->lex.select->item_list, 1);
|
||||
find_item_in_list(this, thd->lex.select->item_list, REPORT_ALL_ERRORS);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -831,6 +848,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!ref)
|
||||
return 1;
|
||||
max_length= (*ref)->max_length;
|
||||
maybe_null= (*ref)->maybe_null;
|
||||
decimals= (*ref)->decimals;
|
||||
|
@ -32,11 +32,22 @@ SUBSELECT TODO:
|
||||
#include "mysql_priv.h"
|
||||
#include "sql_select.h"
|
||||
|
||||
Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex,
|
||||
select_subselect *result):
|
||||
Item_subselect::Item_subselect():
|
||||
Item(), engine_owner(1), value_assigned(0)
|
||||
{
|
||||
DBUG_ENTER("Item_subselect::Item_subselect");
|
||||
assign_null();
|
||||
/*
|
||||
item value is NULL if select_subselect not changed this value
|
||||
(i.e. some rows will be found returned)
|
||||
*/
|
||||
null_value= 1;
|
||||
}
|
||||
|
||||
void Item_subselect::init(THD *thd, st_select_lex *select_lex,
|
||||
select_subselect *result)
|
||||
{
|
||||
|
||||
DBUG_ENTER("Item_subselect::init");
|
||||
DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex));
|
||||
|
||||
if (select_lex->next_select())
|
||||
@ -45,12 +56,6 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex,
|
||||
else
|
||||
engine= new subselect_single_select_engine(thd, select_lex, result,
|
||||
this);
|
||||
assign_null();
|
||||
/*
|
||||
item value is NULL if select_subselect not changed this value
|
||||
(i.e. some rows will be found returned)
|
||||
*/
|
||||
null_value= 1;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -83,6 +88,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
return 1;
|
||||
}
|
||||
int res= engine->prepare();
|
||||
if (!res)
|
||||
fix_length_and_dec();
|
||||
return res;
|
||||
}
|
||||
@ -99,8 +105,9 @@ inline table_map Item_subselect::used_tables() const
|
||||
|
||||
Item_singleval_subselect::Item_singleval_subselect(THD *thd,
|
||||
st_select_lex *select_lex):
|
||||
Item_subselect(thd, select_lex, new select_singleval_subselect(this))
|
||||
Item_subselect()
|
||||
{
|
||||
init(thd, select_lex, new select_singleval_subselect(this));
|
||||
max_columns= 1;
|
||||
maybe_null= 1;
|
||||
}
|
||||
@ -119,28 +126,38 @@ Item::Type Item_subselect::type() const
|
||||
double Item_singleval_subselect::val ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
return 0;
|
||||
}
|
||||
return real_value;
|
||||
}
|
||||
|
||||
longlong Item_singleval_subselect::val_int ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
return 0;
|
||||
}
|
||||
return int_value;
|
||||
}
|
||||
|
||||
String *Item_singleval_subselect::val_str (String *str)
|
||||
{
|
||||
if (engine->exec() || null_value)
|
||||
{
|
||||
assign_null();
|
||||
return 0;
|
||||
}
|
||||
return &str_value;
|
||||
}
|
||||
|
||||
Item_exists_subselect::Item_exists_subselect(THD *thd,
|
||||
st_select_lex *select_lex):
|
||||
Item_subselect(thd, select_lex, new select_exists_subselect(this))
|
||||
Item_subselect()
|
||||
{
|
||||
init(thd, select_lex, new select_exists_subselect(this));
|
||||
max_columns= UINT_MAX;
|
||||
null_value= 0; //can't be NULL
|
||||
maybe_null= 0; //can't be NULL
|
||||
@ -157,21 +174,30 @@ void Item_exists_subselect::fix_length_and_dec()
|
||||
double Item_exists_subselect::val ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
return 0;
|
||||
}
|
||||
return (double) value;
|
||||
}
|
||||
|
||||
longlong Item_exists_subselect::val_int ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
return 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
String *Item_exists_subselect::val_str(String *str)
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
return 0;
|
||||
}
|
||||
str->set(value);
|
||||
return str;
|
||||
}
|
||||
|
@ -39,8 +39,7 @@ protected:
|
||||
uint max_columns;
|
||||
|
||||
public:
|
||||
Item_subselect(THD *thd, st_select_lex *select_lex,
|
||||
select_subselect* result);
|
||||
Item_subselect();
|
||||
Item_subselect(Item_subselect *item)
|
||||
{
|
||||
null_value= item->null_value;
|
||||
@ -50,6 +49,14 @@ public:
|
||||
engine_owner= 0;
|
||||
name= item->name;
|
||||
}
|
||||
|
||||
/*
|
||||
We need this method, because some compilers do not allow 'this'
|
||||
pointer in constructor initialization list, but we need pass pointer
|
||||
to subselect Item class to select_subselect classes constructor.
|
||||
*/
|
||||
void init (THD *thd, st_select_lex *select_lex, select_subselect *result);
|
||||
|
||||
~Item_subselect();
|
||||
virtual void assign_null()
|
||||
{
|
||||
|
@ -457,6 +457,7 @@ bool wait_for_tables(THD *thd);
|
||||
bool table_is_used(TABLE *table, bool wait_for_name_lock);
|
||||
bool drop_locked_tables(THD *thd,const char *db, const char *table_name);
|
||||
void abort_locked_tables(THD *thd,const char *db, const char *table_name);
|
||||
extern const Field *not_found_field;
|
||||
Field *find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables,
|
||||
bool report_error);
|
||||
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
||||
@ -546,7 +547,11 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
|
||||
|
||||
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
||||
table_map read_tables, COND *conds, int *error);
|
||||
Item ** find_item_in_list(Item *item, List<Item> &items, bool report_error);
|
||||
enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
|
||||
IGNORE_ERRORS};
|
||||
extern const Item **not_found_item;
|
||||
Item ** find_item_in_list(Item *item, List<Item> &items,
|
||||
find_item_error_report_type report_error);
|
||||
bool insert_fields(THD *thd,TABLE_LIST *tables,
|
||||
const char *db_name, const char *table_name,
|
||||
List_iterator<Item> *it);
|
||||
|
@ -1781,9 +1781,29 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
||||
return field;
|
||||
}
|
||||
|
||||
// Special Field pointer for find_field_in_tables returning
|
||||
const Field *not_found_field= (Field*) 0x1;
|
||||
/*
|
||||
Find field in table list.
|
||||
|
||||
SYNOPSIS
|
||||
find_field_in_tables()
|
||||
thd - pointer to current thread structure
|
||||
item - field item that should be found
|
||||
tables - tables for scaning
|
||||
report_error - if FALSE then do not report error if item not found and
|
||||
return not_found_field;
|
||||
|
||||
RETURN VALUES
|
||||
0 - field is not found or field is not unique, error message is
|
||||
reported
|
||||
not_found_field - function was called with report_error == FALSE and
|
||||
field if not found, no error message reported
|
||||
found field
|
||||
*/
|
||||
|
||||
Field *
|
||||
find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables,
|
||||
find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables,
|
||||
bool report_error)
|
||||
{
|
||||
Field *found=0;
|
||||
@ -1829,13 +1849,18 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables,
|
||||
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
|
||||
table_name=buff;
|
||||
}
|
||||
my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0),table_name,
|
||||
thd->where);
|
||||
if (report_error)
|
||||
my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
|
||||
table_name, thd->where);
|
||||
else
|
||||
return (Field*) not_found_field;
|
||||
}
|
||||
else
|
||||
if (report_error)
|
||||
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
|
||||
item->full_name(),thd->where);
|
||||
else
|
||||
return (Field*) not_found_field;
|
||||
return (Field*) 0;
|
||||
}
|
||||
bool allow_rowid= tables && !tables->next; // Only one table
|
||||
@ -1850,9 +1875,8 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables,
|
||||
return (Field*) 0;
|
||||
if (found)
|
||||
{
|
||||
if (!report_error) // Returns first found
|
||||
if (!thd->where) // Returns first found
|
||||
break;
|
||||
if (report_error)
|
||||
my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
|
||||
name,thd->where);
|
||||
return (Field*) 0;
|
||||
@ -1865,11 +1889,39 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables,
|
||||
if (report_error)
|
||||
my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR),
|
||||
MYF(0), item->full_name(), thd->where);
|
||||
else
|
||||
return (Field*) not_found_field;
|
||||
return (Field*) 0;
|
||||
}
|
||||
|
||||
// Special Item pointer for find_item_in_list returning
|
||||
const Item **not_found_item= (const Item**) 0x1;
|
||||
|
||||
/*
|
||||
Find Item in list of items (find_field_in_tables analog)
|
||||
|
||||
SYNOPSIS
|
||||
find_item_in_list()
|
||||
find - item to find
|
||||
items - list of items
|
||||
report_error
|
||||
REPORT_ALL_ERRORS - report errors, return 0 if error
|
||||
REPORT_EXCEPT_NOT_FOUND - do not report 'not found' error and return not_ found_item, report other errors, return 0
|
||||
IGNORE_ERRORS - do not report errors, return 0 if error
|
||||
|
||||
RETURN VALUES
|
||||
0 - item is not found or item is not unique, error message is
|
||||
reported
|
||||
not_found_item - function was called with report_error ==
|
||||
REPORT_EXCEPT_NOT_FOUND and item if not found, no error
|
||||
message reported
|
||||
found field
|
||||
|
||||
*/
|
||||
|
||||
Item **
|
||||
find_item_in_list(Item *find, List<Item> &items, bool report_error)
|
||||
find_item_in_list(Item *find, List<Item> &items,
|
||||
find_item_error_report_type report_error)
|
||||
{
|
||||
List_iterator<Item> li(items);
|
||||
Item **found=0,*item;
|
||||
@ -1894,7 +1946,7 @@ find_item_in_list(Item *find, List<Item> &items, bool report_error)
|
||||
{
|
||||
if ((*found)->eq(item,0))
|
||||
continue; // Same field twice (Access?)
|
||||
if (report_error)
|
||||
if (report_error != IGNORE_ERRORS)
|
||||
my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
|
||||
find->full_name(), current_thd->where);
|
||||
return (Item**) 0;
|
||||
@ -1917,10 +1969,17 @@ find_item_in_list(Item *find, List<Item> &items, bool report_error)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found && report_error)
|
||||
if (found)
|
||||
return found;
|
||||
else if (report_error != REPORT_EXCEPT_NOT_FOUND)
|
||||
{
|
||||
if (report_error == REPORT_ALL_ERRORS)
|
||||
my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0),
|
||||
find->full_name(), current_thd->where);
|
||||
return found;
|
||||
return (Item **) 0;
|
||||
}
|
||||
else
|
||||
return (Item **) not_found_item;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -6487,7 +6487,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields,
|
||||
order->in_field_list=1;
|
||||
return 0;
|
||||
}
|
||||
Item **item=find_item_in_list(*order->item, fields, 0);
|
||||
Item **item= find_item_in_list(*order->item, fields, IGNORE_ERRORS);
|
||||
if (item)
|
||||
{
|
||||
order->item=item; // use it
|
||||
@ -6587,7 +6587,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
||||
thd->set_query_id=1; // Not really needed, but...
|
||||
for (; new_field ; new_field= new_field->next)
|
||||
{
|
||||
if ((item= find_item_in_list(*new_field->item, fields, 0)))
|
||||
if ((item= find_item_in_list(*new_field->item, fields, IGNORE_ERRORS)))
|
||||
new_field->item=item; /* Change to shared Item */
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user