Commit 51605017 authored by unknown's avatar unknown

Update of manual with 4.0 changes

Create innodb table space if configuring with InnoDB and not using --skip-innodb
Fixes for TRUNCATE TABLE and DROP DATABASE.


Docs/manual.texi:
  Update of manual with 4.0 changes.
mysql-test/mysql-test-run.sh:
  Fixed option --mysqld
mysql-test/r/innodb.result:
  More test cases
mysql-test/r/truncate.result:
  More test cases
mysql-test/t/drop.test:
  More test cases
mysql-test/t/innodb.test:
  More test cases
mysql-test/t/truncate.test:
  More test cases
sql/gen_lex_hash.cc:
  Smaller array
sql/ha_innobase.cc:
  Create innodb table space if not using --skip-innodb
sql/lock.cc:
  Fixed wrong mutex handling in global read lock.
sql/md5.c:
  Fixed bug from merge
sql/sql_base.cc:
  cleanup
sql/sql_db.cc:
  Use new global lock functions.
  Fixed new bug that database wasn't always dropped.
sql/sql_delete.cc:
  Fixed problem with mysql_truncate() when called from restore_table
sql/sql_parse.cc:
  Fixed error message handling.
sql/sql_table.cc:
  cleanup
parent b4a41710
...@@ -145,14 +145,14 @@ distribution for that version. ...@@ -145,14 +145,14 @@ distribution for that version.
@cindex online location of manual @cindex online location of manual
@cindex manual, online location @cindex manual, online location
This is the MySQL reference manual; it documents MySQL This is the MySQL reference manual; it documents MySQL Version
Version @value{mysql_version}. As MySQL is work in progress, @value{mysql_version}. As MySQL is work in progress, the manual gets
the manual gets updated frequently. There is a very good chance that updated frequently. There is a very good chance that this version is
this version is out of date, unless you are looking at it online. The out of date, unless you are looking at it online. The most recent
most recent version of this manual is available at version of this manual is available at
@uref{http://www.mysql.com/documentation/} in many different formats. If you @uref{http://www.mysql.com/documentation/index.html} in many different
have a hard time finding information in the manual, you can try the formats. If you have a hard time finding information in the manual, you
searchable PHP version at @uref{http://www.mysql.com/documentation/manual.php}. can try the searchable PHP version at @uref{http://www.mysql.com/doc}.
MySQL is a very fast, multi-threaded, multi-user, and robust SQL MySQL is a very fast, multi-threaded, multi-user, and robust SQL
(Structured Query Language) database server. (Structured Query Language) database server.
...@@ -181,6 +181,10 @@ For installation instructions, see @ref{Installing}. ...@@ -181,6 +181,10 @@ For installation instructions, see @ref{Installing}.
For tips on porting MySQL to new architectures or operating For tips on porting MySQL to new architectures or operating
systems, see @ref{Porting}. systems, see @ref{Porting}.
@item
For information about upgrading from a Version 3.23 release, see
@ref{Upgrading-from-3.23}.
@item @item
For information about upgrading from a Version 3.22 release, see For information about upgrading from a Version 3.22 release, see
@ref{Upgrading-from-3.22}. @ref{Upgrading-from-3.22}.
...@@ -1484,36 +1488,19 @@ A complete reference to DBI. ...@@ -1484,36 +1488,19 @@ A complete reference to DBI.
@node General-SQL, Useful Links, MySQL-Books, MySQL Information Sources @node General-SQL, Useful Links, MySQL-Books, MySQL Information Sources
@subsection General SQL Information and Tutorials @subsection General SQL Information and Tutorials
The following book has been recommended by several people on the MySQL The MySQL book portal is split into different sections to make it easy
mailing list: to locate books for various purposes.
@uref{http://www.mysql.com/portal/books/html/index.html}
@example
Judith S. Bowman, Sandra L. Emerson and Marcy Darnovsky
@emph{The Practical SQL Handbook: Using Structured Query Language}
Second Edition
Addison-Wesley
ISBN 0-201-62623-3
http://www.awl.com
@end example
The following book has also received some recommendations by MySQL
users:
@example
Martin Gruber
@emph{Understanding SQL}
ISBN 0-89588-644-8
Publisher Sybex 510 523 8233
Alameda, CA USA
@end example
A SQL tutorial is available on the net at
http://w3.one.net/~jhoffman/sqltut.htm
Tutorials can be found at:
@uref{http://www.mysql.com/portal/development/html/development-61-1.html}
@node Useful Links, Questions, General-SQL, MySQL Information Sources @node Useful Links, Questions, General-SQL, MySQL Information Sources
@subsection Useful MySQL-related Links @subsection Useful MySQL-related Links
The MySQL development portal is the ultimate source of MySQL related
links. @uref{http://www.mysql.com/portal/development/html/index.html}
Apart from the following links, you can find and download a lot of Apart from the following links, you can find and download a lot of
MySQL programs, tools and APIs from the MySQL programs, tools and APIs from the
@uref{http://www.mysql.com/Downloads/Contrib/, Contrib directory}. @uref{http://www.mysql.com/Downloads/Contrib/, Contrib directory}.
...@@ -5347,10 +5334,11 @@ SQL functions and aggregates, but this is not yet as easy or as flexible ...@@ -5347,10 +5334,11 @@ SQL functions and aggregates, but this is not yet as easy or as flexible
as in PostgreSQL. @xref{Adding functions}. as in PostgreSQL. @xref{Adding functions}.
@item @item
Updates and deletes that run over multiple tables is harder to do in Updates that run over multiple tables is harder to do in MySQL.
MySQL. This will, hoever, be fixed in MySQL 4.0 with multi-table This will, however, be fixed in MySQL 4.0 with multi-table @code{UPDATE}
@code{DELETE} and multi-table @code{UPDATE} and in MySQL 4.1 and in MySQL 4.1 with subselects.
with subselects. In MySQL 4.0 one can use multi-table deletes to delete from many tables
at the same time. @xref{DELETE}.
@end itemize @end itemize
PostgreSQL currently offers the following advantages over MySQL: PostgreSQL currently offers the following advantages over MySQL:
...@@ -5710,6 +5698,9 @@ master. ...@@ -5710,6 +5698,9 @@ master.
@code{DELETE FROM table_name} will return the number of deleted rows. For @code{DELETE FROM table_name} will return the number of deleted rows. For
fast execution one should use @code{TRUNCATE table_name}. fast execution one should use @code{TRUNCATE table_name}.
@item @item
Multi-table @code{DELETE} (cascading @code{DELETE} and multi-table
@code{DELETE}.
@item
Allow @code{DELETE} on @code{MyISAM} tables to use the record cache. Allow @code{DELETE} on @code{MyISAM} tables to use the record cache.
To do this, we need to update the threads record cache when we update To do this, we need to update the threads record cache when we update
the @code{.MYD} file. the @code{.MYD} file.
...@@ -5806,6 +5797,8 @@ Multiple result sets. ...@@ -5806,6 +5797,8 @@ Multiple result sets.
Change the protocol to allow binary transfer of values. To do this Change the protocol to allow binary transfer of values. To do this
efficiently, we need to add an API to allow binding of variables. efficiently, we need to add an API to allow binding of variables.
@item @item
Add @code{PREPARE} of statements and sending of parameters to @code{mysqld}.
@item
Make it possible to specify @code{long_query_time} with a granularity Make it possible to specify @code{long_query_time} with a granularity
in microseconds. in microseconds.
@item @item
...@@ -9291,14 +9284,45 @@ particularly if you notice symptoms such as all your @code{DBI} scripts ...@@ -9291,14 +9284,45 @@ particularly if you notice symptoms such as all your @code{DBI} scripts
dumping core after you upgrade MySQL. dumping core after you upgrade MySQL.
@menu @menu
* Upgrading-from-3.23:: Upgrading from a 3.23 version to 4.0
* Upgrading-from-3.22:: Upgrading from a 3.22 version to 3.23 * 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.21:: Upgrading from a 3.21 version to 3.22
* Upgrading-from-3.20:: Upgrading from a 3.20 version to 3.21 * Upgrading-from-3.20:: Upgrading from a 3.20 version to 3.21
* Upgrading-to-arch:: Upgrading to another architecture * Upgrading-to-arch:: Upgrading to another architecture
@end menu @end menu
@cindex compatibility, between MySQL versions
@cindex upgrading, 3.23 to 4.0
@node Upgrading-from-3.23, Upgrading-from-3.22, Upgrade, Upgrade
@subsection Upgrading From Version 3.23 to Version 4.0
You can use your old data files without any modification with Version 4.0.
If you want to move your data from a MySQL 4.0 server to an older server,
you have to use @code{mysqldump}.
Old clients should work with a Version 4.0 server without any problems.
The following lists tell what you have to watch out for when upgrading to
Version 4.0;
@node Upgrading-from-3.22, Upgrading-from-3.21, Upgrade, Upgrade @itemize @bullet
@item
@file{safe_mysqld} is renamed to @file{mysqld_safe}.
@item
The old C API functions @code{mysql_drop_db}, @code{mysql_create_db} and
@code{mysql_connect} are not supported anymore, unless one compiles
MySQL with @code{USE_OLD_FUNCTIONS}.
@item
You should use @code{TRUNCATE TABLE} when you want to delete all rows
from a table and you don't care of how many rows where deleted.
(Because @code{TRUNCATE TABLE} is faster than @code{DELETE FROM table_name}).
@item
You will get an error if you have an active @code{LOCK TABLES} or
transaction when trying to execute @code{TRUNCATE TABLE} or @code{DROP
DATABASE}.
@end itemize
@node Upgrading-from-3.22, Upgrading-from-3.21, Upgrading-from-3.23, Upgrade
@subsection Upgrading From Version 3.22 to Version 3.23 @subsection Upgrading From Version 3.22 to Version 3.23
@cindex compatibility, between MySQL versions @cindex compatibility, between MySQL versions
...@@ -16908,6 +16932,7 @@ GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ...@@ -16908,6 +16932,7 @@ GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
ON @{tbl_name | * | *.* | db_name.*@} ON @{tbl_name | * | *.* | db_name.*@}
TO user_name [IDENTIFIED BY 'password'] TO user_name [IDENTIFIED BY 'password']
[, user_name [IDENTIFIED BY 'password'] ...] [, user_name [IDENTIFIED BY 'password'] ...]
[REQUIRE @{SSL|X509@} [ISSUER issuer] [SUBJECT subject]]
[WITH GRANT OPTION] [WITH GRANT OPTION]
REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
...@@ -23651,6 +23676,15 @@ The number of seconds the slave thread will sleep before retrying to ...@@ -23651,6 +23676,15 @@ The number of seconds the slave thread will sleep before retrying to
connect to the master in case the master goes down or the connection is connect to the master in case the master goes down or the connection is
lost. Default is 60. (Example: @code{master-connect-retry=60}) lost. Default is 60. (Example: @code{master-connect-retry=60})
@item @code{master-ssl} @tab
Turn SSL on (Example: @code{master-ssl})
@item @code{master-ssl-key} @tab
Master SSL keyfile name (Example: @code{master-ssl-key=SSL/master-key.pem})
@item @code{master-ssl-cert} @tab
Master SSL certificate file name (Example: @code{master-ssl-key=SSL/master-cert.pem})
@item @code{master-info-file=filename} @tab @item @code{master-info-file=filename} @tab
The location of the file that remembers where we left off on the master The location of the file that remembers where we left off on the master
during the replication process. The default is master.info in the data during the replication process. The default is master.info in the data
...@@ -25348,6 +25382,8 @@ Some ways to speed up inserts: ...@@ -25348,6 +25382,8 @@ Some ways to speed up inserts:
If you are inserting many rows from the same client at the same time, use If you are inserting many rows from the same client at the same time, use
multiple value lists @code{INSERT} statements. This is much faster (many multiple value lists @code{INSERT} statements. This is much faster (many
times in some cases) than using separate @code{INSERT} statements. times in some cases) than using separate @code{INSERT} statements.
Tune up @code{myisam_bulk_insert_tree_size} variable to make it even
faster. @xref{SHOW VARIABLES}.
@item @item
If you are inserting a lot of rows from different clients, you can get If you are inserting a lot of rows from different clients, you can get
higher speed by using the @code{INSERT DELAYED} statement. @xref{INSERT, higher speed by using the @code{INSERT DELAYED} statement. @xref{INSERT,
...@@ -25397,6 +25433,13 @@ flush-tables}. ...@@ -25397,6 +25433,13 @@ flush-tables}.
This procedure will be built into @code{LOAD DATA INFILE} in some future This procedure will be built into @code{LOAD DATA INFILE} in some future
version of MySQL. version of MySQL.
Since @strong{MySQL 4.0} you can also use
@code{ALTER TABLE tbl_name DISABLE KEYS} instead of
@code{myisamchk --keys-used=0 -rq /path/to/db/tbl_name} and
@code{ALTER TABLE tbl_name ENABLE KEYS} instead of
@code{myisamchk -r -q /path/to/db/tbl_name}. This way you can also skip
@code{FLUSH TABLES} steps.
@item @item
You can speed up insertions by locking your tables: You can speed up insertions by locking your tables:
...@@ -27197,8 +27240,6 @@ Things that are not yet supported: ...@@ -27197,8 +27240,6 @@ Things that are not yet supported:
@end itemize @end itemize
@node Reference, Table types, MySQL Optimization, Top @node Reference, Table types, MySQL Optimization, Top
@chapter MySQL Language Reference @chapter MySQL Language Reference
...@@ -27210,6 +27251,7 @@ Things that are not yet supported: ...@@ -27210,6 +27251,7 @@ Things that are not yet supported:
* Data Definition:: Data Definition: @code{CREATE}, @code{DROP}, @code{ALTER} * Data Definition:: Data Definition: @code{CREATE}, @code{DROP}, @code{ALTER}
* Basic User Commands:: Basic MySQL User Utility Commands * Basic User Commands:: Basic MySQL User Utility Commands
* Transactional Commands:: MySQL Transactional and Locking Commands * Transactional Commands:: MySQL Transactional and Locking Commands
* HANDLER::
* Fulltext Search:: MySQL Full-text Search * Fulltext Search:: MySQL Full-text Search
@end menu @end menu
...@@ -27458,12 +27500,16 @@ like an integer (64-bit precision). In string context these act like a binary ...@@ -27458,12 +27500,16 @@ like an integer (64-bit precision). In string context these act like a binary
string where each pair of hex digits is converted to a character: string where each pair of hex digits is converted to a character:
@example @example
mysql> SELECT x'FF'
-> 255
mysql> SELECT 0xa+0; mysql> SELECT 0xa+0;
-> 10 -> 10
mysql> select 0x5061756c; mysql> select 0x5061756c;
-> Paul -> Paul
@end example @end example
The x'hexstring' syntax (new in 4.0) is based on ANSI SQL and the 0x
syntax is based on ODBC.
Hexadecimal strings are often used by ODBC to give values for BLOB columns. Hexadecimal strings are often used by ODBC to give values for BLOB columns.
...@@ -31988,6 +32034,7 @@ facilitate replication testing. ...@@ -31988,6 +32034,7 @@ facilitate replication testing.
@menu @menu
* SELECT:: @code{SELECT} Syntax * SELECT:: @code{SELECT} Syntax
* UNION::
* INSERT:: @code{INSERT} Syntax * INSERT:: @code{INSERT} Syntax
* INSERT DELAYED:: @code{INSERT DELAYED} syntax * INSERT DELAYED:: @code{INSERT DELAYED} syntax
* UPDATE:: @code{UPDATE} Syntax * UPDATE:: @code{UPDATE} Syntax
...@@ -31997,7 +32044,7 @@ facilitate replication testing. ...@@ -31997,7 +32044,7 @@ facilitate replication testing.
* LOAD DATA:: @code{LOAD DATA INFILE} Syntax * LOAD DATA:: @code{LOAD DATA INFILE} Syntax
@end menu @end menu
@node SELECT, INSERT, Data Manipulation, Data Manipulation @node SELECT, UNION, Data Manipulation, Data Manipulation
@subsection @code{SELECT} Syntax @subsection @code{SELECT} Syntax
@findex SELECT @findex SELECT
...@@ -32425,7 +32472,40 @@ mysql> select * from table1 IGNORE INDEX (key3) WHERE key1=1 and key2=2 AND ...@@ -32425,7 +32472,40 @@ mysql> select * from table1 IGNORE INDEX (key3) WHERE key1=1 and key2=2 AND
@xref{LEFT JOIN optimization, , @code{LEFT JOIN} optimization}. @xref{LEFT JOIN optimization, , @code{LEFT JOIN} optimization}.
@node INSERT, INSERT DELAYED, SELECT, Data Manipulation @node UNION, INSERT, SELECT, Data Manipulation
@subsection @code{UNION} Syntax
@findex UNION
@example
SELECT ....
UNION [ALL]
SELECT ....
[UNION
SELECT ...]
@end example
@code{UNION} is implemented in MySQL 4.0.0.
@code{UNION} is used to combine the result from many @code{SELECT}
statements into one result set.
The @code{SELECT} commands are normal select commands, but with the following
restrictions:
@itemize @bullet
@item
Only the last @code{SELECT} command can have @code{INTO OUTFILE}.
@item
Only the last @code{SELECT} command can have @code{ORDER BY}.
@end itemize
If you don't use the keyword @code{ALL} for the @code{UNION}, all
returned rows will be unique, like if you had done a @code{DISTINCT} for
the total result set. If you specify @code{ALL}, then you will get all
matching rows from all the used @code{SELECT} statements.
@node INSERT, INSERT DELAYED, UNION, Data Manipulation
@subsection @code{INSERT} Syntax @subsection @code{INSERT} Syntax
@findex INSERT @findex INSERT
...@@ -32800,40 +32880,82 @@ only a given number of rows are changed. ...@@ -32800,40 +32880,82 @@ only a given number of rows are changed.
@findex DELETE @findex DELETE
@example @example
DELETE [LOW_PRIORITY] FROM tbl_name DELETE [LOW_PRIORITY | QUICK] FROM table_name
[WHERE where_definition] [WHERE where_definition]
[ORDER BY ...]
[LIMIT rows] [LIMIT rows]
or
DELETE [LOW_PRIORITY | QUICK] table_name[.*] [table_name[.*] ...] FROM
table-references [WHERE where_definition]
@end example @end example
@code{DELETE} deletes rows from @code{tbl_name} that satisfy the condition @code{DELETE} deletes rows from @code{table_name} that satisfy the condition
given by @code{where_definition}, and returns the number of records deleted. given by @code{where_definition}, and returns the number of records deleted.
If you issue a @code{DELETE} with no @code{WHERE} clause, all rows are If you issue a @code{DELETE} with no @code{WHERE} clause, all rows are
deleted. If you do this in @code{AUTOCOMMIT} mode, this works as deleted. If you do this in @code{AUTOCOMMIT} mode, this works as
@code{TRUNCATE}. @xref{TRUNCATE}. One problem with this is that @code{TRUNCATE}. @xref{TRUNCATE}. In MySQL 3.23 @code{DELETE} without a
@code{DELETE} will return zero as the number of affected records, but @code{WHERE} clause will return zero as the number of affected records.
this will be fixed in 4.0.
If you really want to know how many records are deleted when you are deleting If you really want to know how many records are deleted when you are deleting
all rows, and are willing to suffer a speed penalty, you can use a all rows, and are willing to suffer a speed penalty, you can use a
@code{DELETE} statement of this form: @code{DELETE} statement of this form:
@example @example
mysql> DELETE FROM tbl_name WHERE 1>0; mysql> DELETE FROM table_name WHERE 1>0;
@end example @end example
Note that this is MUCH slower than @code{DELETE FROM tbl_name} with no Note that this is MUCH slower than @code{DELETE FROM table_name} with no
@code{WHERE} clause, because it deletes rows one at a time. @code{WHERE} clause, because it deletes rows one at a time.
If you specify the keyword @code{LOW_PRIORITY}, execution of the If you specify the keyword @code{LOW_PRIORITY}, execution of the
@code{DELETE} is delayed until no other clients are reading from the table. @code{DELETE} is delayed until no other clients are reading from the table.
Deleted records are maintained in a linked list and subsequent @code{INSERT} If you specify the word @code{QUICK} then the table handler will not
operations reuse old record positions. To reclaim unused space and reduce merge index leafs during delete, which may speed up certain kind of
file sizes, use the @code{OPTIMIZE TABLE} statement or the @code{myisamchk} deletes.
utility to reorganize tables. @code{OPTIMIZE TABLE} is easier, but
@code{myisamchk} is faster. In MyISAM tables deleted records are maintained in a linked list and
See @ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}} and @ref{Optimization}. subsequent @code{INSERT} operations reuse old record positions. To
reclaim unused space and reduce file sizes, use the @code{OPTIMIZE
TABLE} statement or the @code{myisamchk} utility to reorganize tables.
@code{OPTIMIZE TABLE} is easier, but @code{myisamchk} is faster. See
@ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}} and @ref{Optimization}.
The multi table delete format is supported starting from MySQL 4.0.0.
The idea is that only matching rows from the tables listed BEFORE the
@code{FROM} clause is deleted. The effect is that you can delete rows
from many tables at the same time and also have additional tables that
are used for searching.
The @code{.*} after the table names is there just to be compatible with
@code{Access}:
@example
DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
@end example
In the above case we delete matching rows just from tables @code{t1} and
@code{t2}.
@code{ORDER BY} and using multiple tables in the DELETE is supported in
MySQL 4.0.
If an @code{ORDER BY} clause is used, the rows will be deleted in that order.
This is really only useful in conjunction with @code{LIMIT}. For example:
@example
DELETE FROM somelog
WHERE user = 'jcole'
ORDER BY timestamp
LIMIT 1
@end example
This will delete the oldest entry (by @code{timestamp}) where the row matches
the @code{WHERE} clause.
The MySQL-specific @code{LIMIT rows} option to @code{DELETE} tells The MySQL-specific @code{LIMIT rows} option to @code{DELETE} tells
the server the maximum number of rows to be deleted before control is the server the maximum number of rows to be deleted before control is
...@@ -32852,16 +32974,19 @@ the @code{LIMIT} value. ...@@ -32852,16 +32974,19 @@ the @code{LIMIT} value.
TRUNCATE TABLE table_name TRUNCATE TABLE table_name
@end example @end example
Is in 3.23 and the same thing as @code{DELETE FROM table_name}. @xref{DELETE}. In 3.23 @code{TRUNCATE TABLE} is mapped to
The differences are: @code{COMMIT ; DELETE FROM table_name}. @xref{DELETE}.
The differences between @code{TRUNCATE TABLE} and @code{DELETE FROM ..}
are:
@itemize @bullet @itemize @bullet
@item @item
Implemented as a drop and re-create of the table, which makes this Truncates does a drop and re-create of the table, which is much faster
much faster when deleting many rows. than deleting rows one by one.
@item @item
Not transaction-safe; @code{TRUNCATE TABLE} will automatically end the current Not transaction-safe; You will get an error if you have an active
transaction as if @code{COMMIT} would have been called. transaction or an active table lock.
@item @item
Doesn't return the number of deleted rows. Doesn't return the number of deleted rows.
@item @item
...@@ -32872,7 +32997,6 @@ files have become corrupted. ...@@ -32872,7 +32997,6 @@ files have become corrupted.
@code{TRUNCATE} is an Oracle SQL extension. @code{TRUNCATE} is an Oracle SQL extension.
@node REPLACE, LOAD DATA, TRUNCATE, Data Manipulation @node REPLACE, LOAD DATA, TRUNCATE, Data Manipulation
@subsection @code{REPLACE} Syntax @subsection @code{REPLACE} Syntax
...@@ -34024,6 +34148,8 @@ alter_specification: ...@@ -34024,6 +34148,8 @@ alter_specification:
or DROP [COLUMN] col_name or DROP [COLUMN] col_name
or DROP PRIMARY KEY or DROP PRIMARY KEY
or DROP INDEX index_name or DROP INDEX index_name
or DISABLE KEYS
or ENABLE KEYS
or RENAME [TO] new_tbl_name or RENAME [TO] new_tbl_name
or ORDER BY col or ORDER BY col
or table_options or table_options
...@@ -34091,6 +34217,15 @@ options, MySQL simply renames the files that correspond to the table ...@@ -34091,6 +34217,15 @@ options, MySQL simply renames the files that correspond to the table
@code{tbl_name}. There is no need to create the temporary table. @code{tbl_name}. There is no need to create the temporary table.
@xref{RENAME TABLE,, @code{RENAME TABLE}}. @xref{RENAME TABLE,, @code{RENAME TABLE}}.
@item
Since @strong{MySQL 4.0} the above feature can be activated explicitly.
@code{ALTER TABLE ... DISABLE KEYS} makes MySQL to stop updating
non-unique indexes for @code{MyISAM} table.
@code{ALTER TABLE ... ENABLE KEYS} then should be used to recreate missing
indexes. As MySQL does it with special algorithm which is much
faster then inserting keys one by one, disabling keys could give a
considerable speedup on bulk inserts.
@item @item
@code{create_definition} clauses use the same syntax for @code{ADD} and @code{create_definition} clauses use the same syntax for @code{ADD} and
@code{CHANGE} as for @code{CREATE TABLE}. Note that this syntax includes @code{CHANGE} as for @code{CREATE TABLE}. Note that this syntax includes
...@@ -34190,6 +34325,15 @@ If you use @code{ALTER TABLE} on a @code{MyISAM} table, all non-unique ...@@ -34190,6 +34325,15 @@ If you use @code{ALTER TABLE} on a @code{MyISAM} table, all non-unique
indexes are created in a separate batch (like in @code{REPAIR}). indexes are created in a separate batch (like in @code{REPAIR}).
This should make @code{ALTER TABLE} much faster when you have many indexes. This should make @code{ALTER TABLE} much faster when you have many indexes.
@item
Since @strong{MySQL 4.0} this can be activated explicitly.
@code{ALTER TABLE ... DISABLE KEYS} makes MySQL to stop updating
non-unique indexes for @code{MyISAM} table.
@code{ALTER TABLE ... ENABLE KEYS} then should be used to recreate missing
indexes. As MySQL does it with special algorithm which is much
faster then inserting keys one by one, disabling keys could give a
considerable speedup on bulk inserts.
@item @item
@findex mysql_info() @findex mysql_info()
With the C API function @code{mysql_info()}, you can find out how many With the C API function @code{mysql_info()}, you can find out how many
...@@ -34486,7 +34630,7 @@ The @code{SHOW} statement provides similar information. ...@@ -34486,7 +34630,7 @@ The @code{SHOW} statement provides similar information.
@xref{SHOW, , @code{SHOW}}. @xref{SHOW, , @code{SHOW}}.
@node Transactional Commands, Fulltext Search, Basic User Commands, Reference @node Transactional Commands, HANDLER, Basic User Commands, Reference
@section MySQL Transactional and Locking Commands @section MySQL Transactional and Locking Commands
@menu @menu
...@@ -34719,8 +34863,48 @@ future transactions. ...@@ -34719,8 +34863,48 @@ future transactions.
You can set the default isolation level for @code{mysqld} with You can set the default isolation level for @code{mysqld} with
@code{--transaction-isolation=...}. @xref{Command-line options}. @code{--transaction-isolation=...}. @xref{Command-line options}.
@findex HANDLER
@node HANDLER, Fulltext Search, Transactional Commands, Reference
@section @code{HANDLER} Syntax
@example
HANDLER table OPEN [ AS alias ]
HANDLER table READ index @{ = | >= | <= | < @} (value1, value2, ... ) [ WHERE ... ] [LIMIT ... ]
HANDLER table READ index @{ FIRST | NEXT | PREV | LAST @} [ WHERE ... ] [LIMIT ... ]
HANDLER table READ @{ FIRST | NEXT @} [ WHERE ... ] [LIMIT ... ]
HANDLER table CLOSE
@end example
The @code{HANDLER} statement provides direct access to MySQL table
interface, bypassing SQL optimizer. Thus, it is faster then SELECT.
The first form of @code{HANDLER} statement opens a table, making
in accessible via the following @code{HANDLER ... READ} routines.
The second form fetches one (or, specified by @code{LIMIT} clause) row
where the index specified complies to the condition and @code{WHERE}
condition is met. If the index consists of several parts (spans over
several columns) the values are specified in comma-separated list,
providing values only for few first columns is possible.
The third form fetches one (or, specified by @code{LIMIT} clause) row
from the table in index order, matching @code{WHERE} condition.
The fourth form (without index specification) fetches one (or, specified
by @code{LIMIT} clause) row from the table in natural row order (as stored
in data file) matching @code{WHERE} condition. It is faster than
@code{HANDLER table READ index} when full table scan is desired.
The last form closes the table, opened with @code{HANDLER ... OPEN}.
@node Fulltext Search, , Transactional Commands, Reference @code{HANDLER} is somewhat low-level statement, for example it does not
provide consistency. That is @code{HANDLER ... OPEN} does @strong{not}
takes a snapshot of the table, and does @strong{not} locks the table. The
above means, that after @code{HANDLER ... OPEN} table data can be
modified (by this or other thread) and these modifications may appear only
partially in @code{HANDLER ... NEXT} or @code{HANDLER ... PREV} scans.
@node Fulltext Search, , HANDLER, Reference
@section MySQL Full-text Search @section MySQL Full-text Search
@cindex searching, full-text @cindex searching, full-text
...@@ -34980,8 +35164,6 @@ parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}). ...@@ -34980,8 +35164,6 @@ parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}).
@end itemize @end itemize
@node Table types, Clients, Reference, Top @node Table types, Clients, Reference, Top
@chapter MySQL Table Types @chapter MySQL Table Types
...@@ -37060,9 +37242,8 @@ InnoDB database. ...@@ -37060,9 +37242,8 @@ InnoDB database.
@strong{9.} @strong{9.}
Beware also of other big disk-bound operations. Beware also of other big disk-bound operations.
Use @code{DROP TABLE} Use @code{DROP TABLE} or @code{TRUNCATE} (from MySQL-4.0 up) to empty a
or @code{TRUNCATE} (from MySQL-4.0 up) to empty a table, not table, not @code{DELETE FROM yourtable}.
@code{DELETE FROM yourtable}.
@strong{10.} @strong{10.}
Use the multi-line @code{INSERT} to reduce Use the multi-line @code{INSERT} to reduce
...@@ -46554,8 +46735,9 @@ this means that the version has not yet been released! ...@@ -46554,8 +46735,9 @@ this means that the version has not yet been released!
@node News-4.0.x, News-3.23.x, News, News @node News-4.0.x, News-3.23.x, News, News
@appendixsec Changes in release 4.0.x (Development; Alpha) @appendixsec Changes in release 4.0.x (Development; Alpha)
We have now started to work on MySQL 4.0. We will update this We are now working actively on MySQL 4.0 and will only provide critical
section as we add new features, so that others can follow our development. bug fixes for MySQL 3.23. We will update this section as we add new
features, so that others can follow our development.
Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
...@@ -46571,32 +46753,51 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. ...@@ -46571,32 +46753,51 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@itemize @bullet @itemize @bullet
@item @item
Multi-table @code{DELETE}. @code{TRUNCATE TABLE} and @code{DELETE FROM table_name} are now separate
functions. One bonus is that @code{DELETE FROM table_name} now returns
the number of deleted rows.
@item
@code{DROP DATABASE} now executes a @code{DROP TABLE} on all tables in
the database, which fixes a problem with InnoDB tables.
@item
Changed @code{WEEK(#,0)} to match the calender in the USA.
@item
Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK}
@item
Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimization.
@item
Speed up all internal list handling.
@item
Added support for @code{UNION}.
@item
Allow ANSI SQL syntax @code{X'hexadecimal-number'}
@item
Tree-like cache to speed up bulk inserts and
@code{myisam_bulk_insert_tree_size} variable.
@item @item
Don't support old client protocols prior to MySQL 3.21 any more. Added @code{ALTER TABLE table_name DISABLE KEYS} and
@code{ALTER TABLE table_name ENABLE KEYS} commands.
@item @item
Don't include the old C API functions @code{mysql_drop_db}, @code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave.
@code{mysql_create_db} and @code{mysql_connect}, unless compiled with
@code{USE_OLD_FUNCTIONS}.
@item @item
Renamed @code{safe_mysqld} to @code{mysqld_safe}. Renamed @code{safe_mysqld} to @code{mysqld_safe}.
@item @item
Allow @code{IN} as a synonym for @code{FROM} in @code{SHOW} commands. Allow one to use @code{IN} instead of @code{FROM} in @code{SHOW} commands.
@item @item
@code{SHOW INDEXES} is now a synonym for @code{SHOW INDEX}. @code{SHOW INDEXES} is now a synonym for @code{SHOW INDEX}.
@item @item
Added support for symbolic links to @code{MyISAM} tables. Symlink handling is Added support for symbolic links to @code{MyISAM} tables. Symlink handling is
now enabled by default for Windows. now enabled by default for Windows.
@item @item
@code{LOAD DATA FROM MASTER} ``auto-magically'' sets up a slave. @code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave.
@item @item
A new @code{HANDLER} interface to @code{MyISAM} tables. A new @code{HANDLER} interface to @code{MyISAM} tables.
@item @item
@code{COUNT(DISTINCT)} is about 30% faster. @code{COUNT(DISTINCT)} is about 30% faster.
@item @item
@code{FULLTEXT} index creation now is much faster. Creating full text indexes are now much faster.
@item @item
Searching on packed (@code{CHAR}/@code{VARCHAR}) keys now is much faster. Searching on packed (@code{CHAR}/@code{VARCHAR}) keys are now much faster.
@item @item
Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This makes it Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This makes it
possible to know how many rows a query would have returned possible to know how many rows a query would have returned
...@@ -171,7 +171,7 @@ while test $# -gt 0; do ...@@ -171,7 +171,7 @@ while test $# -gt 0; do
;; ;;
--mysqld=*) --mysqld=*)
TMP=`$ECHO "$1" | $SED -e "s;--mysqld=;;"` TMP=`$ECHO "$1" | $SED -e "s;--mysqld=;;"`
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $TMP" EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT $TMP"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT $TMP" EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT $TMP"
;; ;;
--gcov ) --gcov )
......
...@@ -479,3 +479,5 @@ id name value uid ...@@ -479,3 +479,5 @@ id name value uid
1 one one value 101 1 one one value 101
3 three three value 103 3 three three value 103
6 two other value 102 6 two other value 102
a
a
...@@ -2,3 +2,4 @@ count(*) ...@@ -2,3 +2,4 @@ count(*)
0 0
count(*) count(*)
1 1
a b c1
...@@ -28,16 +28,16 @@ drop database foo; ...@@ -28,16 +28,16 @@ drop database foo;
# test drop/create database and FLUSH TABLES WITH READ LOCK # test drop/create database and FLUSH TABLES WITH READ LOCK
drop database if exists foo; drop database if exists foo;
flush tables with read lock; flush tables with read lock;
--error 1209 --error 1209,1218;
create database foo; create database foo;
unlock tables; unlock tables;
create database foo; create database foo;
show databases; show databases;
flush tables with read lock; flush tables with read lock;
--error 1208 --error 1208,1218;
drop database foo; drop database foo;
unlock tables; unlock tables;
drop database foo; drop database foo;
show databases; show databases;
--error 1008
drop database foo;
...@@ -512,3 +512,37 @@ replace into t1 (value,name,uid) values ('other value','two',102); ...@@ -512,3 +512,37 @@ replace into t1 (value,name,uid) values ('other value','two',102);
select * from t1; select * from t1;
drop table t1; drop table t1;
#
# Test DROP DATABASE
#
create database test_$1;
create table test_$1.t1 (a int not null) type= innodb;
insert into test_$1.t1 values(1);
create table test_$1.t2 (a int not null) type= myisam;
insert into test_$1.t2 values(1);
create table test_$1.t3 (a int not null) type= heap;
insert into test_$1.t3 values(1);
commit;
drop database test_$1;
--error 12
show tables from test_$1;
#
# Test truncate table
#
create table t1 (a int not null) type= innodb;
insert into t1 values(1),(2);
--error 1192
truncate table t1;
commit;
truncate table t1;
select * from t1;
insert into t1 values(1),(2);
delete from t1;
select * from t1;
commit;
drop table t1;
...@@ -2,10 +2,14 @@ ...@@ -2,10 +2,14 @@
# Test of truncate # Test of truncate
# #
create table t1 (a integer, b integer,c1 CHAR(10)); create table t1 (a integer, b integer,c1 CHAR(10));
insert into t1 (a) values (1),(2);
truncate table t1; truncate table t1;
select count(*) from t1; select count(*) from t1;
insert into t1 values(1,2,"test"); insert into t1 values(1,2,"test");
select count(*) from t1; select count(*) from t1;
delete from t1;
select * from t1;
drop table t1; drop table t1;
# The following should fail # The following should fail
!$1146 select count(*) from t1; --error 1146
select count(*) from t1;
...@@ -472,7 +472,7 @@ int main(int argc,char **argv) ...@@ -472,7 +472,7 @@ int main(int argc,char **argv)
int error; int error;
MY_INIT(argv[0]); MY_INIT(argv[0]);
start_value=6130115L; best_t1=3632784L; best_t2=86437L; best_type=3; /* mode=4229 add=2 type: 0 */ start_value=3579077L; best_t1=6681742L; best_t2=142815L; best_type=3; /* mode=5167 add=7 type: 0 */
if (get_options(argc,(char **) argv)) if (get_options(argc,(char **) argv))
exit(1); exit(1);
......
...@@ -92,7 +92,7 @@ bool innobase_flush_log_at_trx_commit, innobase_log_archive, ...@@ -92,7 +92,7 @@ bool innobase_flush_log_at_trx_commit, innobase_log_archive,
to specify any startup options. to specify any startup options.
*/ */
char *innobase_data_file_path= (char*) "ibdata:64M"; char *innobase_data_file_path= (char*) "ibdata1:64M";
/* The following counter is used to convey information to InnoDB /* The following counter is used to convey information to InnoDB
about server activity: in selects it is not sensible to call about server activity: in selects it is not sensible to call
...@@ -1915,7 +1915,7 @@ ha_innobase::change_active_index( ...@@ -1915,7 +1915,7 @@ ha_innobase::change_active_index(
build_template(prebuilt, user_thd, table, ROW_MYSQL_WHOLE_ROW); build_template(prebuilt, user_thd, table, ROW_MYSQL_WHOLE_ROW);
return(0); DBUG_RETURN(0);
} }
/************************************************************************** /**************************************************************************
......
...@@ -394,8 +394,8 @@ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list) ...@@ -394,8 +394,8 @@ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
error=0; error=0;
end: end:
start_waiting_global_read_lock(thd);
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
start_waiting_global_read_lock(thd);
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -532,6 +532,10 @@ bool lock_global_read_lock(THD *thd) ...@@ -532,6 +532,10 @@ bool lock_global_read_lock(THD *thd)
(void) pthread_mutex_lock(&LOCK_open); (void) pthread_mutex_lock(&LOCK_open);
const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open, const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
"Waiting to get readlock"); "Waiting to get readlock");
DBUG_PRINT("info",
("waiting_for: %d protect_against: %d",
waiting_for_read_lock, protect_against_global_read_lock));
waiting_for_read_lock++; waiting_for_read_lock++;
while (protect_against_global_read_lock && !thd->killed) while (protect_against_global_read_lock && !thd->killed)
pthread_cond_wait(&COND_refresh, &LOCK_open); pthread_cond_wait(&COND_refresh, &LOCK_open);
...@@ -573,6 +577,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) ...@@ -573,6 +577,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh)
if (thd->global_read_lock) // This thread had the read locks if (thd->global_read_lock) // This thread had the read locks
{ {
my_error(ER_CANT_UPDATE_WITH_READLOCK,MYF(0)); my_error(ER_CANT_UPDATE_WITH_READLOCK,MYF(0));
(void) pthread_mutex_unlock(&LOCK_open);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
old_message=thd->enter_cond(&COND_refresh, &LOCK_open, old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
...@@ -594,9 +599,11 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) ...@@ -594,9 +599,11 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh)
void start_waiting_global_read_lock(THD *thd) void start_waiting_global_read_lock(THD *thd)
{ {
bool tmp; bool tmp;
DBUG_ENTER("start_waiting_global_read_lock");
(void) pthread_mutex_lock(&LOCK_open); (void) pthread_mutex_lock(&LOCK_open);
tmp= (!--protect_against_global_read_lock && waiting_for_read_lock); tmp= (!--protect_against_global_read_lock && waiting_for_read_lock);
(void) pthread_mutex_unlock(&LOCK_open); (void) pthread_mutex_unlock(&LOCK_open);
if (tmp) if (tmp)
pthread_cond_broadcast(&COND_refresh); pthread_cond_broadcast(&COND_refresh);
DBUG_VOID_RETURN;
} }
...@@ -124,7 +124,7 @@ void my_MD5Init (my_MD5_CTX *context) /* context */ ...@@ -124,7 +124,7 @@ void my_MD5Init (my_MD5_CTX *context) /* context */
context. context.
*/ */
void MD5Update ( void my_MD5Update (
my_MD5_CTX *context, /* context */ my_MD5_CTX *context, /* context */
unsigned char *input, /* input block */ unsigned char *input, /* input block */
unsigned int inputLen) /* length of input block */ unsigned int inputLen) /* length of input block */
...@@ -165,9 +165,10 @@ unsigned int inputLen) /* length of input block */ ...@@ -165,9 +165,10 @@ unsigned int inputLen) /* length of input block */
/* MD5 finalization. Ends an MD5 message-digest operation, writing the /* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context. the message digest and zeroizing the context.
*/ */
void my_MD5Final ( void my_MD5Final (
unsigned char digest[16], /* message digest */ unsigned char digest[16], /* message digest */
MD5_CTX *context) /* context */ my_MD5_CTX *context) /* context */
{ {
unsigned char bits[8]; unsigned char bits[8];
unsigned int idx, padLen; unsigned int idx, padLen;
......
...@@ -691,7 +691,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) ...@@ -691,7 +691,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
if (thd->killed) if (thd->killed)
DBUG_RETURN(0); DBUG_RETURN(0);
TABLE* table; TABLE* table;
if(!(table = table_list->table)) if (!(table = table_list->table))
DBUG_RETURN(0); DBUG_RETURN(0);
char* db = thd->db ? thd->db : table_list->db; char* db = thd->db ? thd->db : table_list->db;
......
...@@ -40,33 +40,14 @@ int mysql_create_db(THD *thd, char *db, uint create_options) ...@@ -40,33 +40,14 @@ int mysql_create_db(THD *thd, char *db, uint create_options)
DBUG_ENTER("mysql_create_db"); DBUG_ENTER("mysql_create_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
VOID(pthread_mutex_lock(&LOCK_open));
// do not create database if another thread is holding read lock // do not create database if another thread is holding read lock
if (global_read_lock) if (wait_if_global_read_lock(thd,0))
{
if (thd->global_read_lock)
{
net_printf(&thd->net, ER_CREATE_DB_WITH_READ_LOCK);
VOID(pthread_mutex_unlock(&LOCK_open));
goto exit;
}
while (global_read_lock && ! thd->killed)
{
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
}
if (thd->killed)
{ {
net_printf(&thd->net, ER_SERVER_SHUTDOWN); error= -1;
VOID(pthread_mutex_unlock(&LOCK_open)); goto exit2;
goto exit;
} }
}
VOID(pthread_mutex_unlock(&LOCK_open));
/* Check directory */ /* Check directory */
(void)sprintf(path,"%s/%s", mysql_data_home, db); (void)sprintf(path,"%s/%s", mysql_data_home, db);
unpack_dirname(path,path); // Convert if not unix unpack_dirname(path,path); // Convert if not unix
...@@ -75,7 +56,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options) ...@@ -75,7 +56,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options)
my_dirend(dirp); my_dirend(dirp);
if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
{ {
if(thd) if (thd)
net_printf(&thd->net,ER_DB_CREATE_EXISTS,db); net_printf(&thd->net,ER_DB_CREATE_EXISTS,db);
error = 1; error = 1;
goto exit; goto exit;
...@@ -87,14 +68,14 @@ int mysql_create_db(THD *thd, char *db, uint create_options) ...@@ -87,14 +68,14 @@ int mysql_create_db(THD *thd, char *db, uint create_options)
strend(path)[-1]=0; // Remove last '/' from path strend(path)[-1]=0; // Remove last '/' from path
if (my_mkdir(path,0777,MYF(0)) < 0) if (my_mkdir(path,0777,MYF(0)) < 0)
{ {
if(thd) if (thd)
net_printf(&thd->net,ER_CANT_CREATE_DB,db,my_errno); net_printf(&thd->net,ER_CANT_CREATE_DB,db,my_errno);
error = 1; error = 1;
goto exit; goto exit;
} }
} }
if(thd) if (thd)
{ {
if (!thd->query) if (!thd->query)
{ {
...@@ -117,7 +98,10 @@ int mysql_create_db(THD *thd, char *db, uint create_options) ...@@ -117,7 +98,10 @@ int mysql_create_db(THD *thd, char *db, uint create_options)
} }
send_ok(&thd->net, result); send_ok(&thd->net, result);
} }
exit: exit:
start_waiting_global_read_lock(thd);
exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -126,6 +110,10 @@ const char *del_exts[]= {".frm", ".BAK", NullS}; ...@@ -126,6 +110,10 @@ const char *del_exts[]= {".frm", ".BAK", NullS};
static TYPELIB deletable_extentions= static TYPELIB deletable_extentions=
{array_elements(del_exts)-1,"del_exts", del_exts}; {array_elements(del_exts)-1,"del_exts", del_exts};
const char *known_exts[]=
{".ISM",".ISD",".ISM",".MRG",".MYI",".MYD", ".db", NullS};
static TYPELIB known_extentions=
{array_elements(del_exts)-1,"del_exts", known_exts};
/* /*
Drop all tables in a database. Drop all tables in a database.
...@@ -145,11 +133,13 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists) ...@@ -145,11 +133,13 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists)
DBUG_ENTER("mysql_rm_db"); DBUG_ENTER("mysql_rm_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
VOID(pthread_mutex_lock(&LOCK_open));
// do not drop database if another thread is holding read lock // do not drop database if another thread is holding read lock
if (wait_if_global_read_lock(thd,0)) if (wait_if_global_read_lock(thd,0))
goto exit; {
error= -1;
goto exit2;
}
(void) sprintf(path,"%s/%s",mysql_data_home,db); (void) sprintf(path,"%s/%s",mysql_data_home,db);
unpack_dirname(path,path); // Convert if not unix unpack_dirname(path,path); // Convert if not unix
...@@ -188,14 +178,14 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists) ...@@ -188,14 +178,14 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists)
thd->query = 0; // just in case thd->query = 0; // just in case
thd->query_length = 0; thd->query_length = 0;
} }
send_ok(&thd->net,(ulong) deleted); send_ok(&thd->net,(ulong) deleted);
error = 0;
} }
exit: exit:
VOID(pthread_mutex_unlock(&LOCK_open));
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -246,6 +236,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, ...@@ -246,6 +236,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
} }
if (find_type(fn_ext(file->name),&deletable_extentions,1+2) <= 0) if (find_type(fn_ext(file->name),&deletable_extentions,1+2) <= 0)
{ {
if (find_type(fn_ext(file->name),&known_extentions,1+2) <= 0)
found_other_files++; found_other_files++;
continue; continue;
} }
......
...@@ -488,6 +488,7 @@ bool multi_delete::send_eof() ...@@ -488,6 +488,7 @@ bool multi_delete::send_eof()
normally can't safely do this. normally can't safely do this.
- We don't want an ok to be sent to the end user. - We don't want an ok to be sent to the end user.
- We don't want to log the truncate command - We don't want to log the truncate command
- If we want to have a name lock on the table on exit without errors.
*/ */
int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
...@@ -499,7 +500,7 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -499,7 +500,7 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
DBUG_ENTER("mysql_truncate"); DBUG_ENTER("mysql_truncate");
/* If it is a temporary table, close and regenerate it */ /* If it is a temporary table, close and regenerate it */
if ((table_ptr=find_temporary_table(thd,table_list->db, if (!dont_send_ok && (table_ptr=find_temporary_table(thd,table_list->db,
table_list->real_name))) table_list->real_name)))
{ {
TABLE *table= *table_ptr; TABLE *table= *table_ptr;
...@@ -536,7 +537,7 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -536,7 +537,7 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
{ {
/* Probably InnoDB table */ /* Probably InnoDB table */
DBUG_RETURN(mysql_delete(thd,table_list, (COND*) 0, (ORDER*) 0, DBUG_RETURN(mysql_delete(thd,table_list, (COND*) 0, (ORDER*) 0,
(ha_rows) 0, TL_WRITE, 0)); HA_POS_ERROR, TL_WRITE, 0));
} }
if (lock_and_wait_for_table_name(thd, table_list)) if (lock_and_wait_for_table_name(thd, table_list))
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -545,9 +546,10 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -545,9 +546,10 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
bzero((char*) &create_info,sizeof(create_info)); bzero((char*) &create_info,sizeof(create_info));
*fn_ext(path)=0; // Remove the .frm extension *fn_ext(path)=0; // Remove the .frm extension
error= ha_create_table(path,&create_info,1) ? -1 : 0; error= ha_create_table(path,&create_info,1) ? -1 : 0;
VOID(pthread_mutex_unlock(&LOCK_open));
if (!error && !dont_send_ok) if (!dont_send_ok)
{
if (!error)
{ {
mysql_update_log.write(thd,thd->query,thd->query_length); mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
...@@ -558,5 +560,8 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -558,5 +560,8 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
send_ok(&thd->net); // This should return record count send_ok(&thd->net); // This should return record count
} }
unlock_table_name(thd, table_list); unlock_table_name(thd, table_list);
}
else if (error)
unlock_table_name(thd, table_list);
DBUG_RETURN(error ? -1 : 0); DBUG_RETURN(error ? -1 : 0);
} }
...@@ -890,7 +890,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -890,7 +890,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
error=TRUE; // End server error=TRUE; // End server
break; break;
case COM_CREATE_DB: case COM_CREATE_DB: // QQ: To be removed
{ {
char *db=thd->strdup(packet); char *db=thd->strdup(packet);
// null test to handle EOM // null test to handle EOM
...@@ -905,7 +905,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -905,7 +905,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
mysql_create_db(thd,db,0); mysql_create_db(thd,db,0);
break; break;
} }
case COM_DROP_DB: case COM_DROP_DB: // QQ: To be removed
{ {
char *db=thd->strdup(packet); char *db=thd->strdup(packet);
// null test to handle EOM // null test to handle EOM
...@@ -914,8 +914,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -914,8 +914,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
break; break;
} }
if (check_access(thd,DROP_ACL,db,0,1) || end_active_trans(thd)) if (thd->locked_tables || thd->active_transaction())
{
send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
break; break;
}
mysql_log.write(thd,command,db); mysql_log.write(thd,command,db);
mysql_rm_db(thd,db,0); mysql_rm_db(thd,db,0);
break; break;
...@@ -1632,7 +1635,7 @@ mysql_execute_command(void) ...@@ -1632,7 +1635,7 @@ mysql_execute_command(void)
*/ */
if (thd->locked_tables || thd->active_transaction()) if (thd->locked_tables || thd->active_transaction())
{ {
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0)); send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS);
goto error; goto error;
} }
res=mysql_truncate(thd,tables); res=mysql_truncate(thd,tables);
...@@ -1963,7 +1966,7 @@ mysql_execute_command(void) ...@@ -1963,7 +1966,7 @@ mysql_execute_command(void)
} }
if (check_access(thd,CREATE_ACL,lex->name,0,1)) if (check_access(thd,CREATE_ACL,lex->name,0,1))
break; break;
mysql_create_db(thd,lex->name,lex->create_info.options); res=mysql_create_db(thd,lex->name,lex->create_info.options);
break; break;
} }
case SQLCOM_DROP_DB: case SQLCOM_DROP_DB:
...@@ -1977,10 +1980,10 @@ mysql_execute_command(void) ...@@ -1977,10 +1980,10 @@ mysql_execute_command(void)
break; break;
if (thd->locked_tables || thd->active_transaction()) if (thd->locked_tables || thd->active_transaction())
{ {
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0)); send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
goto error; goto error;
} }
mysql_rm_db(thd,lex->name,lex->drop_if_exists); res=mysql_rm_db(thd,lex->name,lex->drop_if_exists);
break; break;
} }
case SQLCOM_CREATE_FUNCTION: case SQLCOM_CREATE_FUNCTION:
...@@ -2057,7 +2060,7 @@ mysql_execute_command(void) ...@@ -2057,7 +2060,7 @@ mysql_execute_command(void)
{ {
if (lex->columns.elements) if (lex->columns.elements)
{ {
net_printf(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); send_error(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
res=1; res=1;
} }
else else
...@@ -2305,7 +2308,7 @@ static bool check_merge_table_access(THD *thd, char *db, ...@@ -2305,7 +2308,7 @@ static bool check_merge_table_access(THD *thd, char *db,
{ {
if (!tmp->db || !tmp->db[0]) if (!tmp->db || !tmp->db[0])
tmp->db=db; tmp->db=db;
else if (!strcmp(tmp->db,db)) else if (strcmp(tmp->db,db))
{ {
send_error(&thd->net,ER_UNION_TABLES_IN_DIFFERENT_DIR); send_error(&thd->net,ER_UNION_TABLES_IN_DIFFERENT_DIR);
return 1; return 1;
......
...@@ -864,7 +864,6 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) ...@@ -864,7 +864,6 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
DBUG_RETURN(send_check_errmsg(thd, table, "restore", DBUG_RETURN(send_check_errmsg(thd, table, "restore",
"Failed generating table from .frm file")); "Failed generating table from .frm file"));
} }
/* truncate has released name lock */
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment