summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2002-07-23 18:31:22 +0300
committerunknown <monty@mashka.mysql.fi>2002-07-23 18:31:22 +0300
commita8caad316a89d6eeb8c22e70bc7a5fd4cf6ce904 (patch)
tree2e458857fc65791ee553b4cde0e28ef9459050a5
parent6b3e98d505297e6cbd0cbd22d4f46eacb091d924 (diff)
downloadmariadb-git-a8caad316a89d6eeb8c22e70bc7a5fd4cf6ce904.tar.gz
New SET syntax & system variables.
Made a some new buffers thread specific and changeable. Resize of key_buffer. AUTO_COMMIT -> AUTOCOMMIT Fixed mutex bug in DROP DATABASE Fixed bug when using auto_increment as second part of a key where first part could include NULL. Split handler->extra() to extra() and extra_opt() to be able to support thread specific buffers. Don't write message to error log when slave reconnects becasue of timeout. Fixed possible update problem when using DELETE/UPDATE on small tables (In some cases we used index even if table scanning would be better) A lot of minior code cleanups BitKeeper/deleted/.del-net.c~ef21d6402bb882f9: Delete: libmysql/net.c BitKeeper/etc/ignore: added libmysql/net.c Docs/manual.texi: New SET syntax & system variables. client/client_priv.h: moved order of include files client/mysql.cc: Removed compiler warning client/mysqladmin.c: Use new SHOW GLOBAL syntax (if server supports it) configure.in: version change include/Makefile.am: indentation cleanup include/my_getopt.h: Made some helper functions global include/my_sys.h: Removed not used code include/myisam.h: Added extra argument to ..._extra() include/myisammrg.h: Added extra argument to ..._extra() include/mysql_com.h: changed NET to be able to support changeable system variables include/mysql_embed.h: Added MYSQL_SERVER_SUFFIX include/mysql_version.h.in: Added check of multiple including (needed for embedded library) include/mysqld_error.h: New error messages innobase/dict/dict0dict.c: Remove compiler warnings innobase/include/ut0mem.h: Remove compiler warnings innobase/include/ut0mem.ic: Remove compiler warnings isam/isamchk.c: new init_key_cache() arguments isam/isamlog.c: new init_key_cache() arguments isam/test2.c: new init_key_cache() arguments isam/test3.c: new init_key_cache() arguments libmysql/Makefile.am: Removed net.c (Automaticly make it from net_serv.cc) libmysql/Makefile.shared: Removed net.c (Automaticly make it from net_serv.cc) libmysql/libmysql.c: Changeable system variables libmysqld/Makefile.am: Added set_var.cc file libmysqld/embedded_priv.h: Changed order of include fiels libmysqld/lib_sql.cc: merge with mysqld.cc (for changeable variables) libmysqld/libmysqld.c: New changeable system variables myisam/mi_check.c: Added extra argument to ..._extra() myisam/mi_extra.c: Added extra argument to ..._extra() myisam/mi_open.c: Removed not used variable myisam/mi_test1.c: Changed call to init_key_cache myisam/mi_test2.c: Added extra argument to ..._extra() myisam/mi_test3.c: Added extra argument to ..._extra() myisam/mi_write.c: Add cache size argument to bulk-insert-init myisam/myisamchk.c: Use new key cache myisam/myisamdef.h: new mi_init_bulk_insert() arguments myisam/myisamlog.c: Added extra argument to ..._extra() myisam/myisampack.c: Added extra argument to ..._extra() myisammrg/myrg_extra.c: Added extra argument to ..._extra() myisammrg/myrg_rrnd.c: Added extra argument to ..._extra() mysql-test/r/insert_select.result: New changeable system variables mysql-test/r/key.result: Test of bug in auto_increment mysql-test/r/query_cache.result: New changeable system variables mysql-test/r/rpl000001.result: New changeable system variables mysql-test/r/rpl000016.result: New changeable system variables mysql-test/r/union.result: New changeable system variables mysql-test/r/user_var.result: New changeable system variables mysql-test/r/variables.result: New changeable system variables mysql-test/t/key.test: Test of bug in auto_increment mysql-test/t/query_cache.test: New changeable system variables mysql-test/t/rpl000001.test: New changeable system variables mysql-test/t/rpl000009.test: New changeable system variables mysql-test/t/rpl000016.test: New changeable system variables mysql-test/t/rpl_compat.test: New changeable system variables mysql-test/t/union.test: New changeable system variables mysql-test/t/user_var.test: New changeable system variables mysql-test/t/variables.test: New changeable system variables mysys/default.c: Bigger default memory allocation mysys/mf_iocache.c: Removed compiler warning mysys/mf_keycache.c: Made key cache resizable on the fly Removed not needed extra argument to init_key_cache() mysys/my_getopt.c: Made some helper functions global sql/Makefile.am: Aded set_var.cc sql/convert.cc: Comment cleanup sql/field.cc: new changeable system variables sql/filesort.cc: new changeable system variables sql/ha_berkeley.cc: AUTO_COMMIT -> AUTOCOMMIT sql/ha_innodb.cc: new changeable system variables sql/ha_myisam.cc: Added extra argument to ..._extra() sql/ha_myisam.h: Added extra argument to ..._extra() sql/ha_myisammrg.cc: Added extra argument to ..._extra() sql/ha_myisammrg.h: Added extra argument to ..._extra() sql/handler.cc: Added extra argument to ..._extra() Added resize of key cache Change ha_table_typelib for use with new system variables sql/handler.h: Added extra argument to ..._extra() sql/item.cc: new changeable system variables sql/item.h: Added better support of Item_uint sql/item_func.cc: Added support for SET @@[global | session] system_variable sql/item_strfunc.cc: new changeable system variables sql/key.cc: Fixed bug in auto_increment on second part keys sql/lex.h: Removed not needed keywords sql/log.cc: new changeable system variables sql/log_event.cc: new changeable system variables sql/log_event.h: Removed not needed var reference sql/mini_client.cc: new changeable system variables code cleanup sql/mini_client.h: Indentation cleanup sql/mysql_priv.h: Changed order of include files & variables to make file more readable sql/mysqld.cc: Changed order of variables to make file more readable. Support for changeable variables Rename of system variables Moved init_vars to set_var.cc Changed output of --help sql/net_pkg.cc: Added my_net_local_init() to make it possible to set different defaults for network connection depending if you are a client, embedded library or server. sql/net_serv.cc: new changeable system variables To support this, some global variables had to be move to the NET structure. sql/records.cc: new changeable system variables use extra_opt() sql/repl_failsafe.cc: new changeable system variables minior code cleanups sql/repl_failsafe.h: removed not needed external var reference sql/share/czech/errmsg.txt: new changeable system variables sql/share/danish/errmsg.txt: new changeable system variables sql/share/dutch/errmsg.txt: new changeable system variables sql/share/english/errmsg.txt: new changeable system variables sql/share/estonian/errmsg.txt: new changeable system variables sql/share/french/errmsg.txt: new changeable system variables sql/share/german/errmsg.txt: new changeable system variables sql/share/greek/errmsg.txt: new changeable system variables sql/share/hungarian/errmsg.txt: new changeable system variables sql/share/italian/errmsg.txt: new changeable system variables sql/share/japanese/errmsg.txt: new changeable system variables sql/share/korean/errmsg.txt: new changeable system variables sql/share/norwegian-ny/errmsg.txt: new changeable system variables sql/share/norwegian/errmsg.txt: new changeable system variables sql/share/polish/errmsg.txt: new changeable system variables sql/share/portuguese/errmsg.txt: new changeable system variables sql/share/romanian/errmsg.txt: new changeable system variables sql/share/russian/errmsg.txt: new changeable system variables sql/share/slovak/errmsg.txt: new changeable system variables sql/share/spanish/errmsg.txt: new changeable system variables sql/share/swedish/errmsg.txt: new changeable system variables sql/share/ukrainian/errmsg.txt: new changeable system variables sql/slave.cc: new changeable system variables Added some suppression of error messages Initialize current_thd for all slave threads. sql/sql_acl.cc: Added checking of arguments for SET PASSWORD (for new SET defintion) sql/sql_acl.h: new prototypes sql/sql_base.cc: new changeable system variables sql/sql_cache.cc: new changeable system variables sql/sql_cache.h: Renamed some arguments to make code more readable sql/sql_class.cc: new changeable system variables sql/sql_class.h: New changeable system variables Code cleanup sql/sql_db.cc: Fixed bug in DROP DATABASE sql/sql_delete.cc: Usage of wrong define in test (possible speed problem) sql/sql_insert.cc: use extra_opt() Code cleanup sql/sql_lex.cc: Added support for SET @@[global | session] system_variable sql/sql_lex.h: Added support for SET @@[global | session] system_variable sql/sql_load.cc: Cleanup for embedded library Use extra_opt() sql/sql_parse.cc: Cleanup for embedded library New changeable system variables sql/sql_repl.cc: new changeable system variables sql/sql_repl.h: Fixed variable definitions sql/sql_select.cc: new changeable system variables sql/sql_show.cc: New changeable system variables sql/sql_table.cc: Fixed bug in DROP DATABASE sql/sql_union.cc: New changeable system variables sql/sql_update.cc: Usage of wrong define in test (possible speed problem) sql/sql_yacc.yy: New changeable system variables sql/structs.h: Added typedef for SHOW_VAR sql/table.cc: Fixed bug in auto_increment on second part keys sql/uniques.cc: Comment fix sql/unireg.h: A
-rw-r--r--.bzrignore1
-rw-r--r--Docs/manual.texi745
-rw-r--r--client/client_priv.h2
-rw-r--r--client/mysql.cc10
-rw-r--r--client/mysqladmin.c4
-rw-r--r--configure.in2
-rw-r--r--include/Makefile.am4
-rw-r--r--include/my_getopt.h2
-rw-r--r--include/my_sys.h19
-rw-r--r--include/myisam.h8
-rw-r--r--include/myisammrg.h10
-rw-r--r--include/mysql_com.h7
-rw-r--r--include/mysql_embed.h4
-rw-r--r--include/mysql_version.h.in7
-rw-r--r--include/mysqld_error.h8
-rw-r--r--innobase/dict/dict0dict.c6
-rw-r--r--innobase/include/ut0mem.h2
-rw-r--r--innobase/include/ut0mem.ic2
-rw-r--r--isam/isamchk.c6
-rw-r--r--isam/isamlog.c2
-rw-r--r--isam/test2.c2
-rw-r--r--isam/test3.c2
-rw-r--r--libmysql/Makefile.am12
-rw-r--r--libmysql/Makefile.shared9
-rw-r--r--libmysql/libmysql.c16
-rw-r--r--libmysql/net.c826
-rw-r--r--libmysqld/Makefile.am6
-rw-r--r--libmysqld/embedded_priv.h3
-rw-r--r--libmysqld/lib_sql.cc140
-rw-r--r--libmysqld/libmysqld.c3
-rw-r--r--myisam/mi_check.c12
-rw-r--r--myisam/mi_extra.c41
-rw-r--r--myisam/mi_open.c2
-rw-r--r--myisam/mi_test1.c2
-rw-r--r--myisam/mi_test2.c22
-rw-r--r--myisam/mi_test3.c10
-rw-r--r--myisam/mi_write.c9
-rw-r--r--myisam/myisamchk.c4
-rw-r--r--myisam/myisamdef.h2
-rw-r--r--myisam/myisamlog.c4
-rw-r--r--myisam/myisampack.c12
-rw-r--r--myisammrg/myrg_extra.c12
-rw-r--r--myisammrg/myrg_rrnd.c8
-rw-r--r--mysql-test/r/insert_select.result2
-rw-r--r--mysql-test/r/key.result31
-rw-r--r--mysql-test/r/query_cache.result6
-rw-r--r--mysql-test/r/rpl000001.result2
-rw-r--r--mysql-test/r/rpl000016.result2
-rw-r--r--mysql-test/r/union.result4
-rw-r--r--mysql-test/r/user_var.result2
-rw-r--r--mysql-test/r/variables.result274
-rw-r--r--mysql-test/t/key.test20
-rw-r--r--mysql-test/t/query_cache.test6
-rw-r--r--mysql-test/t/rpl000001.test2
-rw-r--r--mysql-test/t/rpl000009.test18
-rw-r--r--mysql-test/t/rpl000016.test2
-rw-r--r--mysql-test/t/rpl_compat.test2
-rw-r--r--mysql-test/t/union.test2
-rw-r--r--mysql-test/t/user_var.test2
-rw-r--r--mysql-test/t/variables-master.opt1
-rw-r--r--mysql-test/t/variables.test197
-rw-r--r--mysys/default.c2
-rw-r--r--mysys/mf_iocache.c2
-rw-r--r--mysys/mf_keycache.c142
-rw-r--r--mysys/my_getopt.c48
-rw-r--r--sql/Makefile.am2
-rw-r--r--sql/convert.cc2
-rw-r--r--sql/field.cc2
-rw-r--r--sql/filesort.cc7
-rw-r--r--sql/ha_berkeley.cc2
-rw-r--r--sql/ha_innodb.cc4
-rw-r--r--sql/ha_myisam.cc39
-rw-r--r--sql/ha_myisam.h1
-rw-r--r--sql/ha_myisammrg.cc23
-rw-r--r--sql/ha_myisammrg.h1
-rw-r--r--sql/handler.cc28
-rw-r--r--sql/handler.h12
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item.h3
-rw-r--r--sql/item_func.cc30
-rw-r--r--sql/item_strfunc.cc25
-rw-r--r--sql/key.cc2
-rw-r--r--sql/lex.h22
-rw-r--r--sql/log.cc4
-rw-r--r--sql/log_event.cc10
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/mini_client.cc27
-rw-r--r--sql/mini_client.h19
-rw-r--r--sql/mysql_priv.h136
-rw-r--r--sql/mysqld.cc529
-rw-r--r--sql/net_pkg.cc16
-rw-r--r--sql/net_serv.cc54
-rw-r--r--sql/records.cc7
-rw-r--r--sql/repl_failsafe.cc16
-rw-r--r--sql/repl_failsafe.h1
-rw-r--r--sql/set_var.cc1293
-rw-r--r--sql/set_var.h419
-rw-r--r--sql/share/czech/errmsg.txt6
-rw-r--r--sql/share/danish/errmsg.txt6
-rw-r--r--sql/share/dutch/errmsg.txt6
-rw-r--r--sql/share/english/errmsg.txt6
-rw-r--r--sql/share/estonian/errmsg.txt6
-rw-r--r--sql/share/french/errmsg.txt6
-rw-r--r--sql/share/german/errmsg.txt6
-rw-r--r--sql/share/greek/errmsg.txt6
-rw-r--r--sql/share/hungarian/errmsg.txt6
-rw-r--r--sql/share/italian/errmsg.txt6
-rw-r--r--sql/share/japanese/errmsg.txt6
-rw-r--r--sql/share/korean/errmsg.txt6
-rw-r--r--sql/share/norwegian-ny/errmsg.txt6
-rw-r--r--sql/share/norwegian/errmsg.txt6
-rw-r--r--sql/share/polish/errmsg.txt6
-rw-r--r--sql/share/portuguese/errmsg.txt6
-rw-r--r--sql/share/romanian/errmsg.txt6
-rw-r--r--sql/share/russian/errmsg.txt6
-rw-r--r--sql/share/slovak/errmsg.txt6
-rw-r--r--sql/share/spanish/errmsg.txt6
-rw-r--r--sql/share/swedish/errmsg.txt6
-rw-r--r--sql/share/ukrainian/errmsg.txt6
-rw-r--r--sql/slave.cc140
-rw-r--r--sql/sql_acl.cc58
-rw-r--r--sql/sql_acl.h1
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_cache.cc46
-rw-r--r--sql/sql_cache.h13
-rw-r--r--sql/sql_class.cc21
-rw-r--r--sql/sql_class.h93
-rw-r--r--sql/sql_db.cc3
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_insert.cc10
-rw-r--r--sql/sql_lex.cc37
-rw-r--r--sql/sql_lex.h27
-rw-r--r--sql/sql_load.cc26
-rw-r--r--sql/sql_parse.cc83
-rw-r--r--sql/sql_repl.cc18
-rw-r--r--sql/sql_repl.h3
-rw-r--r--sql/sql_select.cc10
-rw-r--r--sql/sql_show.cc89
-rw-r--r--sql/sql_table.cc32
-rw-r--r--sql/sql_union.cc7
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sql_yacc.yy368
-rw-r--r--sql/structs.h41
-rw-r--r--sql/table.cc26
-rw-r--r--sql/uniques.cc2
-rw-r--r--sql/unireg.h1
146 files changed, 4339 insertions, 2473 deletions
diff --git a/.bzrignore b/.bzrignore
index 9f97c9ca9bf..4c1775db904 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -480,3 +480,4 @@ mit-pthreads/machdep.c
mit-pthreads/pg++
mit-pthreads/pgcc
scripts/mysql_tableinfo
+libmysql/net.c
diff --git a/Docs/manual.texi b/Docs/manual.texi
index 83999b6daae..2a8909f0e6a 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -1709,7 +1709,7 @@ domain names is not allowed without written permission from @code{MySQL AB}.
Dateline: 16 October 2001, Uppsala, Sweden
Long promised by @code{MySQL AB} and long awaited by our users,
-MySQL Server 4.0 is now available in alpha version for download from
+MySQL Server 4.0 is now available in beta version for download from
@uref{http://www.mysql.com/} and our mirrors.
Main new features of MySQL Server 4.0 are geared toward our existing
@@ -2758,7 +2758,7 @@ Strings may be enclosed by either @samp{"} or @samp{'}, not just by @samp{'}.
Use of the escape @samp{\} character.
@item
-The @code{SET OPTION} statement. @xref{SET OPTION, , @code{SET OPTION}}.
+The @code{SET} statement. @xref{SET OPTION, , @code{SET}}.
@item
You don't need to name all selected columns in the @code{GROUP BY} part.
@@ -3688,26 +3688,7 @@ this without sacrificing the speed or compromising the code.
@node TODO MySQL 4.0, TODO MySQL 4.1, TODO, TODO
@subsection Things That Should be in 4.0
-We are now in the final stages of the development of the MySQL Server
-4.0. server. The target is to quickly implement the rest of the
-following features and then shift development to MySQL Server
-4.1. @xref{MySQL 4.0 In A Nutshell}.
-
-The news section for 4.0 includes a list of the features we have already
-implemented in the 4.0 tree. @xref{News-4.0.x}.
-
-This section lists features not yet implemented in the current version
-of MySQL Server 4.0, which will, however, be implemented in later versions
-of MySQL 4.0. This being very volatile information, please consider this
-list valid only if you are reading it from the MySQL web site
-(@uref{http://www.mysql.com/}).
-
-@itemize @bullet
-@item
-Allow users to change startup options without taking down the server.
-@item
-@code{SET SQL_DEFAULT_TABLE_TYPE=[MyISAM | INNODB | BDB | HEAP]}.
-@end itemize
+All done. We now only do bug fixes MySQL 4.0.
@node TODO MySQL 4.1, TODO future, TODO MySQL 4.0, TODO
@subsection Things That Should be in 4.1
@@ -6920,8 +6901,8 @@ shell> ./configure --with-charset=CHARSET
@xref{Character sets}.
If you want to convert characters between the server and the client,
-you should take a look at the @code{SET OPTION CHARACTER SET} command.
-@xref{SET OPTION, , @code{SET OPTION}}.
+you should take a look at the @code{SET CHARACTER SET} command.
+@xref{SET OPTION, , @code{SET}}.
@cindex @code{myisamchk}
@strong{Warning}: If you change character sets after having created any
@@ -8165,6 +8146,36 @@ should check if you need some of the new grants that you didn't need
before. In particular, you will need @code{REPLICATION SLAVE}
(instead of @code{FILE}) for new slaves.
@item
+The startup parameters @code{myisam_max_extra_sort_file_size} and
+@code{myisam_max_extra_sort_file_size} are now given in bytes
+(was megabytes before 4.0.3).
+@item
+The following startup variables/options have been renamed:
+@multitable @columnfractions .50 .50
+@item @strong{From} @tab @strong{to}.
+@item @code{myisam_bulk_insert_tree_size} @tab @code{bulk_insert_buffer_size}
+@item @code{query_cache_startup_type} @tab @code{query_cache_type}
+@item @code{record_buffer} @tab @code{read_buffer_size}
+@item @code{record_rnd_buffer} @tab @code{read_rnd_buffer_size}
+@item @code{sort_buffer} @tab @code{sort_buffer_size}
+@item @code{warnings} @tab @code{log-warnings}
+@end multitable
+
+The startup options @code{record_buffer}, @code{sort_buffer} and @code{warnings} will still work in MySQL 4.0 but are deprecated.
+@item
+The following SQL variables have changed name.
+@multitable @columnfractions .50 .50
+@item @strong{From} @tab @strong{to}.
+@item @code{SQL_BIG_TABLES} @tab @code{BIG_TABLES}
+@item @code{SQL_LOW_PRIORITY_UPDATES} @tab @code{LOW_PRIORITY_UPDATES}
+@item @code{SQL_MAX_JOIN_SIZE} @tab @code{MAX_JOIN_SIZE}
+@item @code{SQL_QUERY_CACHE_TYPE} @tab @code{QUERY_CACHE_TYPE}
+@end multitable
+The old names still work in MySQL 4.0 but are depricated.
+@item
+You have to use @code{SET GLOBAL SQL_SLAVE_SKIP_COUNTER=#} instead of
+@code{SET SQL_SLAVE_SKIP_COUNTER=#}.
+@item
@code{DOUBLE} and @code{FLOAT} columns are now honoring the
@code{UNSIGNED} flag on storage (before, @code{UNSIGNED} was ignored for
these columns).
@@ -9395,7 +9406,7 @@ C:\> mysqladmin --user=root --password=your_password shutdown
If you are using the old shareware version of MySQL Version
3.21 under Windows, the above command will fail with an error:
-@code{parse error near 'SET OPTION password'}. The solution for
+@code{parse error near 'SET password'}. The solution for
this is to download and upgrade to the latest MySQL version,
which is now freely available.
@@ -14235,7 +14246,7 @@ Table-modifying operations (@code{INSERT}/@code{DELETE}/@code{UPDATE})
will have lower priority than selects. It can also be done via
@code{@{INSERT | REPLACE | UPDATE | DELETE@} LOW_PRIORITY ...} to lower
the priority of only one query, or by
-@code{SET OPTION SQL_LOW_PRIORITY_UPDATES=1} to change the priority in one
+@code{SET LOW_PRIORITY_UPDATES=1} to change the priority in one
thread. @xref{Table locking}.
@item --memlock
@@ -14296,6 +14307,18 @@ description for all variables in the @code{SHOW VARIABLES} section in this
manual. @xref{SHOW VARIABLES}. The tuning server parameters section includes
information of how to optimise these. @xref{Server parameters}.
+In MySQL 4.0.2 one can set a variable directly with
+@code{--variable-name=option} and @code{set-variable} is not anymore needed
+in option files.
+
+If you want to restrict the maximum value a startup option can be set to
+with @code{SET}, you can define this by using the
+@code{--maximum-variable-name} command line option. @xref{SET OPTION}.
+
+Note that when setting a variable to a value, MySQL may automaticly
+correct it to stay within a given range and also adjusts the value a
+little to fix for the used algorithm.
+
@item --safe-mode
Skip some optimise stages. Implies @code{--skip-delay-key-write}.
@@ -14408,11 +14431,13 @@ This option is @strong{mandatory} when starting @code{mysqld} as root.
@item -V, --version
Output version information and exit.
-@item -W, --warnings
+@item -W, --log-warnings (Was --warnings)
Print out warnings like @code{Aborted connection...} to the @file{.err} file.
@xref{Communication errors}.
@end table
+One can change most values for a running server with the
+@code{SET} command. @xref{SET OPTION}.
@node Option files, Installing many servers, Command-line options, Configuring MySQL
@subsection @file{my.cnf} Option Files
@@ -16641,7 +16666,7 @@ function @code{PASSWORD()} or the C API function
@code{IDENTIFIED BY} clause, the user has no password. This is insecure.
Passwords can also be set with the @code{SET PASSWORD} command.
-@xref{SET OPTION, , @code{SET OPTION}}.
+@xref{SET OPTION, , @code{SET}}.
If you grant privileges for a database, an entry in the @code{mysql.db}
table is created if needed. When all privileges for the database have been
@@ -19609,7 +19634,7 @@ instead of disk based.
@subsubsection @code{SHOW VARIABLES}
@example
-SHOW VARIABLES [LIKE wild]
+SHOW [GLOBAL | SESSION] VARIABLES [LIKE wild]
@end example
@code{SHOW VARIABLES} shows the values of some MySQL system
@@ -19618,6 +19643,15 @@ variables} command. If the default values are unsuitable, you can set most
of these variables using command-line options when @code{mysqld} starts up.
@xref{Command-line options}.
+The options @code{GLOBAL} and @code{SESSION} are new in MySQL 4.0.3.
+With @code{GLOBAL} you will get the variables that will be used for new
+connections to MySQL. With @code{SESSION} you will get the values that
+are in effect for the current connection. If you are not using either
+option, @code{SESSION} is used.
+
+You can change most options with the @code{SET} command.
+@xref{SET OPTION, , @code{SET}}.
+
The output resembles that shown here, though the format and numbers may
differ somewhat:
@@ -19636,6 +19670,7 @@ differ somewhat:
| bdb_shared_data | OFF |
| bdb_tmpdir | /tmp/ |
| binlog_cache_size | 32768 |
+| bulk_insert_buffer_size | 8388608 |
| concurrent_insert | ON |
| connect_timeout | 5 |
| datadir | /my/monty/data/ |
@@ -19676,7 +19711,6 @@ differ somewhat:
| max_sort_length | 1024 |
| max_tmp_tables | 32 |
| max_write_lock_count | 4294967295 |
-| myisam_bulk_insert_tree_size | 8388608 |
| myisam_recover_options | DEFAULT |
| myisam_sort_buffer_size | 8388608 |
| net_buffer_length | 16384 |
@@ -19687,11 +19721,10 @@ differ somewhat:
| pid_file | /my/monty/data/donna.pid |
| port | 3306 |
| protocol_version | 10 |
-| record_buffer | 131072 |
-| query_buffer_size | 0 |
+| read_buffer_size | 131072 |
| query_cache_limit | 1048576 |
| query_cache_size | 16768060 |
-| query_cache_startup_type | 1 |
+| query_cache_type | 1 |
| safe_show_database | OFF |
| server_id | 0 |
| skip_locking | ON |
@@ -19783,6 +19816,15 @@ statements for the binary log during a transaction. If you often use
big, multi-statement transactions you can increase this to get more
performance. @xref{COMMIT}.
+@item @code{bulk_insert_buffer_size} (was @code{myisam_bulk_insert_tree_size})
+MyISAM uses special tree-like cache to make bulk inserts (that is,
+@code{INSERT ... SELECT}, @code{INSERT ... VALUES (...), (...), ...}, and
+@code{LOAD DATA INFILE}) faster. This variable limits
+the size of the cache tree in bytes per thread. Setting it to 0
+will disable this optimization.
+@strong{Note}: this cache is only used when adding data to non-empty table.
+Default value is 8 MB.
+
@item @code{character_set}
The default character set.
@@ -20012,15 +20054,6 @@ Maximum number of temporary tables a client can keep open at the same time.
@item @code{max_write_lock_count}
After this many write locks, allow some read locks to run in between.
-@item @code{myisam_bulk_insert_tree_size}
-MySQL uses special tree-like cache to make bulk inserts (that is,
-@code{INSERT ... SELECT}, @code{INSERT ... VALUES (...), (...), ...}, and
-@code{LOAD DATA INFILE}) faster. This variable limits
-the size of the cache tree in bytes per thread. Setting it to 0
-will disable this optimization.
-@strong{Note}: this cache is only used when adding data to non-empty table.
-Default value is 8 MB.
-
@item @code{myisam_recover_options}
The value of the @code{--myisam-recover} option.
@@ -20081,19 +20114,17 @@ The value of the @code{--port} option.
@item @code{protocol_version}
The protocol version used by the MySQL server.
-@item @code{record_buffer}
+@item @code{read_buffer_size} (was @code{record_buffer})
Each thread that does a sequential scan allocates a buffer of this
size for each table it scans. If you do many sequential scans, you may
want to increase this value.
-@item @code{record_rnd_buffer}
-When reading rows in sorted order after a sort, the rows are read through this
-buffer to avoid a disk seeks. If not set, then it's set to the value of
-@code{record_buffer}.
-
-@item @code{query_buffer_size}
-The initial allocation of the query buffer. If most of your queries are
-long (like when inserting blobs), you should increase this!
+@item @code{record_rnd_buffer_size}
+When reading rows in sorted order after a sort, the rows are read
+through this buffer to avoid a disk seeks. Can improve @code{ORDER BY}
+by a lot if set to a high value. As this is a thread specific variable,
+one should not set this big globally, but just change this when running
+some specific big queries.
@item @code{query_cache_limit}
Don't cache results that are bigger than this. (Default 1M).
@@ -20102,7 +20133,7 @@ Don't cache results that are bigger than this. (Default 1M).
The memory allocated to store results from old queries.
If this is 0, the query cache is disabled (default).
-@item @code{query_cache_startup_type}
+@item @code{query_cache_type}
This may be set (only numeric) to
@multitable @columnfractions .09 .14 .72
@item @strong{Value} @tab @strong{Alias} @tab @strong{Comment}
@@ -20388,7 +20419,7 @@ Create Table: CREATE TABLE t (
@code{SHOW CREATE TABLE} will quote table and column names according to
@code{SQL_QUOTE_SHOW_CREATE} option.
-@ref{SET OPTION, , @code{SET OPTION SQL_QUOTE_SHOW_CREATE}}.
+@ref{SET OPTION, , @code{SET SQL_QUOTE_SHOW_CREATE}}.
@node Localisation, Server-Side Scripts, Database Administration, MySQL Database Administration
@@ -24066,25 +24097,26 @@ contrast to @code{replicate-do-db}.
Example: @code{replicate-do-table=some_db.some_table}
@item @code{replicate-ignore-table=db_name.table_name} @tab
-Tells the slave thread to not replicate to the specified table. To
-specify more than one table to ignore, use the directive multiple times,
-once for each table. This will work for cross-datbase updates,
-in contrast to @code{replicate-ignore-db}.
+Tells the slave thread to not replicate any command that updates the
+specified table (even if any other tables may be update by the same
+command). To specify more than one table to ignore, use the directive
+multiple times, once for each table. This will work for cross-datbase
+updates, in contrast to @code{replicate-ignore-db}.
Example: @code{replicate-ignore-table=db_name.some_table}
@item @code{replicate-wild-do-table=db_name.table_name} @tab
-Tells the slave thread to restrict replication to the tables that match
-the specified wildcard pattern. To specify more than one table, use the
-directive multiple times, once for each table. This will work for
-cross-database updates.
+Tells the slave thread to restrict replication to queries where any of
+the updated tables match the specified wildcard pattern. To specify
+more than one table, use the directive multiple times, once for each
+table. This will work for cross-database updates.
-Example: @code{replicate-wild-do-table=foo%.bar%} will replicate only updates
-to tables in all databases that start with @code{foo} and whose table names
-start with @code{bar}.
+Example: @code{replicate-wild-do-table=foo%.bar%} will replicate only
+updates that uses a table in any databases that start with @code{foo}
+and whose table names start with @code{bar}.
@item @code{replicate-wild-ignore-table=db_name.table_name} @tab
-Tells the slave thread to not replicate to the tables that match the
+Tells the slave thread to not replicate a query whare any table matches the
given wildcard pattern. To specify more than one table to ignore, use
the directive multiple times, once for each table. This will work for
cross-database updates.
@@ -24094,21 +24126,32 @@ to tables in databases that start with @code{foo} and whose table names start
with @code{bar}.
@item @code{replicate-ignore-db=database_name} @tab
-Tells the slave thread to not replicate to the specified database. To
-specify more than one database to ignore, use the directive multiple
-times, once for each database. This option will not work if you use cross
-database updates. If you need cross database updates to work, make sure
-you have 3.23.28 or later, and use
-@code{replicate-wild-ignore-table=db_name.%}.
+
+Tells the slave thread to not replicate any command where the current
+database is @code{database_name}. To specify more than one database to
+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
+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
+the current database, as this only has to be done once at connect time
+or when the database changes.
+
+If you need cross database updates to work, make sure you have 3.23.28
+or later, and use @code{replicate-wild-ignore-table=db_name.%}.
Example: @code{replicate-ignore-db=some_db}
@item @code{replicate-do-db=database_name} @tab
-Tells the slave thread to restrict replication to the specified
-database. To specify more than one database, use the directive multiple
-times, once for each database. Note that this will only work if you do
-not use cross-database queries such as @code{UPDATE some_db.some_table
+Tells the slave thread to restrict replication to commands where
+the current database is @code{database_name}.
+To specify more than one database, use the directive multiple
+times, once for each database. Note that this will not replicate
+cross-database queries such as @code{UPDATE some_db.some_table
SET foo='bar'} while having selected a different or no database. If you
need cross database updates to work, make sure you have 3.23.28 or
later, and use @code{replicate-wild-do-table=db_name.%}.
@@ -24190,7 +24233,7 @@ summary of commands:
@tab Re-enables update logging if the user has the @code{SUPER} privilege.
Ignored otherwise. (Master)
-@item @code{SET SQL_SLAVE_SKIP_COUNTER=n}
+@item @code{GLOBAL SET SQL_SLAVE_SKIP_COUNTER=n}
@tab Skip the next @code{n} events from the master. Only valid when
the slave thread is not running, otherwise, gives an error. Useful for
recovering from replication glitches.
@@ -24696,9 +24739,9 @@ be safe to make the update manually ( if needed) and then ignore the next
query from the master.
@item
If you have decided you can skip the next query, do
-@code{SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START;} to skip a query that
+@code{SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; SLAVE START;} to skip a query that
does not use @code{AUTO_INCREMENT} or @code{LAST_INSERT_ID()}, or
-@code{SET SQL_SLAVE_SKIP_COUNTER=2; SLAVE START;} otherwise. The reason
+@code{SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; SLAVE START;} otherwise. The reason
queries that use @code{AUTO_INCREMENT} or @code{LAST_INSERT_ID()}
are different is that they take two events in the binary log of the master.
@@ -26065,7 +26108,7 @@ Some ways to speed up inserts:
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 times
in some cases) than using separate @code{INSERT} statements. If you are adding
-data to non-empty table, you may tune up @code{myisam_bulk_insert_tree_size}
+data to non-empty table, you may tune up @code{bulk_insert_buffer_size}
variable to make it even faster. @xref{SHOW VARIABLES}.
@item
If you are inserting a lot of rows from different clients, you can get
@@ -26550,8 +26593,8 @@ Start @code{mysqld} with a low value for @strong{max_write_lock_count} to give
@item
You can specify that all updates from a specific thread should be done with
-low priority by using the SQL command: @code{SET SQL_LOW_PRIORITY_UPDATES=1}.
-@xref{SET OPTION, , @code{SET OPTION}}.
+low priority by using the SQL command: @code{SET LOW_PRIORITY_UPDATES=1}.
+@xref{SET OPTION, , @code{SET}}.
@item
You can specify that a specific @code{SELECT} is very important with the
@@ -27232,9 +27275,8 @@ net_buffer_length current value: 16384
net_retry_count current value: 10
net_read_timeout current value: 30
net_write_timeout current value: 60
-query_buffer_size current value: 0
-record_buffer current value: 131072
-record_rnd_buffer current value: 131072
+read_buffer_size current value: 131072
+record_rnd_buffer_size current value: 131072
slow_launch_time current value: 2
sort_buffer current value: 2097116
table_cache current value: 64
@@ -27271,7 +27313,7 @@ with a moderate number of clients, you should use something like this:
@example
shell> safe_mysqld -O key_buffer=64M -O table_cache=256 \
- -O sort_buffer=4M -O record_buffer=1M &
+ -O sort_buffer=4M -O read_buffer_size=1M &
@end example
If you have only 128M and only a few tables, but you still do a lot of
@@ -27285,14 +27327,14 @@ If you have little memory and lots of connections, use something like this:
@example
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k \
- -O record_buffer=100k &
+ -O read_buffer_size=100k &
@end example
or even:
@example
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \
- -O table_cache=32 -O record_buffer=8k -O net_buffer=1K &
+ -O table_cache=32 -O read_buffer_size=8k -O net_buffer_length=1K &
@end example
If you are doing a @code{GROUP BY} or @code{ORDER BY} on files that are
@@ -27484,8 +27526,8 @@ automatically changing the in-memory (HEAP) table to a disk-based
(MyISAM) table as necessary. To work around this problem, you can
increase the temporary table size by setting the @code{tmp_table_size}
option to @code{mysqld}, or by setting the SQL option
-@code{SQL_BIG_TABLES} in the client program. @xref{SET OPTION, ,
-@code{SET OPTION}}. In MySQL Version 3.20, the maximum size of the
+@code{BIG_TABLES} in the client program. @xref{SET OPTION, ,
+@code{SET}}. In MySQL Version 3.20, the maximum size of the
temporary table was @code{record_buffer*16}, so if you are using this
version, you have to increase the value of @code{record_buffer}. You can
also start @code{mysqld} with the @code{--big-tables} option to always
@@ -27579,12 +27621,86 @@ by starting @code{mysqld} with @code{--skip-networking}.
@findex SET OPTION
@example
-SET [OPTION] SQL_VALUE_OPTION= value, ...
+SET [GLOBAL | SESSION] sql_variable=expression, [[GLOBAL | SESSION] sql_variable=expression...]
+@end example
+
+@code{SET} sets various options that affect the operation of the
+server or your client.
+
+The following examples shows the different syntaxes one can use to set
+variables:
+
+In old MySQL versions we allowed the use of the @code{SET OPTION} syntax,
+but this syntax is now deprecated.
+
+In MySQL 4.0.3 we added the @code{GLOBAL} and @code{SESSION} options
+and access to most important startup variables.
+
+@code{LOCAL} can be used as a synonym for @code{SESSION}.
+
+If you set several variables on the same command line, the last used
+@code{GLOBAL | SESSION} mode is used.
+
+@example
+SET sort_buffer_size=10000;
+SET @@@@local.sort_buffer_size=10000;
+SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000;
+SET @@@@sort_buffer_size=1000000;
+SET @@@@global.sort_buffer_size=1000000, @@@@local.sort_buffer_size=1000000;
+@end example
+
+The @code{@@@@variable_name} syntax is supported to make MySQL syntax
+compatible with some other databases.
+
+The different system variables one can set are described in the system
+variable section of this manual. @xref{System Variables}.
+
+If you are using @code{SESSION} (the default) the option you set remains
+in effect until the current session ends, or until you set the option to
+a different value. If you use @code{GLOBAL}, which require the
+@code{SUPER} privilege, the option is remembered and used for new
+connections until the server restarts. If you want to make an option
+permanent, you should set it in one of the MySQL option
+files. @xref{Option files}.
+
+To avoid wrong usage MySQL will give an error if you use @code{SET
+GLOBAL} with a variable that can only be used with @code{SET SESSION} or if
+you are not using @code{SET GLOBAL} with a global variable.
+
+If you want to set a @code{SESSION} variable to the @code{GLOBAL} value or a
+@code{GLOBAL} value to the MySQL default value, you can set it to
+@code{DEFAULT}.
+
+@example
+SET max_join_size=DEFAULT;
+@end example
+
+This is idential to:
+
+@example
+SET @@@@session.max_join_size=@@@@global.max_join_size;
+@end example
+
+If you want to restrict the maximum value a startup option can be set to
+with the @code{SET} command, you can specify this by using the
+@code{--maximum-variable-name} command line option. @xref{Command-line
+options}.
+
+You can get a list of most variables with @code{SHOW VARIABLES}.
+@xref{SHOW VARIABLES}. You can get the value for a specific value with
+the @code{@@@@[global.|local.]variable_name} syntax:
+@example
+SHOW VARIABLES like "max_join_size";
+SHOW GLOBAL VARIABLES like "max_join_size";
+SELECT @@@@max_join_size, @@@@global.max_join_size;
@end example
-@code{SET OPTION} sets various options that affect the operation of the
-server or your client. Any option you set remains in effect until the
-current session ends, or until you set the option to a different value.
+Here follows a description of the variables that uses a the variables
+that uses a non-standard @code{SET} syntax and some of the other
+variables. The other variable definitions can be found in the system
+variable section, among the startup options or in the description of
+@code{SHOW VARIABLES}. @xref{System Variables}. @xref{Command-line
+options}. @xref{SHOW VARIABLES}.
@table @code
@item CHARACTER SET character_set_name | DEFAULT
@@ -27636,13 +27752,14 @@ that when you change from not @code{AUTOCOMMIT} mode to
@code{AUTOCOMMIT} mode, MySQL will do an automatic
@code{COMMIT} on any open transactions.
-@item SQL_BIG_TABLES = 0 | 1
+@item BIG_TABLES = 0 | 1
@cindex table is full
If set to @code{1}, all temporary tables are stored on disk rather than in
memory. This will be a little slower, but you will not get the error
@code{The table tbl_name is full} for big @code{SELECT} operations that
require a large temporary table. The default value for a new connection is
@code{0} (that is, use in-memory temporary tables).
+This option was before named @code{SQL_BIG_TABLES}.
@item SQL_BIG_SELECTS = 0 | 1
If set to @code{0}, MySQL will abort if a @code{SELECT} is attempted
@@ -27658,12 +27775,13 @@ to be put into a temporary table. This will help MySQL free the
table locks early and will help in cases where it takes a long time to
send the result set to the client.
-@item SQL_LOW_PRIORITY_UPDATES = 0 | 1
+@item LOW_PRIORITY_UPDATES = 0 | 1
If set to @code{1}, all @code{INSERT}, @code{UPDATE}, @code{DELETE}, and
and @code{LOCK TABLE WRITE} statements wait until there is no pending
@code{SELECT} or @code{LOCK TABLE READ} on the affected table.
+This option was before named @code{SQL_LOW_PRIORITY_UPDATES}.
-@item SQL_MAX_JOIN_SIZE = value | DEFAULT
+@item MAX_JOIN_SIZE = value | DEFAULT
Don't allow @code{SELECT}s that will probably need to examine more than
@code{value} row combinations. By setting this value, you can catch
@code{SELECT}s where keys are not used properly and that would probably
@@ -27672,14 +27790,15 @@ the @code{SQL_BIG_SELECTS} flag. If you set the @code{SQL_BIG_SELECTS}
flag again, the @code{SQL_MAX_JOIN_SIZE} variable will be ignored.
You can set a default value for this variable by starting @code{mysqld} with
@code{-O max_join_size=#}.
+This option was before named @code{SQL_MAX_JOIN_SIZE}.
Note that if the result of the query is already in the query cache, the
above check will not be made. Instead, MySQL will send the result to the
client. Since the query result is already computed and it will not burden
the server to send the result to the client.
-@item SQL_QUERY_CACHE_TYPE = OFF | ON | DEMAND
-@item SQL_QUERY_CACHE_TYPE = 0 | 1 | 2
+@item QUERY_CACHE_TYPE = OFF | ON | DEMAND
+@item QUERY_CACHE_TYPE = 0 | 1 | 2
Set query cache setting for this thread.
@multitable @columnfractions .20 .70
@item @strong{Option} @tab @strong{Description}
@@ -27733,8 +27852,6 @@ command when inserting an @code{AUTO_INCREMENT} value. This is mainly used
with the update log.
@end table
-@xref{SET TRANSACTION}.
-
@node Disk issues, , Optimising the Server, MySQL Optimisation
@section Disk Issues
@@ -27822,7 +27939,7 @@ too much reliability. (This flag is on by default on Linux.)
@item
If you don't need to know when a file was last accessed (which is not
really useful on a database server), you can mount your filesystems
-with the noatime flag.
+with the @code{noatime} flag.
@end itemize
@menu
@@ -28008,6 +28125,7 @@ may find it useful to refer to the various indexes.
* Legal names:: Database, Table, Index, Column, and Alias Names
* Name case sensitivity:: Case-Sensitivity in Names
* Variables:: User Variables
+* System Variables:: System Variables
* Comments:: Comment Syntax
* Reserved words:: Is MySQL Picky About Reserved Words?
@end menu
@@ -28428,14 +28546,14 @@ the case of the file extensions in each specified database directory
@file{mysql_fix_extensions} can be found in the @file{script} subdirectory.
-@node Variables, Comments, Name case sensitivity, Language Structure
+@node Variables, System Variables, Name case sensitivity, Language Structure
@subsection User Variables
@cindex variables, user
@cindex user variables
@cindex names, variables
-MySQL supports thread-specific variables with the
+MySQL supports thread-specific user variables with the
@code{@@variablename} syntax. A variable name may consist of
alphanumeric characters from the current character set and also
@samp{_}, @samp{$}, and @samp{.} . The default character set is
@@ -28486,7 +28604,181 @@ mysql> SELECT (@@aa:=id) AS a, (@@aa+3) AS b FROM table_name HAVING b=5;
The reason is that @code{@@aa} will not contain the value of the current
row, but the value of @code{id} for the previous accepted row.
-@node Comments, Reserved words, Variables, Language Structure
+@node System Variables, Comments, Variables, Language Structure
+@subsection System Variables
+
+Starting from MySQL 4.0.3 we provide better access to a lot of system
+variables and one can change most of them without having to take
+down the server.
+
+There are two kind of system variables: Thread (or connection) specific
+variables that are unique to the current connection and global variables
+that are either used to configure global events or used as initial
+variables for a new connection.
+
+When mysqld starts all global variables are initialised from command
+line arguments and option files. You can change the used value with the
+@code{SET GLOBAL} command. When a new thread is created the thread
+specific variables are initialised from the global variables and they
+will not change even if one issues a new @code{SET GLOBAL} command.
+
+To set the value for a @code{GLOBAL} variable, you should use one
+of the following syntaxes:
+(Here we use @code{sort_buffer_size} as an example variable)
+
+@example
+SET GLOBAL sort_buffer_size=value;
+SET @@@@global.sort_buffer_size=value;
+@end example
+
+To set the value for @code{SESSION} variable, you can use on of the
+following syntaxes:
+
+@example
+SET SESSION sort_buffer_size=value;
+SET @@@@session.sort_buffer_size=value;
+SET sort_buffer_size=value;
+@end example
+
+If you don't specify @code{GLOBAL} or @code{SESSION} then @code{SESSION}
+is used. @xref{SET OPTION}.
+
+@code{LOCAL} is a synonym for @code{SESSION}.
+
+To retrieve the value for a @code{GLOBAL} variable you can use one of the
+following commands:
+
+@example
+SELECT @@@@global.sort_buffer_size;
+SHOW GLOBAL VARIABLES like 'sort_buffer_size';
+@end example
+
+To retrieve the value for a @code{SESSION} variable you can use one of the
+following commands:
+
+@example
+SELECT @@@@session.sort_buffer_size;
+SHOW SESSION VARIABLES like 'sort_buffer_size';
+@end example
+
+When you @strong{retrieve} a variable value with the
+@code{@@@@variable_name} syntax and you don't specify @code{GLOBAL} or
+@code{SESSION} then MySQL will return the thread specific
+(@code{SESSION}) value if a such exist. If not, MySQL will return the
+global value.
+
+The reason for requiring @code{GLOBAL} for setting @code{GLOBAL} only
+variables but not for retrieving them is to ensure that we don't later
+run into problems if we later would introduce a thread specific variable
+with the same name or remove a thread specific variable. In this case
+you could accidently change the state for the whole server and not
+just for your own connection.
+
+The following is a full list of all variables that you change and retrieve
+and if you can use @code{GLOBAL} or @code{SESSION} with them.
+
+@multitable @columnfractions .50 .25 .25
+@item @strong{Variable name} @tab @strong{Value type} @tab @strong{Type}
+@item autocommit @tab bool @tab SESSION
+@item big_tables @tab bool @tab SESSION
+@item binlog_cache_size @tab num @tab GLOBAL
+@item bulk_insert_buffer_size @tab num @tab GLOBAL | SESSION
+@item concurrent_insert @tab bool @tab GLOBAL
+@item connect_timeout @tab num @tab GLOBAL
+@item convert_character_set @tab string @tab SESSION
+@item delay_key_write @tab bool @tab GLOBAL
+@item delayed_insert_limit @tab num @tab GLOBAL
+@item delayed_insert_timeout @tab num @tab GLOBAL
+@item delayed_queue_size @tab num @tab GLOBAL
+@item flush @tab bool @tab GLOBAL
+@item flush_time @tab num @tab GLOBAL
+@item identity @tab num @tab SESSION
+@item insert_id @tab bool @tab SESSION
+@item interactive_timeout @tab num @tab GLOBAL | SESSION
+@item join_buffer_size @tab num @tab GLOBAL | SESSION
+@item key_buffer_size @tab num @tab GLOBAL
+@item last_insert_id @tab bool @tab SESSION
+@item local_infile @tab bool @tab GLOBAL
+@item log_warnings @tab bool @tab GLOBAL
+@item long_query_time @tab num @tab GLOBAL | SESSION
+@item low_priority_updates @tab bool @tab GLOBAL | SESSION
+@item max_allowed_packet @tab num @tab GLOBAL | SESSION
+@item max_binlog_cache_size @tab num @tab GLOBAL
+@item max_binlog_size @tab num @tab GLOBAL
+@item max_connect_errors @tab num @tab GLOBAL
+@item max_connections @tab num @tab GLOBAL
+@item max_delayed_threads @tab num @tab GLOBAL
+@item max_heap_table_size @tab num @tab GLOBAL | SESSION
+@item max_join_size @tab num @tab GLOBAL | SESSION
+@item max_sort_length @tab num @tab GLOBAL | SESSION
+@item max_tmp_tables @tab num @tab GLOBAL
+@item max_user_connections @tab num @tab GLOBAL
+@item max_write_lock_count @tab num @tab GLOBAL
+@item myisam_max_extra_sort_file_size @tab num @tab GLOBAL | SESSION
+@item myisam_max_sort_file_size @tab num @tab GLOBAL | SESSION
+@item myisam_sort_buffer_size @tab num @tab GLOBAL | SESSION
+@item net_buffer_length @tab num @tab GLOBAL | SESSION
+@item net_read_timeout @tab num @tab GLOBAL | SESSION
+@item net_write_timeout @tab num @tab GLOBAL | SESSION
+@item query_cache_limit @tab num @tab GLOBAL
+@item query_cache_size @tab num @tab GLOBAL
+@item query_cache_type @tab enum @tab GLOBAL
+@item read_buffer_size @tab num @tab GLOBAL | SESSION
+@item read_rnd_buffer_size num @tab GLOBAL | SESSION
+@item rpl_recovery_rank @tab num @tab GLOBAL
+@item safe_show_database @tab bool @tab GLOBAL
+@item server_id @tab num @tab GLOBAL
+@item slave_net_timeout @tab num @tab GLOBAL
+@item slow_launch_time @tab num @tab GLOBAL
+@item sort_buffer_size @tab num @tab GLOBAL | SESSION
+@item sql_auto_is_null @tab bool @tab SESSION
+@item sql_big_selects @tab bool @tab SESSION
+@item sql_big_tables @tab bool @tab SESSION
+@item sql_buffer_result @tab bool @tab SESSION
+@item sql_log_binlog @tab bool @tab SESSION
+@item sql_log_off @tab bool @tab SESSION
+@item sql_log_update @tab bool @tab SESSION
+@item sql_low_priority_updates @tab bool @tab GLOBAL | SESSION
+@item sql_max_join_size @tab num @tab GLOBAL | SESSION
+@item sql_quote_show_create @tab bool @tab SESSION
+@item sql_safe_updates @tab bool @tab SESSION
+@item sql_select_limit @tab bool @tab SESSION
+@item sql_slave_skip_counter @tab num @tab GLOBAL
+@item sql_warnings @tab bool @tab SESSION
+@item table_cache @tab num @tab GLOBAL
+@item table_type @tab enum @tab GLOBAL | SESSION
+@item thread_cache_size @tab num @tab GLOBAL
+@item timestamp @tab bool @tab SESSION
+@item tmp_table_size @tab enum @tab GLOBAL | SESSION
+@item tx_isolation @tab enum @tab GLOBAL | SESSION
+@item version @tab string @tab GLOBAL
+@item wait_timeout @tab num @tab GLOBAL | SESSION
+@end multitable
+
+Variables that are marked with @code{num} can be given a numerical
+value. Variables that are marked with @code{bool} can be set to 0, 1,
+@code{ON} or @code{OFF}. Variables that are of type @code{enum} should
+normally be set to one of the available values for the variable, but can
+also be set to the number that correspond to the enum value. (The first
+enum value is 0).
+
+Here is a description of some of the variables:
+
+@multitable @columnfractions 0.30 0.70
+@item @strong{Variable} @tab @strong{Description}
+@item identity @tab Alias for last_insert_id (Sybase compatiblity)
+@item sql_low_priority_updates @tab Alias for low_priority_updates
+@item sql_max_join_size @tab Alias for max_join_size
+@item version @tab Alias for VERSION() (Sybase (?) compatability)
+@end multitable
+
+A description of the other variable definitions can be found in the
+startup options section, the description of @code{SHOW VARIABLES} and in
+the @code{SET} section. @xref{Command-line
+options}. @xref{SHOW VARIABLES}. @xref{SET OPTION}.
+
+
+@node Comments, Reserved words, System Variables, Language Structure
@subsection Comment Syntax
@findex Comment syntax
@@ -28559,7 +28851,7 @@ A few are reserved because MySQL needs them and is
@c START_OF_RESERVED_WORDS
-@c Reserved word list updated Fri Jun 14 09:34:10 2002 by arjen.
+@c Reserved word list updated Tue Jul 23 02:10:12 2002 by monty.
@c To regenerate, use Support/update-reserved-words.pl.
@multitable @columnfractions .33 .33 .34
@@ -28637,118 +28929,103 @@ A few are reserved because MySQL needs them and is
@tab @code{INNER}
@item @code{INNODB}
@tab @code{INSERT}
- @tab @code{INSERT_ID}
-@item @code{INT}
- @tab @code{INTEGER}
+ @tab @code{INT}
+@item @code{INTEGER}
@tab @code{INTERVAL}
-@item @code{INTO}
- @tab @code{IS}
+ @tab @code{INTO}
+@item @code{IS}
@tab @code{JOIN}
-@item @code{KEY}
- @tab @code{KEYS}
+ @tab @code{KEY}
+@item @code{KEYS}
@tab @code{KILL}
-@item @code{LAST_INSERT_ID}
@tab @code{LEADING}
- @tab @code{LEFT}
-@item @code{LIKE}
+@item @code{LEFT}
+ @tab @code{LIKE}
@tab @code{LIMIT}
- @tab @code{LINES}
-@item @code{LOAD}
+@item @code{LINES}
+ @tab @code{LOAD}
@tab @code{LOCK}
- @tab @code{LONG}
-@item @code{LONGBLOB}
+@item @code{LONG}
+ @tab @code{LONGBLOB}
@tab @code{LONGTEXT}
- @tab @code{LOW_PRIORITY}
-@item @code{MASTER_SERVER_ID}
+@item @code{LOW_PRIORITY}
+ @tab @code{MASTER_SERVER_ID}
@tab @code{MATCH}
- @tab @code{MEDIUMBLOB}
-@item @code{MEDIUMINT}
+@item @code{MEDIUMBLOB}
+ @tab @code{MEDIUMINT}
@tab @code{MEDIUMTEXT}
- @tab @code{MIDDLEINT}
-@item @code{MINUTE_SECOND}
+@item @code{MIDDLEINT}
+ @tab @code{MINUTE_SECOND}
@tab @code{MRG_MYISAM}
- @tab @code{NATURAL}
-@item @code{NOT}
+@item @code{NATURAL}
+ @tab @code{NOT}
@tab @code{NULL}
- @tab @code{NUMERIC}
-@item @code{ON}
+@item @code{NUMERIC}
+ @tab @code{ON}
@tab @code{OPTIMIZE}
- @tab @code{OPTION}
-@item @code{OPTIONALLY}
+@item @code{OPTION}
+ @tab @code{OPTIONALLY}
@tab @code{OR}
- @tab @code{ORDER}
-@item @code{OUTER}
+@item @code{ORDER}
+ @tab @code{OUTER}
@tab @code{OUTFILE}
- @tab @code{PARTIAL}
-@item @code{PRECISION}
+@item @code{PARTIAL}
+ @tab @code{PRECISION}
@tab @code{PRIMARY}
- @tab @code{PRIVILEGES}
-@item @code{PROCEDURE}
+@item @code{PRIVILEGES}
+ @tab @code{PROCEDURE}
@tab @code{PURGE}
- @tab @code{READ}
-@item @code{REAL}
+@item @code{READ}
+ @tab @code{REAL}
@tab @code{REFERENCES}
- @tab @code{REGEXP}
-@item @code{RENAME}
+@item @code{REGEXP}
+ @tab @code{RENAME}
@tab @code{REPLACE}
- @tab @code{REQUIRE}
-@item @code{RESTRICT}
+@item @code{REQUIRE}
+ @tab @code{RESTRICT}
@tab @code{RETURNS}
- @tab @code{REVOKE}
-@item @code{RIGHT}
+@item @code{REVOKE}
+ @tab @code{RIGHT}
@tab @code{RLIKE}
- @tab @code{SELECT}
-@item @code{SET}
+@item @code{SELECT}
+ @tab @code{SET}
@tab @code{SHOW}
- @tab @code{SMALLINT}
-@item @code{SONAME}
- @tab @code{SQL_AUTO_IS_NULL}
+@item @code{SMALLINT}
+ @tab @code{SONAME}
@tab @code{SQL_BIG_RESULT}
-@item @code{SQL_BIG_SELECTS}
- @tab @code{SQL_BIG_TABLES}
- @tab @code{SQL_BUFFER_RESULT}
@item @code{SQL_CALC_FOUND_ROWS}
- @tab @code{SQL_LOG_BIN}
- @tab @code{SQL_LOG_OFF}
-@item @code{SQL_LOG_UPDATE}
- @tab @code{SQL_LOW_PRIORITY_UPDATES}
- @tab @code{SQL_MAX_JOIN_SIZE}
-@item @code{SQL_QUOTE_SHOW_CREATE}
- @tab @code{SQL_SAFE_UPDATES}
- @tab @code{SQL_SELECT_LIMIT}
-@item @code{SQL_SLAVE_SKIP_COUNTER}
@tab @code{SQL_SMALL_RESULT}
- @tab @code{SQL_WARNINGS}
-@item @code{SSL}
- @tab @code{STARTING}
+ @tab @code{SSL}
+@item @code{STARTING}
@tab @code{STRAIGHT_JOIN}
-@item @code{STRIPED}
- @tab @code{TABLE}
+ @tab @code{STRIPED}
+@item @code{TABLE}
@tab @code{TABLES}
-@item @code{TERMINATED}
- @tab @code{THEN}
+ @tab @code{TERMINATED}
+@item @code{THEN}
@tab @code{TINYBLOB}
-@item @code{TINYINT}
- @tab @code{TINYTEXT}
+ @tab @code{TINYINT}
+@item @code{TINYTEXT}
@tab @code{TO}
-@item @code{TRAILING}
- @tab @code{UNION}
+ @tab @code{TRAILING}
+@item @code{UNION}
@tab @code{UNIQUE}
-@item @code{UNLOCK}
- @tab @code{UNSIGNED}
+ @tab @code{UNLOCK}
+@item @code{UNSIGNED}
@tab @code{UPDATE}
-@item @code{USAGE}
- @tab @code{USE}
+ @tab @code{USAGE}
+@item @code{USE}
@tab @code{USER_RESOURCES}
-@item @code{USING}
- @tab @code{VALUES}
+ @tab @code{USING}
+@item @code{VALUES}
@tab @code{VARBINARY}
-@item @code{VARCHAR}
- @tab @code{VARYING}
+ @tab @code{VARCHAR}
+@item @code{VARYING}
@tab @code{WHEN}
-@item @code{WHERE}
- @tab @code{WITH}
+ @tab @code{WHERE}
+@item @code{WITH}
@tab @code{WRITE}
+ @tab @code{XOR}
@item @code{YEAR_MONTH}
@tab @code{ZEROFILL}
@tab
@@ -33742,7 +34019,7 @@ FOUND_ROWS()}. @xref{Miscellaneous functions}.
@item
@code{SQL_CACHE} tells MySQL to store the query result in the query cache
-if you are using @code{SQL_QUERY_CACHE_TYPE=2} (@code{DEMAND}).
+if you are using @code{QUERY_CACHE_TYPE=2} (@code{DEMAND}).
@xref{Query Cache}.
@item
@@ -34094,8 +34371,7 @@ HANDLER tbl_name CLOSE
@end example
The @code{HANDLER} statement provides direct access to the @code{MyISAM} table
-handler interface, bypassing the SQL optimiser. Thus, it is faster than
-@code{SELECT}.
+handler interface.
The first form of @code{HANDLER} statement opens a table, making
it accessible via subsequent @code{HANDLER ... READ} statements.
@@ -34129,6 +34405,34 @@ means that after a @code{HANDLER ... OPEN} is issued, table data can be
modified (by this or any other thread) and these modifications may appear
only partially in @code{HANDLER ... NEXT} or @code{HANDLER ... PREV} scans.
+The reasons to use this interface instead of normal SQL are:
+
+@itemize @bullet
+@item
+It's faster than @code{SELECT} because:
+@itemize @bullet
+@item
+A designated table handler is allocated for the thread in @code{HANDLER open}.
+@item
+There is less parsing involved.
+@item
+No optimizer and no query checking overhead.
+@item
+The used table doesn't have to be locked between two handler requests.
+@item
+The handler interface doesn't have to provide a consistent look of the
+data (for example dirty-reads are allow), which allows the table handler
+to do optimizations that SQL doesn't normally allow.
+@end itemize
+@item
+It makes it much easier to port applications that uses an ISAM like
+interface to MySQL.
+@item
+It allows one to traverse a database in a manner that is not easy
+(in some case impossible) to do with SQL. The handler interface is
+more natural way to look at data when working with applications that
+provide an interactive user interfaces to the database.
+@end itemize
@node INSERT, INSERT DELAYED, HANDLER, Data Manipulation
@subsection @code{INSERT} Syntax
@@ -37024,7 +37328,7 @@ Don't cache results that are bigger than this. (Default 1M).
The memory allocated to store results from old queries.
If this is 0, the query cache is disabled (default).
-@item @code{query_cache_startup_type}
+@item @code{query_cache_type}
This may be set (only numeric) to
@multitable @columnfractions .10 .75
@item @strong{Option} @tab @strong{Description}
@@ -37034,12 +37338,11 @@ This may be set (only numeric) to
@end multitable
@end itemize
-
Inside a thread (connection), the behaviour of the query cache can be
changed from the default. The syntax is as follows:
-@code{SQL_QUERY_CACHE_TYPE = OFF | ON | DEMAND}
-@code{SQL_QUERY_CACHE_TYPE = 0 | 1 | 2}
+@code{QUERY_CACHE_TYPE = OFF | ON | DEMAND}
+@code{QUERY_CACHE_TYPE = 0 | 1 | 2}
@multitable @columnfractions .20 .70
@item @strong{Option} @tab @strong{Description}
@@ -37048,9 +37351,6 @@ changed from the default. The syntax is as follows:
@item 2 or DEMAND @tab Cache only @code{SELECT SQL_CACHE ...} queries.
@end multitable
-By default @code{SQL_QUERY_CACHE_TYPE} depends on the value of
-@code{query_cache_startup_type} when the thread was created.
-
@node Query Cache in SELECT, Query Cache Status and Maintenance, Query Cache Configuration, Query Cache
@subsection Query Cache Options in @code{SELECT}
@@ -37064,9 +37364,9 @@ specified in a @code{SELECT} query:
@multitable @columnfractions .20 .80
@item @strong{Option} @tab @strong{Description}
@item @code{SQL_CACHE}
- @tab If @code{SQL_QUERY_CACHE_TYPE} is @code{DEMAND}, allow the query to be cached.
- If @code{SQL_QUERY_CACHE_TYPE} is @code{ON}, this is the default.
- If @code{SQL_QUERY_CACHE_TYPE} is @code{OFF}, do nothing.
+ @tab If @code{QUERY_CACHE_TYPE} is @code{DEMAND}, allow the query to be cached.
+ If @code{QUERY_CACHE_TYPE} is @code{ON}, this is the default.
+ If @code{QUERY_CACHE_TYPE} is @code{OFF}, do nothing.
@item @code{SQL_NO_CACHE}
@tab Make this query non-cachable, don't allow this query to be stored in the cache.
@end multitable
@@ -37095,7 +37395,7 @@ You can monitor query cache performance in @code{SHOW STATUS}:
@tab Number of cache hits.
@item @code{Qcache_not_cached}
@tab Number of non-cached queries
- (not cachable, or due to @code{SQL_QUERY_CACHE_TYPE}).
+ (not cachable, or due to @code{QUERY_CACHE_TYPE}).
@item @code{Qcache_free_memory}
@tab Amount of free memory for query cache.
@item @code{Qcache_total_blocks}
@@ -37330,7 +37630,7 @@ The following options to @code{mysqld} can be used to change the behaviour of
@item @code{--delay-key-write-for-all-tables} @tab Don't flush key buffers between writes for any MyISAM table
@item @code{-O myisam_max_extra_sort_file_size=#} @tab Used to help MySQL to decide when to use the slow but safe key cache index create method. @strong{Note} that this parameter is given in megabytes!
@item @code{-O myisam_max_sort_file_size=#} @tab Don't use the fast sort index method to created index if the temporary file would get bigger than this. @strong{Note} that this paramter is given in megabytes!
-@item @code{-O myisam_bulk_insert_tree_size=#} @tab Size of tree cache used in bulk insert optimisation. @strong{Note} that this is a limit @strong{per thread}!
+@item @code{-O bulk_insert_buffer_size=#} @tab Size of tree cache used in bulk insert optimisation. @strong{Note} that this is a limit @strong{per thread}!
@end multitable
The automatic recovery is activated if you start @code{mysqld} with
@@ -38369,11 +38669,11 @@ too high}. glibc will allow the process heap to grow over thread stacks,
which will crash your server. It is a risk if the value of
@example
innodb_buffer_pool_size + key_buffer +
-max_connections * (sort_buffer + record_buffer) + max_connections * 2 MB
+max_connections * (sort_buffer + read_buffer_size) + max_connections * 2 MB
@end example
is close to 2 GB or exceeds 2 GB. Each thread will use a stack
(often 2 MB, but in MySQL AB binaries only 256 kB) and in the worst case also
-@code{sort_buffer + record_buffer}
+@code{sort_buffer + read_buffer_size}
additional memory.
@strong{How to tune other @file{mysqld} server parameters?}
@@ -38381,7 +38681,7 @@ Typical values which suit most users are:
@example
skip-locking
set-variable = max_connections=200
-set-variable = record_buffer=1M
+set-variable = read_buffer_size=1M
set-variable = sort_buffer=1M
# Set key_buffer to 5 - 50%
# of your RAM depending on how
@@ -46878,11 +47178,11 @@ You are using an older MySQL version (before 3.23.0) when an in-memory
temporary table becomes larger than @code{tmp_table_size} bytes.
To avoid this problem, you can use the @code{-O tmp_table_size=#} option
to make @code{mysqld} increase the temporary table size or use the SQL
-option @code{SQL_BIG_TABLES} before you issue the problematic query.
-@xref{SET OPTION, ,@code{SET OPTION}}.
+option @code{BIG_TABLES} before you issue the problematic query.
+@xref{SET OPTION, ,@code{SET}}.
You can also start @code{mysqld} with the @code{--big-tables} option.
-This is exactly the same as using @code{SQL_BIG_TABLES} for all queries.
+This is exactly the same as using @code{BIG_TABLES} for all queries.
In MySQL Version 3.23, in-memory temporary tables will automatically be
converted to a disk-based @code{MyISAM} table after the table size gets
@@ -49674,12 +49974,35 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@cindex changes, version 4.0
@menu
+* News-4.0.3:: Changes in release 4.0.3
* News-4.0.2:: Changes in release 4.0.2 (01 July 2002)
* News-4.0.1:: Changes in release 4.0.1 (23 Dec 2001)
* News-4.0.0:: Changes in release 4.0.0 (Oct 2001: Alpha)
@end menu
-@node News-4.0.2, News-4.0.1, News-4.0.x, News-4.0.x
+@node News-4.0.3, News-4.0.2, News-4.0.x, News-4.0.x
+@appendixsubsec Changes in release 4.0.3
+@itemize @bullet
+The startup parameters @code{myisam_max_extra_sort_file_size} and
+@code{myisam_max_extra_sort_file_size} are now given in bytes, not megabytes.
+@item
+Fixed a timing bug in @code{DROP DATABASE}
+@item
+New @code{SET [GLOBAL | SESSION]} syntax to change thread specific and global
+server variables at runtime.
+@item
+Renamed variable @code{query_cache_startup_type} to @code{query_cache_type},
+@code{myisam_bulk_insert_tree_size} to @code{bulk_insert_buffer_size},
+@code{record_buffer} to @code{read_buffer_size} and
+@code{record_rnd_buffer} to @code{record_rnd_buffer_size}.
+@item
+Renamed some sql variables, but old names will still work until 5.0.
+@xref{Upgrading-from-3.23}.
+@item
+Removed not used variable @code{query_buffer_size}.
+@end itemize
+
+@node News-4.0.2, News-4.0.1, News-4.0.3, News-4.0.x
@appendixsubsec Changes in release 4.0.2 (01 July 2002)
@itemize @bullet
@@ -53273,7 +53596,7 @@ construct returned the rightmost 'pos' characters.)
@item
Fixed problem with @code{LOCK TABLES} combined with @code{DELETE FROM table}
@item
-Fixed problem that @code{INSERT ... SELECT} didn't use @code{SQL_BIG_TABLES}.
+Fixed problem that @code{INSERT ... SELECT} didn't use @code{BIG_TABLES}.
@item
@code{SET SQL_LOW_PRIORITY_UPDATES=#} didn't work.
@item
@@ -53902,7 +54225,7 @@ assumes the value is given as: @code{[[[D ]HH:]MM:]SS} instead of
and hours up to 32767.
@item
Added new option
-@code{SET OPTION SQL_LOG_UPDATE=@{0|1@}} to allow users with
+@code{SET SQL_LOG_UPDATE=@{0|1@}} to allow users with
the @code{PROCESS} privilege to bypass the update log.
(Modified patch from Sergey A Mukhin @email{violet@@rosnet.net}.)
@item
@@ -53921,7 +54244,7 @@ Added @code{--low-priority-updates} option to @code{mysqld}, to give
table-modifying operations (@code{INSERT}, @code{REPLACE}, @code{UPDATE},
@code{DELETE}) lower priority than retrievals. You can now use
@code{@{INSERT | REPLACE | UPDATE | DELETE@} LOW_PRIORITY ...} You can
-also use @code{SET OPTION SQL_LOW_PRIORITY_UPDATES=@{0|1@}} to change
+also use @code{SET SQL_LOW_PRIORITY_UPDATES=@{0|1@}} to change
the priority for one thread. One side effect is that @code{LOW_PRIORITY}
is now a reserved word. :(
@item
@@ -54969,7 +55292,7 @@ Fixed better @code{FOREIGN KEY} syntax skipping. New reserved words:
@code{mysqld} now allows IP number and hostname for the @code{--bind-address}
option.
@item
-Added @code{SET OPTION CHARACTER SET cp1251_koi8} to enable conversions of
+Added @code{SET CHARACTER SET cp1251_koi8} to enable conversions of
data to and from the @code{cp1251_koi8} character set.
@item
Lots of changes for Windows 95 port. In theory, this version should now be
@@ -55229,7 +55552,7 @@ Added @code{-O join_cache_size=#} option to @code{mysqld}.
@item
Added @code{-O max_join_size=#} option to @code{mysqld}, to be able to set a
limit how big queries (in this case big = slow) one should be able to handle
-without specifying @code{SET OPTION SQL_BIG_SELECTS=1}. A # = is about 10
+without specifying @code{SET SQL_BIG_SELECTS=1}. A # = is about 10
examined records. The default is ``unlimited''.
@item
When comparing a @code{TIME}, @code{DATE}, @code{DATETIME} or @code{TIMESTAMP}
@@ -55518,7 +55841,7 @@ Now @code{LIKE} is always case-insensitive.
@item
@file{mysql.cc}: Allow @code{'#'} anywhere on the line.
@item
-New command @code{SET OPTION SQL_SELECT_LIMIT=#}. See the FAQ for more details.
+New command @code{SET SQL_SELECT_LIMIT=#}. See the FAQ for more details.
@item
New version of the @code{mysqlaccess} script.
@item
diff --git a/client/client_priv.h b/client/client_priv.h
index b527bdf201c..acf9455bf9c 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -19,8 +19,8 @@
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
-#include <mysql_embed.h>
#include <mysql.h>
+#include <mysql_embed.h>
#include <errmsg.h>
#include <my_getopt.h>
diff --git a/client/mysql.cc b/client/mysql.cc
index 5b2379e91ec..5577fa2e28f 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1487,7 +1487,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
static void init_pager()
{
-#if !defined( __WIN__) && !defined( OS2) && (!defined(HAVE_mit_thread) && defined(THREAD))
+#if !defined( __WIN__) && !defined( OS2) && (!defined(HAVE_mit_thread) || !defined(THREAD))
if (!opt_nopager)
{
if (!(PAGER= popen(pager, "w")))
@@ -2336,11 +2336,11 @@ com_status(String *buffer __attribute__((unused)),
if ((status=mysql_stat(&mysql)) && !mysql_error(&mysql)[0])
{
- char *pos,buff[40];
ulong sec;
- pos=strchr(status,' ');
- *pos++=0;
- tee_fprintf(stdout, "%s\t\t\t", status); /* print label */
+ char buff[40];
+ const char *pos= strchr(status,' ');
+ /* print label */
+ tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status), status);
if ((status=str2int(pos,10,0,LONG_MAX,(long*) &sec)))
{
nice_time((double) sec,buff,0);
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index b790880be6f..d890a096542 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -23,7 +23,7 @@
#include <my_pthread.h> /* because of signal() */
#endif
-#define ADMIN_VERSION "8.35"
+#define ADMIN_VERSION "8.36"
#define MAX_MYSQL_VAR 128
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
@@ -588,7 +588,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
MYSQL_ROW row;
new_line=1;
- if (mysql_query(mysql,"show variables") ||
+ if (mysql_query(mysql,"show /*!40003 GLOBAL */ variables") ||
!(res=mysql_store_result(mysql)))
{
my_printf_error(0,"unable to show variables; error: '%s'",MYF(ME_BELL),
diff --git a/configure.in b/configure.in
index 90ee62059e6..144447d4cb6 100644
--- a/configure.in
+++ b/configure.in
@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
-AM_INIT_AUTOMAKE(mysql, 4.0.2-alpha)
+AM_INIT_AUTOMAKE(mysql, 4.0.3-beta)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
diff --git a/include/Makefile.am b/include/Makefile.am
index 0f135c64b53..ed2401df9ec 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -18,8 +18,8 @@
BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h
pkginclude_HEADERS = dbug.h m_string.h my_sys.h my_list.h \
mysql.h mysql_com.h mysqld_error.h mysql_embed.h \
- my_semaphore.h my_pthread.h my_no_pthread.h raid.h errmsg.h \
- my_global.h my_net.h my_alloc.h\
+ my_semaphore.h my_pthread.h my_no_pthread.h raid.h \
+ errmsg.h my_global.h my_net.h my_alloc.h\
sslopt-case.h sslopt-longopts.h sslopt-usage.h \
sslopt-vars.h $(BUILT_SOURCES)
noinst_HEADERS = config-win.h \
diff --git a/include/my_getopt.h b/include/my_getopt.h
index 3b50fbe2ded..3b4551b445e 100644
--- a/include/my_getopt.h
+++ b/include/my_getopt.h
@@ -49,4 +49,6 @@ extern int handle_options (int *argc, char ***argv,
extern void my_print_help(const struct my_option *options);
extern void my_print_variables(const struct my_option *options);
+ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp);
+my_bool getopt_compare_strings(const char *s, const char *t, uint length);
C_MODE_END
diff --git a/include/my_sys.h b/include/my_sys.h
index 664131e8187..b4a6570ca4b 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -494,18 +494,6 @@ my_off_t my_b_append_tell(IO_CACHE* info);
#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
*(info)->current_pos)
-typedef struct st_changeable_var
-{
- const char *name; /* Name of variable */
- long *varptr; /* Pointer to variable */
- long def_value, /* Default value */
- min_value, /* Min allowed value */
- max_value, /* Max allowed value */
- sub_size, /* Subtract this from given value */
- block_size; /* Value should be a mult. of this */
-} CHANGEABLE_VAR;
-
-
#include <my_alloc.h>
/* Prototypes for mysys and my_func functions */
@@ -647,7 +635,8 @@ extern int flush_write_cache(RECORD_CACHE *info);
extern long my_clock(void);
extern sig_handler sigtstp_handler(int signal_number);
extern void handle_recived_signals(void);
-extern int init_key_cache(ulong use_mem,ulong leave_this_much_mem);
+extern int init_key_cache(ulong use_mem);
+extern int resize_key_cache(ulong use_mem);
extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length,
uint block_length,int return_buffer);
extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length,
@@ -726,10 +715,6 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
extern my_bool dynstr_realloc(DYNAMIC_STRING *str, ulong additional_size);
extern void dynstr_free(DYNAMIC_STRING *str);
-void set_all_changeable_vars(CHANGEABLE_VAR *vars);
-my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars);
-my_bool set_changeable_varval(const char *var, ulong val,
- CHANGEABLE_VAR *vars);
#ifdef HAVE_MLOCK
extern byte *my_malloc_lock(uint length,myf flags);
extern void my_free_lock(byte *ptr,myf flags);
diff --git a/include/myisam.h b/include/myisam.h
index cd70292d283..ca70a99b3e3 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -237,7 +237,8 @@ extern int mi_create(const char *name,uint keys,MI_KEYDEF *keydef,
extern int mi_delete_table(const char *name);
extern int mi_rename(const char *from, const char *to);
extern int mi_extra(struct st_myisam_info *file,
- enum ha_extra_function function);
+ enum ha_extra_function function,
+ void *extra_arg);
extern ha_rows mi_records_in_range(struct st_myisam_info *info,int inx,
const byte *start_key,uint start_key_len,
enum ha_rkey_function start_search_flag,
@@ -251,9 +252,8 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
/* this is used to pass to mysql_myisamchk_table -- by Sasha Pachev */
-#define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r*/
-#define MYISAMCHK_VERIFY 2 /* run equivalent of myisamchk -c,
- * if corruption is detected, do myisamchk -r*/
+#define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r */
+#define MYISAMCHK_VERIFY 2 /* Verify, run repair if failure */
/*
Definitions needed for myisamchk.c
diff --git a/include/myisammrg.h b/include/myisammrg.h
index acf80ee2adf..c3b3b39424b 100644
--- a/include/myisammrg.h
+++ b/include/myisammrg.h
@@ -62,14 +62,15 @@ typedef struct st_myrg_table_info
typedef struct st_myrg_info
{
MYRG_TABLE *open_tables,*current_table,*end_table,*last_used_table;
- uint merge_insert_method;
ulonglong records; /* records in tables */
ulonglong del; /* Removed records */
ulonglong data_file_length;
+ ulong cache_size;
+ uint merge_insert_method;
uint tables,options,reclength,keys;
my_bool cache_in_use;
- LIST open_list;
- QUEUE by_key;
+ LIST open_list;
+ QUEUE by_key;
} MYRG_INFO;
@@ -93,7 +94,8 @@ extern int myrg_status(MYRG_INFO *file,MYMERGE_INFO *x,int flag);
extern int myrg_lock_database(MYRG_INFO *file,int lock_type);
extern int myrg_create(const char *name, const char **table_names,
uint insert_method, my_bool fix_names);
-extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function);
+extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function,
+ void *extra_arg);
extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv);
extern ha_rows myrg_records_in_range(MYRG_INFO *info,int inx,
const byte *start_key,uint start_key_len,
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 126324a9276..641c4b95f24 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -21,7 +21,6 @@
#ifndef _mysql_com_h
#define _mysql_com_h
-
#define NAME_LEN 64 /* Field/table name length */
#define HOSTNAME_LENGTH 60
#define USERNAME_LENGTH 16
@@ -115,9 +114,10 @@ typedef struct st_net {
Vio* vio;
unsigned char *buff,*buff_end,*write_pos,*read_pos;
my_socket fd; /* For Perl DBI/dbd */
- unsigned long max_packet;
+ unsigned long max_packet,max_packet_size;
+ unsigned int last_errno,pkt_nr,compress_pkt_nr;
+ unsigned int write_timeout,read_timeout;
int fcntl;
- unsigned int last_errno,timeout,pkt_nr,compress_pkt_nr;
char last_error[MYSQL_ERRMSG_SIZE];
unsigned char error;
my_bool return_errno,compress;
@@ -165,6 +165,7 @@ extern "C" {
#endif
int my_net_init(NET *net, Vio* vio);
+void my_net_local_init(NET *net);
void net_end(NET *net);
void net_clear(NET *net);
int net_flush(NET *net);
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
index 58a743771fa..bc75c3fbcb8 100644
--- a/include/mysql_embed.h
+++ b/include/mysql_embed.h
@@ -27,4 +27,8 @@
#undef HAVE_ISAM
#define DONT_USE_RAID
+
+#undef MYSQL_SERVER_SUFFIX
+#define MYSQL_SERVER_SUFFIX "-embedded"
+
#endif /* EMBEDDED_LIBRARY */
diff --git a/include/mysql_version.h.in b/include/mysql_version.h.in
index 44fd00f806a..5d738ce3326 100644
--- a/include/mysql_version.h.in
+++ b/include/mysql_version.h.in
@@ -3,6 +3,8 @@
/* Version numbers for protocol & mysqld */
+#ifndef _mysql_version_h
+#define _mysql_version_h
#ifdef _CUSTOMCONFIG_
#include <custom_conf.h>
#else
@@ -17,5 +19,6 @@
/* mysqld compile time options */
#ifndef MYSQL_CHARSET
#define MYSQL_CHARSET "@default_charset@"
-#endif
-#endif
+#endif /* MYSQL_CHARSET */
+#endif /* _CUSTOMCONFIG_ */
+#endif /* _mysql_version_h */
diff --git a/include/mysqld_error.h b/include/mysqld_error.h
index fa7ab07b046..dafee798416 100644
--- a/include/mysqld_error.h
+++ b/include/mysqld_error.h
@@ -244,4 +244,10 @@
#define ER_DUP_ARGUMENT 1225
#define ER_USER_LIMIT_REACHED 1226
#define ER_SPECIFIC_ACCESS_DENIED_ERROR 1227
-#define ER_ERROR_MESSAGES 228
+#define ER_LOCAL_VARIABLE 1228
+#define ER_GLOBAL_VARIABLE 1229
+#define ER_NO_DEFAULT 1230
+#define ER_WRONG_VALUE_FOR_VAR 1231
+#define ER_WRONG_TYPE_FOR_VAR 1232
+#define ER_VAR_CANT_BE_READ 1233
+#define ER_ERROR_MESSAGES 234
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 5f6d947bb92..b053724c0e3 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -1781,8 +1781,8 @@ char*
dict_scan_to(
/*=========*/
- char* ptr, /* in: scan from */
- char* string) /* in: look for this */
+ char* ptr, /* in: scan from */
+ const char *string) /* in: look for this */
{
ibool success;
ulint i;
@@ -1820,7 +1820,7 @@ dict_accept(
/* out: if string was accepted, the pointer
is moved after that, else ptr is returned */
char* ptr, /* in: scan from this */
- char* string, /* in: accept only this string as the next
+ const char* string, /* in: accept only this string as the next
non-whitespace string */
ibool* success)/* out: TRUE if accepted */
{
diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h
index 2d245e5f72f..09e0d800685 100644
--- a/innobase/include/ut0mem.h
+++ b/innobase/include/ut0mem.h
@@ -69,7 +69,7 @@ ut_strcpy(char* dest, char* sour);
UNIV_INLINE
ulint
-ut_strlen(char* str);
+ut_strlen(const char* str);
UNIV_INLINE
int
diff --git a/innobase/include/ut0mem.ic b/innobase/include/ut0mem.ic
index 7ae9bc8bd74..1049aee8ecc 100644
--- a/innobase/include/ut0mem.ic
+++ b/innobase/include/ut0mem.ic
@@ -36,7 +36,7 @@ ut_strcpy(char* dest, char* sour)
UNIV_INLINE
ulint
-ut_strlen(char* str)
+ut_strlen(const char* str)
{
return(strlen(str));
}
diff --git a/isam/isamchk.c b/isam/isamchk.c
index 23bded29f79..ea3055534ca 100644
--- a/isam/isamchk.c
+++ b/isam/isamchk.c
@@ -516,7 +516,7 @@ static int nisamchk(my_string filename)
if (!rep_quick)
{
if (testflag & T_EXTEND)
- VOID(init_key_cache(use_buffers,(uint) NEED_MEM));
+ VOID(init_key_cache(use_buffers));
VOID(init_io_cache(&read_cache,datafile,(uint) read_buffer_length,
READ_CACHE,share->pack.header_length,1,
MYF(MY_WME)));
@@ -1459,7 +1459,7 @@ my_string name;
printf("Data records: %lu\n",(ulong) share->state.records);
}
- VOID(init_key_cache(use_buffers,NEED_MEM));
+ VOID(init_key_cache(use_buffers));
if (init_io_cache(&read_cache,info->dfile,(uint) read_buffer_length,
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
goto err;
@@ -1936,7 +1936,7 @@ int write_info;
if (share->state.key_root[sort_key] == NI_POS_ERROR)
DBUG_RETURN(0); /* Nothing to do */
- init_key_cache(use_buffers,NEED_MEM);
+ init_key_cache(use_buffers);
if (init_io_cache(&info->rec_cache,-1,(uint) write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
diff --git a/isam/isamlog.c b/isam/isamlog.c
index 6d2bde42bf7..0367c03e08a 100644
--- a/isam/isamlog.c
+++ b/isam/isamlog.c
@@ -329,7 +329,7 @@ static int examine_log(my_string file_name, char **table_names)
bzero((gptr) com_count,sizeof(com_count));
init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
(tree_element_free) file_info_free, NULL);
- VOID(init_key_cache(KEY_CACHE_SIZE,(uint) (10*4*(IO_SIZE+MALLOC_OVERHEAD))));
+ VOID(init_key_cache(KEY_CACHE_SIZE));
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&
diff --git a/isam/test2.c b/isam/test2.c
index 176346e74fa..c8f97ccdefa 100644
--- a/isam/test2.c
+++ b/isam/test2.c
@@ -156,7 +156,7 @@ int main(int argc, char *argv[])
goto err;
printf("- Writing key:s\n");
if (key_cacheing)
- init_key_cache(IO_SIZE*16,(uint) IO_SIZE*4*10); /* Use a small cache */
+ init_key_cache(IO_SIZE*16); /* Use a small cache */
if (locking)
nisam_lock_database(file,F_WRLCK);
if (write_cacheing)
diff --git a/isam/test3.c b/isam/test3.c
index 6c3390a2720..7027c56d0f6 100644
--- a/isam/test3.c
+++ b/isam/test3.c
@@ -171,7 +171,7 @@ void start_test(int id)
exit(1);
}
if (key_cacheing && rnd(2) == 0)
- init_key_cache(65536L,(uint) IO_SIZE*4*10);
+ init_key_cache(65536L);
printf("Process %d, pid: %d\n",id,(int) getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am
index 2eaf9709a36..3d380c14076 100644
--- a/libmysql/Makefile.am
+++ b/libmysql/Makefile.am
@@ -17,9 +17,9 @@
# This file is public domain and comes with NO WARRANTY of any kind
-target = libmysqlclient.la
-target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -DMYSQL_CLIENT
-LIBS = @CLIENT_LIBS@
+target = libmysqlclient.la
+target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -DMYSQL_CLIENT
+LIBS = @CLIENT_LIBS@
INCLUDES = -I$(srcdir)/../include -I../include \
-I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes)
@@ -60,7 +60,9 @@ link_sources:
for f in $$ms $(mysysheaders); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../mysys/$$f $(srcdir)/$$f; \
- done;
+ done; \
+ rm -f $(srcdir)/net.c; \
+ @LN_CP_F@ $(srcdir)/../sql/net_serv.cc $(srcdir)/net.c
# This part requires GNUmake
#
@@ -77,7 +79,7 @@ nh = my_global.h config-win32.h dbug.h errmsg.h \
mysql.h mysql_com.h mysql_version.h mysqld_error.h \
mysys_err.h my_pthread.h thr_alarm.h violite.h hash.h
# Get a list of the needed objects
-lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects)
+lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects) $(sqlobjects)
do-lib-dist:
dir=libmysql-$(MYSQL_NO_DASH_VERSION); \
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 1e36a74ab12..87f9fe42a3c 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -31,8 +31,8 @@ noinst_PROGRAMS = conf_to_src
CHARSET_OBJS=@CHARSET_OBJS@
LTCHARSET_OBJS= ${CHARSET_OBJS:.o=.lo}
-target_sources = libmysql.c net.c password.c manager.c \
- get_password.c errmsg.c
+target_sources = libmysql.c password.c manager.c \
+ get_password.c errmsg.c
mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
strmake.lo strend.lo \
@@ -60,12 +60,13 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
mf_iocache2.lo my_seek.lo \
my_pread.lo mf_cache.lo my_vsnprintf.lo md5.lo \
my_getopt.lo my_gethostbyname.lo
+sqlobjects = net.lo
# Not needed in the minimum library
mysysobjects2 = my_lib.lo
mysysobjects = $(mysysobjects1) $(mysysobjects2)
target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
- $(vio_objects)
+ $(vio_objects) $(sqlobjects)
target_ldflags = -version-info @SHARED_LIB_VERSION@
vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
@@ -84,7 +85,7 @@ clean-local:
`echo $(mysysobjects) | sed "s;\.lo;.c;g"` \
`echo $(vio_objects) | sed "s;\.lo;.c;g"` \
$(mystringsextra) $(mysysheaders) ctype_extra_sources.c \
- ../linked_client_sources
+ net.c ../linked_client_sources
ctype_extra_sources.c: conf_to_src
./conf_to_src $(top_srcdir) @CHARSETS_NEED_SOURCE@ > \
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index fa505063deb..458e5db24d5 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -59,6 +59,10 @@
static my_bool mysql_client_init=0;
uint mysql_port=0;
my_string mysql_unix_port=0;
+ulong net_buffer_length=8192;
+ulong max_allowed_packet=16*1024*1024L;
+ulong net_read_timeout= NET_READ_TIMEOUT;
+ulong net_write_timeout= NET_WRITE_TIMEOUT;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)
@@ -2890,6 +2894,18 @@ uint STDCALL mysql_thread_safe(void)
****************************************************************************/
/*
+ Functions called my my_net_init() to set some application specific variables
+*/
+
+void my_net_local_init(NET *net)
+{
+ net->max_packet= (uint) net_buffer_length;
+ net->read_timeout= (uint) net_read_timeout;
+ net->write_timeout=(uint) net_write_timeout;
+ net->max_packet_size= max(net_buffer_length, max_allowed_packet);
+}
+
+/*
Add escape characters to a string (blob?) to make it suitable for a insert
to should at least have place for length*2+1 chars
Returns the length of the to string
diff --git a/libmysql/net.c b/libmysql/net.c
deleted file mode 100644
index 0d6e548a873..00000000000
--- a/libmysql/net.c
+++ /dev/null
@@ -1,826 +0,0 @@
-/* Copyright (C) 2000 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Write and read of logical packets to/from socket
-** Writes are cached into net_buffer_length big packets.
-** Read packets are reallocated dynamicly when reading big packets.
-** Each logical packet has the following pre-info:
-** 3 byte length & 1 byte package-number.
-*/
-
-#ifdef EMBEDDED_LIBRARY
-#define net_read_timeout net_read_timeout1
-#define net_write_timeout net_write_timeout1
-#endif
-
-#ifdef __WIN__
-#include <winsock.h>
-#endif
-#include <my_global.h>
-#include <mysql.h>
-#include <mysql_embed.h>
-#include <mysql_com.h>
-#include <mysqld_error.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include <my_net.h>
-#include <violite.h>
-#include <signal.h>
-#include <errno.h>
-
-/*
- The following handles the differences when this is linked between the
- client and the server.
-
- This gives an error if a too big packet is found
- The server can change this with the -O switch, but because the client
- can't normally do this the client should have a bigger max_allowed_packet.
-*/
-
-#ifdef MYSQL_SERVER
-ulong max_allowed_packet=65536;
-extern ulong net_read_timeout,net_write_timeout;
-extern uint test_flags;
-#define USE_QUERY_CACHE
-extern void query_cache_insert(NET *net, const char *packet, ulong length);
-#else
-ulong max_allowed_packet=16*1024*1024L;
-ulong net_read_timeout= NET_READ_TIMEOUT;
-ulong net_write_timeout= NET_WRITE_TIMEOUT;
-#endif
-
-#if defined(__WIN__) || !defined(MYSQL_SERVER)
- /* The following is because alarms doesn't work on windows. */
-#define NO_ALARM
-#endif
-
-#ifndef NO_ALARM
-#include "my_pthread.h"
-void sql_print_error(const char *format,...);
-#define RETRY_COUNT mysqld_net_retry_count
-extern ulong mysqld_net_retry_count;
-extern ulong bytes_sent, bytes_received;
-extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
-#else
-#undef statistic_add
-#define statistic_add(A,B,C)
-#define DONT_USE_THR_ALARM
-#define RETRY_COUNT 1
-#endif /* NO_ALARM */
-
-#include "thr_alarm.h"
-
-#define TEST_BLOCKING 8
-#define MAX_THREE_BYTES 255L*255L*255L
-
-ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */
-
-static int net_write_buff(NET *net,const char *packet,ulong len);
-
-
- /* Init with packet info */
-
-int my_net_init(NET *net, Vio* vio)
-{
- if (!(net->buff=(uchar*) my_malloc((uint32) net_buffer_length+
- NET_HEADER_SIZE + COMP_HEADER_SIZE,
- MYF(MY_WME))))
- return 1;
- if (net_buffer_length > max_allowed_packet)
- max_allowed_packet=net_buffer_length;
- net->buff_end=net->buff+(net->max_packet=net_buffer_length);
- net->vio = vio;
- net->no_send_ok = 0;
- net->error=0; net->return_errno=0; net->return_status=0;
- net->timeout=(uint) net_read_timeout; /* Timeout for read */
- net->pkt_nr=net->compress_pkt_nr=0;
- net->write_pos=net->read_pos = net->buff;
- net->last_error[0]=0;
- net->compress=0; net->reading_or_writing=0;
- net->where_b = net->remain_in_buf=0;
- net->last_errno=0;
- net->query_cache_query=0;
-
- if (vio != 0) /* If real connection */
- {
- net->fd = vio_fd(vio); /* For perl DBI/DBD */
-#if defined(MYSQL_SERVER) && !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
- if (!(test_flags & TEST_BLOCKING))
- vio_blocking(vio, FALSE);
-#endif
- vio_fastsend(vio);
- }
- return 0;
-}
-
-void net_end(NET *net)
-{
- my_free((gptr) net->buff,MYF(MY_ALLOW_ZERO_PTR));
- net->buff=0;
-}
-
-/* Realloc the packet buffer */
-
-static my_bool net_realloc(NET *net, ulong length)
-{
- uchar *buff;
- ulong pkt_length;
- if (length >= max_allowed_packet)
- {
- DBUG_PRINT("error",("Packet too large (%lu)", length));
- net->error=1;
- net->last_errno=ER_NET_PACKET_TOO_LARGE;
- return 1;
- }
- pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
- /* We must allocate some extra bytes for the end 0 and to be able to
- read big compressed blocks */
- if (!(buff=(uchar*) my_realloc((char*) net->buff, (uint32) pkt_length +
- NET_HEADER_SIZE + COMP_HEADER_SIZE,
- MYF(MY_WME))))
- {
- net->error=1;
-#ifdef MYSQL_SERVER
- net->last_errno=ER_OUT_OF_RESOURCES;
-#endif
- return 1;
- }
- net->buff=net->write_pos=buff;
- net->buff_end=buff+(net->max_packet=pkt_length);
- return 0;
-}
-
- /* Remove unwanted characters from connection */
-
-void net_clear(NET *net)
-{
-#if !defined(EXTRA_DEBUG) && !defined(EMBEDDED_LIBRARY)
- int count; /* One may get 'unused' warn */
- bool is_blocking=vio_is_blocking(net->vio);
- if (is_blocking)
- vio_blocking(net->vio, FALSE);
- if (!vio_is_blocking(net->vio)) /* Safety if SSL */
- {
- while ( (count = vio_read(net->vio, (char*) (net->buff),
- (uint32) net->max_packet)) > 0)
- DBUG_PRINT("info",("skipped %d bytes from file: %s",
- count,vio_description(net->vio)));
- if (is_blocking)
- vio_blocking(net->vio, TRUE);
- }
-#endif /* EXTRA_DEBUG */
- net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */
- net->write_pos=net->buff;
-}
-
- /* Flush write_buffer if not empty. */
-
-int net_flush(NET *net)
-{
- int error=0;
- DBUG_ENTER("net_flush");
- if (net->buff != net->write_pos)
- {
- error=net_real_write(net,(char*) net->buff,
- (ulong) (net->write_pos - net->buff));
- net->write_pos=net->buff;
- }
- /* Sync packet number if using compression */
- if (net->compress)
- net->pkt_nr=net->compress_pkt_nr;
- DBUG_RETURN(error);
-}
-
-
-/*****************************************************************************
-** Write something to server/client buffer
-*****************************************************************************/
-
-/*
-** Write a logical packet with packet header
-** Format: Packet length (3 bytes), packet number(1 byte)
-** When compression is used a 3 byte compression length is added
-** NOTE: If compression is used the original package is modified!
-*/
-
-int
-my_net_write(NET *net,const char *packet,ulong len)
-{
- uchar buff[NET_HEADER_SIZE];
- /*
- Big packets are handled by splitting them in packets of MAX_THREE_BYTES
- length. The last packet is always a packet that is < MAX_THREE_BYTES.
- (The last packet may even have a lengt of 0)
- */
- while (len >= MAX_THREE_BYTES)
- {
- const ulong z_size = MAX_THREE_BYTES;
- int3store(buff, z_size);
- buff[3]= (uchar) net->pkt_nr++;
- if (net_write_buff(net, (char*) buff, NET_HEADER_SIZE) ||
- net_write_buff(net, packet, z_size))
- return 1;
- packet += z_size;
- len-= z_size;
- }
- /* Write last packet */
- int3store(buff,len);
- buff[3]= (uchar) net->pkt_nr++;
- if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE))
- return 1;
- return net_write_buff(net,packet,len);
-}
-
-/*
- Send a command to the server.
- As the command is part of the first data packet, we have to do some data
- juggling to put the command in there, without having to create a new
- packet.
- This function will split big packets into sub-packets if needed.
- (Each sub packet can only be 2^24 bytes)
-*/
-
-int
-net_write_command(NET *net,uchar command,const char *packet,ulong len)
-{
- ulong length=len+1; /* 1 extra byte for command */
- uchar buff[NET_HEADER_SIZE+1];
- uint header_size=NET_HEADER_SIZE+1;
- buff[4]=command; /* For first packet */
-
- if (length >= MAX_THREE_BYTES)
- {
- /* Take into account that we have the command in the first header */
- len= MAX_THREE_BYTES -1;
- do
- {
- int3store(buff, MAX_THREE_BYTES);
- buff[3]= (uchar) net->pkt_nr++;
- if (net_write_buff(net,(char*) buff, header_size) ||
- net_write_buff(net,packet,len))
- return 1;
- packet+= len;
- length-= MAX_THREE_BYTES;
- len=MAX_THREE_BYTES;
- header_size=NET_HEADER_SIZE;
- } while (length >= MAX_THREE_BYTES);
- len=length; /* Data left to be written */
- }
- int3store(buff,length);
- buff[3]= (uchar) net->pkt_nr++;
- return test(net_write_buff(net,(char*) buff,header_size) ||
- net_write_buff(net,packet,len) || net_flush(net));
-}
-
-/*
- Caching the data in a local buffer before sending it.
- One can force the buffer to be flushed with 'net_flush'.
-*/
-
-static int
-net_write_buff(NET *net,const char *packet,ulong len)
-{
- ulong left_length=(ulong) (net->buff_end - net->write_pos);
-
- while (len > left_length)
- {
- memcpy((char*) net->write_pos,packet,left_length);
- if (net_real_write(net,(char*) net->buff,net->max_packet))
- return 1;
- net->write_pos=net->buff;
- packet+=left_length;
- len-=left_length;
- left_length=net->max_packet;
- }
- memcpy((char*) net->write_pos,packet,len);
- net->write_pos+=len;
- return 0;
-}
-
-
-/*
- Read and write one packet using timeouts.
- If needed, the packet is compressed before sending.
-*/
-
-int
-net_real_write(NET *net,const char *packet,ulong len)
-{
- long int length;
- char *pos,*end;
- thr_alarm_t alarmed;
-#ifndef NO_ALARM
- ALARM alarm_buff;
-#endif
- uint retry_count=0;
- my_bool net_blocking = vio_is_blocking(net->vio);
- DBUG_ENTER("net_real_write");
-
-#if defined(MYSQL_SERVER) && defined(HAVE_QUERY_CACHE)
- if (net->query_cache_query != 0)
- query_cache_insert(net, packet, len);
-#endif
-
- if (net->error == 2)
- DBUG_RETURN(-1); /* socket can't be used */
-
- net->reading_or_writing=2;
-#ifdef HAVE_COMPRESS
- if (net->compress)
- {
- ulong complen;
- uchar *b;
- uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
- if (!(b=(uchar*) my_malloc((uint32) len + NET_HEADER_SIZE +
- COMP_HEADER_SIZE, MYF(MY_WME))))
- {
-#ifdef MYSQL_SERVER
- net->last_errno=ER_OUT_OF_RESOURCES;
- net->error=2;
-#endif
- net->reading_or_writing=0;
- DBUG_RETURN(1);
- }
- memcpy(b+header_length,packet,len);
-
- if (my_compress((byte*) b+header_length,&len,&complen))
- {
- DBUG_PRINT("warning",
- ("Compression error; Continuing without compression"));
- complen=0;
- }
- int3store(&b[NET_HEADER_SIZE],complen);
- int3store(b,len);
- b[3]=(uchar) (net->compress_pkt_nr++);
- len+= header_length;
- packet= (char*) b;
- }
-#endif /* HAVE_COMPRESS */
-
- /* DBUG_DUMP("net",packet,len); */
-#ifndef NO_ALARM
- thr_alarm_init(&alarmed);
- if (net_blocking)
- thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff);
-#else
- alarmed=0;
-#endif /* NO_ALARM */
-
- pos=(char*) packet; end=pos+len;
- while (pos != end)
- {
- if ((long) (length=vio_write(net->vio,pos,(uint32) (end-pos))) <= 0)
- {
- my_bool interrupted = vio_should_retry(net->vio);
-#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2))
- if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed))
- {
- if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff))
- { /* Always true for client */
- if (!vio_is_blocking(net->vio))
- {
- while (vio_blocking(net->vio, TRUE) < 0)
- {
- if (vio_should_retry(net->vio) && retry_count++ < RETRY_COUNT)
- continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr,
- "%s: my_net_write: fcntl returned error %d, aborting thread\n",
- my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
- net->error=2; /* Close socket */
- goto end;
- }
- }
- retry_count=0;
- continue;
- }
- }
- else
-#endif /* (!defined(__WIN__) && !defined(__EMX__)) */
- if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
- interrupted)
- {
- if (retry_count++ < RETRY_COUNT)
- continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr, "%s: write looped, aborting thread\n",
- my_progname);
-#endif /* EXTRA_DEBUG */
- }
-#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
- if (vio_errno(net->vio) == SOCKET_EINTR)
- {
- DBUG_PRINT("warning",("Interrupted write. Retrying..."));
- continue;
- }
-#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
- net->error=2; /* Close socket */
-#ifdef MYSQL_SERVER
- net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
- ER_NET_ERROR_ON_WRITE);
-#endif /* MYSQL_SERVER */
- break;
- }
- pos+=length;
- statistic_add(bytes_sent,length,&LOCK_bytes_sent);
- }
-#ifndef __WIN__
- end:
-#endif
-#ifdef HAVE_COMPRESS
- if (net->compress)
- my_free((char*) packet,MYF(0));
-#endif
- if (thr_alarm_in_use(&alarmed))
- {
- thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking);
- }
- net->reading_or_writing=0;
- DBUG_RETURN(((int) (pos != end)));
-}
-
-
-/*****************************************************************************
-** Read something from server/clinet
-*****************************************************************************/
-
-#ifndef NO_ALARM
-/*
- Help function to clear the commuication buffer when we get a too
- big packet
-*/
-
-static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed)
-{
- ALARM alarm_buff;
- uint retry_count=0;
- if (!thr_alarm_in_use(&alarmed))
- {
- if (!thr_alarm(alarmed,net->timeout,&alarm_buff) ||
- (!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0))
- return; /* Can't setup, abort */
- }
- while (remain > 0)
- {
- ulong length;
- if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L)
- {
- my_bool interrupted = vio_should_retry(net->vio);
- if (!thr_got_alarm(&alarmed) && interrupted)
- { /* Probably in MIT threads */
- if (retry_count++ < RETRY_COUNT)
- continue;
- }
- return;
- }
- remain -= (uint32) length;
- statistic_add(bytes_received,length,&LOCK_bytes_received);
- }
-}
-#endif /* NO_ALARM */
-
-
-/*
- Reads one packet to net->buff + net->where_b
- Returns length of packet. Long packets are handled by my_net_read().
- This function reallocates the net->buff buffer if necessary.
-*/
-
-static ulong
-my_real_read(NET *net, ulong *complen)
-{
- uchar *pos;
- long length;
- uint i,retry_count=0;
- ulong len=packet_error;
- thr_alarm_t alarmed;
-#ifndef NO_ALARM
- ALARM alarm_buff;
-#endif
- my_bool net_blocking=vio_is_blocking(net->vio);
- uint32 remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
- NET_HEADER_SIZE);
- *complen = 0;
-
- net->reading_or_writing=1;
- thr_alarm_init(&alarmed);
-#ifndef NO_ALARM
- if (net_blocking)
- thr_alarm(&alarmed,net->timeout,&alarm_buff);
-#endif /* NO_ALARM */
-
- pos = net->buff + net->where_b; /* net->packet -4 */
- for (i=0 ; i < 2 ; i++)
- {
- while (remain > 0)
- {
- /* First read is done with non blocking mode */
- if ((int) (length=vio_read(net->vio,(char*) pos,remain)) <= 0L)
- {
- my_bool interrupted = vio_should_retry(net->vio);
-
- DBUG_PRINT("info",("vio_read returned %d, errno: %d",
- length, vio_errno(net->vio)));
-#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
- /*
- We got an error that there was no data on the socket. We now set up
- an alarm to not 'read forever', change the socket to non blocking
- mode and try again
- */
- if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
- {
- if (!thr_alarm(&alarmed,net->timeout,&alarm_buff)) /* Don't wait too long */
- {
- if (!vio_is_blocking(net->vio))
- {
- while (vio_blocking(net->vio,TRUE) < 0)
- {
- if (vio_should_retry(net->vio) &&
- retry_count++ < RETRY_COUNT)
- continue;
- DBUG_PRINT("error",
- ("fcntl returned error %d, aborting thread",
- vio_errno(net->vio)));
-#ifdef EXTRA_DEBUG
- fprintf(stderr,
- "%s: read: fcntl returned error %d, aborting thread\n",
- my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
- len= packet_error;
- net->error=2; /* Close socket */
-#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_FCNTL_ERROR;
-#endif
- goto end;
- }
- }
- retry_count=0;
- continue;
- }
- }
-#endif /* (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER) */
- if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
- interrupted)
- { /* Probably in MIT threads */
- if (retry_count++ < RETRY_COUNT)
- continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
- my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
- }
-#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
- if (vio_should_retry(net->vio))
- {
- DBUG_PRINT("warning",("Interrupted read. Retrying..."));
- continue;
- }
-#endif
- DBUG_PRINT("error",("Couldn't read packet: remain: %lu errno: %d length: %ld alarmed: %d", remain,vio_errno(net->vio),length,alarmed));
- len= packet_error;
- net->error=2; /* Close socket */
-#ifdef MYSQL_SERVER
- net->last_errno= (interrupted ? ER_NET_READ_INTERRUPTED :
- ER_NET_READ_ERROR);
-#endif
- goto end;
- }
- remain -= (uint32) length;
- pos+= (ulong) length;
- statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
- }
- if (i == 0)
- { /* First parts is packet length */
- ulong helping;
- if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
- {
- if (net->buff[net->where_b] != (uchar) 255)
- {
- DBUG_PRINT("error",
- ("Packets out of order (Found: %d, expected %u)",
- (int) net->buff[net->where_b + 3],
- net->pkt_nr));
-#ifdef EXTRA_DEBUG
- fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n",
- (int) net->buff[net->where_b + 3],
- (uint) (uchar) net->pkt_nr);
-#endif
- }
- len= packet_error;
-#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER;
-#endif
- goto end;
- }
- net->compress_pkt_nr= ++net->pkt_nr;
-#ifdef HAVE_COMPRESS
- if (net->compress)
- {
- /* complen is > 0 if package is really compressed */
- *complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
- }
-#endif
-
- len=uint3korr(net->buff+net->where_b);
- if (!len) /* End of big multi-packet */
- goto end;
- helping = max(len,*complen) + net->where_b;
- /* The necessary size of net->buff */
- if (helping >= net->max_packet)
- {
- if (net_realloc(net,helping))
- {
-#ifndef NO_ALARM
- if (i == 1)
- my_net_skip_rest(net, (uint32) len, &alarmed);
-#endif
- len= packet_error; /* Return error */
- goto end;
- }
- }
- pos=net->buff + net->where_b;
- remain = (uint32) len;
- }
- }
-
-end:
- if (thr_alarm_in_use(&alarmed))
- {
- thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking);
- }
- net->reading_or_writing=0;
- return(len);
-}
-
-
-/*
- Read a packet from the client/server and return it without the internal
- package header.
- If the packet is the first packet of a multi-packet packet
- (which is indicated by the length of the packet = 0xffffff) then
- all sub packets are read and concatenated.
- If the packet was compressed, its uncompressed and the length of the
- uncompressed packet is returned.
-
- The function returns the length of the found packet or packet_error.
- net->read_pos points to the read data.
-*/
-
-ulong
-my_net_read(NET *net)
-{
- ulong len,complen;
-
-#ifdef HAVE_COMPRESS
- if (!net->compress)
- {
-#endif
- len = my_real_read(net,&complen);
- if (len == MAX_THREE_BYTES)
- {
- /* First packet of a multi-packet. Concatenate the packets */
- ulong save_pos = net->where_b;
- ulong total_length=0;
- do
- {
- net->where_b += len;
- total_length += len;
- len = my_real_read (net,&complen);
- } while (len == MAX_THREE_BYTES);
- if (len != packet_error)
- len+= total_length;
- net->where_b = save_pos;
- }
- net->read_pos = net->buff + net->where_b;
- if (len != packet_error)
- net->read_pos[len]=0; /* Safeguard for mysql_use_result */
- return len;
-#ifdef HAVE_COMPRESS
- }
- else
- {
- /* We are using the compressed protocol */
-
- ulong buf_length= net->buf_length;
- ulong start_of_packet= net->buf_length - net->remain_in_buf;
- ulong first_packet_offset=start_of_packet;
- uint read_length, multi_byte_packet=0;
-
- if (net->remain_in_buf)
- {
- /* Restore the character that was overwritten by the end 0 */
- net->buff[start_of_packet]=net->save_char;
- }
- else
- {
- /* reuse buffer, as there is noting in it that we need */
- buf_length=start_of_packet=first_packet_offset=0;
- }
- for (;;)
- {
- ulong packet_len;
-
- if (buf_length - start_of_packet >= NET_HEADER_SIZE)
- {
- read_length = uint3korr(net->buff+start_of_packet);
- if (!read_length)
- {
- /* End of multi-byte packet */
- start_of_packet += NET_HEADER_SIZE;
- break;
- }
- if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
- {
- if (multi_byte_packet)
- {
- /* Remove packet header for second packet */
- memmove(net->buff + first_packet_offset + start_of_packet,
- net->buff + first_packet_offset + start_of_packet +
- NET_HEADER_SIZE,
- buf_length - start_of_packet);
- start_of_packet += read_length;
- buf_length -= NET_HEADER_SIZE;
- }
- else
- start_of_packet+= read_length + NET_HEADER_SIZE;
-
- if (read_length != MAX_THREE_BYTES) /* last package */
- {
- multi_byte_packet= 0; /* No last zero len packet */
- break;
- }
- multi_byte_packet= NET_HEADER_SIZE;
- /* Move data down to read next data packet after current one */
- if (first_packet_offset)
- {
- memmove(net->buff,net->buff+first_packet_offset,
- buf_length-first_packet_offset);
- buf_length-=first_packet_offset;
- start_of_packet -= first_packet_offset;
- first_packet_offset=0;
- }
- continue;
- }
- }
- /* Move data down to read next data packet after current one */
- if (first_packet_offset)
- {
- memmove(net->buff,net->buff+first_packet_offset,
- buf_length-first_packet_offset);
- buf_length-=first_packet_offset;
- start_of_packet -= first_packet_offset;
- first_packet_offset=0;
- }
-
- net->where_b=buf_length;
- if ((packet_len = my_real_read(net,&complen)) == packet_error)
- return packet_error;
- if (my_uncompress((byte*) net->buff + net->where_b, &packet_len,
- &complen))
- {
- net->error=2; /* caller will close socket */
-#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_UNCOMPRESS_ERROR;
-#endif
- return packet_error;
- }
- buf_length+=packet_len;
- }
-
- net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
- net->buf_length= buf_length;
- net->remain_in_buf= (ulong) (buf_length - start_of_packet);
- len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
- multi_byte_packet);
- net->save_char= net->read_pos[len]; /* Must be saved */
- net->read_pos[len]=0; /* Safeguard for mysql_use_result */
- }
-#endif /* HAVE_COMPRESS */
- return len;
-}
-
-int net_request_file(NET* net, const char* fname)
-{
- char tmp [FN_REFLEN+1],*end;
- DBUG_ENTER("net_request_file");
- tmp[0] = (char) 251; /* NULL_LENGTH */
- end=strnmov(tmp+1,fname,sizeof(tmp)-2);
- DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) ||
- net_flush(net));
-}
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index edee13c98bb..4b2b8dcb31c 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -32,7 +32,7 @@ INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(srcdir)/../include \
noinst_LIBRARIES = libmysqld_int.a
pkglib_LIBRARIES = libmysqld.a
SUBDIRS = . examples
-libmysqld_sources= libmysqld.c lib_sql.cc lib_load.cc
+libmysqld_sources= libmysqld.c lib_sql.cc
libmysqlsources = errmsg.c get_password.c password.c
noinst_HEADERS = embedded_priv.h
@@ -46,10 +46,10 @@ sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \
item_uniq.cc key.cc lock.cc log.cc log_event.cc mf_iocache.cc\
mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \
opt_sum.cc procedure.cc records.cc sql_acl.cc \
- repl_failsafe.cc slave.cc \
+ repl_failsafe.cc slave.cc sql_load.cc \
sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
sql_crypt.cc sql_db.cc sql_delete.cc sql_insert.cc sql_lex.cc \
- sql_list.cc sql_manager.cc sql_map.cc sql_parse.cc \
+ sql_list.cc sql_manager.cc sql_map.cc set_var.cc sql_parse.cc \
sql_rename.cc sql_repl.cc sql_select.cc sql_do.cc sql_show.cc \
sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h
index 96d2c96ed0b..e17b72e84d8 100644
--- a/libmysqld/embedded_priv.h
+++ b/libmysqld/embedded_priv.h
@@ -17,9 +17,8 @@
/* Prototypes for the embedded version of MySQL */
#include <my_global.h>
-#include <mysql_embed.h>
#include <mysql.h>
-#include <mysql_version.h>
+#include <mysql_embed.h>
#include <mysqld_error.h>
#include <my_pthread.h>
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 60f0c74859b..d461c46d604 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -11,11 +11,9 @@
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
- */
-#include "embedded_priv.h"
-#include "sys/types.h"
-#include "../regex/regex.h"
-#include "my_sys.h"
+
+ This code was modified by the MySQL team
+*/
/*
The following is needed to not cause conflicts when we include mysqld.cc
@@ -24,26 +22,6 @@
#define main main1
#define mysql_unix_port mysql_inix_port1
#define mysql_port mysql_port1
-#define net_read_timeout net_read_timeout1
-#define net_write_timeout net_write_timeout1
-#define changeable_vars changeable_vars1
-
-extern "C"
-{
-#include "mysql_com.h"
-#include "lib_vio.c"
-}
-
-
-class THD;
-
-static int check_connections1(THD * thd);
-static int check_connections2(THD * thd);
-static bool check_user(THD *thd, enum_server_command command,
- const char *user, const char *passwd, const char *db,
- bool check_count);
-void free_defaults_internal(char ** argv) {if (argv) free_defaults(argv);}
-#define free_defaults free_defaults_internal
#if defined (__WIN__)
#include "../sql/mysqld.cpp"
@@ -53,11 +31,16 @@ void free_defaults_internal(char ** argv) {if (argv) free_defaults(argv);}
#define SCRAMBLE_LENGTH 8
C_MODE_START
+#include "lib_vio.c"
+static int check_connections1(THD * thd);
+static int check_connections2(THD * thd);
+static bool check_user(THD *thd, enum_server_command command,
+ const char *user, const char *passwd, const char *db,
+ bool check_count);
char * get_mysql_home(){ return mysql_home;};
char * get_mysql_real_data_home(){ return mysql_real_data_home;};
-
bool lib_dispatch_command(enum enum_server_command command, NET *net,
const char *arg, ulong length)
{
@@ -117,7 +100,7 @@ void start_embedded_conn1(NET * net)
thd->dbug_thread_id=my_thread_id();
thd->thread_stack= (char*) &thd;
- if (thd->max_join_size == HA_POS_ERROR)
+ if (thd->variables.max_join_size == (ulong) HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
thd->proc_info=0; // Remove 'login'
@@ -206,12 +189,12 @@ check_connections2(THD * thd)
#endif
if (connect_errors)
reset_host_errors(&thd->remote.sin_addr);
- if (thd->packet.alloc(net_buffer_length))
+ if (thd->packet.alloc(thd->variables.net_buffer_length))
return(ER_OUT_OF_RESOURCES);
thd->client_capabilities=uint2korr(net->read_pos);
- thd->max_packet_length=uint3korr(net->read_pos+2);
+ thd->max_client_packet_length=uint3korr(net->read_pos+2);
char *user= (char*) net->read_pos+5;
char *passwd= strend(user)+1;
char *db=0;
@@ -219,11 +202,9 @@ check_connections2(THD * thd)
return ER_HANDSHAKE_ERROR;
if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
db=strend(passwd)+1;
- if (thd->client_capabilities & CLIENT_INTERACTIVE)
- thd->inactive_timeout= thd->variables.net_interactive_timeout;
if (thd->client_capabilities & CLIENT_TRANSACTIONS)
thd->net.return_status= &thd->server_status;
- net->timeout=net_read_timeout;
+ net->read_timeout=thd->variables.net_read_timeout;
if (check_user(thd,COM_CONNECT, user, passwd, db, 1))
return (-1);
thd->password=test(passwd[0]);
@@ -249,7 +230,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
CLIENT_LONG_PASSWORD),&ur);
DBUG_PRINT("info",
("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
- thd->client_capabilities, thd->max_packet_length,
+ thd->client_capabilities, thd->max_client_packet_length,
thd->host_or_ip, thd->priv_user,
passwd[0] ? "yes": "no",
thd->master_access, thd->db ? thd->db : "*none*"));
@@ -297,6 +278,7 @@ extern "C"
{
static my_bool inited, org_my_init_done;
+ulong max_allowed_packet, net_buffer_length;
int STDCALL mysql_server_init(int argc, char **argv, char **groups)
{
@@ -358,20 +340,24 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
strmov(glob_hostname,"mysql");
#ifndef DBUG_OFF
- strcat(server_version,"-debug");
+ strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
+#else
+ strmov(strend(server_version),MYSQL_SERVER_SUFFIX);
#endif
- strcat(server_version,"-embedded");
load_defaults("my", (const char **) groups, argcp, argvp);
defaults_argv=*argvp;
- mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
+
+ /* Get default temporary directory */
+ opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
#if defined( __WIN__) || defined(OS2)
- if (!mysql_tmpdir)
- mysql_tmpdir=getenv("TEMP");
- if (!mysql_tmpdir)
- mysql_tmpdir=getenv("TMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TEMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TMP");
#endif
- if (!mysql_tmpdir || !mysql_tmpdir[0])
- mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
+ if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
+ opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
+
set_options();
get_options(*argcp, *argvp);
@@ -398,15 +384,19 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
(void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_server_id, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
(void) pthread_cond_init(&COND_thread_count,NULL);
(void) pthread_cond_init(&COND_refresh,NULL);
(void) pthread_cond_init(&COND_thread_cache,NULL);
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
(void) pthread_cond_init(&COND_manager,NULL);
- (void) pthread_cond_init(&COND_binlog_update, NULL);
+ (void) pthread_cond_init(&COND_rpl_status, NULL);
- if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
+ if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME)))
{
mysql_server_end();
return 1;
@@ -420,13 +410,15 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
pthread_attr_setstacksize(&connection_attrib,thread_stack);
pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
-#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
- /* connections and databases neads lots of files */
+#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
+ /* connections and databases needs lots of files */
{
uint wanted_files=10+(uint) max(max_connections*5,
max_connections+table_cache_size*2);
+ set_if_bigger(wanted_files, open_files_limit);
+ // Note that some system returns 0 if we succeed here:
uint files=set_maximum_open_files(wanted_files);
- if (files && files < wanted_files) // Some systems return 0
+ if (files && files < wanted_files && ! open_files_limit)
{
max_connections= (ulong) min((files-10),max_connections);
table_cache_size= (ulong) max((files-10-max_connections)/2,64);
@@ -441,6 +433,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
init_errmessage(); /* Read error messages from file */
lex_init();
item_init();
+ set_var_init();
mysys_uses_curses=0;
#ifdef USE_REGEX
regex_init();
@@ -452,12 +445,13 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
}
/*
- ** We have enough space for fiddling with the argv, continue
+ We have enough space for fiddling with the argv, continue
*/
umask(((~my_umask) & 0666));
table_cache_init();
hostname_cache_init();
- /*sql_cache_init();*/
+ query_cache_result_size_limit(query_cache_limit);
+ query_cache_resize(query_cache_size);
randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
reset_floating_point_exceptions();
init_thr_lock();
@@ -472,20 +466,6 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
LOG_NEW);
using_update_log=1;
}
- if (opt_bin_log)
- {
- if (!opt_bin_logname)
- {
- char tmp[FN_REFLEN];
- strmake(tmp,glob_hostname,FN_REFLEN-5);
- strmov(strcend(tmp,'.'),"-bin");
- opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
- }
- mysql_bin_log.set_index_file_name(opt_binlog_index_name);
- open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
- LOG_BIN);
- using_update_log=1;
- }
if (opt_slow_log)
open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
@@ -496,10 +476,9 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
exit(1);
}
ha_key_cache();
-#ifdef HAVE_MLOCKALL
+#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
if (locked_in_memory && !geteuid())
{
- ha_key_cache();
if (mlockall(MCL_CURRENT))
{
sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno);
@@ -513,7 +492,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
if (opt_myisam_log)
(void) mi_log( 1 );
- ft_init_stopwords(ft_precompiled_stopwords); /* SerG */
+ ft_init_stopwords(ft_precompiled_stopwords);
/*
init signals & alarm
@@ -532,12 +511,33 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
mysql_server_end();
return 1;
}
+ if (!opt_noacl)
+ (void) grant_init();
+ init_max_user_conn();
#ifdef HAVE_DLOPEN
if (!opt_noacl)
udf_init();
#endif
+ if (opt_bin_log)
+ {
+ if (!opt_bin_logname)
+ {
+ char tmp[FN_REFLEN];
+ /* TODO: The following should be using fn_format(); We just need to
+ first change fn_format() to cut the file name if it's too long.
+ */
+ strmake(tmp,glob_hostname,FN_REFLEN-5);
+ strmov(strcend(tmp,'.'),"-bin");
+ opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
+ }
+ mysql_bin_log.set_index_file_name(opt_binlog_index_name);
+ open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
+ LOG_BIN);
+ using_update_log=1;
+ }
+
(void) thr_setconcurrency(concurrency); // 10 by default
if (
@@ -548,12 +548,12 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
{
pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
- {
sql_print_error("Warning: Can't create thread to manage maintenance");
- mysql_server_end();
- return 1;
- }
}
+
+ /* Update mysqld variables from client variables */
+ global_system_variables.max_allowed_packet=max_allowed_packet;
+ global_system_variables.net_buffer_length=net_buffer_length;
return 0;
}
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
index 59e6239c1e7..3fba238a8bf 100644
--- a/libmysqld/libmysqld.c
+++ b/libmysqld/libmysqld.c
@@ -794,6 +794,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
{
char buff[100],charset_name_buff[16],*end,*host_info, *charset_name;
uint pkt_length;
+ ulong max_allowed_packet;
NET *net= &mysql->net;
DBUG_ENTER("mysql_real_connect");
DBUG_PRINT("enter",("host: %s db: %s user: %s",
@@ -949,7 +950,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
int2store(buff,client_flag);
mysql->client_flag=client_flag;
-
+ max_allowed_packet=net->max_packet_size;
int3store(buff+2,max_allowed_packet);
if (user && user[0])
strmake(buff+5,user,32);
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index daecbb7ef2c..9196b74a4b9 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -455,7 +455,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
info->s->state.auto_increment=save_auto_value;
/* Check that there isn't a row with auto_increment = 0 in the table */
- mi_extra(info,HA_EXTRA_KEYREAD);
+ mi_extra(info,HA_EXTRA_KEYREAD,0);
bzero(info->lastkey,keyinfo->seg->length);
if (!mi_rkey(info, info->rec_buff, key, (const byte*) info->lastkey,
keyinfo->seg->length, HA_READ_KEY_EXACT))
@@ -466,7 +466,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
"Found row where the auto_increment column has the value 0");
param->warning_printed=save;
}
- mi_extra(info,HA_EXTRA_NO_KEYREAD);
+ mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
}
length=(my_off_t) isam_key_length(info,keyinfo)*keys + param->key_blocks*2;
@@ -1128,7 +1128,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
param->testflag|=T_REP; /* for easy checking */
if (!param->using_global_keycache)
- VOID(init_key_cache(param->use_buffers,NEED_MEM));
+ VOID(init_key_cache(param->use_buffers));
if (init_io_cache(&param->read_cache,info->dfile,
(uint) param->read_buffer_length,
@@ -3601,12 +3601,12 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
!(param->testflag & T_REP))
printf("Updating MyISAM file: %s\n", param->isam_file_name);
/* We have to use keyread here as a normal read uses info->rec_buff */
- mi_extra(info,HA_EXTRA_KEYREAD);
+ mi_extra(info,HA_EXTRA_KEYREAD,0);
if (mi_rlast(info,info->rec_buff, info->s->base.auto_key-1))
{
if (my_errno != HA_ERR_END_OF_FILE)
{
- mi_extra(info,HA_EXTRA_NO_KEYREAD);
+ mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
mi_check_print_error(param,"%d when reading last record",my_errno);
return;
}
@@ -3621,7 +3621,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
update_auto_increment(info,info->rec_buff);
set_if_bigger(info->s->state.auto_increment,auto_increment);
}
- mi_extra(info,HA_EXTRA_NO_KEYREAD);
+ mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
update_state_info(param, info, UPDATE_AUTO_INC);
return;
}
diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c
index 9e514a6c055..6c658a33dda 100644
--- a/myisam/mi_extra.c
+++ b/myisam/mi_extra.c
@@ -14,11 +14,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Extra functions we want to do with a database */
-/* - Set flags for quicker databasehandler */
-/* - Set databasehandler to normal */
-/* - Reset recordpointers as after open database */
-
#include "myisamdef.h"
#ifdef HAVE_MMAP
#include <sys/mman.h>
@@ -27,11 +22,28 @@
#include <errno.h>
#endif
- /* set extra flags for database */
+/*
+ Set options and buffers to optimize table handling
+
+ SYNOPSIS
+ mi_extra()
+ info open table
+ function operation
+ extra_arg Pointer to extra argument (normally pointer to ulong)
+ Used when function is one of:
+ HA_EXTRA_WRITE_CACHE
+ HA_EXTRA_CACHE
+ HA_EXTRA_BULK_INSERT_BEGIN
+ If extra_arg is 0, then the default cache size is used.
+ RETURN VALUES
+ 0 ok
+*/
-int mi_extra(MI_INFO *info, enum ha_extra_function function)
+
+int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
{
int error=0;
+ ulong cache_size;
MYISAM_SHARE *share=info->s;
DBUG_ENTER("mi_extra");
DBUG_PRINT("enter",("function: %d",(int) function));
@@ -103,11 +115,13 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
if (!(info->opt_flag &
(READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED)))
{
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
if (!(init_io_cache(&info->rec_cache,info->dfile,
(uint) min(info->state->data_file_length+1,
- my_default_record_cache_size),
- READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
- MYF(share->write_flag & MY_WAIT_IF_FULL))))
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
{
info->opt_flag|=READ_CACHE_USED;
info->update&= ~HA_STATE_ROW_CHANGED;
@@ -133,10 +147,12 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
error=1; /* Not possibly if not locked */
break;
}
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
if (!(info->opt_flag &
(READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) &&
!share->state.header.uniques)
- if (!(init_io_cache(&info->rec_cache,info->dfile,0,
+ if (!(init_io_cache(&info->rec_cache,info->dfile, cache_size,
WRITE_CACHE,info->state->data_file_length,
(pbool) (info->lock_type != F_UNLCK),
MYF(share->write_flag & MY_WAIT_IF_FULL))))
@@ -337,7 +353,8 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
info->quick_mode=1;
break;
case HA_EXTRA_BULK_INSERT_BEGIN:
- error=_mi_init_bulk_insert(info);
+ error=_mi_init_bulk_insert(info, (extra_arg ? *(ulong*) extra_arg :
+ myisam_bulk_insert_tree_size));
break;
case HA_EXTRA_BULK_INSERT_END:
if (info->bulk_insert)
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index c9ecdaab47f..e10d931e6d3 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -66,7 +66,7 @@ static MI_INFO *test_if_reopen(char *filename)
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
int lock_error,kfile,open_mode,save_errno;
- uint i,j,len,errpos,head_length,base_pos,offset,info_length,extra,keys,
+ uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
key_parts,unique_key_parts,tmp_length,uniques;
char name_buff[FN_REFLEN], org_name [FN_REFLEN], index_name[FN_REFLEN],
data_name[FN_REFLEN];
diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c
index d0ce3ea966e..bcb9cd172ec 100644
--- a/myisam/mi_test1.c
+++ b/myisam/mi_test1.c
@@ -50,7 +50,7 @@ int main(int argc,char *argv[])
MY_INIT(argv[0]);
my_init();
if (key_cacheing)
- init_key_cache(IO_SIZE*16,(uint) IO_SIZE*4*10);
+ init_key_cache(IO_SIZE*16);
get_options(argc,argv);
exit(run_test("test1"));
diff --git a/myisam/mi_test2.c b/myisam/mi_test2.c
index 75129ac7667..93538e3ead7 100644
--- a/myisam/mi_test2.c
+++ b/myisam/mi_test2.c
@@ -208,13 +208,13 @@ int main(int argc, char *argv[])
if (!silent)
printf("- Writing key:s\n");
if (key_cacheing)
- init_key_cache(key_cache_size,(uint) IO_SIZE*4*10); /* Use a small cache */
+ init_key_cache(key_cache_size); /* Use a small cache */
if (locking)
mi_lock_database(file,F_WRLCK);
if (write_cacheing)
- mi_extra(file,HA_EXTRA_WRITE_CACHE);
+ mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
if (opt_quick_mode)
- mi_extra(file,HA_EXTRA_QUICK);
+ mi_extra(file,HA_EXTRA_QUICK,0);
for (i=0 ; i < recant ; i++)
{
@@ -261,11 +261,15 @@ int main(int argc, char *argv[])
if (testflag==1) goto end;
if (write_cacheing)
- if (mi_extra(file,HA_EXTRA_NO_CACHE))
+ {
+ if (mi_extra(file,HA_EXTRA_NO_CACHE,0))
{
puts("got error from mi_extra(HA_EXTRA_NO_CACHE)");
goto end;
}
+ if (key_cacheing)
+ resize_key_cache(key_cache_size*2);
+ }
if (!silent)
printf("- Delete\n");
@@ -677,7 +681,7 @@ int main(int argc, char *argv[])
if (!silent)
printf("- mi_extra(CACHE) + mi_rrnd.... + mi_extra(NO_CACHE)\n");
- if (mi_extra(file,HA_EXTRA_RESET) || mi_extra(file,HA_EXTRA_CACHE))
+ if (mi_extra(file,HA_EXTRA_RESET,0) || mi_extra(file,HA_EXTRA_CACHE,0))
{
if (locking || (!use_blob && !pack_fields))
{
@@ -695,7 +699,7 @@ int main(int argc, char *argv[])
ant,write_count-opt_delete);
goto end;
}
- if (mi_extra(file,HA_EXTRA_NO_CACHE))
+ if (mi_extra(file,HA_EXTRA_NO_CACHE,0))
{
puts("got error from mi_extra(HA_EXTRA_NO_CACHE)");
goto end;
@@ -720,7 +724,7 @@ int main(int argc, char *argv[])
DBUG_PRINT("progpos",("Removing keys"));
lastpos = HA_OFFSET_ERROR;
/* DBUG_POP(); */
- mi_extra(file,HA_EXTRA_RESET);
+ mi_extra(file,HA_EXTRA_RESET,0);
found_parts=0;
while ((error=mi_rrnd(file,read_record,HA_OFFSET_ERROR)) !=
HA_ERR_END_OF_FILE)
@@ -791,8 +795,10 @@ end:
printf("myisam_block_size: %u\n", myisam_block_size);
if (key_cacheing)
{
- puts("Key cacheing used");
+ puts("Key cache used");
printf("key_cache_block_size: %u\n", key_cache_block_size);
+ if (write_cacheing)
+ puts("Key cache resized");
}
if (write_cacheing)
puts("Write cacheing used");
diff --git a/myisam/mi_test3.c b/myisam/mi_test3.c
index 36222c3edbc..ac36f55a181 100644
--- a/myisam/mi_test3.c
+++ b/myisam/mi_test3.c
@@ -173,7 +173,7 @@ void start_test(int id)
exit(1);
}
if (key_cacheing && rnd(2) == 0)
- init_key_cache(65536L,(uint) IO_SIZE*4*10);
+ init_key_cache(65536L);
printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
@@ -302,7 +302,7 @@ int test_rrnd(MI_INFO *file,int id)
return 1;
}
if (rnd(2) == 0)
- mi_extra(file,HA_EXTRA_CACHE);
+ mi_extra(file,HA_EXTRA_CACHE,0);
}
count=0;
@@ -323,7 +323,7 @@ int test_rrnd(MI_INFO *file,int id)
end:
if (lock)
{
- mi_extra(file,HA_EXTRA_NO_CACHE);
+ mi_extra(file,HA_EXTRA_NO_CACHE,0);
if (mi_lock_database(file,F_UNLCK))
{
fprintf(stderr,"%2d: Can't unlock table\n",id);
@@ -355,7 +355,7 @@ int test_write(MI_INFO *file,int id,int lock_type)
return 1;
}
if (rnd(2) == 0)
- mi_extra(file,HA_EXTRA_WRITE_CACHE);
+ mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
}
sprintf(record.id,"%7d",getpid());
@@ -380,7 +380,7 @@ int test_write(MI_INFO *file,int id,int lock_type)
}
if (lock)
{
- mi_extra(file,HA_EXTRA_NO_CACHE);
+ mi_extra(file,HA_EXTRA_NO_CACHE,0);
if (mi_lock_database(file,F_UNLCK))
{
fprintf(stderr,"%2d: Can't unlock table\n",id);
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index 9998a25a96a..cfacd0bc4d5 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -801,7 +801,7 @@ static int keys_free(uchar *key, TREE_FREE mode, bulk_insert_param *param)
}
-int _mi_init_bulk_insert(MI_INFO *info)
+int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size)
{
MYISAM_SHARE *share=info->s;
MI_KEYDEF *key=share->keyinfo;
@@ -809,6 +809,7 @@ int _mi_init_bulk_insert(MI_INFO *info)
uint i, num_keys;
ulonglong key_map=0;
DBUG_ENTER("_mi_init_bulk_insert");
+ DBUG_PRINT("enter",("cache_size: %lu", cache_size));
if (info->bulk_insert)
DBUG_RETURN(0);
@@ -824,7 +825,7 @@ int _mi_init_bulk_insert(MI_INFO *info)
}
if (num_keys==0 ||
- num_keys * MI_MIN_SIZE_BULK_INSERT_TREE > myisam_bulk_insert_tree_size)
+ num_keys * MI_MIN_SIZE_BULK_INSERT_TREE > cache_size)
DBUG_RETURN(0);
info->bulk_insert=(TREE *)
@@ -842,8 +843,8 @@ int _mi_init_bulk_insert(MI_INFO *info)
params->info=info;
params->keynr=i;
init_tree(&info->bulk_insert[i],
- myisam_bulk_insert_tree_size / num_keys / 4 + 10,
- myisam_bulk_insert_tree_size / num_keys, 0,
+ cache_size / num_keys / 4 + 10,
+ cache_size / num_keys, 0,
(qsort_cmp2)keys_compare, 0,
(tree_element_free) keys_free, (void *)params++);
}
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index e91181ff420..ff8c47f93cc 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -1003,7 +1003,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
!(param->testflag & (T_FAST | T_FORCE_CREATE)))
{
if (param->testflag & (T_EXTEND | T_MEDIUM))
- VOID(init_key_cache(param->use_buffers,(uint) NEED_MEM));
+ VOID(init_key_cache(param->use_buffers));
VOID(init_io_cache(&param->read_cache,datafile,
(uint) param->read_buffer_length,
READ_CACHE,
@@ -1413,7 +1413,7 @@ static int mi_sort_records(MI_CHECK *param,
if (share->state.key_root[sort_key] == HA_OFFSET_ERROR)
DBUG_RETURN(0); /* Nothing to do */
- init_key_cache(param->use_buffers,NEED_MEM);
+ init_key_cache(param->use_buffers);
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index 5790ae6f475..8c1ca393a3c 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -656,7 +656,7 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
int mi_open_keyfile(MYISAM_SHARE *share);
void mi_setup_functions(register MYISAM_SHARE *share);
-int _mi_init_bulk_insert(MI_INFO *info);
+int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size);
/* Functions needed by mi_check */
void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...));
diff --git a/myisam/myisamlog.c b/myisam/myisamlog.c
index 2d4c7570956..ceca8d2a0e3 100644
--- a/myisam/myisamlog.c
+++ b/myisam/myisamlog.c
@@ -333,7 +333,7 @@ static int examine_log(my_string file_name, char **table_names)
bzero((gptr) com_count,sizeof(com_count));
init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
(tree_element_free) file_info_free, NULL);
- VOID(init_key_cache(KEY_CACHE_SIZE,(uint) (10*4*(IO_SIZE+MALLOC_OVERHEAD))));
+ VOID(init_key_cache(KEY_CACHE_SIZE));
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&
@@ -484,7 +484,7 @@ static int examine_log(my_string file_name, char **table_names)
command_name[command], (int) extra_command,result);
if (update && curr_file_info && !curr_file_info->closed)
{
- if (mi_extra(curr_file_info->isam, extra_command) != (int) result)
+ if (mi_extra(curr_file_info->isam, extra_command, 0) != (int) result)
{
fflush(stdout);
VOID(fprintf(stderr,
diff --git a/myisam/myisampack.c b/myisam/myisampack.c
index b7dd788821a..14fde9aa8b3 100644
--- a/myisam/myisampack.c
+++ b/myisam/myisampack.c
@@ -2088,7 +2088,7 @@ static void mrg_reset(PACK_MRG_INFO *mrg)
{
if (mrg->current)
{
- mi_extra(*mrg->current,HA_EXTRA_NO_CACHE);
+ mi_extra(*mrg->current, HA_EXTRA_NO_CACHE, 0);
mrg->current=0;
}
}
@@ -2103,8 +2103,8 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf)
{
isam_info= *(info->current=info->file);
info->end=info->current+info->count;
- mi_extra(isam_info,HA_EXTRA_RESET);
- mi_extra(isam_info,HA_EXTRA_CACHE);
+ mi_extra(isam_info, HA_EXTRA_RESET, 0);
+ mi_extra(isam_info, HA_EXTRA_CACHE, 0);
filepos=isam_info->s->pack.header_length;
}
else
@@ -2120,14 +2120,14 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf)
filepos, 1)) ||
error != HA_ERR_END_OF_FILE)
return (error);
- mi_extra(isam_info,HA_EXTRA_NO_CACHE);
+ mi_extra(isam_info,HA_EXTRA_NO_CACHE, 0);
if (info->current+1 == info->end)
return(HA_ERR_END_OF_FILE);
info->current++;
isam_info= *info->current;
filepos=isam_info->s->pack.header_length;
- mi_extra(isam_info,HA_EXTRA_RESET);
- mi_extra(isam_info,HA_EXTRA_CACHE);
+ mi_extra(isam_info,HA_EXTRA_RESET, 0);
+ mi_extra(isam_info,HA_EXTRA_CACHE, 0);
}
}
diff --git a/myisammrg/myrg_extra.c b/myisammrg/myrg_extra.c
index 5434d30a50e..ad17b0f82f2 100644
--- a/myisammrg/myrg_extra.c
+++ b/myisammrg/myrg_extra.c
@@ -22,7 +22,8 @@
#include "myrg_def.h"
-int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
+int myrg_extra(MYRG_INFO *info,enum ha_extra_function function,
+ void *extra_arg)
{
int error,save_error=0;
MYRG_TABLE *file;
@@ -30,7 +31,11 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
DBUG_PRINT("info",("function: %d",(ulong) function));
if (function == HA_EXTRA_CACHE)
+ {
info->cache_in_use=1;
+ info->cache_size= (extra_arg ? *(long*) extra_arg :
+ my_default_record_cache_size);
+ }
else
{
if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET)
@@ -41,12 +46,15 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
info->last_used_table=info->open_tables;
}
for (file=info->open_tables ; file != info->end_table ; file++)
- if ((error=mi_extra(file->table,function)))
+ {
+ if ((error=mi_extra(file->table, function, extra_arg)))
save_error=error;
+ }
}
DBUG_RETURN(save_error);
}
+
void myrg_extrafunc(MYRG_INFO *info, invalidator_by_filename inv)
{
MYRG_TABLE *file;
diff --git a/myisammrg/myrg_rrnd.c b/myisammrg/myrg_rrnd.c
index 3e7002c8679..d623ea8ea9c 100644
--- a/myisammrg/myrg_rrnd.c
+++ b/myisammrg/myrg_rrnd.c
@@ -48,7 +48,7 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
}
isam_info=(info->current_table=info->open_tables)->table;
if (info->cache_in_use)
- mi_extra(isam_info,HA_EXTRA_CACHE);
+ mi_extra(isam_info,HA_EXTRA_CACHE,(byte*) &info->cache_size);
filepos=isam_info->s->pack.header_length;
isam_info->lastinx= (uint) -1; /* Can't forward or backward */
}
@@ -66,13 +66,15 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
HA_ERR_END_OF_FILE)
DBUG_RETURN(error);
if (info->cache_in_use)
- mi_extra(info->current_table->table,HA_EXTRA_NO_CACHE);
+ mi_extra(info->current_table->table, HA_EXTRA_NO_CACHE,
+ (byte*) &info->cache_size);
if (info->current_table+1 == info->end_table)
DBUG_RETURN(HA_ERR_END_OF_FILE);
info->current_table++;
info->last_used_table=info->current_table;
if (info->cache_in_use)
- mi_extra(info->current_table->table,HA_EXTRA_CACHE);
+ mi_extra(info->current_table->table, HA_EXTRA_CACHE,
+ (byte*) &info->cache_size);
info->current_table->file_offset=
info->current_table[-1].file_offset+
info->current_table[-1].table->state->data_file_length;
diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result
index d61b6c67030..e24c3179a0c 100644
--- a/mysql-test/r/insert_select.result
+++ b/mysql-test/r/insert_select.result
@@ -61,7 +61,7 @@ SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM crash2
WHERE numeropost=9 ORDER BY numreponse ASC;
show variables like '%bulk%';
Variable_name Value
-myisam_bulk_insert_tree_size 8388608
+bulk_insert_buffer_size 8388608
INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip)
SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM crash2
WHERE numeropost=9 ORDER BY numreponse ASC;
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index 6dfe0809e7f..1cd9c9dfe79 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -147,3 +147,34 @@ t1 0 e 1 e A 0 NULL NULL BTREE
t1 0 b 1 b A NULL NULL NULL YES BTREE
t1 1 c 1 c A NULL NULL NULL YES BTREE
drop table t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+c i
+ 1
+ 2
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+c i
+ 1
+ 2
+a 1
+a 2
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NULL, i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+c i
+NULL 1
+NULL 2
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+c i
+NULL 1
+NULL 2
+a 1
+a 2
+drop table t1;
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index af14575a812..3afe1cd62cc 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -226,7 +226,7 @@ show status like "Qcache_free_blocks";
Variable_name Value
Qcache_free_blocks 1
drop table t1, t2, t3, t11, t21;
-set sql_query_cache_type=demand;
+set query_cache_type=demand;
create table t1 (a int not null);
insert into t1 values (1),(2),(3);
select * from t1;
@@ -242,7 +242,7 @@ a
1
2
3
-set sql_query_cache_type=2;
+set query_cache_type=2;
select sql_cache * from t1;
a
1
@@ -254,7 +254,7 @@ Qcache_hits 4
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
-set sql_query_cache_type=on;
+set query_cache_type=on;
reset query cache;
show status like "Qcache_queries_in_cache";
Variable_name Value
diff --git a/mysql-test/r/rpl000001.result b/mysql-test/r/rpl000001.result
index 60a5db1de3a..2c36df65ca9 100644
--- a/mysql-test/r/rpl000001.result
+++ b/mysql-test/r/rpl000001.result
@@ -67,7 +67,7 @@ select (@id := id) - id from t2;
kill @id;
drop table t2;
Server shutdown in progress
-set sql_slave_skip_counter=1;
+set global sql_slave_skip_counter=1;
slave start;
select count(*) from t1;
count(*)
diff --git a/mysql-test/r/rpl000016.result b/mysql-test/r/rpl000016.result
index 9d6ba071200..ccd584bfcdc 100644
--- a/mysql-test/r/rpl000016.result
+++ b/mysql-test/r/rpl000016.result
@@ -33,7 +33,7 @@ master-bin.003
insert into t2 values(1234);
set insert_id=1234;
insert into t2 values(NULL);
-set sql_slave_skip_counter=1;
+set global sql_slave_skip_counter=1;
slave start;
purge master logs to 'master-bin.003';
show master logs;
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 7d914d029af..52f4d4a14f6 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -194,9 +194,9 @@ a
1
2
set SQL_SELECT_LIMIT=2;
-(select * from t1 limit 2) union (select * from t2 limit 3);
+(select * from t1 limit 1) union (select * from t2 limit 3);
a
1
-2
+11
set SQL_SELECT_LIMIT=DEFAULT;
drop table t1,t2;
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 5c8b4581c5c..5643900182e 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -1,5 +1,5 @@
set @a := foo;
-You may only use constant expressions with SET
+Unknown column 'foo' in 'field list'
set @a := connection_id() + 3;
select @a - connection_id();
@a - connection_id()
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 52c2c026bd3..4227ecfdadb 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -44,17 +44,277 @@ c_id c_name c_country
1 Bozo USA
4 Mr. Floppy GB
drop table t1;
+set max_join_size=100;
+show variables like 'max_join_size';
+Variable_name Value
+max_join_size 100
+show global variables like 'max_join_size';
+Variable_name Value
+max_join_size 4294967295
+set GLOBAL max_join_size=2000;
+show global variables like 'max_join_size';
+Variable_name Value
+max_join_size 2000
+set max_join_size=DEFAULT;
+show variables like 'max_join_size';
+Variable_name Value
+max_join_size 2000
+set GLOBAL max_join_size=DEFAULT;
+show global variables like 'max_join_size';
+Variable_name Value
+max_join_size 4294967295
+set @@max_join_size=1000, @@global.max_join_size=2000;
+select @@local.max_join_size, @@global.max_join_size;
+@@max_join_size @@max_join_size
+1000 2000
+select @@identity, length(@@version)>0;
+@@identity length(@@version)>0
+0 1
select @@VERSION=version();
@@VERSION=version()
1
select last_insert_id(345);
last_insert_id(345)
345
-select @@IDENTITY,last_insert_id();
-@@IDENTITY last_insert_id()
-345 345
-select @@identity;
-@@IDENTITY
-345
-select @@unknown_variable;
+select @@IDENTITY,last_insert_id(), @@identity;
+@@identity last_insert_id() @@identity
+345 345 345
+set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", big_tables="ON";
+set global concurrent_insert=ON;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert ON
+set global concurrent_insert=1;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert ON
+set global concurrent_insert=0;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert OFF
+set global concurrent_insert=OFF;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert OFF
+set global concurrent_insert=DEFAULT;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert ON
+set table_type=MYISAM, table_type="HEAP", global table_type="INNODB";
+show local variables like 'table_type';
+Variable_name Value
+table_type HEAP
+show global variables like 'table_type';
+Variable_name Value
+table_type INNODB
+set GLOBAL query_cache_size=100000;
+set GLOBAL safe_show_database=0;
+set myisam_max_sort_file_size=10000, GLOBAL myisam_max_sort_file_size=20000;
+show variables like 'myisam_max_sort_file_size';
+Variable_name Value
+myisam_max_sort_file_size 10000
+show global variables like 'myisam_max_sort_file_size';
+Variable_name Value
+myisam_max_sort_file_size 20000
+set myisam_max_sort_file_size=default;
+show variables like 'myisam_max_sort_file_size';
+Variable_name Value
+myisam_max_sort_file_size 20000
+set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
+set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600;
+show global variables like 'net_%';
+Variable_name Value
+net_buffer_length 1024
+net_read_timeout 300
+net_retry_count 10
+net_write_timeout 200
+show session variables like 'net_%';
+Variable_name Value
+net_buffer_length 2048
+net_read_timeout 600
+net_retry_count 10
+net_write_timeout 500
+set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000;
+show global variables like 'net_%';
+Variable_name Value
+net_buffer_length 1024
+net_read_timeout 900
+net_retry_count 10
+net_write_timeout 1000
+show session variables like 'net_%';
+Variable_name Value
+net_buffer_length 7168
+net_read_timeout 600
+net_retry_count 10
+net_write_timeout 500
+set net_buffer_length=1;
+show variables like 'net_buffer_length';
+Variable_name Value
+net_buffer_length 1024
+set net_buffer_length=2000000000;
+show variables like 'net_buffer_length';
+Variable_name Value
+net_buffer_length 1048576
+set GLOBAL character set cp1251_koi8;
+show global variables like "convert_character_set";
+Variable_name Value
+convert_character_set cp1251_koi8
+set character set cp1251_koi8;
+show variables like "convert_character_set";
+Variable_name Value
+convert_character_set cp1251_koi8
+set global character set default, session character set default;
+show variables like "convert_character_set";
+Variable_name Value
+convert_character_set cp1251_koi8
+select @@timestamp>0;
+@@timestamp>0
+1
+set big_tables=OFFF;
+Variable 'big_tables' can't be set to the value of 'OFFF'
+set big_tables="OFFF";
+Variable 'big_tables' can't be set to the value of 'OFFF'
+set unknown_variable=1;
Unknown system variable 'unknown_variable'
+set max_join_size="hello";
+Wrong argument type to variable 'max_join_size'
+set table_type=UNKNOWN_TABLE_TYPE;
+Variable 'table_type' can't be set to the value of 'UNKNOWN_TABLE_TYPE'
+set table_type=INNODB, big_tables=2;
+Variable 'big_tables' can't be set to the value of '2'
+show local variables like 'table_type';
+Variable_name Value
+table_type HEAP
+set SESSION query_cache_size=10000;
+Variable 'query_cache_size' is a GLOBAL variable and should be set with SET GLOBAL
+set GLOBAL table_type=DEFAULT;
+Variable 'table_type' doesn't have a default value
+set convert_character_set=UNKNOWN_CHARACTER_SET;
+Unknown character set: 'UNKNOWN_CHARACTER_SET'
+set character set unknown;
+Unknown character set: 'unknown'
+set character set 0;
+Wrong argument type to variable 'convert_character_set'
+set global autocommit=1;
+Variable 'autocommit' is a LOCAL variable and can't be used with SET GLOBAL
+select @@global.timestamp;
+Variable 'timestamp' is a LOCAL variable and can't be used with SET GLOBAL
+set @@version='';
+Unknown system variable 'version'
+set @@concurrent_insert=1;
+Variable 'concurrent_insert' is a GLOBAL variable and should be set with SET GLOBAL
+set @@global.sql_auto_is_null=1;
+Variable 'sql_auto_is_null' is a LOCAL variable and can't be used with SET GLOBAL
+select @@global.sql_auto_is_null;
+Variable 'sql_auto_is_null' is a LOCAL variable and can't be used with SET GLOBAL
+set autocommit=1;
+set big_tables=1;
+select @@autocommit, @@big_tables;
+@@autocommit @@big_tables
+1 1
+set global binlog_cache_size=100;
+set bulk_insert_buffer_size=100;
+set convert_character_set=cp1251_koi8;
+set convert_character_set=default;
+set @@global.concurrent_insert=1;
+set global connect_timeout=100;
+set global delay_key_write=1;
+set global delayed_insert_limit=100;
+set global delayed_insert_timeout=100;
+set global delayed_queue_size=100;
+set global flush=1;
+set global flush_time=100;
+set insert_id=1;
+set interactive_timeout=100;
+set join_buffer_size=100;
+set last_insert_id=1;
+set global local_infile=1;
+set long_query_time=100;
+set low_priority_updates=1;
+set max_allowed_packet=100;
+set global max_binlog_cache_size=100;
+set global max_binlog_size=100;
+set global max_connect_errors=100;
+set global max_connections=100;
+set global max_delayed_threads=100;
+set max_heap_table_size=100;
+set max_join_size=100;
+set max_sort_length=100;
+set max_tmp_tables=100;
+set global max_user_connections=100;
+select @@max_user_connections;
+@@max_user_connections
+100
+set global max_write_lock_count=100;
+set myisam_max_extra_sort_file_size=100;
+select @@myisam_max_extra_sort_file_size;
+@@myisam_max_extra_sort_file_size
+100
+set myisam_max_sort_file_size=100;
+set myisam_sort_buffer_size=100;
+set net_buffer_length=100;
+set net_read_timeout=100;
+set net_write_timeout=100;
+set global query_cache_limit=100;
+set global query_cache_size=100;
+set global query_cache_type=demand;
+set read_buffer_size=100;
+set read_rnd_buffer_size=100;
+set global rpl_recovery_rank=100;
+set global safe_show_database=1;
+set global server_id=100;
+set global slave_net_timeout=100;
+set global slow_launch_time=100;
+set sort_buffer_size=100;
+set sql_auto_is_null=1;
+select @@sql_auto_is_null;
+@@sql_auto_is_null
+1
+set @@sql_auto_is_null=0;
+select @@sql_auto_is_null;
+@@sql_auto_is_null
+0
+set sql_big_selects=1;
+set sql_big_tables=1;
+set sql_buffer_result=1;
+set sql_log_bin=1;
+set sql_log_off=1;
+set sql_log_update=1;
+set sql_low_priority_updates=1;
+set sql_max_join_size=200;
+select @@sql_max_join_size,@@max_join_size;
+@@sql_max_join_size @@max_join_size
+200 200
+set sql_quote_show_create=1;
+set sql_safe_updates=1;
+set sql_select_limit=1;
+set global sql_slave_skip_counter=100;
+set sql_warnings=1;
+set global table_cache=100;
+set table_type=myisam;
+set global thread_cache_size=100;
+set timestamp=1, timestamp=default;
+set tmp_table_size=100;
+set tx_isolation="READ-COMMITTED";
+set wait_timeout=100;
+set log_warnings=1;
+DROP TABLE IF EXISTS t1,t2;
+create table t1 (a int not null auto_increment, primary key(a));
+create table t2 (a int not null auto_increment, primary key(a));
+insert into t1 values(null),(null),(null);
+insert into t2 values(null),(null),(null);
+set global key_buffer_size=100000;
+select @@key_buffer_size;
+@@key_buffer_size
+98304
+select * from t1 where a=2;
+a
+2
+select * from t2 where a=3;
+a
+3
+check table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+drop table t1,t2;
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index 6fc975a1cb3..1996c793880 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -168,3 +168,23 @@ drop table t1;
create table t1 (a int not null unique, b int unique, c int, d int not null primary key, key(c), e int not null unique);
show keys from t1;
drop table t1;
+
+#
+# Problem with UNIQUE() with NULL parts and auto increment
+#
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NULL, i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+drop table t1;
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index a3227a5db1d..e7633f3bae0 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -139,17 +139,17 @@ drop table t1, t2, t3, t11, t21;
#
# SELECT SQL_CACHE ...
#
-set sql_query_cache_type=demand;
+set query_cache_type=demand;
create table t1 (a int not null);
insert into t1 values (1),(2),(3);
select * from t1;
show status like "Qcache_queries_in_cache";
select sql_cache * from t1;
-set sql_query_cache_type=2;
+set query_cache_type=2;
select sql_cache * from t1;
show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
-set sql_query_cache_type=on;
+set query_cache_type=on;
#
# RESET QUERY CACHE
#
diff --git a/mysql-test/t/rpl000001.test b/mysql-test/t/rpl000001.test
index a5496d505f0..6d46124d238 100644
--- a/mysql-test/t/rpl000001.test
+++ b/mysql-test/t/rpl000001.test
@@ -85,7 +85,7 @@ wait_for_slave_to_stop;
# --replace_result 9306 9999 3334 9999 3335 9999
# show slave status;
-set sql_slave_skip_counter=1;
+set global sql_slave_skip_counter=1;
slave start;
select count(*) from t1;
connection master1;
diff --git a/mysql-test/t/rpl000009.test b/mysql-test/t/rpl000009.test
index 208e6f0b037..d45fe0870ff 100644
--- a/mysql-test/t/rpl000009.test
+++ b/mysql-test/t/rpl000009.test
@@ -1,5 +1,6 @@
-#this one assumes we are ignoring updates on tables in database foo, but doing
-#the ones in database bar
+# This one assumes we are ignoring updates on tables in database foo, but doing
+# the ones in database bar
+
source include/master-slave.inc;
connection master;
drop database if exists foo;
@@ -32,9 +33,10 @@ sync_with_master;
drop database if exists bar;
drop database if exists foo;
-#now let's test load data from master
+# Now let's test load data from master
+
+# First create some databases and tables on the master
-#first create some databases and tables on the master
connection master;
set sql_log_bin = 0;
create database foo;
@@ -55,11 +57,11 @@ save_master_pos;
connection slave;
sync_with_master;
-#this should show that the slave is empty at this point
+# This should show that the slave is empty at this point
show databases;
load data from master;
-#now let's check if we have the right tables and the right data in them
+# Now let's check if we have the right tables and the right data in them
show databases;
use foo;
show tables;
@@ -68,7 +70,7 @@ show tables;
select * from bar.t1;
select * from bar.t2;
-#now let's see if replication works
+# Now let's see if replication works
connection master;
insert into bar.t1 values (4, 'four bar');
save_master_pos;
@@ -76,7 +78,7 @@ connection slave;
sync_with_master;
select * from bar.t1;
-#now time for cleanup
+# Now time for cleanup
connection master;
drop database bar;
drop database foo;
diff --git a/mysql-test/t/rpl000016.test b/mysql-test/t/rpl000016.test
index 7559b2d3515..b830d0b8d91 100644
--- a/mysql-test/t/rpl000016.test
+++ b/mysql-test/t/rpl000016.test
@@ -54,7 +54,7 @@ sync_with_master;
wait_for_slave_to_stop;
#restart slave skipping one event
-set sql_slave_skip_counter=1;
+set global sql_slave_skip_counter=1;
slave start;
connection master;
diff --git a/mysql-test/t/rpl_compat.test b/mysql-test/t/rpl_compat.test
index c9455c1e2d2..9c67cce1680 100644
--- a/mysql-test/t/rpl_compat.test
+++ b/mysql-test/t/rpl_compat.test
@@ -58,7 +58,7 @@ sync_with_master ;
#now slave will hit an error
wait_for_slave_to_stop;
-set sql_slave_skip_counter=1;
+set global sql_slave_skip_counter=1;
slave start;
select count(*) from t1;
connection master1;
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index f5a92b05e0d..d13b5dec662 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -88,6 +88,6 @@ insert into t2 values (11),(12),(13),(14),(15);
(select * from t1 limit 2) union (select * from t2 limit 3);
(select * from t1 limit 2) union (select * from t2 limit 20,3);
set SQL_SELECT_LIMIT=2;
-(select * from t1 limit 2) union (select * from t2 limit 3);
+(select * from t1 limit 1) union (select * from t2 limit 3);
set SQL_SELECT_LIMIT=DEFAULT;
drop table t1,t2;
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 70283446fb3..bb1a9b59611 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -1,4 +1,4 @@
-error 1204;
+error 1054;
set @a := foo;
set @a := connection_id() + 3;
select @a - connection_id();
diff --git a/mysql-test/t/variables-master.opt b/mysql-test/t/variables-master.opt
new file mode 100644
index 00000000000..5851d32ec31
--- /dev/null
+++ b/mysql-test/t/variables-master.opt
@@ -0,0 +1 @@
+max_join_size=10
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index b3127402238..967c21f7eab 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -32,9 +32,200 @@ drop table t1;
# Test system variables
#
+set max_join_size=100;
+show variables like 'max_join_size';
+show global variables like 'max_join_size';
+set GLOBAL max_join_size=2000;
+show global variables like 'max_join_size';
+set max_join_size=DEFAULT;
+show variables like 'max_join_size';
+set GLOBAL max_join_size=DEFAULT;
+show global variables like 'max_join_size';
+set @@max_join_size=1000, @@global.max_join_size=2000;
+select @@local.max_join_size, @@global.max_join_size;
+select @@identity, length(@@version)>0;
select @@VERSION=version();
select last_insert_id(345);
-select @@IDENTITY,last_insert_id();
-select @@identity;
+select @@IDENTITY,last_insert_id(), @@identity;
+
+set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", big_tables="ON";
+
+set global concurrent_insert=ON;
+show variables like 'concurrent_insert';
+set global concurrent_insert=1;
+show variables like 'concurrent_insert';
+set global concurrent_insert=0;
+show variables like 'concurrent_insert';
+set global concurrent_insert=OFF;
+show variables like 'concurrent_insert';
+set global concurrent_insert=DEFAULT;
+show variables like 'concurrent_insert';
+
+set table_type=MYISAM, table_type="HEAP", global table_type="INNODB";
+show local variables like 'table_type';
+show global variables like 'table_type';
+set GLOBAL query_cache_size=100000;
+set GLOBAL safe_show_database=0;
+
+set myisam_max_sort_file_size=10000, GLOBAL myisam_max_sort_file_size=20000;
+show variables like 'myisam_max_sort_file_size';
+show global variables like 'myisam_max_sort_file_size';
+set myisam_max_sort_file_size=default;
+show variables like 'myisam_max_sort_file_size';
+
+set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
+set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600;
+show global variables like 'net_%';
+show session variables like 'net_%';
+set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000;
+show global variables like 'net_%';
+show session variables like 'net_%';
+set net_buffer_length=1;
+show variables like 'net_buffer_length';
+set net_buffer_length=2000000000;
+show variables like 'net_buffer_length';
+
+set GLOBAL character set cp1251_koi8;
+show global variables like "convert_character_set";
+set character set cp1251_koi8;
+show variables like "convert_character_set";
+set global character set default, session character set default;
+show variables like "convert_character_set";
+select @@timestamp>0;
+
+# The following should give errors
+
+--error 1231
+set big_tables=OFFF;
+--error 1231
+set big_tables="OFFF";
--error 1193
-select @@unknown_variable;
+set unknown_variable=1;
+--error 1232
+set max_join_size="hello";
+--error 1231
+set table_type=UNKNOWN_TABLE_TYPE;
+--error 1231
+set table_type=INNODB, big_tables=2;
+show local variables like 'table_type';
+--error 1229
+set SESSION query_cache_size=10000;
+--error 1230
+set GLOBAL table_type=DEFAULT;
+--error 1115
+set convert_character_set=UNKNOWN_CHARACTER_SET;
+--error 1115
+set character set unknown;
+--error 1232
+set character set 0;
+--error 1228
+set global autocommit=1;
+--error 1228
+select @@global.timestamp;
+--error 1193
+set @@version='';
+--error 1229
+set @@concurrent_insert=1;
+--error 1228
+set @@global.sql_auto_is_null=1;
+--error 1228
+select @@global.sql_auto_is_null;
+
+# Test setting all variables
+
+set autocommit=1;
+set big_tables=1;
+select @@autocommit, @@big_tables;
+set global binlog_cache_size=100;
+set bulk_insert_buffer_size=100;
+set convert_character_set=cp1251_koi8;
+set convert_character_set=default;
+set @@global.concurrent_insert=1;
+set global connect_timeout=100;
+set global delay_key_write=1;
+set global delayed_insert_limit=100;
+set global delayed_insert_timeout=100;
+set global delayed_queue_size=100;
+set global flush=1;
+set global flush_time=100;
+set insert_id=1;
+set interactive_timeout=100;
+set join_buffer_size=100;
+set last_insert_id=1;
+set global local_infile=1;
+set long_query_time=100;
+set low_priority_updates=1;
+set max_allowed_packet=100;
+set global max_binlog_cache_size=100;
+set global max_binlog_size=100;
+set global max_connect_errors=100;
+set global max_connections=100;
+set global max_delayed_threads=100;
+set max_heap_table_size=100;
+set max_join_size=100;
+set max_sort_length=100;
+set max_tmp_tables=100;
+set global max_user_connections=100;
+select @@max_user_connections;
+set global max_write_lock_count=100;
+set myisam_max_extra_sort_file_size=100;
+select @@myisam_max_extra_sort_file_size;
+set myisam_max_sort_file_size=100;
+set myisam_sort_buffer_size=100;
+set net_buffer_length=100;
+set net_read_timeout=100;
+set net_write_timeout=100;
+set global query_cache_limit=100;
+set global query_cache_size=100;
+set global query_cache_type=demand;
+set read_buffer_size=100;
+set read_rnd_buffer_size=100;
+set global rpl_recovery_rank=100;
+set global safe_show_database=1;
+set global server_id=100;
+set global slave_net_timeout=100;
+set global slow_launch_time=100;
+set sort_buffer_size=100;
+set sql_auto_is_null=1;
+select @@sql_auto_is_null;
+set @@sql_auto_is_null=0;
+select @@sql_auto_is_null;
+set sql_big_selects=1;
+set sql_big_tables=1;
+set sql_buffer_result=1;
+set sql_log_bin=1;
+set sql_log_off=1;
+set sql_log_update=1;
+set sql_low_priority_updates=1;
+set sql_max_join_size=200;
+select @@sql_max_join_size,@@max_join_size;
+set sql_quote_show_create=1;
+set sql_safe_updates=1;
+set sql_select_limit=1;
+set global sql_slave_skip_counter=100;
+set sql_warnings=1;
+set global table_cache=100;
+set table_type=myisam;
+set global thread_cache_size=100;
+set timestamp=1, timestamp=default;
+set tmp_table_size=100;
+set tx_isolation="READ-COMMITTED";
+set wait_timeout=100;
+set log_warnings=1;
+
+#
+# key buffer
+#
+
+DROP TABLE IF EXISTS t1,t2;
+create table t1 (a int not null auto_increment, primary key(a));
+create table t2 (a int not null auto_increment, primary key(a));
+insert into t1 values(null),(null),(null);
+insert into t2 values(null),(null),(null);
+set global key_buffer_size=100000;
+select @@key_buffer_size;
+select * from t1 where a=2;
+select * from t2 where a=3;
+check table t1,t2;
+drop table t1,t2;
+
diff --git a/mysys/default.c b/mysys/default.c
index 12d7d2e4ed0..fdeeabf83eb 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -82,7 +82,7 @@ void load_defaults(const char *conf_file, const char **groups,
char *ptr,**res;
DBUG_ENTER("load_defaults");
- init_alloc_root(&alloc,128,0);
+ init_alloc_root(&alloc,512,0);
if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
{
/* remove the --no-defaults argument and return only the other arguments */
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index b141e341016..b6e721cbd57 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -547,7 +547,7 @@ int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count)
info->error=(int) read_len;
DBUG_RETURN(1);
}
- cnt=(len > Count) ? (int) Count : len;
+ cnt=((uint) len > Count) ? (int) Count : len;
memcpy(Buffer,info->read_pos, (size_t)cnt);
Count -=cnt;
Buffer+=cnt;
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 2ddf13bfa1f..5a573bff0f7 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -53,6 +53,7 @@ typedef struct sec_link {
static SEC_LINK *find_key_block(int file,my_off_t filepos,int *error);
+static int flush_all_key_blocks();
/* static variables in this file */
static SEC_LINK *_my_block_root,**_my_hash_root,
@@ -76,11 +77,9 @@ static my_bool _my_printed;
/* Returns blocks in use */
/* ARGSUSED */
-int init_key_cache(ulong use_mem,
- ulong leave_this_much_mem __attribute__((unused)))
+int init_key_cache(ulong use_mem)
{
uint blocks,length;
- byte *extra_mem=0;
DBUG_ENTER("init_key_cache");
if (key_cache_inited && _my_disk_blocks > 0)
@@ -105,10 +104,6 @@ int init_key_cache(ulong use_mem,
/* No use to have very few blocks */
if (blocks >= 8 && _my_disk_blocks < 0)
{
-#if !defined(HAVE_ALLOCA) && !defined(THREAD)
- if ((extra_mem=my_malloc((uint) leave_this_much_mem,MYF(0))) == 0)
- goto err;
-#endif
for (;;)
{
/* Set my_hash_blocks to the next bigger 2 power */
@@ -138,21 +133,48 @@ int init_key_cache(ulong use_mem,
DBUG_PRINT("exit",("disk_blocks: %d block_root: %lx _my_hash_blocks: %d hash_root: %lx",
_my_disk_blocks,_my_block_root,_my_hash_blocks,
_my_hash_root));
-#if !defined(HAVE_ALLOCA) && !defined(THREAD)
- my_free(extra_mem,MYF(0));
-#endif
}
bzero((gptr) changed_blocks,sizeof(changed_blocks[0])*CHANGED_BLOCKS_HASH);
bzero((gptr) file_blocks,sizeof(file_blocks[0])*CHANGED_BLOCKS_HASH);
DBUG_RETURN((int) blocks);
+
err:
- if (extra_mem) /* purecov: inspected */
- my_free(extra_mem,MYF(0));
my_errno=ENOMEM;
DBUG_RETURN(0);
} /* init_key_cache */
+/*
+ Resize the key cache
+
+ SYNOPSIS
+ resize_key_cache()
+ use_mem Bytes to use for new key cache
+
+ RETURN VALUES
+ 0 Error
+ # number of blocks in key cache
+*/
+
+
+int resize_key_cache(ulong use_mem)
+{
+ int block;
+ pthread_mutex_lock(&THR_LOCK_keycache);
+ if (flush_all_key_blocks())
+ {
+ /* TODO: If this happens, we should write a warning in the log file ! */
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return 0;
+ }
+ end_key_cache();
+ /* The following will work even if memory is 0 */
+ block=init_key_cache(use_mem);
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return block;
+}
+
+
/* Remove key_cache from memory */
void end_key_cache(void)
@@ -264,6 +286,11 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
byte *start=buff;
uint read_length;
pthread_mutex_lock(&THR_LOCK_keycache);
+ if (_my_disk_blocks <= 0) /* Resize failed */
+ {
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ goto no_key_cache;
+ }
do
{
_my_cache_r_requests++;
@@ -300,6 +327,8 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
pthread_mutex_unlock(&THR_LOCK_keycache);
DBUG_RETURN(start);
}
+
+no_key_cache:
_my_cache_r_requests++;
_my_cache_read++;
if (my_pread(file,(byte*) buff,length,filepos,MYF(MY_NABP)))
@@ -336,6 +365,12 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
{ /* We have key_cacheing */
uint read_length;
pthread_mutex_lock(&THR_LOCK_keycache);
+ if (_my_disk_blocks <= 0) /* If resize failed */
+ {
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ goto no_key_cache;
+ }
+
_my_cache_w_requests++;
do
{
@@ -359,8 +394,11 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
} while ((length-= read_length));
error=0;
pthread_mutex_unlock(&THR_LOCK_keycache);
+ goto end;
}
- else if (dont_write)
+
+no_key_cache:
+ if (dont_write)
{ /* We must write, no cache */
_my_cache_w_requests++;
_my_cache_write++;
@@ -368,6 +406,7 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
error=1;
}
+
end:
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache",test_key_cache("end of key_cache_write",1););
@@ -507,6 +546,7 @@ static int cmp_sec_link(SEC_LINK **a, SEC_LINK **b)
((*a)->diskpos > (*b)->diskpos) ? 1 : 0);
}
+
static int flush_cached_blocks(File file, SEC_LINK **cache, uint count)
{
uint last_errno=0;
@@ -525,25 +565,23 @@ static int flush_cached_blocks(File file, SEC_LINK **cache, uint count)
}
-int flush_key_blocks(File file, enum flush_type type)
+static int flush_key_blocks_int(File file, enum flush_type type)
{
int error=0,last_errno=0;
uint count=0;
SEC_LINK *cache_buff[FLUSH_CACHE],**cache,**pos,**end;
SEC_LINK *used,*next;
- DBUG_ENTER("flush_key_blocks");
+ DBUG_ENTER("flush_key_blocks_int");
DBUG_PRINT("enter",("file: %d blocks_used: %d blocks_changed: %d",
file,_my_blocks_used,_my_blocks_changed));
- pthread_mutex_lock(&THR_LOCK_keycache);
-
-#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
- DBUG_EXECUTE("check_keycache",test_key_cache("start of flush_key_blocks",0););
-#endif
cache=cache_buff; /* If no key cache */
if (_my_disk_blocks > 0 &&
(!my_disable_flush_key_blocks || type != FLUSH_KEEP))
{
+#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
+ DBUG_EXECUTE("check_keycache",test_key_cache("start of flush_key_blocks",0););
+#endif
if (type != FLUSH_IGNORE_CHANGED)
{
/* Count how many key blocks we have to cache to be able to
@@ -614,22 +652,69 @@ int flush_key_blocks(File file, enum flush_type type)
free_block(used);
}
}
- }
#ifndef DBUG_OFF
- DBUG_EXECUTE("check_keycache",test_key_cache("end of flush_key_blocks",0););
+ DBUG_EXECUTE("check_keycache",test_key_cache("end of flush_key_blocks",0););
#endif
- pthread_mutex_unlock(&THR_LOCK_keycache);
+ }
if (cache != cache_buff)
my_free((gptr) cache,MYF(0));
if (last_errno)
errno=last_errno; /* Return first error */
DBUG_RETURN(last_errno != 0);
-} /* flush_key_blocks */
+}
+
+
+/*
+ Flush all blocks for a specific file to disk
+
+ SYNOPSIS
+ flush_all_key_blocks()
+ file File descriptor
+ type Type of flush operation
+
+ RETURN VALUES
+ 0 Ok
+ 1 Error
+*/
+
+int flush_key_blocks(File file, enum flush_type type)
+{
+ int res;
+ pthread_mutex_lock(&THR_LOCK_keycache);
+ res=flush_key_blocks_int(file, type);
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return res;
+}
+
+
+/*
+ Flush all blocks in the key cache to disk
+
+ SYNOPSIS
+ flush_all_key_blocks()
+
+ NOTE
+ We must have a lock on THR_LOCK_keycache before calling this function
+
+ RETURN VALUES
+ 0 Ok
+ 1 Error
+*/
+
+
+static int flush_all_key_blocks()
+{
+ int error=0;
+ while (_my_blocks_changed > 0)
+ if (flush_key_blocks_int(_my_used_first->file, FLUSH_RELEASE))
+ error=1;
+ return error;
+}
#ifndef DBUG_OFF
- /* Test if disk-cachee is ok */
+ /* Test if disk-cache is ok */
static void test_key_cache(const char *where, my_bool lock)
{
@@ -638,7 +723,14 @@ static void test_key_cache(const char *where, my_bool lock)
SEC_LINK *pos,**prev;
if (lock)
+ {
pthread_mutex_lock(&THR_LOCK_keycache);
+ if (_my_disk_blocks <= 0) /* No active key cache */
+ {
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return;
+ }
+ }
found=error=0;
for (i= 0 ; i < _my_hash_blocks ; i++)
{
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index b0eb8a8b2e5..436e557c914 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -25,7 +25,8 @@
static int findopt(char *optpat, uint length,
const struct my_option **opt_res,
char **ffname);
-static my_bool compare_strings(register const char *s, register const char *t,
+my_bool getopt_compare_strings(const char *s,
+ const char *t,
uint length);
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
static ulonglong getopt_ull(char *arg, const struct my_option *optp,
@@ -116,7 +117,7 @@ int handle_options(int *argc, char ***argv,
(*argc)--;
}
}
- else if (!compare_strings(cur_arg, "-set-variable", 13))
+ else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
{
must_be_var= 1;
if (cur_arg[13] == '=')
@@ -182,8 +183,8 @@ int handle_options(int *argc, char ***argv,
must_be_var= 1; /* option is followed by an argument */
for (i= 0; special_opt_prefix[i]; i++)
{
- if (!compare_strings(special_opt_prefix[i], cur_arg,
- special_opt_prefix_lengths[i]) &&
+ if (!getopt_compare_strings(special_opt_prefix[i], cur_arg,
+ special_opt_prefix_lengths[i]) &&
cur_arg[special_opt_prefix_lengths[i]] == '-')
{
/*
@@ -481,21 +482,21 @@ static int setval (const struct my_option *opts, char *argument,
the name in ffname argument
*/
-static int findopt (char *optpat, uint length,
- const struct my_option **opt_res,
- char **ffname)
+static int findopt(char *optpat, uint length,
+ const struct my_option **opt_res,
+ char **ffname)
{
int count;
struct my_option *opt= (struct my_option *) *opt_res;
for (count= 0; opt->name; opt++)
{
- if (!compare_strings(opt->name, optpat, length)) /* match found */
+ if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
{
(*opt_res)= opt;
if (!count)
- *ffname= (char *) opt->name; /* we only need to know one prev */
- if (length == strlen(opt->name)) /* exact match */
+ *ffname= (char *) opt->name; /* We only need to know one prev */
+ if (!opt->name[length]) /* Exact match */
return 1;
count++;
}
@@ -511,7 +512,7 @@ static int findopt (char *optpat, uint length,
2.) Returns -1 if strings differ, 0 if they are equal
*/
-static my_bool compare_strings(register const char *s, register const char *t,
+my_bool getopt_compare_strings(register const char *s, register const char *t,
uint length)
{
char const *end= s + length;
@@ -565,7 +566,7 @@ static longlong eval_num_suffix (char *argument, int *error, char *option_name)
In case of an error, set error value in *err.
*/
-static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
+longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
{
longlong num;
@@ -594,16 +595,23 @@ static ulonglong getopt_ull (char *arg, const struct my_option *optp, int *err)
ulonglong num;
num= eval_num_suffix(arg, err, (char*) optp->name);
+ return getopt_ull_limit_value(num, optp);
+}
+
+
+ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp)
+{
+ if ((ulonglong) num > (ulonglong) (ulong) optp->max_value &&
+ optp->max_value) /* if max value is not set -> no upper limit */
+ num= (ulonglong) (ulong) optp->max_value;
+ if (optp->block_size > 1)
+ {
+ num/= (ulonglong) optp->block_size;
+ num*= (ulonglong) optp->block_size;
+ }
if (num < (ulonglong) optp->min_value)
num= (ulonglong) optp->min_value;
- else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value
- && optp->max_value) /* if max value is not set -> no upper limit */
- num= (ulonglong) (ulong) optp->max_value;
- num= ((num - (ulonglong) optp->sub_size) / (optp->block_size ?
- (ulonglong) optp->block_size :
- 1L));
- return (ulonglong) (num * (optp->block_size ? (ulonglong) optp->block_size :
- 1L));
+ return num;
}
/*
diff --git a/sql/Makefile.am b/sql/Makefile.am
index e1ed9ad8915..4e1e78a149c 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -65,7 +65,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
net_serv.cc net_pkg.cc lock.cc my_lock.c \
sql_string.cc sql_manager.cc sql_map.cc \
mysqld.cc password.c hash_filo.cc hostname.cc \
- convert.cc sql_parse.cc sql_yacc.yy \
+ convert.cc set_var.cc sql_parse.cc sql_yacc.yy \
sql_base.cc table.cc sql_select.cc sql_insert.cc \
sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
procedure.cc item_uniq.cc sql_test.cc \
diff --git a/sql/convert.cc b/sql/convert.cc
index 75af13e0939..e4ae13d1e07 100644
--- a/sql/convert.cc
+++ b/sql/convert.cc
@@ -27,7 +27,7 @@
#include "mysql_priv.h"
/****************************************************************************
-** Convert tables
+ Convert tables
****************************************************************************/
/* Windows cp1251->koi8 and reverse conversion by Timur I. Bakeyev <translate@bat.ru> */
diff --git a/sql/field.cc b/sql/field.cc
index 88f4098ca0a..eb3dc7948d4 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -201,7 +201,7 @@ bool Field::send(THD *thd, String *packet)
String tmp(buff,sizeof(buff));
val_str(&tmp,&tmp);
CONVERT *convert;
- if ((convert=thd->convert_set))
+ if ((convert=thd->variables.convert_set))
return convert->store(packet,tmp.ptr(),tmp.length());
return net_store_data(packet,tmp.ptr(),tmp.length());
}
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 1fc884d8587..c6782aa0d93 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -318,7 +318,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
file->extra(HA_EXTRA_KEYREAD); // QQ is removed
next_pos=(byte*) 0; /* Find records in sequence */
file->rnd_init();
- file->extra(HA_EXTRA_CACHE); /* Quicker reads */
+ file->extra_opt(HA_EXTRA_CACHE,
+ current_thd->variables.read_buff_size);
}
for (;;)
@@ -920,7 +921,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length)
if (sortorder->field)
{
if (sortorder->field->type() == FIELD_TYPE_BLOB)
- sortorder->length= thd->variables.max_item_sort_length;
+ sortorder->length= thd->variables.max_sort_length;
else
{
sortorder->length=sortorder->field->pack_length();
@@ -956,7 +957,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length)
if (sortorder->item->maybe_null)
length++; // Place for NULL marker
}
- set_if_smaller(sortorder->length, thd->variables.max_item_sort_length);
+ set_if_smaller(sortorder->length, thd->variables.max_sort_length);
length+=sortorder->length;
}
sortorder->field= (Field*) 0; // end marker
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 0aace45da94..e34bfdea2dd 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -1701,7 +1701,7 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
DBUG_ASSERT(thd->transaction.stmt.bdb_tid == 0);
transaction=0; // Safety
/* First table lock, start transaction */
- if ((thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN |
+ if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK)) &&
!thd->transaction.all.bdb_tid)
{
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 8bb866341b7..e85965de60c 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -3176,7 +3176,7 @@ ha_innobase::external_lock(
thd->transaction.all.innodb_active_trans = 1;
trx->n_mysql_tables_in_use++;
- if (thd->tx_isolation == ISO_SERIALIZABLE
+ if (thd->variables.tx_isolation == ISO_SERIALIZABLE
&& prebuilt->select_lock_type == LOCK_NONE) {
/* To get serializable execution we let InnoDB
@@ -3204,7 +3204,7 @@ ha_innobase::external_lock(
innobase_release_stat_resources(trx);
if (!(thd->options
- & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) {
+ & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
innobase_commit(thd, trx);
thd->transaction.all.innodb_active_trans=0;
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 172584c84ca..6ff59babeb4 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -30,7 +30,6 @@
#include "../myisam/myisamdef.h"
#endif
-ulong myisam_sort_buffer_size;
ulong myisam_recover_options= HA_RECOVER_NONE;
/* bits in myisam_recover_options */
@@ -218,10 +217,10 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
return (my_errno ? my_errno : -1);
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
- VOID(mi_extra(file,HA_EXTRA_NO_WAIT_LOCK));
+ VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
- VOID(mi_extra(file,HA_EXTRA_WAIT_LOCK));
+ VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
if (!table->db_record_offset)
int_table_flags|=HA_REC_NOT_IN_SEQ;
return (0);
@@ -665,13 +664,16 @@ void ha_myisam::deactivate_non_unique_index(ha_rows rows)
if (share->state.key_map == ((ulonglong) 1L << share->base.keys)-1)
{
if (!(specialflag & SPECIAL_SAFE_MODE))
- if (rows==HA_POS_ERROR)
- mi_extra(file, HA_EXTRA_NO_KEYS);
+ {
+ if (rows == HA_POS_ERROR)
+ mi_extra(file, HA_EXTRA_NO_KEYS, 0);
else
{
mi_disable_non_unique_index(file,rows);
- mi_extra(file, HA_EXTRA_BULK_INSERT_BEGIN);
+ ha_myisam::extra_opt(HA_EXTRA_BULK_INSERT_BEGIN,
+ current_thd->variables.bulk_insert_buff_size);
}
+ }
enable_activate_all_index=1;
}
else
@@ -686,7 +688,7 @@ bool ha_myisam::activate_all_index(THD *thd)
MYISAM_SHARE* share = file->s;
DBUG_ENTER("activate_all_index");
- mi_extra(file, HA_EXTRA_BULK_INSERT_END);
+ mi_extra(file, HA_EXTRA_BULK_INSERT_END, 0);
if (enable_activate_all_index &&
share->state.key_map != set_bits(ulonglong, share->base.keys))
{
@@ -697,7 +699,7 @@ bool ha_myisam::activate_all_index(THD *thd)
param.testflag = (T_SILENT | T_REP_BY_SORT | T_QUICK |
T_CREATE_MISSING_KEYS);
param.myf_rw&= ~MY_WAIT_IF_FULL;
- param.sort_buffer_length= myisam_sort_buffer_size;
+ param.sort_buffer_length= thd->variables.myisam_sort_buff_size;
param.tmpdir=mysql_tmpdir;
error=repair(thd,param,0) != HA_ADMIN_OK;
thd->proc_info=save_proc_info;
@@ -828,8 +830,7 @@ int ha_myisam::rnd_init(bool scan)
{
if (scan)
return mi_scan_init(file);
- else
- return mi_extra(file,HA_EXTRA_RESET);
+ return mi_extra(file, HA_EXTRA_RESET, 0);
}
int ha_myisam::rnd_next(byte *buf)
@@ -921,17 +922,27 @@ void ha_myisam::info(uint flag)
int ha_myisam::extra(enum ha_extra_function operation)
{
- if (((specialflag & SPECIAL_SAFE_MODE) || (test_flags & TEST_NO_EXTRA)) &&
+ if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_KEYREAD)
+ return 0;
+ return mi_extra(file, operation, 0);
+}
+
+
+/* To be used with WRITE_CACHE, EXTRA_CACHE and BULK_INSERT_BEGIN */
+
+int ha_myisam::extra_opt(enum ha_extra_function operation, ulong cache_size)
+{
+ if ((specialflag & SPECIAL_SAFE_MODE) &
(operation == HA_EXTRA_WRITE_CACHE ||
- operation == HA_EXTRA_KEYREAD ||
operation == HA_EXTRA_BULK_INSERT_BEGIN))
return 0;
- return mi_extra(file,operation);
+ return mi_extra(file, operation, (void*) &cache_size);
}
+
int ha_myisam::reset(void)
{
- return mi_extra(file,HA_EXTRA_RESET);
+ return mi_extra(file, HA_EXTRA_RESET, 0);
}
int ha_myisam::delete_all_rows()
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h
index e7f426bb76c..95ebbd87c96 100644
--- a/sql/ha_myisam.h
+++ b/sql/ha_myisam.h
@@ -100,6 +100,7 @@ class ha_myisam: public handler
my_off_t row_position() { return mi_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
+ int extra_opt(enum ha_extra_function operation, ulong cache_size);
int reset(void);
int external_lock(THD *thd, int lock_type);
int delete_all_rows(void);
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 4e09c87f341..2c32fe34285 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -49,10 +49,10 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref);
if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED ||
test_if_locked == HA_OPEN_ABORT_IF_LOCKED))
- myrg_extra(file,HA_EXTRA_NO_WAIT_LOCK);
+ myrg_extra(file,HA_EXTRA_NO_WAIT_LOCK,0);
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
- myrg_extra(file,HA_EXTRA_WAIT_LOCK);
+ myrg_extra(file,HA_EXTRA_WAIT_LOCK,0);
if (table->reclength != mean_rec_length && mean_rec_length)
{
DBUG_PRINT("error",("reclength: %d mean_rec_length: %d",
@@ -155,7 +155,7 @@ int ha_myisammrg::index_last(byte * buf)
int ha_myisammrg::rnd_init(bool scan)
{
- return myrg_extra(file,HA_EXTRA_RESET);
+ return myrg_extra(file,HA_EXTRA_RESET,0);
}
int ha_myisammrg::rnd_next(byte *buf)
@@ -210,12 +210,25 @@ int ha_myisammrg::extra(enum ha_extra_function operation)
if (operation == HA_EXTRA_FORCE_REOPEN ||
operation == HA_EXTRA_PREPARE_FOR_DELETE)
return 0;
- return myrg_extra(file,operation);
+ return myrg_extra(file,operation,0);
}
+
+/* To be used with WRITE_CACHE, EXTRA_CACHE and BULK_INSERT_BEGIN */
+
+int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size)
+{
+ if ((specialflag & SPECIAL_SAFE_MODE) &
+ (operation == HA_EXTRA_WRITE_CACHE ||
+ operation == HA_EXTRA_BULK_INSERT_BEGIN))
+ return 0;
+ return myrg_extra(file, operation, (void*) &cache_size);
+}
+
+
int ha_myisammrg::reset(void)
{
- return myrg_extra(file,HA_EXTRA_RESET);
+ return myrg_extra(file,HA_EXTRA_RESET,0);
}
int ha_myisammrg::external_lock(THD *thd, int lock_type)
diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h
index 2b9d7433d2f..c93d37ec687 100644
--- a/sql/ha_myisammrg.h
+++ b/sql/ha_myisammrg.h
@@ -72,6 +72,7 @@ class ha_myisammrg: public handler
my_off_t row_position() { return myrg_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
+ int extra_opt(enum ha_extra_function operation, ulong cache_size);
int reset(void);
int external_lock(THD *thd, int lock_type);
uint lock_count(void) const;
diff --git a/sql/handler.cc b/sql/handler.cc
index 25617d95075..7b84c788205 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -53,8 +53,10 @@ const char *ha_table_type[] = {
"MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNODB", "GEMINI", "?", "?",NullS
};
-TYPELIB ha_table_typelib= {array_elements(ha_table_type)-4,"",
- ha_table_type+1};
+TYPELIB ha_table_typelib=
+{
+ array_elements(ha_table_type)-3, "", ha_table_type
+};
const char *ha_row_type[] = {
"", "FIXED", "DYNAMIC", "COMPRESSED","?","?","?"
@@ -216,7 +218,7 @@ int ha_autocommit_or_rollback(THD *thd, int error)
}
else
(void) ha_rollback_stmt(thd);
- thd->tx_isolation=thd->session_tx_isolation;
+ thd->variables.tx_isolation=thd->session_tx_isolation;
}
#endif
DBUG_RETURN(error);
@@ -314,7 +316,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
#endif /*HAVE_QUERY_CACHE*/
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
sql_print_error("Error: Got error during commit; Binlog is not up to date!");
- thd->tx_isolation=thd->session_tx_isolation;
+ thd->variables.tx_isolation=thd->session_tx_isolation;
if (operation_done)
{
statistic_increment(ha_commit_count,&LOCK_status);
@@ -362,7 +364,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
- thd->tx_isolation=thd->session_tx_isolation;
+ thd->variables.tx_isolation=thd->session_tx_isolation;
if (operation_done)
{
statistic_increment(ha_rollback_count,&LOCK_status);
@@ -865,8 +867,14 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
void ha_key_cache(void)
{
if (keybuff_size)
- (void) init_key_cache(keybuff_size,0);
-} /* ha_key_cache */
+ (void) init_key_cache(keybuff_size);
+}
+
+
+void ha_resize_key_cache(void)
+{
+ (void) resize_key_cache(keybuff_size);
+}
static int NEAR_F delete_file(const char *name,const char *ext,int extflag)
@@ -875,3 +883,9 @@ static int NEAR_F delete_file(const char *name,const char *ext,int extflag)
VOID(fn_format(buff,name,"",ext,extflag | 4));
return(my_delete_with_symlink(buff,MYF(MY_WME)));
}
+
+void st_ha_check_opt::init()
+{
+ flags= sql_flags= 0;
+ sort_buffer_size = current_thd->variables.myisam_sort_buff_size;
+}
diff --git a/sql/handler.h b/sql/handler.h
index 7984be87058..fcc6bc261e7 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -172,18 +172,13 @@ typedef struct st_ha_create_information
struct st_table;
typedef struct st_table TABLE;
-extern ulong myisam_sort_buffer_size;
typedef struct st_ha_check_opt
{
ulong sort_buffer_size;
uint flags; /* isam layer flags (e.g. for myisamchk) */
uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
- inline void init()
- {
- flags= sql_flags= 0;
- sort_buffer_size = myisam_sort_buffer_size;
- }
+ void init();
} HA_CHECK_OPT;
class handler :public Sql_alloc
@@ -285,6 +280,10 @@ public:
virtual my_off_t row_position() { return HA_OFFSET_ERROR; }
virtual void info(uint)=0;
virtual int extra(enum ha_extra_function operation)=0;
+ virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
+ {
+ return extra(operation);
+ }
virtual int reset()=0;
virtual int external_lock(THD *thd, int lock_type)=0;
virtual void unlock_row() {}
@@ -367,6 +366,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
int ha_delete_table(enum db_type db_type, const char *path);
void ha_drop_database(char* path);
void ha_key_cache(void);
+void ha_resize_key_cache(void);
int ha_start_stmt(THD *thd);
int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
my_off_t end_offset);
diff --git a/sql/item.cc b/sql/item.cc
index dac10eafafb..2b1e3b381c8 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -593,7 +593,7 @@ bool Item::send(THD *thd, String *packet)
String s(buff,sizeof(buff)),*res;
if (!(res=val_str(&s)))
return net_store_null(packet);
- if ((convert=thd->convert_set))
+ if ((convert=thd->variables.convert_set))
return convert->store(packet,res->ptr(),res->length());
return net_store_data(packet,res->ptr(),res->length());
}
diff --git a/sql/item.h b/sql/item.h
index 7612246b4b0..910db2fbddc 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -98,6 +98,7 @@ public:
const char *full_name() const;
};
+
class Item_field :public Item_ident
{
void set_field(Field *field);
@@ -193,6 +194,7 @@ class Item_uint :public Item_int
public:
Item_uint(const char *str_arg, uint length) :
Item_int(str_arg, (longlong) strtoull(str_arg,(char**) 0,10), length) {}
+ Item_uint(uint32 i) :Item_int((longlong) i, 10) {}
double val() { return ulonglong2double(value); }
String *val_str(String*);
void make_field(Send_field *field);
@@ -478,4 +480,3 @@ extern Item_buff *new_Item_buff(Item *item);
extern Item_result item_cmp_type(Item_result a,Item_result b);
extern Item *resolve_const_item(Item *item,Item *cmp_item);
extern bool field_is_equal_to_item(Field *field,Item *item);
-Item *get_system_var(LEX_STRING name);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 4ec4377509f..45b9b473934 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1761,7 +1761,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
bool Item_func_set_user_var::fix_fields(THD *thd,TABLE_LIST *tables)
{
if (!thd)
- thd=current_thd;
+ thd=current_thd; // Should never happen
if (Item_func::fix_fields(thd,tables) ||
!(entry= get_variable(&thd->user_vars, name, 1)))
return 1;
@@ -2269,21 +2269,35 @@ longlong Item_func_bit_xor::val_int()
/***************************************************************************
System variables
- This has to be recoded after we get more than 3 system variables
****************************************************************************/
-Item *get_system_var(LEX_STRING name)
+Item *get_system_var(enum_var_type var_type, LEX_STRING name)
{
- if (!my_strcasecmp(name.str,"IDENTITY"))
- return new Item_int((char*) "@@IDENTITY",
- current_thd->insert_id(),21);
if (!my_strcasecmp(name.str,"VERSION"))
return new Item_string("@@VERSION",server_version,
(uint) strlen(server_version));
- net_printf(&current_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str);
- return 0;
+
+ THD *thd=current_thd;
+ Item *item;
+ sys_var *var;
+ char buff[MAX_SYS_VAR_LENGTH+3];
+
+ if (!(var= find_sys_var(name.str)))
+ {
+ net_printf(&thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str);
+ return 0;
+ }
+ if (!(item=var->item(thd, var_type)))
+ return 0; // Impossible
+ thd->safe_to_cache_query=0;
+ buff[0]='@';
+ buff[1]='@';
+ memcpy(buff+2, var->name, var->name_length+1);
+ item->set_name(buff,var->name_length+2); // Will allocate name
+ return item;
}
+
/*
Check a user level lock.
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index f692ebc31ed..f074629e376 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -236,7 +236,8 @@ String *Item_func_concat::val_str(String *str)
goto null;
if (res2->length() == 0)
continue;
- if (res->length()+res2->length() > max_allowed_packet)
+ if (res->length()+res2->length() >
+ current_thd->variables.max_allowed_packet)
goto null; // Error check
if (res->alloced_length() >= res->length()+res2->length())
{ // Use old buffer
@@ -505,7 +506,7 @@ String *Item_func_concat_ws::val_str(String *str)
continue; // Skip NULL and empty string
if (res->length() + sep_str->length() + res2->length() >
- max_allowed_packet)
+ current_thd->variables.max_allowed_packet)
goto null; // Error check
if (res->alloced_length() >=
res->length() + sep_str->length() + res2->length())
@@ -714,7 +715,8 @@ redo:
while (j != search_end)
if (*i++ != *j++) goto skipp;
offset= (int) (ptr-res->ptr());
- if (res->length()-from_length + to_length > max_allowed_packet)
+ if (res->length()-from_length + to_length >
+ current_thd->variables.max_allowed_packet)
goto null;
if (!alloced)
{
@@ -734,7 +736,8 @@ skipp:
#endif /* USE_MB */
do
{
- if (res->length()-from_length + to_length > max_allowed_packet)
+ if (res->length()-from_length + to_length >
+ current_thd->variables.max_allowed_packet)
goto null;
if (!alloced)
{
@@ -794,7 +797,8 @@ String *Item_func_insert::val_str(String *str)
return res; // Wrong param; skip insert
if (length > res->length()-start)
length=res->length()-start;
- if (res->length() - length + res2->length() > max_allowed_packet)
+ if (res->length() - length + res2->length() >
+ current_thd->variables.max_allowed_packet)
goto null; // OOM check
res=copy_if_not_alloced(str,res,res->length());
res->replace(start,length,*res2);
@@ -1699,7 +1703,8 @@ String *Item_func_repeat::val_str(String *str)
if (count == 1) // To avoid reallocs
return res;
length=res->length();
- if (length > max_allowed_packet/count)// Safe length check
+ // Safe length check
+ if (length > current_thd->variables.max_allowed_packet/count)
goto err; // Probably an error
tot_length= length*(uint) count;
if (!(res= alloc_buffer(res,str,&tmp_value,tot_length)))
@@ -1757,7 +1762,8 @@ String *Item_func_rpad::val_str(String *str)
return (res);
}
length_pad= rpad->length();
- if ((ulong) count > max_allowed_packet || args[2]->null_value || !length_pad)
+ if ((ulong) count > current_thd->variables.max_allowed_packet ||
+ args[2]->null_value || !length_pad)
goto err;
if (!(res= alloc_buffer(res,str,&tmp_value,count)))
goto err;
@@ -1816,7 +1822,8 @@ String *Item_func_lpad::val_str(String *str)
return (res);
}
length_pad= lpad->length();
- if (count > max_allowed_packet || args[2]->null_value || !length_pad)
+ if (count > current_thd->variables.max_allowed_packet ||
+ args[2]->null_value || !length_pad)
goto err;
if (res->alloced_length() < count)
@@ -1937,7 +1944,7 @@ String *Item_load_file::val_str(String *str)
/* my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), file_name->c_ptr()); */
goto err;
}
- if (stat_info.st_size > (long) max_allowed_packet)
+ if (stat_info.st_size > (long) current_thd->variables.max_allowed_packet)
{
/* my_error(ER_TOO_LONG_STRING, MYF(0), file_name->c_ptr()); */
goto err;
diff --git a/sql/key.cc b/sql/key.cc
index d2f483e3d73..d103c07eb72 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -59,7 +59,7 @@ int find_ref_key(TABLE *table,Field *field, uint *key_length)
{
if (key_part->offset == fieldpos)
return(i); /* Use this key */
- *key_length+=key_part->length;
+ *key_length+=key_part->store_length;
}
}
return(-1); /* No key is ok */
diff --git a/sql/lex.h b/sql/lex.h
index 81d597c6a5c..df80b38950d 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -61,7 +61,6 @@ static SYMBOL symbols[] = {
{ "AVG", SYM(AVG_SYM),0,0},
{ "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH),0,0},
{ "AUTO_INCREMENT", SYM(AUTO_INC),0,0},
- { "AUTOCOMMIT", SYM(AUTOCOMMIT),0,0},
{ "BACKUP", SYM(BACKUP_SYM),0,0},
{ "BEGIN", SYM(BEGIN_SYM),0,0},
{ "BERKELEYDB", SYM(BERKELEY_DB_SYM),0,0},
@@ -117,7 +116,6 @@ static SYMBOL symbols[] = {
{ "DELAYED", SYM(DELAYED_SYM),0,0},
{ "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0},
{ "DELETE", SYM(DELETE_SYM),0,0},
- { "DEMAND", SYM(DEMAND_SYM),0,0},
{ "DESC", SYM(DESC),0,0},
{ "DESCRIBE", SYM(DESCRIBE),0,0},
{ "DIRECTORY", SYM(DIRECTORY_SYM),0,0},
@@ -182,7 +180,6 @@ static SYMBOL symbols[] = {
{ "INNOBASE", SYM(INNOBASE_SYM),0,0},
{ "INNODB", SYM(INNOBASE_SYM),0,0},
{ "INSERT", SYM(INSERT),0,0},
- { "INSERT_ID", SYM(INSERT_ID),0,0},
{ "INSERT_METHOD", SYM(INSERT_METHOD),0,0},
{ "INT", SYM(INT_SYM),0,0},
{ "INTEGER", SYM(INT_SYM),0,0},
@@ -204,7 +201,6 @@ static SYMBOL symbols[] = {
{ "KEYS", SYM(KEYS),0,0},
{ "KILL", SYM(KILL_SYM),0,0},
{ "LAST", SYM(LAST_SYM),0,0},
- { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0},
{ "LEADING", SYM(LEADING),0,0},
{ "LEFT", SYM(LEFT),0,0},
{ "LEVEL", SYM(LEVEL_SYM),0,0},
@@ -257,7 +253,6 @@ static SYMBOL symbols[] = {
{ "NOT", SYM(NOT),0,0},
{ "NULL", SYM(NULL_SYM),0,0},
{ "NUMERIC", SYM(NUMERIC_SYM),0,0},
- { "OFF", SYM(OFF),0,0},
{ "ON", SYM(ON),0,0},
{ "OPEN", SYM(OPEN_SYM),0,0},
{ "OPTIMIZE", SYM(OPTIMIZE),0,0},
@@ -317,27 +312,13 @@ static SYMBOL symbols[] = {
{ "SLAVE", SYM(SLAVE),0,0},
{ "SMALLINT", SYM(SMALLINT),0,0},
{ "SONAME", SYM(UDF_SONAME_SYM),0,0},
- { "SQL_AUTO_IS_NULL", SYM(SQL_AUTO_IS_NULL),0,0},
{ "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),0,0},
- { "SQL_BIG_SELECTS", SYM(SQL_BIG_SELECTS),0,0},
- { "SQL_BIG_TABLES", SYM(SQL_BIG_TABLES),0,0},
{ "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0},
{ "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0},
{ "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0},
- { "SQL_LOG_BIN", SYM(SQL_LOG_BIN),0,0},
- { "SQL_LOG_OFF", SYM(SQL_LOG_OFF),0,0},
- { "SQL_LOG_UPDATE", SYM(SQL_LOG_UPDATE),0,0},
- { "SQL_LOW_PRIORITY_UPDATES", SYM(SQL_LOW_PRIORITY_UPDATES),0,0},
- { "SQL_MAX_JOIN_SIZE",SYM(SQL_MAX_JOIN_SIZE), 0, 0},
{ "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0},
- { "SQL_QUERY_CACHE_TYPE",SYM(SQL_QUERY_CACHE_TYPE_SYM), 0, 0},
- { "SQL_QUOTE_SHOW_CREATE",SYM(SQL_QUOTE_SHOW_CREATE), 0, 0},
- { "SQL_SAFE_UPDATES", SYM(SQL_SAFE_UPDATES),0,0},
- { "SQL_SELECT_LIMIT", SYM(SQL_SELECT_LIMIT),0,0},
- { "SQL_SLAVE_SKIP_COUNTER", SYM(SQL_SLAVE_SKIP_COUNTER),0,0},
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
- { "SQL_THREAD", SYM(SQL_THREAD),0,0},
- { "SQL_WARNINGS", SYM(SQL_WARNINGS),0,0},
+ { "SQL_THREAD", SYM(SQL_THREAD),0,0},
{ "SSL", SYM(SSL_SYM),0,0},
{ "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0},
{ "START", SYM(START_SYM),0,0},
@@ -458,6 +439,7 @@ static SYMBOL sql_functions[] = {
{ "INSTR", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_instr)},
{ "ISNULL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)},
{ "IS_FREE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)},
+ { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0},
{ "LCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)},
{ "LEAST", SYM(LEAST_SYM),0,0},
{ "LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
diff --git a/sql/log.cc b/sql/log.cc
index f8bcd05510d..95f6319231d 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -937,11 +937,11 @@ bool MYSQL_LOG::write(Log_event* event_info)
if (e.write(file))
goto err;
}
- if (thd && thd->convert_set)
+ if (thd && thd->variables.convert_set)
{
char buf[1024] = "SET CHARACTER SET ";
char* p = strend(buf);
- p = strmov(p, thd->convert_set->name);
+ p = strmov(p, thd->variables.convert_set->name);
int save_query_length = thd->query_length;
// just in case somebody wants it later
thd->query_length = (uint)(p - buf);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 6765ecc5b1f..52e97310d75 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -446,7 +446,8 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
goto end;
}
data_len= uint4korr(buf + EVENT_LEN_OFFSET);
- if (data_len < LOG_EVENT_HEADER_LEN || data_len > max_allowed_packet)
+ if (data_len < LOG_EVENT_HEADER_LEN ||
+ data_len > current_thd->variables.max_allowed_packet)
{
result= ((data_len < LOG_EVENT_HEADER_LEN) ? LOG_READ_BOGUS :
@@ -480,6 +481,7 @@ end:
#ifndef MYSQL_CLIENT
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
+#define max_allowed_packet current_thd->variables.max_allowed_packet
#else
#define UNLOCK_MUTEX
#define LOCK_MUTEX
@@ -753,7 +755,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
thread_id(thd_arg->thread_id),
cache_stmt(using_trans &&
- (thd_arg->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
+ (thd_arg->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
time_t end_time;
time(&end_time);
@@ -1649,7 +1651,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
{
// master could be inconsistent, abort and tell DBA to check/fix it
thd->db = thd->query = 0;
- thd->convert_set = 0;
+ thd->variables.convert_set = 0;
close_thread_tables(thd);
free_root(&thd->mem_root,0);
return 1;
@@ -1658,7 +1660,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
thd->db= 0; // prevent db from being freed
thd->query= 0; // just to be sure
// assume no convert for next query unless set explictly
- thd->convert_set = 0;
+ thd->variables.convert_set = 0;
close_thread_tables(thd);
if (thd->query_error || thd->fatal_error)
diff --git a/sql/log_event.h b/sql/log_event.h
index bcdcc72e0c2..9b8145f14b0 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -214,8 +214,6 @@ class MYSQL_LOG;
class THD;
#endif
-extern uint32 server_id;
-
struct st_relay_log_info;
class Log_event
diff --git a/sql/mini_client.cc b/sql/mini_client.cc
index f8c930a2154..a50bef4bbca 100644
--- a/sql/mini_client.cc
+++ b/sql/mini_client.cc
@@ -20,12 +20,7 @@
Note: all file-global symbols must begin with mc_ , even the static ones, just
in case we decide to make them external at some point
- */
-
-#ifdef EMBEDDED_LIBRARY
-#define net_read_timeout net_read_timeout1
-#define net_write_timeout net_write_timeout1
-#endif
+*/
#include <my_global.h>
/* my_pthread must be included early to be able to fix things */
@@ -51,8 +46,6 @@
#define ER CER
#endif
-extern ulong net_read_timeout;
-
extern "C" { // Because of SCO 3.2V4.2
#include <sys/stat.h>
#include <signal.h>
@@ -404,7 +397,8 @@ int mc_mysql_errno(MYSQL *mysql)
return (mysql)->net.last_errno;
}
-my_bool mc_mysql_reconnect(MYSQL *mysql)
+
+my_bool mc_mysql_reconnect(MYSQL *mysql)
{
MYSQL tmp_mysql;
DBUG_ENTER("mc_mysql_reconnect");
@@ -415,8 +409,8 @@ my_bool mc_mysql_reconnect(MYSQL *mysql)
mc_mysql_init(&tmp_mysql);
tmp_mysql.options=mysql->options;
if (!mc_mysql_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
- mysql->db, mysql->port, mysql->unix_socket,
- mysql->client_flag))
+ mysql->db, mysql->port, mysql->unix_socket,
+ mysql->client_flag, mysql->net.read_timeout))
{
tmp_mysql.reconnect=0;
mc_mysql_close(&tmp_mysql);
@@ -489,8 +483,9 @@ mc_simple_command(MYSQL *mysql,enum enum_server_command command,
MYSQL *
mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *passwd, const char *db,
- uint port, const char *unix_socket,uint client_flag)
+ const char *passwd, const char *db,
+ uint port, const char *unix_socket,uint client_flag,
+ uint net_read_timeout)
{
char buff[100],*end,*host_info;
my_socket sock;
@@ -499,7 +494,8 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
ulong pkt_length;
NET *net= &mysql->net;
thr_alarm_t alarmed;
- ALARM alarm_buff;
+ ALARM alarm_buff;
+ ulong max_allowed_packet;
#ifdef __WIN__
HANDLE hPipe=INVALID_HANDLE_VALUE;
@@ -514,7 +510,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
db ? db : "(Null)",
user ? user : "(Null)"));
thr_alarm_init(&alarmed);
- thr_alarm(&alarmed,(uint) net_read_timeout,&alarm_buff);
+ thr_alarm(&alarmed, net_read_timeout, &alarm_buff);
bzero((char*) &mysql->options,sizeof(mysql->options));
net->vio = 0; /* If something goes wrong */
@@ -778,6 +774,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
DBUG_PRINT("info", ("IO layer change done!"));
}
#endif /* HAVE_OPENSSL */
+ max_allowed_packet=mysql->net.max_packet;
int3store(buff+2,max_allowed_packet);
diff --git a/sql/mini_client.h b/sql/mini_client.h
index 6721b072080..24c13646170 100644
--- a/sql/mini_client.h
+++ b/sql/mini_client.h
@@ -19,23 +19,18 @@
MYSQL* mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *passwd, const char *db,
- uint port, const char *unix_socket,uint client_flag);
-
-int mc_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
- uint length, my_bool skipp_check);
+ const char *passwd, const char *db,
+ uint port, const char *unix_socket,uint client_flag,
+ uint net_read_timeout);
+int mc_simple_command(MYSQL *mysql,enum enum_server_command command,
+ const char *arg, uint length, my_bool skipp_check);
void mc_mysql_close(MYSQL *mysql);
-
-MYSQL * mc_mysql_init(MYSQL *mysql);
-
+MYSQL *mc_mysql_init(MYSQL *mysql);
void mc_mysql_debug(const char *debug);
-
ulong mc_net_safe_read(MYSQL *mysql);
-
-char * mc_mysql_error(MYSQL *mysql);
+char *mc_mysql_error(MYSQL *mysql);
int mc_mysql_errno(MYSQL *mysql);
my_bool mc_mysql_reconnect(MYSQL* mysql);
-
int mc_mysql_send_query(MYSQL* mysql, const char* query, uint length);
int mc_mysql_read_query_result(MYSQL *mysql);
int mc_mysql_query(MYSQL *mysql, const char *query, uint length);
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 1ac3fed5721..94a39ebc380 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -14,14 +14,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifndef _MYSQL_PRIV_H
-#define _MYSQL_PRIV_H
-
#include <my_global.h>
-#include "mysql_embed.h"
+#include <mysql_version.h>
+#include <mysql_embed.h>
#include <my_sys.h>
#include <m_string.h>
-#include <mysql_version.h>
#include <hash.h>
#include <signal.h>
#include <thr_lock.h>
@@ -165,15 +162,14 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
#define OPTION_BIG_SELECTS 1024 /* for SQL OPTION */
#define OPTION_LOG_OFF 2048
#define OPTION_UPDATE_LOG 4096 /* update log flag */
-#define OPTION_LOW_PRIORITY_UPDATES 8192
#define OPTION_WARNINGS 16384
#define OPTION_AUTO_IS_NULL 32768
#define OPTION_FOUND_COMMENT 65536L
#define OPTION_SAFE_UPDATES OPTION_FOUND_COMMENT*2
#define OPTION_BUFFER_RESULT OPTION_SAFE_UPDATES*2
#define OPTION_BIN_LOG OPTION_BUFFER_RESULT*2
-#define OPTION_NOT_AUTO_COMMIT OPTION_BIN_LOG*2
-#define OPTION_BEGIN OPTION_NOT_AUTO_COMMIT*2
+#define OPTION_NOT_AUTOCOMMIT OPTION_BIN_LOG*2
+#define OPTION_BEGIN OPTION_NOT_AUTOCOMMIT*2
#define OPTION_TABLE_LOCK OPTION_BEGIN*2
#define OPTION_QUICK OPTION_TABLE_LOCK*2
#define OPTION_QUOTE_SHOW_CREATE OPTION_QUICK*2
@@ -295,6 +291,9 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags);
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists);
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
bool log_query);
+int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables,
+ bool if_exists,
+ bool log_query);
int quick_rm_table(enum db_type base,const char *db,
const char *table_name);
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
@@ -469,7 +468,7 @@ void mysqld_list_processes(THD *thd,const char *user,bool verbose);
int mysqld_show_status(THD *thd);
int mysqld_show_variables(THD *thd,const char *wild);
int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
- struct system_variables *variable_values);
+ enum enum_var_type value_type);
/* sql_handler.cc */
int mysql_ha_open(THD *thd, TABLE_LIST *tables);
@@ -579,29 +578,66 @@ void open_log(MYSQL_LOG *log, const char *hostname,
enum_log_type type, bool read_append = 0,
bool no_auto_events = 0);
-extern uint32 server_id;
+/*
+ External variables
+*/
+
+extern time_t start_time;
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
- max_sort_char, mysql_real_data_home[];
+ max_sort_char, mysql_real_data_home[], *charsets_list;
extern my_string mysql_tmpdir;
+extern const char *command_name[];
extern const char *first_keyword, *localhost, *delayed_user;
-extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables,
- created_tmp_tables, created_tmp_disk_tables,
- aborted_threads,aborted_connects,
- delayed_insert_timeout,
- delayed_insert_limit, delayed_queue_size,
- delayed_insert_threads, delayed_insert_writes,
- delayed_rows_in_use,delayed_insert_errors;
+extern const char **errmesg; /* Error messages */
+extern const char *myisam_recover_options_str;
+extern uchar *days_in_month;
+extern char language[LIBLEN],reg_ext[FN_EXTLEN];
+extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
+extern char pidfile_name[FN_REFLEN], time_zone[30], *opt_init_file;
+extern char blob_newline;
+extern double log_10[32];
+extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
+extern ulong created_tmp_tables, created_tmp_disk_tables;
+extern ulong aborted_threads,aborted_connects;
+extern ulong delayed_insert_timeout;
+extern ulong delayed_insert_limit, delayed_queue_size;
+extern ulong delayed_insert_threads, delayed_insert_writes;
+extern ulong delayed_rows_in_use,delayed_insert_errors;
extern ulong filesort_rows, filesort_range_count, filesort_scan_count;
extern ulong filesort_merge_passes;
extern ulong select_range_check_count, select_range_count, select_scan_count;
-extern ulong select_full_range_join_count,select_full_join_count,
- slave_open_temp_tables;
-extern uint test_flags,select_errors,ha_open_options;
+extern ulong select_full_range_join_count,select_full_join_count;
+extern ulong slave_open_temp_tables, query_cache_size;
extern ulong thd_startup_options, slow_launch_threads, slow_launch_time;
-extern ulong query_cache_startup_type;
-extern time_t start_time;
-extern const char *command_name[];
-extern I_List<THD> threads;
+extern ulong server_id;
+extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count;
+extern ulong ha_read_key_count, ha_read_next_count, ha_read_prev_count;
+extern ulong ha_read_first_count, ha_read_last_count;
+extern ulong ha_read_rnd_count, ha_read_rnd_next_count;
+extern ulong ha_commit_count, ha_rollback_count, mysqld_net_retry_count;
+extern ulong keybuff_size,table_cache_size;
+extern ulong max_connections,max_connect_errors, connect_timeout;
+extern ulong max_insert_delayed_threads, max_user_connections;
+extern ulong long_query_count, what_to_log,flush_time,opt_sql_mode;
+extern ulong query_buff_size, thread_stack,thread_stack_min;
+extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
+extern ulong max_binlog_size, rpl_recovery_rank, thread_cache_size;
+extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log;
+extern ulong specialflag, current_pid;
+
+extern uint test_flags,select_errors,ha_open_options;
+extern uint protocol_version,dropping_tables;
+extern bool opt_endinfo, using_udf_functions, locked_in_memory;
+extern bool opt_using_transactions, use_temp_pool, mysql_embedded;
+extern bool using_update_log, opt_large_files;
+extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
+extern bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
+extern bool opt_disable_networking, opt_skip_show_db;
+extern bool volatile abort_loop, shutdown_in_progress, grant_option;
+extern uint volatile thread_count, thread_running, global_read_lock;
+extern my_bool opt_safe_show_db, opt_local_infile, lower_case_table_names;
+extern char f_fyllchar;
+
extern MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern FILE *bootstrap_file;
extern pthread_key(MEM_ROOT*,THR_MALLOC);
@@ -613,53 +649,22 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_server_id, LOCK_slave_list, LOCK_active_mi, LOCK_manager,
LOCK_global_system_variables;
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
-
extern pthread_attr_t connection_attrib;
-extern bool opt_endinfo, using_udf_functions, locked_in_memory,
- opt_using_transactions, use_temp_pool, mysql_embedded;
-extern char f_fyllchar;
-extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
- ha_read_key_count, ha_read_next_count, ha_read_prev_count,
- ha_read_first_count, ha_read_last_count,
- ha_read_rnd_count, ha_read_rnd_next_count,
- ha_commit_count, ha_rollback_count;
+extern I_List<THD> threads;
extern MY_BITMAP temp_pool;
-extern uchar *days_in_month;
extern DATE_FORMAT dayord;
-extern double log_10[32];
-extern uint protocol_version,dropping_tables;
-extern ulong keybuff_size,table_cache_size,
- max_connections,max_connect_errors,
- max_insert_delayed_threads, max_user_connections,
- long_query_count,
- net_read_timeout,net_write_timeout,
- what_to_log,flush_time,opt_sql_mode,
- query_buff_size, lower_case_table_names,
- thread_stack,thread_stack_min,
- binlog_cache_size, max_binlog_cache_size;
-extern ulong com_stat[(uint) SQLCOM_END], com_other;
-extern ulong specialflag, current_pid;
-extern bool low_priority_updates, using_update_log;
-extern bool opt_sql_bin_update, opt_safe_show_db,
- opt_safe_user_create, opt_no_mix_types;
-extern char language[LIBLEN],reg_ext[FN_EXTLEN],blob_newline;
-extern const char **errmesg; /* Error messages */
-extern const char *default_tx_isolation_name;
extern String empty_string;
-extern struct show_var_st init_vars[];
-extern struct show_var_st status_vars[];
+extern SHOW_VAR init_vars[],status_vars[], internal_vars[];
extern struct system_variables global_system_variables;
-extern enum db_type default_table_type;
-extern enum enum_tx_isolation default_tx_isolation;
-extern char glob_hostname[FN_REFLEN];
+extern struct system_variables max_system_variables;
+
+extern SHOW_COMP_OPTION have_isam, have_raid, have_openssl, have_symlink;
+extern SHOW_COMP_OPTION have_query_cache;
#ifndef __WIN__
extern pthread_t signal_thread;
#endif
-extern bool volatile abort_loop, shutdown_in_progress, grant_option;
-extern uint volatile thread_count, thread_running, global_read_lock;
-
MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **table,uint count);
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
@@ -757,11 +762,14 @@ void hostname_cache_free();
void hostname_cache_refresh(void);
bool get_interval_info(const char *str,uint length,uint count,
long *values);
-/* sql_cache */
+/* sql_cache.cc */
extern bool sql_cache_init();
extern void sql_cache_free();
extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
+/* item.cc */
+Item *get_system_var(enum_var_type var_type, LEX_STRING name);
+
/* Some inline functions for more speed */
inline bool add_item_to_list(Item *item)
@@ -786,5 +794,3 @@ inline void mark_as_null_row(TABLE *table)
table->status|=STATUS_NULL_ROW;
bfill(table->null_flags,table->null_bytes,255);
}
-
-#endif
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 17ad87b63c1..96a86a00b48 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -15,7 +15,6 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
-#include <mysql.h>
#include <m_ctype.h>
#include <my_dir.h>
#include "sql_acl.h"
@@ -240,31 +239,41 @@ SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_YES;
SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_NO;
#endif
-bool opt_skip_slave_start = 0; // If set, slave is not autostarted
+bool opt_large_files= sizeof(my_off_t) > 4;
+
+/*
+ Variables to store startup options
+*/
+bool opt_skip_slave_start = 0; // If set, slave is not autostarted
/*
If set, some standard measures to enforce slave data integrity will not
be performed
*/
bool opt_reckless_slave = 0;
+
+ulong back_log, connect_timeout;
+char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], time_zone[30];
+bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
+bool opt_disable_networking=0, opt_skip_show_db=0;
+my_bool opt_local_infile;
+
static bool opt_do_pstack = 0;
static ulong opt_specialflag=SPECIAL_ENGLISH;
-static ulong back_log,connect_timeout,concurrency;
+static ulong concurrency;
static ulong opt_myisam_block_size;
static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
static my_string opt_logname=0,opt_update_logname=0,
opt_binlog_index_name = 0,opt_slow_logname=0;
-static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
+
static char* mysql_home_ptr= mysql_home;
static char* pidfile_name_ptr= pidfile_name;
static pthread_t select_thread;
-static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
- opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
- opt_myisam_log=0,
- opt_large_files=sizeof(my_off_t) > 4;
-bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0,
- opt_show_slave_auth_info = 0, opt_old_rpl_compat = 0,
- opt_safe_user_create = 0, opt_no_mix_types = 0;
+static bool opt_noacl, opt_bootstrap=0, opt_myisam_log=0;
+bool opt_sql_bin_update = 0, opt_log_slave_updates = 0;
+bool opt_safe_user_create = 0, opt_no_mix_types = 0;
+my_bool opt_safe_show_db=0, lower_case_table_names, opt_old_rpl_compat;
+my_bool opt_show_slave_auth_info;
volatile bool mqh_used = 0;
FILE *bootstrap_file=0;
int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
@@ -277,8 +286,7 @@ int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
static bool kill_in_progress=FALSE;
static struct rand_struct sql_rand;
static int cleanup_done;
-static char **defaults_argv,time_zone[30];
-static const char *default_table_type_name;
+static char **defaults_argv;
char glob_hostname[FN_REFLEN];
#include "sslopt-vars.h"
@@ -293,7 +301,7 @@ I_List<i_string> replicate_do_db, replicate_ignore_db;
I_List<i_string> binlog_do_db, binlog_ignore_db;
/* if we guessed server_id , we need to know about it */
-uint32 server_id = 0;
+ulong server_id= 0; // Must be long becasue of set_var.cc
bool server_id_supplied = 0;
uint mysql_port;
@@ -308,16 +316,16 @@ struct system_variables max_system_variables;
ulong keybuff_size,table_cache_size,
thread_stack,
thread_stack_min,what_to_log= ~ (1L << (uint) COM_TIME),
- query_buff_size, lower_case_table_names, mysqld_net_retry_count,
+ query_buff_size, mysqld_net_retry_count,
slow_launch_time = 2L,
- net_read_timeout,net_write_timeout,slave_open_temp_tables=0,
+ slave_open_temp_tables=0,
open_files_limit=0, max_binlog_size;
ulong com_stat[(uint) SQLCOM_END], com_other;
ulong slave_net_timeout;
ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0;
ulong query_cache_size=0;
#ifdef HAVE_QUERY_CACHE
-ulong query_cache_limit=0, query_cache_startup_type=1;
+ulong query_cache_limit=0;
Query_cache query_cache;
#endif
@@ -339,7 +347,7 @@ bool master_ssl = 0;
ulong master_retry_count=0;
ulong bytes_sent = 0L, bytes_received = 0L;
-bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory;
+bool opt_endinfo,using_udf_functions, locked_in_memory;
bool opt_using_transactions, using_update_log;
bool volatile abort_loop,select_thread_in_use,grant_option;
bool volatile ready_to_exit,shutdown_in_progress;
@@ -361,11 +369,10 @@ ulong slow_launch_threads = 0;
char mysql_real_data_home[FN_REFLEN],
language[LIBLEN],reg_ext[FN_EXTLEN],
- default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
+ mysql_charsets_dir[FN_REFLEN], *charsets_list,
blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot,
*opt_init_file;
char *language_ptr= language;
-char *default_charset_ptr= default_charset;
#ifndef EMBEDDED_LIBRARY
char mysql_data_home_buff[2], *mysql_data_home=mysql_data_home_buff;
bool mysql_embedded=0;
@@ -381,12 +388,9 @@ const char *first_keyword="first";
const char **errmesg; /* Error messages */
const char *myisam_recover_options_str="OFF";
const char *sql_mode_str="OFF";
-const char *default_tx_isolation_name;
-enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED;
-
-uint rpl_recovery_rank=0;
+ulong rpl_recovery_rank=0;
-my_string mysql_unix_port=NULL, mysql_tmpdir=NULL, allocated_mysql_tmpdir=NULL;
+my_string mysql_unix_port=NULL, opt_mysql_tmpdir=NULL, mysql_tmpdir=NULL;
ulong my_bind_addr; /* the address we bind to */
DATE_FORMAT dayord;
double log_10[32]; /* 10 potences */
@@ -414,12 +418,11 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_server_id, LOCK_global_system_variables,
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
-pthread_cond_t COND_refresh,COND_thread_count,COND_binlog_update,
- COND_slave_stopped, COND_slave_start;
+pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped,
+ COND_slave_start;
pthread_cond_t COND_thread_cache,COND_flush_thread_cache;
pthread_t signal_thread;
pthread_attr_t connection_attrib;
-enum db_type default_table_type=DB_TYPE_MYISAM;
#ifdef __WIN__
#undef getpid
@@ -766,7 +769,7 @@ static pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
static sig_handler print_signal_warning(int sig)
{
- if (current_thd->variables.opt_warnings)
+ if (global_system_variables.log_warnings)
sql_print_error("Warning: Got signal %d from thread %d",
sig,my_thread_id());
#ifdef DONT_REMEMBER_SIGNAL
@@ -813,6 +816,7 @@ void clean_up(bool print_message)
hostname_cache_free();
item_user_lock_free();
lex_free(); /* Free some memory */
+ set_var_free();
#ifdef HAVE_DLOPEN
if (!opt_noacl)
udf_free();
@@ -832,9 +836,10 @@ void clean_up(bool print_message)
opt_ssl_key=opt_ssl_cert=opt_ssl_ca=opt_ssl_capath=0;
#endif /* HAVE_OPENSSL */
- free_defaults(defaults_argv);
+ if (defaults_argv)
+ free_defaults(defaults_argv);
my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR));
- my_free(allocated_mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
x_free(opt_bin_logname);
x_free(opt_relay_logname);
@@ -1048,8 +1053,8 @@ static void server_init(void)
PIPE_READMODE_BYTE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
- (int) net_buffer_length,
- (int) net_buffer_length,
+ (int) global_variables.net_buffer_length,
+ (int) global_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity )) == INVALID_HANDLE_VALUE)
{
@@ -1334,14 +1339,14 @@ We will try our best to scrape up some info that will hopefully help diagnose\n\
the problem, but since we have already crashed, something is definitely wrong\n\
and this may fail.\n\n");
fprintf(stderr, "key_buffer_size=%ld\n", keybuff_size);
- fprintf(stderr, "record_buffer=%ld\n", my_default_record_cache_size);
- fprintf(stderr, "sort_buffer=%ld\n", thd->variables.sortbuff_size);
+ fprintf(stderr, "read_buffer_size=%ld\n", global_system_variables.read_buff_size);
+ fprintf(stderr, "sort_buffer_size=%ld\n", thd->variables.sortbuff_size);
fprintf(stderr, "max_used_connections=%ld\n", max_used_connections);
fprintf(stderr, "max_connections=%ld\n", max_connections);
fprintf(stderr, "threads_connected=%d\n", thread_count);
fprintf(stderr, "It is possible that mysqld could use up to \n\
-key_buffer_size + (record_buffer + sort_buffer)*max_connections = %ld K\n\
-bytes of memory\n", (keybuff_size + (my_default_record_cache_size +
+key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = %ld K\n\
+bytes of memory\n", (keybuff_size + (global_system_variables.read_buff_size +
thd->variables.sortbuff_size) *
max_connections)/ 1024);
fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
@@ -1793,15 +1798,17 @@ int main(int argc, char **argv)
#endif
load_defaults("my",load_default_groups,&argc,&argv);
defaults_argv=argv;
- mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
+
+ /* Get default temporary directory */
+ opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
#if defined( __WIN__) || defined(OS2)
- if (!mysql_tmpdir)
- mysql_tmpdir=getenv("TEMP");
- if (!mysql_tmpdir)
- mysql_tmpdir=getenv("TMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TEMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TMP");
#endif
- if (!mysql_tmpdir || !mysql_tmpdir[0])
- mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
+ if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
+ opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
set_options();
get_options(argc,argv);
@@ -1841,7 +1848,7 @@ int main(int argc, char **argv)
(void) pthread_cond_init(&COND_rpl_status, NULL);
init_signals();
- if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
+ if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME)))
exit(1);
charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS));
@@ -1900,6 +1907,7 @@ int main(int argc, char **argv)
init_errmessage(); /* Read error messages from file */
lex_init();
item_init();
+ set_var_init();
mysys_uses_curses=0;
#ifdef USE_REGEX
regex_init();
@@ -2284,10 +2292,11 @@ static int bootstrap(FILE *file)
{
THD *thd= new THD;
int error;
+
thd->bootstrap=1;
thd->client_capabilities=0;
my_net_init(&thd->net,(st_vio*) 0);
- thd->max_packet_length=thd->net.max_packet;
+ thd->max_client_packet_length= thd->net.max_packet;
thd->master_access= ~0;
thd->thread_id=thread_id++;
thread_count++;
@@ -2332,7 +2341,7 @@ static void create_new_thread(THD *thd)
DBUG_ENTER("create_new_thread");
NET *net=&thd->net; // For easy ref
- net->timeout = (uint) connect_timeout; // Timeout for read
+ net->read_timeout = (uint) connect_timeout;
if (protocol_version > 9)
net->return_errno=1;
@@ -2663,8 +2672,8 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
PIPE_READMODE_BYTE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
- (int) net_buffer_length,
- (int) net_buffer_length,
+ (int) global_variables.net_buffer_length,
+ (int) global_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity )) ==
INVALID_HANDLE_VALUE )
@@ -2681,8 +2690,8 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
PIPE_READMODE_BYTE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
- (int) net_buffer_length,
- (int) net_buffer_length,
+ (int) global_variables.net_buffer_length,
+ (int) global_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity)) ==
INVALID_HANDLE_VALUE)
@@ -2800,14 +2809,14 @@ enum options {
OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH,
OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
- OPT_MAX_WRITE_LOCK_COUNT, OPT_MYISAM_BULK_INSERT_TREE_SIZE,
+ OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
- OPT_OPEN_FILES_LIMIT, OPT_QUERY_BUFFER_SIZE,
+ OPT_OPEN_FILES_LIMIT,
OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_SIZE,
- OPT_QUERY_CACHE_STARTUP_TYPE, OPT_RECORD_BUFFER,
+ OPT_QUERY_CACHE_TYPE, OPT_RECORD_BUFFER,
OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT,
OPT_SLAVE_NET_TIMEOUT, OPT_SLOW_LAUNCH_TIME,
OPT_SORT_BUFFER, OPT_TABLE_CACHE,
@@ -2832,7 +2841,7 @@ enum options {
#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
-static struct my_option my_long_options[] =
+struct my_option my_long_options[] =
{
{"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -2911,12 +2920,11 @@ static struct my_option my_long_options[] =
0, 0, 0, 0, 0, 0},
#endif /* HAVE_OPENSSL */
{"default-character-set", 'C', "Set the default character set",
- (gptr*) &default_charset_ptr, (gptr*) &default_charset_ptr, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ (gptr*) &sys_charset.value, (gptr*) &sys_charset.value, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"default-table-type", OPT_TABLE_TYPE,
- "Set the default table type for tables", (gptr*) &default_table_type_name,
- (gptr*) &default_table_type_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0,
- 0},
+ "Set the default table type for tables", 0, 0,
+ 0, GET_NO_ARG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE,
"Don't flush key buffers between writes for any MyISAM table", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -2980,8 +2988,8 @@ static struct my_option my_long_options[] =
0, 0, 0, 0, 0, 0},
{"local-infile", OPT_LOCAL_INFILE,
"Enable/disable LOAD DATA LOCAL INFILE (takes values 1|0)",
- (gptr*) &global_system_variables.opt_local_infile,
- (gptr*) &max_system_variables.opt_local_infile, 0, GET_BOOL, OPT_ARG,
+ (gptr*) &opt_local_infile,
+ (gptr*) &opt_local_infile, 0, GET_BOOL, OPT_ARG,
1, 0, 0, 0, 0, 0},
{"log-bin", OPT_BIN_LOG,
"Log queries in new binary format (for replication)",
@@ -3006,12 +3014,14 @@ static struct my_option my_long_options[] =
"Log some extra information to update log", 0, 0, 0, GET_NO_ARG, NO_ARG,
0, 0, 0, 0, 0, 0},
{"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
- "Tells the slave to log the updates from the slave thread to the binary log. Off by default. You will need to turn it on if you plan to daisy-chain the slaves.",
+ "Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves.",
(gptr*) &opt_log_slave_updates, (gptr*) &opt_log_slave_updates, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
- "INSERT/DELETE/UPDATE has lower priority than selects", 0, 0, 0, GET_NO_ARG,
- NO_ARG, 0, 0, 0, 0, 0, 0},
+ "INSERT/DELETE/UPDATE has lower priority than selects",
+ (gptr*) &global_system_variables.low_priority_updates,
+ (gptr*) &max_system_variables.low_priority_updates,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"master-host", OPT_MASTER_HOST,
"Master hostname or IP address for replication. If not set, the slave thread will not be started. Note that the setting of master-host will be ignored if there exists a valid master.info file.",
(gptr*) &master_host, (gptr*) &master_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
@@ -3083,14 +3093,15 @@ static struct my_option my_long_options[] =
{"new", 'n', "Use very new possible 'unsafe' functions", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef NOT_YET
- {"no-mix-table-types", OPT_NO_MIX_TYPE, "Undocumented",
+ {"no-mix-table-types", OPT_NO_MIX_TYPE, "Don't allow commands with uses two different table types",
(gptr*) &opt_no_mix_types, (gptr*) &opt_no_mix_types, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
#endif
{"old-protocol", 'o', "Use the old (3.20) protocol",
(gptr*) &protocol_version, (gptr*) &protocol_version, 0, GET_UINT, NO_ARG,
PROTOCOL_VERSION, 0, 0, 0, 0, 0},
- {"old-rpl-compat", OPT_OLD_RPL_COMPAT, "Undocumented",
+ {"old-rpl-compat", OPT_OLD_RPL_COMPAT,
+ "Use old LOAD DATA format in the binary log (don't save data in file)",
(gptr*) &opt_old_rpl_compat, (gptr*) &opt_old_rpl_compat, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef ONE_THREAD
@@ -3103,7 +3114,7 @@ static struct my_option my_long_options[] =
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection.", (gptr*) &mysql_port,
(gptr*) &mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"reckless-slave", OPT_RECKLESS_SLAVE, "Undocumented", 0, 0, 0, GET_NO_ARG,
+ {"reckless-slave", OPT_RECKLESS_SLAVE, "For debugging", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-do-db", OPT_REPLICATE_DO_DB,
"Tells the slave thread to restrict replication to the specified database. To specify more than one database, use the directive multiple times, once for each database. Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.%.",
@@ -3151,28 +3162,31 @@ static struct my_option my_long_options[] =
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef TO_BE_DELETED
{"safe-show-database", OPT_SAFE_SHOW_DB,
"Depricated option; One should use GRANT SHOW DATABASES instead...",
(gptr*) &opt_safe_show_db, (gptr*) &opt_safe_show_db, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
+#endif
{"safe-user-create", OPT_SAFE_USER_CREATE,
"Don't allow new user creation by the user who has no write privileges to the mysql.user table",
(gptr*) &opt_safe_user_create, (gptr*) &opt_safe_user_create, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"server-id", OPT_SERVER_ID,
"Uniquely identifies the server instance in the community of replication partners",
- (gptr*) &server_id, (gptr*) &server_id, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0,
+ (gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0,
0, 0, 0},
{"set-variable", 'O',
"Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO, "Undocumented",
+ {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO,
+ "Show user and password in SHOW SLAVE STATUS",
(gptr*) &opt_show_slave_auth_info, (gptr*) &opt_show_slave_auth_info, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"concurrent-insert", OPT_CONCURRENT_INSERT,
"Use concurrent insert with MyISAM. Disable with prefix --skip-",
(gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"delay-key-write", OPT_USE_DELAY_KEY_WRITE,
"Use delay_key_write option for all tables. Disable with prefix --skip-",
(gptr*) &myisam_delay_key_write, (gptr*) &myisam_delay_key_write, 0,
@@ -3237,11 +3251,11 @@ static struct my_option my_long_options[] =
"Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
(gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0},
- {"tmpdir", 't', "Path for temporary files", (gptr*) &mysql_tmpdir,
- (gptr*) &mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"tmpdir", 't', "Path for temporary files", (gptr*) &opt_mysql_tmpdir,
+ (gptr*) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"transaction-isolation", OPT_TX_ISOLATION,
- "Default transaction isolation level", (gptr*) &default_tx_isolation_name,
- (gptr*) &default_tx_isolation_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ "Default transaction isolation level", 0, 0, 0, GET_NO_ARG, REQUIRED_ARG, 0,
+ 0, 0, 0,
0, 0},
{"use-locking", OPT_USE_LOCKING, "Use system (external) locking",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -3256,9 +3270,13 @@ static struct my_option my_long_options[] =
NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'v', "Synonym for option -v", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
0, 0, 0, 0},
- {"warnings", 'W', "Log some not critical warnings to the log file",
- (gptr*) &global_system_variables.opt_warnings,
- (gptr*) &max_system_variables.opt_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ {"log-warnings", 'W', "Log some not critical warnings to the log file",
+ (gptr*) &global_system_variables.log_warnings,
+ (gptr*) &max_system_variables.log_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"warnings", 'W', "Deprecated ; Use --log-warnings instead",
+ (gptr*) &global_system_variables.log_warnings,
+ (gptr*) &max_system_variables.log_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
{ "back_log", OPT_BACK_LOG,
"The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.", (gptr*) &back_log, (gptr*) &back_log, 0, GET_ULONG,
@@ -3287,8 +3305,8 @@ static struct my_option my_long_options[] =
REQUIRED_ARG, 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE, 0},
{"connect_timeout", OPT_CONNECT_TIMEOUT,
"The number of seconds the mysqld server is waiting for a connect packet before responding with Bad handshake",
- (gptr*) &connect_timeout, (gptr*) &connect_timeout, 0, GET_ULONG,
- REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
+ (gptr*) &connect_timeout, (gptr*) &connect_timeout,
+ 0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
{"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
"How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
(gptr*) &delayed_insert_timeout, (gptr*) &delayed_insert_timeout, 0,
@@ -3385,11 +3403,11 @@ static struct my_option my_long_options[] =
"If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive.",
(gptr*) &lower_case_table_names,
(gptr*) &lower_case_table_names, 0,
- GET_ULONG, REQUIRED_ARG, IF_WIN(1,0), 0, 1, 0, 1, 0},
+ GET_BOOL, REQUIRED_ARG, IF_WIN(1,0), 0, 1, 0, 1, 0},
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
"Max packetlength to send/receive from to server.",
- (gptr*) &max_allowed_packet,
- (gptr*) &max_allowed_packet, 0, GET_ULONG,
+ (gptr*) &global_system_variables.max_allowed_packet,
+ (gptr*) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
REQUIRED_ARG, 1024*1024L, 80, 64*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
{"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
"Can be used to restrict the total size used to cache a multi-transaction query.",
@@ -3423,8 +3441,8 @@ static struct my_option my_long_options[] =
~0L, 1, ~0L, 0, 1, 0},
{"max_sort_length", OPT_MAX_SORT_LENGTH,
"The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).",
- (gptr*) &global_system_variables.max_item_sort_length,
- (gptr*) &max_system_variables.max_item_sort_length, 0, GET_ULONG,
+ (gptr*) &global_system_variables.max_sort_length,
+ (gptr*) &max_system_variables.max_sort_length, 0, GET_ULONG,
REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
{"max_tmp_tables", OPT_MAX_TMP_TABLES,
"Maximum number of temporary tables a client can keep open at a time.",
@@ -3439,58 +3457,56 @@ static struct my_option my_long_options[] =
"After this many write locks, allow some read locks to run in between.",
(gptr*) &max_write_lock_count, (gptr*) &max_write_lock_count, 0, GET_ULONG,
REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0},
- {"myisam_bulk_insert_tree_size", OPT_MYISAM_BULK_INSERT_TREE_SIZE,
+ {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
"Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!",
- (gptr*) &myisam_bulk_insert_tree_size,
- (gptr*) &myisam_bulk_insert_tree_size,
+ (gptr*) &global_system_variables.bulk_insert_buff_size,
+ (gptr*) &max_system_variables.bulk_insert_buff_size,
0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ~0L, 0, 1, 0},
{"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
- "Undocumented", (gptr*) &opt_myisam_block_size,
+ "Block size to be used for MyISAM index pages",
+ (gptr*) &opt_myisam_block_size,
(gptr*) &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
0, MI_MIN_KEY_BLOCK_LENGTH, 0},
{"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
- "Used to help MySQL to decide when to use the slow but safe key cache index create method. Note that this parameter is given in megabytes!",
+ "Used to help MySQL to decide when to use the slow but safe key cache index create method",
(gptr*) &global_system_variables.myisam_max_extra_sort_file_size,
(gptr*) &max_system_variables.myisam_max_extra_sort_file_size,
- 0, GET_ULONG, REQUIRED_ARG, (long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)),
+ 0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH,
0, ~0L, 0, 1, 0},
{"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
- "Don't use the fast sort index method to created index if the temporary file would get bigger than this. Note that this paramter is given in megabytes!",
+ "Don't use the fast sort index method to created index if the temporary file would get bigger than this!",
(gptr*) &global_system_variables.myisam_max_sort_file_size,
(gptr*) &max_system_variables.myisam_max_sort_file_size, 0,
- GET_ULONG, REQUIRED_ARG, (long) (LONG_MAX/(1024L*1024L)), 0, ~0L, 0, 1, 0},
+ GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, ~0L, 0, 1024*1024, 0},
{"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
"The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
- (gptr*) &myisam_sort_buffer_size, (gptr*) &myisam_sort_buffer_size, 0,
+ (gptr*) &global_system_variables.myisam_sort_buff_size,
+ (gptr*) &max_system_variables.myisam_sort_buff_size, 0,
GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
{"net_buffer_length", OPT_NET_BUFFER_LENGTH,
- "Buffer for TCP/IP and socket communication.",
- (gptr*) &net_buffer_length,
- (gptr*) &net_buffer_length, 0, GET_ULONG,
- REQUIRED_ARG, 16384, 1024, 1024*1024L, MALLOC_OVERHEAD, 1024, 0},
+ "Buffer length for TCP/IP and socket communication.",
+ (gptr*) &global_system_variables.net_buffer_length,
+ (gptr*) &max_system_variables.net_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
{"net_retry_count", OPT_NET_RETRY_COUNT,
"If a read on a communication port is interrupted, retry this many times before giving up.",
(gptr*) &mysqld_net_retry_count, (gptr*) &mysqld_net_retry_count, 0,
GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1, 0},
{"net_read_timeout", OPT_NET_READ_TIMEOUT,
"Number of seconds to wait for more data from a connection before aborting the read.",
- (gptr*) &net_read_timeout,
- (gptr*) &net_read_timeout, 0, GET_ULONG,
+ (gptr*) &global_system_variables.net_read_timeout,
+ (gptr*) &max_system_variables.net_read_timeout, 0, GET_ULONG,
REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
{"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
"Number of seconds to wait for a block to be written to a connection before aborting the write.",
- (gptr*) &net_write_timeout,
- (gptr*) &net_write_timeout, 0, GET_ULONG,
+ (gptr*) &global_system_variables.net_write_timeout,
+ (gptr*) &max_system_variables.net_write_timeout, 0, GET_ULONG,
REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
{"open_files_limit", OPT_OPEN_FILES_LIMIT,
"If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.",
(gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, 65535, 0, 1, 0},
- {"query_buffer_size", OPT_QUERY_BUFFER_SIZE,
- "The initial allocation of the query buffer.", (gptr*) &query_buff_size,
- (gptr*) &query_buff_size, 0, GET_ULONG, REQUIRED_ARG, 0, MALLOC_OVERHEAD,
- (long) ~0, MALLOC_OVERHEAD, IO_SIZE, 0},
#ifdef HAVE_QUERY_CACHE
{"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
"Don't cache results that are bigger than this.",
@@ -3500,24 +3516,30 @@ static struct my_option my_long_options[] =
{"query_cache_size", OPT_QUERY_CACHE_SIZE,
"The memory allocated to store results from old queries.",
(gptr*) &query_cache_size, (gptr*) &query_cache_size, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1024, 0},
#ifdef HAVE_QUERY_CACHE
- {"query_cache_startup_type", OPT_QUERY_CACHE_STARTUP_TYPE,
+ {"query_cache_type", OPT_QUERY_CACHE_TYPE,
"0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT SQL_CACHE ... queries.",
- (gptr*) &query_cache_startup_type, (gptr*) &query_cache_startup_type, 0,
- GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
+ (gptr*) &global_system_variables.query_cache_type,
+ (gptr*) &max_system_variables.query_cache_type,
+ 0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
#endif /*HAVE_QUERY_CACHE*/
- {"record_buffer", OPT_RECORD_BUFFER,
+ {"read_buffer_size", OPT_RECORD_BUFFER,
"Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.",
- (gptr*) &my_default_record_cache_size,
- (gptr*) &my_default_record_cache_size, 0, GET_ULONG, REQUIRED_ARG,
+ (gptr*) &global_system_variables.read_buff_size,
+ (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
- {"record_rnd_buffer", OPT_RECORD_RND_BUFFER,
+ {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
"When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks. If not set, then it's set to the value of record_buffer.",
- (gptr*) &global_system_variables.record_rnd_cache_size,
- (gptr*) &max_system_variables.record_rnd_cache_size, 0,
- GET_ULONG, REQUIRED_ARG, 0, IO_SIZE*2+MALLOC_OVERHEAD,
+ (gptr*) &global_system_variables.read_rnd_buff_size,
+ (gptr*) &max_system_variables.read_rnd_buff_size, 0,
+ GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
+ {"record_buffer", OPT_RECORD_BUFFER,
+ "Alias for read_buffer_size",
+ (gptr*) &global_system_variables.read_buff_size,
+ (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
+ 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
{"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
"Undocumented", (gptr*) &relay_log_space_limit,
(gptr*) &relay_log_space_limit, 0, GET_ULONG, REQUIRED_ARG, 0L, 0L,
@@ -3530,7 +3552,7 @@ static struct my_option my_long_options[] =
"If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.",
(gptr*) &slow_launch_time, (gptr*) &slow_launch_time, 0, GET_ULONG,
REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
- {"sort_buffer", OPT_SORT_BUFFER,
+ {"sort_buffer_size", OPT_SORT_BUFFER,
"Each thread that needs to do a sort allocates a buffer of this size.",
(gptr*) &global_system_variables.sortbuff_size,
(gptr*) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
@@ -3565,176 +3587,6 @@ static struct my_option my_long_options[] =
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-struct show_var_st init_vars[]= {
- {"back_log", (char*) &back_log, SHOW_LONG},
- {"basedir", mysql_home, SHOW_CHAR},
-#ifdef HAVE_BERKELEY_DB
- {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
- {"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG},
- {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
- {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
- {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
- {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL},
- {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR},
- {"bdb_version", (char*) DB_VERSION_STRING, SHOW_CHAR},
-#endif
- {"binlog_cache_size", (char*) &binlog_cache_size, SHOW_LONG},
- {"character_set", default_charset, SHOW_CHAR},
- {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
- {"concurrent_insert", (char*) &myisam_concurrent_insert, SHOW_MY_BOOL},
- {"connect_timeout", (char*) &connect_timeout, SHOW_LONG},
- {"datadir", mysql_real_data_home, SHOW_CHAR},
- {"delay_key_write", (char*) &myisam_delay_key_write, SHOW_MY_BOOL},
- {"delayed_insert_limit", (char*) &delayed_insert_limit, SHOW_LONG},
- {"delayed_insert_timeout", (char*) &delayed_insert_timeout, SHOW_LONG},
- {"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG},
- {"flush", (char*) &myisam_flush, SHOW_MY_BOOL},
- {"flush_time", (char*) &flush_time, SHOW_LONG},
- {"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG},
- {"ft_max_word_len", (char*) &ft_max_word_len, SHOW_LONG},
- {"ft_max_word_len_for_sort",(char*) &ft_max_word_len_for_sort, SHOW_LONG},
- {"ft_boolean_syntax", (char*) ft_boolean_syntax, SHOW_CHAR},
- {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
- {"have_innodb", (char*) &have_innodb, SHOW_HAVE},
- {"have_isam", (char*) &have_isam, SHOW_HAVE},
- {"have_raid", (char*) &have_raid, SHOW_HAVE},
- {"have_symlink", (char*) &have_symlink, SHOW_HAVE},
- {"have_openssl", (char*) &have_openssl, SHOW_HAVE},
- {"have_query_cache", (char*) &have_query_cache, SHOW_HAVE},
- {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
-#ifdef HAVE_INNOBASE_DB
- {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
- {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONG },
- {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR},
- {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR},
- {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
- {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
- {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG },
- {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_MY_BOOL},
- {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL},
- {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
- {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
- {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR},
- {"innodb_log_archive", (char*) &innobase_log_archive, SHOW_MY_BOOL},
- {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG },
- {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONG},
- {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group, SHOW_LONG},
- {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR},
- {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
-#endif
- {"interactive_timeout",
- (char*) offsetof(struct system_variables, net_interactive_timeout),
- SHOW_LONG_OFFSET},
- {"join_buffer_size",
- (char*) offsetof(struct system_variables, join_buff_size),
- SHOW_LONG_OFFSET},
- {"key_buffer_size", (char*) &keybuff_size, SHOW_LONG},
- {"language", language, SHOW_CHAR},
- {"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
- {"local_infile",
- (char*) offsetof(struct system_variables, opt_local_infile),
- SHOW_MY_BOOL_OFFSET},
-#ifdef HAVE_MLOCKALL
- {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
-#endif
- {"log", (char*) &opt_log, SHOW_BOOL},
- {"log_update", (char*) &opt_update_log, SHOW_BOOL},
- {"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
- {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_BOOL},
- {"log_slow_queries", (char*) &opt_slow_log, SHOW_BOOL},
- {"long_query_time",
- (char*) offsetof(struct system_variables, long_query_time),
- SHOW_LONG_OFFSET},
- {"low_priority_updates", (char*) &low_priority_updates, SHOW_BOOL},
- {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_LONG},
- {"max_allowed_packet", (char*) &max_allowed_packet, SHOW_LONG},
- {"max_binlog_cache_size", (char*) &max_binlog_cache_size, SHOW_LONG},
- {"max_binlog_size", (char*) &max_binlog_size, SHOW_LONG},
- {"max_connections", (char*) &max_connections, SHOW_LONG},
- {"max_connect_errors", (char*) &max_connect_errors, SHOW_LONG},
- {"max_delayed_threads", (char*) &max_insert_delayed_threads, SHOW_LONG},
- {"max_heap_table_size",
- (char*) offsetof(struct system_variables, max_heap_table_size),
- SHOW_LONG_OFFSET},
- {"max_join_size",
- (char*) offsetof(struct system_variables, max_join_size),
- SHOW_LONG_OFFSET},
- {"max_sort_length",
- (char*) offsetof(struct system_variables, max_item_sort_length),
- SHOW_LONG_OFFSET},
- {"max_user_connections", (char*) &max_user_connections, SHOW_LONG},
- {"max_tmp_tables",
- (char*) offsetof(struct system_variables, max_tmp_tables),
- SHOW_LONG_OFFSET},
- {"max_write_lock_count", (char*) &max_write_lock_count, SHOW_LONG},
- {"myisam_bulk_insert_tree_size", (char*) &myisam_bulk_insert_tree_size, SHOW_INT},
- {"myisam_max_extra_sort_file_size",
- (char*) offsetof(struct system_variables,
- myisam_max_extra_sort_file_size),
- SHOW_LONG_OFFSET},
- {"myisam_max_sort_file_size",
- (char*) offsetof(struct system_variables, myisam_max_sort_file_size),
- SHOW_LONG_OFFSET},
- {"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
- {"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG},
-#ifdef __NT__
- {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_BOOL},
-#endif
- {"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG},
- {"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG},
- {"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
- {"net_write_timeout", (char*) &net_write_timeout, SHOW_LONG},
- {"open_files_limit", (char*) &open_files_limit, SHOW_LONG},
- {"pid_file", (char*) pidfile_name, SHOW_CHAR},
- {"port", (char*) &mysql_port, SHOW_INT},
- {"protocol_version", (char*) &protocol_version, SHOW_INT},
- {"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG},
- {"record_rnd_buffer",
- (char*) offsetof(struct system_variables, record_rnd_cache_size),
- SHOW_LONG_OFFSET},
- {"rpl_recovery_rank", (char*) &rpl_recovery_rank, SHOW_LONG},
- {"query_buffer_size", (char*) &query_buff_size, SHOW_LONG},
-#ifdef HAVE_QUERY_CACHE
- {"query_cache_limit", (char*) &query_cache.query_cache_limit, SHOW_LONG},
- {"query_cache_size", (char*) &query_cache.query_cache_size, SHOW_LONG},
- {"query_cache_startup_type",(char*) &query_cache_startup_type, SHOW_LONG},
-#endif /*HAVE_QUERY_CACHE*/
- {"safe_show_database", (char*) &opt_safe_show_db, SHOW_BOOL},
- {"server_id", (char*) &server_id, SHOW_LONG},
- {"slave_net_timeout", (char*) &slave_net_timeout, SHOW_LONG},
- {"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
- {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
- {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
- {"slow_launch_time", (char*) &slow_launch_time, SHOW_LONG},
- {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR},
- {"sort_buffer",
- (char*) offsetof(struct system_variables, sortbuff_size),
- SHOW_LONG_OFFSET},
- {"sql_mode", (char*) &opt_sql_mode, SHOW_LONG},
- {"table_cache", (char*) &table_cache_size, SHOW_LONG},
- {"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR},
- {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG},
-#ifdef HAVE_THR_SETCONCURRENCY
- {"thread_concurrency", (char*) &concurrency, SHOW_LONG},
-#endif
- {"thread_stack", (char*) &thread_stack, SHOW_LONG},
- {"transaction_isolation", (char*) &default_tx_isolation_name, SHOW_CHAR_PTR},
-#ifdef HAVE_TZNAME
- {"timezone", time_zone, SHOW_CHAR},
-#endif
- {"tmp_table_size",
- (char*) offsetof(struct system_variables, tmp_table_size),
- SHOW_LONG_OFFSET},
- {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR},
- {"version", server_version, SHOW_CHAR},
- {"wait_timeout",
- (char*) offsetof(struct system_variables, net_wait_timeout),
- SHOW_LONG_OFFSET},
- {"warnings",
- (char*) offsetof(struct system_variables, opt_warnings),
- SHOW_MY_BOOL_OFFSET},
- {NullS, NullS, SHOW_LONG}
-};
struct show_var_st status_vars[]= {
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
@@ -3943,38 +3795,9 @@ Starts the MySQL server\n");
my_print_help(my_long_options);
my_print_variables(my_long_options);
- printf("\
+ puts("\n\
To see what values a running MySQL server is using, type\n\
-'mysqladmin variables' instead of 'mysqld --help'.\n\
-The default values (after parsing the command line arguments) are:\n\n");
-
- printf("basedir: %s\n",mysql_home);
- printf("datadir: %s\n",mysql_real_data_home);
- printf("tmpdir: %s\n",mysql_tmpdir);
- printf("language: %s\n",language);
-#ifndef __WIN__
- printf("pid file: %s\n",pidfile_name);
-#endif
- if (opt_logname)
- printf("logfile: %s\n",opt_logname);
- if (opt_update_logname)
- printf("update log: %s\n",opt_update_logname);
- if (opt_bin_log)
- {
- printf("binary log: %s\n",opt_bin_logname ? opt_bin_logname : "");
- printf("binary log index: %s\n",
- opt_binlog_index_name ? opt_binlog_index_name : "");
- }
- if (opt_slow_logname)
- printf("update log: %s\n",opt_slow_logname);
- printf("TCP port: %d\n",mysql_port);
-#if defined(HAVE_SYS_UN_H)
- printf("Unix socket: %s\n",mysql_unix_port);
-#endif
- if (my_disable_locking)
- puts("\nsystem locking is not in use");
- if (opt_noacl)
- puts("\nGrant tables are not used. All users have full access rights");
+'mysqladmin variables' instead of 'mysqld --help'.");
}
@@ -3984,10 +3807,19 @@ static void set_options(void)
opt_specialflag |= SPECIAL_NO_PRIOR;
#endif
- (void) strmake(default_charset, MYSQL_CHARSET, sizeof(default_charset)-1);
+ sys_charset.value= (char*) MYSQL_CHARSET;
(void) strmake(language, LANGUAGE, sizeof(language)-1);
(void) strmake(mysql_real_data_home, get_relative_path(DATADIR),
sizeof(mysql_real_data_home-1));
+
+ /* Set default values for some variables */
+ global_system_variables.table_type=DB_TYPE_MYISAM;
+ global_system_variables.tx_isolation=ISO_READ_COMMITTED;
+ global_system_variables.select_limit= (ulong) HA_POS_ERROR;
+ max_system_variables.select_limit= (ulong) HA_POS_ERROR;
+ global_system_variables.max_join_size= (ulong) HA_POS_ERROR;
+ max_system_variables.max_join_size= (ulong) HA_POS_ERROR;
+
#ifdef __WIN__
/* Allow Win32 users to move MySQL anywhere */
{
@@ -4025,7 +3857,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT |
MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE
| MODE_ONLY_FULL_GROUP_BY);
- default_tx_isolation= ISO_SERIALIZABLE;
+ global_system_variables.tx_isolation= ISO_SERIALIZABLE;
break;
case 'b':
strmake(mysql_home,argument,sizeof(mysql_home)-1);
@@ -4313,9 +4145,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
flush_time=0; // No auto flush
break;
case OPT_LOW_PRIORITY_UPDATES:
- thd_startup_options|=OPTION_LOW_PRIORITY_UPDATES;
thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
- low_priority_updates=1;
+ global_system_variables.low_priority_updates=1;
break;
case OPT_BOOTSTRAP:
opt_noacl=opt_bootstrap=1;
@@ -4328,7 +4159,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
fprintf(stderr,"Unknown table type: %s\n",argument);
exit(1);
}
- default_table_type= (enum db_type) type;
+ global_system_variables.table_type= type-1;
break;
}
case OPT_SERVER_ID:
@@ -4338,9 +4169,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
ha_open_options|=HA_OPEN_DELAY_KEY_WRITE;
myisam_delay_key_write=1;
break;
- case 'C':
- strmake(default_charset, argument, sizeof(default_charset)-1);
- break;
case OPT_CHARSETS_DIR:
strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
charsets_dir = mysql_charsets_dir;
@@ -4361,7 +4189,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
fprintf(stderr,"Unknown transaction isolation type: %s\n",argument);
exit(1);
}
- default_tx_isolation= (enum_tx_isolation) (type-1);
+ global_system_variables.tx_isolation= (type-1);
break;
}
#ifdef HAVE_BERKELEY_DB
@@ -4450,9 +4278,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
fprintf(stderr, "Unknown option to sql-mode: %s\n", argument);
exit(1);
}
- default_tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ?
- ISO_SERIALIZABLE :
- ISO_READ_COMMITTED);
+ global_system_variables.tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ?
+ ISO_SERIALIZABLE :
+ ISO_READ_COMMITTED);
break;
}
case OPT_MASTER_PASSWORD:
@@ -4490,22 +4318,20 @@ static void get_options(int argc,char **argv)
if (mysqld_chroot)
set_root(mysqld_chroot);
fix_paths();
- default_table_type_name=ha_table_typelib.type_names[default_table_type-1];
- default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
- /* To be deleted in MySQL 4.0 */
- if (!thd->variables.record_rnd_cache_size)
- thd->variables.record_rnd_cache_size= my_default_record_cache_size;
- /* Fix variables that are base 1024*1024 */
+ /*
+ Set some global variables from the global_system_variables
+ In most cases the global variables will not be used
+ */
+ my_default_record_cache_size=global_system_variables.read_buff_size;
myisam_max_temp_length=
- (my_off_t) min(((ulonglong)
- thd->variables.myisam_max_sort_file_size)*1024 * 1024,
+ (my_off_t) min(global_system_variables.myisam_max_sort_file_size,
(ulonglong) MAX_FILE_SIZE);
myisam_max_extra_temp_length=
- (my_off_t) min(((ulonglong)
- thd->variables.myisam_max_extra_sort_file_size)*1024*1024,
+ (my_off_t) min(global_system_variables.myisam_max_extra_sort_file_size,
(ulonglong) MAX_FILE_SIZE);
+ /* Set global variables based on startup options */
myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
}
@@ -4548,6 +4374,7 @@ fn_format_relative_to_data_home(my_string to, const char *name,
static void fix_paths(void)
{
+ char buff[FN_REFLEN];
(void) fn_format(mysql_home,mysql_home,"","",16); // Remove symlinks
convert_dirname(mysql_home,mysql_home,NullS);
convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
@@ -4556,7 +4383,7 @@ static void fix_paths(void)
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
(void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
- char buff[FN_REFLEN],*sharedir=get_relative_path(SHAREDIR);
+ char *sharedir=get_relative_path(SHAREDIR);
if (test_if_hard_path(sharedir))
strmake(buff,sharedir,sizeof(buff)-1); /* purecov: tested */
else
@@ -4572,24 +4399,18 @@ static void fix_paths(void)
charsets_dir=mysql_charsets_dir;
}
- /* Add '/' to TMPDIR if needed */
- char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE));
- if (tmp)
- {
- char *end=convert_dirname(tmp, mysql_tmpdir, NullS);
-
- mysql_tmpdir=(char*) my_realloc(tmp,(uint) (end-tmp)+1,
- MYF(MY_HOLD_ON_ERROR));
- allocated_mysql_tmpdir=mysql_tmpdir;
- }
+ char *end=convert_dirname(buff, opt_mysql_tmpdir, NullS);
+ if (!(mysql_tmpdir= my_memdup(buff,(uint) (end-buff)+1, MYF(MY_FAE))))
+ exit(1);
if (!slave_load_tmpdir)
{
- // no need to check return value, if we fail, my_malloc() never returns
- slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE));
+ if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
+ exit(1);
}
}
+
#ifdef SET_RLIMIT_NOFILE
static uint set_maximum_open_files(uint max_file_limit)
{
diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc
index f7c28d3d7fe..a8beecd5fb4 100644
--- a/sql/net_pkg.cc
+++ b/sql/net_pkg.cc
@@ -87,6 +87,7 @@ void send_warning(NET *net, uint sql_errno, const char *err)
DBUG_VOID_RETURN;
}
+
/*
Write error package and flush to client
It's a little too low level, but I don't want to allow another buffer
@@ -369,3 +370,18 @@ net_store_data(String *packet, CONVERT *convert, const char *from)
return convert->store(packet, from, length);
return net_store_data(packet,from,length);
}
+
+/*
+ Function called by my_net_init() to set some check variables
+*/
+
+extern "C" {
+void my_net_local_init(NET *net)
+{
+ net->max_packet= (uint) global_system_variables.net_buffer_length;
+ net->read_timeout= (uint) global_system_variables.net_read_timeout;
+ net->write_timeout=(uint) global_system_variables.net_write_timeout;
+ net->max_packet_size= max(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+}
+}
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index b5453d0beb2..5ff040003d5 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -14,17 +14,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Write and read of logical packets to/from socket
-** Writes are cached into net_buffer_length big packets.
-** Read packets are reallocated dynamicly when reading big packets.
-** Each logical packet has the following pre-info:
-** 3 byte length & 1 byte package-number.
-*/
+/*
+ Write and read of logical packets to/from socket
-#ifdef EMBEDDED_LIBRARY
-#define net_read_timeout net_read_timeout1
-#define net_write_timeout net_write_timeout1
-#endif
+ Writes are cached into net_buffer_length big packets.
+ Read packets are reallocated dynamicly when reading big packets.
+ Each logical packet has the following pre-info:
+ 3 byte length & 1 byte package-number.
+*/
#ifdef __WIN__
#include <winsock.h>
@@ -51,15 +48,10 @@
*/
#ifdef MYSQL_SERVER
-ulong max_allowed_packet=65536;
-extern ulong net_read_timeout,net_write_timeout;
-extern uint test_flags;
#define USE_QUERY_CACHE
+extern uint test_flags;
extern void query_cache_insert(NET *net, const char *packet, ulong length);
#else
-ulong max_allowed_packet=16*1024*1024L;
-ulong net_read_timeout= NET_READ_TIMEOUT;
-ulong net_write_timeout= NET_WRITE_TIMEOUT;
#endif
#if defined(__WIN__) || !defined(MYSQL_SERVER)
@@ -86,8 +78,6 @@ extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
#define TEST_BLOCKING 8
#define MAX_THREE_BYTES 255L*255L*255L
-ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */
-
static int net_write_buff(NET *net,const char *packet,ulong len);
@@ -95,17 +85,15 @@ static int net_write_buff(NET *net,const char *packet,ulong len);
int my_net_init(NET *net, Vio* vio)
{
- if (!(net->buff=(uchar*) my_malloc((uint32) net_buffer_length+
+ my_net_local_init(net); /* Set some limits */
+ if (!(net->buff=(uchar*) my_malloc((uint32) net->max_packet+
NET_HEADER_SIZE + COMP_HEADER_SIZE,
MYF(MY_WME))))
return 1;
- if (net_buffer_length > max_allowed_packet)
- max_allowed_packet=net_buffer_length;
- net->buff_end=net->buff+(net->max_packet=net_buffer_length);
+ net->buff_end=net->buff+net->max_packet;
net->vio = vio;
net->no_send_ok = 0;
net->error=0; net->return_errno=0; net->return_status=0;
- net->timeout=(uint) net_read_timeout; /* Timeout for read */
net->pkt_nr=net->compress_pkt_nr=0;
net->write_pos=net->read_pos = net->buff;
net->last_error[0]=0;
@@ -126,19 +114,21 @@ int my_net_init(NET *net, Vio* vio)
return 0;
}
+
void net_end(NET *net)
{
my_free((gptr) net->buff,MYF(MY_ALLOW_ZERO_PTR));
net->buff=0;
}
+
/* Realloc the packet buffer */
static my_bool net_realloc(NET *net, ulong length)
{
uchar *buff;
ulong pkt_length;
- if (length >= max_allowed_packet)
+ if (length >= net->max_packet_size)
{
DBUG_PRINT("error",("Packet too large (%lu)", length));
net->error=1;
@@ -146,8 +136,10 @@ static my_bool net_realloc(NET *net, ulong length)
return 1;
}
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
- /* We must allocate some extra bytes for the end 0 and to be able to
- read big compressed blocks */
+ /*
+ We must allocate some extra bytes for the end 0 and to be able to
+ read big compressed blocks
+ */
if (!(buff=(uchar*) my_realloc((char*) net->buff, (uint32) pkt_length +
NET_HEADER_SIZE + COMP_HEADER_SIZE,
MYF(MY_WME))))
@@ -374,7 +366,7 @@ net_real_write(NET *net,const char *packet,ulong len)
#ifndef NO_ALARM
thr_alarm_init(&alarmed);
if (net_blocking)
- thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff);
+ thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff);
#else
alarmed=0;
#endif /* NO_ALARM */
@@ -388,7 +380,7 @@ net_real_write(NET *net,const char *packet,ulong len)
#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2))
if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed))
{
- if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff))
+ if (!thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff))
{ /* Always true for client */
if (!vio_is_blocking(net->vio))
{
@@ -471,7 +463,7 @@ static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed)
uint retry_count=0;
if (!thr_alarm_in_use(&alarmed))
{
- if (!thr_alarm(alarmed,net->timeout,&alarm_buff) ||
+ if (!thr_alarm(alarmed,net->read_timeout,&alarm_buff) ||
(!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0))
return; /* Can't setup, abort */
}
@@ -521,7 +513,7 @@ my_real_read(NET *net, ulong *complen)
thr_alarm_init(&alarmed);
#ifndef NO_ALARM
if (net_blocking)
- thr_alarm(&alarmed,net->timeout,&alarm_buff);
+ thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
#endif /* NO_ALARM */
pos = net->buff + net->where_b; /* net->packet -4 */
@@ -544,7 +536,7 @@ my_real_read(NET *net, ulong *complen)
*/
if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
{
- if (!thr_alarm(&alarmed,net->timeout,&alarm_buff)) /* Don't wait too long */
+ if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */
{
if (!vio_is_blocking(net->vio))
{
diff --git a/sql/records.cc b/sql/records.cc
index 14049449114..7c3bd1110bb 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -61,7 +61,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
table->file->rnd_init(0);
if (! (specialflag & SPECIAL_SAFE_MODE) &&
- thd->variables.record_rnd_cache_size &&
+ thd->variables.read_rnd_buff_size &&
!table->file->fast_key_read() &&
(table->db_stat & HA_READ_ONLY ||
table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
@@ -103,7 +103,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
!(table->db_options_in_use & HA_OPTION_PACK_RECORD) ||
(use_record_cache < 0 &&
!(table->file->table_flags() & HA_NOT_DELETE_WITH_CACHE)))
- VOID(table->file->extra(HA_EXTRA_CACHE)); // Cache reads
+ VOID(table->file->extra_opt(HA_EXTRA_CACHE,
+ thd->variables.read_buff_size));
}
DBUG_VOID_RETURN;
} /* init_read_record */
@@ -239,7 +240,7 @@ static int init_rr_cache(READ_RECORD *info)
info->reclength=ALIGN_SIZE(info->struct_length);
info->error_offset=info->table->reclength;
- info->cache_records= thd->variables.record_rnd_cache_size /
+ info->cache_records= thd->variables.read_rnd_buff_size /
(info->reclength+info->struct_length);
rec_cache_size=info->cache_records*info->reclength;
info->rec_cache_size=info->cache_records*info->ref_length;
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 3b63a12c05c..f5f5b2de9fc 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -59,8 +59,8 @@ static int init_failsafe_rpl_thread(THD* thd)
thd->system_thread = thd->bootstrap = 1;
thd->client_capabilities = 0;
my_net_init(&thd->net, 0);
- thd->net.timeout = slave_net_timeout;
- thd->max_packet_length=thd->net.max_packet;
+ thd->net.read_timeout = slave_net_timeout;
+ thd->max_client_packet_length=thd->net.max_packet;
thd->master_access= ~0;
thd->priv_user = 0;
thd->system_thread = 1;
@@ -68,10 +68,7 @@ static int init_failsafe_rpl_thread(THD* thd)
thd->thread_id = thread_id++;
pthread_mutex_unlock(&LOCK_thread_count);
- if (init_thr_lock() ||
- my_pthread_setspecific_ptr(THR_THD, thd) ||
- my_pthread_setspecific_ptr(THR_MALLOC, &thd->mem_root) ||
- my_pthread_setspecific_ptr(THR_NET, &thd->net))
+ if (init_thr_lock() || thd->store_globals())
{
close_connection(&thd->net,ER_OUT_OF_RESOURCES); // is this needed?
end_thread(thd,0);
@@ -87,8 +84,8 @@ static int init_failsafe_rpl_thread(THD* thd)
#endif
thd->mem_root.free=thd->mem_root.used=0;
- if (thd->max_join_size == (ulong) ~0L)
- thd->options |= OPTION_BIG_SELECTS;
+ if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
+ thd->options|= OPTION_BIG_SELECTS;
thd->proc_info="Thread initialized";
thd->version=refresh_version;
@@ -626,7 +623,8 @@ int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi)
return 1;
if (!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
- mi->port, 0, 0))
+ mi->port, 0, 0,
+ slave_net_timeout))
{
sql_print_error("Connection to master failed: %s",
mc_mysql_error(mysql));
diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h
index 77bc03ce8c0..ef1dc1f8778 100644
--- a/sql/repl_failsafe.h
+++ b/sql/repl_failsafe.h
@@ -14,7 +14,6 @@ extern RPL_STATUS rpl_status;
extern pthread_mutex_t LOCK_rpl_status;
extern pthread_cond_t COND_rpl_status;
extern TYPELIB rpl_role_typelib, rpl_status_typelib;
-extern uint rpl_recovery_rank;
extern const char* rpl_role_type[], *rpl_status_type[];
pthread_handler_decl(handle_failsafe_rpl,arg);
diff --git a/sql/set_var.cc b/sql/set_var.cc
new file mode 100644
index 00000000000..1ec59c55b1b
--- /dev/null
+++ b/sql/set_var.cc
@@ -0,0 +1,1293 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Handling of MySQL SQL variables
+
+ To add a new variable, one has to do the following:
+
+ - If the variable is thread specific, add it to 'system_variables' struct.
+ If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
+ - Use one of the 'sys_var... classes from set_var.h or write a specific
+ one for the variable type.
+ - Define it in the 'variable definition list' in this file.
+ - If the variable should be changeable, it should be added to the
+ 'list of all variables' list in this file.
+ - If the variable should be changed from the command line, add a definition
+ of it in the my_option structure list in mysqld.dcc
+ - If the variable should show up in 'show variables' add it to the
+ init_vars[] struct in this file
+
+ TODO:
+ - Add full support for the variable character_set (for 4.1)
+
+ - When updating myisam_delay_key_write, we should do a 'flush tables'
+ of all MyISAM tables to ensure that they are reopen with the
+ new attribute.
+*/
+
+#ifdef __GNUC__
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "slave.h"
+#include "sql_acl.h"
+#include <my_getopt.h>
+#include <myisam.h>
+#ifdef HAVE_BERKELEY_DB
+#include "ha_berkeley.h"
+#endif
+#ifdef HAVE_INNOBASE_DB
+#include "ha_innodb.h"
+#endif
+
+static HASH system_variable_hash;
+const char *bool_type_names[]= { "OFF", "ON", NullS };
+TYPELIB bool_typelib=
+{
+ array_elements(bool_type_names)-1, "", bool_type_names
+};
+
+static bool sys_check_charset(THD *thd, set_var *var);
+static bool sys_update_charset(THD *thd, set_var *var);
+static void sys_set_default_charset(THD *thd, enum_var_type type);
+static bool set_option_bit(THD *thd, set_var *var);
+static bool set_option_autocommit(THD *thd, set_var *var);
+static bool set_log_update(THD *thd, set_var *var);
+static void fix_low_priority_updates(THD *thd, enum_var_type type);
+static void fix_tx_isolation(THD *thd, enum_var_type type);
+static void fix_net_read_timeout(THD *thd, enum_var_type type);
+static void fix_net_write_timeout(THD *thd, enum_var_type type);
+static void fix_max_join_size(THD *thd, enum_var_type type);
+static void fix_query_cache_size(THD *thd, enum_var_type type);
+static void fix_key_buffer_size(THD *thd, enum_var_type type);
+
+/*
+ Variable definition list
+
+ These are variables that can be set from the command line, in
+ alphabetic order
+*/
+
+sys_var_long_ptr sys_binlog_cache_size("binlog_cache_size",
+ &binlog_cache_size);
+sys_var_thd_ulong sys_bulk_insert_buff_size("bulk_insert_buffer_size",
+ &SV::bulk_insert_buff_size);
+sys_var_str sys_charset("character_set",
+ sys_check_charset,
+ sys_update_charset,
+ sys_set_default_charset);
+sys_var_thd_conv_charset sys_convert_charset("convert_character_set");
+sys_var_bool_ptr sys_concurrent_insert("concurrent_insert",
+ &myisam_concurrent_insert);
+sys_var_long_ptr sys_connect_timeout("connect_timeout",
+ &connect_timeout);
+sys_var_bool_ptr sys_delay_key_write("delay_key_write",
+ &myisam_delay_key_write);
+sys_var_long_ptr sys_delayed_insert_limit("delayed_insert_limit",
+ &delayed_insert_limit);
+sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout",
+ &delayed_insert_timeout);
+sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size",
+ &delayed_queue_size);
+sys_var_bool_ptr sys_flush("flush", &myisam_flush);
+sys_var_long_ptr sys_flush_time("flush_time", &flush_time);
+sys_var_thd_ulong sys_interactive_timeout("interactive_timeout",
+ &SV::net_interactive_timeout);
+sys_var_thd_ulong sys_join_buffer_size("join_buffer_size",
+ &SV::join_buff_size);
+sys_var_long_ptr sys_key_buffer_size("key_buffer_size",
+ &keybuff_size,
+ fix_key_buffer_size);
+sys_var_bool_ptr sys_local_infile("local_infile",
+ &opt_local_infile);
+sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings);
+sys_var_thd_ulong sys_long_query_time("long_query_time",
+ &SV::long_query_time);
+sys_var_thd_bool sys_low_priority_updates("low_priority_updates",
+ &SV::low_priority_updates,
+ fix_low_priority_updates);
+#ifndef TO_BE_DELETED /* Alias for the low_priority_updates */
+sys_var_thd_bool sys_sql_low_priority_updates("sql_low_priority_updates",
+ &SV::low_priority_updates,
+ fix_low_priority_updates);
+#endif
+sys_var_thd_ulong sys_max_allowed_packet("max_allowed_packet",
+ &SV::max_allowed_packet);
+sys_var_long_ptr sys_max_binlog_cache_size("max_binlog_cache_size",
+ &max_binlog_cache_size);
+sys_var_long_ptr sys_max_binlog_size("max_binlog_size",
+ &max_binlog_size);
+sys_var_long_ptr sys_max_connections("max_connections",
+ &max_connections);
+sys_var_long_ptr sys_max_connect_errors("max_connect_errors",
+ &max_connect_errors);
+sys_var_long_ptr sys_max_delayed_threads("max_delayed_threads",
+ &max_insert_delayed_threads);
+sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size",
+ &SV::max_heap_table_size);
+sys_var_thd_ulong sys_max_join_size("max_join_size",
+ &SV::max_join_size,
+ fix_max_join_size);
+#ifndef TO_BE_DELETED /* Alias for max_join_size */
+sys_var_thd_ulong sys_sql_max_join_size("sql_max_join_size",
+ &SV::max_join_size,
+ fix_max_join_size);
+#endif
+sys_var_thd_ulong sys_max_sort_length("max_sort_length",
+ &SV::max_sort_length);
+sys_var_long_ptr sys_max_user_connections("max_user_connections",
+ &max_user_connections);
+sys_var_thd_ulong sys_max_tmp_tables("max_tmp_tables",
+ &SV::max_tmp_tables);
+sys_var_long_ptr sys_max_write_lock_count("max_write_lock_count",
+ &max_write_lock_count);
+sys_var_thd_ulonglong sys_myisam_max_extra_sort_file_size("myisam_max_extra_sort_file_size", &SV::myisam_max_extra_sort_file_size);
+sys_var_thd_ulonglong sys_myisam_max_sort_file_size("myisam_max_sort_file_size", &SV::myisam_max_sort_file_size);
+sys_var_thd_ulong sys_myisam_sort_buffer_size("myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
+sys_var_thd_ulong sys_net_buffer_length("net_buffer_length",
+ &SV::net_buffer_length);
+sys_var_thd_ulong sys_net_read_timeout("net_read_timeout",
+ &SV::net_read_timeout,
+ fix_net_read_timeout);
+sys_var_thd_ulong sys_net_write_timeout("net_write_timeout",
+ &SV::net_write_timeout,
+ fix_net_write_timeout);
+sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
+ &SV::read_buff_size);
+sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
+ &SV::read_rnd_buff_size);
+sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank",
+ &rpl_recovery_rank);
+sys_var_long_ptr sys_query_cache_size("query_cache_size",
+ &query_cache_size,
+ fix_query_cache_size);
+#ifdef HAVE_QUERY_CACHE
+sys_var_long_ptr sys_query_cache_limit("query_cache_limit",
+ &query_cache.query_cache_limit);
+sys_var_thd_enum sys_query_cache_type("query_cache_type",
+ &SV::query_cache_type,
+ &query_cache_type_typelib);
+#endif /* HAVE_QUERY_CACHE */
+sys_var_bool_ptr sys_safe_show_db("safe_show_database",
+ &opt_safe_show_db);
+sys_var_long_ptr sys_server_id("server_id",&server_id);
+sys_var_long_ptr sys_slave_net_timeout("slave_net_timeout",
+ &slave_net_timeout);
+sys_var_long_ptr sys_slow_launch_time("slow_launch_time",
+ &slow_launch_time);
+sys_var_thd_ulong sys_sort_buffer("sort_buffer_size",
+ &SV::sortbuff_size);
+sys_var_thd_enum sys_table_type("table_type", &SV::table_type,
+ &ha_table_typelib);
+sys_var_long_ptr sys_table_cache_size("table_cache",
+ &table_cache_size);
+sys_var_long_ptr sys_thread_cache_size("thread_cache_size",
+ &thread_cache_size);
+sys_var_thd_enum sys_tx_isolation("tx_isolation",
+ &SV::tx_isolation,
+ &tx_isolation_typelib,
+ fix_tx_isolation);
+sys_var_thd_ulong sys_tmp_table_size("tmp_table_size",
+ &SV::tmp_table_size);
+sys_var_thd_ulong sys_net_wait_timeout("wait_timeout",
+ &SV::net_wait_timeout);
+
+
+/*
+ Variables that are bits in THD
+*/
+
+static sys_var_thd_bit sys_autocommit("autocommit",
+ set_option_autocommit,
+ OPTION_NOT_AUTOCOMMIT,
+ 1);
+static sys_var_thd_bit sys_big_tables("big_tables",
+ set_option_bit,
+ OPTION_BIG_TABLES);
+#ifndef TO_BE_DELETED /* Alias for big_tables */
+static sys_var_thd_bit sys_sql_big_tables("sql_big_tables",
+ set_option_bit,
+ OPTION_BIG_TABLES);
+#endif
+static sys_var_thd_bit sys_big_selects("sql_big_selects",
+ set_option_bit,
+ OPTION_BIG_TABLES);
+static sys_var_thd_bit sys_log_off("sql_log_off",
+ set_option_bit,
+ OPTION_LOG_OFF);
+static sys_var_thd_bit sys_log_update("sql_log_update",
+ set_log_update,
+ OPTION_UPDATE_LOG);
+static sys_var_thd_bit sys_log_binlog("sql_log_bin",
+ set_log_update,
+ OPTION_BIN_LOG);
+static sys_var_thd_bit sys_sql_warnings("sql_warnings",
+ set_option_bit,
+ OPTION_WARNINGS);
+static sys_var_thd_bit sys_auto_is_null("sql_auto_is_null",
+ set_option_bit,
+ OPTION_AUTO_IS_NULL);
+static sys_var_thd_bit sys_safe_updates("sql_safe_updates",
+ set_option_bit,
+ OPTION_SAFE_UPDATES);
+static sys_var_thd_bit sys_buffer_results("sql_buffer_result",
+ set_option_bit,
+ OPTION_BUFFER_RESULT);
+static sys_var_thd_bit sys_quote_show_create("sql_quote_show_create",
+ set_option_bit,
+ OPTION_QUOTE_SHOW_CREATE);
+
+/* Local state variables */
+
+static sys_var_thd_ulong sys_select_limit("sql_select_limit",
+ &SV::select_limit);
+static sys_var_timestamp sys_timestamp("timestamp");
+static sys_var_last_insert_id sys_last_insert_id("last_insert_id");
+static sys_var_last_insert_id sys_identity("identity");
+static sys_var_insert_id sys_insert_id("insert_id");
+/* alias for last_insert_id() to be compatible with Sybase */
+static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter");
+
+
+/*
+ List of all variables for initialisation and storage in hash
+ This is sorted in alphabetical order to make it easy to add new variables
+
+ If the variable is not in this list, it can't be changed with
+ SET variable_name=
+*/
+
+sys_var *sys_variables[]=
+{
+ &sys_auto_is_null,
+ &sys_autocommit,
+ &sys_big_tables,
+ &sys_big_selects,
+ &sys_binlog_cache_size,
+ &sys_buffer_results,
+ &sys_bulk_insert_buff_size,
+ &sys_concurrent_insert,
+ &sys_connect_timeout,
+ &sys_convert_charset,
+ &sys_delay_key_write,
+ &sys_delayed_insert_limit,
+ &sys_delayed_insert_timeout,
+ &sys_delayed_queue_size,
+ &sys_flush,
+ &sys_flush_time,
+ &sys_identity,
+ &sys_insert_id,
+ &sys_interactive_timeout,
+ &sys_join_buffer_size,
+ &sys_key_buffer_size,
+ &sys_last_insert_id,
+ &sys_local_infile,
+ &sys_log_binlog,
+ &sys_log_off,
+ &sys_log_update,
+ &sys_log_warnings,
+ &sys_long_query_time,
+ &sys_low_priority_updates,
+ &sys_max_allowed_packet,
+ &sys_max_binlog_cache_size,
+ &sys_max_binlog_size,
+ &sys_max_connect_errors,
+ &sys_max_connections,
+ &sys_max_delayed_threads,
+ &sys_max_heap_table_size,
+ &sys_max_join_size,
+ &sys_max_sort_length,
+ &sys_max_tmp_tables,
+ &sys_max_user_connections,
+ &sys_max_write_lock_count,
+ &sys_myisam_max_extra_sort_file_size,
+ &sys_myisam_max_sort_file_size,
+ &sys_myisam_sort_buffer_size,
+ &sys_net_buffer_length,
+ &sys_net_read_timeout,
+ &sys_net_wait_timeout,
+ &sys_net_write_timeout,
+ &sys_query_cache_size,
+#ifdef HAVE_QUERY_CACHE
+ &sys_query_cache_limit,
+ &sys_query_cache_type,
+#endif HAVE_QUERY_CACHE
+ &sys_quote_show_create,
+ &sys_read_buff_size,
+ &sys_read_rnd_buff_size,
+ &sys_rpl_recovery_rank,
+ &sys_safe_show_db,
+ &sys_safe_updates,
+ &sys_select_limit,
+ &sys_server_id,
+ &sys_slave_net_timeout,
+ &sys_slave_skip_counter,
+ &sys_slow_launch_time,
+ &sys_sort_buffer,
+ &sys_sql_big_tables,
+ &sys_sql_low_priority_updates,
+ &sys_sql_max_join_size,
+ &sys_sql_warnings,
+ &sys_table_cache_size,
+ &sys_table_type,
+ &sys_thread_cache_size,
+ &sys_timestamp,
+ &sys_tmp_table_size,
+ &sys_tx_isolation,
+};
+
+
+/*
+ Variables shown by SHOW variables in alphabetical order
+*/
+
+struct show_var_st init_vars[]= {
+ {"back_log", (char*) &back_log, SHOW_LONG},
+ {"basedir", mysql_home, SHOW_CHAR},
+#ifdef HAVE_BERKELEY_DB
+ {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
+ {"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG},
+ {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
+ {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
+ {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
+ {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL},
+ {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR},
+ {"bdb_version", (char*) DB_VERSION_STRING, SHOW_CHAR},
+#endif
+ {sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size, SHOW_SYS},
+ {sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS},
+ {sys_charset.name, (char*) &sys_charset, SHOW_SYS},
+ {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
+ {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS},
+ {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
+ {sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS},
+ {"datadir", mysql_real_data_home, SHOW_CHAR},
+ {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS},
+ {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS},
+ {sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
+ {sys_delayed_queue_size.name,(char*) &sys_delayed_queue_size, SHOW_SYS},
+ {sys_flush.name, (char*) &sys_flush, SHOW_SYS},
+ {sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS},
+ {"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG},
+ {"ft_max_word_len", (char*) &ft_max_word_len, SHOW_LONG},
+ {"ft_max_word_len_for_sort",(char*) &ft_max_word_len_for_sort, SHOW_LONG},
+ {"ft_boolean_syntax", (char*) ft_boolean_syntax, SHOW_CHAR},
+ {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
+ {"have_innodb", (char*) &have_innodb, SHOW_HAVE},
+ {"have_isam", (char*) &have_isam, SHOW_HAVE},
+ {"have_raid", (char*) &have_raid, SHOW_HAVE},
+ {"have_symlink", (char*) &have_symlink, SHOW_HAVE},
+ {"have_openssl", (char*) &have_openssl, SHOW_HAVE},
+ {"have_query_cache", (char*) &have_query_cache, SHOW_HAVE},
+ {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
+#ifdef HAVE_INNOBASE_DB
+ {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
+ {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONG },
+ {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR},
+ {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR},
+ {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
+ {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
+ {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG },
+ {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_MY_BOOL},
+ {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL},
+ {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
+ {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
+ {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR},
+ {"innodb_log_archive", (char*) &innobase_log_archive, SHOW_MY_BOOL},
+ {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG },
+ {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONG},
+ {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group, SHOW_LONG},
+ {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR},
+ {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
+#endif
+ {sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS},
+ {sys_join_buffer_size.name, (char*) &sys_join_buffer_size, SHOW_SYS},
+ {sys_key_buffer_size.name, (char*) &sys_key_buffer_size, SHOW_SYS},
+ {"language", language, SHOW_CHAR},
+ {"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
+ {sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS},
+#ifdef HAVE_MLOCKALL
+ {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
+#endif
+ {"log", (char*) &opt_log, SHOW_BOOL},
+ {"log_update", (char*) &opt_update_log, SHOW_BOOL},
+ {"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
+ {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_BOOL},
+ {"log_slow_queries", (char*) &opt_slow_log, SHOW_BOOL},
+ {sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS},
+ {sys_long_query_time.name, (char*) &sys_long_query_time, SHOW_SYS},
+ {sys_low_priority_updates.name, (char*) &sys_low_priority_updates, SHOW_SYS},
+ {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_MY_BOOL},
+ {sys_max_allowed_packet.name,(char*) &sys_max_allowed_packet, SHOW_SYS},
+ {sys_max_binlog_cache_size.name,(char*) &sys_max_binlog_cache_size, SHOW_SYS},
+ {sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS},
+ {sys_max_connections.name, (char*) &sys_max_connections, SHOW_SYS},
+ {sys_max_connect_errors.name, (char*) &sys_max_connect_errors, SHOW_SYS},
+ {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS},
+ {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS},
+ {sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS},
+ {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS},
+ {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
+ {sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS},
+ {sys_max_write_lock_count.name, (char*) &sys_max_write_lock_count,SHOW_SYS},
+ {sys_myisam_max_extra_sort_file_size.name,
+ (char*) &sys_myisam_max_extra_sort_file_size,
+ SHOW_SYS},
+ {sys_myisam_max_sort_file_size.name,
+ (char*) &sys_myisam_max_sort_file_size,
+ SHOW_SYS},
+ {"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
+ {sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
+#ifdef __NT__
+ {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_BOOL},
+#endif
+ {sys_net_buffer_length.name,(char*) &sys_net_buffer_length, SHOW_SYS},
+ {sys_net_read_timeout.name, (char*) &sys_net_read_timeout, SHOW_SYS},
+ {"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
+ {sys_net_write_timeout.name,(char*) &sys_net_write_timeout, SHOW_SYS},
+ {"open_files_limit", (char*) &open_files_limit, SHOW_LONG},
+ {"pid_file", (char*) pidfile_name, SHOW_CHAR},
+ {"port", (char*) &mysql_port, SHOW_INT},
+ {"protocol_version", (char*) &protocol_version, SHOW_INT},
+ {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS},
+ {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS},
+ {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS},
+#ifdef HAVE_QUERTY_CACHE
+ {sys_query_cache_limit.name,(char*) &sys_query_cache_limit, SHOW_SYS},
+ {sys_query_cache_size.name, (char*) &sys_query_cache_size, SHOW_SYS},
+ {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS},
+#endif /* HAVE_QUERY_CACHE */
+ {sys_safe_show_db.name, (char*) &sys_safe_show_db, SHOW_SYS},
+ {sys_server_id.name, (char*) &sys_server_id, SHOW_SYS},
+ {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS},
+ {"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
+ {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
+ {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
+ {sys_slow_launch_time.name, (char*) &sys_slow_launch_time, SHOW_SYS},
+ {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR},
+ {sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS},
+ {"sql_mode", (char*) &opt_sql_mode, SHOW_LONG},
+ {"table_cache", (char*) &table_cache_size, SHOW_LONG},
+ {sys_table_type.name, (char*) &sys_table_type, SHOW_SYS},
+ {sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS},
+#ifdef HAVE_THR_SETCONCURRENCY
+ {"thread_concurrency", (char*) &concurrency, SHOW_LONG},
+#endif
+ {"thread_stack", (char*) &thread_stack, SHOW_LONG},
+ {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS},
+#ifdef HAVE_TZNAME
+ {"timezone", time_zone, SHOW_CHAR},
+#endif
+ {sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS},
+ {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR},
+ {"version", server_version, SHOW_CHAR},
+ {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS},
+ {NullS, NullS, SHOW_LONG}
+};
+
+/*
+ Functions to check and update variables
+*/
+
+/*
+ The following 3 functions need to be changed in 4.1 when we allow
+ one to change character sets
+*/
+
+static bool sys_check_charset(THD *thd, set_var *var)
+{
+ return 0;
+}
+
+
+static bool sys_update_charset(THD *thd, set_var *var)
+{
+ return 0;
+}
+
+
+static void sys_set_default_charset(THD *thd, enum_var_type type)
+{
+}
+
+
+/*
+ If one sets the LOW_PRIORIY UPDATES flag, we also must change the
+ used lock type
+*/
+
+static void fix_low_priority_updates(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->update_lock_default= (thd->variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY : TL_WRITE);
+}
+
+
+/*
+ Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR
+*/
+
+static void fix_max_join_size(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ {
+ if (thd->variables.max_join_size == (ulong) HA_POS_ERROR)
+ thd->options|= OPTION_BIG_SELECTS;
+ else
+ thd->options&= ~OPTION_BIG_SELECTS;
+ }
+}
+
+
+/*
+ If one doesn't use the SESSION modifier, the isolation level
+ is only active for the next command
+*/
+
+static void fix_tx_isolation(THD *thd, enum_var_type type)
+{
+ if (type == OPT_SESSION)
+ thd->session_tx_isolation= ((enum_tx_isolation)
+ thd->variables.tx_isolation);
+}
+
+
+/*
+ If we are changing the thread variable, we have to copy it to NET too
+*/
+
+static void fix_net_read_timeout(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->net.read_timeout=thd->variables.net_read_timeout;
+}
+
+
+static void fix_net_write_timeout(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->net.write_timeout=thd->variables.net_write_timeout;
+}
+
+
+static void fix_query_cache_size(THD *thd, enum_var_type type)
+{
+#ifdef HAVE_QUERY_CACHE
+ query_cache.resize(query_cache_size);
+#endif
+}
+
+
+static void fix_key_buffer_size(THD *thd, enum_var_type type)
+{
+ ha_resize_key_cache();
+}
+
+
+bool sys_var_long_ptr::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+ if (option_limits)
+ *value= (ulong) getopt_ull_limit_value(tmp, option_limits);
+ else
+ *value= (ulong) tmp;
+ return 0;
+}
+
+
+void sys_var_long_ptr::set_default(THD *thd, enum_var_type type)
+{
+ *value= (ulong) option_limits->def_value;
+}
+
+
+bool sys_var_bool_ptr::update(THD *thd, set_var *var)
+{
+ *value= (my_bool) var->save_result.ulong_value;
+ return 0;
+}
+
+
+void sys_var_bool_ptr::set_default(THD *thd, enum_var_type type)
+{
+ *value= (my_bool) option_limits->def_value;
+}
+
+
+bool sys_var_thd_ulong::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+
+ /* Don't use bigger value than given with --maximum-variable-name=.. */
+ if ((ulong) tmp > max_system_variables.*offset)
+ tmp= max_system_variables.*offset;
+
+ if (option_limits)
+ tmp= (ulong) getopt_ull_limit_value(tmp, option_limits);
+ if (var->type == OPT_GLOBAL)
+ {
+ /* Lock is needed to make things safe on 32 bit systems */
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ global_system_variables.*offset=tmp;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ }
+ else
+ thd->variables.*offset= (ulong) tmp;
+ return 0;
+}
+
+
+void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ {
+ /* We will not come here if option_limits is not set */
+ global_system_variables.*offset= (ulong) option_limits->def_value;
+ }
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.*offset= var->value->val_int();
+ else
+ thd->variables.*offset= var->value->val_int();
+ return 0;
+}
+
+
+void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= (ulong) option_limits->def_value;
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var_thd_bool::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.*offset= (my_bool) var->save_result.ulong_value;
+ else
+ thd->variables.*offset= (my_bool) var->save_result.ulong_value;
+ return 0;
+}
+
+
+void sys_var_thd_bool::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= (my_bool) option_limits->def_value;
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names)
+{
+ char buff[80], *value;
+ String str(buff,sizeof(buff)), *res;
+
+ if (var->value->result_type() == STRING_RESULT)
+ {
+ if (!(res=var->value->val_str(&str)) ||
+ ((long) (var->save_result.ulong_value=
+ (ulong) find_type(res->c_ptr(), enum_names, 3)-1))
+ < 0)
+ {
+ value=res->c_ptr();
+ goto err;
+ }
+ }
+ else
+ {
+ ulonglong tmp=var->value->val_int();
+ if (tmp >= enum_names->count)
+ {
+ llstr(tmp,buff);
+ value=buff; // Wrong value is here
+ goto err;
+ }
+ var->save_result.ulong_value= (ulong) tmp; // Save for update
+ }
+ return 0;
+
+err:
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
+ return 1;
+}
+
+/*
+ Return an Item for a variable. Used with @@[global.]variable_name
+
+ If type is not given, return local value if exists, else global
+
+ We have to use netprintf() instead of my_error() here as this is
+ called on the parsing stage.
+*/
+
+Item *sys_var::item(THD *thd, enum_var_type var_type)
+{
+ if (check_type(var_type))
+ {
+ if (var_type != OPT_DEFAULT)
+ {
+ net_printf(&thd->net,
+ var_type == OPT_GLOBAL ? ER_LOCAL_VARIABLE :
+ ER_GLOBAL_VARIABLE, name);
+ return 0;
+ }
+ /* As there was no local variable, return the global value */
+ var_type= OPT_GLOBAL;
+ }
+ switch (type()) {
+ case SHOW_LONG:
+ return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type));
+ case SHOW_LONGLONG:
+ return new Item_int(*(longlong*) value_ptr(thd, var_type));
+ case SHOW_MY_BOOL:
+ return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type),1);
+ case SHOW_CHAR:
+ {
+ char *str= (char*) value_ptr(thd, var_type);
+ return new Item_string(str,strlen(str));
+ }
+ default:
+ net_printf(&thd->net, ER_VAR_CANT_BE_READ, name);
+ }
+ return 0;
+}
+
+
+bool sys_var_thd_enum::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.*offset= var->save_result.ulong_value;
+ else
+ thd->variables.*offset= var->save_result.ulong_value;
+ return 0;
+}
+
+
+void sys_var_thd_enum::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= (ulong) option_limits->def_value;
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type)
+{
+ ulong tmp= ((type == OPT_GLOBAL) ?
+ global_system_variables.*offset :
+ thd->variables.*offset);
+ return (byte*) enum_names->type_names[tmp];
+}
+
+
+bool sys_var_thd_bit::update(THD *thd, set_var *var)
+{
+ bool res= (*update_func)(thd, var);
+ thd->lex.select_lex.options=thd->options;
+ return res;
+}
+
+
+byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type)
+{
+ /*
+ If reverse is 0 (default) return 1 if bit is set.
+ If reverse is 1, return 0 if bit is set
+ */
+ thd->sys_var_tmp.my_bool_value= ((thd->options & bit_flag) ?
+ !reverse : reverse);
+ return (byte*) &thd->sys_var_tmp.my_bool_value;
+}
+
+
+bool sys_var_thd_conv_charset::check(THD *thd, set_var *var)
+{
+ CONVERT *tmp;
+ char buff[80];
+ String str(buff,sizeof(buff)), *res;
+
+ if (!var->value) // Default value
+ {
+ var->save_result.convert= (var->type != OPT_GLOBAL ?
+ global_system_variables.convert_set
+ : (CONVERT*) 0);
+ return 0;
+ }
+ if (!(res=var->value->val_str(&str)))
+ res= &empty_string;
+
+ if (!(tmp=get_convert_set(res->c_ptr())))
+ {
+ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
+ return 1;
+ }
+ var->save_result.convert=tmp; // Save for update
+ return 0;
+}
+
+
+bool sys_var_thd_conv_charset::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.convert_set= var->save_result.convert;
+ else
+ thd->lex.convert_set= thd->variables.convert_set=
+ var->save_result.convert;
+ return 0;
+}
+
+
+byte *sys_var_thd_conv_charset::value_ptr(THD *thd, enum_var_type type)
+{
+ CONVERT *conv= ((type == OPT_GLOBAL) ?
+ global_system_variables.convert_set :
+ thd->variables.convert_set);
+ return conv ? (byte*) conv->name : (byte*) "";
+}
+
+
+
+bool sys_var_timestamp::update(THD *thd, set_var *var)
+{
+ thd->set_time((time_t) var->value->val_int());
+ return 0;
+}
+
+
+void sys_var_timestamp::set_default(THD *thd, enum_var_type type)
+{
+ thd->user_time=0;
+}
+
+
+byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type)
+{
+ thd->sys_var_tmp.long_value= (long) thd->start_time;
+ return (byte*) &thd->sys_var_tmp.long_value;
+}
+
+
+bool sys_var_last_insert_id::update(THD *thd, set_var *var)
+{
+ thd->insert_id(var->value->val_int());
+ return 0;
+}
+
+
+byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type)
+{
+ thd->sys_var_tmp.long_value= (long) thd->insert_id();
+ return (byte*) &thd->last_insert_id;
+}
+
+
+bool sys_var_insert_id::update(THD *thd, set_var *var)
+{
+ thd->next_insert_id=var->value->val_int();
+ return 0;
+}
+
+
+byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type)
+{
+ return (byte*) &thd->current_insert_id;
+}
+
+
+bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
+{
+ bool result=0;
+ LOCK_ACTIVE_MI;
+ pthread_mutex_lock(&active_mi->rli.run_lock);
+ if (active_mi->rli.slave_running)
+ {
+ my_error(ER_SLAVE_MUST_STOP, MYF(0));
+ result=1;
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ UNLOCK_ACTIVE_MI;
+ return result;
+}
+
+
+bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
+{
+ LOCK_ACTIVE_MI;
+ pthread_mutex_lock(&active_mi->rli.run_lock);
+ /*
+ The following test should normally never be true as we test this
+ in the check function; To be safe against multiple
+ SQL_SLAVE_SKIP_COUNTER request, we do the check anyway
+ */
+ if (!active_mi->rli.slave_running)
+ {
+ pthread_mutex_lock(&active_mi->rli.data_lock);
+ active_mi->rli.slave_skip_counter= var->value->val_int();
+ pthread_mutex_unlock(&active_mi->rli.data_lock);
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ UNLOCK_ACTIVE_MI;
+ return 0;
+}
+
+
+/*
+ Functions to update thd->options bits
+*/
+
+static bool set_option_bit(THD *thd, set_var *var)
+{
+ if (var->save_result.ulong_value == 0)
+ thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
+ else
+ thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
+ return 0;
+}
+
+
+static bool set_option_autocommit(THD *thd, set_var *var)
+{
+ /* The test is negative as the flag we use is NOT autocommit */
+
+ ulong org_options=thd->options;
+
+ if (var->save_result.ulong_value != 0)
+ thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
+ else
+ thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
+
+ if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
+ {
+ if ((org_options & OPTION_NOT_AUTOCOMMIT))
+ {
+ /* We changed to auto_commit mode */
+ thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+ thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
+ if (ha_commit(thd))
+ return 1;
+ }
+ else
+ {
+ thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
+ thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
+ }
+ }
+ return 0;
+}
+
+
+static bool set_log_update(THD *thd, set_var *var)
+{
+ if (opt_sql_bin_update)
+ ((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG |
+ OPTION_UPDATE_LOG);
+ set_option_bit(thd, var);
+ return 0;
+}
+
+
+/****************************************************************************
+ Main handling of variables:
+ - Initialisation
+ - Searching during parsing
+ - Update loop
+****************************************************************************/
+
+/*
+ Find variable name in option my_getopt structure used for command line args
+
+ SYNOPSIS
+ find_option()
+ opt option structure array to search in
+ name variable name
+
+ RETURN VALUES
+ 0 Error
+ ptr pointer to option structure
+*/
+
+static struct my_option *find_option(struct my_option *opt, const char *name)
+{
+ uint length=strlen(name);
+ for (; opt->name; opt++)
+ {
+ if (!getopt_compare_strings(opt->name, name, length) &&
+ !opt->name[length])
+ {
+ /*
+ Only accept the option if one can set values through it.
+ If not, there is no default value or limits in the option.
+ */
+ return (opt->value) ? opt : 0;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ Return variable name and length for hashing of variables
+*/
+
+static byte *get_sys_var_length(const sys_var *var, uint *length,
+ my_bool first)
+{
+ *length= var->name_length;
+ return (byte*) var->name;
+}
+
+
+/*
+ Initialises sys variables and put them in system_variable_hash
+*/
+
+
+void set_var_init()
+{
+ extern struct my_option my_long_options[]; // From mysqld
+
+ hash_init(&system_variable_hash,array_elements(sys_variables),0,0,
+ (hash_get_key) get_sys_var_length,0, HASH_CASE_INSENSITIVE);
+ sys_var **var, **end;
+ for (var= sys_variables, end= sys_variables+array_elements(sys_variables) ;
+ var < end;
+ var++)
+ {
+ (*var)->name_length= strlen((*var)->name);
+ (*var)->option_limits= find_option(my_long_options, (*var)->name);
+ hash_insert(&system_variable_hash, (byte*) *var);
+ }
+
+ /*
+ Special cases
+ Needed because MySQL can't find the limits for a variable it it has
+ a different name than the command line option.
+ As these variables are deprecated, this code will disappear soon...
+ */
+ sys_sql_max_join_size.option_limits= sys_max_join_size.option_limits;
+}
+
+
+void set_var_free()
+{
+ hash_free(&system_variable_hash);
+}
+
+
+/*
+ Find a user set-table variable
+
+ SYNOPSIS
+ find_sys_var()
+ str Name of system variable to find
+ length Length of variable. zero means that we should use strlen()
+ on the variable
+
+ NOTE
+ We have to use net_printf() as this is called during the parsing stage
+
+ RETURN VALUES
+ pointer pointer to variable definitions
+ 0 Unknown variable (error message is given)
+*/
+
+sys_var *find_sys_var(const char *str, uint length=0)
+{
+ sys_var *var= (sys_var*) hash_search(&system_variable_hash, str,
+ length ? length :
+ strlen(str));
+ if (!var)
+ net_printf(&current_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str);
+ return var;
+}
+
+
+/*
+ Execute update of all variables
+
+ SYNOPSIS
+
+ sql_set
+ THD Thread id
+ set_var List of variables to update
+
+ DESCRIPTION
+ First run a check of all variables that all updates will go ok.
+ If yes, then execute all updates, returning an error if any one failed.
+
+ This should ensure that in all normal cases none all or variables are
+ updated
+
+ RETURN VALUE
+ 0 ok
+ 1 Something got wrong (normally no variables was updated)
+*/
+
+bool sql_set_variables(THD *thd, List<set_var_base> *var_list)
+{
+ bool error=0;
+ List_iterator<set_var_base> it(*var_list);
+
+ set_var_base *var;
+ while ((var=it++))
+ {
+ if (var->check(thd))
+ return 1;
+ }
+ it.rewind();
+ while ((var=it++))
+ {
+ if (var->update(thd))
+ error=1;
+ }
+ return error;
+}
+
+
+/*****************************************************************************
+ Functions to handle SET mysql_internal_variable=const_expr
+*****************************************************************************/
+
+bool set_var::check(THD *thd)
+{
+ if (var->check_type(type))
+ {
+ my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE,
+ MYF(0),
+ var->name);
+ return 1;
+ }
+ if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)))
+ return 1;
+
+ /* value is a NULL pointer if we are using SET ... = DEFAULT */
+ if (!value)
+ {
+ if (var->check_default(type))
+ {
+ my_error(ER_NO_DEFAULT, MYF(0), var->name);
+ return 1;
+ }
+ return 0;
+ }
+
+ if (value->fix_fields(thd,0))
+ return 1;
+ if (var->check_update_type(value->result_type()))
+ {
+ my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
+ return 1;
+ }
+ return var->check(thd, this);
+}
+
+
+bool set_var::update(THD *thd)
+{
+ if (!value)
+ var->set_default(thd, type);
+ else if (var->update(thd, this))
+ return 1; // should never happen
+ if (var->after_update)
+ (*var->after_update)(thd, type);
+ return 0;
+}
+
+
+/*****************************************************************************
+ Functions to handle SET @user_variable=const_expr
+*****************************************************************************/
+
+bool set_var_user::check(THD *thd)
+{
+ return user_var_item->fix_fields(thd,0);
+}
+
+
+bool set_var_user::update(THD *thd)
+{
+ if (user_var_item->update())
+ {
+ /* Give an error if it's not given already */
+ send_error(&thd->net, ER_SET_CONSTANTS_ONLY);
+ return 1;
+ }
+ return 0;
+}
+
+
+/*****************************************************************************
+ Functions to handle SET PASSWORD
+*****************************************************************************/
+
+bool set_var_password::check(THD *thd)
+{
+ if (!user->host.str)
+ user->host.str= (char*) thd->host_or_ip;
+ return check_change_password(thd, user->host.str, user->user.str);
+}
+
+bool set_var_password::update(THD *thd)
+{
+ return change_password(thd, user->host.str, user->user.str, password);
+}
+
+/****************************************************************************
+ Used templates
+****************************************************************************/
+
+#ifdef __GNUC__
+template class List<set_var_base>;
+template class List_iterator<set_var_base>;
+#endif
diff --git a/sql/set_var.h b/sql/set_var.h
new file mode 100644
index 00000000000..607e44d2ef3
--- /dev/null
+++ b/sql/set_var.h
@@ -0,0 +1,419 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Classes to support the SET command */
+
+#ifdef __GNUC__
+#pragma interface /* gcc class implementation */
+#endif
+
+/****************************************************************************
+ Variables that are changable runtime are declared using the
+ following classes
+****************************************************************************/
+
+class sys_var;
+class set_var;
+typedef struct system_variables SV;
+extern TYPELIB bool_typelib;
+
+enum enum_var_type
+{
+ OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
+};
+
+typedef bool (*sys_check_func)(THD *, set_var *);
+typedef bool (*sys_update_func)(THD *, set_var *);
+typedef void (*sys_after_update_func)(THD *,enum_var_type);
+typedef void (*sys_set_default_func)(THD *, enum_var_type);
+
+class sys_var
+{
+public:
+ struct my_option *option_limits; /* Updated by by set_var_init() */
+ uint name_length; /* Updated by by set_var_init() */
+ const char *name;
+ sys_after_update_func after_update;
+ sys_var(const char *name_arg) :name(name_arg),after_update(0)
+ {}
+ sys_var(const char *name_arg,sys_after_update_func func)
+ :name(name_arg),after_update(func)
+ {}
+ virtual ~sys_var() {}
+ virtual bool check(THD *thd, set_var *var) { return 0; }
+ bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names);
+ virtual bool update(THD *thd, set_var *var)=0;
+ virtual void set_default(THD *thd, enum_var_type type) {}
+ virtual SHOW_TYPE type() { return SHOW_UNDEF; }
+ virtual byte *value_ptr(THD *thd, enum_var_type type) { return 0; }
+ virtual bool check_type(enum_var_type type)
+ { return type != OPT_GLOBAL; } /* Error if not GLOBAL */
+ virtual bool check_update_type(Item_result type)
+ { return type != INT_RESULT; } /* Assume INT */
+ virtual bool check_default(enum_var_type type)
+ { return option_limits == 0; }
+ Item *item(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_long_ptr :public sys_var
+{
+public:
+ ulong *value;
+ sys_var_long_ptr(const char *name_arg, ulong *value_ptr)
+ :sys_var(name_arg),value(value_ptr) {}
+ sys_var_long_ptr(const char *name_arg, ulong *value_ptr,
+ sys_after_update_func func)
+ :sys_var(name_arg,func), value(value_ptr) {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONG; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+};
+
+
+class sys_var_bool_ptr :public sys_var
+{
+public:
+ my_bool *value;
+ sys_var_bool_ptr(const char *name_arg, my_bool *value_arg)
+ :sys_var(name_arg),value(value_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, &bool_typelib);
+ }
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_MY_BOOL; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_str :public sys_var
+{
+public:
+ char *value; // Pointer to allocated string
+ sys_check_func check_func;
+ sys_update_func update_func;
+ sys_set_default_func set_default_func;
+ sys_var_str(const char *name_arg,
+ sys_check_func check_func_arg,
+ sys_update_func update_func_arg,
+ sys_set_default_func set_default_func_arg)
+ :sys_var(name_arg), check_func(check_func_arg),
+ update_func(update_func_arg),set_default_func(set_default_func_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_func ? (*check_func)(thd, var) : 0;
+ }
+ bool update(THD *thd, set_var *var)
+ {
+ return (*update_func)(thd, var);
+ }
+ void set_default(THD *thd, enum_var_type type)
+ {
+ return (*set_default_func)(thd, type);
+ }
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+ bool check_update_type(Item_result type)
+ {
+ return type != STRING_RESULT; /* Only accept strings */
+ }
+ bool check_default(enum_var_type type) { return 0; }
+};
+
+
+class sys_var_thd :public sys_var
+{
+public:
+ sys_var_thd(const char *name_arg)
+ :sys_var(name_arg)
+ {}
+ sys_var_thd(const char *name_arg, sys_after_update_func func)
+ :sys_var(name_arg,func)
+ {}
+ bool check_type(enum_var_type type) { return 0; }
+ bool check_default(enum_var_type type)
+ {
+ return type == OPT_GLOBAL && !option_limits;
+ }
+};
+
+
+class sys_var_thd_ulong :public sys_var_thd
+{
+public:
+ ulong SV::*offset;
+ sys_var_thd_ulong(const char *name_arg, ulong SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ sys_var_thd_ulong(const char *name_arg, ulong SV::*offset_arg,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_thd_ulonglong :public sys_var_thd
+{
+public:
+ ulonglong SV::*offset;
+ sys_var_thd_ulonglong(const char *name_arg, ulonglong SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_thd_bool :public sys_var_thd
+{
+public:
+ my_bool SV::*offset;
+ sys_var_thd_bool(const char *name_arg, my_bool SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ sys_var_thd_bool(const char *name_arg, my_bool SV::*offset_arg,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_MY_BOOL; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, &bool_typelib);
+ }
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_thd_enum :public sys_var_thd
+{
+ ulong SV::*offset;
+ TYPELIB *enum_names;
+public:
+ sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+ TYPELIB *typelib)
+ :sys_var_thd(name_arg), offset(offset_arg), enum_names(typelib)
+ {}
+ sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+ TYPELIB *typelib,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg), enum_names(typelib)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, enum_names);
+ }
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_thd_bit :public sys_var_thd
+{
+ sys_update_func update_func;
+public:
+ ulong bit_flag;
+ bool reverse;
+ sys_var_thd_bit(const char *name_arg, sys_update_func func, ulong bit,
+ bool reverse_arg=0)
+ :sys_var_thd(name_arg), update_func(func), bit_flag(bit),
+ reverse(reverse_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, &bool_typelib);
+ }
+ bool update(THD *thd, set_var *var);
+ bool check_update_type(Item_result type) { return 0; }
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE type() { return SHOW_MY_BOOL; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+/* some variables that require special handling */
+
+class sys_var_timestamp :public sys_var
+{
+public:
+ sys_var_timestamp(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ bool check_default(enum_var_type type) { return 0; }
+ SHOW_TYPE type() { return SHOW_LONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_last_insert_id :public sys_var
+{
+public:
+ sys_var_last_insert_id(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_insert_id :public sys_var
+{
+public:
+ sys_var_insert_id(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_slave_skip_counter :public sys_var
+{
+public:
+ sys_var_slave_skip_counter(const char *name_arg) :sys_var(name_arg) {}
+ bool check(THD *thd, set_var *var);
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type != OPT_GLOBAL; }
+ /*
+ We can't retrieve the value of this, so we don't have to define
+ type() or value_ptr()
+ */
+};
+
+
+class sys_var_thd_conv_charset :public sys_var_thd
+{
+public:
+ sys_var_thd_conv_charset(const char *name_arg)
+ :sys_var_thd(name_arg)
+ {}
+ bool check(THD *thd, set_var *var);
+ bool update(THD *thd, set_var *var);
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check_update_type(Item_result type)
+ {
+ return type != STRING_RESULT; /* Only accept strings */
+ }
+ bool check_default(enum_var_type type) { return 0; }
+};
+
+
+/****************************************************************************
+ Classes for parsing of the SET command
+****************************************************************************/
+
+class set_var_base :public Sql_alloc
+{
+public:
+ set_var_base() {}
+ virtual ~set_var_base() {}
+ virtual bool check(THD *thd)=0; /* To check privileges etc. */
+ virtual bool update(THD *thd)=0; /* To set the value */
+};
+
+
+/* MySQL internal variables, like query_cache_size */
+
+class set_var :public set_var_base
+{
+public:
+ sys_var *var;
+ Item *value;
+ enum_var_type type;
+ union
+ {
+ CONVERT *convert;
+ ulong ulong_value;
+ } save_result;
+
+ set_var(enum_var_type type_arg, sys_var *var_arg, Item *value_arg)
+ :var(var_arg), type(type_arg)
+ {
+ /*
+ If the set value is a field, change it to a string to allow things like
+ SET table_type=MYISAM;
+ */
+ if (value_arg && value_arg->type() == Item::FIELD_ITEM)
+ {
+ Item_field *item= (Item_field*) value_arg;
+ if (!(value=new Item_string(item->field_name, strlen(item->field_name))))
+ value=value_arg; /* Give error message later */
+ }
+ else
+ value=value_arg;
+ }
+ bool check(THD *thd);
+ bool update(THD *thd);
+};
+
+
+/* User variables like @my_own_variable */
+
+class set_var_user: public set_var_base
+{
+ Item_func_set_user_var *user_var_item;
+public:
+ set_var_user(Item_func_set_user_var *item)
+ :user_var_item(item)
+ {}
+ bool check(THD *thd);
+ bool update(THD *thd);
+};
+
+/* For SET PASSWORD */
+
+class set_var_password: public set_var_base
+{
+ LEX_USER *user;
+ char *password;
+public:
+ set_var_password(LEX_USER *user_arg,char *password_arg)
+ :user(user_arg), password(password_arg)
+ {}
+ bool check(THD *thd);
+ bool update(THD *thd);
+};
+
+
+/*
+ Prototypes for helper functions
+*/
+
+void set_var_init();
+void set_var_free();
+sys_var *find_sys_var(const char *str, uint length=0);
+bool sql_set_variables(THD *thd, List<set_var_base> *var_list);
+
+extern sys_var_str sys_charset;
diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt
index 70ec831eaa0..f5695a1aeb6 100644
--- a/sql/share/czech/errmsg.txt
+++ b/sql/share/czech/errmsg.txt
@@ -238,3 +238,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt
index 0aba168d398..f758f3c6c4c 100644
--- a/sql/share/danish/errmsg.txt
+++ b/sql/share/danish/errmsg.txt
@@ -232,3 +232,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt
index 641cd6c73ae..3081968c537 100644
--- a/sql/share/dutch/errmsg.txt
+++ b/sql/share/dutch/errmsg.txt
@@ -238,3 +238,9 @@
"Optie '%s' tweemaal gebruikt in opdracht",
"Gebruiker '%-.64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)",
"Toegang geweigerd. U moet het %-.128s privilege hebben voor deze operatie",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt
index 8845d5fead7..0e480d795c3 100644
--- a/sql/share/english/errmsg.txt
+++ b/sql/share/english/errmsg.txt
@@ -229,3 +229,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt
index 3939c50f378..603560e31ed 100644
--- a/sql/share/estonian/errmsg.txt
+++ b/sql/share/estonian/errmsg.txt
@@ -234,3 +234,9 @@
"Määrangut '%s' on lauses kasutatud topelt",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt
index 97178218826..807312b41a2 100644
--- a/sql/share/french/errmsg.txt
+++ b/sql/share/french/errmsg.txt
@@ -229,3 +229,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt
index 19e981539c2..5c0f222bb1b 100644
--- a/sql/share/german/errmsg.txt
+++ b/sql/share/german/errmsg.txt
@@ -232,3 +232,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt
index c3c9f2e010a..404a9ea5c1d 100644
--- a/sql/share/greek/errmsg.txt
+++ b/sql/share/greek/errmsg.txt
@@ -229,3 +229,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt
index 5d2589e60f5..658f1161843 100644
--- a/sql/share/hungarian/errmsg.txt
+++ b/sql/share/hungarian/errmsg.txt
@@ -231,3 +231,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt
index 4a6561c712a..52915d6c143 100644
--- a/sql/share/italian/errmsg.txt
+++ b/sql/share/italian/errmsg.txt
@@ -229,3 +229,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt
index 3007bc8b0cb..958c04e3d75 100644
--- a/sql/share/japanese/errmsg.txt
+++ b/sql/share/japanese/errmsg.txt
@@ -231,3 +231,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt
index dc44bb25109..ba5e5023a17 100644
--- a/sql/share/korean/errmsg.txt
+++ b/sql/share/korean/errmsg.txt
@@ -229,3 +229,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt
index 89cde7754cd..e205cae60d1 100644
--- a/sql/share/norwegian-ny/errmsg.txt
+++ b/sql/share/norwegian-ny/errmsg.txt
@@ -231,3 +231,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt
index e0c8142a939..4d650b1c439 100644
--- a/sql/share/norwegian/errmsg.txt
+++ b/sql/share/norwegian/errmsg.txt
@@ -231,3 +231,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt
index 4b67e5f76ea..9ee380b0ab9 100644
--- a/sql/share/polish/errmsg.txt
+++ b/sql/share/polish/errmsg.txt
@@ -233,3 +233,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt
index 8e416e3dcb2..3906e638ba2 100644
--- a/sql/share/portuguese/errmsg.txt
+++ b/sql/share/portuguese/errmsg.txt
@@ -229,3 +229,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt
index 1bc22fbb360..ffde33c0e1d 100644
--- a/sql/share/romanian/errmsg.txt
+++ b/sql/share/romanian/errmsg.txt
@@ -233,3 +233,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt
index 83747310839..fa03d28ee32 100644
--- a/sql/share/russian/errmsg.txt
+++ b/sql/share/russian/errmsg.txt
@@ -232,3 +232,9 @@
"ïÐÃÉÑ '%s' ÉÓÐÏÌØÚÏ×ÁÎÁ Ä×ÁÖÄÙ",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt
index fc23521305c..cb5f62302b6 100644
--- a/sql/share/slovak/errmsg.txt
+++ b/sql/share/slovak/errmsg.txt
@@ -237,3 +237,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt
index b5f1795bf8f..1b0fbc87241 100644
--- a/sql/share/spanish/errmsg.txt
+++ b/sql/share/spanish/errmsg.txt
@@ -230,3 +230,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt
index 5cec38202fa..fb948a01083 100644
--- a/sql/share/swedish/errmsg.txt
+++ b/sql/share/swedish/errmsg.txt
@@ -229,3 +229,9 @@
"Option '%s' användes två gånger",
"Användare '%-.64s' har överskridit '%s' (nuvarande värde: %ld)",
"Du har inte privlegiet '%-.128s' som behövs för denna operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt
index 81530dbd03c..2e7560ed618 100644
--- a/sql/share/ukrainian/errmsg.txt
+++ b/sql/share/ukrainian/errmsg.txt
@@ -234,3 +234,9 @@
"Option '%s' used twice in statement",
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
diff --git a/sql/slave.cc b/sql/slave.cc
index 4b58816f409..e8119c6aea2 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -70,9 +70,10 @@ static inline bool sql_slave_killed(THD* thd,RELAY_LOG_INFO* rli);
static int count_relay_log_space(RELAY_LOG_INFO* rli);
static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
-static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
+static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool suppress_warnings);
static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool reconnect);
+ bool reconnect, bool suppress_warnings);
static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
void* thread_killed_arg);
static int request_table_dump(MYSQL* mysql, const char* db, const char* table);
@@ -1476,8 +1477,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
thd->system_thread = thd->bootstrap = 1;
thd->client_capabilities = 0;
my_net_init(&thd->net, 0);
- thd->net.timeout = slave_net_timeout;
- thd->max_packet_length=thd->net.max_packet;
+ thd->net.read_timeout = slave_net_timeout;
thd->master_access= ~0;
thd->priv_user = 0;
thd->slave_thread = 1;
@@ -1503,7 +1503,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
#endif
- if (thd->max_join_size == (ulong) ~0L)
+ if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
if (thd_type == SLAVE_THD_SQL)
@@ -1515,6 +1515,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
DBUG_RETURN(0);
}
+
static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
void* thread_killed_arg)
{
@@ -1548,7 +1549,8 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
return 0;
}
-static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
+static int request_dump(MYSQL* mysql, MASTER_INFO* mi,
+ bool *suppress_warnings)
{
char buf[FN_REFLEN + 10];
int len;
@@ -1567,7 +1569,10 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
in the future, we should do a better error analysis, but for
now we just fill up the error log :-)
*/
- sql_print_error("Error on COM_BINLOG_DUMP: %s, will retry in %d secs",
+ if (mc_mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
+ *suppress_warnings= 1; // Suppress reconnect warning
+ else
+ sql_print_error("Error on COM_BINLOG_DUMP: %s, will retry in %d secs",
mc_mysql_error(mysql), master_connect_retry);
return 1;
}
@@ -1582,10 +1587,10 @@ static int request_table_dump(MYSQL* mysql, const char* db, const char* table)
uint table_len = (uint) strlen(table);
uint db_len = (uint) strlen(db);
if (table_len + db_len > sizeof(buf) - 2)
- {
- sql_print_error("request_table_dump: Buffer overrun");
- return 1;
- }
+ {
+ sql_print_error("request_table_dump: Buffer overrun");
+ return 1;
+ }
*p++ = db_len;
memcpy(p, db, db_len);
@@ -1603,7 +1608,24 @@ command");
return 0;
}
-static ulong read_event(MYSQL* mysql, MASTER_INFO *mi)
+/*
+ read one event from the master
+
+ SYNOPSIS
+ read_event()
+ mysql MySQL connection
+ mi Master connection information
+ suppress_warnings TRUE when a normal net read timeout has caused us to
+ try a reconnect. We do not want to print anything to
+ the error log in this case because this a anormal
+ event in an idle server.
+ RETURN VALUES
+ 'packet_error' Error
+ number Length of packet
+
+*/
+
+static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
{
ulong len = packet_error;
@@ -1615,14 +1637,25 @@ static ulong read_event(MYSQL* mysql, MASTER_INFO *mi)
if (disconnect_slave_event_count && !(events_till_disconnect--))
return packet_error;
#endif
+ *suppress_warnings= 0;
len = mc_net_safe_read(mysql);
if (len == packet_error || (long) len < 1)
{
- sql_print_error("Error reading packet from server: %s (\
+ if (mc_mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
+ {
+ /*
+ We are trying a normal reconnect after a read timeout;
+ we suppress prints to .err file as long as the reconnect
+ happens without problems
+ */
+ *suppress_warnings= TRUE;
+ }
+ else
+ sql_print_error("Error reading packet from server: %s (\
server_errno=%d)",
- mc_mysql_error(mysql), mc_mysql_errno(mysql));
+ mc_mysql_error(mysql), mc_mysql_errno(mysql));
return packet_error;
}
@@ -1639,26 +1672,26 @@ server_errno=%d)",
return len - 1;
}
+
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int expected_error)
{
- switch (expected_error)
- {
- case ER_NET_READ_ERROR:
- case ER_NET_ERROR_ON_WRITE:
- case ER_SERVER_SHUTDOWN:
- case ER_NEW_ABORTING_CONNECTION:
- my_snprintf(rli->last_slave_error, sizeof(rli->last_slave_error),
- "Slave: query '%s' partially completed on the master \
+ switch (expected_error) {
+ case ER_NET_READ_ERROR:
+ case ER_NET_ERROR_ON_WRITE:
+ case ER_SERVER_SHUTDOWN:
+ case ER_NEW_ABORTING_CONNECTION:
+ my_snprintf(rli->last_slave_error, sizeof(rli->last_slave_error),
+ "Slave: query '%s' partially completed on the master \
and was aborted. There is a chance that your master is inconsistent at this \
point. If you are sure that your master is ok, run this query manually on the\
slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\
SLAVE START;", thd->query);
- rli->last_slave_errno = expected_error;
- sql_print_error("%s",rli->last_slave_error);
- return 1;
- default:
- return 0;
- }
+ rli->last_slave_errno = expected_error;
+ sql_print_error("%s",rli->last_slave_error);
+ return 1;
+ default:
+ return 0;
+ }
}
static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
@@ -1752,6 +1785,7 @@ slave_begin:
}
mi->io_thd = thd;
thd->thread_stack = (char*)&thd; // remember where our stack is
+ thd->store_globals();
threads.append(thd);
mi->slave_running = 1;
mi->abort_slave = 0;
@@ -1805,8 +1839,9 @@ connected:
while (!io_slave_killed(thd,mi))
{
+ bool suppress_warnings= 0;
thd->proc_info = "Requesting binlog dump";
- if (request_dump(mysql, mi))
+ if (request_dump(mysql, mi, &suppress_warnings))
{
sql_print_error("Failed on request_dump()");
if (io_slave_killed(thd,mi))
@@ -1837,10 +1872,12 @@ dump");
}
thd->proc_info = "Reconnecting after a failed dump request";
- sql_print_error("Slave I/O thread: failed dump request, \
+ if (!suppress_warnings)
+ sql_print_error("Slave I/O thread: failed dump request, \
reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
- if (safe_reconnect(thd, mysql, mi) || io_slave_killed(thd,mi))
+ llstr(mi->master_log_pos,llbuff));
+ if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
+ io_slave_killed(thd,mi))
{
sql_print_error("Slave I/O thread killed during or \
after reconnect");
@@ -1852,8 +1889,9 @@ after reconnect");
while (!io_slave_killed(thd,mi))
{
+ bool suppress_warnings= 0;
thd->proc_info = "Reading master update";
- ulong event_len = read_event(mysql, mi);
+ ulong event_len = read_event(mysql, mi, &suppress_warnings);
if (io_slave_killed(thd,mi))
{
sql_print_error("Slave I/O thread killed while reading event");
@@ -1867,7 +1905,7 @@ after reconnect");
sql_print_error("Log entry on master is longer than \
max_allowed_packet (%ld) on slave. Slave thread will be aborted. If the entry \
is correct, restart the server with a higher value of max_allowed_packet",
- max_allowed_packet);
+ thd->variables.max_allowed_packet);
goto err;
}
@@ -1886,10 +1924,12 @@ reconnect after a failed read");
goto err;
}
thd->proc_info = "Reconnecting after a failed read";
- sql_print_error("Slave I/O thread: Failed reading log event, \
+ if (!suppress_warnings)
+ sql_print_error("Slave I/O thread: Failed reading log event, \
reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos, llbuff));
- if (safe_reconnect(thd, mysql, mi) || io_slave_killed(thd,mi))
+ llstr(mi->master_log_pos, llbuff));
+ if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
+ io_slave_killed(thd,mi))
{
sql_print_error("Slave I/O thread killed during or after a \
reconnect done to recover from failed read");
@@ -2005,6 +2045,7 @@ slave_begin:
THD_CHECK_SENTRY(thd);
thd->thread_stack = (char*)&thd; // remember where our stack is
thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
+ thd->store_globals();
threads.append(thd);
rli->sql_thd = thd;
rli->slave_running = 1;
@@ -2383,7 +2424,7 @@ void end_relay_log_info(RELAY_LOG_INFO* rli)
/* try to connect until successful or slave killed */
static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
{
- return connect_to_master(thd, mysql, mi, 0);
+ return connect_to_master(thd, mysql, mi, 0, 0);
}
@@ -2393,7 +2434,7 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
*/
static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool reconnect)
+ bool reconnect, bool suppress_warnings)
{
int slave_was_killed;
int last_errno= -2; // impossible error
@@ -2406,11 +2447,13 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
while (!(slave_was_killed = io_slave_killed(thd,mi)) &&
(reconnect ? mc_mysql_reconnect(mysql) != 0 :
!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
- mi->port, 0, 0)))
+ mi->port, 0, 0,
+ thd->variables.net_read_timeout)))
{
/* Don't repeat last error */
if (mc_mysql_errno(mysql) != last_errno)
{
+ suppress_warnings= 0;
sql_print_error("Slave I/O thread: error connecting to master \
'%s@%s:%d': \
%s, last_errno=%d, retry in %d sec",mi->user,mi->host,mi->port,
@@ -2437,11 +2480,14 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
if (!slave_was_killed)
{
if (reconnect)
- sql_print_error("Slave: connected to master '%s@%s:%d',\
+ {
+ if (!suppress_warnings)
+ sql_print_error("Slave: connected to master '%s@%s:%d',\
replication resumed in log '%s' at position %s", mi->user,
- mi->host, mi->port,
- IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
+ mi->host, mi->port,
+ IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
+ }
else
{
change_rpl_status(RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE);
@@ -2462,11 +2508,13 @@ replication resumed in log '%s' at position %s", mi->user,
master_retry_count times
*/
-static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
+static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool suppress_warnings)
{
- return connect_to_master(thd, mysql, mi, 1);
+ return connect_to_master(thd, mysql, mi, 1, suppress_warnings);
}
+
int flush_relay_log_info(RELAY_LOG_INFO* rli)
{
register IO_CACHE* file = &rli->info_file;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 23e02114e0e..e5abd5ce8a7 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -970,41 +970,63 @@ bool acl_check_host(const char *host, const char *ip)
}
/*****************************************************************************
-** Change password for the user if it's not an anonymous user
-** Note: This should write the error directly to the client!
+ Change password for the user if it's not an anonymous user
+ Note: This should write the error directly to the client!
*****************************************************************************/
-bool change_password(THD *thd, const char *host, const char *user,
- char *new_password)
-{
- uint length=0;
- DBUG_ENTER("change_password");
- DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'",
- host,user,new_password));
+/*
+ Check if the user is allowed to change password
+
+ SYNOPSIS:
+ check_change_password()
+ thd THD
+ host hostname for the user
+ user user name
+ RETURN VALUE
+ 0 OK
+ 1 ERROR ; In this case the error is sent to the client.
+*/
+
+bool check_change_password(THD *thd, const char *host, const char *user)
+{
if (!initialized)
{
send_error(&thd->net, ER_PASSWORD_NOT_ALLOWED); /* purecov: inspected */
- DBUG_RETURN(1); /* purecov: inspected */
+ return(1); /* purecov: inspected */
}
- if (!host)
- host=thd->ip; /* purecov: tested */
- /* password should always be 0 or 16 chars; simple hack to avoid cracking */
- length=(uint) strlen(new_password);
- new_password[length & 16]=0;
-
if (!thd->slave_thread &&
(strcmp(thd->user,user) ||
my_strcasecmp(host,thd->host ? thd->host : thd->ip)))
{
if (check_access(thd, UPDATE_ACL, "mysql",0,1))
- DBUG_RETURN(1);
+ return(1);
}
if (!thd->slave_thread && !thd->user[0])
{
send_error(&thd->net, ER_PASSWORD_ANONYMOUS_USER);
- DBUG_RETURN(1);
+ return(1);
}
+ return(0);
+}
+
+
+bool change_password(THD *thd, const char *host, const char *user,
+ char *new_password)
+{
+ uint length=0;
+ DBUG_ENTER("change_password");
+ DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'",
+ host,user,new_password));
+ DBUG_ASSERT(host != 0); // Ensured by parent
+
+ if (check_change_password(thd, host, user))
+ DBUG_RETURN(1);
+
+ /* password should always be 0 or 16 chars; simple hack to avoid cracking */
+ length=(uint) strlen(new_password);
+ new_password[length & 16]=0;
+
VOID(pthread_mutex_lock(&acl_cache->lock));
ACL_USER *acl_user;
if (!(acl_user= find_acl_user(host,user)))
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 5d522fa1d7e..d6cf320c978 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -79,6 +79,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
const char *password,const char *scramble,char **priv_user,
bool old_ver, USER_RESOURCES *max);
bool acl_check_host(const char *host, const char *ip);
+bool check_change_password(THD *thd, const char *host, const char *user);
bool change_password(THD *thd, const char *host, const char *user,
char *password);
int mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 40f6b40f9b5..29cc925218f 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -193,7 +193,7 @@ send_fields(THD *thd,List<Item> &list,uint flag)
List_iterator_fast<Item> it(list);
Item *item;
char buff[80];
- CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set;
+ CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->variables.convert_set;
DBUG_ENTER("send_fields");
String tmp((char*) buff,sizeof(buff)),*res,*packet= &thd->packet;
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 56ce1997bcb..cba9f17359a 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -342,6 +342,12 @@ TODO list:
#define DUMP(C)
#endif
+const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND",NullS };
+TYPELIB query_cache_type_typelib=
+{
+ array_elements(query_cache_type_names)-1,"", query_cache_type_names
+};
+
/*****************************************************************************
Query_cache_block_table method(s)
*****************************************************************************/
@@ -711,13 +717,13 @@ Query_cache::Query_cache(ulong query_cache_limit,
}
-ulong Query_cache::resize(ulong query_cache_size)
+ulong Query_cache::resize(ulong query_cache_size_arg)
{
DBUG_ENTER("Query_cache::resize");
- DBUG_PRINT("qcache", ("from %lu to %lu",this->query_cache_size,
- query_cache_size));
+ DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size,
+ query_cache_size_arg));
free_cache(0);
- this->query_cache_size=query_cache_size;
+ query_cache_size=query_cache_size_arg;
DBUG_RETURN(init_cache());
}
@@ -757,10 +763,10 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
most significant bit - CLIENT_LONG_FLAG,
other - charset number (0 no charset convertion)
*/
- if (thd->convert_set != 0)
+ if (thd->variables.convert_set != 0)
{
- flags|= (byte) thd->convert_set->number();
- DBUG_ASSERT(thd->convert_set->number() < 128);
+ flags|= (byte) thd->variables.convert_set->number();
+ DBUG_ASSERT(thd->variables.convert_set->number() < 128);
}
tot_length=thd->query_length+thd->db_length+2;
thd->query[tot_length-1] = (char) flags;
@@ -864,8 +870,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
it is not possible to check has_transactions() function of handler
because tables not opened yet
*/
- (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)) ||
- thd->query_cache_type == 0)
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
+ thd->variables.query_cache_type == 0)
{
DBUG_PRINT("qcache", ("query cache disabled or not in autocommit mode"));
@@ -917,10 +923,10 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Other - charset number (0 no charset convertion)
*/
flags = (thd->client_capabilities & CLIENT_LONG_FLAG ? 0x80 : 0);
- if (thd->convert_set != 0)
+ if (thd->variables.convert_set != 0)
{
- flags |= (byte) thd->convert_set->number();
- DBUG_ASSERT(thd->convert_set->number() < 128);
+ flags |= (byte) thd->variables.convert_set->number();
+ DBUG_ASSERT(thd->variables.convert_set->number() < 128);
}
sql[tot_length-1] = (char) flags;
query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql,
@@ -1031,7 +1037,7 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
DUMP(this);
using_transactions = using_transactions &&
- (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN));
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
for (; tables_used; tables_used=tables_used->next)
{
DBUG_ASSERT(!using_transactions || tables_used->table!=0);
@@ -1089,7 +1095,7 @@ void Query_cache::invalidate(THD *thd, TABLE *table,
if (query_cache_size > 0)
{
using_transactions = using_transactions &&
- (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN));
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
if (using_transactions && table->file->has_transactions())
thd->add_changed_table(table);
else
@@ -2389,16 +2395,16 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
if (lex->sql_command == SQLCOM_SELECT &&
thd->temporary_tables == 0 &&
- (thd->query_cache_type == 1 ||
- (thd->query_cache_type == 2 && (lex->select->options &
- OPTION_TO_QUERY_CACHE))) &&
+ (thd->variables.query_cache_type == 1 ||
+ (thd->variables.query_cache_type == 2 && (lex->select->options &
+ OPTION_TO_QUERY_CACHE))) &&
thd->safe_to_cache_query)
{
my_bool has_transactions = 0;
DBUG_PRINT("qcache", ("options %lx %lx, type %u",
OPTION_TO_QUERY_CACHE,
lex->select->options,
- (int) thd->query_cache_type));
+ (int) thd->variables.query_cache_type));
for (; tables_used; tables_used=tables_used->next)
{
@@ -2422,7 +2428,7 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
}
}
- if ((thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)) &&
+ if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
has_transactions)
{
DBUG_PRINT("qcache", ("not in autocommin mode"));
@@ -2437,7 +2443,7 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
(int) lex->sql_command,
OPTION_TO_QUERY_CACHE,
lex->select->options,
- (int) thd->query_cache_type));
+ (int) thd->variables.query_cache_type));
DBUG_RETURN(0);
}
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index 5403377564b..3088331f19a 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -189,10 +189,10 @@ struct Query_cache_memory_bin
uint number;
Query_cache_block *free_blocks;
- inline void init(ulong size)
+ inline void init(ulong size_arg)
{
#ifndef DBUG_OFF
- this->size = size;
+ size = size_arg;
#endif
number = 0;
free_blocks = 0;
@@ -204,11 +204,11 @@ struct Query_cache_memory_bin_step
ulong size;
ulong increment;
uint idx;
- inline void init(ulong size, uint idx, ulong increment)
+ inline void init(ulong size_arg, uint idx_arg, ulong increment_arg)
{
- this->size = size;
- this->idx = idx;
- this->increment = increment;
+ size = size_arg;
+ idx = idx_arg;
+ increment = increment_arg;
}
};
@@ -398,6 +398,7 @@ protected:
};
extern Query_cache query_cache;
+extern TYPELIB query_cache_type_typelib;
void query_cache_insert(NET *net, const char *packet, ulong length);
void query_cache_end_of_result(NET *net);
void query_cache_abort(NET *net);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index a823a8a8df4..cc2c9fdc6ef 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -51,8 +51,6 @@ template class List<Alter_drop>;
template class List_iterator<Alter_drop>;
template class List<Alter_column>;
template class List_iterator<Alter_column>;
-template class List<Set_option>;
-template class List_iterator<Set_option>;
#endif
/****************************************************************************
@@ -105,7 +103,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
slave_proxy_id = 0;
file_id = 0;
cond_count=0;
- convert_set=0;
mysys_var=0;
#ifndef DBUG_OFF
dbug_sentry=THD_SENTRY_MAGIC;
@@ -129,23 +126,15 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
slave_net = 0;
log_pos = 0;
server_status= SERVER_STATUS_AUTOCOMMIT;
- update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
+ update_lock_default= (variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY :
+ TL_WRITE);
options= thd_startup_options;
-#ifdef HAVE_QUERY_CACHE
- query_cache_type= (byte) query_cache_startup_type;
-#else
- query_cache_type= 0; //Safety
-#endif
sql_mode=(uint) opt_sql_mode;
- inactive_timeout= variables.net_wait_timeout;
open_options=ha_open_options;
- tx_isolation=session_tx_isolation=default_tx_isolation;
+ session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
command=COM_CONNECT;
set_query_id=1;
- default_select_limit= HA_POS_ERROR;
- max_join_size= ((variables.max_join_size != ~ (ulong) 0L) ?
- variables.max_join_size :
- HA_POS_ERROR);
db_access=NO_ACCESS;
/* Initialize sub structures */
@@ -300,7 +289,7 @@ void THD::add_changed_table(TABLE *table)
{
DBUG_ENTER("THD::add_changed_table(table)");
- DBUG_ASSERT((options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)) &&
+ DBUG_ASSERT((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
table->file->has_transactions());
CHANGED_TABLE_LIST** prev = &transaction.changed_tables;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 760e96c057b..633f7a4aa76 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -282,43 +282,61 @@ class delayed_insert;
struct system_variables
{
- my_bool opt_local_infile;
- my_bool opt_warnings;
+ ulonglong myisam_max_extra_sort_file_size;
+ ulonglong myisam_max_sort_file_size;
+ ulong bulk_insert_buff_size;
ulong join_buff_size;
ulong long_query_time;
+ ulong max_allowed_packet;
ulong max_heap_table_size;
- ulong max_item_sort_length;
+ ulong max_sort_length;
ulong max_join_size;
ulong max_tmp_tables;
- ulong myisam_max_extra_sort_file_size;
- ulong myisam_max_sort_file_size;
+ ulong myisam_sort_buff_size;
+ ulong net_buffer_length;
ulong net_interactive_timeout;
+ ulong net_read_timeout;
ulong net_wait_timeout;
- ulong record_rnd_cache_size;
+ ulong net_write_timeout;
+ ulong query_cache_type;
+ ulong read_buff_size;
+ ulong read_rnd_buff_size;
+ ulong select_limit;
ulong sortbuff_size;
ulong tmp_table_size;
-}; /* system variables */
+ ulong tx_isolation;
+ ulong table_type;
+ my_bool log_warnings;
+ my_bool low_priority_updates;
+
+ CONVERT *convert_set;
+};
-/* For each client connection we create a separate thread with THD serving as
- a thread/connection descriptor */
+
+/*
+ For each client connection we create a separate thread with THD serving as
+ a thread/connection descriptor
+*/
class THD :public ilink {
public:
- NET net; // client connection descriptor
- LEX lex; // parse tree descriptor
- MEM_ROOT mem_root; // 1 command-life memory allocation pool
- HASH user_vars; // hash for user variables
- String packet; // dynamic string buffer used for network I/O
- struct sockaddr_in remote; // client socket address
- struct rand_struct rand; // used for authentication
- struct system_variables variables;
+ NET net; // client connection descriptor
+ LEX lex; // parse tree descriptor
+ MEM_ROOT mem_root; // 1 command-life memory pool
+ HASH user_vars; // hash for user variables
+ String packet; // dynamic buffer for network I/O
+ struct sockaddr_in remote; // client socket address
+ struct rand_struct rand; // used for authentication
+ struct system_variables variables; // Changeable local variables
- /* query points to the current query,
- thread_stack is a pointer to the stack frame of handle_one_connection(),
- which is called first in the thread for handling a client
- */
- char *query,*thread_stack;
+ char *query; // Points to the current query,
+ /*
+ A pointer to the stack frame of handle_one_connection(),
+ which is called first in the thread for handling a client
+ */
+ char *thread_stack;
+
/*
host - host of the client
user - user of the client, set to NULL until the user has been read from
@@ -336,9 +354,9 @@ public:
const char *host_or_ip;
uint client_capabilities; /* What the client supports */
- ulong max_packet_length; /* Max packet length for client */
/* Determines if which non-standard SQL behaviour should be enabled */
uint sql_mode;
+ uint max_client_packet_length;
ulong master_access; /* Global privileges from mysql.user */
ulong db_access; /* Privileges for current db */
@@ -358,7 +376,7 @@ public:
#endif
struct st_my_thread_var *mysys_var;
enum enum_server_command command;
- uint32 server_id;
+ uint32 server_id;
uint32 file_id; // for LOAD DATA INFILE
const char *where;
time_t start_time,time_after_lock,user_time;
@@ -385,7 +403,6 @@ public:
}
} transaction;
Item *free_list, *handler_items;
- CONVERT *convert_set;
Field *dupp_field;
#ifndef __WIN__
sigset_t signals,block_signals;
@@ -396,18 +413,19 @@ public:
#endif
ulonglong next_insert_id,last_insert_id,current_insert_id,
limit_found_rows;
- ha_rows select_limit,offset_limit,default_select_limit,cuted_fields,
- max_join_size, sent_row_count, examined_row_count;
+ ha_rows select_limit, offset_limit, cuted_fields,
+ sent_row_count, examined_row_count;
table_map used_tables;
USER_CONN *user_connect;
- ulong query_id,version, inactive_timeout,options,thread_id, col_access;
+ ulong query_id,version, options,thread_id, col_access;
long dbug_thread_id;
pthread_t real_id;
uint current_tablenr,tmp_table,cond_count;
uint server_status,open_options;
uint32 query_length;
uint32 db_length;
- enum_tx_isolation tx_isolation, session_tx_isolation;
+ /* variables.transaction_isolation is reset to this after each commit */
+ enum_tx_isolation session_tx_isolation;
char scramble[9];
uint8 query_cache_type; // type of query cache processing
bool slave_thread;
@@ -432,6 +450,13 @@ public:
NET* slave_net; // network connection from slave -> m.
my_off_t log_pos;
+ /* Used by the sys_var class to store temporary values */
+ union
+ {
+ my_bool my_bool_value;
+ long long_value;
+ } sys_var_tmp;
+
THD();
~THD();
void cleanup(void);
@@ -452,11 +477,11 @@ public:
inline void close_active_vio()
{
pthread_mutex_lock(&active_vio_lock);
- if(active_vio)
- {
- vio_close(active_vio);
- active_vio = 0;
- }
+ if (active_vio)
+ {
+ vio_close(active_vio);
+ active_vio = 0;
+ }
pthread_mutex_unlock(&active_vio_lock);
}
#endif
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 6ea815cd51a..87926d0612c 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -274,7 +274,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
}
my_dirend(dirp);
- if (thd->killed || (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 1)))
+ if (thd->killed ||
+ (tot_list && mysql_rm_table_part2_with_lock(thd, tot_list, 1, 1)))
DBUG_RETURN(-1);
/*
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index de86bb8abc9..8788a1576dc 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -78,7 +78,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
select=make_select(table,0,0,conds,&error);
if (error)
DBUG_RETURN(-1);
- if ((select && select->check_quick(test(thd->options & SQL_SAFE_UPDATES),
+ if ((select && select->check_quick(test(thd->options & OPTION_SAFE_UPDATES),
limit)) ||
!limit)
{
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index a3c6da5e50d..53388220924 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -197,8 +197,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
lock_type != TL_WRITE_DELAYED &&
!(specialflag & SPECIAL_SAFE_MODE))))
{
- table->file->extra(HA_EXTRA_WRITE_CACHE);
- table->file->extra(HA_EXTRA_BULK_INSERT_BEGIN);
+ table->file->extra_opt(HA_EXTRA_WRITE_CACHE,
+ thd->variables.read_buff_size);
+ table->file->extra_opt(HA_EXTRA_BULK_INSERT_BEGIN,
+ thd->variables.bulk_insert_buff_size);
}
while ((values = its++))
@@ -933,9 +935,7 @@ static pthread_handler_decl(handle_delayed_insert,arg)
#endif
DBUG_ENTER("handle_delayed_insert");
- if (init_thr_lock() ||
- my_pthread_setspecific_ptr(THR_THD, thd) ||
- my_pthread_setspecific_ptr(THR_NET, &thd->net))
+ if (init_thr_lock() || thd->store_globals())
{
thd->fatal_error=1;
strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 7015ce3f98b..9a6eb05ac5d 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -147,7 +147,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->select->in_sum_expr=0;
lex->select->expr_list.empty();
lex->select->ftfunc_list.empty();
- lex->convert_set=(lex->thd=thd)->convert_set;
+ lex->convert_set=(lex->thd=thd)->variables.convert_set;
lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE);
lex->slave_thd_opt=0;
@@ -525,7 +525,7 @@ int yylex(void *arg)
}
yylval->lex_str=get_token(lex,length);
if (lex->convert_set)
- lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
return(IDENT);
case STATE_IDENT_SEP: // Found ident and now '.'
@@ -853,14 +853,12 @@ int yylex(void *arg)
}
break;
case STATE_USER_END: // end '@' of user@hostname
- switch (state_map[yyPeek()])
- {
+ switch (state_map[yyPeek()]) {
case STATE_STRING:
case STATE_USER_VARIABLE_DELIMITER:
break;
case STATE_USER_END:
- lex->next_state=STATE_USER_END;
- yySkip();
+ lex->next_state=STATE_SYSTEM_VAR;
break;
default:
lex->next_state=STATE_HOSTNAME;
@@ -875,6 +873,33 @@ int yylex(void *arg)
c= yyGet()) ;
yylval->lex_str=get_token(lex,yyLength());
return(LEX_HOSTNAME);
+ case STATE_SYSTEM_VAR:
+ yylval->lex_str.str=(char*) lex->ptr;
+ yylval->lex_str.length=1;
+ lex->next_state=STATE_IDENT_OR_KEYWORD;
+ yySkip(); // Skip '@'
+ return((int) '@');
+ case STATE_IDENT_OR_KEYWORD:
+ /*
+ We come here when we have found two '@' in a row.
+ We should now be able to handle:
+ [(global | local | session) .]variable_name
+ */
+
+ while (state_map[c=yyGet()] == STATE_IDENT ||
+ state_map[c] == STATE_NUMBER_IDENT) ;
+ if (c == '.')
+ lex->next_state=STATE_IDENT_SEP;
+ length= (uint) (lex->ptr - lex->tok_start)-1;
+ if ((tokval= find_keyword(lex,length,0)))
+ {
+ yyUnget(); // Put back 'c'
+ return(tokval); // Was keyword
+ }
+ yylval->lex_str=get_token(lex,length);
+ if (lex->convert_set)
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
+ return(IDENT);
}
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 305e3e44cbc..fae7eb8e7ff 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -27,6 +27,8 @@ class LEX_COLUMN;
YYSTYPE before including this file
*/
+#include "set_var.h"
+
#ifdef MYSQL_YACC
#define LEX_YYSTYPE void *
#else
@@ -71,7 +73,8 @@ enum lex_states
STATE_OPERATOR_OR_IDENT, STATE_NUMBER_IDENT, STATE_INT_OR_REAL,
STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT,
STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END,
- STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER
+ STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER, STATE_SYSTEM_VAR,
+ STATE_IDENT_OR_KEYWORD
};
typedef List<Item> List_item;
@@ -114,19 +117,6 @@ typedef struct st_select_lex
} SELECT_LEX;
-class Set_option :public Sql_alloc
-{
-public:
- const char *name;
- Item *item;
- uint name_length;
- bool type; /* 1 if global */
- Set_option(bool par_type, const char *par_name, uint length,
- Item *par_item)
- :name(par_name), item(par_item), name_length(length), type(par_type) {}
-};
-
-
/* The state of the lex parsing. This is saved in the THD struct */
typedef struct st_lex
@@ -147,22 +137,22 @@ typedef struct st_lex
List<Alter_drop> drop_list;
List<Alter_column> alter_list;
List<String> interval_list;
- List<st_lex_user> users_list;
+ List<LEX_USER> users_list;
List<LEX_COLUMN> columns;
List<Key> key_list;
List<create_field> create_list;
List<Item> *insert_list,field_list,value_list;
List<List_item> many_values;
- List<Set_option> option_list;
+ List<set_var_base> var_list;
SQL_LIST proc_list, auxilliary_table_list;
TYPELIB *interval;
create_field *last_field;
Item *default_value;
CONVERT *convert_set;
+ CONVERT *thd_convert_set; // Set with SET CHAR SET
LEX_USER *grant_user;
gptr yacc_yyss,yacc_yyvs;
THD *thd;
- struct system_variables *variable_values;
udf_func udf;
HA_CHECK_OPT check_opt; // check/repair options
HA_CREATE_INFO create_info;
@@ -176,10 +166,11 @@ typedef struct st_lex
enum enum_ha_read_modes ha_read_mode;
enum ha_rkey_function ha_rkey_mode;
enum enum_enable_or_disable alter_keys_onoff;
+ enum enum_var_type option_type;
uint grant,grant_tot_col,which_columns, union_option;
thr_lock_type lock_option;
bool drop_primary,drop_if_exists,local_file;
- bool in_comment,ignore_space,verbose,simple_alter, option_type;
+ bool in_comment,ignore_space,verbose,simple_alter;
uint slave_thd_opt;
} LEX;
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 820d85d5117..e58c7493a0f 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -52,17 +52,21 @@ public:
char unescape(char chr);
int terminator(char *ptr,uint length);
bool find_start_of_fields();
- // we need to force cache close before destructor is invoked to log
- // the last read block
+ /*
+ We need to force cache close before destructor is invoked to log
+ the last read block
+ */
void end_io_cache()
{
::end_io_cache(&cache);
need_end_io_cache = 0;
}
- // either this method, or we need to make cache public
- // arg must be set from mysql_load() since constructor does not see
- // either the table or THD value
+ /*
+ Either this method, or we need to make cache public
+ Arg must be set from mysql_load() since constructor does not see
+ either the table or THD value
+ */
void set_io_cache_arg(void* arg) { cache.arg = arg; }
};
@@ -89,6 +93,10 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
bool using_transactions;
DBUG_ENTER("mysql_load");
+#ifdef EMBEDDED_LIBRARY
+ read_file_from_client = 0; //server is always in the same process
+#endif
+
if (escaped->length() > 1 || enclosed->length() > 1)
{
my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS),
@@ -216,7 +224,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
lf_info.handle_dup = handle_duplicates;
lf_info.wrote_create_file = 0;
lf_info.last_pos_in_file = HA_POS_ERROR;
- read_info.set_io_cache_arg((void*)&lf_info);
+ read_info.set_io_cache_arg((void*) &lf_info);
}
restore_record(table,2);
@@ -238,8 +246,10 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (use_timestamp)
table->time_stamp=0;
table->next_number_field=table->found_next_number_field;
- VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
- VOID(table->file->extra(HA_EXTRA_BULK_INSERT_BEGIN));
+ VOID(table->file->extra_opt(HA_EXTRA_WRITE_CACHE,
+ thd->variables.read_buff_size));
+ VOID(table->file->extra_opt(HA_EXTRA_BULK_INSERT_BEGIN,
+ thd->variables.bulk_insert_buff_size));
if (handle_duplicates == DUP_IGNORE ||
handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6f5d0bf03a1..c8297a584ca 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -14,11 +14,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef EMBEDDED_LIBRARY
-#define net_read_timeout net_read_timeout1
-#define net_write_timeout net_write_timeout1
-#endif
-
#include "mysql_priv.h"
#include "sql_acl.h"
#include "sql_repl.h"
@@ -107,7 +102,7 @@ static void init_signals(void)
inline bool end_active_trans(THD *thd)
{
int error=0;
- if (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN |
+ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK))
{
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
@@ -203,7 +198,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
CLIENT_LONG_PASSWORD),&ur);
DBUG_PRINT("info",
("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
- thd->client_capabilities, thd->max_packet_length,
+ thd->client_capabilities, thd->max_client_packet_length,
thd->host_or_ip, thd->priv_user,
passwd[0] ? "yes": "no",
thd->master_access, thd->db ? thd->db : "*none*"));
@@ -516,7 +511,7 @@ check_connections(THD *thd)
#endif
if (connect_errors)
reset_host_errors(&thd->remote.sin_addr);
- if (thd->packet.alloc(net_buffer_length))
+ if (thd->packet.alloc(thd->variables.net_buffer_length))
return(ER_OUT_OF_RESOURCES);
thd->client_capabilities=uint2korr(net->read_pos);
@@ -528,7 +523,7 @@ check_connections(THD *thd)
{
/* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress..."));
- sslaccept(ssl_acceptor_fd, net->vio, thd->inactive_timeout);
+ sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout);
DBUG_PRINT("info", ("Reading user information over SSL layer"));
if ((pkt_len=my_net_read(net)) == packet_error ||
pkt_len < NORMAL_HANDSHAKE_SIZE)
@@ -550,7 +545,7 @@ check_connections(THD *thd)
}
#endif
- thd->max_packet_length=uint3korr(net->read_pos+2);
+ thd->max_client_packet_length=uint3korr(net->read_pos+2);
char *user= (char*) net->read_pos+5;
char *passwd= strend(user)+1;
char *db=0;
@@ -559,11 +554,11 @@ check_connections(THD *thd)
if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
db=strend(passwd)+1;
if (thd->client_capabilities & CLIENT_INTERACTIVE)
- thd->inactive_timeout= thd->variables.net_interactive_timeout;
+ thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions)
thd->net.return_status= &thd->server_status;
- net->timeout=(uint) net_read_timeout;
+ net->read_timeout=(uint) thd->variables.net_read_timeout;
if (check_user(thd,COM_CONNECT, user, passwd, db, 1))
return (-1);
thd->password=test(passwd[0]);
@@ -639,7 +634,7 @@ pthread_handler_decl(handle_one_connection,arg)
goto end_thread;
}
- if (thd->max_join_size == HA_POS_ERROR)
+ if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
if (thd->client_capabilities & CLIENT_COMPRESS)
net->compress=1; // Use compression
@@ -661,7 +656,7 @@ pthread_handler_decl(handle_one_connection,arg)
free_root(&thd->mem_root,MYF(0));
if (net->error && net->vio != 0)
{
- if (!thd->killed && thd->variables.opt_warnings)
+ if (!thd->killed && thd->variables.log_warnings)
sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
thd->thread_id,(thd->db ? thd->db : "unconnected"),
thd->user ? thd->user : "unauthenticated",
@@ -715,7 +710,7 @@ pthread_handler_decl(handle_bootstrap,arg)
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
#endif
- if (thd->max_join_size == (ulong) ~0L)
+ if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
thd->proc_info=0;
@@ -833,8 +828,9 @@ bool do_command(THD *thd)
thd->current_tablenr=0;
packet=0;
- old_timeout=net->timeout;
- net->timeout=(uint) thd->inactive_timeout; // Wait max for 8 hours
+ old_timeout=net->read_timeout;
+ // Wait max for 8 hours
+ net->read_timeout=(uint) thd->variables.net_wait_timeout;
net->last_error[0]=0; // Clear error message
net->last_errno=0;
@@ -853,7 +849,7 @@ bool do_command(THD *thd)
vio_description(net->vio), command,
command_name[command]));
}
- net->timeout=old_timeout; // Timeout for writing
+ net->read_timeout=old_timeout; // restore it
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
}
@@ -871,13 +867,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
DBUG_ENTER("dispatch_command");
thd->command=command;
+ thd->set_time();
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id=query_id;
if (command != COM_STATISTICS && command != COM_PING)
query_id++;
thread_running++;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->set_time();
+
thd->lex.select_lex.options=0; // We store status here
switch (command) {
case COM_INIT_DB:
@@ -972,7 +969,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->db_length+2)))
break;
thd->query[packet_length]=0;
- thd->packet.shrink(net_buffer_length); // Reclaim some memory
+ thd->packet.shrink(thd->variables.net_buffer_length);// Reclaim some memory
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
mysql_log.write(thd,command,"%s",thd->query);
@@ -1213,7 +1210,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->query=0;
thread_running--;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->packet.shrink(net_buffer_length); // Reclaim some memory
+ thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
DBUG_RETURN(error);
}
@@ -2042,11 +2039,11 @@ mysql_execute_command(void)
break;
case SQLCOM_SHOW_STATUS:
res= mysqld_show(thd,(lex->wild ? lex->wild->ptr() : NullS),status_vars,
- (struct system_variables*) 0);
+ OPT_GLOBAL);
break;
case SQLCOM_SHOW_VARIABLES:
res= mysqld_show(thd, (lex->wild ? lex->wild->ptr() : NullS),
- init_vars, lex->variable_values);
+ init_vars, lex->option_type);
break;
case SQLCOM_SHOW_LOGS:
{
@@ -2153,7 +2150,7 @@ mysql_execute_command(void)
else
{
if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
- ! thd->variables.opt_local_infile)
+ ! opt_local_infile)
{
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND);
goto error;
@@ -2167,39 +2164,11 @@ mysql_execute_command(void)
break;
}
case SQLCOM_SET_OPTION:
- {
- ulong org_options=thd->options;
- thd->options=select_lex->options;
- thd->update_lock_default= ((thd->options & OPTION_LOW_PRIORITY_UPDATES) ?
- TL_WRITE_LOW_PRIORITY : TL_WRITE);
- thd->default_select_limit=select_lex->select_limit;
- thd->tx_isolation=lex->tx_isolation;
- DBUG_PRINT("info",("options: %ld limit: %ld",
- thd->options,(long) thd->default_select_limit));
-
- /* Check if auto_commit mode changed */
- if ((org_options ^ select_lex->options) & OPTION_NOT_AUTO_COMMIT)
- {
- if ((org_options & OPTION_NOT_AUTO_COMMIT))
- {
- /* We changed to auto_commit mode */
- thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
- thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
- if (ha_commit(thd))
- {
- res= -1;
- break;
- }
- }
- else
- {
- thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
- thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
- }
- }
- send_ok(&thd->net);
+ if (sql_set_variables(thd, &lex->var_list))
+ res= -1;
+ else
+ send_ok(&thd->net);
break;
- }
case SQLCOM_UNLOCK_TABLES:
if (thd->locked_tables)
{
@@ -2726,7 +2695,7 @@ mysql_init_select(LEX *lex)
{
SELECT_LEX *select_lex = lex->select;
select_lex->where=select_lex->having=0;
- select_lex->select_limit=lex->thd->default_select_limit;
+ select_lex->select_limit= lex->thd->variables.select_limit;
select_lex->offset_limit=0;
select_lex->options=0;
select_lex->linkage=UNSPECIFIED_TYPE;
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 3b689a2571d..3e652a4d5a6 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -92,13 +92,17 @@ static int send_file(THD *thd)
char buf[IO_SIZE]; // It's safe to alloc this
DBUG_ENTER("send_file");
- // the client might be slow loading the data, give him wait_timeout to do
- // the job
- old_timeout = thd->net.timeout;
- thd->net.timeout = thd->inactive_timeout;
+ /*
+ The client might be slow loading the data, give him wait_timeout to do
+ the job
+ */
+ old_timeout = thd->net.read_timeout;
+ thd->net.read_timeout = thd->variables.net_wait_timeout;
- // we need net_flush here because the client will not know it needs to send
- // us the file name until it has processed the load event entry
+ /*
+ We need net_flush here because the client will not know it needs to send
+ us the file name until it has processed the load event entry
+ */
if (net_flush(net) || (packet_len = my_net_read(net)) == packet_error)
{
errmsg = "while reading file name";
@@ -137,7 +141,7 @@ static int send_file(THD *thd)
error = 0;
err:
- thd->net.timeout = old_timeout;
+ thd->net.read_timeout = old_timeout;
if (fd >= 0)
(void) my_close(fd, MYF(0));
if (errmsg)
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index 207c2e110a7..6770f8aa01a 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -11,10 +11,9 @@ typedef struct st_slave_info
THD* thd;
} SLAVE_INFO;
-extern bool opt_show_slave_auth_info, opt_old_rpl_compat;
+extern my_bool opt_show_slave_auth_info, opt_old_rpl_compat;
extern char* master_host;
extern my_string opt_bin_logname, master_info_file;
-extern uint32 server_id;
extern bool server_id_supplied;
extern I_List<i_string> binlog_do_db, binlog_ignore_db;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 46b2b656fcf..89d22e2f595 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -426,7 +426,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
goto err;
}
if (!(thd->options & OPTION_BIG_SELECTS) &&
- join.best_read > (double) thd->max_join_size &&
+ join.best_read > (double) thd->variables.max_join_size &&
!(select_options & SELECT_DESCRIBE))
{ /* purecov: inspected */
result->send_error(ER_TOO_BIG_SELECT,ER(ER_TOO_BIG_SELECT)); /* purecov: inspected */
@@ -4894,7 +4894,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
error=join->result->send_data(*join->fields);
if (error)
DBUG_RETURN(-1); /* purecov: inspected */
- if (++join->send_records >= join->thd->select_limit && join->do_send_rows)
+ if (++join->send_records >= join->thd->select_limit &&
+ join->do_send_rows)
{
if (join->select_options & OPTION_FOUND_ROWS)
{
@@ -4986,7 +4987,8 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
join->send_records++;
DBUG_RETURN(0);
}
- if (!error && ++join->send_records >= join->thd->select_limit &&
+ if (!error &&
+ ++join->send_records >= join->thd->select_limit &&
join->do_send_rows)
{
if (!(join->select_options & OPTION_FOUND_ROWS))
@@ -5776,7 +5778,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
if (!field_count)
{ // only const items
- join->thd->select_limit=1; // Only send first row
+ join->thd->select_limit=1; // Only send first row
DBUG_RETURN(0);
}
Field **first_field=entry->field+entry->fields - field_count;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index ec0f7e09469..24f5ddeab7a 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -84,7 +84,7 @@ mysqld_show_dbs(THD *thd,const char *wild)
(grant_option && !check_grant_db(thd, file_name)))
{
thd->packet.length(0);
- net_store_data(&thd->packet, thd->convert_set, file_name);
+ net_store_data(&thd->packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
thd->packet.length()))
DBUG_RETURN(-1);
@@ -102,7 +102,7 @@ int mysqld_show_open_tables(THD *thd,const char *wild)
{
List<Item> field_list;
OPEN_TABLE_LIST *open_list;
- CONVERT *convert=thd->convert_set;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_open_tables");
field_list.push_back(new Item_empty_string("Database",NAME_LEN));
@@ -161,7 +161,7 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild)
while ((file_name=it++))
{
thd->packet.length(0);
- net_store_data(&thd->packet, thd->convert_set, file_name);
+ net_store_data(&thd->packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
}
@@ -257,7 +257,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
char *file_name;
TABLE *table;
String *packet= &thd->packet;
- CONVERT *convert=thd->convert_set;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_extend_show_tables");
(void) sprintf(path,"%s/%s",mysql_data_home,db);
@@ -433,7 +433,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
handler *file;
char tmp[MAX_FIELD_WIDTH];
Item *item;
- CONVERT *convert=thd->convert_set;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_fields");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name));
@@ -549,7 +549,7 @@ int
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
{
TABLE *table;
- CONVERT *convert=thd->convert_set;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_create");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name));
@@ -637,7 +637,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
{
TABLE *table;
char buff[256];
- CONVERT *convert=thd->convert_set;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_keys");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name));
@@ -768,7 +768,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
int
mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
{
- CONVERT *convert=thd->convert_set;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_dump_create_info");
DBUG_PRINT("enter",("table: %s",table->real_name));
@@ -1018,8 +1018,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
Item *field;
List<Item> field_list;
I_List<thread_info> thread_infos;
- ulong max_query_length= verbose ? max_allowed_packet : PROCESS_LIST_WIDTH;
- CONVERT *convert=thd->convert_set;
+ ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
+ PROCESS_LIST_WIDTH);
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_list_processes");
field_list.push_back(new Item_int("Id",0,7));
@@ -1143,13 +1144,12 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
- struct system_variables *values)
+ enum enum_var_type value_type)
{
- uint i;
char buff[8192];
String packet2(buff,sizeof(buff));
List<Item> field_list;
- CONVERT *convert=thd->convert_set;
+ CONVERT *convert=thd->variables.convert_set;
ulong offset;
DBUG_ENTER("mysqld_show");
@@ -1160,55 +1160,48 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
/* pthread_mutex_lock(&THR_LOCK_keycache); */
pthread_mutex_lock(&LOCK_status);
- for (i=0; variables[i].name; i++)
+ for (; variables->name; variables++)
{
- if (!(wild && wild[0] && wild_case_compare(variables[i].name,wild)))
+ if (!(wild && wild[0] && wild_case_compare(variables->name,wild)))
{
packet2.length(0);
- net_store_data(&packet2,convert,variables[i].name);
- switch (variables[i].type){
+ net_store_data(&packet2,convert,variables->name);
+ SHOW_TYPE show_type=variables->type;
+ char *value=variables->value;
+ if (show_type == SHOW_SYS)
+ {
+ show_type= ((sys_var*) value)->type();
+ value= ((sys_var*) value)->value_ptr(thd, value_type);
+ }
+
+ switch (show_type) {
case SHOW_LONG:
case SHOW_LONG_CONST:
- net_store_data(&packet2,(uint32) *(ulong*) variables[i].value);
+ net_store_data(&packet2,(uint32) *(ulong*) value);
+ break;
+ case SHOW_LONGLONG:
+ net_store_data(&packet2,(longlong) *(longlong*) value);
break;
- case SHOW_LONG_OFFSET:
- offset= (ulong) variables[i].value;
- net_store_data(&packet2,
- (uint32) *(ulong*) (((char*) values) + offset));
- break;
case SHOW_BOOL:
- net_store_data(&packet2,(ulong) *(bool*) variables[i].value ?
- "ON" : "OFF");
+ net_store_data(&packet2,(ulong) *(bool*) value ? "ON" : "OFF");
break;
case SHOW_MY_BOOL:
- net_store_data(&packet2,(ulong) *(my_bool*) variables[i].value ?
- "ON" : "OFF");
- break;
- case SHOW_MY_BOOL_OFFSET:
- offset= (ulong) variables[i].value;
- net_store_data(&packet2,
- ((ulong) *(my_bool*) (((char*) values) + offset)) ?
- "ON" : "OFF");
+ net_store_data(&packet2,(ulong) *(my_bool*) value ? "ON" : "OFF");
break;
case SHOW_INT_CONST:
case SHOW_INT:
- net_store_data(&packet2,(uint32) *(int*) variables[i].value);
- break;
- case SHOW_INT_OFFSET:
- offset= (ulong) variables[i].value;
- net_store_data(&packet2,
- (uint32) *(int*) (((char*) values) + offset));
+ net_store_data(&packet2,(uint32) *(int*) value);
break;
case SHOW_HAVE:
{
- SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) variables[i].value;
+ SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
net_store_data(&packet2, (tmp == SHOW_OPTION_NO ? "NO" :
tmp == SHOW_OPTION_YES ? "YES" :
"DISABLED"));
break;
}
case SHOW_CHAR:
- net_store_data(&packet2,convert, variables[i].value);
+ net_store_data(&packet2,convert, value);
break;
case SHOW_STARTTIME:
net_store_data(&packet2,(uint32) (thd->query_start() - start_time));
@@ -1232,11 +1225,11 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
net_store_data(&packet2,(uint32) cached_tables());
break;
case SHOW_CHAR_PTR:
- {
- char *value= *(char**) variables[i].value;
- net_store_data(&packet2,convert, value ? value : "");
- break;
- }
+ {
+ value= *(char**) value;
+ net_store_data(&packet2,convert, value ? value : "");
+ break;
+ }
#ifdef HAVE_OPENSSL
/* First group - functions relying on CTX */
case SHOW_SSL_CTX_SESS_ACCEPT:
@@ -1393,6 +1386,10 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
break;
#endif /* HAVE_OPENSSL */
+ case SHOW_UNDEF: // Show never happen
+ case SHOW_SYS:
+ net_store_data(&packet2, ""); // Safety
+ break;
}
if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length()))
goto err; /* purecov: inspected */
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9695f273327..296db748c03 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -71,8 +71,8 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
error=mysql_rm_table_part2(thd,tables,if_exists,0);
err:
- VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
pthread_mutex_unlock(&LOCK_open);
+ VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
@@ -85,6 +85,27 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
DBUG_RETURN(0);
}
+int mysql_rm_table_part2_with_lock(THD *thd,
+ TABLE_LIST *tables, bool if_exists,
+ bool dont_log_query)
+{
+ int error;
+ thd->mysys_var->current_mutex= &LOCK_open;
+ thd->mysys_var->current_cond= &COND_refresh;
+ VOID(pthread_mutex_lock(&LOCK_open));
+
+ error=mysql_rm_table_part2(thd,tables, if_exists, dont_log_query);
+
+ pthread_mutex_unlock(&LOCK_open);
+ VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
+
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex= 0;
+ thd->mysys_var->current_cond= 0;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+ return error;
+}
+
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
bool dont_log_query)
@@ -115,15 +136,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
}
drop_locked_tables(thd,db,table->real_name);
if (thd->killed)
- {
- VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
- VOID(pthread_mutex_unlock(&LOCK_open));
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
DBUG_RETURN(-1);
- }
+
/* remove form file and isam files */
(void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table->real_name,
reg_ext);
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 983ff44dc73..9529b02fecd 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -61,10 +61,11 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
*/
lex_sl= sl;
order= (ORDER *) lex_sl->order_list.first;
- found_rows_for_union = lex->select_lex.options & OPTION_FOUND_ROWS && !describe && sl->select_limit;
+ found_rows_for_union = (lex->select_lex.options & OPTION_FOUND_ROWS &&
+ !describe && sl->select_limit);
if (found_rows_for_union)
lex->select_lex.options ^= OPTION_FOUND_ROWS;
-// This is done to eliminate unnecessary slowing down of the first query
+ // This is done to eliminate unnecessary slowing down of the first query
if (!order || !describe)
last_sl->next=0; // Remove this extra element
}
@@ -195,7 +196,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
else
{
thd->offset_limit= 0;
- thd->select_limit= thd->default_select_limit;
+ thd->select_limit= thd->variables.select_limit;
}
if (describe)
thd->select_limit= HA_POS_ERROR; // no limit
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 7fcd25e2acf..fda07721da8 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -117,7 +117,7 @@ int mysql_update(THD *thd,
table->used_keys=0;
select=make_select(table,0,0,conds,&error);
if (error ||
- (select && select->check_quick(test(thd->options & SQL_SAFE_UPDATES),
+ (select && select->check_quick(test(thd->options & OPTION_SAFE_UPDATES),
limit)) ||
!limit)
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6a4f13940a7..c9bae82ff04 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -53,19 +53,20 @@ inline Item *or_or_concat(Item* A, Item* B)
Item *item;
List<Item> *item_list;
List<String> *string_list;
+ String *string;
+ key_part_spec *key_part;
+ TABLE_LIST *table_list;
+ udf_func *udf;
+ LEX_USER *lex_user;
+ sys_var *variable;
Key::Keytype key_type;
enum db_type db_type;
enum row_type row_type;
enum ha_rkey_function ha_rkey_mode;
enum enum_tx_isolation tx_isolation;
enum Item_cast cast_type;
- String *string;
- key_part_spec *key_part;
- TABLE_LIST *table_list;
- udf_func *udf;
- interval_type interval;
- LEX_USER *lex_user;
enum Item_udftype udf_type;
+ interval_type interval;
}
%{
@@ -150,7 +151,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token AS
%token ASC
%token AUTO_INC
-%token AUTOCOMMIT
%token AVG_ROW_LENGTH
%token BACKUP_SYM
%token BERKELEY_DB_SYM
@@ -177,7 +177,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DEFAULT
%token DELAYED_SYM
%token DELAY_KEY_WRITE_SYM
-%token DEMAND_SYM
%token DESC
%token DESCRIBE
%token DES_KEY_FILE
@@ -263,7 +262,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token NO_SYM
%token NULL_SYM
%token NUM
-%token OFF
%token ON
%token OPEN_SYM
%token OPTION
@@ -417,7 +415,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token HOUR_SYM
%token IDENTIFIED_SYM
%token IF
-%token INSERT_ID
%token INSERT_METHOD
%token INTERVAL_SYM
%token LAST_INSERT_ID
@@ -461,26 +458,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token END
%token THEN_SYM
-%token SQL_AUTO_IS_NULL
%token SQL_BIG_RESULT
-%token SQL_BIG_SELECTS
-%token SQL_BIG_TABLES
%token SQL_CACHE_SYM
%token SQL_CALC_FOUND_ROWS
-%token SQL_LOG_BIN
-%token SQL_LOG_OFF
-%token SQL_LOG_UPDATE
-%token SQL_LOW_PRIORITY_UPDATES
-%token SQL_MAX_JOIN_SIZE
%token SQL_NO_CACHE_SYM
-%token SQL_QUERY_CACHE_TYPE_SYM
-%token SQL_SAFE_UPDATES
-%token SQL_SELECT_LIMIT
%token SQL_SMALL_RESULT
-%token SQL_WARNINGS
%token SQL_BUFFER_RESULT
-%token SQL_QUOTE_SHOW_CREATE
-%token SQL_SLAVE_SKIP_COUNTER
%token ISSUER_SYM
%token SUBJECT_SYM
@@ -520,9 +503,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
text_string
%type <num>
- type int_type real_type order_dir opt_field_spec set_option lock_option
+ type int_type real_type order_dir opt_field_spec lock_option
udf_type if_exists opt_local opt_table_options table_options
- table_option opt_if_not_exists opt_var_type
+ table_option opt_if_not_exists opt_var_type opt_var_ident_type
%type <ulong_num>
ULONG_NUM raid_types merge_insert_types
@@ -534,7 +517,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
literal text_literal insert_ident order_ident
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr
- using_list
+ using_list expr_or_default
%type <item_list>
expr_list udf_expr_list when_list ident_list ident_list_arg
@@ -561,7 +544,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <row_type> row_types
-%type <tx_isolation> tx_isolation isolation_types
+%type <tx_isolation> isolation_types
%type <ha_rkey_mode> handler_rkey_mode
@@ -573,6 +556,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <lex_user> user grant_user
+%type <variable> internal_variable_name
+
%type <NONE>
query verb_clause create change select do drop insert replace insert2
insert_values update delete truncate rename
@@ -675,8 +660,7 @@ change:
master_defs:
master_def
- |
- master_defs ',' master_def;
+ | master_defs ',' master_def;
master_def:
MASTER_HOST_SYM EQ TEXT_STRING
@@ -742,7 +726,7 @@ create:
lex->change=NullS;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
lex->create_info.options=$2 | $4;
- lex->create_info.db_type= default_table_type;
+ lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type;
}
create2
@@ -1295,19 +1279,15 @@ slave:
lex->type = 0;
};
-slave_thread_opts: slave_thread_opt
- | slave_thread_opts ',' slave_thread_opt;
+slave_thread_opts:
+ slave_thread_opt
+ | slave_thread_opts ',' slave_thread_opt;
slave_thread_opt:
- /*empty*/ {}
- | SQL_THREAD
- {
- Lex->slave_thd_opt|=SLAVE_SQL;
- }
- | IO_THREAD
- {
- Lex->slave_thd_opt|=SLAVE_IO;
- };
+ /*empty*/ {}
+ | SQL_THREAD { Lex->slave_thd_opt|=SLAVE_SQL; }
+ | IO_THREAD { Lex->slave_thd_opt|=SLAVE_IO; }
+ ;
restore:
RESTORE_SYM table_or_tables
@@ -1318,6 +1298,7 @@ restore:
{
Lex->backup_dir = $6.str;
};
+
backup:
BACKUP_SYM table_or_tables
{
@@ -1642,16 +1623,19 @@ simple_expr:
simple_ident
| literal
| '@' ident_or_text SET_VAR expr
- { $$= new Item_func_set_user_var($2,$4);
+ {
+ $$= new Item_func_set_user_var($2,$4);
current_thd->safe_to_cache_query=0;
}
| '@' ident_or_text
- { $$= new Item_func_get_user_var($2);
+ {
+ $$= new Item_func_get_user_var($2);
current_thd->safe_to_cache_query=0;
}
- | '@' '@' ident_or_text
- { if (!($$= get_system_var($3))) YYABORT;
- current_thd->safe_to_cache_query=0;
+ | '@' '@' opt_var_ident_type ident_or_text
+ {
+ if (!($$= get_system_var((enum_var_type) $3, $4)))
+ YYABORT;
}
| sum_expr
| '-' expr %prec NEG { $$= new Item_func_neg($2); }
@@ -2203,12 +2187,13 @@ limit_clause:
{
SELECT_LEX *sel=Select;
sel->select_limit= $2;
- sel->offset_limit=0L;
+ sel->offset_limit= 0L;
}
| LIMIT ULONG_NUM ',' ULONG_NUM
{
SELECT_LEX *sel=Select;
- sel->select_limit= $4; sel->offset_limit=$2;
+ sel->select_limit= $4;
+ sel->offset_limit= $2;
};
delete_limit_clause:
@@ -2431,7 +2416,13 @@ ident_eq_value:
};
equal: EQ {}
- | SET_VAR {};
+ | SET_VAR {}
+ ;
+
+opt_equal:
+ /* empty */ {}
+ | equal {}
+ ;
no_braces:
'('
@@ -2615,7 +2606,7 @@ show_param:
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_SHOW_BINLOG_EVENTS;
- lex->select->select_limit= lex->thd->default_select_limit;
+ lex->select->select_limit= lex->thd->variables.select_limit;
lex->select->offset_limit= 0L;
} limit_clause
| keys_or_index FROM table_ident opt_db
@@ -2634,10 +2625,7 @@ show_param:
{
THD *thd= current_thd;
thd->lex.sql_command= SQLCOM_SHOW_VARIABLES;
- if ($1)
- thd->lex.variable_values= &thd->variables;
- else
- thd->lex.variable_values= &global_system_variables;
+ thd->lex.option_type= (enum_var_type) $1;
}
| LOGS_SYM
{ Lex->sql_command= SQLCOM_SHOW_LOGS; }
@@ -2675,12 +2663,6 @@ opt_full:
/* empty */ { Lex->verbose=0; }
| FULL { Lex->verbose=1; };
-opt_var_type:
- /* empty */ { $$=1; /* local variable */ }
- | LOCAL_SYM { $$=1; }
- | GLOBAL_SYM { $$=0; }
- ;
-
from_or_in:
FROM
| IN_SYM;
@@ -3001,7 +2983,6 @@ keyword:
| AFTER_SYM {}
| AGAINST {}
| AGGREGATE_SYM {}
- | AUTOCOMMIT {}
| AUTO_INC {}
| AVG_ROW_LENGTH {}
| AVG_SYM {}
@@ -3029,7 +3010,6 @@ keyword:
| DATE_SYM {}
| DAY_SYM {}
| DELAY_KEY_WRITE_SYM {}
- | DEMAND_SYM {}
| DES_KEY_FILE {}
| DIRECTORY_SYM {}
| DO_SYM {}
@@ -3062,7 +3042,7 @@ keyword:
| ISSUER_SYM {}
| INNOBASE_SYM {}
| INSERT_METHOD {}
- | IO_THREAD {}
+ | IO_THREAD {}
| LAST_SYM {}
| LEVEL_SYM {}
| LOCAL_SYM {}
@@ -3093,7 +3073,6 @@ keyword:
| NEXT_SYM {}
| NEW_SYM {}
| NO_SYM {}
- | OFF {}
| OPEN_SYM {}
| PACK_KEYS_SYM {}
| PASSWORD {}
@@ -3128,8 +3107,8 @@ keyword:
| SHUTDOWN {}
| SLAVE {}
| SQL_CACHE_SYM {}
+ | SQL_BUFFER_RESULT {}
| SQL_NO_CACHE_SYM {}
- | SQL_QUERY_CACHE_TYPE_SYM {}
| SQL_THREAD {}
| START_SYM {}
| STATUS_SYM {}
@@ -3158,11 +3137,8 @@ set:
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SET_OPTION;
- lex->select->options=lex->thd->options;
- lex->select->select_limit=lex->thd->default_select_limit;
- lex->tx_isolation=lex->thd->tx_isolation;
- lex->option_type=0;
- lex->option_list.empty();
+ lex->option_type=OPT_DEFAULT;
+ lex->var_list.empty();
}
option_value_list;
@@ -3171,142 +3147,89 @@ opt_option:
| OPTION {};
option_value_list:
- option_value
- | GLOBAL_SYM { Lex->option_type=1; } option_value
- | LOCAL_SYM { Lex->option_type=0; } option_value
- | option_value_list ',' option_value;
+ option_type option_value
+ | option_value_list ',' option_type option_value;
+
+option_type:
+ /* empty */ {}
+ | GLOBAL_SYM { Lex->option_type= OPT_GLOBAL; }
+ | LOCAL_SYM { Lex->option_type= OPT_SESSION; }
+ | SESSION_SYM { Lex->option_type= OPT_SESSION; }
+ ;
+
+opt_var_type:
+ /* empty */ { $$=OPT_SESSION; }
+ | LOCAL_SYM { $$=OPT_SESSION; }
+ | SESSION_SYM { $$=OPT_SESSION; }
+ | GLOBAL_SYM { $$=OPT_GLOBAL; }
+ ;
+
+opt_var_ident_type:
+ /* empty */ { $$=OPT_DEFAULT; }
+ | LOCAL_SYM '.' { $$=OPT_SESSION; }
+ | SESSION_SYM '.' { $$=OPT_SESSION; }
+ | GLOBAL_SYM '.' { $$=OPT_GLOBAL; }
+ ;
option_value:
- set_option equal NUM
- {
- SELECT_LEX *sel=Select;
- if (atoi($3.str) == 0)
- sel->options&= ~$1;
- else
- sel->options|= $1;
- }
- | set_isolation
- | AUTOCOMMIT equal NUM
- {
- SELECT_LEX *sel=Select;
- if (atoi($3.str) != 0) /* Test NOT AUTOCOMMIT */
- sel->options&= ~(OPTION_NOT_AUTO_COMMIT);
- else
- sel->options|= OPTION_NOT_AUTO_COMMIT;
- }
- | SQL_SELECT_LIMIT equal ULONG_NUM
- {
- Select->select_limit= $3;
- }
- | SQL_SELECT_LIMIT equal DEFAULT
- {
- Select->select_limit= HA_POS_ERROR;
- }
- | SQL_MAX_JOIN_SIZE equal ULONG_NUM
- {
- LEX *lex=Lex;
- lex->thd->max_join_size= $3;
- lex->select->options&= ~OPTION_BIG_SELECTS;
- }
- | SQL_MAX_JOIN_SIZE equal DEFAULT
- {
- current_thd->max_join_size= HA_POS_ERROR;
- }
- | TIMESTAMP equal ULONG_NUM
- {
- current_thd->set_time((time_t) $3);
- }
- | TIMESTAMP equal DEFAULT
- {
- current_thd->user_time=0;
- }
- | LAST_INSERT_ID equal ulonglong_num
- {
- current_thd->insert_id($3);
- }
- | INSERT_ID equal ulonglong_num
+ '@' ident_or_text equal expr
{
- current_thd->next_insert_id=$3;
+ Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4)));
}
- | CHAR_SYM SET IDENT
- {
- CONVERT *tmp;
- if (!(tmp=get_convert_set($3.str)))
+ | internal_variable_name equal expr_or_default
{
- net_printf(&current_thd->net,ER_UNKNOWN_CHARACTER_SET,$3);
- YYABORT;
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var(lex->option_type, $1, $3));
}
- current_thd->convert_set=tmp;
- }
- | CHAR_SYM SET DEFAULT
+ | '@' '@' opt_var_ident_type internal_variable_name equal expr_or_default
+ {
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var((enum_var_type) $3, $4, $6));
+ }
+ | TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
+ {
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var(lex->option_type,
+ find_sys_var("transaction_isolation_num"),
+ new Item_int((int) $4)));
+ }
+ | CHAR_SYM SET opt_equal expr_or_default
{
- current_thd->convert_set=0;
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var(lex->option_type,
+ find_sys_var("convert_character_set"),
+ $4));
}
| PASSWORD equal text_or_password
- {
- if (change_password(current_thd,current_thd->host,
- current_thd->priv_user,$3))
- YYABORT;
- }
- | PASSWORD FOR_SYM user equal text_or_password
- {
- if (change_password(current_thd,
- $3->host.str ? $3->host.str : current_thd->host,
- $3->user.str,$5))
- YYABORT;
- }
- | SQL_QUERY_CACHE_TYPE_SYM equal query_cache_type
- | '@' ident_or_text equal expr
- {
- Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
- if (item->fix_fields(current_thd,0) || item->update())
- {
- send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY);
- YYABORT;
- }
- }
- | SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM
- {
- LOCK_ACTIVE_MI;
- pthread_mutex_lock(&active_mi->rli.run_lock);
- if (active_mi->rli.slave_running)
- send_error(&current_thd->net, ER_SLAVE_MUST_STOP);
- else
- {
- pthread_mutex_lock(&active_mi->rli.data_lock);
- active_mi->rli.slave_skip_counter = $3;
- pthread_mutex_unlock(&active_mi->rli.data_lock);
- }
- pthread_mutex_unlock(&active_mi->rli.run_lock);
- UNLOCK_ACTIVE_MI;
- }
- | ident equal DEFAULT
{
- LEX *lex=Lex;
- lex->option_list.push_back(new Set_option(lex->option_type,
- $1.str,$1.length,
- (Item*) 0));
- }
- | ident equal expr
+ THD *thd=current_thd;
+ LEX_USER *user;
+ if (!(user=(LEX_USER*) sql_alloc(sizeof(LEX_USER))))
+ YYABORT;
+ user->host.str=0;
+ user->user.str=thd->priv_user;
+ thd->lex.var_list.push_back(new set_var_password(user, $3));
+ }
+ | PASSWORD FOR_SYM user equal text_or_password
{
- THD *thd=current_thd;
- Item *item= $3;
- if (item->fix_fields(current_thd,0))
- {
- send_error(&thd->net, ER_SET_CONSTANTS_ONLY);
- YYABORT;
- }
- thd->lex.option_list.
- push_back(new Set_option(thd->lex.option_type,
- $1.str,$1.length,
- item));
- };
+ Lex->var_list.push_back(new set_var_password($3,$5));
+ }
-query_cache_type:
- NUM { current_thd->query_cache_type = set_zone(atoi($1.str),0,3); }
- | OFF { current_thd->query_cache_type = 0; }
- | ON { current_thd->query_cache_type = 1; }
- | DEMAND_SYM { current_thd->query_cache_type = 2; };
+internal_variable_name:
+ ident
+ {
+ sys_var *tmp=find_sys_var($1.str, $1.length);
+ if (!tmp)
+ YYABORT;
+ $$=tmp;
+ }
+
+isolation_types:
+ READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
+ | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; }
+ | REPEATABLE_SYM READ_SYM { $$= ISO_REPEATABLE_READ; }
+ | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; }
+ ;
text_or_password:
TEXT_STRING { $$=$1.str;}
@@ -3322,54 +3245,13 @@ text_or_password:
}
};
-set_option:
- SQL_BIG_TABLES { $$= OPTION_BIG_TABLES; }
- | SQL_BIG_SELECTS { $$= OPTION_BIG_SELECTS; }
- | SQL_LOG_OFF { $$= OPTION_LOG_OFF; }
- | SQL_LOG_UPDATE
- {
- $$= (opt_sql_bin_update)?
- OPTION_UPDATE_LOG|OPTION_BIN_LOG:
- OPTION_UPDATE_LOG ;
- }
- | SQL_LOG_BIN
- {
- $$= (opt_sql_bin_update)?
- OPTION_UPDATE_LOG|OPTION_BIN_LOG:
- OPTION_BIN_LOG ;
- }
- | SQL_WARNINGS { $$= OPTION_WARNINGS; }
- | SQL_LOW_PRIORITY_UPDATES { $$= OPTION_LOW_PRIORITY_UPDATES; }
- | SQL_AUTO_IS_NULL { $$= OPTION_AUTO_IS_NULL; }
- | SQL_SAFE_UPDATES { $$= OPTION_SAFE_UPDATES; }
- | SQL_BUFFER_RESULT { $$= OPTION_BUFFER_RESULT; }
- | SQL_QUOTE_SHOW_CREATE { $$= OPTION_QUOTE_SHOW_CREATE; };
-
-
-set_isolation:
- GLOBAL_SYM tx_isolation
- {
- if (check_global_access(current_thd, SUPER_ACL))
- YYABORT;
- default_tx_isolation= $2;
- default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
- }
- | SESSION_SYM tx_isolation
- {
- LEX *lex=Lex;
- lex->thd->session_tx_isolation= lex->tx_isolation= $2;
- }
- | tx_isolation
- { Lex->tx_isolation= $1; };
-tx_isolation:
- TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types { $$=$4; };
+expr_or_default:
+ expr { $$=$1; }
+ | DEFAULT { $$=0; }
+ | ON { $$=new Item_string("ON",2); }
+ ;
-isolation_types:
- READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
- | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; }
- | REPEATABLE_SYM READ_SYM { $$= ISO_REPEATABLE_READ; }
- | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; };
/* Lock function */
@@ -3756,12 +3638,10 @@ optional_order_or_limit:
YYABORT;
mysql_init_select(lex);
lex->select->linkage=NOT_A_SELECT;
- lex->select->select_limit=lex->thd->default_select_limit;
+ lex->select->select_limit=lex->thd->variables.select_limit;
}
opt_order_clause limit_clause;
union_option:
/* empty */ {}
| ALL {Lex->union_option=1;};
-
-
diff --git a/sql/structs.h b/sql/structs.h
index fde618caf4f..c7a1daee513 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -124,34 +124,37 @@ typedef struct {
} INTERVAL;
-enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL,
- SHOW_MY_BOOL,SHOW_OPENTABLES,SHOW_STARTTIME,SHOW_QUESTION,
- SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE,
- SHOW_LONG_OFFSET, SHOW_INT_OFFSET, SHOW_MY_BOOL_OFFSET
+enum SHOW_TYPE
+{
+ SHOW_UNDEF,
+ SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_BOOL,
+ SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUESTION,
+ SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS,
#ifdef HAVE_OPENSSL
- ,SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD
- ,SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE
- ,SHOW_SSL_CTX_SESS_CB_HITS, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE
- ,SHOW_SSL_CTX_SESS_NUMBER, SHOW_SSL_SESSION_REUSED
- ,SHOW_SSL_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER
- ,SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE
- ,SHOW_SSL_CTX_GET_VERIFY_MODE, SHOW_SSL_GET_VERIFY_DEPTH
- ,SHOW_SSL_CTX_GET_VERIFY_DEPTH, SHOW_SSL_CTX_SESS_CONNECT
- ,SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE, SHOW_SSL_CTX_SESS_CONNECT_GOOD
- ,SHOW_SSL_CTX_SESS_HITS, SHOW_SSL_CTX_SESS_MISSES
- ,SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL
- ,SHOW_SSL_GET_CIPHER_LIST
+ SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD,
+ SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE,
+ SHOW_SSL_CTX_SESS_CB_HITS, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE,
+ SHOW_SSL_CTX_SESS_NUMBER, SHOW_SSL_SESSION_REUSED,
+ SHOW_SSL_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER,
+ SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE,
+ SHOW_SSL_CTX_GET_VERIFY_MODE, SHOW_SSL_GET_VERIFY_DEPTH,
+ SHOW_SSL_CTX_GET_VERIFY_DEPTH, SHOW_SSL_CTX_SESS_CONNECT,
+ SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE, SHOW_SSL_CTX_SESS_CONNECT_GOOD,
+ SHOW_SSL_CTX_SESS_HITS, SHOW_SSL_CTX_SESS_MISSES,
+ SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL,
+ SHOW_SSL_GET_CIPHER_LIST,
#endif /* HAVE_OPENSSL */
- ,SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING
+ SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING
};
enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
+typedef int *(*update_var)(THD *, struct show_var_st *);
-struct show_var_st {
+typedef struct show_var_st {
const char *name;
char *value;
SHOW_TYPE type;
-};
+} SHOW_VAR;
typedef struct lex_string {
char *str;
diff --git a/sql/table.cc b/sql/table.cc
index 2eb924caaf2..2a284d4c027 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -357,17 +357,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
}
}
if (reg_field->unireg_check == Field::NEXT_NUMBER)
- {
- if ((int) (outparam->next_number_index= (uint)
- find_ref_key(outparam,reg_field,
- &outparam->next_number_key_offset)) < 0)
- reg_field->unireg_check=Field::NONE; /* purecov: inspected */
- else
- {
- outparam->found_next_number_field=reg_field;
- reg_field->flags|=AUTO_INCREMENT_FLAG;
- }
- }
+ outparam->found_next_number_field= reg_field;
if (outparam->timestamp_field == reg_field)
outparam->timestamp_field_offset=i;
if (use_hash)
@@ -532,6 +522,20 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
bfill(outparam->null_flags+outparam->rec_buff_length*2,null_length,255);
}
+
+ if ((reg_field=outparam->found_next_number_field))
+ {
+ if ((int) (outparam->next_number_index= (uint)
+ find_ref_key(outparam,reg_field,
+ &outparam->next_number_key_offset)) < 0)
+ {
+ reg_field->unireg_check=Field::NONE; /* purecov: inspected */
+ outparam->found_next_number_field=0;
+ }
+ else
+ reg_field->flags|=AUTO_INCREMENT_FLAG;
+ }
+
if (outparam->blob_fields)
{
Field **ptr;
diff --git a/sql/uniques.cc b/sql/uniques.cc
index 3a26f610dc5..60905567ba0 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -22,7 +22,7 @@
The basic idea is as follows:
Store first all strings in a binary tree, ignoring duplicates.
- When the three uses more memory than 'max_heap_table_size',
+ When the tree uses more memory than 'max_heap_table_size',
write the tree (in sorted order) out to disk and start with a new tree.
When all data has been generated, merge the trees (removing any found
duplicates).
diff --git a/sql/unireg.h b/sql/unireg.h
index e8fdd5dd5dd..2cfa709bbdc 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -46,6 +46,7 @@
#define MAX_DBKEY_LENGTH (FN_LEN*2+6) /* extra 4 bytes for slave tmp
* tables */
#define MAX_FIELD_NAME 34 /* Max colum name length +2 */
+#define MAX_SYS_VAR_LENGTH 32
#define MAX_KEY 32 /* Max used keys */
#define MAX_REF_PARTS 16 /* Max parts used as ref */
#define MAX_KEY_LENGTH 500 /* max possible key */