diff options
author | igor@rurik.mysql.com <> | 2004-02-19 01:09:54 -0800 |
---|---|---|
committer | igor@rurik.mysql.com <> | 2004-02-19 01:09:54 -0800 |
commit | f18e0068ba81c909b28ed4b66ee6d84f7e4ad932 (patch) | |
tree | aa627335f475f099e0d352b39af4e24d6e1ac189 | |
parent | 09fa16424a9d5e35b1b7abbc912b0bdfc105f15f (diff) | |
parent | 1be033f62cc7decdc0867ad44aaebd87b3f74884 (diff) | |
download | mariadb-git-f18e0068ba81c909b28ed4b66ee6d84f7e4ad932.tar.gz |
Manual merge
268 files changed, 6449 insertions, 2960 deletions
diff --git a/BUILD/compile-pentium-debug-max-no-embedded b/BUILD/compile-pentium-debug-max-no-embedded new file mode 100755 index 00000000000..4554e38fdc1 --- /dev/null +++ b/BUILD/compile-pentium-debug-max-no-embedded @@ -0,0 +1,13 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +extra_flags="$pentium_cflags $debug_cflags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$pentium_configs $debug_configs" + +extra_configs="$extra_configs --with-berkeley-db --with-innodb --without-isam --with-openssl --with-raid" + +. "$path/FINISH.sh" diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index a28e7dc78f0..6e53347b0a6 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -16,6 +16,7 @@ arjen@george.bitbike.com bar@bar.intranet.mysql.r18.ru bar@bar.mysql.r18.ru bar@bar.udmsearch.izhnet.ru +bar@deer.(none) bar@gw.udmsearch.izhnet.ru bell@laptop.sanja.is.com.ua bell@sanja.is.com.ua @@ -54,6 +55,7 @@ jani@linux.local jani@rhols221.adsl.netsonic.fi jani@rhols221.arenanet.fi jani@ua126d19.elisa.omakaista.fi +jani@ua141d10.elisa.omakaista.fi jani@ua167d18.elisa.omakaista.fi jcole@abel.spaceapes.com jcole@main.burghcom.com diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt index c1b91d2c2c5..24a47aa2c38 100644 --- a/Docs/sp-imp-spec.txt +++ b/Docs/sp-imp-spec.txt @@ -135,7 +135,7 @@ while x > 0 do set x = x-1; insert into db.tab values (x, s); - end while + end while; end would generate the following structures: diff --git a/Docs/sp-implemented.txt b/Docs/sp-implemented.txt index e64b2476c31..6f2cf49b3b0 100644 --- a/Docs/sp-implemented.txt +++ b/Docs/sp-implemented.txt @@ -1,18 +1,4 @@ -Stored Procedures implemented 2003-12-10: - - -Summary of Not Yet Implemented: - - - SQL statements using table (like SELECT, INSERT, UPDATE etc) - in FUNCTIONs - - External languages - - Access control - - Routine characteristics (mostly used for external languages) - - SQL-99 COMMIT (related to BEGIN/END) - - FOR-loops - - CASCADE/RESTRICT for ALTER and DROP - - ALTER/DROP METHOD (as it implies User Defined Types) - - SIGNAL and RESIGNAL, and UNDO handlers +Stored Procedures implemented 2004-01-29: Summary of what's implemented: @@ -26,7 +12,19 @@ Summary of what's implemented: - Prepared SP caching - CONDITIONs and HANDLERs - Simple read-only CURSORs. - - SHOW DECLARE PROCEDURE/FUNCTION and SHOW PROCEDURE/FUNCTION STATUS + - SHOW CREATE PROCEDURE/FUNCTION and SHOW PROCEDURE/FUNCTION STATUS + + +Summary of Not Yet Implemented: + + - SQL statements using tables (like SELECT, INSERT, UPDATE etc) in FUNCTIONs + - External languages + - Access control + - SQL-99 COMMIT (related to BEGIN/END) + - FOR-loops + - CASCADE/RESTRICT for ALTER and DROP + - ALTER/DROP METHOD (as it implies User Defined Types) + - SIGNAL and RESIGNAL, and UNDO handlers List of what's implemented: @@ -50,13 +48,12 @@ List of what's implemented: CASCADE/RESTRICT is not implemented. - CALL name (args) - OUT and INOUT parameters are only supported for local variables, and - therefore only useful when calling such procedures from within another - procedure. - Note: For the time being, when a procedure with OUT/INOUT parameter is - called, the out values are silently discarded. In the future, this - will either generate an error message, or it might even work to - call all procedures from the top-level. + OUT and INOUT parameters are also works for user variables ("global" + variables) - i.e., if a procedure is defined as: + CREATE PROCEDURE foo(OUT p INT) ...; + a call like: + CALL foo(@x); + will set @x to the output value. - Function/Procedure body: - BEGIN/END @@ -81,17 +78,17 @@ List of what's implemented: is implemented. (Note: This is not SQL-99 feature, but common in other databases.) - A FUNCTION can have flow control contructs, but must not contain - an SQL query, like SELECT, INSERT, UPDATE, etc. The reason is that it's - hard to allow this is that a FUNCTION is executed as part of another - query (unlike a PROCEDURE, which is called as a statement). The table - locking scheme used makes it difficult to allow "subqueries" during - FUNCTION invokation. + an SQL query/statement, like SELECT, INSERT, UPDATE, etc. The reason + is that it's hard to allow this is that a FUNCTION is executed as part + of another query (unlike a PROCEDURE, which is called as a statement). + The table locking scheme used makes it difficult to allow "subqueries" + during FUNCTION invokation. - SPs are cached, but with a separate cache for each thread (THD). There are still quite a few non-reentrant constructs in the lexical context which makes sharing prepared SPs impossible. And, even when this is resolved, it's not necessarily the case that it will be faster than a cache per thread. A global cache requires locks, which might - become a buttleneck. (It would save memory though.) + become a bottleneck. (It would save memory though.) - CONDITIONs and HANDLERs are implemented, but not the SIGNAL and RESIGNAL statements. (It's unclear if these can be implemented.) The semantics of CONDITIONs is expanded to allow catching MySQL error @@ -102,9 +99,13 @@ List of what's implemented: (NEXT, PRIOR, etc). Cursors are ASENSITIVE, READ-ONLY, non-SCROLLing. (The additional syntax will be added for completeness, but for the most part unsupported with the current underlying cursor mechanism.) + N.B. The current implementation is temporary and only works within a + stored procedure, and may not perform well for very large result sets. + A "real" cursor implementation is under development; this will replace + the current one when it's finished. - SHOW procedures and functions - SHOW DECLARE PROCEDURE|FUNCTION <name> + SHOW CREATE PROCEDURE|FUNCTION <name> returns the definition of a routine. SHOW PROCEDURE|FUNCTION STATUS [LIKE <pattern>] returns characteristics of routines, like the name, type, creator, diff --git a/VC++Files/libmysqld/libmysqld.def b/VC++Files/libmysqld/libmysqld.def index c3f757b5f1a..37a6114a6d0 100644 --- a/VC++Files/libmysqld/libmysqld.def +++ b/VC++Files/libmysqld/libmysqld.def @@ -92,6 +92,28 @@ EXPORTS mysql_thread_safe mysql_use_result mysql_warning_count + mysql_prepare + mysql_execute + mysql_param_count + mysql_bind_param + mysql_bind_result + mysql_fetch + mysql_fetch_column + mysql_send_long_data + mysql_get_metadata + mysql_param_result + mysql_stmt_close + mysql_stmt_reset + mysql_stmt_free_result + mysql_stmt_errno + mysql_stmt_error + mysql_stmt_sqlstate + mysql_stmt_affected_rows + mysql_stmt_store_result + mysql_stmt_row_seek + mysql_stmt_row_tell + mysql_stmt_data_seek + mysql_stmt_num_rows net_buffer_length set_dynamic strcend diff --git a/client/client_priv.h b/client/client_priv.h index f6d766b7ef9..910de1f03e9 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -26,18 +26,21 @@ /* We have to define 'enum options' identical in all files to keep OS2 happy */ -enum options_client { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, - OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE, - OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS, - OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE, - OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES, - OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_AUTO_REHASH, - OPT_LINE_NUMBERS, OPT_COLUMN_NAMES, OPT_CONNECT_TIMEOUT, - OPT_MAX_ALLOWED_PACKET, OPT_NET_BUFFER_LENGTH, - OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL, - OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, - OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE, - OPT_DELETE_MASTER_LOGS, - OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL, - OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION, - OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH }; +enum options_client +{ + OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, + OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE, + OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS, + OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE, + OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES, + OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_AUTO_REHASH, + OPT_LINE_NUMBERS, OPT_COLUMN_NAMES, OPT_CONNECT_TIMEOUT, + OPT_MAX_ALLOWED_PACKET, OPT_NET_BUFFER_LENGTH, + OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL, + OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, + OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE, + OPT_DELETE_MASTER_LOGS, OPT_COMPACT, + OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL, + OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION, + OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH, +}; diff --git a/client/mysql.cc b/client/mysql.cc index 16923eaf149..b79dda51317 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -44,7 +44,7 @@ #include <locale.h> #endif -const char *VER= "14.3"; +const char *VER= "14.5"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -134,7 +134,8 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, vertical=0, line_numbers=1, column_names=1,opt_html=0, opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, - default_charset_used= 0, opt_secure_auth= 0; + default_charset_used= 0, opt_secure_auth= 0, + default_pager_set= 0; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static my_string opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; @@ -173,9 +174,7 @@ static CHARSET_INFO *charset_info= &my_charset_latin1; #include "sslopt-vars.h" -#ifndef DBUG_OFF const char *default_dbug_option="d:t:o,/tmp/mysql.trace"; -#endif void tee_fprintf(FILE *file, const char *fmt, ...); void tee_fputs(const char *s, FILE *file); @@ -227,11 +226,12 @@ typedef struct { } COMMANDS; static COMMANDS commands[] = { - { "help", 'h', com_help, 1, "Display this help." }, { "?", '?', com_help, 1, "Synonym for `help'." }, { "clear", 'c', com_clear, 0, "Clear command."}, { "connect",'r', com_connect,1, "Reconnect to the server. Optional arguments are db and host." }, + { "delimiter", 'd', com_delimiter, 1, + "Set query delimiter. " }, #ifdef USE_POPEN { "edit", 'e', com_edit, 0, "Edit command with $EDITOR."}, #endif @@ -239,6 +239,7 @@ static COMMANDS commands[] = { "Send command to mysql server, display result vertically."}, { "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."}, { "go", 'g', com_go, 0, "Send command to mysql server." }, + { "help", 'h', com_help, 1, "Display this help." }, #ifdef USE_POPEN { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." }, #endif @@ -261,8 +262,6 @@ static COMMANDS commands[] = { "Set outfile [to_outfile]. Append everything into given outfile." }, { "use", 'u', com_use, 1, "Use another database. Takes database name as argument." }, - { "delimiter", 'd', com_delimiter, 1, - "Set query delimiter. " }, /* Get bash-like expansion for some commands */ { "create table", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""}, @@ -331,8 +330,11 @@ int main(int argc,char *argv[]) strmov(pager, "stdout"); // the default, if --pager wasn't given { char *tmp=getenv("PAGER"); - if (tmp) - strmov(default_pager,tmp); + if (tmp && strlen(tmp)) + { + default_pager_set= 1; + strmov(default_pager, tmp); + } } if (!isatty(0) || !isatty(1)) { @@ -467,6 +469,8 @@ static struct my_option my_long_options[] = { {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, {"auto-rehash", OPT_AUTO_REHASH, "Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.", (gptr*) &rehash, (gptr*) &rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -484,8 +488,11 @@ static struct my_option my_long_options[] = {"compress", 'C', "Use compression in server/client protocol.", (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifndef DBUG_OFF - {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option, +#ifdef DBUG_OFF + {"debug", '#', "This is a non-debug version. Catch this and exit", + 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#else + {"debug", '#', "Output debug log", (gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif {"database", 'D', "Database to use.", (gptr*) ¤t_db, @@ -608,19 +615,27 @@ static struct my_option my_long_options[] = GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout, + {"connect_timeout", OPT_CONNECT_TIMEOUT, + "Number of seconds before connection timeout.", + (gptr*) &opt_connect_timeout, (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0, 0, 1}, - {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", + {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, + "Max packet length to send to, or receive from server", (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096, (longlong) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", + {"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, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"select_limit", OPT_SELECT_LIMIT, "", (gptr*) &select_limit, + {"select_limit", OPT_SELECT_LIMIT, + "Automatic limit for SELECT when using --safe-updates", + (gptr*) &select_limit, (gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0}, - {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size, + {"max_join_size", OPT_MAX_JOIN_SIZE, + "Automatic limit for rows in a join when using --safe-updates", + (gptr*) &max_join_size, (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1, 0}, {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it" @@ -689,11 +704,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), else { opt_nopager= 0; - if (argument) + if (argument && strlen(argument)) + { + default_pager_set= 1; strmov(pager, argument); - else + strmov(default_pager, pager); + } + else if (default_pager_set) strmov(pager, default_pager); - strmov(default_pager, pager); + else + opt_nopager= 1; } break; case OPT_NOPAGER: @@ -814,11 +834,14 @@ static int get_options(int argc, char **argv) strmov(default_pager, "stdout"); strmov(pager, "stdout"); opt_nopager= 1; + default_pager_set= 0; opt_outfile= 0; opt_reconnect= 0; connect_flag= 0; /* Not in interactive mode */ } - if (!(charset_info= get_charset_by_csname(default_charset, + + if (strcmp(default_charset, charset_info->csname) && + !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))) exit(1); if (argc > 1) @@ -1535,7 +1558,7 @@ static int com_server_help(String *buffer __attribute__((unused)), init_pager(); char last_char; - int num_name, num_cat; + int num_name= 0, num_cat= 0; LINT_INIT(num_name); LINT_INIT(num_cat); @@ -1577,8 +1600,8 @@ static int com_help(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { - reg1 int i; - char * help_arg= strchr(line,' '); + reg1 int i, j; + char * help_arg= strchr(line,' '), buff[32], *end; if (help_arg) return com_server_help(buffer,line,help_arg+1); @@ -1591,8 +1614,11 @@ com_help(String *buffer __attribute__((unused)), put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO); for (i = 0; commands[i].name; i++) { + end= strmov(buff, commands[i].name); + for (j= strlen(commands[i].name); j < 10; j++) + end= strmov(end, " "); if (commands[i].func) - tee_fprintf(stdout, "%s\t(\\%c)\t%s\n", commands[i].name, + tee_fprintf(stdout, "%s(\\%c) %s\n", buff, commands[i].cmd_char, commands[i].doc); } if (connected && mysql_get_server_version(&mysql) >= 40100) @@ -2160,12 +2186,17 @@ com_pager(String *buffer, char *line __attribute__((unused))) if (status.batch) return 0; - /* Skip space from file name */ - while (my_isspace(charset_info,*line)) + /* Skip spaces in front of the pager command */ + while (my_isspace(charset_info, *line)) line++; - if (!(param= strchr(line, ' '))) // if pager was not given, use the default + /* Skip the pager command */ + param= strchr(line, ' '); + /* Skip the spaces between the command and the argument */ + while (param && my_isspace(charset_info, *param)) + param++; + if (!param || !strlen(param)) // if pager was not given, use the default { - if (!default_pager[0]) + if (!default_pager_set) { tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n"); opt_nopager=1; @@ -2177,9 +2208,7 @@ com_pager(String *buffer, char *line __attribute__((unused))) } else { - while (my_isspace(charset_info,*param)) - param++; - end=strmake(pager_name, param, sizeof(pager_name)-1); + end= strmake(pager_name, param, sizeof(pager_name)-1); while (end > pager_name && (my_isspace(charset_info,end[-1]) || my_iscntrl(charset_info,end[-1]))) end--; @@ -2188,7 +2217,7 @@ com_pager(String *buffer, char *line __attribute__((unused))) strmov(default_pager, pager_name); } opt_nopager=0; - tee_fprintf(stdout, "PAGER set to %s\n", pager); + tee_fprintf(stdout, "PAGER set to '%s'\n", pager); return 0; } @@ -2199,6 +2228,7 @@ com_nopager(String *buffer __attribute__((unused)), { strmov(pager, "stdout"); opt_nopager=1; + PAGER= stdout; tee_fprintf(stdout, "PAGER set to stdout\n"); return 0; } @@ -2433,8 +2463,9 @@ com_delimiter(String *buffer __attribute__((unused)), char *line) static int com_use(String *buffer __attribute__((unused)), char *line) { - char *tmp; - char buff[256]; + char *tmp, buff[FN_REFLEN + 1]; + MYSQL_RES *res; + MYSQL_ROW row; bzero(buff, sizeof(buff)); strmov(buff, line); @@ -2444,6 +2475,31 @@ com_use(String *buffer __attribute__((unused)), char *line) put_info("USE must be followed by a database name", INFO_ERROR); return 0; } + + /* + We need to recheck the current database, because it may change + under our feet, for example if DROP DATABASE or RENAME DATABASE + (latter one not yet available by the time the comment was written) + */ + current_db= 0; // Let's reset current_db, assume it's gone + /* + We don't care about in case of an error below because current_db + was just set to 0. + */ + if (!mysql_query(&mysql, "SELECT DATABASE()") && + (res= mysql_use_result(&mysql))) + { + row= mysql_fetch_row(res); + if (row[0] && + (!current_db || cmp_database(charset_info, current_db, row[0]))) + { + my_free(current_db, MYF(MY_ALLOW_ZERO_PTR)); + current_db= my_strdup(row[0], MYF(MY_WME)); + } + (void) mysql_fetch_row(res); // Read eof + mysql_free_result(res); + } + if (!current_db || cmp_database(charset_info, current_db, tmp)) { if (one_database) @@ -2649,6 +2705,9 @@ com_status(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { const char *status; + char buff[22]; + ulonglong id; + tee_puts("--------------", stdout); usage(1); /* Print version */ if (connected) @@ -2694,6 +2753,9 @@ com_status(String *buffer __attribute__((unused)), tee_fprintf(stdout, "Server version:\t\t%s\n", mysql_get_server_info(&mysql)); tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql)); tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql)); + if ((id= mysql_insert_id(&mysql))) + tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff)); + tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->name); tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->name); diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 1768d948373..03ab45957d4 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -311,7 +311,8 @@ static int get_options(int *argc, char ***argv) } /* TODO: This variable is not yet used */ - if (!(charset_info= get_charset_by_csname(default_charset, + if (strcmp(default_charset, charset_info->csname) && + !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))) exit(1); if (*argc > 0 && opt_alldbs) diff --git a/client/mysqldump.c b/client/mysqldump.c index 018cd43ce87..345c7f0b945 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -37,7 +37,7 @@ ** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov */ -#define DUMP_VERSION "10.4" +#define DUMP_VERSION "10.5" #include <my_global.h> #include <my_sys.h> @@ -81,7 +81,7 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick= 1, extended_insert= 1, opt_alldbs=0,opt_create_db=0,opt_first_slave=0,opt_set_names=0, opt_autocommit=0,opt_master_data,opt_disable_keys=1,opt_xml=0, opt_delete_master_logs=0, tty_password=0, - opt_single_transaction=0, opt_comments= 0; + opt_single_transaction=0, opt_comments= 0, opt_compact= 0; static MYSQL mysql_connection,*sock=0; static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, @@ -107,7 +107,8 @@ static CHARSET_INFO *charset_info= &my_charset_latin1; const char *compatible_mode_names[]= { "MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2", - "SAPDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", + "MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", + "ANSI", NullS }; TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1, @@ -136,9 +137,13 @@ static struct my_option my_long_options[] = "Directory where character sets are.", (gptr*) &charsets_dir, (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"compatible", OPT_COMPATIBLE, - "Change the dump to be compatible with a given mode. By default tables are dumped without any restrictions. Legal modes are: mysql323, mysql40, postgresql, oracle, mssql, db2, sapdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option does a no operation on earlier server versions.", + "Change the dump to be compatible with a given mode. By default tables are dumped without any restrictions. Legal modes are: ansi, mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option does a no operation on earlier server versions.", (gptr*) &opt_compatible_mode_str, (gptr*) &opt_compatible_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"compact", OPT_COMPACT, + "Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys --skip-lock-tables", + (gptr*) &opt_compact, (gptr*) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, {"complete-insert", 'c', "Use complete insert statements.", (gptr*) &cFlag, (gptr*) &cFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"compress", 'C', "Use compression in server/client protocol.", @@ -239,7 +244,7 @@ static struct my_option my_long_options[] = {"quick", 'q', "Don't buffer query, dump directly to stdout.", (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"quote-names",'Q', "Quote table and column names with backticks (`).", - (gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + (gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"result-file", 'r', "Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).", @@ -346,15 +351,19 @@ static void write_header(FILE *sql_file, char *db_name) fputs("<?xml version=\"1.0\"?>\n", sql_file); fputs("<mysqldump>\n", sql_file); } - else if (opt_comments) + else if (!opt_compact) { - fprintf(sql_file, "-- MySQL dump %s\n--\n", DUMP_VERSION); - fprintf(sql_file, "-- Host: %s Database: %s\n", - current_host ? current_host : "localhost", db_name ? db_name : ""); - fputs("-- ------------------------------------------------------\n", - sql_file); - fprintf(sql_file, "-- Server version\t%s\n", - mysql_get_server_info(&mysql_connection)); + if (opt_comments) + { + fprintf(sql_file, "-- MySQL dump %s\n--\n", DUMP_VERSION); + fprintf(sql_file, "-- Host: %s Database: %s\n", + current_host ? current_host : "localhost", db_name ? db_name : + ""); + fputs("-- ------------------------------------------------------\n", + sql_file); + fprintf(sql_file, "-- Server version\t%s\n", + mysql_get_server_info(&mysql_connection)); + } if (!opt_set_names) fprintf(sql_file,"\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=%s */;\n",default_charset); fprintf(md_result_file,"\ @@ -370,17 +379,18 @@ static void write_header(FILE *sql_file, char *db_name) static void write_footer(FILE *sql_file) { if (opt_xml) - fputs("</mysqldump>", sql_file); - else + fputs("</mysqldump>\n", sql_file); + else if (!opt_compact) { fprintf(md_result_file,"\n\ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;\n\ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n\ -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n\ -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n\ -"); +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n"); + if (!opt_set_names) + fprintf(md_result_file, + "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"); + fputs("\n", sql_file); } - fputs("\n", sql_file); } /* write_footer */ @@ -447,6 +457,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), extended_insert= opt_drop= opt_lock= quick= create_options= opt_disable_keys= lock_tables= 0; break; + case (int) OPT_COMPACT: + if (opt_compact) + { + opt_comments= opt_drop= opt_disable_keys= opt_lock= 0; + opt_set_names= 1; + } case (int) OPT_TABLES: opt_databases=0; break; @@ -520,7 +536,8 @@ static int get_options(int *argc, char ***argv) my_progname); return(1); } - if (!(charset_info= get_charset_by_csname(default_charset, + if (strcmp(default_charset, charset_info->csname) && + !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))) exit(1); if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs)) @@ -648,7 +665,7 @@ static char *quote_name(const char *name, char *buff, my_bool force) while (*name) { if (*name == QUOTE_CHAR) - *to= QUOTE_CHAR; + *to++= QUOTE_CHAR; *to++= *name++; } to[0]=QUOTE_CHAR; @@ -830,7 +847,7 @@ static uint getTableStructure(char *table, char* db) char *end; uint i; - sprintf(buff, "/*!41000 SET @@sql_mode=\""); + sprintf(buff, "/*!40100 SET @@sql_mode=\""); end= strend(buff); for (i= 0; opt_compatible_mode; opt_compatible_mode>>= 1, i++) { @@ -1269,7 +1286,7 @@ static void dumpTable(uint numFields, char *table) fprintf(md_result_file,"-- WHERE: %s\n",where); strxmov(strend(query), " WHERE ",where,NullS); } - if (!opt_xml) + if (!opt_xml && !opt_compact) fputs("\n", md_result_file); if (mysql_query(sock, query)) { @@ -1646,7 +1663,7 @@ static int dump_all_tables_in_db(char *database) if (opt_xml) fputs("</database>\n", md_result_file); if (lock_tables) - mysql_query(sock,"UNLOCK_TABLES"); + mysql_query(sock,"UNLOCK TABLES"); return 0; } /* dump_all_tables_in_db */ diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 5ad6d1dc429..d47ae48b1ac 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -238,7 +238,8 @@ static int get_options(int *argc, char ***argv) fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n"); return(1); } - if (!(charset_info= get_charset_by_csname(default_charset, + if (strcmp(default_charset, charset_info->csname) && + !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))) exit(1); if (*argc < 2) diff --git a/client/sql_string.cc b/client/sql_string.cc index 65a9ff68c53..7de0df02f53 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -415,7 +415,7 @@ int String::strstr(const String &s,uint32 offset) register const char *search=s.ptr(); const char *end=Ptr+str_length-s.length()+1; const char *search_end=s.ptr()+s.length(); -skipp: +skip: while (str != end) { if (*str++ == *search) @@ -423,7 +423,7 @@ skipp: register char *i,*j; i=(char*) str; j=(char*) search+1; while (j != search_end) - if (*i++ != *j++) goto skipp; + if (*i++ != *j++) goto skip; return (int) (str-Ptr) -1; } } @@ -447,7 +447,7 @@ int String::strstr_case(const String &s,uint32 offset) register const char *search=s.ptr(); const char *end=Ptr+str_length-s.length()+1; const char *search_end=s.ptr()+s.length(); -skipp: +skip: while (str != end) { if (str_charset->sort_order[*str++] == str_charset->sort_order[*search]) @@ -457,7 +457,7 @@ skipp: while (j != search_end) if (str_charset->sort_order[*i++] != str_charset->sort_order[*j++]) - goto skipp; + goto skip; return (int) (str-Ptr) -1; } } @@ -480,7 +480,7 @@ int String::strrstr(const String &s,uint32 offset) const char *end=Ptr+s.length()-2; const char *search_end=s.ptr()-1; -skipp: +skip: while (str != end) { if (*str-- == *search) @@ -488,7 +488,7 @@ skipp: register char *i,*j; i=(char*) str; j=(char*) search-1; while (j != search_end) - if (*i-- != *j--) goto skipp; + if (*i-- != *j--) goto skip; return (int) (i-Ptr) +1; } } diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index 19171f62ffb..eb6b930c0b2 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -24,10 +24,21 @@ noinst_HEADERS = chared.h el.h histedit.h key.h \ hist.h map.h prompt.h search.h \ strlcpy.h libedit_term.h tty.h -EXTRA_DIST = makelist +EXTRA_DIST = makelist.sh + +CLEANFILES = makelist DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR +SUFFIXES = .sh + +.sh: + @RM@ -f $@ $@-t + @SED@ \ + -e 's!@''AWK''@!@AWK@!' \ + $< > $@-t + @MV@ $@-t $@ + vi.h: vi.c makelist sh ./makelist -h ./vi.c > $@.tmp && \ mv $@.tmp $@ diff --git a/cmd-line-utils/libedit/makelist b/cmd-line-utils/libedit/makelist.sh index 3c3338e9875..13d37512591 100644 --- a/cmd-line-utils/libedit/makelist +++ b/cmd-line-utils/libedit/makelist.sh @@ -39,7 +39,7 @@ # makelist.sh: Automatically generate header files... -AWK=/usr/bin/awk +AWK=@AWK@ USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>" if [ "x$1" = "x" ] diff --git a/configure.in b/configure.in index cf19670dc6e..b07f970a651 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, 5.0.0-alpha) +AM_INIT_AUTOMAKE(mysql, 5.0.1-alpha) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -452,6 +452,9 @@ then FIND_PROC="$PS \$\$PID | grep mysqld > /dev/null" else case $SYSTEM_TYPE in + *freebsd*) + FIND_PROC="$PS p \$\$PID | grep mysqld > /dev/null" + ;; *darwin*) FIND_PROC="$PS -uaxww | grep mysqld | grep \" \$\$PID \" > /dev/null" ;; diff --git a/dbug/dbug.c b/dbug/dbug.c index d96ef0cae09..4e4dd87d0a3 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -1640,7 +1640,7 @@ static char *static_strtok (char *s1, pchar separator) cpy--; /* Point at separator */ break; } - end++; /* Two separators in a row, skipp one */ + end++; /* Two separators in a row, skip one */ } } while (*end != EOS); *cpy=EOS; /* Replace last separator */ diff --git a/include/m_ctype.h b/include/m_ctype.h index 0228b359111..88c3418fc0d 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -144,6 +144,8 @@ typedef struct my_charset_handler_st int (*mbcharlen)(struct charset_info_st *, uint); uint (*numchars)(struct charset_info_st *, const char *b, const char *e); uint (*charpos)(struct charset_info_st *, const char *b, const char *e, uint pos); + uint (*wellformedlen)(struct charset_info_st *, + const char *b,const char *e, uint nchars); uint (*lengthsp)(struct charset_info_st *, const char *ptr, uint length); /* Unicode convertion */ @@ -206,8 +208,9 @@ typedef struct charset_info_st uchar state_map[256]; uchar ident_map[256]; uint strxfrm_multiply; + uint mbminlen; uint mbmaxlen; - char max_sort_char; /* For LIKE optimization */ + char max_sort_char; /* For LIKE optimization */ MY_CHARSET_HANDLER *cset; MY_COLLATION_HANDLER *coll; @@ -310,6 +313,7 @@ int my_wildcmp_8bit(CHARSET_INFO *, uint my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e); uint my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos); +uint my_wellformedlen_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos); int my_mbcharlen_8bit(CHARSET_INFO *, uint c); @@ -326,6 +330,7 @@ int my_wildcmp_mb(CHARSET_INFO *, int escape, int w_one, int w_many); uint my_numchars_mb(CHARSET_INFO *, const char *b, const char *e); uint my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, uint pos); +uint my_wellformedlen_mb(CHARSET_INFO *, const char *b, const char *e, uint pos); uint my_instr_mb(struct charset_info_st *, const char *b, uint b_length, const char *s, uint s_length, diff --git a/include/my_getopt.h b/include/my_getopt.h index 148238f8d1b..5f4025efa0e 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -17,11 +17,12 @@ C_MODE_START enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_INT, GET_UINT, GET_LONG, - GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC + GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC, + GET_DISABLED }; -#define GET_ASK_ADDR 128 -#define GET_TYPE_MASK 127 +#define GET_ASK_ADDR 128 +#define GET_TYPE_MASK 127 enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG }; diff --git a/include/my_global.h b/include/my_global.h index 3275b010bb4..8523df629a2 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1186,4 +1186,6 @@ typedef union { #define MYSQL_UNIVERSAL_CLIENT_CHARSET MYSQL_DEFAULT_CHARSET_NAME #endif +#define HAVE_SPATIAL +#define HAVE_RTREE_KEYS #endif /* my_global_h */ diff --git a/include/mysql.h b/include/mysql.h index d1b467f9649..cd5d01d6f44 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -57,9 +57,6 @@ typedef int my_socket; #include "mysql_com.h" #include "mysql_version.h" #include "typelib.h" -#ifndef DBUG_OFF -#define CHECK_EXTRA_ARGUMENTS -#endif #include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */ @@ -537,6 +534,8 @@ typedef struct st_mysql_stmt char *query; /* query buffer */ MEM_ROOT mem_root; /* root allocations */ my_ulonglong last_fetched_column; /* last fetched column */ + my_ulonglong affected_rows; /* copy of mysql->affected_rows + after statement execution */ unsigned long stmt_id; /* Id for prepared statement */ unsigned int last_errno; /* error code */ unsigned int param_count; /* parameters count */ @@ -575,6 +574,7 @@ typedef struct st_mysql_methods int (*unbuffered_fetch)(MYSQL *mysql, char **row); void (*free_embedded_thd)(MYSQL *mysql); const char *(*read_statistic)(MYSQL *mysql); + int (*next_result)(MYSQL *mysql); #endif } MYSQL_METHODS; diff --git a/include/mysql_embed.h b/include/mysql_embed.h index df358e29872..7a169d4133e 100644 --- a/include/mysql_embed.h +++ b/include/mysql_embed.h @@ -32,6 +32,4 @@ #undef MYSQL_SERVER_SUFFIX #define MYSQL_SERVER_SUFFIX "-embedded" -#undef HAVE_QUERY_CACHE /* Cache dosn't work yet */ - #endif /* EMBEDDED_LIBRARY */ diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 2f333bec7c8..a3e063d4ed7 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -303,37 +303,40 @@ #define ER_WARN_HOSTNAME_WONT_WORK 1284 #define ER_UNKNOWN_STORAGE_ENGINE 1285 #define ER_WARN_DEPRECATED_SYNTAX 1286 -#define ER_SP_NO_RECURSIVE_CREATE 1287 -#define ER_SP_ALREADY_EXISTS 1288 -#define ER_SP_DOES_NOT_EXIST 1289 -#define ER_SP_DROP_FAILED 1290 -#define ER_SP_STORE_FAILED 1291 -#define ER_SP_LILABEL_MISMATCH 1292 -#define ER_SP_LABEL_REDEFINE 1293 -#define ER_SP_LABEL_MISMATCH 1294 -#define ER_SP_UNINIT_VAR 1295 -#define ER_SP_BADSELECT 1296 -#define ER_SP_BADRETURN 1297 -#define ER_SP_BADSTATEMENT 1298 -#define ER_UPDATE_LOG_DEPRECATED_IGNORED 1299 -#define ER_UPDATE_LOG_DEPRECATED_TRANSLATED 1300 -#define ER_QUERY_INTERRUPTED 1301 -#define ER_SP_WRONG_NO_OF_ARGS 1302 -#define ER_SP_COND_MISMATCH 1303 -#define ER_SP_NORETURN 1304 -#define ER_SP_NORETURNEND 1305 -#define ER_SP_BAD_CURSOR_QUERY 1306 -#define ER_SP_BAD_CURSOR_SELECT 1307 -#define ER_SP_CURSOR_MISMATCH 1308 -#define ER_SP_CURSOR_ALREADY_OPEN 1309 -#define ER_SP_CURSOR_NOT_OPEN 1310 -#define ER_SP_UNDECLARED_VAR 1311 -#define ER_SP_WRONG_NO_OF_FETCH_ARGS 1312 -#define ER_SP_FETCH_NO_DATA 1313 -#define ER_SP_DUP_PARAM 1314 -#define ER_SP_DUP_VAR 1315 -#define ER_SP_DUP_COND 1316 -#define ER_SP_DUP_CURS 1317 -#define ER_SP_CANT_ALTER 1318 -#define ER_SP_SUBSELECT_NYI 1319 -#define ER_ERROR_MESSAGES 320 +#define ER_NON_UPDATABLE_TABLE 1287 +#define ER_FEATURE_DISABLED 1288 +#define ER_SKIP_GRANT_TABLES 1289 +#define ER_SP_NO_RECURSIVE_CREATE 1290 +#define ER_SP_ALREADY_EXISTS 1291 +#define ER_SP_DOES_NOT_EXIST 1292 +#define ER_SP_DROP_FAILED 1293 +#define ER_SP_STORE_FAILED 1294 +#define ER_SP_LILABEL_MISMATCH 1295 +#define ER_SP_LABEL_REDEFINE 1296 +#define ER_SP_LABEL_MISMATCH 1297 +#define ER_SP_UNINIT_VAR 1298 +#define ER_SP_BADSELECT 1299 +#define ER_SP_BADRETURN 1300 +#define ER_SP_BADSTATEMENT 1301 +#define ER_UPDATE_LOG_DEPRECATED_IGNORED 1302 +#define ER_UPDATE_LOG_DEPRECATED_TRANSLATED 1303 +#define ER_QUERY_INTERRUPTED 1304 +#define ER_SP_WRONG_NO_OF_ARGS 1305 +#define ER_SP_COND_MISMATCH 1306 +#define ER_SP_NORETURN 1307 +#define ER_SP_NORETURNEND 1308 +#define ER_SP_BAD_CURSOR_QUERY 1309 +#define ER_SP_BAD_CURSOR_SELECT 1310 +#define ER_SP_CURSOR_MISMATCH 1311 +#define ER_SP_CURSOR_ALREADY_OPEN 1312 +#define ER_SP_CURSOR_NOT_OPEN 1313 +#define ER_SP_UNDECLARED_VAR 1314 +#define ER_SP_WRONG_NO_OF_FETCH_ARGS 1315 +#define ER_SP_FETCH_NO_DATA 1316 +#define ER_SP_DUP_PARAM 1317 +#define ER_SP_DUP_VAR 1318 +#define ER_SP_DUP_COND 1319 +#define ER_SP_DUP_CURS 1320 +#define ER_SP_CANT_ALTER 1321 +#define ER_SP_SUBSELECT_NYI 1322 +#define ER_ERROR_MESSAGES 323 diff --git a/include/mysys_err.h b/include/mysys_err.h index 0ee89e91ee4..230be5f4720 100644 --- a/include/mysys_err.h +++ b/include/mysys_err.h @@ -68,6 +68,7 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */ #define EXIT_UNKNOWN_SUFFIX 9 #define EXIT_NO_PTR_TO_VARIABLE 10 #define EXIT_CANNOT_CONNECT_TO_SERVICE 11 +#define EXIT_OPTION_DISABLED 12 #ifdef __cplusplus diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index b4a28d5fcd8..805f08af361 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -48,9 +48,12 @@ insert buffer tree, and that is in the system tablespace of InnoDB. 1. The first field is the space id. 2. The second field is a one-byte marker which differentiates records from the < 4.1.x storage format. -3. The third field contains the type info, where we have also added 2 bytes to - store the charset. -4. The rest of the fields contain the fields of the actual index record. +3. The third field is the page number. +4. The fourth field contains the type info, where we have also added 2 bytes to + store the charset. In the compressed table format of 5.0.x we must add more + information here so that we can build a dummy 'index' struct which 5.0.x + can use in the binary search on the index page in the ibuf merge phase. +5. The rest of the fields contain the fields of the actual index record. */ diff --git a/innobase/include/log0recv.h b/innobase/include/log0recv.h index 5991960e8ae..c972c3ce977 100644 --- a/innobase/include/log0recv.h +++ b/innobase/include/log0recv.h @@ -15,6 +15,8 @@ Created 9/20/1997 Heikki Tuuri #include "hash0hash.h" #include "log0log.h" +extern ibool recv_replay_file_ops; + /*********************************************************************** Reads the checkpoint info needed in hot backup. */ diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index b01474753bd..01679a374b0 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -34,6 +34,11 @@ Created 9/20/1997 Heikki Tuuri #include "dict0boot.h" #include "fil0fil.h" +/* This is set to FALSE if the backup was originally taken with the +ibbackup --include regexp option: then we do not want to create tables in +directories which were not included */ +ibool recv_replay_file_ops = TRUE; + /* Log records are stored in the hash table in chunks at most of this size; this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */ #define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t)) @@ -1974,18 +1979,21 @@ loop: || type == MLOG_FILE_RENAME || type == MLOG_FILE_DELETE)) { #ifdef UNIV_HOTBACKUP - /* In ibbackup --apply-log, replay an .ibd file - operation, if possible; note that - fil_path_to_mysql_datadir is set in ibbackup to - point to the datadir we should use there */ + if (recv_replay_file_ops) { + + /* In ibbackup --apply-log, replay an .ibd file + operation, if possible; note that + fil_path_to_mysql_datadir is set in ibbackup to + point to the datadir we should use there */ - if (NULL == fil_op_log_parse_or_replay(body, end_ptr, - type, TRUE, space)) { - fprintf(stderr, + if (NULL == fil_op_log_parse_or_replay(body, + end_ptr, type, TRUE, space)) { + fprintf(stderr, "InnoDB: Error: file op log record of type %lu space %lu not complete in\n" "InnoDB: the replay phase. Path %s\n", (ulint)type, space, (char*)(body + 2)); - ut_a(0); + ut_a(0); + } } #endif /* In normal mysqld crash recovery we do not try to diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index d5472219d09..cf7a3efcdfc 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1447,7 +1447,7 @@ row_create_table_for_mysql( fprintf(stderr, " InnoDB: Error: table %s already exists in InnoDB internal\n" "InnoDB: data dictionary. Have you deleted the .frm file\n" - "InnoDB: and not used DROPT ABLE? Have you used DROP DATABASE\n" + "InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n" "InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n" "InnoDB: See the Restrictions section of the InnoDB manual.\n", table->name); diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index a455722f15a..d5895f20461 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -534,6 +534,8 @@ row_purge_parse_undo_rec( node->table = NULL; + row_mysql_unfreeze_data_dictionary(trx); + return(FALSE); } diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 2215e3feff8..57de309c090 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2773,6 +2773,18 @@ row_search_for_mysql( ut_a(0); } + if (trx->n_mysql_tables_in_use == 0) { + char err_buf[1000]; + + trx_print(err_buf, trx); + + fprintf(stderr, +"InnoDB: Error: MySQL is trying to perform a SELECT\n" +"InnoDB: but it has not locked any tables in ::external_lock()!\n%s\n", + err_buf); + ut_a(0); + } + /* printf("Match mode %lu\n search tuple ", match_mode); dtuple_print(search_tuple); @@ -2891,8 +2903,6 @@ row_search_for_mysql( mtr_start(&mtr); - mtr_start(&mtr); - /*-------------------------------------------------------------*/ /* PHASE 2: Try fast adaptive hash index search if possible */ @@ -3072,6 +3082,18 @@ shortcut_fails_too_big_rec: if (!prebuilt->sql_stat_start) { /* No need to set an intention lock or assign a read view */ + if (trx->read_view == NULL + && prebuilt->select_lock_type == LOCK_NONE) { + char err_buf[1000]; + + trx_print(err_buf, trx); + + fprintf(stderr, +"InnoDB: Error: MySQL is trying to perform a consistent read\n" +"InnoDB: but the read view is not assigned!\n%s\n", err_buf); + + ut_a(0); + } } else if (prebuilt->select_lock_type == LOCK_NONE) { /* This is a consistent read */ /* Assign a read view for the query */ diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 027d7c8fb6e..d2368c5341f 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -2739,8 +2739,6 @@ loop: cnt++; - os_thread_sleep(2000000); - /* Try to track a strange bug reported by Harald Fuchs and others, where the lsn seems to decrease at times */ @@ -2782,6 +2780,8 @@ loop: fflush(stderr); fflush(stdout); + os_thread_sleep(2000000); + if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) { goto loop; diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 5fe66f515bc..e6fdc95fad0 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1512,12 +1512,13 @@ NetWare. */ srv_is_being_started = FALSE; #ifdef UNIV_DEBUG - /* Wait a while so that creates threads have time to suspend themselves - before we switch sync debugging on; otherwise a thread may execute - mutex_enter() before the checks are on, and mutex_exit() after the - checks are on. */ + /* Wait a while so that the created threads have time to suspend + themselves before we switch sync debugging on; otherwise a thread may + execute mutex_enter() before the checks are on, and mutex_exit() after + the checks are on, which will cause an assertion failure in sync + debug. */ - os_thread_sleep(2000000); + os_thread_sleep(3000000); #endif sync_order_checks_on = TRUE; @@ -1603,6 +1604,19 @@ NetWare. */ fflush(stderr); if (trx_doublewrite_must_reset_space_ids) { + /* Actually, we did not change the undo log format between + 4.0 and 4.1.1, and we would not need to run purge to + completion. Note also that the purge algorithm in 4.1.1 + can process the the history list again even after a full + purge, because our algorithm does not cut the end of the + history list in all cases so that it would become empty + after a full purge. That mean that we may purge 4.0 type + undo log even after this phase. + + The insert buffer record format changed between 4.0 and + 4.1.1. It is essential that the insert buffer is emptied + here! */ + fprintf(stderr, "InnoDB: You are upgrading to an InnoDB version which allows multiple\n" "InnoDB: tablespaces. Wait that purge and insert buffer merge run to\n" @@ -1625,8 +1639,9 @@ NetWare. */ fprintf(stderr, "InnoDB: You have now successfully upgraded to the multiple tablespaces\n" -"InnoDB: format. You should not downgrade again to an earlier version of\n" -"InnoDB: InnoDB!\n"); +"InnoDB: format. You should NOT DOWNGRADE again to an earlier version of\n" +"InnoDB: InnoDB! But if you absolutely need to downgrade, see section 4.6 of\n" +"InnoDB: http://www.innodb.com/ibman.php for instructions.\n"); } if (srv_force_recovery == 0) { diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 2c62a71a798..b3f4ccc4b4d 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1589,7 +1589,7 @@ static my_bool my_realloc_str(NET *net, ulong length) ********************************************************************/ /* - Read the prepare statement results .. + Read the prepared statement results .. NOTE This is only called for connection to servers that supports @@ -1653,14 +1653,6 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length) DBUG_ENTER("mysql_prepare"); DBUG_ASSERT(mysql != 0); -#ifdef CHECK_EXTRA_ARGUMENTS - if (!query) - { - set_mysql_error(mysql, CR_NULL_POINTER, unknown_sqlstate); - DBUG_RETURN(0); - } -#endif - if (!(stmt= (MYSQL_STMT *) my_malloc(sizeof(MYSQL_STMT), MYF(MY_WME | MY_ZEROFILL))) || !(stmt->query= my_strdup_with_length((byte *) query, length, MYF(0)))) @@ -1815,7 +1807,7 @@ static void store_param_type(NET *net, uint type) /**************************************************************************** Functions to store parameter data from a prepared statement. - All functions has the following characteristics: + All functions have the following characteristics: SYNOPSIS store_param_xxx() @@ -1997,7 +1989,7 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param) /* - Send the prepare query to server for execution + Send the prepared query to server for execution */ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) @@ -2018,6 +2010,7 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); DBUG_RETURN(1); } + stmt->affected_rows= mysql->affected_rows; DBUG_RETURN(0); } @@ -2035,14 +2028,6 @@ int cli_stmt_execute(MYSQL_STMT *stmt) uint null_count; my_bool result; -#ifdef CHECK_EXTRA_ARGUMENTS - if (!stmt->param_buffers) - { - /* Parameters exists, but no bound buffers */ - set_stmt_error(stmt, CR_NOT_ALL_PARAMS_BOUND, unknown_sqlstate); - DBUG_RETURN(1); - } -#endif net_clear(net); /* Sets net->write_pos */ /* Reserve place for null-marker bytes */ null_count= (stmt->param_count+7) /8; @@ -2087,18 +2072,13 @@ int cli_stmt_execute(MYSQL_STMT *stmt) } /* - Execute the prepare query + Execute the prepared query */ int STDCALL mysql_execute(MYSQL_STMT *stmt) { DBUG_ENTER("mysql_execute"); - if (stmt->state == MY_ST_UNKNOWN) - { - set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate); - DBUG_RETURN(1); - } if ((*stmt->mysql->methods->stmt_execute)(stmt)) DBUG_RETURN(1); @@ -2127,7 +2107,7 @@ ulong STDCALL mysql_param_count(MYSQL_STMT * stmt) my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt) { - return stmt->mysql->last_used_con->affected_rows; + return stmt->affected_rows; } @@ -2144,19 +2124,6 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind) MYSQL_BIND *param, *end; DBUG_ENTER("mysql_bind_param"); -#ifdef CHECK_EXTRA_ARGUMENTS - if (stmt->state == MY_ST_UNKNOWN) - { - set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate); - DBUG_RETURN(1); - } - if (!stmt->param_count) - { - set_stmt_error(stmt, CR_NO_PARAMETERS_EXISTS, unknown_sqlstate); - DBUG_RETURN(1); - } -#endif - /* Allocated on prepare */ memcpy((char*) stmt->params, (char*) bind, sizeof(MYSQL_BIND) * stmt->param_count); @@ -2279,11 +2246,6 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number, DBUG_PRINT("enter",("param no : %d, data : %lx, length : %ld", param_number, data, length)); - if (param_number >= stmt->param_count) - { - set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate); - DBUG_RETURN(1); - } param= stmt->params+param_number; if (param->buffer_type < MYSQL_TYPE_TINY_BLOB || param->buffer_type > MYSQL_TYPE_STRING) @@ -2332,7 +2294,7 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number, /**************************************************************************** Functions to fetch data to application buffers - All functions has the following characteristics: + All functions have the following characteristics: SYNOPSIS fetch_result_xxx() @@ -2853,18 +2815,6 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) DBUG_ENTER("mysql_bind_result"); DBUG_ASSERT(stmt != 0); -#ifdef CHECK_EXTRA_ARGUMENTS - if (stmt->state == MY_ST_UNKNOWN) - { - set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate); - DBUG_RETURN(1); - } - if (!bind) - { - set_stmt_error(stmt, CR_NULL_POINTER, unknown_sqlstate); - DBUG_RETURN(1); - } -#endif if (!(bind_count= stmt->field_count) && !(bind_count= alloc_stmt_fields(stmt))) DBUG_RETURN(0); @@ -3035,6 +2985,15 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt) } else /* un-buffered */ { + if (mysql->status != MYSQL_STATUS_GET_RESULT) + { + if (!stmt->field_count) + goto no_data; + + set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); + DBUG_RETURN(1); + } + if((*mysql->methods->unbuffered_fetch)(mysql, ( char **)&row)) { set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, @@ -3059,13 +3018,13 @@ no_data: /* - Fetch datat for one specified column data + Fetch data for one specified column data SYNOPSIS mysql_fetch_column() stmt Prepared statement handler - bind Where date should be placed. Should be filled in as - when calling mysql_bind_param() + bind Where data should be placed. Should be filled in as + when calling mysql_bind_result() column Column to fetch (first column is 0) ulong offset Offset in result data (to fetch blob in pieces) This is normally 0 @@ -3083,14 +3042,6 @@ int STDCALL mysql_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind, if (!stmt->current_row) goto no_data; -#ifdef CHECK_EXTRA_ARGUMENTS - if (column >= stmt->field_count) - { - set_stmt_errmsg(stmt, "Invalid column descriptor",1, unknown_sqlstate); - DBUG_RETURN(1); - } -#endif - if (param->null_field) { if (bind->is_null) @@ -3224,6 +3175,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) DBUG_RETURN(0); } mysql->affected_rows= result->row_count= result->data->rows; + stmt->affected_rows= result->row_count; result->data_cursor= result->data->data; result->fields= stmt->fields; result->field_count= stmt->field_count; @@ -3492,8 +3444,8 @@ my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode) *********************************************************************/ /* - Returns if there are any more query results exists to be read using - mysql_next_result() + Returns true/false to indicate whether any more query results exist + to be read using mysql_next_result() */ my_bool STDCALL mysql_more_results(MYSQL *mysql) @@ -3511,7 +3463,6 @@ my_bool STDCALL mysql_more_results(MYSQL *mysql) /* Reads and returns the next query results */ - int STDCALL mysql_next_result(MYSQL *mysql) { DBUG_ENTER("mysql_next_result"); @@ -3530,8 +3481,8 @@ int STDCALL mysql_next_result(MYSQL *mysql) mysql->affected_rows= ~(my_ulonglong) 0; if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) - DBUG_RETURN((*mysql->methods->read_query_result)(mysql)); - + DBUG_RETURN((*mysql->methods->next_result)(mysql)); + DBUG_RETURN(-1); /* No more results */ } diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 83fab7e2cdb..ddf275eab81 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -33,10 +33,10 @@ INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \ noinst_LIBRARIES = libmysqld_int.a pkglib_LIBRARIES = libmysqld.a SUBDIRS = . examples -libmysqld_sources= libmysqld.c lib_sql.cc +libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c -noinst_HEADERS = embedded_priv.h +noinst_HEADERS = embedded_priv.h emb_qcache.h sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \ @@ -46,7 +46,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \ item_geofunc.cc item_uniq.cc item_subselect.cc item_row.cc\ key.cc lock.cc log.cc log_event.cc sql_state.c \ - protocol.cc net_serv.cc opt_ft.cc opt_range.cc \ + protocol.cc net_serv.cc opt_range.cc \ opt_sum.cc procedure.cc records.cc sql_acl.cc \ sql_load.cc sql_olap.cc \ sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \ @@ -75,7 +75,6 @@ INC_LIB= $(top_builddir)/regex/libregex.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a \ $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/regex/libregex.a \ $(top_builddir)/vio/libvio.a # diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc new file mode 100644 index 00000000000..4dac154ab80 --- /dev/null +++ b/libmysqld/emb_qcache.cc @@ -0,0 +1,446 @@ +/* Copyright (C) 2000-2003 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 */ + +#include "mysql_priv.h" +#ifdef HAVE_QUERY_CACHE +#include <mysql.h> +#include "emb_qcache.h" + +void Querycache_stream::store_char(char c) +{ + if (data_end == cur_data) + use_next_block(); + *(cur_data++)= c; +#ifndef DBUG_OFF + stored_size++; +#endif +} + +void Querycache_stream::store_short(ushort s) +{ +#ifndef DBUG_OFF + stored_size+= 2; +#endif + if (data_end - cur_data > 1) + { + int2store(cur_data, s); + cur_data+= 2; + return; + } + if (data_end == cur_data) + { + use_next_block(); + int2store(cur_data, s); + cur_data+= 2; + return; + } + *cur_data= ((byte *)(&s))[0]; + use_next_block(); + *(cur_data++)= ((byte *)(&s))[1]; +} + +void Querycache_stream::store_int(uint i) +{ +#ifndef DBUG_OFF + stored_size+= 4; +#endif + size_t rest_len= data_end - cur_data; + if (rest_len > 3) + { + int4store(cur_data, i); + cur_data+= 4; + return; + } + if (!rest_len) + { + use_next_block(); + int4store(cur_data, i); + cur_data+= 4; + return; + } + memcpy(cur_data, &i, rest_len); + use_next_block(); + memcpy(cur_data, ((byte*)&i)+rest_len, 4-rest_len); + cur_data+= 4-rest_len; +} + +void Querycache_stream::store_ll(ulonglong ll) +{ +#ifndef DBUG_OFF + stored_size+= 8; +#endif + size_t rest_len= data_end - cur_data; + if (rest_len > 7) + { + int8store(cur_data, ll); + cur_data+= 8; + return; + } + if (!rest_len) + { + use_next_block(); + int8store(cur_data, ll); + cur_data+= 8; + return; + } + memcpy(cur_data, &ll, rest_len); + use_next_block(); + memcpy(cur_data, ((byte*)&ll)+rest_len, 8-rest_len); + cur_data+= 8-rest_len; +} + +void Querycache_stream::store_str_only(const char *str, uint str_len) +{ +#ifndef DBUG_OFF + stored_size+= str_len; +#endif + do + { + size_t rest_len= data_end - cur_data; + if (rest_len > str_len) + { + memcpy(cur_data, str, str_len); + cur_data+= str_len; + return; + } + memcpy(cur_data, str, rest_len); + use_next_block(); + str_len-= rest_len; + str+= rest_len; + } while(str_len); +} + +void Querycache_stream::store_str(const char *str, uint str_len) +{ + store_int(str_len); + store_str_only(str, str_len); +} + +void Querycache_stream::store_safe_str(const char *str, uint str_len) +{ + if (str) + { + store_int(str_len+1); + store_str_only(str, str_len); + } + else + store_int(0); +} + +char Querycache_stream::load_char() +{ + if (cur_data == data_end) + use_next_block(); + return *(cur_data++); +} + +ushort Querycache_stream::load_short() +{ + ushort result; + if (data_end-cur_data > 1) + { + result= uint2korr(cur_data); + cur_data+= 2; + return result; + } + if (data_end == cur_data) + { + use_next_block(); + result= uint2korr(cur_data); + cur_data+= 2; + return result; + } + ((byte*)&result)[0]= *cur_data; + use_next_block(); + ((byte*)&result)[1]= *(cur_data++); + return result; +} + +uint Querycache_stream::load_int() +{ + int result; + size_t rest_len= data_end - cur_data; + if (rest_len > 3) + { + result= uint4korr(cur_data); + cur_data+= 4; + return result; + } + if (!rest_len) + { + use_next_block(); + result= uint4korr(cur_data); + cur_data+= 4; + return result; + } + memcpy(&result, cur_data, rest_len); + use_next_block(); + memcpy(((byte*)&result)+rest_len, cur_data, 4-rest_len); + cur_data+= 4-rest_len; + return result; +} + +ulonglong Querycache_stream::load_ll() +{ + ulonglong result; + size_t rest_len= data_end - cur_data; + if (rest_len > 7) + { + result= uint8korr(cur_data); + cur_data+= 8; + return result; + } + if (!rest_len) + { + use_next_block(); + result= uint8korr(cur_data); + cur_data+= 8; + return result; + } + memcpy(&result, cur_data, rest_len); + use_next_block(); + memcpy(((byte*)&result)+rest_len, cur_data, 8-rest_len); + cur_data+= 8-rest_len; + return result; +} + +void Querycache_stream::load_str_only(char *buffer, uint str_len) +{ + do + { + size_t rest_len= data_end - cur_data; + if (rest_len > str_len) + { + memcpy(buffer, cur_data, str_len); + cur_data+= str_len; + buffer+= str_len; + break; + } + memcpy(buffer, cur_data, rest_len); + use_next_block(); + str_len-= rest_len; + buffer+= rest_len; + } while(str_len); + *buffer= 0; +} + +char *Querycache_stream::load_str(MEM_ROOT *alloc, uint *str_len) +{ + char *result; + *str_len= load_int(); + if (!(result= alloc_root(alloc, *str_len + 1))) + return 0; + load_str_only(result, *str_len); + return result; +} + +int Querycache_stream::load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len) +{ + if (!(*str_len= load_int())) + { + *str= NULL; + return 0; + } + (*str_len)--; + if (!(*str= alloc_root(alloc, *str_len + 1))) + return 1; + load_str_only(*str, *str_len); + return 0; +} + +int Querycache_stream::load_column(MEM_ROOT *alloc, char** column) +{ + int len; + if (!(len = load_int())) + { + *column= NULL; + return 0; + } + len--; + if (!(*column= (char *)alloc_root(alloc, len + 4 + 1))) + return 1; + int4store(*column, len); + (*column)+= 4; + load_str_only(*column, len); + return 1; +} + +uint emb_count_querycache_size(THD *thd) +{ + uint result; + MYSQL *mysql= thd->mysql; + MYSQL_FIELD *field= mysql->fields; + MYSQL_FIELD *field_end= field + mysql->field_count; + MYSQL_ROWS *cur_row=NULL; + my_ulonglong n_rows=0; + + if (!field) + return 0; + if (thd->data) + { + *thd->data->prev_ptr= NULL; // this marks the last record + cur_row= thd->data->data; + n_rows= thd->data->rows; + } + result= 4+8 + (42 + 4*n_rows)*mysql->field_count; + + for(; field < field_end; field++) + { + result+= field->name_length + field->table_length + + field->org_name_length + field->org_table_length + field->db_length + + field->catalog_length; + if (field->def) + result+= field->def_length; + } + + for (; cur_row; cur_row=cur_row->next) + { + MYSQL_ROW col= cur_row->data; + MYSQL_ROW col_end= col + mysql->field_count; + for (; col < col_end; col++) + if (*col) + result+= *(uint *)((*col) - sizeof(uint)); + } + return result; +} + +void emb_store_querycache_result(Querycache_stream *dst, THD *thd) +{ + MYSQL *mysql= thd->mysql; + MYSQL_FIELD *field= mysql->fields; + MYSQL_FIELD *field_end= field + mysql->field_count; + MYSQL_ROWS *cur_row= NULL; + my_ulonglong n_rows= 0; + + if (!field) + return; + + if (thd->data) + { + *thd->data->prev_ptr= NULL; // this marks the last record + cur_row= thd->data->data; + n_rows= thd->data->rows; + } + + dst->store_int((uint)mysql->field_count); + dst->store_ll((uint)n_rows); + + for(; field < field_end; field++) + { + dst->store_int((uint)field->length); + dst->store_int((uint)field->max_length); + dst->store_char((char)field->type); + dst->store_short((ushort)field->flags); + dst->store_short((ushort)field->charsetnr); + dst->store_char((char)field->decimals); + dst->store_str(field->name, field->name_length); + dst->store_str(field->table, field->table_length); + dst->store_str(field->org_name, field->org_name_length); + dst->store_str(field->org_table, field->org_table_length); + dst->store_str(field->db, field->db_length); + dst->store_str(field->catalog, field->catalog_length); + + dst->store_safe_str(field->def, field->def_length); + } + + for (; cur_row; cur_row=cur_row->next) + { + MYSQL_ROW col= cur_row->data; + MYSQL_ROW col_end= col + mysql->field_count; + for (; col < col_end; col++) + { + uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0; + dst->store_safe_str(*col, len); + } + } + DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size); +} + +int emb_load_querycache_result(THD *thd, Querycache_stream *src) +{ + MYSQL *mysql= thd->mysql; + MYSQL_DATA *data; + MYSQL_FIELD *field; + MYSQL_FIELD *field_end; + MEM_ROOT *f_alloc= &mysql->field_alloc; + MYSQL_ROWS *row, *end_row; + MYSQL_ROWS **prev_row; + ulonglong rows; + MYSQL_ROW columns; + + mysql->field_count= src->load_int(); + rows= src->load_ll(); + + if (!(field= (MYSQL_FIELD *) + alloc_root(&mysql->field_alloc,mysql->field_count*sizeof(MYSQL_FIELD)))) + goto err; + mysql->fields= field; + for(field_end= field+mysql->field_count; field < field_end; field++) + { + field->length= src->load_int(); + field->max_length= (unsigned int)src->load_int(); + field->type= (enum enum_field_types)src->load_char(); + field->flags= (unsigned int)src->load_short(); + field->charsetnr= (unsigned int)src->load_short(); + field->decimals= (unsigned int)src->load_char(); + + if (!(field->name= src->load_str(f_alloc, &field->name_length)) || + !(field->table= src->load_str(f_alloc,&field->table_length)) || + !(field->org_name= src->load_str(f_alloc, &field->org_name_length)) || + !(field->org_table= src->load_str(f_alloc, &field->org_table_length))|| + !(field->db= src->load_str(f_alloc, &field->db_length)) || + !(field->catalog= src->load_str(f_alloc, &field->catalog_length)) || + src->load_safe_str(f_alloc, &field->def, &field->def_length)) + goto err; + } + + if (!rows) + return 0; + if (!(data= (MYSQL_DATA*)my_malloc(sizeof(MYSQL_DATA), + MYF(MY_WME | MY_ZEROFILL)))) + goto err; + thd->data= data; + init_alloc_root(&data->alloc, 8192,0); + row= (MYSQL_ROWS *)alloc_root(&data->alloc, rows * sizeof(MYSQL_ROWS) + + rows * (mysql->field_count+1)*sizeof(char*)); + end_row= row + rows; + columns= (MYSQL_ROW)end_row; + + data->rows= rows; + data->fields= mysql->field_count; + data->data= row; + + for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++) + { + *prev_row= row; + row->data= columns; + MYSQL_ROW col_end= columns + mysql->field_count; + uint len; + for (; columns < col_end; columns++) + src->load_column(&data->alloc, columns); + + *(columns++)= NULL; + } + *prev_row= NULL; + data->prev_ptr= prev_row; + + return 0; +err: + return 1; +} + +#endif /*HAVE_QUERY_CACHE*/ + diff --git a/libmysqld/emb_qcache.h b/libmysqld/emb_qcache.h new file mode 100644 index 00000000000..32ce19847ff --- /dev/null +++ b/libmysqld/emb_qcache.h @@ -0,0 +1,61 @@ +/* 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 */ + +class Querycache_stream +{ + byte *cur_data; + byte *data_end; + Query_cache_block *block; + uint headers_len; +public: +#ifndef DBUG_OFF + uint stored_size; +#endif + Querycache_stream(Query_cache_block *ini_block, uint ini_headers_len) : + block(ini_block), headers_len(ini_headers_len) + { + use_next_block(); +#ifndef DBUG_OFF + stored_size= 0; +#endif + } + void use_next_block() + { + cur_data= ((byte*)block)+headers_len; + data_end= cur_data + (block->used-headers_len); + } + + void store_char(char c); + void store_short(ushort s); + void store_int(uint i); + void store_ll(ulonglong ll); + void store_str_only(const char *str, uint str_len); + void store_str(const char *str, uint str_len); + void store_safe_str(const char *str, uint str_len); + + char load_char(); + ushort load_short(); + uint load_int(); + ulonglong load_ll(); + void load_str_only(char *buffer, uint str_len); + char *load_str(MEM_ROOT *alloc, uint *str_len); + int load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len); + int load_column(MEM_ROOT *alloc, char **column); +}; + +uint emb_count_querycache_size(THD *thd); +int emb_load_querycache_result(THD *thd, Querycache_stream *src); +void emb_store_querycache_result(Querycache_stream *dst, THD* thd); diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h index 673531c0c14..1608f4ed4ad 100644 --- a/libmysqld/embedded_priv.h +++ b/libmysqld/embedded_priv.h @@ -23,9 +23,10 @@ #include <my_pthread.h> C_MODE_START -extern void lib_connection_phase(NET *net, int phase); -extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); -extern void *create_embedded_thd(int client_flag, char *db); -extern MYSQL_METHODS embedded_methods; +void lib_connection_phase(NET *net, int phase); +void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); +void *create_embedded_thd(int client_flag, char *db); +int check_embedded_connection(MYSQL *mysql); void free_old_query(MYSQL *mysql); +extern MYSQL_METHODS embedded_methods; C_MODE_END diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 365e9bc820a..188227c21f9 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -96,6 +96,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, net->last_error[0]= 0; strmov(net->sqlstate, not_error_sqlstate); } + mysql->server_status= thd->server_status; mysql->warning_count= ((THD*)mysql->thd)->total_warn_count; return result; } @@ -244,6 +245,18 @@ static MYSQL_RES * emb_mysql_store_result(MYSQL *mysql) return mysql_store_result(mysql); } +int emb_next_result(MYSQL *mysql) +{ + THD *thd= (THD*)mysql->thd; + DBUG_ENTER("emb_next_result"); + + if (emb_advanced_command(mysql, COM_QUERY,0,0, + thd->query_rest.ptr(),thd->query_rest.length(),1) + || emb_mysql_read_query_result(mysql)) + DBUG_RETURN(1); + + DBUG_RETURN(0); /* No more results */ +} MYSQL_METHODS embedded_methods= { @@ -258,7 +271,8 @@ MYSQL_METHODS embedded_methods= emb_read_binary_rows, emb_unbuffered_fetch, emb_free_embedded_thd, - emb_read_statistic + emb_read_statistic, + emb_next_result }; C_MODE_END @@ -478,7 +492,17 @@ void *create_embedded_thd(int client_flag, char *db) return thd; } -#ifndef NO_EMBEDDED_ACCESS_CHECKS +#ifdef NO_EMBEDDED_ACCESS_CHECKS +int check_embedded_connection(MYSQL *mysql) +{ + THD *thd= (THD*)mysql->thd; + thd->host= (char*)my_localhost; + thd->host_or_ip= thd->host; + thd->user= my_strdup(mysql->user, MYF(0)); + return 0; +} + +#else int check_embedded_connection(MYSQL *mysql) { THD *thd= (THD*)mysql->thd; @@ -486,9 +510,13 @@ int check_embedded_connection(MYSQL *mysql) char scramble_buff[SCRAMBLE_LENGTH]; int passwd_len; - thd->host= mysql->options.client_ip ? - mysql->options.client_ip : (char*)my_localhost; - thd->ip= thd->host; + if (mysql->options.client_ip) + { + thd->host= my_strdup(mysql->options.client_ip, MYF(0)); + thd->ip= my_strdup(thd->host, MYF(0)); + } + else + thd->host= (char*)my_localhost; thd->host_or_ip= thd->host; if (acl_check_host(thd->host,thd->ip)) @@ -497,7 +525,7 @@ int check_embedded_connection(MYSQL *mysql) goto err; } - thd->user= mysql->user; + thd->user= my_strdup(mysql->user, MYF(0)); if (mysql->passwd && mysql->passwd[0]) { memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble @@ -565,6 +593,9 @@ bool Protocol::send_fields(List<Item> *list, uint flag) client_field->org_name_length= strlen(client_field->org_name); client_field->org_table_length= strlen(client_field->org_table); client_field->charsetnr= server_field.charsetnr; + + client_field->catalog= strdup_root(field_alloc, "std"); + client_field->catalog_length= 3; if (INTERNAL_NUM_FIELD(client_field)) client_field->flags|= NUM_FLAG; @@ -575,9 +606,15 @@ bool Protocol::send_fields(List<Item> *list, uint flag) String tmp(buff, sizeof(buff), default_charset_info), *res; if (!(res=item->val_str(&tmp))) + { client_field->def= strdup_root(field_alloc, ""); + client_field->def_length= 0; + } else + { client_field->def= strdup_root(field_alloc, tmp.ptr()); + client_field->def_length= tmp.length(); + } } else client_field->def=0; @@ -652,7 +689,10 @@ send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message) mysql->affected_rows= affected_rows; mysql->insert_id= id; if (message) + { strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1); + mysql->info= thd->net.last_error; + } DBUG_VOID_RETURN; } diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index f96c06ff0f6..95f745aef5f 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -81,28 +81,6 @@ static void end_server(MYSQL *mysql) DBUG_VOID_RETURN; } -/************************************************************************** -** Connect to sql server -** If host == 0 then use localhost -**************************************************************************/ - -MYSQL * STDCALL -mysql_connect(MYSQL *mysql,const char *host, - const char *user, const char *passwd) -{ - MYSQL *res; - mysql=mysql_init(mysql); /* Make it thread safe */ - { - DBUG_ENTER("mysql_connect"); - if (!(res=mysql_real_connect(mysql,host,user,passwd,NullS,0,NullS,0))) - { - if (mysql->free_me) - my_free((gptr) mysql,MYF(0)); - } - DBUG_RETURN(res); - } -} - static inline int mysql_init_charset(MYSQL *mysql) { char charset_name_buff[16], *charset_name; @@ -146,17 +124,14 @@ static inline int mysql_init_charset(MYSQL *mysql) return 0; } -int check_embedded_connection(MYSQL *mysql); - MYSQL * STDCALL mysql_real_connect(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, uint port, const char *unix_socket,ulong client_flag) { char *db_name; -#ifndef NO_EMBEDDED_ACCESS_CHECKS char name_buff[USERNAME_LENGTH]; -#endif + DBUG_ENTER("mysql_real_connect"); DBUG_PRINT("enter",("host: %s db: %s user: %s", host ? host : "(Null)", @@ -187,10 +162,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (!db || !db[0]) db=mysql->options.db; -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (!user || !user[0]) user=mysql->options.user; +#ifndef NO_EMBEDDED_ACCESS_CHECKS if (!passwd) { passwd=mysql->options.password; @@ -199,16 +174,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, passwd=getenv("MYSQL_PWD"); /* get it from environment */ #endif } + mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL; +#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ if (!user || !user[0]) { read_user_name(name_buff); - if (!name_buff[0]) + if (name_buff[0]) user= name_buff; } + if (!user) + user= ""; mysql->user=my_strdup(user,MYF(0)); - mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL; -#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ port=0; unix_socket=0; @@ -218,10 +195,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, init_embedded_mysql(mysql, client_flag, db_name); -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_embedded_connection(mysql)) goto error; -#endif if (mysql_init_charset(mysql)) goto error; diff --git a/myisam/mi_check.c b/myisam/mi_check.c index c61e94b6399..762eef15d68 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -551,7 +551,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, ha_checksum *key_checksum, uint level) { int flag; - uint used_length,comp_flag,nod_flag,key_length,not_used; + uint used_length,comp_flag,nod_flag,key_length=0,not_used; uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos; my_off_t next_page,record; char llbuff[22]; @@ -586,6 +586,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, } for ( ;; ) { + memcpy((char*) info->lastkey,(char*) key,key_length); + info->lastkey_length=key_length; if (nod_flag) { next_page=_mi_kpos(nod_flag,keypos); @@ -629,8 +631,6 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, } (*key_checksum)+= mi_byte_checksum((byte*) key, key_length- info->s->rec_reflength); - memcpy((char*) info->lastkey,(char*) key,key_length); - info->lastkey_length=key_length; record= _mi_dpos(info,0,key+key_length); if (keyinfo->flag & HA_FULLTEXT) /* special handling for ft2 */ { @@ -658,7 +658,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, DBUG_PRINT("test",("page: %s record: %s filelength: %s", llstr(page,llbuff),llstr(record,llbuff2), llstr(info->state->data_file_length,llbuff3))); - DBUG_DUMP("key",(byte*) info->lastkey,key_length); + DBUG_DUMP("key",(byte*) key,key_length); DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos)); goto err; } diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 9036ced751c..72633966b54 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -42,7 +42,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, int errpos,save_errno; myf create_flag; uint fields,length,max_key_length,packed,pointer, - key_length,info_length,key_segs,options,min_key_length_skipp, + key_length,info_length,key_segs,options,min_key_length_skip, base_pos,varchar_count,long_varchar_count,varchar_length, max_key_block_length,unique_key_parts,fulltext_keys,offset; ulong reclength, real_reclength,min_pack_length; @@ -238,7 +238,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { share.state.key_root[i]= HA_OFFSET_ERROR; - min_key_length_skipp=length=0; + min_key_length_skip=length=0; key_length=pointer; if (keydef->flag & HA_SPATIAL) { @@ -269,7 +269,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, keydef->keysegs+=sp_segs; key_length+=SPLEN*sp_segs; length++; /* At least one length byte */ - min_key_length_skipp+=SPLEN*2*SPDIMS; + min_key_length_skip+=SPLEN*2*SPDIMS; } else if (keydef->flag & HA_FULLTEXT) @@ -291,7 +291,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, fulltext_keys++; key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN; length++; /* At least one length byte */ - min_key_length_skipp+=HA_FT_MAXBYTELEN; + min_key_length_skip+=HA_FT_MAXBYTELEN; } else { @@ -348,10 +348,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY; options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ length++; /* At least one length byte */ - min_key_length_skipp+=keyseg->length; + min_key_length_skip+=keyseg->length; if (keyseg->length >= 255) { /* prefix may be 3 bytes */ - min_key_length_skipp+=2; + min_key_length_skip+=2; length+=2; } } @@ -360,10 +360,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, keydef->flag|=HA_VAR_LENGTH_KEY; length++; /* At least one length byte */ options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ - min_key_length_skipp+=keyseg->length; + min_key_length_skip+=keyseg->length; if (keyseg->length >= 255) { /* prefix may be 3 bytes */ - min_key_length_skipp+=2; + min_key_length_skip+=2; length+=2; } } @@ -395,7 +395,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, } set_if_bigger(max_key_block_length,keydef->block_length); keydef->keylength= (uint16) key_length; - keydef->minlength= (uint16) (length-min_key_length_skipp); + keydef->minlength= (uint16) (length-min_key_length_skip); keydef->maxlength= (uint16) length; if (length > max_key_length) diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index a55d5b2a5ca..19cfc050ea1 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -20,10 +20,6 @@ #include "rt_index.h" #include <assert.h> -#ifdef __WIN__ -#include <errno.h> -#endif - static int d_search(MI_INFO *info,MI_KEYDEF *keyinfo,uint comp_flag, uchar *key,uint key_length,my_off_t page,uchar *anc_buff); static int del(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,uchar *anc_buff, diff --git a/myisam/mi_delete_table.c b/myisam/mi_delete_table.c index 6d842d7e6a4..6843881568d 100644 --- a/myisam/mi_delete_table.c +++ b/myisam/mi_delete_table.c @@ -19,9 +19,6 @@ */ #include "fulltext.h" -#ifdef __WIN__ -#include <errno.h> -#endif int mi_delete_table(const char *name) { diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index e1bfe4c3ac5..079779bd0ef 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -1248,7 +1248,7 @@ err: int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, register my_off_t filepos, - my_bool skipp_deleted_blocks) + my_bool skip_deleted_blocks) { int flag,info_read,save_errno; uint left_len,b_type; @@ -1299,7 +1299,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, { if (_mi_read_cache(&info->rec_cache,(byte*) block_info.header,filepos, sizeof(block_info.header), - (!flag && skipp_deleted_blocks ? READING_NEXT : 0) | + (!flag && skip_deleted_blocks ? READING_NEXT : 0) | READING_HEADER)) goto panic; b_type=_mi_get_block_info(&block_info,-1,filepos); @@ -1318,7 +1318,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, BLOCK_FATAL_ERROR)) { if ((b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR)) - && skipp_deleted_blocks) + && skip_deleted_blocks) { filepos=block_info.filepos+block_info.block_len; block_info.second_read=0; @@ -1374,7 +1374,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, { if (_mi_read_cache(&info->rec_cache,(byte*) to,filepos, block_info.data_len, - (!flag && skipp_deleted_blocks) ? READING_NEXT :0)) + (!flag && skip_deleted_blocks) ? READING_NEXT :0)) goto panic; } else @@ -1391,7 +1391,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, if (flag++ == 0) { info->nextpos=block_info.filepos+block_info.block_len; - skipp_deleted_blocks=0; + skip_deleted_blocks=0; } left_len-=block_info.data_len; to+=block_info.data_len; diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c index 10f52f1e39a..ce072d7d57e 100644 --- a/myisam/mi_extra.c +++ b/myisam/mi_extra.c @@ -18,9 +18,6 @@ #ifdef HAVE_MMAP #include <sys/mman.h> #endif -#ifdef __WIN__ -#include <errno.h> -#endif /* Set options and buffers to optimize table handling diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c index 67ccca52d08..816748d459a 100644 --- a/myisam/mi_locking.c +++ b/myisam/mi_locking.c @@ -22,9 +22,6 @@ */ #include "myisamdef.h" -#ifdef __WIN__ -#include <errno.h> -#endif /* lock table by F_UNLCK, F_RDLCK or F_WRLCK */ diff --git a/myisam/mi_log.c b/myisam/mi_log.c index 1dcfd5250d2..13842c56828 100644 --- a/myisam/mi_log.c +++ b/myisam/mi_log.c @@ -21,7 +21,6 @@ #include "myisamdef.h" #if defined(MSDOS) || defined(__WIN__) -#include <errno.h> #include <fcntl.h> #ifndef __WIN__ #include <process.h> diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index b21bf0b2163..94eb2de17e2 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -32,7 +32,7 @@ (BU)->current_byte & ((mi_bit_type) 1 << --(BU)->bits) :\ (fill_buffer(BU), (BU)->bits= BITS_SAVED-1,\ (BU)->current_byte & ((mi_bit_type) 1 << (BITS_SAVED-1)))) -#define skipp_to_next_byte(BU) ((BU)->bits&=~7) +#define skip_to_next_byte(BU) ((BU)->bits&=~7) #define get_bits(BU,count) (((BU)->bits >= count) ? (((BU)->current_byte >> ((BU)->bits-=count)) & mask[count]) : fill_and_get_bits(BU,count)) #define decode_bytes_test_bit(bit) \ @@ -58,9 +58,9 @@ static void (*get_unpack_function(MI_COLUMNDEF *rec))(MI_COLUMNDEF *field, MI_BIT_BUFF *buff, uchar *to, uchar *end); -static void uf_zerofill_skipp_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, +static void uf_zerofill_skip_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, uchar *to,uchar *end); -static void uf_skipp_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, +static void uf_skip_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, uchar *to,uchar *end); static void uf_space_normal(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, uchar *to,uchar *end); @@ -210,7 +210,7 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) huff_tree_bits); share->rec[i].unpack=get_unpack_function(share->rec+i); } - skipp_to_next_byte(&bit_buff); + skip_to_next_byte(&bit_buff); decode_table=share->decode_tables; for (i=0 ; i < trees ; i++) read_huff_table(&bit_buff,share->decode_trees+i,&decode_table, @@ -291,7 +291,7 @@ static void read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree, else *ptr= (uint16) (IS_CHAR + (get_bits(bit_buff,char_bits) + min_chr)); } - skipp_to_next_byte(bit_buff); + skip_to_next_byte(bit_buff); decode_tree->table= *decode_table; decode_tree->intervalls= *intervall_buff; @@ -468,8 +468,8 @@ static void (*get_unpack_function(MI_COLUMNDEF *rec)) switch (rec->base_type) { case FIELD_SKIP_ZERO: if (rec->pack_type & PACK_TYPE_ZERO_FILL) - return &uf_zerofill_skipp_zero; - return &uf_skipp_zero; + return &uf_zerofill_skip_zero; + return &uf_skip_zero; case FIELD_NORMAL: if (rec->pack_type & PACK_TYPE_SPACE_FIELDS) return &uf_space_normal; @@ -515,7 +515,7 @@ static void (*get_unpack_function(MI_COLUMNDEF *rec)) /* De different functions to unpack a field */ -static void uf_zerofill_skipp_zero(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, +static void uf_zerofill_skip_zero(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, uchar *end) { if (get_bit(bit_buff)) @@ -528,7 +528,7 @@ static void uf_zerofill_skipp_zero(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, } } -static void uf_skipp_zero(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, +static void uf_skip_zero(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, uchar *end) { if (get_bit(bit_buff)) diff --git a/myisam/mi_page.c b/myisam/mi_page.c index c70209c2da6..16713c87e10 100644 --- a/myisam/mi_page.c +++ b/myisam/mi_page.c @@ -17,9 +17,6 @@ /* Read and write key blocks */ #include "myisamdef.h" -#ifdef __WIN__ -#include <errno.h> -#endif /* Fetch a key-page in memory */ diff --git a/myisam/mi_rename.c b/myisam/mi_rename.c index db44b8fe28f..8380ee1bfad 100644 --- a/myisam/mi_rename.c +++ b/myisam/mi_rename.c @@ -19,9 +19,6 @@ */ #include "fulltext.h" -#ifdef __WIN__ -#include <errno.h> -#endif int mi_rename(const char *old_name, const char *new_name) { diff --git a/myisam/mi_rrnd.c b/myisam/mi_rrnd.c index 29f686b0456..f6a2f021662 100644 --- a/myisam/mi_rrnd.c +++ b/myisam/mi_rrnd.c @@ -32,14 +32,14 @@ int mi_rrnd(MI_INFO *info, byte *buf, register my_off_t filepos) { - my_bool skipp_deleted_blocks; + my_bool skip_deleted_blocks; DBUG_ENTER("mi_rrnd"); - skipp_deleted_blocks=0; + skip_deleted_blocks=0; if (filepos == HA_OFFSET_ERROR) { - skipp_deleted_blocks=1; + skip_deleted_blocks=1; if (info->lastpos == HA_OFFSET_ERROR) /* First read ? */ filepos= info->s->pack.header_length; /* Read first record */ else @@ -56,5 +56,5 @@ int mi_rrnd(MI_INFO *info, byte *buf, register my_off_t filepos) if (info->opt_flag & WRITE_CACHE_USED && flush_io_cache(&info->rec_cache)) DBUG_RETURN(my_errno); - DBUG_RETURN ((*info->s->read_rnd)(info,buf,filepos,skipp_deleted_blocks)); + DBUG_RETURN ((*info->s->read_rnd)(info,buf,filepos,skip_deleted_blocks)); } diff --git a/myisam/mi_statrec.c b/myisam/mi_statrec.c index 9afebce2ae6..8f5cde45e24 100644 --- a/myisam/mi_statrec.c +++ b/myisam/mi_statrec.c @@ -202,7 +202,7 @@ int _mi_read_static_record(register MI_INFO *info, register my_off_t pos, int _mi_read_rnd_static_record(MI_INFO *info, byte *buf, register my_off_t filepos, - my_bool skipp_deleted_blocks) + my_bool skip_deleted_blocks) { int locked,error,cache_read; uint cache_length; @@ -212,13 +212,13 @@ int _mi_read_rnd_static_record(MI_INFO *info, byte *buf, cache_read=0; cache_length=0; if (info->opt_flag & WRITE_CACHE_USED && - (info->rec_cache.pos_in_file <= filepos || skipp_deleted_blocks) && + (info->rec_cache.pos_in_file <= filepos || skip_deleted_blocks) && flush_io_cache(&info->rec_cache)) DBUG_RETURN(my_errno); if (info->opt_flag & READ_CACHE_USED) { /* Cache in use */ if (filepos == my_b_tell(&info->rec_cache) && - (skipp_deleted_blocks || !filepos)) + (skip_deleted_blocks || !filepos)) { cache_read=1; /* Read record using cache */ cache_length=(uint) (info->rec_cache.read_end - info->rec_cache.read_pos); diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c index 64ffbe2db1d..77c4d3dfbad 100644 --- a/myisam/mi_test1.c +++ b/myisam/mi_test1.c @@ -318,7 +318,7 @@ static int run_test(const char *filename) return (0); err: printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skipp warning */ + return 1; /* skip warning */ } diff --git a/myisam/mi_update.c b/myisam/mi_update.c index d1d41ac351a..f62be133ed9 100644 --- a/myisam/mi_update.c +++ b/myisam/mi_update.c @@ -19,11 +19,6 @@ #include "fulltext.h" #include "rt_index.h" -#ifdef __WIN__ -#include <errno.h> -#endif - - int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) { int flag,key_changed,save_errno; diff --git a/myisam/mi_write.c b/myisam/mi_write.c index d13ba6c2c4e..88e7f070642 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -20,10 +20,6 @@ #include "rt_index.h" #include <assert.h> -#ifdef __WIN__ -#include <errno.h> -#endif - #define MAX_POINTER_LENGTH 8 /* Functions declared in this file */ @@ -378,7 +374,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, my_off_t root=info->dupp_key_pos; keyinfo=&info->s->ft2_keyinfo; key+=off; - keypos-=keyinfo->keylength; /* we'll modify key entry 'in vivo' */ + keypos-=keyinfo->keylength+nod_flag; /* we'll modify key entry 'in vivo' */ error=_mi_ck_real_write_btree(info, keyinfo, key, 0, &root, comp_flag); _mi_dpointer(info, keypos+HA_FT_WLEN, root); diff --git a/myisam/myisampack.c b/myisam/myisampack.c index 93edde33bdb..b6d862e38b5 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -1071,7 +1071,7 @@ test_space_compress(HUFF_COUNTS *huff_counts, my_off_t records, { int min_pos; uint length_bits,i; - my_off_t space_count,min_space_count,min_pack,new_length,skipp; + my_off_t space_count,min_space_count,min_pack,new_length,skip; length_bits=max_bit(max_space_length); @@ -1091,15 +1091,15 @@ test_space_compress(HUFF_COUNTS *huff_counts, my_off_t records, min_space_count=space_count; } /* Test with length-flag */ - for (skipp=0L, i=0 ; i < 8 ; i++) + for (skip=0L, i=0 ; i < 8 ; i++) { if (space_counts[i]) { if (i) huff_counts->counts[(uint) ' ']+=space_counts[i]; - skipp+=huff_counts->pre_space[i]; + skip+=huff_counts->pre_space[i]; new_length=calc_packed_length(huff_counts,0)+ - (records+(records-skipp)*(1+length_bits))/8; + (records+(records-skip)*(1+length_bits))/8; if (new_length < min_pack) { min_pos=(int) i; diff --git a/myisam/rt_test.c b/myisam/rt_test.c index 61890bfded1..bbeb8fce2d1 100644 --- a/myisam/rt_test.c +++ b/myisam/rt_test.c @@ -307,7 +307,7 @@ int run_test(const char *filename) err: printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skipp warning */ + return 1; /* skip warning */ } diff --git a/myisam/sp_test.c b/myisam/sp_test.c index 16a97771887..5cbf5e87579 100644 --- a/myisam/sp_test.c +++ b/myisam/sp_test.c @@ -283,7 +283,7 @@ int run_test(const char *filename) err: printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skipp warning */ + return 1; /* skip warning */ } diff --git a/mysql-test/include/have_big5.inc b/mysql-test/include/have_big5.inc new file mode 100644 index 00000000000..790e8085e1a --- /dev/null +++ b/mysql-test/include/have_big5.inc @@ -0,0 +1,4 @@ +-- require r/have_big5.require +disable_query_log; +show collation like "big5_chinese_ci"; +enable_query_log; diff --git a/mysql-test/include/have_tis620.inc b/mysql-test/include/have_tis620.inc new file mode 100644 index 00000000000..c1e775681b0 --- /dev/null +++ b/mysql-test/include/have_tis620.inc @@ -0,0 +1,4 @@ +-- require r/have_tis620.require +disable_query_log; +show collation like "tis620_thai_ci"; +enable_query_log; diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index d8bdd91c59f..11ed1bb312c 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -66,7 +66,7 @@ if [ x$BINARY_DIST = x1 ] ; then basedir=.. else basedir=. -EXTRA_ARG="--language=../sql/share/english/" +EXTRA_ARG="--language=../sql/share/english/ --character-sets-dir=../sql/share/charsets/" fi mysqld_boot=" $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \ diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 265ff036998..3f7efd3d6bc 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -603,7 +603,7 @@ error () { error_is () { $ECHO "Errors are (from $TIMEFILE) :" $CAT < $TIMEFILE - $ECHO "(the last line(s) may be the ones that caused the die() in mysqltest)" + $ECHO "(the last lines may be the most important ones)" } prefix_to_8() { @@ -1309,6 +1309,9 @@ run_testcase () skip_inc $ECHO "$RES$RES_SPACE [ skipped ]" else + if [ $res -gt 2 ]; then + $ECHO "mysqltest returned unexpected code $res, it has probably crashed" >> $TIMEFILE + fi total_inc fail_inc $ECHO "$RES$RES_SPACE [ fail ]" diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 7ec12c1b021..ce324dc1fa8 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -412,3 +412,15 @@ t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE t1 0 PRIMARY 2 User A 0 NULL NULL BTREE t1 1 Host 1 Host A NULL NULL NULL BTREE disabled DROP TABLE t1; +CREATE TABLE t1 (a int PRIMARY KEY, b INT UNIQUE); +ALTER TABLE t1 DROP PRIMARY KEY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL default '0', + `b` int(11) default NULL, + UNIQUE KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t1 DROP PRIMARY KEY; +ERROR 42000: Can't DROP 'PRIMARY'. Check that column/key exists +DROP TABLE t1; diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index acca50b45dd..877a349d188 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -24,6 +24,12 @@ Note 1003 select high_priority ~(5) AS `~5`,cast(~(5) as signed) AS `cast(~5 as select cast(5 as unsigned) -6.0; cast(5 as unsigned) -6.0 -1.0 +select cast(NULL as signed), cast(1/0 as signed); +cast(NULL as signed) cast(1/0 as signed) +NULL NULL +select cast(NULL as unsigned), cast(1/0 as unsigned); +cast(NULL as unsigned) cast(1/0 as unsigned) +NULL NULL select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A"; cast("A" as binary) = "a" cast(BINARY "a" as CHAR) = "A" 0 1 @@ -33,6 +39,24 @@ cast("2001-1-1" as DATE) cast("2001-1-1" as DATETIME) select cast("1:2:3" as TIME); cast("1:2:3" as TIME) 01:02:03 +select CONVERT("2004-01-22 21:45:33",DATE); +CONVERT("2004-01-22 21:45:33",DATE) +2004-01-22 +select CONVERT(DATE "2004-01-22 21:45:33" USING latin1); +CONVERT(DATE "2004-01-22 21:45:33" USING latin1) +2004-01-22 21:45:33 +select CONVERT(DATE "2004-01-22 21:45:33",CHAR); +CONVERT(DATE "2004-01-22 21:45:33",CHAR) +2004-01-22 21:45:33 +select CONVERT(DATE "2004-01-22 21:45:33",CHAR(4)); +CONVERT(DATE "2004-01-22 21:45:33",CHAR(4)) +2004 +select CONVERT(DATE "2004-01-22 21:45:33",CHAR(4) BINARY); +CONVERT(DATE "2004-01-22 21:45:33",CHAR(4) BINARY) +2004 +select CAST(DATE "2004-01-22 21:45:33" AS CHAR(4) BINARY); +CAST(DATE "2004-01-22 21:45:33" AS CHAR(4) BINARY) +2004 set names binary; select cast(_latin1'test' as char character set latin2); cast(_latin1'test' as char character set latin2) @@ -101,6 +125,21 @@ t1 CREATE TABLE `t1` ( `c5` char(2) character set utf8 NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +create table t1 (a binary(10), b char(10) character set koi8r); +insert into t1 values (_binary'ÔÅÓÔ',_binary'ÔÅÓÔ'); +select a,b,cast(a as char character set cp1251),cast(b as binary) from t1; +a b cast(a as char character set cp1251) cast(b as binary) +ÔÅÓÔ ÔÅÓÔ ÔÅÓÔ ÔÅÓÔ +set names koi8r; +select a,b,cast(a as char character set cp1251),cast(b as binary) from t1; +a b cast(a as char character set cp1251) cast(b as binary) +ÔÅÓÔ ÔÅÓÔ æåõæ ÔÅÓÔ +set names cp1251; +select a,b,cast(a as char character set cp1251),cast(b as binary) from t1; +a b cast(a as char character set cp1251) cast(b as binary) +ÔÅÓÔ òåñò ÔÅÓÔ ÔÅÓÔ +drop table t1; +set names binary; select cast("2001-1-1" as date) = "2001-01-01"; cast("2001-1-1" as date) = "2001-01-01" 1 diff --git a/mysql-test/r/ctype_big5.result b/mysql-test/r/ctype_big5.result new file mode 100644 index 00000000000..44fad0cd96a --- /dev/null +++ b/mysql-test/r/ctype_big5.result @@ -0,0 +1,10 @@ +drop table if exists t1; +SET NAMES big5; +CREATE TABLE t1 (c CHAR(10) CHARACTER SET big5, KEY(c)); +INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa'); +SELECT * FROM t1 WHERE c LIKE 'aaa%'; +c +aaa +aaaa +aaaaa +DROP TABLE t1; diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result index a3e29d24264..add730fe68f 100644 --- a/mysql-test/r/ctype_collate.result +++ b/mysql-test/r/ctype_collate.result @@ -541,3 +541,50 @@ s2 CHAR(5) COLLATE latin1_swedish_ci); SELECT * FROM t1 WHERE s1 = s2; ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '=' DROP TABLE t1; +SET NAMES latin1; +CREATE TABLE t1 +(s1 char(10) COLLATE latin1_german1_ci, +s2 char(10) COLLATE latin1_swedish_ci, +KEY(s1), +KEY(s2)); +INSERT INTO t1 VALUES ('a','a'); +INSERT INTO t1 VALUES ('b','b'); +INSERT INTO t1 VALUES ('c','c'); +INSERT INTO t1 VALUES ('d','d'); +INSERT INTO t1 VALUES ('e','e'); +INSERT INTO t1 VALUES ('f','f'); +INSERT INTO t1 VALUES ('g','g'); +INSERT INTO t1 VALUES ('h','h'); +INSERT INTO t1 VALUES ('i','i'); +INSERT INTO t1 VALUES ('j','j'); +EXPLAIN SELECT * FROM t1 WHERE s1='a'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref s1 s1 11 const 1 Using where +EXPLAIN SELECT * FROM t1 WHERE s2='a'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref s2 s2 11 const 1 Using where +EXPLAIN SELECT * FROM t1 WHERE s1='a' COLLATE latin1_german1_ci; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref s1 s1 11 const 1 Using where +EXPLAIN SELECT * FROM t1 WHERE s2='a' COLLATE latin1_german1_ci; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where +EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range s1 s1 11 NULL 2 Using where +EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where +EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range s1 s1 11 NULL 2 Using where +EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where +EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range s1 s1 11 NULL 1 Using where +EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where +DROP TABLE t1; diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result index 7f150cb0698..c500019042f 100644 --- a/mysql-test/r/ctype_latin1_de.result +++ b/mysql-test/r/ctype_latin1_de.result @@ -1,3 +1,5 @@ +set names latin1; +set @@collation_connection=latin1_german2_ci; select @@collation_connection; @@collation_connection latin1_german2_ci diff --git a/mysql-test/r/ctype_many.result b/mysql-test/r/ctype_many.result index 173d41ecdd1..8bfc6e98226 100644 --- a/mysql-test/r/ctype_many.result +++ b/mysql-test/r/ctype_many.result @@ -340,129 +340,6 @@ CYR CAPIT SOFT SIGN ø ø CYR CAPIT E ü ü CYR CAPIT YU à à CYR CAPIT YA ñ ñ -select CONVERT(koi8_ru_f, 'cp1251_general_ci', 'utf8_general_ci'), comment from t1; -CONVERT(koi8_ru_f, 'cp1251_general_ci', 'utf8_general_ci') comment -a LAT SMALL A -b LAT SMALL B -c LAT SMALL C -d LAT SMALL D -e LAT SMALL E -f LAT SMALL F -g LAT SMALL G -h LAT SMALL H -i LAT SMALL I -j LAT SMALL J -k LAT SMALL K -l LAT SMALL L -m LAT SMALL M -n LAT SMALL N -o LAT SMALL O -p LAT SMALL P -q LAT SMALL Q -r LAT SMALL R -s LAT SMALL S -t LAT SMALL T -u LAT SMALL U -v LAT SMALL V -w LAT SMALL W -x LAT SMALL X -y LAT SMALL Y -z LAT SMALL Z -A LAT CAPIT A -B LAT CAPIT B -C LAT CAPIT C -D LAT CAPIT D -E LAT CAPIT E -F LAT CAPIT F -G LAT CAPIT G -H LAT CAPIT H -I LAT CAPIT I -J LAT CAPIT J -K LAT CAPIT K -L LAT CAPIT L -M LAT CAPIT M -N LAT CAPIT N -O LAT CAPIT O -P LAT CAPIT P -Q LAT CAPIT Q -R LAT CAPIT R -S LAT CAPIT S -T LAT CAPIT T -U LAT CAPIT U -V LAT CAPIT V -W LAT CAPIT W -X LAT CAPIT X -Y LAT CAPIT Y -Z LAT CAPIT Z -â CYR SMALL A -÷ CYR SMALL BE -þ CYR SMALL VE -ú CYR SMALL GE -ä CYR SMALL DE -å CYR SMALL IE -? CYR SMALL IO -ã CYR SMALL ZHE -ÿ CYR SMALL ZE -ê CYR SMALL I -ì CYR SMALL KA -í CYR SMALL EL -î CYR SMALL EM -ï CYR SMALL EN -ð CYR SMALL O -ò CYR SMALL PE -ô CYR SMALL ER -õ CYR SMALL ES -æ CYR SMALL TE -è CYR SMALL U -ö CYR SMALL EF -é CYR SMALL HA -ç CYR SMALL TSE -à CYR SMALL CHE -ù CYR SMALL SHA -ü CYR SMALL SCHA -ñ CYR SMALL HARD SIGN -ý CYR SMALL YERU -û CYR SMALL SOFT SIGN -ø CYR SMALL E -á CYR SMALL YU -ó CYR SMALL YA - CYR CAPIT A -× CYR CAPIT BE -Þ CYR CAPIT VE -Ú CYR CAPIT GE -Ä CYR CAPIT DE -Å CYR CAPIT IE -? CYR CAPIT IO -à CYR CAPIT ZHE -ß CYR CAPIT ZE -Ê CYR CAPIT I -Ì CYR CAPIT KA -Í CYR CAPIT EL -Î CYR CAPIT EM -Ï CYR CAPIT EN -Ð CYR CAPIT O -Ò CYR CAPIT PE -Ô CYR CAPIT ER -Õ CYR CAPIT ES -Æ CYR CAPIT TE -È CYR CAPIT U -Ö CYR CAPIT EF -É CYR CAPIT HA -Ç CYR CAPIT TSE -À CYR CAPIT CHE -Ù CYR CAPIT SHA -Ü CYR CAPIT SCHA -Ñ CYR CAPIT HARD SIGN -Ý CYR CAPIT YERU -Û CYR CAPIT SOFT SIGN -Ø CYR CAPIT E -Á CYR CAPIT YU -Ó CYR CAPIT YA -explain extended select CONVERT(koi8_ru_f, 'cp1251_general_ci', 'utf8_general_ci'), comment from t1; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 116 -Warnings: -Note 1003 select high_priority convert(test.t1.koi8_ru_f,_latin1'utf8_general_ci',_latin1'cp1251_general_ci') AS `CONVERT(koi8_ru_f, 'cp1251_general_ci', 'utf8_general_ci')`,test.t1.comment AS `comment` from test.t1 ALTER TABLE t1 ADD bin_f CHAR(32) BYTE NOT NULL; UPDATE t1 SET bin_f=koi8_ru_f; SELECT COUNT(DISTINCT bin_f),COUNT(DISTINCT koi8_ru_f),COUNT(DISTINCT utf8_f) FROM t1; diff --git a/mysql-test/r/ctype_mb.result b/mysql-test/r/ctype_mb.result index 288033e7530..edccb047c85 100644 --- a/mysql-test/r/ctype_mb.result +++ b/mysql-test/r/ctype_mb.result @@ -22,7 +22,7 @@ Warning 1264 Data truncated for column 'c2' at row 1 Warning 1264 Data truncated for column 'c3' at row 1 SELECT * FROM t1; c1 c2 c3 -aaaabbbbcccc aaaabbbbcccc aaaabbbbcccc +aaaa aaaa aaaa DROP TABLE t1; CREATE TABLE t1 (a CHAR(4) CHARACTER SET utf8, KEY key_a(a(3))); SHOW CREATE TABLE t1; diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index 571c89ef467..7209c86bb31 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -19,6 +19,12 @@ SELECT HEX(a) FROM t2; HEX(a) D0BFD180D0BED0B1D0B0 DROP TABLE t1, t2; +CREATE TABLE t1 (description text character set cp1250 NOT NULL); +INSERT INTO t1 (description) VALUES (_latin2'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssssssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddde'); +SELECT description FROM t1; +description +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssssssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddde +DROP TABLE t1; CREATE TABLE t1 (a TEXT CHARACTER SET cp1251) SELECT _koi8r'ÐÒÏÂÁ' AS a; CREATE TABLE t2 (a TEXT CHARACTER SET utf8); SHOW CREATE TABLE t1; diff --git a/mysql-test/r/ctype_tis620.result b/mysql-test/r/ctype_tis620.result new file mode 100644 index 00000000000..10164cd07ef --- /dev/null +++ b/mysql-test/r/ctype_tis620.result @@ -0,0 +1,113 @@ +drop table if exists t1; +SET @pl0= _tis620 0x000102030405060708090A0B0C0D0E0F; +SET @pl1= _tis620 0x101112131415161718191A1B1C1D1E1F; +SET @pl2= _tis620 0x202122232425262728292A2B2C2D2E2F; +SET @pl3= _tis620 0x303132333435363738393A3B3C3D3E3F; +SET @pl4= _tis620 0x404142434445464748494A4B4C4D4E4F; +SET @pl5= _tis620 0x505152535455565758595A5B5C5D5E5F; +SET @pl6= _tis620 0x606162636465666768696A6B6C6D6E6F; +SET @pl7= _tis620 0x707172737475767778797A7B7C7D7E7F; +SET @pl8= _tis620 0x808182838485868788898A8B8C8D8E8F; +SET @pl9= _tis620 0x909192939495969798999A9B9C9D9E9F; +SET @plA= _tis620 0xA0A1A2A3A4A5A6A7A8A9AAABACADAEAF; +SET @plB= _tis620 0xB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF; +SET @plC= _tis620 0xC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF; +SET @plD= _tis620 0xD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF; +SET @plE= _tis620 0xE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF; +SET @plF= _tis620 0xF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF; +SELECT hex(@u0:=convert(@pl0 using utf8)); +hex(@u0:=convert(@pl0 using utf8)) +000102030405060708090A0B0C0D0E0F +SELECT hex(@u1:=convert(@pl1 using utf8)); +hex(@u1:=convert(@pl1 using utf8)) +101112131415161718191A1B1C1D1E1F +SELECT hex(@u2:=convert(@pl2 using utf8)); +hex(@u2:=convert(@pl2 using utf8)) +202122232425262728292A2B2C2D2E2F +SELECT hex(@u3:=convert(@pl3 using utf8)); +hex(@u3:=convert(@pl3 using utf8)) +303132333435363738393A3B3C3D3E3F +SELECT hex(@u4:=convert(@pl4 using utf8)); +hex(@u4:=convert(@pl4 using utf8)) +404142434445464748494A4B4C4D4E4F +SELECT hex(@u5:=convert(@pl5 using utf8)); +hex(@u5:=convert(@pl5 using utf8)) +505152535455565758595A5B5C5D5E5F +SELECT hex(@u6:=convert(@pl6 using utf8)); +hex(@u6:=convert(@pl6 using utf8)) +606162636465666768696A6B6C6D6E6F +SELECT hex(@u7:=convert(@pl7 using utf8)); +hex(@u7:=convert(@pl7 using utf8)) +707172737475767778797A7B7C7D7E7F +SELECT hex(@u8:=convert(@pl8 using utf8)); +hex(@u8:=convert(@pl8 using utf8)) +C280C281C282C283C284C285C286C287C288C289C28AC28BC28CC28DC28EC28F +SELECT hex(@u9:=convert(@pl9 using utf8)); +hex(@u9:=convert(@pl9 using utf8)) +C290C291C292C293C294C295C296C297C298C299C29AC29BC29CC29DC29EC29F +SELECT hex(@uA:=convert(@plA using utf8)); +hex(@uA:=convert(@plA using utf8)) +EFBFBDE0B881E0B882E0B883E0B884E0B885E0B886E0B887E0B888E0B889E0B88AE0B88BE0B88CE0B88DE0B88EE0B88F +SELECT hex(@uB:=convert(@plB using utf8)); +hex(@uB:=convert(@plB using utf8)) +E0B890E0B891E0B892E0B893E0B894E0B895E0B896E0B897E0B898E0B899E0B89AE0B89BE0B89CE0B89DE0B89EE0B89F +SELECT hex(@uC:=convert(@plC using utf8)); +hex(@uC:=convert(@plC using utf8)) +E0B8A0E0B8A1E0B8A2E0B8A3E0B8A4E0B8A5E0B8A6E0B8A7E0B8A8E0B8A9E0B8AAE0B8ABE0B8ACE0B8ADE0B8AEE0B8AF +SELECT hex(@uD:=convert(@plD using utf8)); +hex(@uD:=convert(@plD using utf8)) +E0B8B0E0B8B1E0B8B2E0B8B3E0B8B4E0B8B5E0B8B6E0B8B7E0B8B8E0B8B9E0B8BAEFBFBDEFBFBDEFBFBDEFBFBDE0B8BF +SELECT hex(@uE:=convert(@plE using utf8)); +hex(@uE:=convert(@plE using utf8)) +E0B980E0B981E0B982E0B983E0B984E0B985E0B986E0B987E0B988E0B989E0B98AE0B98BE0B98CE0B98DE0B98EE0B98F +SELECT hex(@uF:=convert(@plF using utf8)); +hex(@uF:=convert(@plF using utf8)) +E0B990E0B991E0B992E0B993E0B994E0B995E0B996E0B997E0B998E0B999E0B99AE0B99BEFBFBDEFBFBDEFBFBDEFBFBD +SELECT hex(convert(@u0 USING tis620)); +hex(convert(@u0 USING tis620)) +000102030405060708090A0B0C0D0E0F +SELECT hex(convert(@u1 USING tis620)); +hex(convert(@u1 USING tis620)) +101112131415161718191A1B1C1D1E1F +SELECT hex(convert(@u2 USING tis620)); +hex(convert(@u2 USING tis620)) +202122232425262728292A2B2C2D2E2F +SELECT hex(convert(@u3 USING tis620)); +hex(convert(@u3 USING tis620)) +303132333435363738393A3B3C3D3E3F +SELECT hex(convert(@u4 USING tis620)); +hex(convert(@u4 USING tis620)) +404142434445464748494A4B4C4D4E4F +SELECT hex(convert(@u5 USING tis620)); +hex(convert(@u5 USING tis620)) +505152535455565758595A5B5C5D5E5F +SELECT hex(convert(@u6 USING tis620)); +hex(convert(@u6 USING tis620)) +606162636465666768696A6B6C6D6E6F +SELECT hex(convert(@u7 USING tis620)); +hex(convert(@u7 USING tis620)) +707172737475767778797A7B7C7D7E7F +SELECT hex(convert(@u8 USING tis620)); +hex(convert(@u8 USING tis620)) +808182838485868788898A8B8C8D8E8F +SELECT hex(convert(@u9 USING tis620)); +hex(convert(@u9 USING tis620)) +909192939495969798999A9B9C9D9E9F +SELECT hex(convert(@uA USING tis620)); +hex(convert(@uA USING tis620)) +FFA1A2A3A4A5A6A7A8A9AAABACADAEAF +SELECT hex(convert(@uB USING tis620)); +hex(convert(@uB USING tis620)) +B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF +SELECT hex(convert(@uC USING tis620)); +hex(convert(@uC USING tis620)) +C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF +SELECT hex(convert(@uD USING tis620)); +hex(convert(@uD USING tis620)) +D0D1D2D3D4D5D6D7D8D9DAFFFFFFFFDF +SELECT hex(convert(@uE USING tis620)); +hex(convert(@uE USING tis620)) +E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF +SELECT hex(convert(@uF USING tis620)); +hex(convert(@uF USING tis620)) +F0F1F2F3F4F5F6F7F8F9FAFBFFFFFFFF diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 2f6dc0c23ca..30795aaf106 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -77,6 +77,9 @@ a test select * from t1 where a like "%a%"; a +a +abc +abcd select * from t1 where a like "%abcd%"; a abcd @@ -84,6 +87,78 @@ select * from t1 where a like "%abc\d%"; a abcd drop table t1; +select 'AA' like 'AA'; +'AA' like 'AA' +1 +select 'AA' like 'A%A'; +'AA' like 'A%A' +1 +select 'AA' like 'A%%A'; +'AA' like 'A%%A' +1 +select 'AA' like 'AA%'; +'AA' like 'AA%' +1 +select 'AA' like '%AA%'; +'AA' like '%AA%' +1 +select 'AA' like '%A'; +'AA' like '%A' +1 +select 'AA' like '%AA'; +'AA' like '%AA' +1 +select 'AA' like 'A%A%'; +'AA' like 'A%A%' +1 +select 'AA' like '_%_%'; +'AA' like '_%_%' +1 +select 'AA' like '%A%A'; +'AA' like '%A%A' +1 +select 'AAA'like 'A%A%A'; +'AAA'like 'A%A%A' +1 +select 'AZ' like 'AZ'; +'AZ' like 'AZ' +1 +select 'AZ' like 'A%Z'; +'AZ' like 'A%Z' +1 +select 'AZ' like 'A%%Z'; +'AZ' like 'A%%Z' +1 +select 'AZ' like 'AZ%'; +'AZ' like 'AZ%' +1 +select 'AZ' like '%AZ%'; +'AZ' like '%AZ%' +1 +select 'AZ' like '%Z'; +'AZ' like '%Z' +1 +select 'AZ' like '%AZ'; +'AZ' like '%AZ' +1 +select 'AZ' like 'A%Z%'; +'AZ' like 'A%Z%' +1 +select 'AZ' like '_%_%'; +'AZ' like '_%_%' +1 +select 'AZ' like '%A%Z'; +'AZ' like '%A%Z' +1 +select 'AZ' like 'A_'; +'AZ' like 'A_' +1 +select 'AZ' like '_Z'; +'AZ' like '_Z' +1 +select 'AMZ'like 'A%M%Z'; +'AMZ'like 'A%M%Z' +1 CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET ucs2); INSERT INTO t1 VALUES ('ÆÙ×Á'),('æÙ×Á'),('Æù×Á'),('ÆÙ÷Á'),('ÆÙ×á'),('æù÷á'); INSERT INTO t1 VALUES ('ÆÙ×ÁÐÒÏÌÄÖ'),('æÙ×ÁÐÒÏÌÄÖ'),('Æù×ÁÐÒÏÌÄÖ'),('ÆÙ÷ÁÐÒÏÌÄÖ'); @@ -173,6 +248,12 @@ SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630061005F'; word cat DROP TABLE t1; +select insert(_ucs2 0x006100620063,10,2,_ucs2 0x006400650066); +insert(_ucs2 0x006100620063,10,2,_ucs2 0x006400650066) +abc +select insert(_ucs2 0x006100620063,1,2,_ucs2 0x006400650066); +insert(_ucs2 0x006100620063,1,2,_ucs2 0x006400650066) +defc SET NAMES latin1; CREATE TABLE t1 ( word VARCHAR(64), @@ -270,3 +351,107 @@ aardvara aardvark aardvarz DROP TABLE t1; +SELECT HEX(_ucs2 0x0); +HEX(_ucs2 0x0) +0000 +SELECT HEX(_ucs2 0x01); +HEX(_ucs2 0x01) +0001 +SELECT HEX(_ucs2 0x012); +HEX(_ucs2 0x012) +0012 +SELECT HEX(_ucs2 0x0123); +HEX(_ucs2 0x0123) +0123 +SELECT HEX(_ucs2 0x01234); +HEX(_ucs2 0x01234) +00001234 +SELECT HEX(_ucs2 0x012345); +HEX(_ucs2 0x012345) +00012345 +SELECT HEX(_ucs2 0x0123456); +HEX(_ucs2 0x0123456) +00123456 +SELECT HEX(_ucs2 0x01234567); +HEX(_ucs2 0x01234567) +01234567 +SELECT HEX(_ucs2 0x012345678); +HEX(_ucs2 0x012345678) +000012345678 +SELECT HEX(_ucs2 0x0123456789); +HEX(_ucs2 0x0123456789) +000123456789 +SELECT HEX(_ucs2 0x0123456789A); +HEX(_ucs2 0x0123456789A) +00123456789A +SELECT HEX(_ucs2 0x0123456789AB); +HEX(_ucs2 0x0123456789AB) +0123456789AB +SELECT HEX(_ucs2 0x0123456789ABC); +HEX(_ucs2 0x0123456789ABC) +0000123456789ABC +SELECT HEX(_ucs2 0x0123456789ABCD); +HEX(_ucs2 0x0123456789ABCD) +000123456789ABCD +SELECT HEX(_ucs2 0x0123456789ABCDE); +HEX(_ucs2 0x0123456789ABCDE) +00123456789ABCDE +SELECT HEX(_ucs2 0x0123456789ABCDEF); +HEX(_ucs2 0x0123456789ABCDEF) +0123456789ABCDEF +SELECT hex(cast(0xAA as char character set ucs2)); +hex(cast(0xAA as char character set ucs2)) +00AA +SELECT hex(convert(0xAA using ucs2)); +hex(convert(0xAA using ucs2)) +00AA +CREATE TABLE t1 (a char(10) character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +HEX(a) +000A +00AA +0AAA +AAAA +000AAAAA +DROP TABLE t1; +CREATE TABLE t1 (a varchar(10) character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +HEX(a) +000A +00AA +0AAA +AAAA +000AAAAA +DROP TABLE t1; +CREATE TABLE t1 (a text character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +HEX(a) +000A +00AA +0AAA +AAAA +000AAAAA +DROP TABLE t1; +CREATE TABLE t1 (a mediumtext character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +HEX(a) +000A +00AA +0AAA +AAAA +000AAAAA +DROP TABLE t1; +CREATE TABLE t1 (a longtext character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +HEX(a) +000A +00AA +0AAA +AAAA +000AAAAA +DROP TABLE t1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 1aef43cd570..8b7178993a7 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1,3 +1,4 @@ +drop table if exists t1; set names utf8; select left(_utf8 0xD0B0D0B1D0B2,1); left(_utf8 0xD0B0D0B1D0B2,1) @@ -62,3 +63,109 @@ select 'A' like 'a' collate utf8_bin; select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%'); _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%') 1 +select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es'); +insert('txs',2,1,'hi') insert('is ',4,0,'a') insert('txxxxt',2,4,'es') +this is a test +select insert("aa",100,1,"b"),insert("aa",1,3,"b"); +insert("aa",100,1,"b") insert("aa",1,3,"b") +aa b +create table t1 select date_format("2004-01-19 10:10:10", "%Y-%m-%d"); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `date_format("2004-01-19 10:10:10", "%Y-%m-%d")` char(10) binary default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from t1; +date_format("2004-01-19 10:10:10", "%Y-%m-%d") +2004-01-19 +drop table t1; +set names koi8r; +create table t1 (s1 char(1) character set utf8); +insert into t1 values (_koi8r'ÁÂ'); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +select s1,hex(s1),char_length(s1),octet_length(s1) from t1; +s1 hex(s1) char_length(s1) octet_length(s1) +Á D0B0 1 2 +drop table t1; +create table t1 (s1 tinytext character set utf8); +insert into t1 select repeat('a',300); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +insert into t1 select repeat('Ñ',300); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +insert into t1 select repeat('aÑ',300); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +insert into t1 select repeat('Ña',300); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +insert into t1 select repeat('ÑÑ',300); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +select hex(s1) from t1; +hex(s1) +616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 +D18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18F +61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F +D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61 +D18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18F +select length(s1),char_length(s1) from t1; +length(s1) char_length(s1) +255 255 +254 127 +255 170 +255 170 +254 127 +drop table t1; +create table t1 (s1 text character set utf8); +insert into t1 select repeat('a',66000); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +insert into t1 select repeat('Ñ',66000); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +insert into t1 select repeat('aÑ',66000); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +insert into t1 select repeat('Ña',66000); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +insert into t1 select repeat('ÑÑ',66000); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +select length(s1),char_length(s1) from t1; +length(s1) char_length(s1) +65535 65535 +65534 32767 +65535 43690 +65535 43690 +65534 32767 +drop table t1; +create table t1 (s1 char(10) character set utf8); +insert into t1 values (0x41FF); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +select hex(s1) from t1; +hex(s1) +41 +drop table t1; +create table t1 (s1 varchar(10) character set utf8); +insert into t1 values (0x41FF); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +select hex(s1) from t1; +hex(s1) +41 +drop table t1; +create table t1 (s1 text character set utf8); +insert into t1 values (0x41FF); +Warnings: +Warning 1264 Data truncated for column 's1' at row 1 +select hex(s1) from t1; +hex(s1) +41 +drop table t1; +create table t1 (a char(160) character set utf8, primary key(a)); +ERROR HY000: Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the storage engine doesn't support unique sub keys diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index ee4fa074477..165a8d7011c 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -1,6 +1,4 @@ drop table if exists t1; -Warnings: -Note 1051 Unknown table 't1' SHOW GLOBAL VARIABLES LIKE "%_format%"; Variable_name Value date_format %d.%m.%Y diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index bb268cd1094..049d88c5154 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -59,7 +59,7 @@ explain select * from t1 as x1, (select * from t1) as x2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY x1 ALL NULL NULL NULL NULL 4 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 -2 DERIVED x1 ALL NULL NULL NULL NULL 4 +2 DERIVED t1 ALL NULL NULL NULL NULL 4 drop table if exists t2,t3; select * from (select 1) as a; 1 @@ -85,6 +85,10 @@ a b 2 b 3 c 3 c +select * from (select * from t1 union all select * from t1 limit 2) a; +a b +1 a +2 b explain select * from (select * from t1 union select * from t1) a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 @@ -137,7 +141,7 @@ a t explain select count(*) from t1 as tt1, (select * from t1) as tt2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away -2 DERIVED tt1 ALL NULL NULL NULL NULL 10000 +2 DERIVED t1 ALL NULL NULL NULL NULL 10000 drop table t1; SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b; (SELECT * FROM (SELECT 1 as a) as a ) @@ -185,13 +189,13 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY m2 ALL NULL NULL NULL NULL 9 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort -2 DERIVED m2 index NULL PRIMARY 3 NULL 9 Using index +2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1 explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY m2 ALL NULL NULL NULL NULL 9 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort -2 DERIVED m2 index NULL PRIMARY 3 NULL 9 Using index +2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1 drop table t1,t2; SELECT a.x FROM (SELECT 1 AS x) AS a HAVING a.x = 1; x @@ -209,7 +213,7 @@ ERROR 42000: You have an error in your SQL syntax. Check the manual that corres create table t1 (a int); insert into t1 values (1),(2),(3); update (select * from t1) as t1 set a = 5; -ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use +ERROR HY000: The target table t1 of the UPDATE is not updatable. delete from (select * from t1); ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(select * from t1)' at line 1 insert into (select * from t1) values (5); @@ -225,7 +229,7 @@ explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 THEMAX.E2 1 Using where -2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using where +2 DERIVED A ALL NULL NULL NULL NULL 2 Using where 3 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 2 Using where drop table t1; create table t1 (a int); @@ -245,3 +249,74 @@ id select_type table type possible_keys key key_len ref rows Extra 2 DERIVED t1 ALL NULL NULL NULL NULL 2 3 UNION t1 ALL NULL NULL NULL NULL 2 drop table t1; +CREATE TABLE `t1` ( +`N` int(11) unsigned NOT NULL default '0', +`M` tinyint(1) default '0', +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO `t1` (N, M) VALUES (1, 0),(1, 0),(1, 0),(2, 0),(2, 0),(3, 0); +UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2; +select * from t1; +N M +1 2 +1 2 +1 2 +2 2 +2 2 +3 0 +UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2, P2.N = 2; +ERROR HY000: The target table P2 of the UPDATE is not updatable. +UPDATE `t1` AS P1 INNER JOIN (SELECT aaaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2; +ERROR 42S22: Unknown column 'aaaa' in 'field list' +delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N; +select * from t1; +N M +3 0 +delete P1.*,P2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N; +ERROR HY000: The target table P2 of the DELETE is not updatable. +delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N; +ERROR 42S22: Unknown column 'aaa' in 'field list' +drop table t1; +CREATE TABLE t1 ( +OBJECTID int(11) NOT NULL default '0', +SORTORDER int(11) NOT NULL auto_increment, +KEY t1_SortIndex (SORTORDER), +KEY t1_IdIndex (OBJECTID) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +CREATE TABLE t2 ( +ID int(11) default NULL, +PARID int(11) default NULL, +UNIQUE KEY t2_ID_IDX (ID), +KEY t2_PARID_IDX (PARID) +) engine=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (1000,0),(1001,0),(1002,0),(1003,0),(1008,1),(1009,1),(1010,1),(1011,1),(1016,2); +CREATE TABLE t3 ( +ID int(11) default NULL, +DATA decimal(10,2) default NULL, +UNIQUE KEY t3_ID_IDX (ID) +) engine=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t3 VALUES (1000,0.00),(1001,0.25),(1002,0.50),(1003,0.75),(1008,1.00),(1009,1.25),(1010,1.50),(1011,1.75); +select 497, TMP.ID, NULL from (select 497 as ID, MAX(t3.DATA) as DATA from t1 join t2 on (t1.ObjectID = t2.ID) join t3 on (t1.ObjectID = t3.ID) group by t2.ParID order by DATA DESC) as TMP; +497 ID NULL +drop table t1, t2, t3; +CREATE TABLE t1 (name char(1) default NULL, val int(5) default NULL); +INSERT INTO t1 VALUES ('a',1), ('a',2), ('a',2), ('a',2), ('a',3), ('a',6), ('a',7), ('a',11), ('a',11), ('a',12), ('a',13), ('a',13), ('a',20), ('b',2), ('b',3), ('b',4), ('b',5); +SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x, t1 y WHERE x.name=y.name GROUP BY x.name, x.val HAVING SUM(y.val <= x.val) >= COUNT(*)/2 AND SUM(y.val >= x.val) >= COUNT(*)/2) AS s GROUP BY s.name; +name median +a 7.0000 +b 3.5000 +explain SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x, t1 y WHERE x.name=y.name GROUP BY x.name, x.val HAVING SUM(y.val <= x.val) >= COUNT(*)/2 AND SUM(y.val >= x.val) >= COUNT(*)/2) AS s GROUP BY s.name; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort +2 DERIVED x ALL NULL NULL NULL NULL 17 Using temporary; Using filesort +2 DERIVED y ALL NULL NULL NULL NULL 17 Using where +drop table t1; +create table t2 (a int, b int, primary key (a)); +insert into t2 values (1,7),(2,7); +explain select a from t2 where a>1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index +explain select a from (select a from t2 where a>1) tt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> system NULL NULL NULL NULL 1 +2 DERIVED t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index +drop table t2; diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result index cf07ba88477..085e2f2f37e 100644 --- a/mysql-test/r/func_like.result +++ b/mysql-test/r/func_like.result @@ -104,3 +104,33 @@ a ÆÙ×ÁÐÒÏÌÄö æù÷áðòïìäö DROP TABLE t1; +SET NAMES cp1250; +CREATE TABLE t1 (a varchar(250) NOT NULL) DEFAULT CHARACTER SET=cp1250; +INSERT INTO t1 VALUES +('Techni Tapes Sp. z o.o.'), +('Pojazdy Szynowe PESA Bydgoszcz SA Holding'), +('AKAPESTER 1 P.P.H.U.'), +('Pojazdy Szynowe PESA Bydgoszcz S A Holding'), +('PPUH PESKA-I Maria Struniarska'); +select * from t1 where a like '%PESA%'; +a +Pojazdy Szynowe PESA Bydgoszcz SA Holding +Pojazdy Szynowe PESA Bydgoszcz S A Holding +select * from t1 where a like '%PESA %'; +a +Pojazdy Szynowe PESA Bydgoszcz SA Holding +Pojazdy Szynowe PESA Bydgoszcz S A Holding +select * from t1 where a like '%PES%'; +a +Techni Tapes Sp. z o.o. +Pojazdy Szynowe PESA Bydgoszcz SA Holding +AKAPESTER 1 P.P.H.U. +Pojazdy Szynowe PESA Bydgoszcz S A Holding +PPUH PESKA-I Maria Struniarska +select * from t1 where a like '%PESKA%'; +a +PPUH PESKA-I Maria Struniarska +select * from t1 where a like '%ESKA%'; +a +PPUH PESKA-I Maria Struniarska +DROP TABLE t1; diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index d51bea020ed..ec5f76409e7 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -6,10 +6,19 @@ inet_ntoa(inet_aton("255.255.255.255.255.255.255.255")) NULL select inet_aton("255.255.255.255.255"),inet_aton("255.255.1.255"),inet_aton("0.1.255"); inet_aton("255.255.255.255.255") inet_aton("255.255.1.255") inet_aton("0.1.255") -1099511627775 4294902271 511 +1099511627775 4294902271 65791 select inet_ntoa(1099511627775),inet_ntoa(4294902271),inet_ntoa(511); inet_ntoa(1099511627775) inet_ntoa(4294902271) inet_ntoa(511) NULL 255.255.1.255 0.0.1.255 +select hex(inet_aton('127')); +hex(inet_aton('127')) +7F +select hex(inet_aton('127.1')); +hex(inet_aton('127.1')) +7F000001 +select hex(inet_aton('127.1.1')); +hex(inet_aton('127.1.1')) +7F010001 select length(format('nan', 2)) > 0; length(format('nan', 2)) > 0 1 diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index c74feccfb7f..f08ae1b1efd 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -605,3 +605,6 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select high_priority md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,(_latin1'HE' collate _latin1'BINARY') AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate _latin1'latin1_bin'),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substr_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")` +SELECT lpad(12345, 5, "#"); +lpad(12345, 5, "#") +12345 diff --git a/mysql-test/r/func_system.result b/mysql-test/r/func_system.result index a0437ca1c56..338902e3f3a 100644 --- a/mysql-test/r/func_system.result +++ b/mysql-test/r/func_system.result @@ -51,6 +51,20 @@ t1 CREATE TABLE `t1` ( `version` char(40) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +select charset(charset(_utf8'a')), charset(collation(_utf8'a')); +charset(charset(_utf8'a')) charset(collation(_utf8'a')) +utf8 utf8 +select collation(charset(_utf8'a')), collation(collation(_utf8'a')); +collation(charset(_utf8'a')) collation(collation(_utf8'a')) +utf8_general_ci utf8_general_ci +create table t1 select charset(_utf8'a'), collation(_utf8'a'); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `charset(_utf8'a')` char(64) character set utf8 NOT NULL default '', + `collation(_utf8'a')` char(64) character set utf8 NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; select TRUE,FALSE,NULL; TRUE FALSE NULL 1 0 NULL diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result index 6edc4a5485d..95f39fc705e 100644 --- a/mysql-test/r/func_test.result +++ b/mysql-test/r/func_test.result @@ -165,3 +165,9 @@ SELECT f_acc.rank, a1.rank, a2.rank FROM t1 LEFT JOIN t1 f1 ON (f1.access_id=1 rank rank rank 2 2 NULL DROP TABLE t1,t2; +CREATE TABLE t1 (d varchar(6), k int); +INSERT INTO t1 VALUES (NULL, 2); +SELECT GREATEST(d,d) FROM t1 WHERE k=2; +GREATEST(d,d) +NULL +DROP TABLE t1; diff --git a/mysql-test/r/have_big5.require b/mysql-test/r/have_big5.require new file mode 100644 index 00000000000..74aacf74b62 --- /dev/null +++ b/mysql-test/r/have_big5.require @@ -0,0 +1,2 @@ +Collation Charset Id Default Compiled Sortlen +big5_chinese_ci big5 1 Yes Yes 1 diff --git a/mysql-test/r/have_tis620.require b/mysql-test/r/have_tis620.require new file mode 100644 index 00000000000..a1bf93ac491 --- /dev/null +++ b/mysql-test/r/have_tis620.require @@ -0,0 +1,2 @@ +Collation Charset Id Default Compiled Sortlen +tis620_thai_ci tis620 18 Yes Yes 4 diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index af3cf956222..b83a226776d 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -100,7 +100,7 @@ p i a 4 3 zzzz update t1 set p=2 where p=1; update t2 set i=2 where i=1; -cache index t1 keys (`primary`) in keycache1; +cache index t1 key (`primary`) in keycache1; Table Op Msg_type Msg_text test.t1 assign_to_keycache status OK explain select p from t1; @@ -177,7 +177,7 @@ yyyy zzzz cache index t1 in unknown_key_cache; ERROR HY000: Unknown key cache 'unknown_key_cache' -cache index t1 keys (unknown_key) in keycache1; +cache index t1 key (unknown_key) in keycache1; Table Op Msg_type Msg_text test.t1 assign_to_keycache error Key column 'unknown_key' doesn't exist in table test.t1 assign_to_keycache status Operation failed diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 5979a946b51..be09044f96f 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -244,7 +244,7 @@ select * from t2; n d 1 30 1 30 -DELETE t1, t2 FROM t1 a,t2 b where a.n=b.n; +DELETE a, b FROM t1 a,t2 b where a.n=b.n; select * from t1; n d 3 2 diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 04effdfef7c..0e642f48f3c 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -21,17 +21,22 @@ DROP TABLE t1; CREATE TABLE t1 (a decimal(240, 20)); INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), ("0987654321098765432109876543210987654321"); -DROP TABLE IF EXISTS t1; -CREATE TABLE t1 ( - a decimal(240,20) default NULL + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` decimal(240,20) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40000 ALTER TABLE t1 DISABLE KEYS */; -LOCK TABLES t1 WRITE; -INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890.00000000000000000000"),("0987654321098765432109876543210987654321.00000000000000000000"); +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES ("1234567890123456789012345678901234567890.00000000000000000000"),("0987654321098765432109876543210987654321.00000000000000000000"); UNLOCK TABLES; -/*!40000 ALTER TABLE t1 ENABLE KEYS */; +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; @@ -41,17 +46,22 @@ UNLOCK TABLES; DROP TABLE t1; CREATE TABLE t1 (a double); INSERT INTO t1 VALUES (-9e999999); -DROP TABLE IF EXISTS t1; -CREATE TABLE t1 ( - a double default NULL + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` double default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40000 ALTER TABLE t1 DISABLE KEYS */; -LOCK TABLES t1 WRITE; -INSERT INTO t1 VALUES (RES); +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES (RES); UNLOCK TABLES; -/*!40000 ALTER TABLE t1 ENABLE KEYS */; +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; @@ -105,17 +115,22 @@ INSERT INTO t1 VALUES ("1\""), ("\"2"); DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'); -DROP TABLE IF EXISTS t1; -CREATE TABLE t1 ( - a varchar(255) default NULL + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` varchar(255) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=koi8r; -/*!40000 ALTER TABLE t1 DISABLE KEYS */; -LOCK TABLES t1 WRITE; -INSERT INTO t1 VALUES ('абцде'); +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES ('абцде'); UNLOCK TABLES; -/*!40000 ALTER TABLE t1 ENABLE KEYS */; +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; @@ -123,3 +138,67 @@ UNLOCK TABLES; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; DROP TABLE t1; +CREATE TABLE t1 (a int) ENGINE=MYISAM; +INSERT INTO t1 VALUES (1), (2); +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` int(11) default NULL +) TYPE=MyISAM; + + +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES (1),(2); +UNLOCK TABLES; +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; + +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` int(11) default NULL +) TYPE=MyISAM; + + +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES (1),(2); +UNLOCK TABLES; +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; + +DROP TABLE t1; +create table ```a` (i int); + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; +DROP TABLE IF EXISTS ```a`; +CREATE TABLE ```a` ( + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + + +/*!40000 ALTER TABLE ```a` DISABLE KEYS */; +LOCK TABLES ```a` WRITE; +UNLOCK TABLES; +/*!40000 ALTER TABLE ```a` ENABLE KEYS */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; + +drop table ```a`; diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index c4af221e117..aa56bce6453 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -153,3 +153,6 @@ explain select * from t1 where a between 2 and 3 or b is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range idx idx 4 NULL 2 Using where drop table t1; +select cast(NULL as signed); +cast(NULL as signed) +NULL diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 4d166a961f3..c1053087603 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -590,3 +590,24 @@ SELECT id FROM t1 WHERE id <11984 AND menu =2 ORDER BY id DESC LIMIT 1 ; id 11392 drop table t1; +create table t1(a int, b int, index(b)); +insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2); +explain select * from t1 where b=1 or b is null order by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref_or_null b b 5 const 3 Using where; Using filesort +select * from t1 where b=1 or b is null order by a; +a b +1 1 +2 1 +3 NULL +4 NULL +explain select * from t1 where b=2 or b is null order by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref_or_null b b 5 const 4 Using where; Using filesort +select * from t1 where b=2 or b is null order by a; +a b +3 NULL +4 NULL +5 2 +6 2 +drop table t1; diff --git a/mysql-test/r/preload.result b/mysql-test/r/preload.result index bd7b828d5b9..f0b99a8d6f1 100644 --- a/mysql-test/r/preload.result +++ b/mysql-test/r/preload.result @@ -117,7 +117,7 @@ set session preload_buffer_size=1*1024; select @@preload_buffer_size; @@preload_buffer_size 1024 -load index into cache t1, t2 keys (primary,b) ignore leaves; +load index into cache t1, t2 key (primary,b) ignore leaves; Table Op Msg_type Msg_text test.t1 preload_keys status OK test.t2 preload_keys status OK @@ -141,7 +141,7 @@ show status like "key_read%"; Variable_name Value Key_read_requests 0 Key_reads 0 -load index into cache t3, t2 keys (primary,b) ; +load index into cache t3, t2 key (primary,b) ; Table Op Msg_type Msg_text test.t3 preload_keys error Table 'test.t3' doesn't exist test.t2 preload_keys status OK @@ -155,7 +155,7 @@ show status like "key_read%"; Variable_name Value Key_read_requests 0 Key_reads 0 -load index into cache t3 keys (b), t2 keys (c) ; +load index into cache t3 key (b), t2 key (c) ; Table Op Msg_type Msg_text test.t3 preload_keys error Table 'test.t3' doesn't exist test.t2 preload_keys error Key column 'c' doesn't exist in table diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 60a6fac6458..c1d73f20e34 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -696,17 +696,22 @@ word show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 1 -load data infile '../../std_data/words.dat' into table t1; +load data infile 'TEST_DIR/std_data/words.dat' into table t1; show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 +select count(*) from t1; +count(*) +70 drop table t1; create table t1 (a int); insert into t1 values (1),(2),(3); show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 -select * from t1 into outfile "query_caceh.out.file"; +select * from t1 into outfile "query_cache.out.file"; +select * from t1 into outfile "query_cache.out.file"; +ERROR HY000: File 'query_cache.out.file' already exists select * from t1 limit 1 into dumpfile "query_cache.dump.file"; show status like "Qcache_queries_in_cache"; Variable_name Value @@ -815,14 +820,22 @@ Qcache_hits 6 show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 4 -drop table t1; +DROP TABLE t1; +CREATE TABLE t1 (a int(1)); +CREATE DATABASE mysqltest; +USE mysqltest; +DROP DATABASE mysqltest; +SELECT * FROM test.t1; +a +USE test; +DROP TABLE t1; create table t1 (a int); show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 8 +Qcache_inserts 9 show status like "Qcache_hits"; Variable_name Value Qcache_hits 6 @@ -835,7 +848,7 @@ Variable_name Value Qcache_queries_in_cache 1 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 9 +Qcache_inserts 10 show status like "Qcache_hits"; Variable_name Value Qcache_hits 7 diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result index 17b505487e9..b6c525e0e9c 100644 --- a/mysql-test/r/rpl_until.result +++ b/mysql-test/r/rpl_until.result @@ -31,7 +31,7 @@ n 4 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 731 slave-relay-bin.000004 439 master-bin.000001 Yes No 0 0 304 866 Master master-bin.000001 304 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 731 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 304 # Master master-bin.000001 304 No # start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; select * from t1; n diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 8ac880982fb..3fa700ccf26 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -88,20 +88,37 @@ drop table t2; create table t1 ( test_set set( 'val1', 'val2', 'val3' ) not null default '', name char(20) default 'O''Brien' comment 'O''Brien as default', -c int not null comment 'int column' - ) comment = 'it\'s a table' ; -show create table t1 ; +c int not null comment 'int column', +`c-b` int comment 'name with a space', +`space ` int comment 'name with a space', +) comment = 'it\'s a table' ; +show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `test_set` set('val1','val2','val3') NOT NULL default '', `name` char(20) default 'O''Brien' COMMENT 'O''Brien as default', - `c` int(11) NOT NULL default '0' COMMENT 'int column' + `c` int(11) NOT NULL default '0' COMMENT 'int column', + `c-b` int(11) default NULL COMMENT 'name with a space', + `space ` int(11) default NULL COMMENT 'name with a space' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='it''s a table' +set sql_quote_show_create=0; +show create table t1; +Table Create Table +t1 CREATE TABLE t1 ( + test_set set('val1','val2','val3') NOT NULL default '', + `name` char(20) default 'O''Brien' COMMENT 'O''Brien as default', + c int(11) NOT NULL default '0' COMMENT 'int column', + `c-b` int(11) default NULL COMMENT 'name with a space', + `space ` int(11) default NULL COMMENT 'name with a space' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='it''s a table' +set sql_quote_show_create=1; show full columns from t1; Field Type Collation Null Key Default Extra Privileges Comment test_set set('val1','val2','val3') latin1_swedish_ci select,insert,update,references name char(20) latin1_swedish_ci YES O'Brien select,insert,update,references O'Brien as default c int(11) NULL 0 select,insert,update,references int column +c-b int(11) NULL YES NULL select,insert,update,references name with a space +space int(11) NULL YES NULL select,insert,update,references name with a space drop table t1; create table t1 (a int not null, unique aa (a)); show create table t1; @@ -249,3 +266,51 @@ c decimal(4,3) YES NULL d double(4,3) YES NULL f float(4,3) YES NULL drop table t1; +SET sql_mode=''; +SET sql_quote_show_create=OFF; +CREATE TABLE ```ab``cd``` (i INT); +SHOW CREATE TABLE ```ab``cd```; +Table Create Table +`ab`cd` CREATE TABLE ```ab``cd``` ( + i int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE ```ab``cd```; +CREATE TABLE ```ab````cd``` (i INT); +SHOW CREATE TABLE ```ab````cd```; +Table Create Table +`ab``cd` CREATE TABLE ```ab````cd``` ( + i int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE ```ab````cd```; +CREATE TABLE ```a` (i INT); +SHOW CREATE TABLE ```a`; +Table Create Table +`a CREATE TABLE ```a` ( + i int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE ```a`; +SET sql_mode='ANSI_QUOTES'; +CREATE TABLE """a" (i INT); +SHOW CREATE TABLE """a"; +Table Create Table +"a CREATE TABLE """a" ( + i int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE """a"; +SET sql_mode=''; +SET sql_quote_show_create=OFF; +CREATE TABLE t1 (i INT); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE t1 ( + i int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE `table` (i INT); +SHOW CREATE TABLE `table`; +Table Create Table +table CREATE TABLE `table` ( + i int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE `table`; +SET sql_quote_show_create=ON; diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 07835201acb..f965cf90eb4 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -35,7 +35,7 @@ call foo()| ERROR 42000: PROCEDURE foo does not exist drop procedure if exists foo| Warnings: -Warning 1289 PROCEDURE foo does not exist +Warning 1292 PROCEDURE foo does not exist show create procedure foo| ERROR 42000: PROCEDURE foo does not exist create procedure foo() @@ -71,7 +71,7 @@ declare y int; set x = y; end| Warnings: -Warning 1295 Referring to uninitialized variable y +Warning 1298 Referring to uninitialized variable y drop procedure foo| create procedure foo() return 42| diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index f77f0787f20..bf515e4b4cd 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -968,6 +968,27 @@ drop procedure bug2267_1| drop procedure bug2267_2| drop procedure bug2267_3| drop procedure bug2267_4| +create procedure bug2227(x int) +begin +declare y float default 2.6; +declare z char(16) default "zzz"; +select 1.3, x, y, 42, z; +end| +call bug2227(9)| +1.3 x y 42 z +1.3 9 2.6 42 zzz +drop procedure bug2227| +create procedure bug2614() +begin +drop table if exists t3; +create table t3 (id int default '0' not null); +insert into t3 select 12; +insert into t3 select * from t3; +end| +call bug2614()| +call bug2614()| +drop table t3| +drop procedure bug2614| drop table if exists fac| create table fac (n int unsigned not null primary key, f bigint unsigned)| create procedure ifac(n int unsigned) diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index ddc848af1ed..77fe5d06bb0 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -70,7 +70,7 @@ t1 CREATE TABLE `t1` ( `email` varchar(60) NOT NULL default '', PRIMARY KEY (`a`), UNIQUE KEY `email` (`email`) -) ENGINE=HEAP ROW_FORMAT=DYNAMIC +) TYPE=HEAP ROW_FORMAT=DYNAMIC set sql_mode="postgresql,oracle,mssql,db2,maxdb"; select @@sql_mode; @@sql_mode diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 3a2de4035eb..19722ddaa69 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1577,3 +1577,37 @@ INSERT INTO t2 VALUES (100, 200, 'C'); SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1); COLC DROP TABLE t1, t2; +create table t1 (a int, b decimal(13, 3)); +insert into t1 values (1, 0.123); +select a, (select max(b) from t1) into outfile "subselect.out.file.1" from t1; +delete from t1; +load data infile "subselect.out.file.1" into table t1; +select * from t1; +a b +1 0.123 +drop table t1; +CREATE TABLE `t1` ( +`id` int(11) NOT NULL auto_increment, +`id_cns` tinyint(3) unsigned NOT NULL default '0', +`tipo` enum('','UNO','DUE') NOT NULL default '', +`anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000', +`particolare` mediumint(8) unsigned NOT NULL default '0', +`generale` mediumint(8) unsigned NOT NULL default '0', +`bis` tinyint(3) unsigned NOT NULL default '0', +PRIMARY KEY (`id`), +UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`), +UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`) +); +INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0); +CREATE TABLE `t2` ( +`id` tinyint(3) unsigned NOT NULL auto_increment, +`max_anno_dep` smallint(6) unsigned NOT NULL default '0', +PRIMARY KEY (`id`) +); +INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990); +SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns; +id max_anno_dep PIPPO +16 1987 1 +50 1990 0 +51 1990 NULL +DROP TABLE t1, t2; diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result index 6729916f1c8..b2a055fa72c 100644 --- a/mysql-test/r/subselect_innodb.result +++ b/mysql-test/r/subselect_innodb.result @@ -60,6 +60,39 @@ INSERT INTO t2 VALUES (1,1),(2,2),(3,3); SELECT distinct p1.processor_id, (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id) FROM t1 p1; processor_id (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id) 1 1 -2 1 -3 1 +2 2 +3 3 drop table t1,t2,t3; +CREATE TABLE t1 ( +id int(11) NOT NULL default '0', +b int(11) default NULL, +c char(3) default NULL, +PRIMARY KEY (id), +KEY t2i1 (b) +) ENGINE=innodb DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL'); +CREATE TABLE t2 ( +id int(11) NOT NULL default '0', +b int(11) default NULL, +c char(3) default NULL, +PRIMARY KEY (id), +KEY t2i (b) +) ENGINE=innodb DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL'); +select (select max(id) from t2 where b=1 group by b) as x,b from t1 where b=1; +x b +2 1 +drop table t1,t2; +create table t1 (id int not null, value char(255), primary key(id)) engine=innodb; +create table t2 (id int not null, value char(255)) engine=innodb; +insert into t1 values (1,'a'),(2,'b'); +insert into t2 values (1,'z'),(2,'x'); +select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2; +id value (select t1.value from t1 where t1.id=t2.id) +1 z a +2 x b +select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2; +id value (select t1.value from t1 where t1.id=t2.id) +1 z a +2 x b +drop table t1,t2; diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 4ba0ca0eac4..6dc48a0a77e 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -66,7 +66,7 @@ t9 CREATE TABLE `t9` ( drop database mysqltest; create table t1 (a int not null) type=myisam; Warnings: -Warning 1286 'TYPE=database_engine' is deprecated. Use 'ENGINE=database_engine' instead. +Warning 1286 'TYPE=storage_engine' is deprecated. Use 'ENGINE=storage_engine' instead. show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index 97d81d77722..fa4cd231129 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -446,39 +446,6 @@ CREATE TABLE t1 (a_dec DECIMAL(-1,1)); ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '-1,1))' at line 1 create table t1(a decimal(7,3)); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); -Warnings: -Warning 1263 Data truncated, out of range for column 'a' at row 27 -Warning 1263 Data truncated, out of range for column 'a' at row 30 -Warning 1263 Data truncated, out of range for column 'a' at row 31 -Warning 1263 Data truncated, out of range for column 'a' at row 32 -Warning 1263 Data truncated, out of range for column 'a' at row 33 -Warning 1263 Data truncated, out of range for column 'a' at row 34 -Warning 1263 Data truncated, out of range for column 'a' at row 35 -Warning 1263 Data truncated, out of range for column 'a' at row 36 -Warning 1263 Data truncated, out of range for column 'a' at row 37 -Warning 1263 Data truncated, out of range for column 'a' at row 38 -Warning 1263 Data truncated, out of range for column 'a' at row 39 -Warning 1263 Data truncated, out of range for column 'a' at row 40 -Warning 1263 Data truncated, out of range for column 'a' at row 41 -Warning 1263 Data truncated, out of range for column 'a' at row 42 -Warning 1263 Data truncated, out of range for column 'a' at row 43 -Warning 1263 Data truncated, out of range for column 'a' at row 44 -Warning 1263 Data truncated, out of range for column 'a' at row 45 -Warning 1263 Data truncated, out of range for column 'a' at row 46 -Warning 1263 Data truncated, out of range for column 'a' at row 47 -Warning 1263 Data truncated, out of range for column 'a' at row 48 -Warning 1263 Data truncated, out of range for column 'a' at row 49 -Warning 1263 Data truncated, out of range for column 'a' at row 50 -Warning 1263 Data truncated, out of range for column 'a' at row 51 -Warning 1263 Data truncated, out of range for column 'a' at row 52 -Warning 1263 Data truncated, out of range for column 'a' at row 53 -Warning 1263 Data truncated, out of range for column 'a' at row 54 -Warning 1263 Data truncated, out of range for column 'a' at row 55 -Warning 1263 Data truncated, out of range for column 'a' at row 56 -Warning 1263 Data truncated, out of range for column 'a' at row 57 -Warning 1263 Data truncated, out of range for column 'a' at row 58 -Warning 1263 Data truncated, out of range for column 'a' at row 59 -Warning 1263 Data truncated, out of range for column 'a' at row 60 select * from t1; a 1.000 @@ -544,51 +511,6 @@ a drop table t1; create table t1(a decimal(7,3) unsigned); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); -Warnings: -Warning 1263 Data truncated, out of range for column 'a' at row 3 -Warning 1263 Data truncated, out of range for column 'a' at row 6 -Warning 1263 Data truncated, out of range for column 'a' at row 9 -Warning 1263 Data truncated, out of range for column 'a' at row 12 -Warning 1263 Data truncated, out of range for column 'a' at row 15 -Warning 1263 Data truncated, out of range for column 'a' at row 18 -Warning 1263 Data truncated, out of range for column 'a' at row 21 -Warning 1263 Data truncated, out of range for column 'a' at row 24 -Warning 1263 Data truncated, out of range for column 'a' at row 25 -Warning 1263 Data truncated, out of range for column 'a' at row 26 -Warning 1263 Data truncated, out of range for column 'a' at row 27 -Warning 1263 Data truncated, out of range for column 'a' at row 28 -Warning 1263 Data truncated, out of range for column 'a' at row 29 -Warning 1263 Data truncated, out of range for column 'a' at row 30 -Warning 1263 Data truncated, out of range for column 'a' at row 31 -Warning 1263 Data truncated, out of range for column 'a' at row 32 -Warning 1263 Data truncated, out of range for column 'a' at row 33 -Warning 1263 Data truncated, out of range for column 'a' at row 34 -Warning 1263 Data truncated, out of range for column 'a' at row 35 -Warning 1263 Data truncated, out of range for column 'a' at row 36 -Warning 1263 Data truncated, out of range for column 'a' at row 37 -Warning 1263 Data truncated, out of range for column 'a' at row 38 -Warning 1263 Data truncated, out of range for column 'a' at row 39 -Warning 1263 Data truncated, out of range for column 'a' at row 40 -Warning 1263 Data truncated, out of range for column 'a' at row 41 -Warning 1263 Data truncated, out of range for column 'a' at row 42 -Warning 1263 Data truncated, out of range for column 'a' at row 43 -Warning 1263 Data truncated, out of range for column 'a' at row 44 -Warning 1263 Data truncated, out of range for column 'a' at row 45 -Warning 1263 Data truncated, out of range for column 'a' at row 46 -Warning 1263 Data truncated, out of range for column 'a' at row 47 -Warning 1263 Data truncated, out of range for column 'a' at row 48 -Warning 1263 Data truncated, out of range for column 'a' at row 49 -Warning 1263 Data truncated, out of range for column 'a' at row 50 -Warning 1263 Data truncated, out of range for column 'a' at row 51 -Warning 1263 Data truncated, out of range for column 'a' at row 52 -Warning 1263 Data truncated, out of range for column 'a' at row 53 -Warning 1263 Data truncated, out of range for column 'a' at row 54 -Warning 1263 Data truncated, out of range for column 'a' at row 55 -Warning 1263 Data truncated, out of range for column 'a' at row 56 -Warning 1263 Data truncated, out of range for column 'a' at row 57 -Warning 1263 Data truncated, out of range for column 'a' at row 58 -Warning 1263 Data truncated, out of range for column 'a' at row 59 -Warning 1263 Data truncated, out of range for column 'a' at row 60 select * from t1; a 1.000 @@ -654,51 +576,6 @@ a drop table t1; create table t1(a decimal(7,3) zerofill); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); -Warnings: -Warning 1263 Data truncated, out of range for column 'a' at row 3 -Warning 1263 Data truncated, out of range for column 'a' at row 6 -Warning 1263 Data truncated, out of range for column 'a' at row 9 -Warning 1263 Data truncated, out of range for column 'a' at row 12 -Warning 1263 Data truncated, out of range for column 'a' at row 15 -Warning 1263 Data truncated, out of range for column 'a' at row 18 -Warning 1263 Data truncated, out of range for column 'a' at row 21 -Warning 1263 Data truncated, out of range for column 'a' at row 24 -Warning 1263 Data truncated, out of range for column 'a' at row 25 -Warning 1263 Data truncated, out of range for column 'a' at row 26 -Warning 1263 Data truncated, out of range for column 'a' at row 27 -Warning 1263 Data truncated, out of range for column 'a' at row 28 -Warning 1263 Data truncated, out of range for column 'a' at row 29 -Warning 1263 Data truncated, out of range for column 'a' at row 30 -Warning 1263 Data truncated, out of range for column 'a' at row 31 -Warning 1263 Data truncated, out of range for column 'a' at row 32 -Warning 1263 Data truncated, out of range for column 'a' at row 33 -Warning 1263 Data truncated, out of range for column 'a' at row 34 -Warning 1263 Data truncated, out of range for column 'a' at row 35 -Warning 1263 Data truncated, out of range for column 'a' at row 36 -Warning 1263 Data truncated, out of range for column 'a' at row 37 -Warning 1263 Data truncated, out of range for column 'a' at row 38 -Warning 1263 Data truncated, out of range for column 'a' at row 39 -Warning 1263 Data truncated, out of range for column 'a' at row 40 -Warning 1263 Data truncated, out of range for column 'a' at row 41 -Warning 1263 Data truncated, out of range for column 'a' at row 42 -Warning 1263 Data truncated, out of range for column 'a' at row 43 -Warning 1263 Data truncated, out of range for column 'a' at row 44 -Warning 1263 Data truncated, out of range for column 'a' at row 45 -Warning 1263 Data truncated, out of range for column 'a' at row 46 -Warning 1263 Data truncated, out of range for column 'a' at row 47 -Warning 1263 Data truncated, out of range for column 'a' at row 48 -Warning 1263 Data truncated, out of range for column 'a' at row 49 -Warning 1263 Data truncated, out of range for column 'a' at row 50 -Warning 1263 Data truncated, out of range for column 'a' at row 51 -Warning 1263 Data truncated, out of range for column 'a' at row 52 -Warning 1263 Data truncated, out of range for column 'a' at row 53 -Warning 1263 Data truncated, out of range for column 'a' at row 54 -Warning 1263 Data truncated, out of range for column 'a' at row 55 -Warning 1263 Data truncated, out of range for column 'a' at row 56 -Warning 1263 Data truncated, out of range for column 'a' at row 57 -Warning 1263 Data truncated, out of range for column 'a' at row 58 -Warning 1263 Data truncated, out of range for column 'a' at row 59 -Warning 1263 Data truncated, out of range for column 'a' at row 60 select * from t1; a 0001.000 diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 6a5546200ce..0037fb9ea95 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -158,7 +158,7 @@ insert into t1 (F1,F2,F3,cnt,groupid) values ('0','0','0',1,6), ('0','1','2',1,5), ('0','2','0',1,3), ('1','0','1',1,2), ('1','2','1',1,1), ('1','2','2',1,1), ('2','0','1',2,4), ('2','2','0',1,7); -delete from t1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3); +delete from m1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3); select * from t1; F1 F2 F3 cnt groupid 0 0 0 1 6 diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index fcd06a6d8e7..6fccd2bc1a4 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -120,3 +120,45 @@ select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i; 1 3 2 0 3 6 3 0 drop table t1; +set @a=_latin2'test'; +select charset(@a),collation(@a),coercibility(@a); +charset(@a) collation(@a) coercibility(@a) +latin2 latin2_general_ci 3 +select @a=_latin2'TEST'; +@a=_latin2'TEST' +1 +select @a=_latin2'TEST' collate latin2_bin; +@a=_latin2'TEST' collate latin2_bin +0 +set @a=_latin2'test' collate latin2_general_ci; +select charset(@a),collation(@a),coercibility(@a); +charset(@a) collation(@a) coercibility(@a) +latin2 latin2_general_ci 0 +select @a=_latin2'TEST'; +@a=_latin2'TEST' +1 +select @a=_latin2'TEST' collate latin2_bin; +ERROR HY000: Illegal mix of collations (latin2_general_ci,EXPLICIT) and (latin2_bin,EXPLICIT) for operation '=' +select charset(@a:=_latin2'test'); +charset(@a:=_latin2'test') +latin2 +select collation(@a:=_latin2'test'); +collation(@a:=_latin2'test') +latin2_general_ci +select coercibility(@a:=_latin2'test'); +coercibility(@a:=_latin2'test') +3 +select collation(@a:=_latin2'test' collate latin2_bin); +collation(@a:=_latin2'test' collate latin2_bin) +latin2_bin +select coercibility(@a:=_latin2'test' collate latin2_bin); +coercibility(@a:=_latin2'test' collate latin2_bin) +0 +select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST'; +(@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' +0 +select charset(@a),collation(@a),coercibility(@a); +charset(@a) collation(@a) coercibility(@a) +latin2 latin2_bin 0 +select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci; +ERROR HY000: Illegal mix of collations (latin2_bin,EXPLICIT) and (latin2_general_ci,EXPLICIT) for operation '=' diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index ee40d0a48fa..5394c3e1e45 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -360,7 +360,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1299 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. +Note 1302 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. set sql_low_priority_updates=1; set sql_max_join_size=200; select @@sql_max_join_size,@@max_join_size; diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 5c7c75bac00..b675d189d30 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -1,7 +1,4 @@ drop table if exists t1, t2; -Warnings: -Note 1051 Unknown table 't1' -Note 1051 Unknown table 't2' SET SQL_WARNINGS=1; create table t1 (a int); insert into t1 values (1); @@ -128,10 +125,10 @@ Warning 1265 Using storage engine MyISAM for table 't1' drop table t1; create table t1 (id int) type=heap; Warnings: -Warning 1286 'TYPE=database_engine' is deprecated. Use 'ENGINE=database_engine' instead. +Warning 1286 'TYPE=storage_engine' is deprecated. Use 'ENGINE=storage_engine' instead. alter table t1 type=myisam; Warnings: -Warning 1286 'TYPE=database_engine' is deprecated. Use 'ENGINE=database_engine' instead. +Warning 1286 'TYPE=storage_engine' is deprecated. Use 'ENGINE=storage_engine' instead. drop table t1; set table_type=MYISAM; Warnings: diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index eab4fd7f5f0..c013b2251a9 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -244,3 +244,14 @@ LOCK TABLES t1 WRITE; ALTER TABLE t1 DISABLE KEYS; SHOW INDEX FROM t1; DROP TABLE t1; + +# +# Bug 2361 +# + +CREATE TABLE t1 (a int PRIMARY KEY, b INT UNIQUE); +ALTER TABLE t1 DROP PRIMARY KEY; +SHOW CREATE TABLE t1; +--error 1091 +ALTER TABLE t1 DROP PRIMARY KEY; +DROP TABLE t1; diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index dd17904effb..fab35bb334a 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -10,9 +10,17 @@ select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1; select ~5, cast(~5 as signed); explain extended select ~5, cast(~5 as signed); select cast(5 as unsigned) -6.0; +select cast(NULL as signed), cast(1/0 as signed); +select cast(NULL as unsigned), cast(1/0 as unsigned); select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A"; select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME); select cast("1:2:3" as TIME); +select CONVERT("2004-01-22 21:45:33",DATE); +select CONVERT(DATE "2004-01-22 21:45:33" USING latin1); +select CONVERT(DATE "2004-01-22 21:45:33",CHAR); +select CONVERT(DATE "2004-01-22 21:45:33",CHAR(4)); +select CONVERT(DATE "2004-01-22 21:45:33",CHAR(4) BINARY); +select CAST(DATE "2004-01-22 21:45:33" AS CHAR(4) BINARY); # # Character set convertion @@ -64,6 +72,19 @@ select * from t1; show create table t1; drop table t1; +# +# Bug 2202 +# CAST from BINARY to non-BINARY and from non-BINARY to BINARY +# +create table t1 (a binary(10), b char(10) character set koi8r); +insert into t1 values (_binary'ÔÅÓÔ',_binary'ÔÅÓÔ'); +select a,b,cast(a as char character set cp1251),cast(b as binary) from t1; +set names koi8r; +select a,b,cast(a as char character set cp1251),cast(b as binary) from t1; +set names cp1251; +select a,b,cast(a as char character set cp1251),cast(b as binary) from t1; +drop table t1; +set names binary; # # The following should be fixed in 4.1 diff --git a/mysql-test/t/ctype_big5.test b/mysql-test/t/ctype_big5.test new file mode 100644 index 00000000000..9bf1808636e --- /dev/null +++ b/mysql-test/t/ctype_big5.test @@ -0,0 +1,18 @@ +-- source include/have_big5.inc + +# +# Tests with the big5 character set +# +--disable_warnings +drop table if exists t1; +--enable_warnings + +SET NAMES big5; + +# +# Bug 1883: LIKE did not work in some cases with a key. +# +CREATE TABLE t1 (c CHAR(10) CHARACTER SET big5, KEY(c)); +INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa'); +SELECT * FROM t1 WHERE c LIKE 'aaa%'; +DROP TABLE t1; diff --git a/mysql-test/t/ctype_collate.test b/mysql-test/t/ctype_collate.test index 2d9a4be5b36..5916e3da241 100644 --- a/mysql-test/t/ctype_collate.test +++ b/mysql-test/t/ctype_collate.test @@ -156,3 +156,41 @@ CREATE TABLE t1 --error 1266 SELECT * FROM t1 WHERE s1 = s2; DROP TABLE t1; + + +# +# Test that optimizer doesn't use indexes with wrong collation +# +SET NAMES latin1; +CREATE TABLE t1 +(s1 char(10) COLLATE latin1_german1_ci, + s2 char(10) COLLATE latin1_swedish_ci, + KEY(s1), + KEY(s2)); + +INSERT INTO t1 VALUES ('a','a'); +INSERT INTO t1 VALUES ('b','b'); +INSERT INTO t1 VALUES ('c','c'); +INSERT INTO t1 VALUES ('d','d'); +INSERT INTO t1 VALUES ('e','e'); +INSERT INTO t1 VALUES ('f','f'); +INSERT INTO t1 VALUES ('g','g'); +INSERT INTO t1 VALUES ('h','h'); +INSERT INTO t1 VALUES ('i','i'); +INSERT INTO t1 VALUES ('j','j'); + +EXPLAIN SELECT * FROM t1 WHERE s1='a'; +EXPLAIN SELECT * FROM t1 WHERE s2='a'; +EXPLAIN SELECT * FROM t1 WHERE s1='a' COLLATE latin1_german1_ci; +EXPLAIN SELECT * FROM t1 WHERE s2='a' COLLATE latin1_german1_ci; + +EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci; +EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci; + +EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci); +EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci); + +EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci; +EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci; + +DROP TABLE t1; diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test index a5d0c29baf6..e29e43496af 100644 --- a/mysql-test/t/ctype_latin1_de.test +++ b/mysql-test/t/ctype_latin1_de.test @@ -2,6 +2,9 @@ # Test latin_de character set # +set names latin1; +set @@collation_connection=latin1_german2_ci; + select @@collation_connection; --disable_warnings diff --git a/mysql-test/t/ctype_many.test b/mysql-test/t/ctype_many.test index 7b44439aa50..26057e7c997 100644 --- a/mysql-test/t/ctype_many.test +++ b/mysql-test/t/ctype_many.test @@ -147,11 +147,6 @@ UPDATE t1 SET utf8_f=CONVERT(koi8_ru_f USING utf8); SET CHARACTER SET koi8r; SELECT * FROM t1; -# -# codecovarage for Item_func_conv_charset3 -# -select CONVERT(koi8_ru_f, 'cp1251_general_ci', 'utf8_general_ci'), comment from t1; -explain extended select CONVERT(koi8_ru_f, 'cp1251_general_ci', 'utf8_general_ci'), comment from t1; ALTER TABLE t1 ADD bin_f CHAR(32) BYTE NOT NULL; UPDATE t1 SET bin_f=koi8_ru_f; diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test index 0b901009041..40349da8aa9 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -14,6 +14,15 @@ INSERT t2 SELECT * FROM t1; SELECT HEX(a) FROM t2; DROP TABLE t1, t2; + +# +# Check that long strings conversion does not fail (bug#2218) +# +CREATE TABLE t1 (description text character set cp1250 NOT NULL); +INSERT INTO t1 (description) VALUES (_latin2'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssssssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddde'); +SELECT description FROM t1; +DROP TABLE t1; + # same with TEXT CREATE TABLE t1 (a TEXT CHARACTER SET cp1251) SELECT _koi8r'ÐÒÏÂÁ' AS a; CREATE TABLE t2 (a TEXT CHARACTER SET utf8); @@ -62,3 +71,4 @@ SET NAMES koi8r; SELECT hex('ÔÅÓÔ'); SET character_set_connection=cp1251; SELECT hex('ÔÅÓÔ'); + diff --git a/mysql-test/t/ctype_tis620.test b/mysql-test/t/ctype_tis620.test new file mode 100644 index 00000000000..82c660dfea0 --- /dev/null +++ b/mysql-test/t/ctype_tis620.test @@ -0,0 +1,64 @@ +-- source include/have_tis620.inc + +# +# Tests with the big5 character set +# +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# Bug 1552: tis620 <-> unicode conversion crashed +# Check tis620 -> utf8 -> tis620 round trip conversion +# + +SET @pl0= _tis620 0x000102030405060708090A0B0C0D0E0F; +SET @pl1= _tis620 0x101112131415161718191A1B1C1D1E1F; +SET @pl2= _tis620 0x202122232425262728292A2B2C2D2E2F; +SET @pl3= _tis620 0x303132333435363738393A3B3C3D3E3F; +SET @pl4= _tis620 0x404142434445464748494A4B4C4D4E4F; +SET @pl5= _tis620 0x505152535455565758595A5B5C5D5E5F; +SET @pl6= _tis620 0x606162636465666768696A6B6C6D6E6F; +SET @pl7= _tis620 0x707172737475767778797A7B7C7D7E7F; +SET @pl8= _tis620 0x808182838485868788898A8B8C8D8E8F; +SET @pl9= _tis620 0x909192939495969798999A9B9C9D9E9F; +SET @plA= _tis620 0xA0A1A2A3A4A5A6A7A8A9AAABACADAEAF; +SET @plB= _tis620 0xB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF; +SET @plC= _tis620 0xC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF; +SET @plD= _tis620 0xD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF; +SET @plE= _tis620 0xE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF; +SET @plF= _tis620 0xF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF; + +SELECT hex(@u0:=convert(@pl0 using utf8)); +SELECT hex(@u1:=convert(@pl1 using utf8)); +SELECT hex(@u2:=convert(@pl2 using utf8)); +SELECT hex(@u3:=convert(@pl3 using utf8)); +SELECT hex(@u4:=convert(@pl4 using utf8)); +SELECT hex(@u5:=convert(@pl5 using utf8)); +SELECT hex(@u6:=convert(@pl6 using utf8)); +SELECT hex(@u7:=convert(@pl7 using utf8)); +SELECT hex(@u8:=convert(@pl8 using utf8)); +SELECT hex(@u9:=convert(@pl9 using utf8)); +SELECT hex(@uA:=convert(@plA using utf8)); +SELECT hex(@uB:=convert(@plB using utf8)); +SELECT hex(@uC:=convert(@plC using utf8)); +SELECT hex(@uD:=convert(@plD using utf8)); +SELECT hex(@uE:=convert(@plE using utf8)); +SELECT hex(@uF:=convert(@plF using utf8)); + +SELECT hex(convert(@u0 USING tis620)); +SELECT hex(convert(@u1 USING tis620)); +SELECT hex(convert(@u2 USING tis620)); +SELECT hex(convert(@u3 USING tis620)); +SELECT hex(convert(@u4 USING tis620)); +SELECT hex(convert(@u5 USING tis620)); +SELECT hex(convert(@u6 USING tis620)); +SELECT hex(convert(@u7 USING tis620)); +SELECT hex(convert(@u8 USING tis620)); +SELECT hex(convert(@u9 USING tis620)); +SELECT hex(convert(@uA USING tis620)); +SELECT hex(convert(@uB USING tis620)); +SELECT hex(convert(@uC USING tis620)); +SELECT hex(convert(@uD USING tis620)); +SELECT hex(convert(@uE USING tis620)); +SELECT hex(convert(@uF USING tis620)); diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index 90b423cd1e0..5b1a5923ad4 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -69,6 +69,35 @@ select * from t1 where a like "%abcd%"; select * from t1 where a like "%abc\d%"; drop table t1; +# +# More LIKE test: bug#2619 +# +select 'AA' like 'AA'; +select 'AA' like 'A%A'; +select 'AA' like 'A%%A'; +select 'AA' like 'AA%'; +select 'AA' like '%AA%'; +select 'AA' like '%A'; +select 'AA' like '%AA'; +select 'AA' like 'A%A%'; +select 'AA' like '_%_%'; +select 'AA' like '%A%A'; +select 'AAA'like 'A%A%A'; + +select 'AZ' like 'AZ'; +select 'AZ' like 'A%Z'; +select 'AZ' like 'A%%Z'; +select 'AZ' like 'AZ%'; +select 'AZ' like '%AZ%'; +select 'AZ' like '%Z'; +select 'AZ' like '%AZ'; +select 'AZ' like 'A%Z%'; +select 'AZ' like '_%_%'; +select 'AZ' like '%A%Z'; +select 'AZ' like 'A_'; +select 'AZ' like '_Z'; +select 'AMZ'like 'A%M%Z'; + CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET ucs2); INSERT INTO t1 VALUES ('ÆÙ×Á'),('æÙ×Á'),('Æù×Á'),('ÆÙ÷Á'),('ÆÙ×á'),('æù÷á'); INSERT INTO t1 VALUES ('ÆÙ×ÁÐÒÏÌÄÖ'),('æÙ×ÁÐÒÏÌÄÖ'),('Æù×ÁÐÒÏÌÄÖ'),('ÆÙ÷ÁÐÒÏÌÄÖ'); @@ -93,6 +122,12 @@ SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630025'; SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630061005F'; DROP TABLE t1; +# +# Check that INSERT works fine. +# This invokes charpos() function. +select insert(_ucs2 0x006100620063,10,2,_ucs2 0x006400650066); +select insert(_ucs2 0x006100620063,1,2,_ucs2 0x006400650066); + ###################################################### # @@ -192,3 +227,59 @@ DROP TABLE t1; # ######################################################## + +# Bug #2390 +# Check alignment for constants +# +SELECT HEX(_ucs2 0x0); +SELECT HEX(_ucs2 0x01); +SELECT HEX(_ucs2 0x012); +SELECT HEX(_ucs2 0x0123); +SELECT HEX(_ucs2 0x01234); +SELECT HEX(_ucs2 0x012345); +SELECT HEX(_ucs2 0x0123456); +SELECT HEX(_ucs2 0x01234567); +SELECT HEX(_ucs2 0x012345678); +SELECT HEX(_ucs2 0x0123456789); +SELECT HEX(_ucs2 0x0123456789A); +SELECT HEX(_ucs2 0x0123456789AB); +SELECT HEX(_ucs2 0x0123456789ABC); +SELECT HEX(_ucs2 0x0123456789ABCD); +SELECT HEX(_ucs2 0x0123456789ABCDE); +SELECT HEX(_ucs2 0x0123456789ABCDEF); + +# +# Check alignment for from-binary-conversion with CAST and CONVERT +# +SELECT hex(cast(0xAA as char character set ucs2)); +SELECT hex(convert(0xAA using ucs2)); + +# +# Check alignment for string types +# +CREATE TABLE t1 (a char(10) character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a varchar(10) character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a text character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a mediumtext character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a longtext character set ucs2); +INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA); +SELECT HEX(a) FROM t1; +DROP TABLE t1; + +-- the same should be also done with enum and set diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 54d934b66db..49b1ed94757 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -2,6 +2,9 @@ # Tests with the utf8 character set # +--disable_warnings +drop table if exists t1; +--enable_warnings set names utf8; select left(_utf8 0xD0B0D0B1D0B2,1); @@ -35,3 +38,70 @@ select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%'); # #select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD091,_utf8 '%'); # + +# +# Bug 2367: INSERT() behaviour is different for different charsets. +# +select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es'); +select insert("aa",100,1,"b"),insert("aa",1,3,"b"); + +# +# CREATE ... SELECT +# +create table t1 select date_format("2004-01-19 10:10:10", "%Y-%m-%d"); +show create table t1; +select * from t1; +drop table t1; + +# +# Bug #2366 Wrong utf8 behaviour when data is trancated +# +set names koi8r; +create table t1 (s1 char(1) character set utf8); +insert into t1 values (_koi8r'ÁÂ'); +select s1,hex(s1),char_length(s1),octet_length(s1) from t1; +drop table t1; + +create table t1 (s1 tinytext character set utf8); +insert into t1 select repeat('a',300); +insert into t1 select repeat('Ñ',300); +insert into t1 select repeat('aÑ',300); +insert into t1 select repeat('Ña',300); +insert into t1 select repeat('ÑÑ',300); +select hex(s1) from t1; +select length(s1),char_length(s1) from t1; +drop table t1; + +create table t1 (s1 text character set utf8); +insert into t1 select repeat('a',66000); +insert into t1 select repeat('Ñ',66000); +insert into t1 select repeat('aÑ',66000); +insert into t1 select repeat('Ña',66000); +insert into t1 select repeat('ÑÑ',66000); +select length(s1),char_length(s1) from t1; +drop table t1; + +# +# Bug #2368 Multibyte charsets do not check that incoming data is well-formed +# +create table t1 (s1 char(10) character set utf8); +insert into t1 values (0x41FF); +select hex(s1) from t1; +drop table t1; + +create table t1 (s1 varchar(10) character set utf8); +insert into t1 values (0x41FF); +select hex(s1) from t1; +drop table t1; + +create table t1 (s1 text character set utf8); +insert into t1 values (0x41FF); +select hex(s1) from t1; +drop table t1; + +# +# Bug 2699 +# UTF8 breaks primary keys for cols > 85 characters +# +--error 1089 +create table t1 (a char(160) character set utf8, primary key(a)); diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index 7b88c0ecf72..18af3dfb3db 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -2,9 +2,9 @@ # Test of date format functions # ---disable-warnings +--disable_warnings drop table if exists t1; ---enable-warnings +--enable_warnings SHOW GLOBAL VARIABLES LIKE "%_format%"; SHOW SESSION VARIABLES LIKE "%_format%"; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index caf673d95c1..a9341ada416 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -35,6 +35,7 @@ select a from (select 1 as a) as b; select 1 from (select 1) as a; select * from (select * from t1 union select * from t1) a; select * from (select * from t1 union all select * from t1) a; +select * from (select * from t1 union all select * from t1 limit 2) a; explain select * from (select * from t1 union select * from t1) a; explain select * from (select * from t1 union all select * from t1) a; CREATE TABLE t2 (a int not null); @@ -115,7 +116,7 @@ select mail_id, if(folder.f_description!='', folder.f_description, folder.f_nam # create table t1 (a int); insert into t1 values (1),(2),(3); --- error 1149 +-- error 1287 update (select * from t1) as t1 set a = 5; -- error 1064 delete from (select * from t1); @@ -138,3 +139,70 @@ insert into t1 values (1),(2); select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b; explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b; drop table t1; + + +# +# multi-update & multi-delete with derived tables +# +CREATE TABLE `t1` ( + `N` int(11) unsigned NOT NULL default '0', + `M` tinyint(1) default '0', +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO `t1` (N, M) VALUES (1, 0),(1, 0),(1, 0),(2, 0),(2, 0),(3, 0); +UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2; +select * from t1; +-- error 1287 +UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2, P2.N = 2; +-- error 1054 +UPDATE `t1` AS P1 INNER JOIN (SELECT aaaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2; +delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N; +select * from t1; +-- error 1287 +delete P1.*,P2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N; +-- error 1054 +delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N; +drop table t1; + +# +# correct lex->current_select +# +CREATE TABLE t1 ( + OBJECTID int(11) NOT NULL default '0', + SORTORDER int(11) NOT NULL auto_increment, + KEY t1_SortIndex (SORTORDER), + KEY t1_IdIndex (OBJECTID) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +CREATE TABLE t2 ( + ID int(11) default NULL, + PARID int(11) default NULL, + UNIQUE KEY t2_ID_IDX (ID), + KEY t2_PARID_IDX (PARID) +) engine=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (1000,0),(1001,0),(1002,0),(1003,0),(1008,1),(1009,1),(1010,1),(1011,1),(1016,2); +CREATE TABLE t3 ( + ID int(11) default NULL, + DATA decimal(10,2) default NULL, + UNIQUE KEY t3_ID_IDX (ID) +) engine=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t3 VALUES (1000,0.00),(1001,0.25),(1002,0.50),(1003,0.75),(1008,1.00),(1009,1.25),(1010,1.50),(1011,1.75); +select 497, TMP.ID, NULL from (select 497 as ID, MAX(t3.DATA) as DATA from t1 join t2 on (t1.ObjectID = t2.ID) join t3 on (t1.ObjectID = t3.ID) group by t2.ParID order by DATA DESC) as TMP; +drop table t1, t2, t3; + + +# +# explain derived +# +CREATE TABLE t1 (name char(1) default NULL, val int(5) default NULL); +INSERT INTO t1 VALUES ('a',1), ('a',2), ('a',2), ('a',2), ('a',3), ('a',6), ('a',7), ('a',11), ('a',11), ('a',12), ('a',13), ('a',13), ('a',20), ('b',2), ('b',3), ('b',4), ('b',5); +SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x, t1 y WHERE x.name=y.name GROUP BY x.name, x.val HAVING SUM(y.val <= x.val) >= COUNT(*)/2 AND SUM(y.val >= x.val) >= COUNT(*)/2) AS s GROUP BY s.name; +explain SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x, t1 y WHERE x.name=y.name GROUP BY x.name, x.val HAVING SUM(y.val <= x.val) >= COUNT(*)/2 AND SUM(y.val >= x.val) >= COUNT(*)/2) AS s GROUP BY s.name; +drop table t1; + +# +# "Using index" in explain +# +create table t2 (a int, b int, primary key (a)); +insert into t2 values (1,7),(2,7); +explain select a from t2 where a>1; +explain select a from (select a from t2 where a>1) tt; +drop table t2; diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test index 0cd85385df4..a05a2a3bdaa 100644 --- a/mysql-test/t/func_like.test +++ b/mysql-test/t/func_like.test @@ -44,3 +44,22 @@ SELECT * FROM t1 WHERE a LIKE '%Æù×%'; SELECT * FROM t1 WHERE a LIKE 'Æù×Á%'; DROP TABLE t1; + +# Bug #2547 Strange "like" behaviour in tables with default charset=cp1250 +# Test like with non-default character set using TurboBM +# +SET NAMES cp1250; +CREATE TABLE t1 (a varchar(250) NOT NULL) DEFAULT CHARACTER SET=cp1250; +INSERT INTO t1 VALUES +('Techni Tapes Sp. z o.o.'), +('Pojazdy Szynowe PESA Bydgoszcz SA Holding'), +('AKAPESTER 1 P.P.H.U.'), +('Pojazdy Szynowe PESA Bydgoszcz S A Holding'), +('PPUH PESKA-I Maria Struniarska'); + +select * from t1 where a like '%PESA%'; +select * from t1 where a like '%PESA %'; +select * from t1 where a like '%PES%'; +select * from t1 where a like '%PESKA%'; +select * from t1 where a like '%ESKA%'; +DROP TABLE t1; diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index d15c26279ec..9759127b222 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -8,6 +8,10 @@ select inet_ntoa(inet_aton("255.255.255.255.255.255.255.255")); select inet_aton("255.255.255.255.255"),inet_aton("255.255.1.255"),inet_aton("0.1.255"); select inet_ntoa(1099511627775),inet_ntoa(4294902271),inet_ntoa(511); +select hex(inet_aton('127')); +select hex(inet_aton('127.1')); +select hex(inet_aton('127.1.1')); + # # Test for core dump with nan # diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index ad7b9b21b51..155ed459d1f 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -346,3 +346,9 @@ DROP TABLE t1; select substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2),substring_index("1abcd;2abcd;3abcd;4abcd", ';', -2); explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'mood' sounds like 'mud', aes_decrypt(aes_encrypt('abc','1'),'1'),concat('*',space(5),'*'), reverse('abc'), rpad('a',4,'1'), lpad('a',4,'1'), concat_ws(',','',NULL,'a'),make_set(255,_latin2'a',_latin2'b',_latin2'c'),elt(2,1),locate("a","b",2),format(130,10),char(0),conv(130,16,10),hex(130),binary 'HE', export_set(255,_latin2'y',_latin2'n',_latin2' '),FIELD('b' COLLATE latin1_bin,'A','B'),FIND_IN_SET(_latin1'B',_latin1'a,b,c,d'),collation(conv(130,16,10)), coercibility(conv(130,16,10)),length('\n\t\r\b\0\_\%\\'),bit_length('\n\t\r\b\0\_\%\\'),bit_length('\n\t\r\b\0\_\%\\'),concat('monty',' was here ','again'),length('hello'),char(ascii('h')),ord('h'),quote(1/0),crc32("123"),replace('aaaa','a','b'),insert('txs',2,1,'hi'),left(_latin2'a',1),right(_latin2'a',1),lcase(_latin2'a'),ucase(_latin2'a'),SUBSTR('abcdefg',3,2),substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2),trim(_latin2' a '),ltrim(_latin2' a '),rtrim(_latin2' a '), decode(encode(repeat("a",100000),"monty"),"monty"); + +# +# Bug #2182 +# + +SELECT lpad(12345, 5, "#"); diff --git a/mysql-test/t/func_system.test b/mysql-test/t/func_system.test index f3b9b4ffc3f..a05b80ca56b 100644 --- a/mysql-test/t/func_system.test +++ b/mysql-test/t/func_system.test @@ -23,4 +23,10 @@ create table t1 (version char(40)) select database(), user(), version() as 'vers show create table t1; drop table t1; +select charset(charset(_utf8'a')), charset(collation(_utf8'a')); +select collation(charset(_utf8'a')), collation(collation(_utf8'a')); +create table t1 select charset(_utf8'a'), collation(_utf8'a'); +show create table t1; +drop table t1; + select TRUE,FALSE,NULL; diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test index 1559fef7e6e..0d055549866 100644 --- a/mysql-test/t/func_test.test +++ b/mysql-test/t/func_test.test @@ -85,3 +85,11 @@ CREATE TABLE t2 ( access_id smallint(6) NOT NULL default '0', name varchar(20 INSERT INTO t2 VALUES (1,'Everyone',2),(2,'Help',3),(3,'Customer Support',1); SELECT f_acc.rank, a1.rank, a2.rank FROM t1 LEFT JOIN t1 f1 ON (f1.access_id=1 AND f1.faq_group_id = t1.faq_group_id) LEFT JOIN t2 a1 ON (a1.access_id = f1.access_id) LEFT JOIN t1 f2 ON (f2.access_id=3 AND f2.faq_group_id = t1.faq_group_id) LEFT JOIN t2 a2 ON (a2.access_id = f2.access_id), t2 f_acc WHERE LEAST(a1.rank,a2.rank) = f_acc.rank; DROP TABLE t1,t2; + +# +# Test for GREATEST() and LEAST() bug, which segfaulted 4.1.1 server +# +CREATE TABLE t1 (d varchar(6), k int); +INSERT INTO t1 VALUES (NULL, 2); +SELECT GREATEST(d,d) FROM t1 WHERE k=2; +DROP TABLE t1; diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index b2bc57f3804..d9a2200a636 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -75,7 +75,7 @@ select * from t2; update t1 set p=2 where p=1; update t2 set i=2 where i=1; -cache index t1 keys (`primary`) in keycache1; +cache index t1 key (`primary`) in keycache1; explain select p from t1; select p from t1; @@ -101,7 +101,7 @@ select a from t2; # Test some error conditions --error 1283 cache index t1 in unknown_key_cache; -cache index t1 keys (unknown_key) in keycache1; +cache index t1 key (unknown_key) in keycache1; select @@keycache2.key_buffer_size; select @@keycache2.key_cache_block_size; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 50bd2d114ed..84b9c816ee5 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -218,7 +218,7 @@ select * from t2; UPDATE t1 a ,t2 b SET a.d=b.d,b.d=30 WHERE a.n=b.n; select * from t1; select * from t2; -DELETE t1, t2 FROM t1 a,t2 b where a.n=b.n; +DELETE a, b FROM t1 a,t2 b where a.n=b.n; select * from t1; select * from t2; drop table t1,t2; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 1299d73eb99..dc0d45187b4 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -28,12 +28,12 @@ INSERT INTO t1 VALUES (-9e999999); # The following replaces is here because some systems replaces the above # double with '-inf' and others with MAX_DOUBLE --replace_result (-1.79769313486232e+308) (RES) (NULL) (RES) ---exec $MYSQL_DUMP --skip-comments test t1 +--exec $MYSQL_DUMP --skip-comments test t1 DROP TABLE t1; CREATE TABLE t1(a int, b text, c varchar(3)); INSERT INTO t1 VALUES (1, "test", "tes"), (2, "TEST", "TES"); ---exec $MYSQL_DUMP --skip-all --skip-comments -X test t1 +--exec $MYSQL_DUMP --skip-all --skip-comments -X test t1 DROP TABLE t1; # @@ -42,7 +42,7 @@ DROP TABLE t1; CREATE TABLE t1 (`a"b"` char(2)); INSERT INTO t1 VALUES ("1\""), ("\"2"); ---exec $MYSQL_DUMP --skip-all --skip-comments -X test t1 +--exec $MYSQL_DUMP --skip-all --skip-comments -X test t1 DROP TABLE t1; # @@ -51,5 +51,23 @@ DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'); ---exec $MYSQL_DUMP --skip-comments test t1 +--exec $MYSQL_DUMP --skip-comments test t1 +DROP TABLE t1; + +# +# Bug #2634 +# + +CREATE TABLE t1 (a int) ENGINE=MYISAM; +INSERT INTO t1 VALUES (1), (2); +--exec $MYSQL_DUMP --skip-comments --compatible=mysql40 test t1 +--exec $MYSQL_DUMP --skip-comments --compatible=mysql323 test t1 DROP TABLE t1; + +# +# Bug #2592 'mysqldum doesn't quote "tricky" names correctly' +# + +create table ```a` (i int); +--exec $MYSQL_DUMP --skip-comments test +drop table ```a`; diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test index c11ed78253b..9f3b6646e7f 100644 --- a/mysql-test/t/null.test +++ b/mysql-test/t/null.test @@ -97,3 +97,4 @@ insert into t1 values explain select * from t1 where a between 2 and 3; explain select * from t1 where a between 2 and 3 or b is null; drop table t1; +select cast(NULL as signed); diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 1db783c212b..bbb0046b47f 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -381,3 +381,15 @@ CREATE TABLE t1 ( id smallint(6) unsigned NOT NULL default '0', menu tinyint(4 INSERT INTO t1 VALUES (11384, 2),(11392, 2); SELECT id FROM t1 WHERE id <11984 AND menu =2 ORDER BY id DESC LIMIT 1 ; drop table t1; + +# +# REF_OR_NULL optimization + filesort (bug #2419) +# + +create table t1(a int, b int, index(b)); +insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2); +explain select * from t1 where b=1 or b is null order by a; +select * from t1 where b=1 or b is null order by a; +explain select * from t1 where b=2 or b is null order by a; +select * from t1 where b=2 or b is null order by a; +drop table t1; diff --git a/mysql-test/t/preload.test b/mysql-test/t/preload.test index 7eff5cee08f..7a049d06a86 100644 --- a/mysql-test/t/preload.test +++ b/mysql-test/t/preload.test @@ -81,7 +81,7 @@ flush tables; flush status; show status like "key_read%"; set session preload_buffer_size=1*1024; select @@preload_buffer_size; -load index into cache t1, t2 keys (primary,b) ignore leaves; +load index into cache t1, t2 key (primary,b) ignore leaves; show status like "key_read%"; select count(*) from t1 where b = 'test1'; select count(*) from t2 where b = 'test1'; @@ -89,12 +89,12 @@ show status like "key_read%"; flush tables; flush status; show status like "key_read%"; -load index into cache t3, t2 keys (primary,b) ; +load index into cache t3, t2 key (primary,b) ; show status like "key_read%"; flush tables; flush status; show status like "key_read%"; -load index into cache t3 keys (b), t2 keys (c) ; +load index into cache t3 key (b), t2 key (c) ; show status like "key_read%"; drop table t1, t2; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 17ba5418c8a..b46685505ef 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -466,8 +466,10 @@ select * from t1 where id=2; create table t1 (word char(20) not null); select * from t1; show status like "Qcache_queries_in_cache"; -load data infile '../../std_data/words.dat' into table t1; +--replace_result $MYSQL_TEST_DIR TEST_DIR +eval load data infile '$MYSQL_TEST_DIR/std_data/words.dat' into table t1; show status like "Qcache_queries_in_cache"; +select count(*) from t1; drop table t1; # @@ -476,7 +478,9 @@ drop table t1; create table t1 (a int); insert into t1 values (1),(2),(3); show status like "Qcache_queries_in_cache"; -select * from t1 into outfile "query_caceh.out.file"; +select * from t1 into outfile "query_cache.out.file"; +--error 1086 +select * from t1 into outfile "query_cache.out.file"; select * from t1 limit 1 into dumpfile "query_cache.dump.file"; show status like "Qcache_queries_in_cache"; drop table t1; @@ -585,9 +589,21 @@ set character_set_results=cp1251; SELECT a,'Â','â'='Â' FROM t1; show status like "Qcache_hits"; show status like "Qcache_queries_in_cache"; -drop table t1; +DROP TABLE t1; + +# +# DROP current database test # +CREATE TABLE t1 (a int(1)); +CREATE DATABASE mysqltest; +USE mysqltest; +DROP DATABASE mysqltest; +SELECT * FROM test.t1; +USE test; +DROP TABLE t1; + + # comments before command # create table t1 (a int); diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test index 40b810dfd62..545b495938a 100644 --- a/mysql-test/t/rpl_until.test +++ b/mysql-test/t/rpl_until.test @@ -29,7 +29,7 @@ sleep 2; # here table should be still not deleted select * from t1; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 33 # +--replace_column 1 # 9 # 23 # 33 # show slave status; # this should fail right after start @@ -59,9 +59,10 @@ stop slave; # this should stop immediately as we are already there start slave until master_log_file='master-bin.000001', master_log_pos=710; -sleep 2; +# 2 is not enough when running with valgrind +real_sleep 4 # here the sql slave thread should be stopped ---replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004 --replace_column 1 # 9 # 23 # 33 # show slave status; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 4ab39e3ccbc..1d64cfd2105 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -53,9 +53,14 @@ drop table t2; create table t1 ( test_set set( 'val1', 'val2', 'val3' ) not null default '', name char(20) default 'O''Brien' comment 'O''Brien as default', - c int not null comment 'int column' + c int not null comment 'int column', + `c-b` int comment 'name with a space', + `space ` int comment 'name with a space', ) comment = 'it\'s a table' ; -show create table t1 ; +show create table t1; +set sql_quote_show_create=0; +show create table t1; +set sql_quote_show_create=1; show full columns from t1; drop table t1; @@ -137,3 +142,43 @@ drop table t1; create table t1 (c decimal(3,3), d double(3,3), f float(3,3)); show columns from t1; drop table t1; + +# +# Test for Bug #2593 "SHOW CREATE TABLE doesn't properly double quotes" +# + +SET sql_mode=''; +SET sql_quote_show_create=OFF; + +CREATE TABLE ```ab``cd``` (i INT); +SHOW CREATE TABLE ```ab``cd```; +DROP TABLE ```ab``cd```; + +CREATE TABLE ```ab````cd``` (i INT); +SHOW CREATE TABLE ```ab````cd```; +DROP TABLE ```ab````cd```; + +CREATE TABLE ```a` (i INT); +SHOW CREATE TABLE ```a`; +DROP TABLE ```a`; + +SET sql_mode='ANSI_QUOTES'; + +CREATE TABLE """a" (i INT); +SHOW CREATE TABLE """a"; +DROP TABLE """a"; + +# to test quotes around keywords.. : + +SET sql_mode=''; +SET sql_quote_show_create=OFF; + +CREATE TABLE t1 (i INT); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE `table` (i INT); +SHOW CREATE TABLE `table`; +DROP TABLE `table`; + +SET sql_quote_show_create=ON; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index c72dcaedb4e..68a5ccdbe42 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -32,18 +32,18 @@ create function func1() returns int return 42| # Can't create recursively ---error 1287 +--error 1290 create procedure foo() create procedure bar() set @x=3| ---error 1287 +--error 1290 create procedure foo() create function bar() returns double return 2.3| # Already exists ---error 1288 +--error 1291 create procedure proc1() set @x = 42| ---error 1288 +--error 1291 create function func1() returns int return 42| @@ -51,39 +51,39 @@ drop procedure proc1| drop function func1| # Does not exist ---error 1289 +--error 1292 alter procedure foo| ---error 1289 +--error 1292 alter function foo| ---error 1289 +--error 1292 drop procedure foo| ---error 1289 +--error 1292 drop function foo| ---error 1289 +--error 1292 call foo()| drop procedure if exists foo| ---error 1289 +--error 1292 show create procedure foo| # LEAVE/ITERATE with no match ---error 1292 +--error 1295 create procedure foo() foo: loop leave bar; end loop| ---error 1292 +--error 1295 create procedure foo() foo: loop iterate bar; end loop| ---error 1292 +--error 1295 create procedure foo() foo: begin iterate foo; end| # Redefining label ---error 1293 +--error 1296 create procedure foo() foo: loop foo: loop @@ -92,7 +92,7 @@ foo: loop end loop foo| # End label mismatch ---error 1294 +--error 1297 create procedure foo() foo: loop set @x=2; @@ -107,12 +107,12 @@ end| drop procedure foo| # RETURN in FUNCTION only ---error 1297 +--error 1300 create procedure foo() return 42| # Doesn't allow queries in FUNCTIONs (for now :-( ) ---error 1298 +--error 1301 create function foo() returns int begin declare x int; @@ -126,19 +126,19 @@ create procedure p(x int) create function f(x int) returns int return x+42| ---error 1302 +--error 1305 call p()| ---error 1302 +--error 1305 call p(1, 2)| ---error 1302 +--error 1305 select f()| ---error 1302 +--error 1305 select f(1, 2)| drop procedure p| drop function f| ---error 1303 +--error 1306 create procedure p(val int, out res int) begin declare x int default 0; @@ -152,7 +152,7 @@ begin end if; end| ---error 1303 +--error 1306 create procedure p(val int, out res int) begin declare x int default 0; @@ -167,7 +167,7 @@ begin end if; end| ---error 1304 +--error 1307 create function f(val int) returns int begin declare x int; @@ -185,12 +185,12 @@ begin end if; end| ---error 1305 +--error 1308 select f(10)| drop function f| ---error 1306 +--error 1309 create procedure p() begin declare c cursor for insert into test.t1 values ("foo", 42); @@ -199,7 +199,7 @@ begin close c; end| ---error 1307 +--error 1310 create procedure p() begin declare x int; @@ -209,7 +209,7 @@ begin close c; end| ---error 1308 +--error 1311 create procedure p() begin declare c cursor for select * from test.t; @@ -231,7 +231,7 @@ begin open c; close c; end| ---error 1309 +--error 1312 call p()| drop procedure p| @@ -243,11 +243,11 @@ begin close c; close c; end| ---error 1310 +--error 1313 call p()| drop procedure p| ---error 1289 +--error 1292 alter procedure bar3 sql security invoker| --error 1059 alter procedure bar3 name @@ -261,7 +261,7 @@ drop table if exists t1| create table t1 (val int, x float)| insert into t1 values (42, 3.1), (19, 1.2)| ---error 1311 +--error 1314 create procedure p() begin declare c cursor for select * from t1; @@ -281,7 +281,7 @@ begin fetch c into x; close c; end| ---error 1312 +--error 1315 call p()| drop procedure p| @@ -296,34 +296,34 @@ begin fetch c into x, y, z; close c; end| ---error 1312 +--error 1315 call p()| drop procedure p| ---error 1314 +--error 1317 create procedure p(in x int, x char(10)) begin end| ---error 1314 +--error 1317 create function p(x int, x char(10)) begin end| ---error 1315 +--error 1318 create procedure p() begin declare x float; declare x int; end| ---error 1316 +--error 1319 create procedure p() begin declare c condition for 1064; declare c condition for 1065; end| ---error 1317 +--error 1320 create procedure p() begin declare c cursor for select * from t1; @@ -347,13 +347,13 @@ drop procedure bug1965| # # BUG#1966 # ---error 1311 +--error 1314 select 1 into a| # # BUG#336 # ---error 1319 +--error 1322 create procedure bug336(id char(16)) begin declare x int; @@ -363,7 +363,7 @@ end| # # BUG#1654 # ---error 1298 +--error 1301 create function bug1654() returns int return (select sum(t.data) from test.t2 t)| @@ -401,7 +401,7 @@ begin fetch c1 into v1; end| ---error 1310 +--error 1313 call bug2259()| drop procedure bug2259| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 298120bca2f..3cb88ec5717 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -502,7 +502,6 @@ drop procedure sel2| delete from t1| delete from t2| - # SELECT INTO local variables create procedure into_test(x char(16), y int) begin @@ -1107,6 +1106,38 @@ drop procedure bug2267_2| drop procedure bug2267_3| drop procedure bug2267_4| +# +# BUG#2227 +# +create procedure bug2227(x int) +begin + declare y float default 2.6; + declare z char(16) default "zzz"; + + select 1.3, x, y, 42, z; +end| + +call bug2227(9)| +drop procedure bug2227| + +# +# BUG#2614 +# +create procedure bug2614() +begin + drop table if exists t3; + create table t3 (id int default '0' not null); + insert into t3 select 12; + insert into t3 select * from t3; +end| + +--disable_warnings +call bug2614()| +--enable_warnings +call bug2614()| +drop table t3| +drop procedure bug2614| + # # Some "real" examples @@ -1286,7 +1317,6 @@ show create procedure bar| --replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00' show procedure status like 'bar'| drop procedure bar| - delimiter ;| drop table t1; drop table t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 828443dfa10..2f05141ee31 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1014,3 +1014,43 @@ INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365'); INSERT INTO t2 VALUES (100, 200, 'C'); SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1); DROP TABLE t1, t2; + +# +# Bug 2198 +# + +create table t1 (a int, b decimal(13, 3)); +insert into t1 values (1, 0.123); +select a, (select max(b) from t1) into outfile "subselect.out.file.1" from t1; +delete from t1; +load data infile "subselect.out.file.1" into table t1; +select * from t1; +drop table t1; + +# +# Bug 2479 +# + +CREATE TABLE `t1` ( + `id` int(11) NOT NULL auto_increment, + `id_cns` tinyint(3) unsigned NOT NULL default '0', + `tipo` enum('','UNO','DUE') NOT NULL default '', + `anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000', + `particolare` mediumint(8) unsigned NOT NULL default '0', + `generale` mediumint(8) unsigned NOT NULL default '0', + `bis` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`id`), + UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`), + UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`) +); +INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0); +CREATE TABLE `t2` ( + `id` tinyint(3) unsigned NOT NULL auto_increment, + `max_anno_dep` smallint(6) unsigned NOT NULL default '0', + PRIMARY KEY (`id`) +); +INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990); + +SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns; + +DROP TABLE t1, t2; diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test index 9eb35ffc0fd..8e8d41f7653 100644 --- a/mysql-test/t/subselect_innodb.test +++ b/mysql-test/t/subselect_innodb.test @@ -67,4 +67,37 @@ INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t3 VALUES (1,1),(2,2),(3,3); INSERT INTO t2 VALUES (1,1),(2,2),(3,3); SELECT distinct p1.processor_id, (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id) FROM t1 p1; -drop table t1,t2,t3;
\ No newline at end of file +drop table t1,t2,t3; + +# +# innodb locking +# +CREATE TABLE t1 ( + id int(11) NOT NULL default '0', + b int(11) default NULL, + c char(3) default NULL, + PRIMARY KEY (id), + KEY t2i1 (b) +) ENGINE=innodb DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL'); +CREATE TABLE t2 ( + id int(11) NOT NULL default '0', + b int(11) default NULL, + c char(3) default NULL, + PRIMARY KEY (id), + KEY t2i (b) +) ENGINE=innodb DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL'); +select (select max(id) from t2 where b=1 group by b) as x,b from t1 where b=1; +drop table t1,t2; + +# +# reiniting innodb tables +# +create table t1 (id int not null, value char(255), primary key(id)) engine=innodb; +create table t2 (id int not null, value char(255)) engine=innodb; +insert into t1 values (1,'a'),(2,'b'); +insert into t2 values (1,'z'),(2,'x'); +select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2; +select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2; +drop table t1,t2; diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index cddb0347b7e..3257002ae2c 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -248,7 +248,7 @@ CREATE TABLE t1 (a_dec DECIMAL(-1,1)); # # Zero prepend overflow bug # ---disable-warnings +--disable_warnings create table t1(a decimal(7,3)); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); select * from t1; @@ -259,6 +259,6 @@ select * from t1; drop table t1; create table t1(a decimal(7,3) zerofill); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); ---enable-warnings +--enable_warnings select * from t1; drop table t1; diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index 8e50fee56fd..3406dfd6158 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -126,6 +126,6 @@ insert into t1 (F1,F2,F3,cnt,groupid) values ('0','0','0',1,6), ('1','2','1',1,1), ('1','2','2',1,1), ('2','0','1',2,4), ('2','2','0',1,7); -delete from t1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3); +delete from m1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3); select * from t1; drop table t1; diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 39742d20c7c..32ed6fe33db 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -71,3 +71,31 @@ select @a:=0; select @a, @a:=@a+count(*), count(*), @a from t1 group by i; select @a:=0; select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i; drop table t1; +# +# Bug #2244: User variables didn't copy collation and derivation +# attributes from values they were initialized to. +# + +set @a=_latin2'test'; +select charset(@a),collation(@a),coercibility(@a); +select @a=_latin2'TEST'; +select @a=_latin2'TEST' collate latin2_bin; + +set @a=_latin2'test' collate latin2_general_ci; +select charset(@a),collation(@a),coercibility(@a); +select @a=_latin2'TEST'; +--error 1266 +select @a=_latin2'TEST' collate latin2_bin; + +# +# Check the same invoking Item_set_user_var +# +select charset(@a:=_latin2'test'); +select collation(@a:=_latin2'test'); +select coercibility(@a:=_latin2'test'); +select collation(@a:=_latin2'test' collate latin2_bin); +select coercibility(@a:=_latin2'test' collate latin2_bin); +select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST'; +select charset(@a),collation(@a),coercibility(@a); +--error 1266 +select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci; diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test index 0456ca8c1fe..b6042df51f1 100644 --- a/mysql-test/t/warnings.test +++ b/mysql-test/t/warnings.test @@ -1,9 +1,9 @@ # # Test some warnings # ---disable-warnings +--disable_warnings drop table if exists t1, t2; ---enable-warnings +--enable_warnings SET SQL_WARNINGS=1; create table t1 (a int); diff --git a/mysys/charset.c b/mysys/charset.c index 1fe926a51d6..5bf0ea972a5 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -131,7 +131,8 @@ static void simple_cs_init_functions(CHARSET_INFO *cs) cs->coll= &my_collation_8bit_simple_ci_handler; cs->cset= &my_charset_8bit_handler; - cs->mbmaxlen = 1; + cs->mbminlen= 1; + cs->mbmaxlen= 1; } @@ -273,6 +274,7 @@ static int simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from) if (create_fromuni(to)) goto err; } + to->mbminlen= 1; to->mbmaxlen= 1; return 0; @@ -357,7 +359,7 @@ static int add_collation(CHARSET_INFO *cs) } -#define MAX_BUF 1024*16 +#define MY_MAX_ALLOWED_BUF 1024*1024 #define MY_CHARSET_INDEX "Index.xml" const char *charsets_dir= NULL; @@ -369,16 +371,19 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) char *buf; int fd; uint len; + MY_STAT stat_info; - if (!(buf= (char *)my_malloc(MAX_BUF,myflags))) - return FALSE; + if (!my_stat(filename, &stat_info, MYF(MY_WME)) || + ((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) || + !(buf= (char *)my_malloc(len,myflags))) + return TRUE; if ((fd=my_open(filename,O_RDONLY,myflags)) < 0) { my_free(buf,myflags); return TRUE; } - len=read(fd,buf,MAX_BUF); + len=read(fd,buf,len); my_close(fd,myflags); if (my_parse_charset_xml(buf,len,add_collation)) @@ -532,14 +537,14 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) while we may changing the cs_info_table */ pthread_mutex_lock(&THR_LOCK_charset); - - cs= all_charsets[cs_number]; - - if (cs && !(cs->state & MY_CS_COMPILED) && !(cs->state & MY_CS_LOADED)) + if ((cs= all_charsets[cs_number])) { - strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS); - my_read_charset_file(buf,flags); - cs= (cs->state & MY_CS_LOADED) ? cs : NULL; + if (!(cs->state & MY_CS_COMPILED) && !(cs->state & MY_CS_LOADED)) + { + strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS); + my_read_charset_file(buf,flags); + } + cs= (cs->state & MY_CS_AVAILABLE) ? cs : NULL; } pthread_mutex_unlock(&THR_LOCK_charset); return cs; diff --git a/mysys/default.c b/mysys/default.c index 3a751eb4e29..a01ed4dd39f 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -224,7 +224,7 @@ int load_defaults(const char *conf_file, const char **groups, if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults")) { found_print_defaults=1; - --*argc; ++*argv; /* skipp argument */ + --*argc; ++*argv; /* skip argument */ } if (*argc) @@ -461,7 +461,8 @@ static char *remove_end_comment(char *ptr) else if (quote == *ptr) quote= 0; } - if (!quote && *ptr == '#') /* We are not inside a comment */ + /* We are not inside a comment */ + if (!quote && *ptr == '#') { *ptr= 0; return ptr; diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index b5c80d9482f..f64dc5abf2d 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -829,7 +829,7 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count) next_pos_in_file=(info->pos_in_file+ (uint) (info->read_end - info->request_pos)); - /* If reading large blocks, or first read or read with skipp */ + /* If reading large blocks, or first read or read with skip */ if (Count) { if (next_pos_in_file == info->end_of_file) @@ -1175,8 +1175,8 @@ int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) info IO_CACHE Handle to free NOTES - It's currently safe to call this if one has called io_cache_init() - on the 'info' object, even if io_cache_init() failed. + It's currently safe to call this if one has called init_io_cache() + on the 'info' object, even if init_io_cache() failed. This function is also safe to call twice with the same handle. RETURN diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index e2e811fe89a..638bbaf7baf 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -146,7 +146,7 @@ uint cleanup_dirname(register my_string to, const char *from) if (*pos == FN_LIBCHAR) { if ((uint) (pos-start) > length && bcmp(pos-length,parent,length) == 0) - { /* If .../../; skipp prev */ + { /* If .../../; skip prev */ pos-=length; if (pos != start) { /* not /../ */ diff --git a/mysys/mf_wcomp.c b/mysys/mf_wcomp.c index c2a103688f2..1a01388a3db 100644 --- a/mysys/mf_wcomp.c +++ b/mysys/mf_wcomp.c @@ -49,7 +49,7 @@ int wild_compare(register const char *str, register const char *wildstr, if (*wildstr++ == wild_one) { if (! *str || (str_is_pattern && *str == wild_many)) - DBUG_RETURN(1); /* One char; skipp */ + DBUG_RETURN(1); /* One char; skip */ if (*str++ == wild_prefix && str_is_pattern && *str) str++; } diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 76f8f6bf852..b278eaa36e1 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -285,6 +285,19 @@ int handle_options(int *argc, char ***argv, return EXIT_AMBIGUOUS_OPTION; } } + if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED) + { + if (my_getopt_print_errors) + fprintf(stderr, + "%s: %s: Option '%s' used, but is disabled\n", my_progname, + option_is_loose ? "WARNING" : "ERROR", opt_str); + if (option_is_loose) + { + (*argc)--; + continue; + } + return EXIT_OPTION_DISABLED; + } if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG) { if (my_getopt_print_errors) @@ -358,6 +371,14 @@ int handle_options(int *argc, char ***argv, { /* Option recognized. Find next what to do with it */ opt_found= 1; + if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED) + { + if (my_getopt_print_errors) + fprintf(stderr, + "%s: ERROR: Option '-%c' used, but is disabled\n", + my_progname, optp->id); + return EXIT_OPTION_DISABLED; + } if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL && optp->arg_type == NO_ARG) { @@ -550,7 +571,7 @@ static int findopt(char *optpat, uint length, const struct my_option **opt_res, char **ffname) { - int count; + uint count; struct my_option *opt= (struct my_option *) *opt_res; for (count= 0; opt->name; opt++) @@ -562,7 +583,8 @@ static int findopt(char *optpat, uint length, *ffname= (char *) opt->name; /* We only need to know one prev */ if (!opt->name[length]) /* Exact match */ return 1; - count++; + if (!count || strcmp(*ffname, opt->name)) /* Don't count synonyms */ + count++; } } return count; @@ -882,7 +904,8 @@ void my_print_variables(const struct my_option *options) longlong2str(*((ulonglong*) value), buff, 10); printf("%s\n", buff); break; - default: /* dummy default to avoid compiler warnings */ + default: + printf("(Disabled)\n"); break; } } diff --git a/mysys/my_new.cc b/mysys/my_new.cc index 5f2da90bbd1..ec27502d8aa 100644 --- a/mysys/my_new.cc +++ b/mysys/my_new.cc @@ -19,9 +19,9 @@ with gcc 3.0.x to avoid including libstdc++ */ -#include "mysys_priv.h" +#ifdef USE_MYSYS_NEW -#ifdef USE_MYSYS_NEW +#include "mysys_priv.h" void *operator new (size_t sz) { diff --git a/mysys/typelib.c b/mysys/typelib.c index e4eda5bd675..9aaf97d143f 100644 --- a/mysys/typelib.c +++ b/mysys/typelib.c @@ -66,7 +66,7 @@ int find_type(my_string x, TYPELIB *typelib, uint full_name) if (! *j) { while (*i == ' ') - i++; /* skipp_end_space */ + i++; /* skip_end_space */ if (! *i) DBUG_RETURN(pos+1); } diff --git a/netware/init_db.sql b/netware/init_db.sql index 4613e5c0274..063c1815eb1 100644 --- a/netware/init_db.sql +++ b/netware/init_db.sql @@ -24,3 +24,7 @@ CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) comment='Column privileges'; +CREATE TABLE help_topic (help_topic_id int unsigned NOT NULL, name varchar(64) NOT NULL, help_category_id smallint unsigned NOT NULL, description text NOT NULL, example text NOT NULL, url varchar(128) NOT NULL, primary key (help_topic_id), unique index (name))comment='help topics'; +CREATE TABLE help_category (help_category_id smallint unsigned NOT NULL, name varchar(64) NOT NULL, parent_category_id smallint unsigned null, url varchar(128) NOT NULL, primary key (help_category_id), unique index (name)) comment='help categories'; +CREATE TABLE help_keyword (help_keyword_id int unsigned NOT NULL, name varchar(64) NOT NULL, primary key (help_keyword_id), unique index (name)) comment='help keywords'; +CREATE TABLE help_relation (help_topic_id int unsigned NOT NULL references help_topic, help_keyword_id int unsigned NOT NULL references help_keyword, primary key (help_keyword_id, help_topic_id)) comment='keyword-topic relation'; diff --git a/netware/libmysql.imp b/netware/libmysql.imp index 75fcc8d1a99..977fb1b0b1f 100644 --- a/netware/libmysql.imp +++ b/netware/libmysql.imp @@ -77,7 +77,7 @@ mysql_thread_init, mysql_thread_safe,
mysql_use_result,
net_safe_read,
-simple_command,
+#simple_command, mysql_connect,
mysql_create_db,
mysql_drop_db,
diff --git a/sql-common/client.c b/sql-common/client.c index 176f3a41cde..af64bb2b210 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1403,15 +1403,15 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused))) before calling mysql_real_connect ! */ -static my_bool cli_mysql_read_query_result(MYSQL *mysql); -static MYSQL_RES *cli_mysql_use_result(MYSQL *mysql); +static my_bool cli_read_query_result(MYSQL *mysql); +static MYSQL_RES *cli_use_result(MYSQL *mysql); static MYSQL_METHODS client_methods= { - cli_mysql_read_query_result, + cli_read_query_result, cli_advanced_command, cli_read_rows, - cli_mysql_use_result, + cli_use_result, cli_fetch_lengths #ifndef MYSQL_SERVER ,cli_list_fields, @@ -1420,7 +1420,8 @@ static MYSQL_METHODS client_methods= cli_read_binary_rows, cli_unbuffered_fetch, NULL, - cli_read_statistic + cli_read_statistic, + cli_read_query_result #endif }; @@ -1429,14 +1430,13 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, uint port, const char *unix_socket,ulong client_flag) { - char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16]; - char *end,*host_info,*charset_name; + char buff[NAME_LEN+USERNAME_LENGTH+100]; + char *end,*host_info; my_socket sock; in_addr_t ip_addr; struct sockaddr_in sock_addr; ulong pkt_length; NET *net= &mysql->net; - uint charset_number; #ifdef MYSQL_SERVER thr_alarm_t alarmed; ALARM alarm_buff; @@ -1762,10 +1762,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, goto error; } - charset_number= mysql->server_language; - /* Set character set */ - if ((charset_name=mysql->options.charset_name)) + if (mysql->options.charset_name) { const char *save= charsets_dir; if (mysql->options.charset_dir) @@ -1773,44 +1771,34 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->charset=get_charset_by_csname(mysql->options.charset_name, MY_CS_PRIMARY, MYF(MY_WME)); - charset_number= mysql->charset ? mysql->charset->number : 0; charsets_dir= save; - } - else if (mysql->server_language) - { - charset_name=charset_name_buff; - /* Save name in case of errors */ - int10_to_str(mysql->server_language, charset_name, 10); - if (!(mysql->charset = - get_charset((uint8) mysql->server_language, MYF(0)))) - mysql->charset = default_charset_info; /* shouldn't be fatal */ - } - else - { - mysql->charset= default_charset_info; - charset_number= mysql->charset->number; - } - if (!mysql->charset) - { - net->last_errno=CR_CANT_READ_CHARSET; - strmov(net->sqlstate, unknown_sqlstate); - if (mysql->options.charset_dir) - my_snprintf(net->last_error, sizeof(net->last_error)-1, - ER(net->last_errno), - charset_name ? charset_name : "unknown", - mysql->options.charset_dir); - else + if (!mysql->charset) { - char cs_dir_name[FN_REFLEN]; - get_charsets_dir(cs_dir_name); - my_snprintf(net->last_error, sizeof(net->last_error)-1, + net->last_errno=CR_CANT_READ_CHARSET; + strmov(net->sqlstate, unknown_sqlstate); + if (mysql->options.charset_dir) + my_snprintf(net->last_error, sizeof(net->last_error)-1, + ER(net->last_errno), + mysql->options.charset_name, + mysql->options.charset_dir); + else + { + char cs_dir_name[FN_REFLEN]; + get_charsets_dir(cs_dir_name); + my_snprintf(net->last_error, sizeof(net->last_error)-1, ER(net->last_errno), - charset_name ? charset_name : "unknown", + mysql->options.charset_name, cs_dir_name); + } + goto error; } - goto error; } + else + { + mysql->charset= default_charset_info; + } + /* Save connection information */ if (!my_multi_malloc(MYF(0), @@ -1870,7 +1858,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, /* 4.1 server and 4.1 client has a 32 byte option flag */ int4store(buff,client_flag); int4store(buff+4, net->max_packet_size); - buff[8]= (char) charset_number; + buff[8]= (char) mysql->charset->number; bzero(buff+9, 32-9); end= buff+32; } @@ -2022,7 +2010,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, goto error; if (mysql->fields) { - if (!(res= cli_mysql_use_result(mysql))) + if (!(res= cli_use_result(mysql))) goto error; mysql_free_result(res); } @@ -2240,13 +2228,13 @@ void STDCALL mysql_close(MYSQL *mysql) DBUG_VOID_RETURN; } -static my_bool cli_mysql_read_query_result(MYSQL *mysql) +static my_bool cli_read_query_result(MYSQL *mysql) { uchar *pos; ulong field_count; MYSQL_DATA *fields; ulong length; - DBUG_ENTER("cli_mysql_read_query_result"); + DBUG_ENTER("cli_read_query_result"); /* Read from the connection which we actually used, which @@ -2419,10 +2407,10 @@ MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql) have to wait for the client (and will not wait more than 30 sec/packet). **************************************************************************/ -static MYSQL_RES * cli_mysql_use_result(MYSQL *mysql) +static MYSQL_RES * cli_use_result(MYSQL *mysql) { MYSQL_RES *result; - DBUG_ENTER("cli_mysql_use_result"); + DBUG_ENTER("cli_use_result"); mysql = mysql->last_used_con; diff --git a/sql/Makefile.am b/sql/Makefile.am index 7353b58df07..045b3e64698 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -52,7 +52,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ field.h handler.h \ ha_isammrg.h ha_isam.h ha_myisammrg.h\ ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h \ - opt_range.h opt_ft.h protocol.h \ + opt_range.h protocol.h \ sql_select.h structs.h table.h sql_udf.h hash_filo.h\ lex.h lex_symbol.h sql_acl.h sql_crypt.h \ log_event.h sql_repl.h slave.h \ @@ -76,7 +76,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ procedure.cc item_uniq.cc sql_test.cc \ log.cc log_event.cc init.cc derror.cc sql_acl.cc \ unireg.cc des_key_file.cc \ - time.cc opt_range.cc opt_sum.cc opt_ft.cc \ + time.cc opt_range.cc opt_sum.cc \ records.cc filesort.cc handler.cc \ ha_heap.cc ha_myisam.cc ha_myisammrg.cc \ ha_berkeley.cc ha_innodb.cc \ diff --git a/sql/field.cc b/sql/field.cc index a9029b893e3..d26534b5ac7 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4055,44 +4055,45 @@ void Field_datetime::sql_type(String &res) const /* Copy a string and fill with space */ -static bool use_conversion(CHARSET_INFO *cs1, CHARSET_INFO *cs2) -{ - return (cs1 != &my_charset_bin) && (cs2 != &my_charset_bin) && (cs1!=cs2); -} - int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) { int error= 0; + uint32 not_used; char buff[80]; String tmpstr(buff,sizeof(buff), &my_charset_bin); + uint copy_length; + /* Convert character set if nesessary */ - if (use_conversion(cs, field_charset)) + if (String::needs_conversion(length, cs, field_charset, ¬_used)) { tmpstr.copy(from, length, cs, field_charset); from= tmpstr.ptr(); length= tmpstr.length(); } - if (length <= field_length) - { - memcpy(ptr,from,length); - if (length < field_length) - field_charset->cset->fill(field_charset,ptr+length,field_length-length, - ' '); - } - else - { - memcpy(ptr,from,field_length); - if (current_thd->count_cuted_fields) - { // Check if we loosed some info - const char *end=from+length; - from+= field_length; - from+= field_charset->cset->scan(field_charset, from, end, - MY_SEQ_SPACES); - if (from != end) - { - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); - error=1; - } + + /* + Make sure we don't break a multibyte sequence + as well as don't copy a malformed data. + */ + copy_length= field_charset->cset->wellformedlen(field_charset, + from,from+length, + field_length/ + field_charset->mbmaxlen); + memcpy(ptr,from,copy_length); + if (copy_length < field_length) // Append spaces if shorter + field_charset->cset->fill(field_charset,ptr+copy_length, + field_length-copy_length,' '); + + if ((copy_length < length) && current_thd->count_cuted_fields) + { // Check if we loosed some info + const char *end=from+length; + from+= copy_length; + from+= field_charset->cset->scan(field_charset, from, end, + MY_SEQ_SPACES); + if (from != end) + { + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); + error=1; } } return error; @@ -4251,10 +4252,12 @@ uint Field_string::max_packed_col_length(uint max_length) int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) { int error= 0; + uint32 not_used; char buff[80]; String tmpstr(buff,sizeof(buff), &my_charset_bin); + /* Convert character set if nesessary */ - if (use_conversion(cs, field_charset)) + if (String::needs_conversion(length, cs, field_charset, ¬_used)) { tmpstr.copy(from, length, cs, field_charset); from= tmpstr.ptr(); @@ -4470,7 +4473,7 @@ Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, :Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg, cs), - geom_flag(true), packlength(blob_pack_length) + packlength(blob_pack_length) { flags|= BLOB_FLAG; if (table) @@ -4482,19 +4485,9 @@ void Field_blob::store_length(uint32 number) { switch (packlength) { case 1: - if (number > 255) - { - number=255; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); - } ptr[0]= (uchar) number; break; case 2: - if (number > (uint16) ~0) - { - number= (uint16) ~0; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); - } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -4505,11 +4498,6 @@ void Field_blob::store_length(uint32 number) shortstore(ptr,(unsigned short) number); break; case 3: - if (number > (uint32) (1L << 24)) - { - number= (uint32) (1L << 24)-1L; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); - } int3store(ptr,number); break; case 4: @@ -4567,21 +4555,36 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) } else { + bool was_conversion; char buff[80]; String tmpstr(buff,sizeof(buff), &my_charset_bin); + uint copy_length; + uint32 not_used; + /* Convert character set if nesessary */ - if (use_conversion(cs, field_charset)) + if ((was_conversion= String::needs_conversion(length, cs, field_charset, + ¬_used))) { tmpstr.copy(from, length, cs, field_charset); from= tmpstr.ptr(); length= tmpstr.length(); } - Field_blob::store_length(length); - if (table->copy_blobs || length <= MAX_FIELD_WIDTH) + + copy_length= max_data_length(); + if (copy_length > length) + copy_length= length; + copy_length= field_charset->cset->wellformedlen(field_charset, + from,from+copy_length, + field_length); + if (copy_length < length) + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); + + Field_blob::store_length(copy_length); + if (was_conversion || table->copy_blobs || copy_length <= MAX_FIELD_WIDTH) { // Must make a copy if (from != value.ptr()) // For valgrind { - value.copy(from,length,charset()); + value.copy(from,copy_length,charset()); from=value.ptr(); } } @@ -4705,6 +4708,7 @@ void Field_blob::get_key_image(char *buff,uint length, uint32 blob_length= get_length(ptr); char *blob; +#ifdef HAVE_SPATIAL if (type == itMBR) { if (!blob_length) @@ -4721,6 +4725,7 @@ void Field_blob::get_key_image(char *buff,uint length, float8store(buff+24, mbr.ymax); return; } +#endif /*HAVE_SPATIAL*/ if ((uint32) length > blob_length) { @@ -4930,6 +4935,7 @@ uint Field_blob::max_packed_col_length(uint max_length) return (max_length > 255 ? 2 : 1)+max_length; } +#ifdef HAVE_SPATIAL void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs, imagetype type) @@ -5013,6 +5019,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) return 0; } +#endif /*HAVE_SPATIAL*/ /**************************************************************************** ** enum type. @@ -5077,10 +5084,12 @@ void Field_enum::store_type(ulonglong value) int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) { int err= 0; + uint32 not_used; char buff[80]; String tmpstr(buff,sizeof(buff), &my_charset_bin); + /* Convert character set if nesessary */ - if (use_conversion(cs, field_charset)) + if (String::needs_conversion(length, cs, field_charset, ¬_used)) { tmpstr.copy(from, length, cs, field_charset); from= tmpstr.ptr(); @@ -5257,11 +5266,12 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) int err= 0; char *not_used; uint not_used2; + uint32 not_used_offset; char buff[80]; String tmpstr(buff,sizeof(buff), &my_charset_bin); /* Convert character set if nesessary */ - if (use_conversion(cs, field_charset)) + if (String::needs_conversion(length, cs, field_charset, ¬_used_offset)) { tmpstr.copy(from, length, cs, field_charset); from= tmpstr.ptr(); @@ -5488,10 +5498,12 @@ Field *make_field(char *ptr, uint32 field_length, f_packtype(pack_flag), field_length); +#ifdef HAVE_SPATIAL if (f_is_geom(pack_flag)) return new Field_geom(ptr,null_pos,null_bit, unireg_check, field_name, table, pack_length, geom_type); +#endif if (f_is_blob(pack_flag)) return new Field_blob(ptr,null_pos,null_bit, unireg_check, field_name, table, @@ -5609,16 +5621,16 @@ create_field::create_field(Field *old_field,Field *orig_field) case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break; default: sql_type= FIELD_TYPE_LONG_BLOB; break; } - length /= charset->mbmaxlen; // QQ: Probably not needed + length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; // QQ: Probably not needed break; case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: - length /= charset->mbmaxlen; + length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; break; default: break; } - + decimals= old_field->decimals(); if (sql_type == FIELD_TYPE_STRING) { @@ -5651,10 +5663,12 @@ create_field::create_field(Field *old_field,Field *orig_field) def=new Item_string(pos,tmp.length(), charset); } } +#ifdef HAVE_SPATIAL if (sql_type == FIELD_TYPE_GEOMETRY) { geom_type= ((Field_geom*)old_field)->geom_type; } +#endif } diff --git a/sql/field.h b/sql/field.h index e3b4bf29fb8..b62b7a7859e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -913,7 +913,6 @@ public: class Field_blob :public Field_str { - bool geom_flag; protected: uint packlength; String value; // For temporaries @@ -926,7 +925,7 @@ public: struct st_table *table_arg, CHARSET_INFO *cs) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, table_arg, cs), - geom_flag(true), packlength(4) + packlength(4) { flags|= BLOB_FLAG; } @@ -950,6 +949,15 @@ public: void sort_string(char *buff,uint length); uint32 pack_length() const { return (uint32) (packlength+table->blob_ptr_size); } + uint32 max_data_length() const + { + switch (packlength) { + case 1: return 255; + case 2: return (uint32) 0xFFFFL; + case 3: return (uint32) 0xFFFFFF; + default: return (uint32) 0xFFFFFFFF; + } + } void reset(void) { bzero(ptr, packlength+sizeof(char*)); } void reset_fields() { bzero((char*) &value,sizeof(value)); } void store_length(uint32 number); @@ -1001,7 +1009,7 @@ public: field_cast_enum field_cast_type() { return FIELD_CAST_BLOB; } }; - +#ifdef HAVE_SPATIAL class Field_geom :public Field_blob { public: enum geometry_type geom_type; @@ -1029,7 +1037,7 @@ public: void set_key_image(char *buff,uint length, CHARSET_INFO *cs); field_cast_enum field_cast_type() { return FIELD_CAST_GEOM; } }; - +#endif /*HAVE_SPATIAL*/ class Field_enum :public Field_str { protected: diff --git a/sql/filesort.cc b/sql/filesort.cc index 1d06846e8b0..d09b8936d42 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -423,7 +423,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, } if (error == 0) param->examined_rows++; - if (error == 0 && (!select || select->skipp_record() == 0)) + if (error == 0 && (!select || select->skip_record() == 0)) { if (idx == param->keys) { diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 7126b7ee577..6df7d867a4d 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -81,9 +81,10 @@ TODO: #endif #include <my_getopt.h> #include "mysql_version.h" +#include "mysql_priv.h" #include "lex.h" -static struct my_option my_long_options[] = +struct my_option my_long_options[] = { {"help", '?', "Display help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index ae0267b98f3..c1228cbd319 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -40,6 +40,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) if (!create(name, table, &create_info)) file= heap_open(name, mode); } + ref_length= sizeof(HEAP_PTR); return (file ? 0 : 1); } @@ -335,7 +336,6 @@ int ha_heap::create(const char *name, TABLE *table_arg, my_free((gptr) keydef, MYF(0)); if (file) info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); - ref_length= sizeof(HEAP_PTR); return (error); } diff --git a/sql/handler.cc b/sql/handler.cc index e9eecabaa84..0191a7139cd 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1115,10 +1115,12 @@ int handler::delete_all_rows() bool handler::caching_allowed(THD* thd, char* table_key, uint key_length, uint8 cache_type) { +#ifdef HAVE_INNOBASE_DB if (cache_type == HA_CACHE_TBL_ASKTRANSACT) return innobase_query_caching_of_table_permitted(thd, table_key, key_length); else +#endif return 1; } diff --git a/sql/item.cc b/sql/item.cc index 8744bc3574b..7143c8d2f12 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -72,18 +72,18 @@ Item::Item(): Used for duplicating lists in processing queries with temporary tables */ -Item::Item(THD *thd, Item &item): - str_value(item.str_value), - name(item.name), - max_length(item.max_length), - marker(item.marker), - decimals(item.decimals), - maybe_null(item.maybe_null), - null_value(item.null_value), - unsigned_flag(item.unsigned_flag), - with_sum_func(item.with_sum_func), - fixed(item.fixed), - collation(item.collation) +Item::Item(THD *thd, Item *item): + str_value(item->str_value), + name(item->name), + max_length(item->max_length), + marker(item->marker), + decimals(item->decimals), + maybe_null(item->maybe_null), + null_value(item->null_value), + unsigned_flag(item->unsigned_flag), + with_sum_func(item->with_sum_func), + fixed(item->fixed), + collation(item->collation) { next= thd->free_list; // Put in free list thd->free_list= this; @@ -111,12 +111,12 @@ Item_ident::Item_ident(const char *db_name_par,const char *table_name_par, } // Constructor used by Item_field & Item_ref (see Item comment) -Item_ident::Item_ident(THD *thd, Item_ident &item): +Item_ident::Item_ident(THD *thd, Item_ident *item): Item(thd, item), - db_name(item.db_name), - table_name(item.table_name), - field_name(item.field_name), - depended_from(item.depended_from) + db_name(item->db_name), + table_name(item->table_name), + field_name(item->field_name), + depended_from(item->depended_from) {} bool Item_ident::remove_dependence_processor(byte * arg) @@ -327,10 +327,10 @@ Item_field::Item_field(Field *f) } // Constructor need to process subselect with temporary tables (see Item) -Item_field::Item_field(THD *thd, Item_field &item) +Item_field::Item_field(THD *thd, Item_field *item) :Item_ident(thd, item), - field(item.field), - result_field(item.result_field) + field(item->field), + result_field(item->result_field) { collation.set(DERIVATION_IMPLICIT); item_equal= item.item_equal; @@ -487,7 +487,7 @@ table_map Item_field::used_tables() const Item *Item_field::get_tmp_table_item(THD *thd) { - Item_field *new_item= new Item_field(thd, *this); + Item_field *new_item= new Item_field(thd, this); if (new_item) new_item->field= new_item->result_field; return new_item; @@ -600,6 +600,8 @@ void Item_param::set_time(TIME *tm, timestamp_type type) ltime.second_part= tm->second_part; + ltime.neg= tm->neg; + ltime.time_type= type; item_is_time= true; @@ -952,6 +954,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item_ref *rf; *ref= rf= new Item_ref(last->ref_pointer_array + counter, + ref, (char *)table_name, (char *)field_name); if (!rf) @@ -968,7 +971,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (last->having_fix_field) { Item_ref *rf; - *ref= rf= new Item_ref((where->db[0]?where->db:0), + *ref= rf= new Item_ref(ref, *ref, + (where->db[0]?where->db:0), (char *)where->alias, (char *)field_name); if (!rf) @@ -994,6 +998,10 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 0; } +void Item_field::cleanup() +{ + Item_ident::cleanup(); + field= result_field= 0; /* Find a field among specified multiple equalities @@ -1749,6 +1757,14 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) } +void Item_ref::cleanup() +{ + Item_ident::cleanup(); + if (hook_ptr) + *hook_ptr= orig_item; +} + + void Item_ref::print(String *str) { if (ref && *ref) @@ -1912,17 +1928,9 @@ Item *resolve_const_item(Item *item,Item *comp_item) String tmp(buff,sizeof(buff),&my_charset_bin),*result; result=item->val_str(&tmp); if (item->null_value) - { -#ifdef DELETE_ITEMS - delete item; -#endif return new Item_null(name); - } uint length=result->length(); char *tmp_str=sql_strmake(result->ptr(),length); -#ifdef DELETE_ITEMS - delete item; -#endif return new Item_string(name,tmp_str,length,result->charset()); } if (res_type == INT_RESULT) @@ -1930,9 +1938,6 @@ Item *resolve_const_item(Item *item,Item *comp_item) longlong result=item->val_int(); uint length=item->max_length; bool null_value=item->null_value; -#ifdef DELETE_ITEMS - delete item; -#endif return (null_value ? (Item*) new Item_null(name) : (Item*) new Item_int(name,result,length)); } @@ -1941,9 +1946,6 @@ Item *resolve_const_item(Item *item,Item *comp_item) double result=item->val(); uint length=item->max_length,decimals=item->decimals; bool null_value=item->null_value; -#ifdef DELETE_ITEMS - delete item; -#endif return (null_value ? (Item*) new Item_null(name) : (Item*) new Item_real(name,result,decimals,length)); } @@ -2015,7 +2017,6 @@ void Item_cache_int::store(Item *item) { value= item->val_int_result(); null_value= item->null_value; - collation.set(item->collation); } @@ -2023,7 +2024,6 @@ void Item_cache_real::store(Item *item) { value= item->val_result(); null_value= item->null_value; - collation.set(item->collation); } @@ -2046,7 +2046,6 @@ void Item_cache_str::store(Item *item) value_buff.copy(*value); value= &value_buff; } - collation.set(item->collation); } @@ -2160,7 +2159,8 @@ void Item_cache_row::bring_value() Item_type_holder::Item_type_holder(THD *thd, Item *item) - :Item(thd, *item), item_type(item->result_type()) + :Item(thd, item), item_type(item->result_type()), + orig_type(item_type) { DBUG_ASSERT(item->fixed); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e0bdae769ed..9aa69ee4a0e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -496,7 +496,6 @@ longlong Item_func_eq::val_int() return value == 0 ? 1 : 0; } - /* Same as Item_func_eq, but NULL = NULL */ void Item_func_equal::fix_length_and_dec() @@ -1652,32 +1651,25 @@ longlong Item_func_bit_and::val_int() return (longlong) (arg1 & arg2); } -Item_cond::Item_cond(THD *thd, Item_cond &item) +Item_cond::Item_cond(THD *thd, Item_cond *item) :Item_bool_func(thd, item), - abort_on_null(item.abort_on_null), - and_tables_cache(item.and_tables_cache) + abort_on_null(item->abort_on_null), + and_tables_cache(item->and_tables_cache) { /* - here should be following text: - - List_iterator_fast<Item*> li(item.list); - while(Item *it= li++) - list.push_back(it); - - but it do not need, - because this constructor used only for AND/OR and - argument list will be copied by copy_andor_arguments call + item->list will be copied by copy_andor_arguments() call */ - } + void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item) { List_iterator_fast<Item> li(item->list); - while(Item *it= li++) + while (Item *it= li++) list.push_back(it->copy_andor_structure(thd)); } + bool Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { @@ -1704,9 +1696,6 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { // Identical function li.replace(((Item_cond*) item)->list); ((Item_cond*) item)->list.empty(); -#ifdef DELETE_ITEMS - delete (Item_cond*) item; -#endif item= *li.ref(); // new current item } if (abort_on_null) @@ -1792,7 +1781,7 @@ void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields) uint el= fields.elements; fields.push_front(item); ref_pointer_array[el]= item; - li.replace(new Item_ref(ref_pointer_array + el, 0, item->name)); + li.replace(new Item_ref(ref_pointer_array + el, li.ref(), 0, item->name)); } item->update_used_tables(); used_tables_cache|=item->used_tables(); @@ -2236,11 +2225,11 @@ void Item_func_like::turboBM_compute_suffixes(int *suff) int f = 0; int g = plm1; int *const splm1 = suff + plm1; - CHARSET_INFO *cs=system_charset_info; // QQ Needs to be fixed + CHARSET_INFO *cs= cmp.cmp_collation.collation; *splm1 = pattern_len; - if (cmp.cmp_collation.collation == &my_charset_bin) + if (cs == &my_charset_bin) { int i; for (i = pattern_len - 2; i >= 0; i--) @@ -2338,12 +2327,12 @@ void Item_func_like::turboBM_compute_bad_character_shifts() int *end = bmBc + alphabet_size; int j; const int plm1 = pattern_len - 1; - CHARSET_INFO *cs=system_charset_info; // QQ Needs to be fixed + CHARSET_INFO *cs= cmp.cmp_collation.collation; for (i = bmBc; i < end; i++) *i = pattern_len; - if (cmp.cmp_collation.collation == &my_charset_bin) + if (cs == &my_charset_bin) { for (j = 0; j < plm1; j++) bmBc[(uint) (uchar) pattern[j]] = plm1 - j; @@ -2368,13 +2357,13 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const int shift = pattern_len; int j = 0; int u = 0; - CHARSET_INFO *cs= cmp.cmp_collation.collation; // QQ Needs to be fixed + CHARSET_INFO *cs= cmp.cmp_collation.collation; const int plm1= pattern_len - 1; const int tlmpl= text_len - pattern_len; /* Searching */ - if (cmp.cmp_collation.collation == &my_charset_bin) + if (cs == &my_charset_bin) { while (j <= tlmpl) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index d7cd0d93588..39b4e1802e1 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -87,7 +87,7 @@ public: Item_bool_func() :Item_int_func() {} Item_bool_func(Item *a) :Item_int_func(a) {} Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {} - Item_bool_func(THD *thd, Item_bool_func &item) :Item_int_func(thd, item) {} + Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {} void fix_length_and_dec() { decimals=0; max_length=1; } }; @@ -196,17 +196,26 @@ public: bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } void print(String *str) { Item_func::print_op(str); } bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); } + CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; } friend class Arg_comparator; }; class Item_bool_rowready_func2 :public Item_bool_func2 { + Item *orig_a, *orig_b; /* propagate_const can change parameters */ public: - Item_bool_rowready_func2(Item *a,Item *b) :Item_bool_func2(a,b) + Item_bool_rowready_func2(Item *a,Item *b) :Item_bool_func2(a,b), + orig_a(a), orig_b(b) { allowed_arg_cols= a->cols(); } + void cleanup() + { + Item_bool_func2::cleanup(); + tmp_arg[0]= orig_a; + tmp_arg[1]= orig_b; + } }; class Item_func_not :public Item_bool_func @@ -337,6 +346,7 @@ public: const char *func_name() const { return "between"; } void fix_length_and_dec(); void print(String *str); + CHARSET_INFO *compare_collation() { return cmp_collation.collation; } }; @@ -476,6 +486,7 @@ public: const char *func_name() const { return "case"; } void print(String *str); Item *find_item(String *str); + CHARSET_INFO *compare_collation() { return cmp_collation.collation; } }; @@ -710,10 +721,6 @@ class Item_func_in :public Item_int_func } longlong val_int(); void fix_length_and_dec(); - ~Item_func_in() - { - cleanup(); /* This is not called by Item::~Item() */ - } void cleanup() { delete array; @@ -727,6 +734,7 @@ class Item_func_in :public Item_int_func enum Functype functype() const { return IN_FUNC; } const char *func_name() const { return " IN "; } bool nulls_in_row(); + CHARSET_INFO *compare_collation() { return cmp_collation.collation; } }; /* Functions used by where clause */ @@ -767,6 +775,7 @@ public: table_map not_null_tables() const { return 0; } optimize_type select_optimize() const { return OPTIMIZE_NULL; } Item *neg_transformer(); + CHARSET_INFO *compare_collation() { return args[0]->collation.collation; } }; /* Functions used by HAVING for rewriting IN subquery */ @@ -801,6 +810,7 @@ public: table_map not_null_tables() const { return 0; } Item *neg_transformer(); void print(String *str); + CHARSET_INFO *compare_collation() { return args[0]->collation.collation; } }; @@ -855,6 +865,7 @@ public: bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); const char *func_name() const { return "regexp"; } void print(String *str) { print_op(str); } + CHARSET_INFO *compare_collation() { return cmp_collation.collation; } }; #else @@ -890,10 +901,9 @@ public: list.push_back(i1); list.push_back(i2); } - Item_cond(THD *thd, Item_cond &item); + Item_cond(THD *thd, Item_cond *item); Item_cond(List<Item> &nlist) :Item_bool_func(), list(nlist), abort_on_null(0) {} - ~Item_cond() { list.delete_elements(); } bool add(Item *item) { return list.push_back(item); } void add_at_head(List<Item> *nlist) { list.prepand(nlist); } bool fix_fields(THD *, struct st_table_list *, Item **ref); @@ -1053,7 +1063,7 @@ public: to multiple equalities of upper and levels */ Item_cond_and() :Item_cond() {} Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {} - Item_cond_and(THD *thd, Item_cond_and &item) :Item_cond(thd, item) {} + Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {} Item_cond_and(List<Item> &list): Item_cond(list) {} enum Functype functype() const { return COND_AND_FUNC; } longlong val_int(); @@ -1061,7 +1071,7 @@ public: Item* copy_andor_structure(THD *thd) { Item_cond_and *item; - if((item= new Item_cond_and(thd, *this))) + if ((item= new Item_cond_and(thd, this))) item->copy_andor_arguments(thd, this); return item; } @@ -1073,7 +1083,7 @@ class Item_cond_or :public Item_cond public: Item_cond_or() :Item_cond() {} Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {} - Item_cond_or(THD *thd, Item_cond_or &item) :Item_cond(thd, item) {} + Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {} Item_cond_or(List<Item> &list): Item_cond(list) {} enum Functype functype() const { return COND_OR_FUNC; } longlong val_int(); @@ -1082,7 +1092,7 @@ public: Item* copy_andor_structure(THD *thd) { Item_cond_or *item; - if((item= new Item_cond_or(thd, *this))) + if ((item= new Item_cond_or(thd, this))) item->copy_andor_arguments(thd, this); return item; } diff --git a/sql/item_create.cc b/sql/item_create.cc index cccbf6e4226..6519e242465 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -478,6 +478,7 @@ Item *create_func_quote(Item* a) return new Item_func_quote(a); } +#ifdef HAVE_SPATIAL Item *create_func_as_wkt(Item *a) { return new Item_func_as_wkt(a); @@ -637,6 +638,7 @@ Item *create_func_point(Item *a, Item *b) { return new Item_func_point(a, b); } +#endif /*HAVE_SPATIAL*/ Item *create_func_crc32(Item* a) { diff --git a/sql/item_create.h b/sql/item_create.h index b445eab3bac..5dc53fb04b8 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -98,6 +98,8 @@ Item *create_func_is_free_lock(Item* a); Item *create_func_is_used_lock(Item* a); Item *create_func_quote(Item* a); +#ifdef HAVE_SPATIAL + Item *create_func_geometry_from_text(Item *a); Item *create_func_as_wkt(Item *a); Item *create_func_as_wkb(Item *a); @@ -137,6 +139,8 @@ Item *create_func_numgeometries(Item *a); Item *create_func_point(Item *a, Item *b); +#endif /*HAVE_SPATIAL*/ + Item *create_func_compress(Item *a); Item *create_func_uncompress(Item *a); Item *create_func_uncompressed_length(Item *a); diff --git a/sql/item_func.cc b/sql/item_func.cc index 14ce7f79f47..5d9507f435e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -133,13 +133,13 @@ Item_func::Item_func(List<Item> &list) set_arguments(list); } -Item_func::Item_func(THD *thd, Item_func &item) +Item_func::Item_func(THD *thd, Item_func *item) :Item_result_field(thd, item), - allowed_arg_cols(item.allowed_arg_cols), - arg_count(item.arg_count), - used_tables_cache(item.used_tables_cache), - not_null_tables_cache(item.not_null_tables_cache), - const_item_cache(item.const_item_cache) + allowed_arg_cols(item->allowed_arg_cols), + arg_count(item->arg_count), + used_tables_cache(item->used_tables_cache), + not_null_tables_cache(item->not_null_tables_cache), + const_item_cache(item->const_item_cache) { if (arg_count) { @@ -150,7 +150,7 @@ Item_func::Item_func(THD *thd, Item_func &item) if (!(args=(Item**) thd->alloc(sizeof(Item*)*arg_count))) return; } - memcpy((char*) args, (char*) item.args, sizeof(Item*)*arg_count); + memcpy((char*) args, (char*) item->args, sizeof(Item*)*arg_count); } } @@ -294,7 +294,7 @@ void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields) uint el= fields.elements; fields.push_front(item); ref_pointer_array[el]= item; - *arg= new Item_ref(ref_pointer_array + el, 0, item->name); + *arg= new Item_ref(ref_pointer_array + el, arg, 0, item->name); } } } @@ -1110,7 +1110,8 @@ String *Item_func_min_max::val_str(String *str) } } } - res->set_charset(collation.collation); + if (res) // If !NULL + res->set_charset(collation.collation); return res; } case ROW_RESULT: @@ -1600,7 +1601,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, if ((error=(uchar) init(&initid, &f_args, thd->net.last_error))) { my_printf_error(ER_CANT_INITIALIZE_UDF,ER(ER_CANT_INITIALIZE_UDF),MYF(0), - u_d->name,thd->net.last_error); + u_d->name.str, thd->net.last_error); free_udf(u_d); DBUG_RETURN(1); } @@ -1613,7 +1614,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, if (error) { my_printf_error(ER_CANT_INITIALIZE_UDF,ER(ER_CANT_INITIALIZE_UDF),MYF(0), - u_d->name, ER(ER_UNKNOWN_ERROR)); + u_d->name.str, ER(ER_UNKNOWN_ERROR)); DBUG_RETURN(1); } DBUG_RETURN(0); @@ -2212,6 +2213,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, is different from query_id). */ entry->update_query_id= thd->query_id; + entry->collation.set(args[0]->collation); cached_result_type= args[0]->result_type(); return 0; } @@ -2223,6 +2225,7 @@ Item_func_set_user_var::fix_length_and_dec() maybe_null=args[0]->maybe_null; max_length=args[0]->max_length; decimals=args[0]->decimals; + collation.set(args[0]->collation); } @@ -2537,6 +2540,9 @@ void Item_func_get_user_var::fix_length_and_dec() if (!(var_entry= get_variable(&thd->user_vars, name, 0))) null_value= 1; + else + collation.set(var_entry->collation); + if (!(opt_bin_log && is_update_query(thd->lex->sql_command))) return; @@ -2662,6 +2668,7 @@ longlong Item_func_inet_aton::val_int() const char *p,* end; char c = '.'; // we mark c to indicate invalid IP in case length is 0 char buff[36]; + int dot_count= 0; String *s,tmp(buff,sizeof(buff),&my_charset_bin); if (!(s = args[0]->val_str(&tmp))) // If null value @@ -2680,6 +2687,7 @@ longlong Item_func_inet_aton::val_int() } else if (c == '.') { + dot_count++; result= (result << 8) + (ulonglong) byte_result; byte_result = 0; } @@ -2687,7 +2695,19 @@ longlong Item_func_inet_aton::val_int() goto err; // Invalid character } if (c != '.') // IP number can't end on '.' + { + /* + Handle short-forms addresses according to standard. Examples: + 127 -> 0.0.0.127 + 127.1 -> 127.0.0.1 + 127.2.1 -> 127.2.0.1 + */ + switch (dot_count) { + case 1: result<<= 8; /* Fall through */ + case 2: result<<= 8; /* Fall through */ + } return (result << 8) + (ulonglong) byte_result; + } err: null_value=1; diff --git a/sql/item_func.h b/sql/item_func.h index 1e274237cb8..a1994fffc70 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -109,8 +109,7 @@ public: } Item_func(List<Item> &list); // Constructor used for Item_cond_and/or (see Item comment) - Item_func(THD *thd, Item_func &item); - ~Item_func() {} /* Nothing to do; Items are freed automaticly */ + Item_func(THD *thd, Item_func *item); bool fix_fields(THD *,struct st_table_list *, Item **ref); table_map used_tables() const; table_map not_null_tables() const; @@ -204,7 +203,7 @@ public: Item_int_func(Item *a,Item *b) :Item_func(a,b) { max_length=21; } Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { max_length=21; } Item_int_func(List<Item> &list) :Item_func(list) { max_length=21; } - Item_int_func(THD *thd, Item_int_func &item) :Item_func(thd, item) {} + Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {} double val() { return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } @@ -216,20 +215,28 @@ class Item_func_signed :public Item_int_func { public: Item_func_signed(Item *a) :Item_int_func(a) {} - double val() { return args[0]->val(); } - longlong val_int() { return args[0]->val_int(); } + double val() + { + double tmp= args[0]->val(); + null_value= args[0]->null_value; + return tmp; + } + longlong val_int() + { + longlong tmp= args[0]->val_int(); + null_value= args[0]->null_value; + return tmp; + } void fix_length_and_dec() { max_length=args[0]->max_length; unsigned_flag=0; } void print(String *str); }; -class Item_func_unsigned :public Item_int_func +class Item_func_unsigned :public Item_func_signed { public: - Item_func_unsigned(Item *a) :Item_int_func(a) {} - double val() { return args[0]->val(); } - longlong val_int() { return args[0]->val_int(); } + Item_func_unsigned(Item *a) :Item_func_signed(a) {} void fix_length_and_dec() { max_length=args[0]->max_length; unsigned_flag=1; } void print(String *str); @@ -759,7 +766,6 @@ public: Item_udf_func(udf_func *udf_arg) :Item_func(), udf(udf_arg) {} Item_udf_func(udf_func *udf_arg, List<Item> &list) :Item_func(list), udf(udf_arg) {} - ~Item_udf_func() {} const char *func_name() const { return udf.name(); } bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref) { @@ -780,7 +786,6 @@ class Item_func_udf_float :public Item_udf_func Item_func_udf_float(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - ~Item_func_udf_float() {} longlong val_int() { return (longlong) Item_func_udf_float::val(); } double val(); String *val_str(String *str); @@ -794,7 +799,6 @@ public: Item_func_udf_int(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - ~Item_func_udf_int() {} longlong val_int(); double val() { return (double) Item_func_udf_int::val_int(); } String *val_str(String *str); @@ -809,7 +813,6 @@ public: Item_func_udf_str(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - ~Item_func_udf_str() {} String *val_str(String *); double val() { @@ -834,7 +837,6 @@ class Item_func_udf_float :public Item_real_func public: Item_func_udf_float(udf_func *udf_arg) :Item_real_func() {} Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_real_func(list) {} - ~Item_func_udf_float() {} double val() { return 0.0; } }; @@ -844,7 +846,6 @@ class Item_func_udf_int :public Item_int_func public: Item_func_udf_int(udf_func *udf_arg) :Item_int_func() {} Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_int_func(list) {} - ~Item_func_udf_int() {} longlong val_int() { return 0; } }; @@ -854,7 +855,6 @@ class Item_func_udf_str :public Item_func public: Item_func_udf_str(udf_func *udf_arg) :Item_func() {} Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_func(list) {} - ~Item_func_udf_str() {} String *val_str(String *) { null_value=1; return 0; } double val() { null_value=1; return 0.0; } longlong val_int() { null_value=1; return 0; } @@ -1003,7 +1003,7 @@ public: Item_func_match(List<Item> &a, uint b): Item_real_func(a), key(0), flags(b), join_key(0), ft_handler(0), table(0), master(0), concat(0) { } - ~Item_func_match() + void cleanup() { if (!master && ft_handler) { diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 5ac87a25e67..6934ad9d3b0 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -22,6 +22,8 @@ #endif #include "mysql_priv.h" + +#ifdef HAVE_SPATIAL #include "sql_acl.h" #include <m_ctype.h> @@ -651,3 +653,5 @@ longlong Item_func_srid::val_int() uint32 res= uint4korr(swkb->ptr()); return (longlong) res; } + +#endif /*HAVE_SPATIAL*/ diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index f6f00ed2bab..545052807ec 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -17,6 +17,8 @@ /* This file defines all spatial functions */ +#ifdef HAVE_SPATIAL + #ifdef __GNUC__ #pragma interface /* gcc class implementation */ #endif @@ -338,3 +340,12 @@ public: const char *func_name() const { return "srid"; } void fix_length_and_dec() { max_length= 10; } }; + +#define GEOM_NEW(obj_constructor) new obj_constructor + +#else /*HAVE_SPATIAL*/ + +#define GEOM_NEW(obj_constructor) NULL + +#endif + diff --git a/sql/item_row.cc b/sql/item_row.cc index 7a457c9db7a..f4be3226364 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -91,7 +91,7 @@ void Item_row::split_sum_func(Item **ref_pointer_array, List<Item> &fields) uint el= fields.elements; fields.push_front(*arg); ref_pointer_array[el]= *arg; - *arg= new Item_ref(ref_pointer_array + el, 0, (*arg)->name); + *arg= new Item_ref(ref_pointer_array + el, arg, 0, (*arg)->name); } } } diff --git a/sql/item_row.h b/sql/item_row.h index a550bce4b5a..ec5f0f1fc95 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -34,12 +34,6 @@ public: with_null(0) {} - ~Item_row() - { - if (array_holder && items) - sql_element_free(items); - } - enum Type type() const { return ROW_ITEM; }; void illegal_method_call(const char *); bool is_null() { return null_value; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 3cb03d7ea49..ed6e44262c7 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -616,7 +616,8 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array, uint el= fields.elements; fields.push_front(separator); ref_pointer_array[el]= separator; - separator= new Item_ref(ref_pointer_array + el, 0, separator->name); + separator= new Item_ref(ref_pointer_array + el, + &separator, 0, separator->name); } Item_str_func::split_sum_func(ref_pointer_array, fields); } @@ -779,7 +780,7 @@ redo: register char *i,*j; i=(char*) ptr+1; j=(char*) search+1; while (j != search_end) - if (*i++ != *j++) goto skipp; + if (*i++ != *j++) goto skip; offset= (int) (ptr-res->ptr()); if (res->length()-from_length + to_length > current_thd->variables.max_allowed_packet) @@ -793,7 +794,7 @@ redo: offset+=(int) to_length; goto redo; } -skipp: +skip: if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l; else ++ptr; } @@ -975,9 +976,10 @@ String *Item_func_right::val_str(String *str) if (res->length() <= (uint) length) return res; /* purecov: inspected */ - uint start=res->numchars()-(uint) length; - if (start<=0) return res; - start=res->charpos(start); + uint start=res->numchars(); + if (start <= (uint) length) + return res; + start=res->charpos(start - (uint) length); tmp_value.set(*res,start,res->length()-start); return &tmp_value; } @@ -1087,13 +1089,13 @@ String *Item_func_substr_index::val_str(String *str) register char *i,*j; i=(char*) ptr+1; j=(char*) search+1; while (j != search_end) - if (*i++ != *j++) goto skipp; + if (*i++ != *j++) goto skip; if (pass==0) ++n; else if (!--c) break; ptr+=delimeter_length; continue; } - skipp: + skip: if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l; else ++ptr; } /* either not found or got total number when count<0 */ @@ -1646,11 +1648,11 @@ void Item_func_elt::fix_length_and_dec() { max_length=0; decimals=0; - + if (agg_arg_collations(collation, args+1, arg_count-1)) return; - for (uint i=1 ; i < arg_count ; i++) + for (uint i= 1 ; i < arg_count ; i++) { set_if_bigger(max_length,args[i]->max_length); set_if_bigger(decimals,args[i]->decimals); @@ -1709,7 +1711,7 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array, uint el= fields.elements; fields.push_front(item); ref_pointer_array[el]= item; - item= new Item_ref(ref_pointer_array + el, 0, item->name); + item= new Item_ref(ref_pointer_array + el, &item, 0, item->name); } Item_str_func::split_sum_func(ref_pointer_array, fields); } @@ -2022,9 +2024,8 @@ String *Item_func_lpad::val_str(String *str) { uint32 res_char_length,pad_char_length; ulong count= (long) args[1]->val_int(), byte_count; - String a1,a3; - String *res= args[0]->val_str(&a1); - String *pad= args[2]->val_str(&a3); + String *res= args[0]->val_str(&tmp_value); + String *pad= args[2]->val_str(&lpad_str); if (!res || args[1]->null_value || !pad) goto err; @@ -2104,8 +2105,8 @@ String *Item_func_conv_charset::val_str(String *str) null_value=1; return 0; } - null_value= str->copy(arg->ptr(),arg->length(),arg->charset(),conv_charset); - return null_value ? 0 : str; + null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),conv_charset); + return null_value ? 0 : &str_value; } void Item_func_conv_charset::fix_length_and_dec() @@ -2123,78 +2124,6 @@ void Item_func_conv_charset::print(String *str) str->append(')'); } -String *Item_func_conv_charset3::val_str(String *str) -{ - my_wc_t wc; - int cnvres; - const uchar *s, *se; - uchar *d, *d0, *de; - uint32 dmaxlen; - String *arg= args[0]->val_str(str); - String *to_cs= args[1]->val_str(str); - String *from_cs= args[2]->val_str(str); - CHARSET_INFO *from_charset; - CHARSET_INFO *to_charset; - - if (!arg || args[0]->null_value || - !to_cs || args[1]->null_value || - !from_cs || args[2]->null_value || - !(from_charset=get_charset_by_name(from_cs->ptr(), MYF(MY_WME))) || - !(to_charset=get_charset_by_name(to_cs->ptr(), MYF(MY_WME)))) - { - null_value=1; - return 0; - } - - s=(const uchar*)arg->ptr(); - se=s+arg->length(); - - dmaxlen=arg->length()*to_charset->mbmaxlen+1; - str->alloc(dmaxlen); - d0=d=(unsigned char*)str->ptr(); - de=d+dmaxlen; - - while (1) - { - cnvres=from_charset->cset->mb_wc(from_charset,&wc,s,se); - if (cnvres>0) - { - s+=cnvres; - } - else if (cnvres==MY_CS_ILSEQ) - { - s++; - wc='?'; - } - else - break; - -outp: - cnvres=to_charset->cset->wc_mb(to_charset,wc,d,de); - if (cnvres>0) - { - d+=cnvres; - } - else if (cnvres==MY_CS_ILUNI && wc!='?') - { - wc='?'; - goto outp; - } - else - break; - }; - - str->length((uint32) (d-d0)); - str->set_charset(to_charset); - return str; -} - - -void Item_func_conv_charset3::fix_length_and_dec() -{ - max_length = args[0]->max_length; -} - String *Item_func_set_collation::val_str(String *str) { str=args[0]->val_str(str); @@ -2261,7 +2190,7 @@ String *Item_func_charset::val_str(String *str) if ((null_value=(args[0]->null_value || !res->charset()))) return 0; str->copy(res->charset()->csname,strlen(res->charset()->csname), - &my_charset_latin1, default_charset()); + &my_charset_latin1, collation.collation); return str; } @@ -2272,7 +2201,7 @@ String *Item_func_collation::val_str(String *str) if ((null_value=(args[0]->null_value || !res->charset()))) return 0; str->copy(res->charset()->name,strlen(res->charset()->name), - &my_charset_latin1, default_charset()); + &my_charset_latin1, collation.collation); return str; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 2bc37de86d8..04009fe10e1 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -95,7 +95,6 @@ class Item_func_concat_ws :public Item_str_func public: Item_func_concat_ws(Item *a,List<Item> &list) :Item_str_func(list),separator(a) {} - ~Item_func_concat_ws() { delete separator; } String *val_str(String *); void fix_length_and_dec(); void update_used_tables(); @@ -409,7 +408,6 @@ class Item_func_make_set :public Item_str_func public: Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {} - ~Item_func_make_set() { delete item; } String *val_str(String *str); bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { @@ -528,7 +526,8 @@ public: void fix_length_and_dec() { collation.set(default_charset()); - decimals=0; max_length=args[0]->max_length*2; + decimals=0; + max_length=args[0]->max_length*2*collation.collation->mbmaxlen; } }; @@ -628,16 +627,6 @@ public: void print(String *str) { print_op(str); } }; -class Item_func_conv_charset3 :public Item_str_func -{ -public: - Item_func_conv_charset3(Item *arg1,Item *arg2,Item *arg3) - :Item_str_func(arg1,arg2,arg3) {} - String *val_str(String *); - void fix_length_and_dec(); - const char *func_name() const { return "convert"; } -}; - class Item_func_charset :public Item_str_func { public: @@ -646,8 +635,8 @@ public: const char *func_name() const { return "charset"; } void fix_length_and_dec() { - max_length=40; // should be enough collation.set(system_charset_info); + max_length= 64 * collation.collation->mbmaxlen; // should be enough }; }; @@ -659,8 +648,8 @@ public: const char *func_name() const { return "collation"; } void fix_length_and_dec() { - max_length=40; // should be enough collation.set(system_charset_info); + max_length= 64 * collation.collation->mbmaxlen; // should be enough }; }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 43775e1c96c..5b3cc326679 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -63,6 +63,11 @@ void Item_subselect::init(st_select_lex *select_lex, DBUG_VOID_RETURN; } +void Item_subselect::cleanup() +{ + Item_result_field::cleanup(); + engine->cleanup(); +} Item_subselect::~Item_subselect() { @@ -301,8 +306,6 @@ void Item_singlerow_subselect::fix_length_and_dec() if ((max_columns= engine->cols()) == 1) { engine->fix_length_and_dec(row= &value); - if (!(value= Item_cache::get_cache(engine->type()))) - return; } else { @@ -641,7 +644,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, As far as Item_ref_in_optimizer do not substitude itself on fix_fields we can use same item for all selects. */ - expr= new Item_ref((Item**)optimizer->get_cache(), + expr= new Item_ref((Item**)optimizer->get_cache(), + NULL, (char *)"<no matter>", (char *)in_left_expr_name); @@ -791,7 +795,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) (char *) "<list ref>"); func= eq_creator.create(new Item_ref((*optimizer->get_cache())-> - addr(i), + addr(i), + NULL, (char *)"<no matter>", (char *)in_left_expr_name), func); @@ -889,6 +894,12 @@ subselect_single_select_engine(st_select_lex *select, this->select_lex= select_lex; } +void subselect_single_select_engine::cleanup() +{ + prepared= 0; + optimized= 0; + executed= 0; +} subselect_union_engine::subselect_union_engine(st_select_lex_unit *u, select_subselect *result_arg, @@ -906,7 +917,8 @@ int subselect_single_select_engine::prepare() { if (prepared) return 0; - join= new JOIN(thd, select_lex->item_list, select_lex->options, result); + join= new JOIN(thd, select_lex->item_list, + select_lex->options | SELECT_NO_UNLOCK, result); if (!join || !result) { thd->fatal_error(); //out of memory @@ -933,7 +945,7 @@ int subselect_single_select_engine::prepare() int subselect_union_engine::prepare() { - return unit->prepare(thd, result); + return unit->prepare(thd, result, SELECT_NO_UNLOCK); } int subselect_uniquesubquery_engine::prepare() @@ -955,13 +967,9 @@ static Item_result set_row(List<Item> &item_list, Item *item, res_type= sel_item->result_type(); item->decimals= sel_item->decimals; *maybe_null= sel_item->maybe_null; - if (row) - { - if (!(row[i]= Item_cache::get_cache(res_type))) - return STRING_RESULT; // we should return something - row[i]->set_len_n_dec(sel_item->max_length, sel_item->decimals); - row[i]->collation.set(sel_item->collation); - } + if (!(row[i]= Item_cache::get_cache(res_type))) + return STRING_RESULT; // we should return something + row[i]->setup(sel_item); } if (item_list.elements > 1) res_type= ROW_RESULT; @@ -982,7 +990,10 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row) DBUG_ASSERT(row || unit->first_select()->item_list.elements==1); if (unit->first_select()->item_list.elements == 1) + { res_type= set_row(unit->types, item, row, &maybe_null); + item->collation.set(row[0]->collation); + } else { bool fake= 0; @@ -1099,7 +1110,7 @@ int subselect_indexsubquery_engine::exec() if (check_null) { /* We need to check for NULL if there wasn't a matching value */ - *tab->null_ref_key= 0; // Search first for not null + *tab->ref.null_ref_key= 0; // Search first for not null ((Item_in_subselect *) item)->was_null= 0; } @@ -1144,7 +1155,7 @@ int subselect_indexsubquery_engine::exec() { if (!check_null || null_finding) break; /* We don't need to check nulls */ - *tab->null_ref_key= 1; + *tab->ref.null_ref_key= 1; null_finding= 1; /* Check if there exists a row with a null value in the index */ if ((error= (safe_index_read(tab) == 1))) diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 8444dc7bf66..dc3d07540da 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -69,6 +69,7 @@ public: select_subselect *result); ~Item_subselect(); + void cleanup(); virtual void reset() { null_value= 1; @@ -199,6 +200,13 @@ public: {} + void cleanup() + { + Item_exists_subselect::cleanup(); + abort_on_null= 0; + transformed= 0; + upper_not= 0; + } subs_type substype() { return IN_SUBS; } void reset() { @@ -261,6 +269,7 @@ public: maybe_null= 0; } virtual ~subselect_engine() {}; // to satisfy compiler + virtual void cleanup() {} // set_thd should be called before prepare() void set_thd(THD *thd_arg) { thd= thd_arg; } @@ -290,6 +299,7 @@ public: subselect_single_select_engine(st_select_lex *select, select_subselect *result, Item_subselect *item); + void cleanup(); int prepare(); void fix_length_and_dec(Item_cache** row); int exec(); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 3bc52159a96..6507e826b7e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -42,17 +42,17 @@ Item_sum::Item_sum(List<Item> &list) } // Constructor used in processing select with temporary tebles -Item_sum::Item_sum(THD *thd, Item_sum &item): - Item_result_field(thd, item), quick_group(item.quick_group) +Item_sum::Item_sum(THD *thd, Item_sum *item): + Item_result_field(thd, item), quick_group(item->quick_group) { - arg_count= item.arg_count; + arg_count= item->arg_count; if (arg_count <= 2) args=tmp_args; else if (!(args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) return; for (uint i= 0; i < arg_count; i++) - args[i]= item.args[i]; + args[i]= item->args[i]; } void Item_sum::mark_as_sum_func() @@ -240,7 +240,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item *Item_sum_sum::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_sum(thd, *this); + return new (&thd->mem_root) Item_sum_sum(thd, this); } @@ -281,7 +281,7 @@ Item_sum_sum_distinct::Item_sum_sum_distinct(Item *item) Item_sum_sum_distinct::Item_sum_sum_distinct(THD *thd, - Item_sum_sum_distinct &original) + Item_sum_sum_distinct *original) :Item_sum_num(thd, original), sum(0.0), tree(0) { quick_group= 0; @@ -297,7 +297,7 @@ Item_sum_sum_distinct::~Item_sum_sum_distinct() Item * Item_sum_sum_distinct::copy_or_same(THD *thd) { - return new (&thd->mem_root) Item_sum_sum_distinct(thd, *this); + return new (&thd->mem_root) Item_sum_sum_distinct(thd, this); } C_MODE_START @@ -383,7 +383,7 @@ double Item_sum_sum_distinct::val() Item *Item_sum_count::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_count(thd, *this); + return new (&thd->mem_root) Item_sum_count(thd, this); } @@ -417,7 +417,7 @@ longlong Item_sum_count::val_int() Item *Item_sum_avg::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_avg(thd, *this); + return new (&thd->mem_root) Item_sum_avg(thd, this); } @@ -462,7 +462,7 @@ double Item_sum_std::val() Item *Item_sum_std::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_std(thd, *this); + return new (&thd->mem_root) Item_sum_std(thd, this); } @@ -472,7 +472,7 @@ Item *Item_sum_std::copy_or_same(THD* thd) Item *Item_sum_variance::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_variance(thd, *this); + return new (&thd->mem_root) Item_sum_variance(thd, this); } @@ -613,7 +613,7 @@ Item_sum_hybrid::val_str(String *str) Item *Item_sum_min::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_min(thd, *this); + return new (&thd->mem_root) Item_sum_min(thd, this); } @@ -666,7 +666,7 @@ bool Item_sum_min::add() Item *Item_sum_max::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_max(thd, *this); + return new (&thd->mem_root) Item_sum_max(thd, this); } @@ -732,7 +732,7 @@ void Item_sum_bit::clear() Item *Item_sum_or::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_or(thd, *this); + return new (&thd->mem_root) Item_sum_or(thd, this); } @@ -746,7 +746,7 @@ bool Item_sum_or::add() Item *Item_sum_xor::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_xor(thd, *this); + return new (&thd->mem_root) Item_sum_xor(thd, this); } @@ -760,7 +760,7 @@ bool Item_sum_xor::add() Item *Item_sum_and::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_and(thd, *this); + return new (&thd->mem_root) Item_sum_and(thd, this); } @@ -1193,8 +1193,9 @@ int dump_leaf(byte* key, uint32 count __attribute__((unused)), } -Item_sum_count_distinct::~Item_sum_count_distinct() +void Item_sum_count_distinct::cleanup() { + Item_sum_int::cleanup(); /* Free table and tree if they belong to this item (if item have not pointer to original item from which was made copy => it own its objects ) @@ -1202,13 +1203,21 @@ Item_sum_count_distinct::~Item_sum_count_distinct() if (!original) { if (table) + { free_tmp_table(current_thd, table); + table= 0; + } delete tmp_table_param; + tmp_table_param= 0; if (use_tree) + { delete_tree(tree); + use_tree= 0; + } } } + bool Item_sum_count_distinct::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { @@ -1390,7 +1399,7 @@ int Item_sum_count_distinct::tree_to_myisam() Item *Item_sum_count_distinct::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_count_distinct(thd, *this); + return new (&thd->mem_root) Item_sum_count_distinct(thd, this); } @@ -1490,7 +1499,7 @@ bool Item_udf_sum::add() Item *Item_sum_udf_float::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_udf_float(thd, *this); + return new (&thd->mem_root) Item_sum_udf_float(thd, this); } double Item_sum_udf_float::val() @@ -1513,7 +1522,7 @@ String *Item_sum_udf_float::val_str(String *str) Item *Item_sum_udf_int::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_udf_int(thd, *this); + return new (&thd->mem_root) Item_sum_udf_int(thd, this); } @@ -1549,7 +1558,7 @@ void Item_sum_udf_str::fix_length_and_dec() Item *Item_sum_udf_str::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_sum_udf_str(thd, *this); + return new (&thd->mem_root) Item_sum_udf_str(thd, this); } @@ -1772,6 +1781,31 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, } +void Item_func_group_concat::cleanup() +{ + /* + Free table and tree if they belong to this item (if item have not pointer + to original item from which was made copy => it own its objects ) + */ + if (!original) + { + THD *thd= current_thd; + if (table) + { + free_tmp_table(thd, table); + table= 0; + } + delete tmp_table_param; + tmp_table_param= 0; + if (tree_mode) + { + tree_mode= 0; + delete_tree(tree); + } + } +} + + Item_func_group_concat::~Item_func_group_concat() { /* @@ -1787,18 +1821,13 @@ Item_func_group_concat::~Item_func_group_concat() sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values); warning->set_msg(thd, warn_buff); } - if (table) - free_tmp_table(thd, table); - delete tmp_table_param; - if (tree_mode) - delete_tree(tree); } } Item *Item_func_group_concat::copy_or_same(THD* thd) { - return new (&thd->mem_root) Item_func_group_concat(thd, *this); + return new (&thd->mem_root) Item_func_group_concat(thd, this); } diff --git a/sql/item_sum.h b/sql/item_sum.h index afed152bb0e..1957f652afe 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -57,8 +57,12 @@ public: } Item_sum(List<Item> &list); //Copy constructor, need to perform subselects with temporary tables - Item_sum(THD *thd, Item_sum &item); - ~Item_sum() { result_field=0; } + Item_sum(THD *thd, Item_sum *item); + void cleanup() + { + Item_result_field::cleanup(); + result_field=0; + } enum Type type() const { return SUM_FUNC_ITEM; } virtual enum Sumfunctype sum_func () const=0; @@ -106,7 +110,7 @@ public: Item_sum_num(Item *item_par) :Item_sum(item_par) {} Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {} Item_sum_num(List<Item> &list) :Item_sum(list) {} - Item_sum_num(THD *thd, Item_sum_num &item) :Item_sum(thd, item) {} + Item_sum_num(THD *thd, Item_sum_num *item) :Item_sum(thd, item) {} bool fix_fields(THD *, TABLE_LIST *, Item **); longlong val_int() { return (longlong) val(); } /* Real as default */ String *val_str(String*str); @@ -119,7 +123,7 @@ class Item_sum_int :public Item_sum_num public: Item_sum_int(Item *item_par) :Item_sum_num(item_par) {} Item_sum_int(List<Item> &list) :Item_sum_num(list) {} - Item_sum_int(THD *thd, Item_sum_int &item) :Item_sum_num(thd, item) {} + Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {} double val() { return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } @@ -135,8 +139,8 @@ class Item_sum_sum :public Item_sum_num public: Item_sum_sum(Item *item_par) :Item_sum_num(item_par),sum(0.0) {} - Item_sum_sum(THD *thd, Item_sum_sum &item) - :Item_sum_num(thd, item), sum(item.sum) {} + Item_sum_sum(THD *thd, Item_sum_sum *item) + :Item_sum_num(thd, item), sum(item->sum) {} enum Sumfunctype sum_func () const {return SUM_FUNC;} void clear(); bool add(); @@ -162,7 +166,7 @@ class Item_sum_sum_distinct :public Item_sum_num double sum; Unique *tree; private: - Item_sum_sum_distinct(THD *thd, Item_sum_sum_distinct &item); + Item_sum_sum_distinct(THD *thd, Item_sum_sum_distinct *item); public: Item_sum_sum_distinct(Item *item_par); ~Item_sum_sum_distinct(); @@ -191,9 +195,9 @@ class Item_sum_count :public Item_sum_int Item_sum_count(Item *item_par) :Item_sum_int(item_par),count(0),used_table_cache(~(table_map) 0) {} - Item_sum_count(THD *thd, Item_sum_count &item) - :Item_sum_int(thd, item), count(item.count), - used_table_cache(item.used_table_cache) + Item_sum_count(THD *thd, Item_sum_count *item) + :Item_sum_int(thd, item), count(item->count), + used_table_cache(item->used_table_cache) {} table_map used_tables() const { return used_table_cache; } bool const_item() const { return !used_table_cache; } @@ -259,16 +263,16 @@ class Item_sum_count_distinct :public Item_sum_int tmp_table_param(0), tree(&tree_base), original(0), use_tree(0), always_null(0) { quick_group= 0; } - Item_sum_count_distinct(THD *thd, Item_sum_count_distinct &item) - :Item_sum_int(thd, item), table(item.table), - used_table_cache(item.used_table_cache), - field_lengths(item.field_lengths), tmp_table_param(item.tmp_table_param), - tree(item.tree), original(&item), key_length(item.key_length), - max_elements_in_tree(item.max_elements_in_tree), - rec_offset(item.rec_offset), use_tree(item.use_tree), - always_null(item.always_null) + Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item) + :Item_sum_int(thd, item), table(item->table), + used_table_cache(item->used_table_cache), + field_lengths(item->field_lengths), tmp_table_param(item->tmp_table_param), + tree(item->tree), original(item), key_length(item->key_length), + max_elements_in_tree(item->max_elements_in_tree), + rec_offset(item->rec_offset), use_tree(item->use_tree), + always_null(item->always_null) {} - ~Item_sum_count_distinct(); + void cleanup(); table_map used_tables() const { return used_table_cache; } enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; } @@ -314,8 +318,8 @@ class Item_sum_avg :public Item_sum_num public: Item_sum_avg(Item *item_par) :Item_sum_num(item_par),count(0) {} - Item_sum_avg(THD *thd, Item_sum_avg &item) - :Item_sum_num(thd, item), sum(item.sum), count(item.count) {} + Item_sum_avg(THD *thd, Item_sum_avg *item) + :Item_sum_num(thd, item), sum(item->sum), count(item->count) {} enum Sumfunctype sum_func () const {return AVG_FUNC;} void clear(); bool add(); @@ -366,9 +370,9 @@ class Item_sum_variance : public Item_sum_num public: Item_sum_variance(Item *item_par) :Item_sum_num(item_par),count(0) {} - Item_sum_variance(THD *thd, Item_sum_variance &item): - Item_sum_num(thd, item), sum(item.sum), sum_sqr(item.sum_sqr), - count(item.count) {} + Item_sum_variance(THD *thd, Item_sum_variance *item): + Item_sum_num(thd, item), sum(item->sum), sum_sqr(item->sum_sqr), + count(item->count) {} enum Sumfunctype sum_func () const { return VARIANCE_FUNC; } void clear(); bool add(); @@ -399,7 +403,7 @@ class Item_sum_std :public Item_sum_variance { public: Item_sum_std(Item *item_par) :Item_sum_variance(item_par) {} - Item_sum_std(THD *thd, Item_sum_std &item) + Item_sum_std(THD *thd, Item_sum_std *item) :Item_sum_variance(thd, item) {} enum Sumfunctype sum_func () const { return STD_FUNC; } @@ -426,15 +430,16 @@ class Item_sum_hybrid :public Item_sum public: Item_sum_hybrid(Item *item_par,int sign) - :Item_sum(item_par), hybrid_type(INT_RESULT), cmp_sign(sign), - used_table_cache(~(table_map) 0), + :Item_sum(item_par), sum(0.0), sum_int(0), + hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG), + cmp_sign(sign), used_table_cache(~(table_map) 0), cmp_charset(&my_charset_bin) {} - Item_sum_hybrid(THD *thd, Item_sum_hybrid &item): - Item_sum(thd, item), value(item.value), tmp_value(item.tmp_value), - sum(item.sum), sum_int(item.sum_int), hybrid_type(item.hybrid_type), - hybrid_field_type(item.hybrid_field_type),cmp_sign(item.cmp_sign), - used_table_cache(item.used_table_cache), cmp_charset(item.cmp_charset) {} + Item_sum_hybrid(THD *thd, Item_sum_hybrid *item): + Item_sum(thd, item), value(item->value), + sum(item->sum), sum_int(item->sum_int), hybrid_type(item->hybrid_type), + hybrid_field_type(item->hybrid_field_type),cmp_sign(item->cmp_sign), + used_table_cache(item->used_table_cache), cmp_charset(item->cmp_charset) {} bool fix_fields(THD *, TABLE_LIST *, Item **); table_map used_tables() const { return used_table_cache; } bool const_item() const { return !used_table_cache; } @@ -465,7 +470,7 @@ class Item_sum_min :public Item_sum_hybrid { public: Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {} - Item_sum_min(THD *thd, Item_sum_min &item) :Item_sum_hybrid(thd, item) {} + Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_hybrid(thd, item) {} enum Sumfunctype sum_func () const {return MIN_FUNC;} bool add(); @@ -478,7 +483,7 @@ class Item_sum_max :public Item_sum_hybrid { public: Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {} - Item_sum_max(THD *thd, Item_sum_max &item) :Item_sum_hybrid(thd, item) {} + Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_hybrid(thd, item) {} enum Sumfunctype sum_func () const {return MAX_FUNC;} bool add(); @@ -495,8 +500,8 @@ protected: public: Item_sum_bit(Item *item_par,ulonglong reset_arg) :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {} - Item_sum_bit(THD *thd, Item_sum_bit &item): - Item_sum_int(thd, item), reset_bits(item.reset_bits), bits(item.bits) {} + Item_sum_bit(THD *thd, Item_sum_bit *item): + Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits) {} enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;} void clear(); longlong val_int(); @@ -511,7 +516,7 @@ class Item_sum_or :public Item_sum_bit { public: Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} - Item_sum_or(THD *thd, Item_sum_or &item) :Item_sum_bit(thd, item) {} + Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {} bool add(); const char *func_name() const { return "bit_or"; } Item *copy_or_same(THD* thd); @@ -522,7 +527,7 @@ class Item_sum_and :public Item_sum_bit { public: Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {} - Item_sum_and(THD *thd, Item_sum_and &item) :Item_sum_bit(thd, item) {} + Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {} bool add(); const char *func_name() const { return "bit_and"; } Item *copy_or_same(THD* thd); @@ -532,7 +537,7 @@ class Item_sum_xor :public Item_sum_bit { public: Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} - Item_sum_xor(THD *thd, Item_sum_xor &item) :Item_sum_bit(thd, item) {} + Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {} bool add(); const char *func_name() const { return "bit_xor"; } Item *copy_or_same(THD* thd); @@ -554,9 +559,8 @@ public: Item_udf_sum( udf_func *udf_arg, List<Item> &list ) :Item_sum( list ), udf(udf_arg) { quick_group=0;} - Item_udf_sum(THD *thd, Item_udf_sum &item) - :Item_sum(thd, item), udf(item.udf) {} - ~Item_udf_sum() {} + Item_udf_sum(THD *thd, Item_udf_sum *item) + :Item_sum(thd, item), udf(item->udf) {} const char *func_name() const { return udf.name(); } bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { @@ -579,9 +583,8 @@ class Item_sum_udf_float :public Item_udf_sum Item_sum_udf_float(udf_func *udf_arg) :Item_udf_sum(udf_arg) {} Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_udf_sum(udf_arg,list) {} - Item_sum_udf_float(THD *thd, Item_sum_udf_float &item) + Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) :Item_udf_sum(thd, item) {} - ~Item_sum_udf_float() {} longlong val_int() { return (longlong) Item_sum_udf_float::val(); } double val(); String *val_str(String*str); @@ -596,9 +599,8 @@ public: Item_sum_udf_int(udf_func *udf_arg) :Item_udf_sum(udf_arg) {} Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_udf_sum(udf_arg,list) {} - Item_sum_udf_int(THD *thd, Item_sum_udf_int &item) + Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) :Item_udf_sum(thd, item) {} - ~Item_sum_udf_int() {} longlong val_int(); double val() { return (double) Item_sum_udf_int::val_int(); } String *val_str(String*str); @@ -614,9 +616,8 @@ public: Item_sum_udf_str(udf_func *udf_arg) :Item_udf_sum(udf_arg) {} Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) :Item_udf_sum(udf_arg,list) {} - Item_sum_udf_str(THD *thd, Item_sum_udf_str &item) + Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) :Item_udf_sum(thd, item) {} - ~Item_sum_udf_str() {} String *val_str(String *); double val() { @@ -643,9 +644,8 @@ class Item_sum_udf_float :public Item_sum_num public: Item_sum_udf_float(udf_func *udf_arg) :Item_sum_num() {} Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} - Item_sum_udf_float(THD *thd, Item_sum_udf_float &item) + Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) :Item_sum_num(thd, item) {} - ~Item_sum_udf_float() {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } double val() { return 0.0; } void clear() {} @@ -659,9 +659,8 @@ class Item_sum_udf_int :public Item_sum_num public: Item_sum_udf_int(udf_func *udf_arg) :Item_sum_num() {} Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} - Item_sum_udf_int(THD *thd, Item_sum_udf_int &item) + Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) :Item_sum_num(thd, item) {} - ~Item_sum_udf_int() {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } longlong val_int() { return 0; } double val() { return 0; } @@ -676,9 +675,8 @@ class Item_sum_udf_str :public Item_sum_num public: Item_sum_udf_str(udf_func *udf_arg) :Item_sum_num() {} Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} - Item_sum_udf_str(THD *thd, Item_sum_udf_str &item) + Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) :Item_sum_num(thd, item) {} - ~Item_sum_udf_str() {} String *val_str(String *) { null_value=1; return 0; } double val() { null_value=1; return 0.0; } longlong val_int() { null_value=1; return 0; } @@ -740,33 +738,35 @@ class Item_func_group_concat : public Item_sum Item_func_group_concat(bool is_distinct,List<Item> *is_select, SQL_LIST *is_order,String *is_separator); - Item_func_group_concat(THD *thd, Item_func_group_concat &item) + Item_func_group_concat(THD *thd, Item_func_group_concat *item) :Item_sum(thd, item),item_thd(thd), - tmp_table_param(item.tmp_table_param), - max_elements_in_tree(item.max_elements_in_tree), - warning(item.warning), - warning_available(item.warning_available), - key_length(item.key_length), - rec_offset(item.rec_offset), - tree_mode(item.tree_mode), - distinct(item.distinct), - warning_for_row(item.warning_for_row), - separator(item.separator), - tree(item.tree), - table(item.table), - order(item.order), - tables_list(item.tables_list), - group_concat_max_len(item.group_concat_max_len), - show_elements(item.show_elements), - arg_count_order(item.arg_count_order), - arg_count_field(item.arg_count_field), - arg_show_fields(item.arg_show_fields), - count_cut_values(item.count_cut_values), - original(&item) + tmp_table_param(item->tmp_table_param), + max_elements_in_tree(item->max_elements_in_tree), + warning(item->warning), + warning_available(item->warning_available), + key_length(item->key_length), + rec_offset(item->rec_offset), + tree_mode(item->tree_mode), + distinct(item->distinct), + warning_for_row(item->warning_for_row), + separator(item->separator), + tree(item->tree), + table(item->table), + order(item->order), + tables_list(item->tables_list), + group_concat_max_len(item->group_concat_max_len), + show_elements(item->show_elements), + arg_count_order(item->arg_count_order), + arg_count_field(item->arg_count_field), + arg_show_fields(item->arg_show_fields), + count_cut_values(item->count_cut_values), + original(item) { - quick_group= item.quick_group; + quick_group= item->quick_group; }; ~Item_func_group_concat(); + void cleanup(); + enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} const char *func_name() const { return "group_concat"; } enum Type type() const { return SUM_FUNC_ITEM; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index cccea6bcdb5..e49f2287f4b 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1289,14 +1289,20 @@ longlong Item_func_sec_to_time::val_int() void Item_func_date_format::fix_length_and_dec() { decimals=0; + collation.set(&my_charset_bin); if (args[1]->type() == STRING_ITEM) { // Optimize the normal case fixed_length=1; - max_length=format_length(((Item_string*) args[1])->const_string()); + /* + The result is a binary string (no reason to use collation->mbmaxlen + This is becasue make_date_time() only returns binary strings + */ + max_length= format_length(((Item_string*) args[1])->const_string()); } else { fixed_length=0; + /* The result is a binary string (no reason to use collation->mbmaxlen */ max_length=args[1]->max_length*10; set_if_smaller(max_length,MAX_BLOB_WIDTH); } @@ -1867,6 +1873,8 @@ String *Item_char_typecast::val_str(String *str) } res= str; } + + res->set_charset(cast_cs); /* Cut the tail if cast with length diff --git a/sql/item_uniq.h b/sql/item_uniq.h index 5c6f6eefb6b..47f967b52c6 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -38,7 +38,7 @@ class Item_sum_unique_users :public Item_sum_num public: Item_sum_unique_users(Item *name_arg,int start,int end,Item *item_arg) :Item_sum_num(item_arg) {} - Item_sum_unique_users(THD *thd, Item_sum_unique_users &item) + Item_sum_unique_users(THD *thd, Item_sum_unique_users *item) :Item_sum_num(thd, item) {} double val() { return 0.0; } enum Sumfunctype sum_func () const {return UNIQUE_USERS_FUNC;} @@ -53,7 +53,7 @@ public: } Item *copy_or_same(THD* thd) { - return new Item_sum_unique_users(thd, *this); + return new Item_sum_unique_users(thd, this); } void print(String *str) { str->append("0.0", 3); } }; diff --git a/sql/lex.h b/sql/lex.h index 114e1a6b960..72888f7d89e 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -20,13 +20,25 @@ #include "lex_symbol.h" /* We don't want to include sql_yacc.h into gen_lex_hash */ +SYM_GROUP sym_group_common= {"", ""}; +SYM_GROUP sym_group_geom= {"Spatial extentions", "HAVE_SPATIAL"}; +SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"}; #ifdef NO_YACC_SYMBOLS -#define SYM(A) 0 -#define CREATE_FUNC(A) 0 +#define SYM_OR_NULL(A) 0 #else -#define SYM(A) A -#define CREATE_FUNC(A) (void*) (A) +#define SYM_OR_NULL(A) A +#endif + +#define SYM(A) SYM_OR_NULL(A),0,0,&sym_group_common +#define F_SYM(A) SYM_OR_NULL(A) + +#define CREATE_FUNC(A) (void *)(SYM_OR_NULL(A)), &sym_group_common + +#ifdef HAVE_SPATIAL +#define CREATE_FUNC_GEOM(A) (void *)(SYM_OR_NULL(A)), &sym_group_geom +#else +#define CREATE_FUNC_GEOM(A) 0, &sym_group_geom #endif /* @@ -36,683 +48,683 @@ */ static SYMBOL symbols[] = { - { "&&", SYM(AND),0,0}, - { "<", SYM(LT),0,0}, - { "<=", SYM(LE),0,0}, - { "<>", SYM(NE),0,0}, - { "!=", SYM(NE),0,0}, - { "=", SYM(EQ),0,0}, - { ">", SYM(GT_SYM),0,0}, - { ">=", SYM(GE),0,0}, - { "<<", SYM(SHIFT_LEFT),0,0}, - { ">>", SYM(SHIFT_RIGHT),0,0}, - { "<=>", SYM(EQUAL_SYM),0,0}, - { "ACTION", SYM(ACTION),0,0}, - { "ADD", SYM(ADD),0,0}, - { "AFTER", SYM(AFTER_SYM),0,0}, - { "AGAINST", SYM(AGAINST),0,0}, - { "AGGREGATE", SYM(AGGREGATE_SYM),0,0}, - { "ALL", SYM(ALL),0,0}, - { "ALTER", SYM(ALTER),0,0}, - { "ANALYZE", SYM(ANALYZE_SYM),0,0}, - { "AND", SYM(AND),0,0}, - { "ANY", SYM(ANY_SYM),0,0}, - { "AS", SYM(AS),0,0}, - { "ASC", SYM(ASC),0,0}, - { "ASCII", SYM(ASCII_SYM),0,0}, - { "ASENSITIVE", SYM(ASENSITIVE_SYM),0,0}, - { "AUTO_INCREMENT", SYM(AUTO_INC),0,0}, - { "AVG", SYM(AVG_SYM),0,0}, - { "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH),0,0}, - { "BACKUP", SYM(BACKUP_SYM),0,0}, - { "BDB", SYM(BERKELEY_DB_SYM),0,0}, - { "BEFORE", SYM(BEFORE_SYM),0,0}, - { "BEGIN", SYM(BEGIN_SYM),0,0}, - { "BERKELEYDB", SYM(BERKELEY_DB_SYM),0,0}, - { "BETWEEN", SYM(BETWEEN_SYM),0,0}, - { "BIGINT", SYM(BIGINT),0,0}, - { "BINARY", SYM(BINARY),0,0}, - { "BINLOG", SYM(BINLOG_SYM),0,0}, - { "BIT", SYM(BIT_SYM),0,0}, - { "BLOB", SYM(BLOB_SYM),0,0}, - { "BOOL", SYM(BOOL_SYM),0,0}, - { "BOOLEAN", SYM(BOOLEAN_SYM),0,0}, - { "BOTH", SYM(BOTH),0,0}, - { "BTREE", SYM(BTREE_SYM),0,0}, - { "BY", SYM(BY),0,0}, - { "BYTE", SYM(BYTE_SYM), 0, 0}, - { "CACHE", SYM(CACHE_SYM),0,0}, - { "CALL", SYM(CALL_SYM),0,0}, - { "CASCADE", SYM(CASCADE),0,0}, - { "CASE", SYM(CASE_SYM),0,0}, - { "CHANGE", SYM(CHANGE),0,0}, - { "CHANGED", SYM(CHANGED),0,0}, - { "CHAR", SYM(CHAR_SYM),0,0}, - { "CHARACTER", SYM(CHAR_SYM),0,0}, - { "CHARSET", SYM(CHARSET),0,0}, - { "CHECK", SYM(CHECK_SYM),0,0}, - { "CHECKSUM", SYM(CHECKSUM_SYM),0,0}, - { "CIPHER", SYM(CIPHER_SYM),0,0}, - { "CLIENT", SYM(CLIENT_SYM),0,0}, - { "CLOSE", SYM(CLOSE_SYM),0,0}, - { "COLLATE", SYM(COLLATE_SYM),0,0}, - { "COLLATION", SYM(COLLATION_SYM),0,0}, - { "COLUMN", SYM(COLUMN_SYM),0,0}, - { "COLUMNS", SYM(COLUMNS),0,0}, - { "COMMENT", SYM(COMMENT_SYM),0,0}, - { "COMMIT", SYM(COMMIT_SYM),0,0}, - { "COMMITTED", SYM(COMMITTED_SYM),0,0}, - { "COMPRESSED", SYM(COMPRESSED_SYM),0,0}, - { "CONCURRENT", SYM(CONCURRENT),0,0}, - { "CONDITION", SYM(CONDITION_SYM),0,0}, - { "CONNECTION", SYM(CONNECTION_SYM),0,0}, - { "CONSTRAINT", SYM(CONSTRAINT),0,0}, - { "CONTINUE", SYM(CONTINUE_SYM),0,0}, - { "CREATE", SYM(CREATE),0,0}, - { "CROSS", SYM(CROSS),0,0}, - { "CUBE", SYM(CUBE_SYM),0,0}, - { "CURRENT_DATE", SYM(CURDATE),0,0}, - { "CURRENT_TIME", SYM(CURTIME),0,0}, - { "CURRENT_TIMESTAMP", SYM(NOW_SYM),0,0}, - { "CURSOR", SYM(CURSOR_SYM),0,0}, - { "DATA", SYM(DATA_SYM),0,0}, - { "DATABASE", SYM(DATABASE),0,0}, - { "DATABASES", SYM(DATABASES),0,0}, - { "DATE", SYM(DATE_SYM),0,0}, - { "DATETIME", SYM(DATETIME),0,0}, - { "DAY", SYM(DAY_SYM),0,0}, - { "DAY_HOUR", SYM(DAY_HOUR_SYM),0,0}, - { "DAY_MICROSECOND", SYM(DAY_MICROSECOND_SYM),0,0}, - { "DAY_MINUTE", SYM(DAY_MINUTE_SYM),0,0}, - { "DAY_SECOND", SYM(DAY_SECOND_SYM),0,0}, - { "DEC", SYM(DECIMAL_SYM),0,0}, - { "DECIMAL", SYM(DECIMAL_SYM),0,0}, - { "DECLARE", SYM(DECLARE_SYM),0,0}, - { "DEFAULT", SYM(DEFAULT),0,0}, - { "DEFINER", SYM(DEFINER_SYM),0,0}, - { "DELAYED", SYM(DELAYED_SYM),0,0}, - { "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0}, - { "DELETE", SYM(DELETE_SYM),0,0}, - { "DESC", SYM(DESC),0,0}, - { "DESCRIBE", SYM(DESCRIBE),0,0}, - { "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0}, - { "DETERMINISTIC", SYM(DETERMINISTIC_SYM),0,0}, - { "DIRECTORY", SYM(DIRECTORY_SYM),0,0}, - { "DISABLE", SYM(DISABLE_SYM),0,0}, - { "DISCARD", SYM(DISCARD),0,0}, - { "DISTINCT", SYM(DISTINCT),0,0}, - { "DISTINCTROW", SYM(DISTINCT),0,0}, /* Access likes this */ - { "DIV", SYM(DIV_SYM),0,0}, - { "DO", SYM(DO_SYM),0,0}, - { "DOUBLE", SYM(DOUBLE_SYM),0,0}, - { "DROP", SYM(DROP),0,0}, - { "DUAL", SYM(DUAL_SYM),0,0}, - { "DUMPFILE", SYM(DUMPFILE),0,0}, - { "DUPLICATE", SYM(DUPLICATE_SYM),0,0}, - { "DYNAMIC", SYM(DYNAMIC_SYM),0,0}, - { "ELSE", SYM(ELSE),0,0}, - { "ELSEIF", SYM(ELSEIF_SYM),0,0}, - { "ENABLE", SYM(ENABLE_SYM),0,0}, - { "ENCLOSED", SYM(ENCLOSED),0,0}, - { "END", SYM(END),0,0}, - { "ENGINE", SYM(ENGINE_SYM),0,0}, - { "ENGINES", SYM(ENGINES_SYM),0,0}, - { "ENUM", SYM(ENUM),0,0}, - { "ERRORS", SYM(ERRORS),0,0}, - { "ESCAPE", SYM(ESCAPE_SYM),0,0}, - { "ESCAPED", SYM(ESCAPED),0,0}, - { "EVENTS", SYM(EVENTS_SYM),0,0}, - { "EXECUTE", SYM(EXECUTE_SYM),0,0}, - { "EXISTS", SYM(EXISTS),0,0}, - { "EXIT", SYM(EXIT_SYM),0,0}, - { "EXPANSION", SYM(EXPANSION_SYM),0,0}, - { "EXPLAIN", SYM(DESCRIBE),0,0}, - { "EXTENDED", SYM(EXTENDED_SYM),0,0}, - { "FALSE", SYM(FALSE_SYM),0,0}, - { "FAST", SYM(FAST_SYM),0,0}, - { "FETCH", SYM(FETCH_SYM),0,0}, - { "FIELDS", SYM(COLUMNS),0,0}, - { "FILE", SYM(FILE_SYM),0,0}, - { "FIRST", SYM(FIRST_SYM),0,0}, - { "FIXED", SYM(FIXED_SYM),0,0}, - { "FLOAT", SYM(FLOAT_SYM),0,0}, - { "FLOAT4", SYM(FLOAT_SYM),0,0}, - { "FLOAT8", SYM(DOUBLE_SYM),0,0}, - { "FLUSH", SYM(FLUSH_SYM),0,0}, - { "FOR", SYM(FOR_SYM),0,0}, - { "FORCE", SYM(FORCE_SYM),0,0}, - { "FOREIGN", SYM(FOREIGN),0,0}, - { "FOUND", SYM(FOUND_SYM),0,0}, - { "FRAC_SECOND", SYM(FRAC_SECOND_SYM),0,0}, - { "FROM", SYM(FROM),0,0}, - { "FULL", SYM(FULL),0,0}, - { "FULLTEXT", SYM(FULLTEXT_SYM),0,0}, - { "FUNCTION", SYM(FUNCTION_SYM),0,0}, - { "GEOMETRY", SYM(GEOMETRY_SYM),0,0}, - { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION),0,0}, - { "GET_FORMAT", SYM(GET_FORMAT),0,0}, - { "GLOBAL", SYM(GLOBAL_SYM),0,0}, - { "GRANT", SYM(GRANT),0,0}, - { "GRANTS", SYM(GRANTS),0,0}, - { "GROUP", SYM(GROUP),0,0}, - { "HANDLER", SYM(HANDLER_SYM),0,0}, - { "HASH", SYM(HASH_SYM),0,0}, - { "HAVING", SYM(HAVING),0,0}, - { "HELP", SYM(HELP_SYM),0,0}, - { "HIGH_PRIORITY", SYM(HIGH_PRIORITY),0,0}, - { "HOSTS", SYM(HOSTS_SYM),0,0}, - { "HOUR", SYM(HOUR_SYM),0,0}, - { "HOUR_MICROSECOND", SYM(HOUR_MICROSECOND_SYM),0,0}, - { "HOUR_MINUTE", SYM(HOUR_MINUTE_SYM),0,0}, - { "HOUR_SECOND", SYM(HOUR_SECOND_SYM),0,0}, - { "IDENTIFIED", SYM(IDENTIFIED_SYM),0,0}, - { "IF", SYM(IF),0,0}, - { "IGNORE", SYM(IGNORE_SYM),0,0}, - { "IMPORT", SYM(IMPORT),0,0}, - { "IN", SYM(IN_SYM),0,0}, - { "INDEX", SYM(INDEX),0,0}, - { "INDEXES", SYM(INDEXES),0,0}, - { "INFILE", SYM(INFILE),0,0}, - { "INNER", SYM(INNER_SYM),0,0}, - { "INNOBASE", SYM(INNOBASE_SYM),0,0}, - { "INNODB", SYM(INNOBASE_SYM),0,0}, - { "INOUT", SYM(INOUT_SYM),0,0}, - { "INSENSITIVE", SYM(INSENSITIVE_SYM),0,0}, - { "INSERT", SYM(INSERT),0,0}, - { "INSERT_METHOD", SYM(INSERT_METHOD),0,0}, - { "INT", SYM(INT_SYM),0,0}, - { "INT1", SYM(TINYINT),0,0}, - { "INT2", SYM(SMALLINT),0,0}, - { "INT3", SYM(MEDIUMINT),0,0}, - { "INT4", SYM(INT_SYM),0,0}, - { "INT8", SYM(BIGINT),0,0}, - { "INTEGER", SYM(INT_SYM),0,0}, - { "INTERVAL", SYM(INTERVAL_SYM),0,0}, - { "INTO", SYM(INTO),0,0}, - { "IO_THREAD", SYM(RELAY_THREAD),0,0}, - { "IS", SYM(IS),0,0}, - { "ISOLATION", SYM(ISOLATION),0,0}, - { "ISSUER", SYM(ISSUER_SYM),0,0}, - { "ITERATE", SYM(ITERATE_SYM),0,0}, - { "INVOKER", SYM(INVOKER_SYM),0,0}, - { "JOIN", SYM(JOIN_SYM),0,0}, - { "KEY", SYM(KEY_SYM),0,0}, - { "KEYS", SYM(KEYS),0,0}, - { "KILL", SYM(KILL_SYM),0,0}, - { "LANGUAGE", SYM(LANGUAGE_SYM),0,0}, - { "LAST", SYM(LAST_SYM),0,0}, - { "LEADING", SYM(LEADING),0,0}, - { "LEAVE", SYM(LEAVE_SYM),0,0}, - { "LEAVES", SYM(LEAVES),0,0}, - { "LEFT", SYM(LEFT),0,0}, - { "LEVEL", SYM(LEVEL_SYM),0,0}, - { "LIKE", SYM(LIKE),0,0}, - { "LIMIT", SYM(LIMIT),0,0}, - { "LINES", SYM(LINES),0,0}, - { "LINESTRING", SYM(LINESTRING),0,0}, - { "LOAD", SYM(LOAD),0,0}, - { "LOCAL", SYM(LOCAL_SYM),0,0}, - { "LOCALTIME", SYM(NOW_SYM),0,0}, - { "LOCALTIMESTAMP", SYM(NOW_SYM),0,0}, - { "LOCK", SYM(LOCK_SYM),0,0}, - { "LOCKS", SYM(LOCKS_SYM),0,0}, - { "LOGS", SYM(LOGS_SYM),0,0}, - { "LONG", SYM(LONG_SYM),0,0}, - { "LONGBLOB", SYM(LONGBLOB),0,0}, - { "LONGTEXT", SYM(LONGTEXT),0,0}, - { "LOOP", SYM(LOOP_SYM),0,0}, - { "LOW_PRIORITY", SYM(LOW_PRIORITY),0,0}, - { "MASTER", SYM(MASTER_SYM),0,0}, - { "MASTER_CONNECT_RETRY", SYM(MASTER_CONNECT_RETRY_SYM),0,0}, - { "MASTER_HOST", SYM(MASTER_HOST_SYM),0,0}, - { "MASTER_LOG_FILE", SYM(MASTER_LOG_FILE_SYM),0,0}, - { "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM),0,0}, - { "MASTER_PASSWORD", SYM(MASTER_PASSWORD_SYM),0,0}, - { "MASTER_PORT", SYM(MASTER_PORT_SYM),0,0}, - { "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM),0,0}, - { "MASTER_SSL", SYM(MASTER_SSL_SYM),0,0}, - { "MASTER_SSL_CA", SYM(MASTER_SSL_CA_SYM),0,0}, - { "MASTER_SSL_CAPATH",SYM(MASTER_SSL_CAPATH_SYM),0,0}, - { "MASTER_SSL_CERT", SYM(MASTER_SSL_CERT_SYM),0,0}, - { "MASTER_SSL_CIPHER",SYM(MASTER_SSL_CIPHER_SYM),0,0}, - { "MASTER_SSL_KEY", SYM(MASTER_SSL_KEY_SYM),0,0}, - { "MASTER_USER", SYM(MASTER_USER_SYM),0,0}, - { "MATCH", SYM(MATCH),0,0}, - { "MAX_CONNECTIONS_PER_HOUR", SYM(MAX_CONNECTIONS_PER_HOUR), 0,0}, - { "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR), 0,0}, - { "MAX_ROWS", SYM(MAX_ROWS),0,0}, - { "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR), 0,0}, - { "MEDIUM", SYM(MEDIUM_SYM),0,0}, - { "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0}, - { "MEDIUMINT", SYM(MEDIUMINT),0,0}, - { "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0}, - { "MICROSECOND", SYM(MICROSECOND_SYM),0,0}, - { "MIDDLEINT", SYM(MEDIUMINT),0,0}, /* For powerbuilder */ - { "MINUTE", SYM(MINUTE_SYM),0,0}, - { "MINUTE_MICROSECOND", SYM(MINUTE_MICROSECOND_SYM),0,0}, - { "MINUTE_SECOND", SYM(MINUTE_SECOND_SYM),0,0}, - { "MIN_ROWS", SYM(MIN_ROWS),0,0}, - { "MOD", SYM(MOD_SYM),0,0}, - { "MODE", SYM(MODE_SYM),0,0}, - { "MODIFY", SYM(MODIFY_SYM),0,0}, - { "MONTH", SYM(MONTH_SYM),0,0}, - { "MULTILINESTRING", SYM(MULTILINESTRING),0,0}, - { "MULTIPOINT", SYM(MULTIPOINT),0,0}, - { "MULTIPOLYGON", SYM(MULTIPOLYGON),0,0}, - { "NAME", SYM(NAME_SYM),0,0}, - { "NAMES", SYM(NAMES_SYM),0,0}, - { "NATIONAL", SYM(NATIONAL_SYM),0,0}, - { "NATURAL", SYM(NATURAL),0,0}, - { "NCHAR", SYM(NCHAR_SYM),0,0}, - { "NEW", SYM(NEW_SYM),0,0}, - { "NEXT", SYM(NEXT_SYM),0,0}, - { "NO", SYM(NO_SYM),0,0}, - { "NONE", SYM(NONE_SYM),0,0}, - { "NOT", SYM(NOT),0,0}, - { "NO_WRITE_TO_BINLOG", SYM(NO_WRITE_TO_BINLOG),0,0}, - { "NULL", SYM(NULL_SYM),0,0}, - { "NUMERIC", SYM(NUMERIC_SYM),0,0}, - { "NVARCHAR", SYM(NVARCHAR_SYM),0,0}, - { "OFFSET", SYM(OFFSET_SYM),0,0}, - { "OLD_PASSWORD", SYM(OLD_PASSWORD),0,0}, - { "ON", SYM(ON),0,0}, - { "OPEN", SYM(OPEN_SYM),0,0}, - { "OPTIMIZE", SYM(OPTIMIZE),0,0}, - { "OPTION", SYM(OPTION),0,0}, - { "OPTIONALLY", SYM(OPTIONALLY),0,0}, - { "OR", SYM(OR),0,0}, - { "ORDER", SYM(ORDER_SYM),0,0}, - { "OUT", SYM(OUT_SYM),0,0}, - { "OUTER", SYM(OUTER),0,0}, - { "OUTFILE", SYM(OUTFILE),0,0}, - { "PACK_KEYS", SYM(PACK_KEYS_SYM),0,0}, - { "PARTIAL", SYM(PARTIAL),0,0}, - { "PASSWORD", SYM(PASSWORD),0,0}, - { "POINT", SYM(POINT_SYM),0,0}, - { "POLYGON", SYM(POLYGON),0,0}, - { "PRECISION", SYM(PRECISION),0,0}, - { "PREV", SYM(PREV_SYM),0,0}, - { "PRIMARY", SYM(PRIMARY_SYM),0,0}, - { "PRIVILEGES", SYM(PRIVILEGES),0,0}, - { "PROCEDURE", SYM(PROCEDURE),0,0}, - { "PROCESS" , SYM(PROCESS),0,0}, - { "PROCESSLIST", SYM(PROCESSLIST_SYM),0,0}, - { "PURGE", SYM(PURGE),0,0}, - { "QUARTER", SYM(QUARTER_SYM),0,0}, - { "QUERY", SYM(QUERY_SYM),0,0}, - { "QUICK", SYM(QUICK),0,0}, - { "RAID0", SYM(RAID_0_SYM),0,0}, - { "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0}, - { "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0}, - { "RAID_TYPE", SYM(RAID_TYPE),0,0}, - { "READ", SYM(READ_SYM),0,0}, - { "REAL", SYM(REAL),0,0}, - { "REFERENCES", SYM(REFERENCES),0,0}, - { "REGEXP", SYM(REGEXP),0,0}, - { "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM),0,0}, - { "RELAY_LOG_POS", SYM(RELAY_LOG_POS_SYM),0,0}, - { "RELAY_THREAD", SYM(RELAY_THREAD),0,0}, - { "RELOAD", SYM(RELOAD),0,0}, - { "RENAME", SYM(RENAME),0,0}, - { "REPAIR", SYM(REPAIR),0,0}, - { "REPEATABLE", SYM(REPEATABLE_SYM),0,0}, - { "REPLACE", SYM(REPLACE),0,0}, - { "REPLICATION", SYM(REPLICATION),0,0}, - { "REPEAT", SYM(REPEAT_SYM),0,0}, - { "REQUIRE", SYM(REQUIRE_SYM),0,0}, - { "RESET", SYM(RESET_SYM),0,0}, - { "RESTORE", SYM(RESTORE_SYM),0,0}, - { "RESTRICT", SYM(RESTRICT),0,0}, - { "RETURN", SYM(RETURN_SYM),0,0}, - { "RETURNS", SYM(RETURNS_SYM),0,0}, - { "REVOKE", SYM(REVOKE),0,0}, - { "RIGHT", SYM(RIGHT),0,0}, - { "RLIKE", SYM(REGEXP),0,0}, /* Like in mSQL2 */ - { "ROLLBACK", SYM(ROLLBACK_SYM),0,0}, - { "ROLLUP", SYM(ROLLUP_SYM),0,0}, - { "ROW", SYM(ROW_SYM),0,0}, - { "ROWS", SYM(ROWS_SYM),0,0}, - { "ROW_FORMAT", SYM(ROW_FORMAT_SYM),0,0}, - { "RTREE", SYM(RTREE_SYM),0,0}, - { "SAVEPOINT", SYM(SAVEPOINT_SYM),0,0}, - { "SECOND", SYM(SECOND_SYM),0,0}, - { "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM),0,0}, - { "SECURITY", SYM(SECURITY_SYM),0,0}, - { "SELECT", SYM(SELECT_SYM),0,0}, - { "SENSITIVE", SYM(SENSITIVE_SYM),0,0}, - { "SEPARATOR", SYM(SEPARATOR_SYM),0,0}, - { "SERIAL", SYM(SERIAL_SYM),0,0}, - { "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0}, - { "SESSION", SYM(SESSION_SYM),0,0}, - { "SET", SYM(SET),0,0}, - { "SHARE", SYM(SHARE_SYM),0,0}, - { "SHOW", SYM(SHOW),0,0}, - { "SHUTDOWN", SYM(SHUTDOWN),0,0}, - { "SIGNED", SYM(SIGNED_SYM),0,0}, - { "SIMPLE", SYM(SIMPLE_SYM),0,0}, - { "SLAVE", SYM(SLAVE),0,0}, - { "SMALLINT", SYM(SMALLINT),0,0}, - { "SOME", SYM(ANY_SYM),0,0}, - { "SONAME", SYM(UDF_SONAME_SYM),0,0}, - { "SOUNDS", SYM(SOUNDS_SYM),0,0}, - { "SPATIAL", SYM(SPATIAL_SYM),0,0}, - { "SPECIFIC", SYM(SPECIFIC_SYM),0,0}, - { "SQL", SYM(SQL_SYM),0,0}, - { "SQLEXCEPTION", SYM(SQLEXCEPTION_SYM),0,0}, - { "SQLSTATE", SYM(SQLSTATE_SYM),0,0}, - { "SQLWARNING", SYM(SQLWARNING_SYM),0,0}, - { "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),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_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0}, - { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0}, - { "SQL_THREAD", SYM(SQL_THREAD),0,0}, - { "SQL_TSI_FRAC_SECOND", SYM(FRAC_SECOND_SYM),0,0}, - { "SQL_TSI_SECOND", SYM(SECOND_SYM),0,0}, - { "SQL_TSI_MINUTE", SYM(MINUTE_SYM),0,0}, - { "SQL_TSI_HOUR", SYM(HOUR_SYM),0,0}, - { "SQL_TSI_DAY", SYM(DAY_SYM),0,0}, - { "SQL_TSI_WEEK", SYM(WEEK_SYM),0,0}, - { "SQL_TSI_MONTH", SYM(MONTH_SYM),0,0}, - { "SQL_TSI_QUARTER", SYM(QUARTER_SYM),0,0}, - { "SQL_TSI_YEAR", SYM(YEAR_SYM),0,0}, - { "SSL", SYM(SSL_SYM),0,0}, - { "START", SYM(START_SYM),0,0}, - { "STARTING", SYM(STARTING),0,0}, - { "STATUS", SYM(STATUS_SYM),0,0}, - { "STOP", SYM(STOP_SYM),0,0}, - { "STORAGE", SYM(STORAGE_SYM),0,0}, - { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0}, - { "STRING", SYM(STRING_SYM),0,0}, - { "STRIPED", SYM(RAID_STRIPED_SYM),0,0}, - { "SUBJECT", SYM(SUBJECT_SYM),0,0}, - { "SUPER", SYM(SUPER_SYM),0,0}, - { "TABLE", SYM(TABLE_SYM),0,0}, - { "TABLES", SYM(TABLES),0,0}, - { "TABLESPACE", SYM(TABLESPACE),0,0}, - { "TEMPORARY", SYM(TEMPORARY),0,0}, - { "TERMINATED", SYM(TERMINATED),0,0}, - { "TEXT", SYM(TEXT_SYM),0,0}, - { "THEN", SYM(THEN_SYM),0,0}, - { "TIME", SYM(TIME_SYM),0,0}, - { "TIMESTAMP", SYM(TIMESTAMP),0,0}, - { "TIMESTAMPADD", SYM(TIMESTAMP_ADD),0,0}, - { "TIMESTAMPDIFF", SYM(TIMESTAMP_DIFF),0,0}, - { "TINYBLOB", SYM(TINYBLOB),0,0}, - { "TINYINT", SYM(TINYINT),0,0}, - { "TINYTEXT", SYM(TINYTEXT),0,0}, - { "TO", SYM(TO_SYM),0,0}, - { "TRAILING", SYM(TRAILING),0,0}, - { "TRANSACTION", SYM(TRANSACTION_SYM),0,0}, - { "TRUE", SYM(TRUE_SYM),0,0}, - { "TRUNCATE", SYM(TRUNCATE_SYM),0,0}, - { "TYPE", SYM(TYPE_SYM),0,0}, - { "TYPES", SYM(TYPES_SYM),0,0}, - { "UNCOMMITTED", SYM(UNCOMMITTED_SYM),0,0}, - { "UNDO", SYM(UNDO_SYM),0,0}, - { "UNICODE", SYM(UNICODE_SYM),0,0}, - { "UNION", SYM(UNION_SYM),0,0}, - { "UNIQUE", SYM(UNIQUE_SYM),0,0}, - { "UNLOCK", SYM(UNLOCK_SYM),0,0}, - { "UNSIGNED", SYM(UNSIGNED),0,0}, - { "UNTIL", SYM(UNTIL_SYM),0,0}, - { "UPDATE", SYM(UPDATE_SYM),0,0}, - { "USAGE", SYM(USAGE),0,0}, - { "USE", SYM(USE_SYM),0,0}, - { "USER", SYM(USER),0,0}, - { "USER_RESOURCES", SYM(RESOURCES),0,0}, - { "USE_FRM", SYM(USE_FRM),0,0}, - { "USING", SYM(USING),0,0}, - { "UTC_DATE", SYM(UTC_DATE_SYM),0,0}, - { "UTC_TIME", SYM(UTC_TIME_SYM),0,0}, - { "UTC_TIMESTAMP", SYM(UTC_TIMESTAMP_SYM),0,0}, - { "VALUE", SYM(VALUE_SYM),0,0}, - { "VALUES", SYM(VALUES),0,0}, - { "VARBINARY", SYM(VARBINARY),0,0}, - { "VARCHAR", SYM(VARCHAR),0,0}, - { "VARCHARACTER", SYM(VARCHAR),0,0}, - { "VARIABLES", SYM(VARIABLES),0,0}, - { "VARYING", SYM(VARYING),0,0}, - { "WARNINGS", SYM(WARNINGS),0,0}, - { "WEEK", SYM(WEEK_SYM),0,0}, - { "WHEN", SYM(WHEN_SYM),0,0}, - { "WHERE", SYM(WHERE),0,0}, - { "WITH", SYM(WITH),0,0}, - { "WORK", SYM(WORK_SYM),0,0}, - { "WRITE", SYM(WRITE_SYM),0,0}, - { "WHILE", SYM(WHILE_SYM),0,0}, - { "X509", SYM(X509_SYM),0,0}, - { "XOR", SYM(XOR),0,0}, - { "YEAR", SYM(YEAR_SYM),0,0}, - { "YEAR_MONTH", SYM(YEAR_MONTH_SYM),0,0}, - { "ZEROFILL", SYM(ZEROFILL),0,0}, - { "||", SYM(OR_OR_CONCAT),0,0} + { "&&", SYM(AND)}, + { "<", SYM(LT)}, + { "<=", SYM(LE)}, + { "<>", SYM(NE)}, + { "!=", SYM(NE)}, + { "=", SYM(EQ)}, + { ">", SYM(GT_SYM)}, + { ">=", SYM(GE)}, + { "<<", SYM(SHIFT_LEFT)}, + { ">>", SYM(SHIFT_RIGHT)}, + { "<=>", SYM(EQUAL_SYM)}, + { "ACTION", SYM(ACTION)}, + { "ADD", SYM(ADD)}, + { "AFTER", SYM(AFTER_SYM)}, + { "AGAINST", SYM(AGAINST)}, + { "AGGREGATE", SYM(AGGREGATE_SYM)}, + { "ALL", SYM(ALL)}, + { "ALTER", SYM(ALTER)}, + { "ANALYZE", SYM(ANALYZE_SYM)}, + { "AND", SYM(AND)}, + { "ANY", SYM(ANY_SYM)}, + { "AS", SYM(AS)}, + { "ASC", SYM(ASC)}, + { "ASCII", SYM(ASCII_SYM)}, + { "ASENSITIVE", SYM(ASENSITIVE_SYM)}, + { "AUTO_INCREMENT", SYM(AUTO_INC)}, + { "AVG", SYM(AVG_SYM)}, + { "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH)}, + { "BACKUP", SYM(BACKUP_SYM)}, + { "BDB", SYM(BERKELEY_DB_SYM)}, + { "BEFORE", SYM(BEFORE_SYM)}, + { "BEGIN", SYM(BEGIN_SYM)}, + { "BERKELEYDB", SYM(BERKELEY_DB_SYM)}, + { "BETWEEN", SYM(BETWEEN_SYM)}, + { "BIGINT", SYM(BIGINT)}, + { "BINARY", SYM(BINARY)}, + { "BINLOG", SYM(BINLOG_SYM)}, + { "BIT", SYM(BIT_SYM)}, + { "BLOB", SYM(BLOB_SYM)}, + { "BOOL", SYM(BOOL_SYM)}, + { "BOOLEAN", SYM(BOOLEAN_SYM)}, + { "BOTH", SYM(BOTH)}, + { "BTREE", SYM(BTREE_SYM)}, + { "BY", SYM(BY)}, + { "BYTE", SYM(BYTE_SYM)}, + { "CACHE", SYM(CACHE_SYM)}, + { "CALL", SYM(CALL_SYM)}, + { "CASCADE", SYM(CASCADE)}, + { "CASE", SYM(CASE_SYM)}, + { "CHANGE", SYM(CHANGE)}, + { "CHANGED", SYM(CHANGED)}, + { "CHAR", SYM(CHAR_SYM)}, + { "CHARACTER", SYM(CHAR_SYM)}, + { "CHARSET", SYM(CHARSET)}, + { "CHECK", SYM(CHECK_SYM)}, + { "CHECKSUM", SYM(CHECKSUM_SYM)}, + { "CIPHER", SYM(CIPHER_SYM)}, + { "CLIENT", SYM(CLIENT_SYM)}, + { "CLOSE", SYM(CLOSE_SYM)}, + { "COLLATE", SYM(COLLATE_SYM)}, + { "COLLATION", SYM(COLLATION_SYM)}, + { "COLUMN", SYM(COLUMN_SYM)}, + { "COLUMNS", SYM(COLUMNS)}, + { "COMMENT", SYM(COMMENT_SYM)}, + { "COMMIT", SYM(COMMIT_SYM)}, + { "COMMITTED", SYM(COMMITTED_SYM)}, + { "COMPRESSED", SYM(COMPRESSED_SYM)}, + { "CONCURRENT", SYM(CONCURRENT)}, + { "CONDITION", SYM(CONDITION_SYM)}, + { "CONNECTION", SYM(CONNECTION_SYM)}, + { "CONSTRAINT", SYM(CONSTRAINT)}, + { "CONTINUE", SYM(CONTINUE_SYM)}, + { "CREATE", SYM(CREATE)}, + { "CROSS", SYM(CROSS)}, + { "CUBE", SYM(CUBE_SYM)}, + { "CURRENT_DATE", SYM(CURDATE)}, + { "CURRENT_TIME", SYM(CURTIME)}, + { "CURRENT_TIMESTAMP", SYM(NOW_SYM)}, + { "CURSOR", SYM(CURSOR_SYM)}, + { "DATA", SYM(DATA_SYM)}, + { "DATABASE", SYM(DATABASE)}, + { "DATABASES", SYM(DATABASES)}, + { "DATE", SYM(DATE_SYM)}, + { "DATETIME", SYM(DATETIME)}, + { "DAY", SYM(DAY_SYM)}, + { "DAY_HOUR", SYM(DAY_HOUR_SYM)}, + { "DAY_MICROSECOND", SYM(DAY_MICROSECOND_SYM)}, + { "DAY_MINUTE", SYM(DAY_MINUTE_SYM)}, + { "DAY_SECOND", SYM(DAY_SECOND_SYM)}, + { "DEC", SYM(DECIMAL_SYM)}, + { "DECIMAL", SYM(DECIMAL_SYM)}, + { "DECLARE", SYM(DECLARE_SYM)}, + { "DEFAULT", SYM(DEFAULT)}, + { "DEFINER", SYM(DEFINER_SYM)}, + { "DELAYED", SYM(DELAYED_SYM)}, + { "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM)}, + { "DELETE", SYM(DELETE_SYM)}, + { "DESC", SYM(DESC)}, + { "DESCRIBE", SYM(DESCRIBE)}, + { "DES_KEY_FILE", SYM(DES_KEY_FILE)}, + { "DETERMINISTIC", SYM(DETERMINISTIC_SYM)}, + { "DIRECTORY", SYM(DIRECTORY_SYM)}, + { "DISABLE", SYM(DISABLE_SYM)}, + { "DISCARD", SYM(DISCARD)}, + { "DISTINCT", SYM(DISTINCT)}, + { "DISTINCTROW", SYM(DISTINCT)}, /* Access likes this */ + { "DIV", SYM(DIV_SYM)}, + { "DO", SYM(DO_SYM)}, + { "DOUBLE", SYM(DOUBLE_SYM)}, + { "DROP", SYM(DROP)}, + { "DUAL", SYM(DUAL_SYM)}, + { "DUMPFILE", SYM(DUMPFILE)}, + { "DUPLICATE", SYM(DUPLICATE_SYM)}, + { "DYNAMIC", SYM(DYNAMIC_SYM)}, + { "ELSE", SYM(ELSE)}, + { "ELSEIF", SYM(ELSEIF_SYM)}, + { "ENABLE", SYM(ENABLE_SYM)}, + { "ENCLOSED", SYM(ENCLOSED)}, + { "END", SYM(END)}, + { "ENGINE", SYM(ENGINE_SYM)}, + { "ENGINES", SYM(ENGINES_SYM)}, + { "ENUM", SYM(ENUM)}, + { "ERRORS", SYM(ERRORS)}, + { "ESCAPE", SYM(ESCAPE_SYM)}, + { "ESCAPED", SYM(ESCAPED)}, + { "EVENTS", SYM(EVENTS_SYM)}, + { "EXECUTE", SYM(EXECUTE_SYM)}, + { "EXISTS", SYM(EXISTS)}, + { "EXIT", SYM(EXIT_SYM)}, + { "EXPANSION", SYM(EXPANSION_SYM)}, + { "EXPLAIN", SYM(DESCRIBE)}, + { "EXTENDED", SYM(EXTENDED_SYM)}, + { "FALSE", SYM(FALSE_SYM)}, + { "FAST", SYM(FAST_SYM)}, + { "FETCH", SYM(FETCH_SYM)}, + { "FIELDS", SYM(COLUMNS)}, + { "FILE", SYM(FILE_SYM)}, + { "FIRST", SYM(FIRST_SYM)}, + { "FIXED", SYM(FIXED_SYM)}, + { "FLOAT", SYM(FLOAT_SYM)}, + { "FLOAT4", SYM(FLOAT_SYM)}, + { "FLOAT8", SYM(DOUBLE_SYM)}, + { "FLUSH", SYM(FLUSH_SYM)}, + { "FOR", SYM(FOR_SYM)}, + { "FORCE", SYM(FORCE_SYM)}, + { "FOREIGN", SYM(FOREIGN)}, + { "FOUND", SYM(FOUND_SYM)}, + { "FRAC_SECOND", SYM(FRAC_SECOND_SYM)}, + { "FROM", SYM(FROM)}, + { "FULL", SYM(FULL)}, + { "FULLTEXT", SYM(FULLTEXT_SYM)}, + { "FUNCTION", SYM(FUNCTION_SYM)}, + { "GEOMETRY", SYM(GEOMETRY_SYM)}, + { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)}, + { "GET_FORMAT", SYM(GET_FORMAT)}, + { "GLOBAL", SYM(GLOBAL_SYM)}, + { "GRANT", SYM(GRANT)}, + { "GRANTS", SYM(GRANTS)}, + { "GROUP", SYM(GROUP)}, + { "HANDLER", SYM(HANDLER_SYM)}, + { "HASH", SYM(HASH_SYM)}, + { "HAVING", SYM(HAVING)}, + { "HELP", SYM(HELP_SYM)}, + { "HIGH_PRIORITY", SYM(HIGH_PRIORITY)}, + { "HOSTS", SYM(HOSTS_SYM)}, + { "HOUR", SYM(HOUR_SYM)}, + { "HOUR_MICROSECOND", SYM(HOUR_MICROSECOND_SYM)}, + { "HOUR_MINUTE", SYM(HOUR_MINUTE_SYM)}, + { "HOUR_SECOND", SYM(HOUR_SECOND_SYM)}, + { "IDENTIFIED", SYM(IDENTIFIED_SYM)}, + { "IF", SYM(IF)}, + { "IGNORE", SYM(IGNORE_SYM)}, + { "IMPORT", SYM(IMPORT)}, + { "IN", SYM(IN_SYM)}, + { "INDEX", SYM(INDEX)}, + { "INDEXES", SYM(INDEXES)}, + { "INFILE", SYM(INFILE)}, + { "INNER", SYM(INNER_SYM)}, + { "INNOBASE", SYM(INNOBASE_SYM)}, + { "INNODB", SYM(INNOBASE_SYM)}, + { "INOUT", SYM(INOUT_SYM)}, + { "INSENSITIVE", SYM(INSENSITIVE_SYM)}, + { "INSERT", SYM(INSERT)}, + { "INSERT_METHOD", SYM(INSERT_METHOD)}, + { "INT", SYM(INT_SYM)}, + { "INT1", SYM(TINYINT)}, + { "INT2", SYM(SMALLINT)}, + { "INT3", SYM(MEDIUMINT)}, + { "INT4", SYM(INT_SYM)}, + { "INT8", SYM(BIGINT)}, + { "INTEGER", SYM(INT_SYM)}, + { "INTERVAL", SYM(INTERVAL_SYM)}, + { "INTO", SYM(INTO)}, + { "IO_THREAD", SYM(RELAY_THREAD)}, + { "IS", SYM(IS)}, + { "ISOLATION", SYM(ISOLATION)}, + { "ISSUER", SYM(ISSUER_SYM)}, + { "ITERATE", SYM(ITERATE_SYM)}, + { "INVOKER", SYM(INVOKER_SYM)}, + { "JOIN", SYM(JOIN_SYM)}, + { "KEY", SYM(KEY_SYM)}, + { "KEYS", SYM(KEYS)}, + { "KILL", SYM(KILL_SYM)}, + { "LANGUAGE", SYM(LANGUAGE_SYM)}, + { "LAST", SYM(LAST_SYM)}, + { "LEADING", SYM(LEADING)}, + { "LEAVE", SYM(LEAVE_SYM)}, + { "LEAVES", SYM(LEAVES)}, + { "LEFT", SYM(LEFT)}, + { "LEVEL", SYM(LEVEL_SYM)}, + { "LIKE", SYM(LIKE)}, + { "LIMIT", SYM(LIMIT)}, + { "LINES", SYM(LINES)}, + { "LINESTRING", SYM(LINESTRING)}, + { "LOAD", SYM(LOAD)}, + { "LOCAL", SYM(LOCAL_SYM)}, + { "LOCALTIME", SYM(NOW_SYM)}, + { "LOCALTIMESTAMP", SYM(NOW_SYM)}, + { "LOCK", SYM(LOCK_SYM)}, + { "LOCKS", SYM(LOCKS_SYM)}, + { "LOGS", SYM(LOGS_SYM)}, + { "LONG", SYM(LONG_SYM)}, + { "LONGBLOB", SYM(LONGBLOB)}, + { "LONGTEXT", SYM(LONGTEXT)}, + { "LOOP", SYM(LOOP_SYM)}, + { "LOW_PRIORITY", SYM(LOW_PRIORITY)}, + { "MASTER", SYM(MASTER_SYM)}, + { "MASTER_CONNECT_RETRY", SYM(MASTER_CONNECT_RETRY_SYM)}, + { "MASTER_HOST", SYM(MASTER_HOST_SYM)}, + { "MASTER_LOG_FILE", SYM(MASTER_LOG_FILE_SYM)}, + { "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM)}, + { "MASTER_PASSWORD", SYM(MASTER_PASSWORD_SYM)}, + { "MASTER_PORT", SYM(MASTER_PORT_SYM)}, + { "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM)}, + { "MASTER_SSL", SYM(MASTER_SSL_SYM)}, + { "MASTER_SSL_CA", SYM(MASTER_SSL_CA_SYM)}, + { "MASTER_SSL_CAPATH",SYM(MASTER_SSL_CAPATH_SYM)}, + { "MASTER_SSL_CERT", SYM(MASTER_SSL_CERT_SYM)}, + { "MASTER_SSL_CIPHER",SYM(MASTER_SSL_CIPHER_SYM)}, + { "MASTER_SSL_KEY", SYM(MASTER_SSL_KEY_SYM)}, + { "MASTER_USER", SYM(MASTER_USER_SYM)}, + { "MATCH", SYM(MATCH)}, + { "MAX_CONNECTIONS_PER_HOUR", SYM(MAX_CONNECTIONS_PER_HOUR)}, + { "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR)}, + { "MAX_ROWS", SYM(MAX_ROWS)}, + { "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR)}, + { "MEDIUM", SYM(MEDIUM_SYM)}, + { "MEDIUMBLOB", SYM(MEDIUMBLOB)}, + { "MEDIUMINT", SYM(MEDIUMINT)}, + { "MEDIUMTEXT", SYM(MEDIUMTEXT)}, + { "MICROSECOND", SYM(MICROSECOND_SYM)}, + { "MIDDLEINT", SYM(MEDIUMINT)}, /* For powerbuilder */ + { "MINUTE", SYM(MINUTE_SYM)}, + { "MINUTE_MICROSECOND", SYM(MINUTE_MICROSECOND_SYM)}, + { "MINUTE_SECOND", SYM(MINUTE_SECOND_SYM)}, + { "MIN_ROWS", SYM(MIN_ROWS)}, + { "MOD", SYM(MOD_SYM)}, + { "MODE", SYM(MODE_SYM)}, + { "MODIFY", SYM(MODIFY_SYM)}, + { "MONTH", SYM(MONTH_SYM)}, + { "MULTILINESTRING", SYM(MULTILINESTRING)}, + { "MULTIPOINT", SYM(MULTIPOINT)}, + { "MULTIPOLYGON", SYM(MULTIPOLYGON)}, + { "NAME", SYM(NAME_SYM)}, + { "NAMES", SYM(NAMES_SYM)}, + { "NATIONAL", SYM(NATIONAL_SYM)}, + { "NATURAL", SYM(NATURAL)}, + { "NCHAR", SYM(NCHAR_SYM)}, + { "NEW", SYM(NEW_SYM)}, + { "NEXT", SYM(NEXT_SYM)}, + { "NO", SYM(NO_SYM)}, + { "NONE", SYM(NONE_SYM)}, + { "NOT", SYM(NOT)}, + { "NO_WRITE_TO_BINLOG", SYM(NO_WRITE_TO_BINLOG)}, + { "NULL", SYM(NULL_SYM)}, + { "NUMERIC", SYM(NUMERIC_SYM)}, + { "NVARCHAR", SYM(NVARCHAR_SYM)}, + { "OFFSET", SYM(OFFSET_SYM)}, + { "OLD_PASSWORD", SYM(OLD_PASSWORD)}, + { "ON", SYM(ON)}, + { "OPEN", SYM(OPEN_SYM)}, + { "OPTIMIZE", SYM(OPTIMIZE)}, + { "OPTION", SYM(OPTION)}, + { "OPTIONALLY", SYM(OPTIONALLY)}, + { "OR", SYM(OR)}, + { "ORDER", SYM(ORDER_SYM)}, + { "OUT", SYM(OUT_SYM)}, + { "OUTER", SYM(OUTER)}, + { "OUTFILE", SYM(OUTFILE)}, + { "PACK_KEYS", SYM(PACK_KEYS_SYM)}, + { "PARTIAL", SYM(PARTIAL)}, + { "PASSWORD", SYM(PASSWORD)}, + { "POINT", SYM(POINT_SYM)}, + { "POLYGON", SYM(POLYGON)}, + { "PRECISION", SYM(PRECISION)}, + { "PREV", SYM(PREV_SYM)}, + { "PRIMARY", SYM(PRIMARY_SYM)}, + { "PRIVILEGES", SYM(PRIVILEGES)}, + { "PROCEDURE", SYM(PROCEDURE)}, + { "PROCESS" , SYM(PROCESS)}, + { "PROCESSLIST", SYM(PROCESSLIST_SYM)}, + { "PURGE", SYM(PURGE)}, + { "QUARTER", SYM(QUARTER_SYM)}, + { "QUERY", SYM(QUERY_SYM)}, + { "QUICK", SYM(QUICK)}, + { "RAID0", SYM(RAID_0_SYM)}, + { "RAID_CHUNKS", SYM(RAID_CHUNKS)}, + { "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE)}, + { "RAID_TYPE", SYM(RAID_TYPE)}, + { "READ", SYM(READ_SYM)}, + { "REAL", SYM(REAL)}, + { "REFERENCES", SYM(REFERENCES)}, + { "REGEXP", SYM(REGEXP)}, + { "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM)}, + { "RELAY_LOG_POS", SYM(RELAY_LOG_POS_SYM)}, + { "RELAY_THREAD", SYM(RELAY_THREAD)}, + { "RELOAD", SYM(RELOAD)}, + { "RENAME", SYM(RENAME)}, + { "REPAIR", SYM(REPAIR)}, + { "REPEATABLE", SYM(REPEATABLE_SYM)}, + { "REPLACE", SYM(REPLACE)}, + { "REPLICATION", SYM(REPLICATION)}, + { "REPEAT", SYM(REPEAT_SYM)}, + { "REQUIRE", SYM(REQUIRE_SYM)}, + { "RESET", SYM(RESET_SYM)}, + { "RESTORE", SYM(RESTORE_SYM)}, + { "RESTRICT", SYM(RESTRICT)}, + { "RETURN", SYM(RETURN_SYM)}, + { "RETURNS", SYM(RETURNS_SYM)}, + { "REVOKE", SYM(REVOKE)}, + { "RIGHT", SYM(RIGHT)}, + { "RLIKE", SYM(REGEXP)}, /* Like in mSQL2 */ + { "ROLLBACK", SYM(ROLLBACK_SYM)}, + { "ROLLUP", SYM(ROLLUP_SYM)}, + { "ROW", SYM(ROW_SYM)}, + { "ROWS", SYM(ROWS_SYM)}, + { "ROW_FORMAT", SYM(ROW_FORMAT_SYM)}, + { "RTREE", SYM(RTREE_SYM)}, + { "SAVEPOINT", SYM(SAVEPOINT_SYM)}, + { "SECOND", SYM(SECOND_SYM)}, + { "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM)}, + { "SECURITY", SYM(SECURITY_SYM)}, + { "SELECT", SYM(SELECT_SYM)}, + { "SENSITIVE", SYM(SENSITIVE_SYM)}, + { "SEPARATOR", SYM(SEPARATOR_SYM)}, + { "SERIAL", SYM(SERIAL_SYM)}, + { "SERIALIZABLE", SYM(SERIALIZABLE_SYM)}, + { "SESSION", SYM(SESSION_SYM)}, + { "SET", SYM(SET)}, + { "SHARE", SYM(SHARE_SYM)}, + { "SHOW", SYM(SHOW)}, + { "SHUTDOWN", SYM(SHUTDOWN)}, + { "SIGNED", SYM(SIGNED_SYM)}, + { "SIMPLE", SYM(SIMPLE_SYM)}, + { "SLAVE", SYM(SLAVE)}, + { "SMALLINT", SYM(SMALLINT)}, + { "SOME", SYM(ANY_SYM)}, + { "SONAME", SYM(UDF_SONAME_SYM)}, + { "SOUNDS", SYM(SOUNDS_SYM)}, + { "SPATIAL", SYM(SPATIAL_SYM)}, + { "SPECIFIC", SYM(SPECIFIC_SYM)}, + { "SQL", SYM(SQL_SYM)}, + { "SQLEXCEPTION", SYM(SQLEXCEPTION_SYM)}, + { "SQLSTATE", SYM(SQLSTATE_SYM)}, + { "SQLWARNING", SYM(SQLWARNING_SYM)}, + { "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT)}, + { "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT)}, + { "SQL_CACHE", SYM(SQL_CACHE_SYM)}, + { "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS)}, + { "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM)}, + { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT)}, + { "SQL_THREAD", SYM(SQL_THREAD)}, + { "SQL_TSI_FRAC_SECOND", SYM(FRAC_SECOND_SYM)}, + { "SQL_TSI_SECOND", SYM(SECOND_SYM)}, + { "SQL_TSI_MINUTE", SYM(MINUTE_SYM)}, + { "SQL_TSI_HOUR", SYM(HOUR_SYM)}, + { "SQL_TSI_DAY", SYM(DAY_SYM)}, + { "SQL_TSI_WEEK", SYM(WEEK_SYM)}, + { "SQL_TSI_MONTH", SYM(MONTH_SYM)}, + { "SQL_TSI_QUARTER", SYM(QUARTER_SYM)}, + { "SQL_TSI_YEAR", SYM(YEAR_SYM)}, + { "SSL", SYM(SSL_SYM)}, + { "START", SYM(START_SYM)}, + { "STARTING", SYM(STARTING)}, + { "STATUS", SYM(STATUS_SYM)}, + { "STOP", SYM(STOP_SYM)}, + { "STORAGE", SYM(STORAGE_SYM)}, + { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN)}, + { "STRING", SYM(STRING_SYM)}, + { "STRIPED", SYM(RAID_STRIPED_SYM)}, + { "SUBJECT", SYM(SUBJECT_SYM)}, + { "SUPER", SYM(SUPER_SYM)}, + { "TABLE", SYM(TABLE_SYM)}, + { "TABLES", SYM(TABLES)}, + { "TABLESPACE", SYM(TABLESPACE)}, + { "TEMPORARY", SYM(TEMPORARY)}, + { "TERMINATED", SYM(TERMINATED)}, + { "TEXT", SYM(TEXT_SYM)}, + { "THEN", SYM(THEN_SYM)}, + { "TIME", SYM(TIME_SYM)}, + { "TIMESTAMP", SYM(TIMESTAMP)}, + { "TIMESTAMPADD", SYM(TIMESTAMP_ADD)}, + { "TIMESTAMPDIFF", SYM(TIMESTAMP_DIFF)}, + { "TINYBLOB", SYM(TINYBLOB)}, + { "TINYINT", SYM(TINYINT)}, + { "TINYTEXT", SYM(TINYTEXT)}, + { "TO", SYM(TO_SYM)}, + { "TRAILING", SYM(TRAILING)}, + { "TRANSACTION", SYM(TRANSACTION_SYM)}, + { "TRUE", SYM(TRUE_SYM)}, + { "TRUNCATE", SYM(TRUNCATE_SYM)}, + { "TYPE", SYM(TYPE_SYM)}, + { "TYPES", SYM(TYPES_SYM)}, + { "UNCOMMITTED", SYM(UNCOMMITTED_SYM)}, + { "UNDO", SYM(UNDO_SYM)}, + { "UNICODE", SYM(UNICODE_SYM)}, + { "UNION", SYM(UNION_SYM)}, + { "UNIQUE", SYM(UNIQUE_SYM)}, + { "UNLOCK", SYM(UNLOCK_SYM)}, + { "UNSIGNED", SYM(UNSIGNED)}, + { "UNTIL", SYM(UNTIL_SYM)}, + { "UPDATE", SYM(UPDATE_SYM)}, + { "USAGE", SYM(USAGE)}, + { "USE", SYM(USE_SYM)}, + { "USER", SYM(USER)}, + { "USER_RESOURCES", SYM(RESOURCES)}, + { "USE_FRM", SYM(USE_FRM)}, + { "USING", SYM(USING)}, + { "UTC_DATE", SYM(UTC_DATE_SYM)}, + { "UTC_TIME", SYM(UTC_TIME_SYM)}, + { "UTC_TIMESTAMP", SYM(UTC_TIMESTAMP_SYM)}, + { "VALUE", SYM(VALUE_SYM)}, + { "VALUES", SYM(VALUES)}, + { "VARBINARY", SYM(VARBINARY)}, + { "VARCHAR", SYM(VARCHAR)}, + { "VARCHARACTER", SYM(VARCHAR)}, + { "VARIABLES", SYM(VARIABLES)}, + { "VARYING", SYM(VARYING)}, + { "WARNINGS", SYM(WARNINGS)}, + { "WEEK", SYM(WEEK_SYM)}, + { "WHEN", SYM(WHEN_SYM)}, + { "WHERE", SYM(WHERE)}, + { "WHILE", SYM(WHILE_SYM)}, + { "WITH", SYM(WITH)}, + { "WORK", SYM(WORK_SYM)}, + { "WRITE", SYM(WRITE_SYM)}, + { "X509", SYM(X509_SYM)}, + { "XOR", SYM(XOR)}, + { "YEAR", SYM(YEAR_SYM)}, + { "YEAR_MONTH", SYM(YEAR_MONTH_SYM)}, + { "ZEROFILL", SYM(ZEROFILL)}, + { "||", SYM(OR_OR_CONCAT)} }; static SYMBOL sql_functions[] = { - { "ABS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_abs)}, - { "ACOS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_acos)}, - { "ADDDATE", SYM(ADDDATE_SYM),0,0}, - { "ADDTIME", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_addtime)}, - { "AES_ENCRYPT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_encrypt)}, - { "AES_DECRYPT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_decrypt)}, - { "AREA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_area)}, - { "ASIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)}, - { "ASBINARY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_wkb)}, - { "ASTEXT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_wkt)}, - { "ASWKB", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_wkb)}, - { "ASWKT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_wkt)}, - { "ATAN", SYM(ATAN),0,0}, - { "ATAN2", SYM(ATAN),0,0}, - { "BENCHMARK", SYM(BENCHMARK_SYM),0,0}, - { "BIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bin)}, - { "BIT_COUNT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)}, - { "BIT_OR", SYM(BIT_OR),0,0}, - { "BIT_AND", SYM(BIT_AND),0,0}, - { "BIT_XOR", SYM(BIT_XOR),0,0}, - { "CAST", SYM(CAST_SYM),0,0}, - { "CEIL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)}, - { "CEILING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)}, - { "CURRENT_USER", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_current_user)}, - { "BIT_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)}, - { "CENTROID", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_centroid)}, - { "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, - { "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, - { "COALESCE", SYM(COALESCE),0,0}, - { "COERCIBILITY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_coercibility)}, - { "COMPRESS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_compress)}, - { "CONCAT", SYM(CONCAT),0,0}, - { "CONCAT_WS", SYM(CONCAT_WS),0,0}, - { "CONNECTION_ID", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)}, - { "CONTAINS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_contains)}, - { "CONV", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)}, - { "CONVERT", SYM(CONVERT_SYM),0,0}, - { "COUNT", SYM(COUNT_SYM),0,0}, - { "COS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)}, - { "COT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)}, - { "CRC32", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_crc32)}, - { "CROSSES", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_crosses)}, - { "CURDATE", SYM(CURDATE),0,0}, - { "CURTIME", SYM(CURTIME),0,0}, - { "DATE_ADD", SYM(DATE_ADD_INTERVAL),0,0}, - { "DATEDIFF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_datediff)}, - { "DATE_FORMAT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_date_format)}, - { "DATE_SUB", SYM(DATE_SUB_INTERVAL),0,0}, - { "DAYNAME", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayname)}, - { "DAYOFMONTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofmonth)}, - { "DAYOFWEEK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofweek)}, - { "DAYOFYEAR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofyear)}, - { "DECODE", SYM(DECODE_SYM),0,0}, - { "DEGREES", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_degrees)}, - { "DES_ENCRYPT", SYM(DES_ENCRYPT_SYM),0,0}, - { "DES_DECRYPT", SYM(DES_DECRYPT_SYM),0,0}, - { "DIMENSION", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dimension)}, - { "DISJOINT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_disjoint)}, - { "ELT", SYM(ELT_FUNC),0,0}, - { "ENCODE", SYM(ENCODE_SYM),0,0}, - { "ENCRYPT", SYM(ENCRYPT),0,0}, - { "ENDPOINT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_endpoint)}, - { "ENVELOPE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_envelope)}, - { "EQUALS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_equals)}, - { "EXTERIORRING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_exteriorring)}, - { "EXTRACT", SYM(EXTRACT_SYM),0,0}, - { "EXP", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_exp)}, - { "EXPORT_SET", SYM(EXPORT_SET),0,0}, - { "FIELD", SYM(FIELD_FUNC),0,0}, /* For compability */ - { "FIND_IN_SET", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_find_in_set)}, - { "FLOOR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_floor)}, - { "FORMAT", SYM(FORMAT_SYM),0,0}, - { "FOUND_ROWS", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_found_rows)}, - { "FROM_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_from_days)}, - { "FROM_UNIXTIME", SYM(FROM_UNIXTIME),0,0}, - { "GET_LOCK", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_get_lock)}, - { "GEOMETRYN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_geometryn)}, - { "GEOMETRYTYPE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_geometry_type)}, - { "GEOMCOLLFROMTEXT", SYM(GEOMCOLLFROMTEXT),0,0}, - { "GEOMCOLLFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "GEOMETRYCOLLECTIONFROMTEXT",SYM(GEOMCOLLFROMTEXT),0,0}, - { "GEOMETRYCOLLECTIONFROMWKB",SYM(GEOMFROMWKB),0,0}, - { "GEOMETRYFROMTEXT", SYM(GEOMFROMTEXT),0,0}, - { "GEOMETRYFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "GEOMFROMTEXT", SYM(GEOMFROMTEXT),0,0}, - { "GEOMFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "GLENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_glength)}, - { "GREATEST", SYM(GREATEST_SYM),0,0}, - { "GROUP_CONCAT", SYM(GROUP_CONCAT_SYM),0,0}, - { "GROUP_UNIQUE_USERS", SYM(GROUP_UNIQUE_USERS),0,0}, - { "HEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_hex)}, - { "IFNULL", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_ifnull)}, - { "INET_ATON", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_aton)}, - { "INET_NTOA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_ntoa)}, - { "INSTR", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_instr)}, - { "INTERIORRINGN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_interiorringn)}, - { "INTERSECTS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_intersects)}, - { "ISCLOSED", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isclosed)}, - { "ISEMPTY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isempty)}, - { "ISNULL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)}, - { "IS_FREE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)}, - { "IS_USED_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_used_lock)}, - { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0}, - { "ISSIMPLE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_issimple)}, - { "LAST_DAY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_last_day)}, - { "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)}, - { "LN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ln)}, - { "LINEFROMTEXT", SYM(LINEFROMTEXT),0,0}, - { "LINEFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "LINESTRINGFROMTEXT",SYM(LINEFROMTEXT),0,0}, - { "LINESTRINGFROMWKB",SYM(GEOMFROMWKB),0,0}, - { "LOAD_FILE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_load_file)}, - { "LOCATE", SYM(LOCATE),0,0}, - { "LOG", SYM(LOG_SYM),0,0}, - { "LOG2", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log2)}, - { "LOG10", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log10)}, - { "LOWER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)}, - { "LPAD", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_lpad)}, - { "LTRIM", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ltrim)}, - { "MAKE_SET", SYM(MAKE_SET_SYM),0,0}, - { "MAKEDATE", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_makedate)}, - { "MAKETIME", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_maketime)}, - { "MASTER_POS_WAIT", SYM(MASTER_POS_WAIT),0,0}, - { "MAX", SYM(MAX_SYM),0,0}, - { "MBRCONTAINS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_contains)}, - { "MBRDISJOINT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_disjoint)}, - { "MBREQUAL", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_equals)}, - { "MBRINTERSECTS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_intersects)}, - { "MBROVERLAPS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_overlaps)}, - { "MBRTOUCHES", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_touches)}, - { "MBRWITHIN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_within)}, - { "MD5", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_md5)}, - { "MID", SYM(SUBSTRING),0,0}, /* unireg function */ - { "MIN", SYM(MIN_SYM),0,0}, - { "MLINEFROMTEXT", SYM(MLINEFROMTEXT),0,0}, - { "MLINEFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "MPOINTFROMTEXT", SYM(MPOINTFROMTEXT),0,0}, - { "MPOINTFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "MPOLYFROMTEXT", SYM(MPOLYFROMTEXT),0,0}, - { "MPOLYFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "MONTHNAME", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_monthname)}, - { "MULTILINESTRINGFROMTEXT",SYM(MLINEFROMTEXT),0,0}, - { "MULTILINESTRINGFROMWKB",SYM(GEOMFROMWKB),0,0}, - { "MULTIPOINTFROMTEXT",SYM(MPOINTFROMTEXT),0,0}, - { "MULTIPOINTFROMWKB",SYM(GEOMFROMWKB),0,0}, - { "MULTIPOLYGONFROMTEXT",SYM(MPOLYFROMTEXT),0,0}, - { "MULTIPOLYGONFROMWKB",SYM(GEOMFROMWKB),0,0}, - { "NOW", SYM(NOW_SYM),0,0}, - { "NULLIF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_nullif)}, - { "NUMGEOMETRIES", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numgeometries)}, - { "NUMINTERIORRINGS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numinteriorring)}, - { "NUMPOINTS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numpoints)}, - { "OCTET_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)}, - { "OCT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)}, - { "ORD", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ord)}, - { "OVERLAPS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_overlaps)}, - { "PERIOD_ADD", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)}, - { "PERIOD_DIFF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_diff)}, - { "PI", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_pi)}, - { "POINTFROMTEXT", SYM(POINTFROMTEXT),0,0}, - { "POINTFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "POINTN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pointn)}, - { "POLYFROMTEXT", SYM(POLYFROMTEXT),0,0}, - { "POLYFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "POLYGONFROMTEXT", SYM(POLYFROMTEXT),0,0}, - { "POLYGONFROMWKB", SYM(GEOMFROMWKB),0,0}, - { "POSITION", SYM(POSITION_SYM),0,0}, - { "POW", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, - { "POWER", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, - { "QUOTE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quote)}, - { "RADIANS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)}, - { "RAND", SYM(RAND),0,0}, - { "RELEASE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)}, - { "REVERSE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)}, - { "ROUND", SYM(ROUND),0,0}, - { "RPAD", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)}, - { "RTRIM", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_rtrim)}, - { "SEC_TO_TIME", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sec_to_time)}, - { "SESSION_USER", SYM(USER),0,0}, - { "SUBDATE", SYM(SUBDATE_SYM),0,0}, - { "SIGN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sign)}, - { "SIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sin)}, - { "SHA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)}, - { "SHA1", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)}, - { "SOUNDEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_soundex)}, - { "SPACE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_space)}, - { "SQRT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sqrt)}, - { "SRID", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_srid)}, - { "STARTPOINT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_startpoint)}, - { "STD", SYM(STD_SYM),0,0}, - { "STDDEV", SYM(STD_SYM),0,0}, - { "STR_TO_DATE", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_str_to_date)}, - { "STRCMP", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)}, - { "SUBSTR", SYM(SUBSTRING),0,0}, - { "SUBSTRING", SYM(SUBSTRING),0,0}, - { "SUBSTRING_INDEX", SYM(SUBSTRING_INDEX),0,0}, - { "SUBTIME", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_subtime)}, - { "SUM", SYM(SUM_SYM),0,0}, - { "SYSDATE", SYM(NOW_SYM),0,0}, - { "SYSTEM_USER", SYM(USER),0,0}, - { "TAN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_tan)}, - { "TIME_FORMAT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_time_format)}, - { "TIME_TO_SEC", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_time_to_sec)}, - { "TIMEDIFF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_timediff)}, - { "TO_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_to_days)}, - { "TOUCHES", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_touches)}, - { "TRIM", SYM(TRIM),0,0}, - { "UCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, - { "UNCOMPRESS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompress)}, - { "UNCOMPRESSED_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompressed_length)}, - { "UNIQUE_USERS", SYM(UNIQUE_USERS),0,0}, - { "UNIX_TIMESTAMP", SYM(UNIX_TIMESTAMP),0,0}, - { "UPPER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, - { "VARIANCE", SYM(VARIANCE_SYM),0,0}, - { "VERSION", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)}, - { "WEEKDAY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)}, - { "WEEKOFYEAR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekofyear)}, - { "WITHIN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_within)}, - { "X", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_x)}, - { "Y", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_y)}, - { "YEARWEEK", SYM(YEARWEEK),0,0} + { "ABS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_abs)}, + { "ACOS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_acos)}, + { "ADDDATE", SYM(ADDDATE_SYM)}, + { "ADDTIME", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_addtime)}, + { "AES_ENCRYPT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_encrypt)}, + { "AES_DECRYPT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_decrypt)}, + { "AREA", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_area)}, + { "ASIN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)}, + { "ASBINARY", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkb)}, + { "ASTEXT", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkt)}, + { "ASWKB", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkb)}, + { "ASWKT", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkt)}, + { "ATAN", SYM(ATAN)}, + { "ATAN2", SYM(ATAN)}, + { "BENCHMARK", SYM(BENCHMARK_SYM)}, + { "BIN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bin)}, + { "BIT_COUNT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)}, + { "BIT_OR", SYM(BIT_OR)}, + { "BIT_AND", SYM(BIT_AND)}, + { "BIT_XOR", SYM(BIT_XOR)}, + { "CAST", SYM(CAST_SYM)}, + { "CEIL", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)}, + { "CEILING", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)}, + { "CURRENT_USER", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_current_user)}, + { "BIT_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)}, + { "CENTROID", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_centroid)}, + { "CHAR_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, + { "CHARACTER_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, + { "COALESCE", SYM(COALESCE)}, + { "COERCIBILITY", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_coercibility)}, + { "COMPRESS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_compress)}, + { "CONCAT", SYM(CONCAT)}, + { "CONCAT_WS", SYM(CONCAT_WS)}, + { "CONNECTION_ID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)}, + { "CONTAINS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_contains)}, + { "CONV", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)}, + { "CONVERT", SYM(CONVERT_SYM)}, + { "COUNT", SYM(COUNT_SYM)}, + { "COS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)}, + { "COT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)}, + { "CRC32", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_crc32)}, + { "CROSSES", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_crosses)}, + { "CURDATE", SYM(CURDATE)}, + { "CURTIME", SYM(CURTIME)}, + { "DATE_ADD", SYM(DATE_ADD_INTERVAL)}, + { "DATEDIFF", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_datediff)}, + { "DATE_FORMAT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_date_format)}, + { "DATE_SUB", SYM(DATE_SUB_INTERVAL)}, + { "DAYNAME", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayname)}, + { "DAYOFMONTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofmonth)}, + { "DAYOFWEEK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofweek)}, + { "DAYOFYEAR", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofyear)}, + { "DECODE", SYM(DECODE_SYM)}, + { "DEGREES", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_degrees)}, + { "DES_ENCRYPT", SYM(DES_ENCRYPT_SYM)}, + { "DES_DECRYPT", SYM(DES_DECRYPT_SYM)}, + { "DIMENSION", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_dimension)}, + { "DISJOINT", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_disjoint)}, + { "ELT", SYM(ELT_FUNC)}, + { "ENCODE", SYM(ENCODE_SYM)}, + { "ENCRYPT", SYM(ENCRYPT)}, + { "ENDPOINT", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_endpoint)}, + { "ENVELOPE", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_envelope)}, + { "EQUALS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_equals)}, + { "EXTERIORRING", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_exteriorring)}, + { "EXTRACT", SYM(EXTRACT_SYM)}, + { "EXP", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_exp)}, + { "EXPORT_SET", SYM(EXPORT_SET)}, + { "FIELD", SYM(FIELD_FUNC)}, /* For compability */ + { "FIND_IN_SET", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_find_in_set)}, + { "FLOOR", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_floor)}, + { "FORMAT", SYM(FORMAT_SYM)}, + { "FOUND_ROWS", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_found_rows)}, + { "FROM_DAYS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_from_days)}, + { "FROM_UNIXTIME", SYM(FROM_UNIXTIME)}, + { "GET_LOCK", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_get_lock)}, + { "GEOMETRYN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_geometryn)}, + { "GEOMETRYTYPE", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_geometry_type)}, + { "GEOMCOLLFROMTEXT", SYM(GEOMCOLLFROMTEXT)}, + { "GEOMCOLLFROMWKB", SYM(GEOMFROMWKB)}, + { "GEOMETRYCOLLECTIONFROMTEXT",SYM(GEOMCOLLFROMTEXT)}, + { "GEOMETRYCOLLECTIONFROMWKB",SYM(GEOMFROMWKB)}, + { "GEOMETRYFROMTEXT", SYM(GEOMFROMTEXT)}, + { "GEOMETRYFROMWKB", SYM(GEOMFROMWKB)}, + { "GEOMFROMTEXT", SYM(GEOMFROMTEXT)}, + { "GEOMFROMWKB", SYM(GEOMFROMWKB)}, + { "GLENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_glength)}, + { "GREATEST", SYM(GREATEST_SYM)}, + { "GROUP_CONCAT", SYM(GROUP_CONCAT_SYM)}, + { "GROUP_UNIQUE_USERS", SYM(GROUP_UNIQUE_USERS)}, + { "HEX", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_hex)}, + { "IFNULL", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_ifnull)}, + { "INET_ATON", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_aton)}, + { "INET_NTOA", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_ntoa)}, + { "INSTR", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_instr)}, + { "INTERIORRINGN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_interiorringn)}, + { "INTERSECTS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_intersects)}, + { "ISCLOSED", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_isclosed)}, + { "ISEMPTY", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_isempty)}, + { "ISNULL", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)}, + { "IS_FREE_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)}, + { "IS_USED_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_used_lock)}, + { "LAST_INSERT_ID", SYM(LAST_INSERT_ID)}, + { "ISSIMPLE", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_issimple)}, + { "LAST_DAY", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_last_day)}, + { "LCASE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)}, + { "LEAST", SYM(LEAST_SYM)}, + { "LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)}, + { "LN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ln)}, + { "LINEFROMTEXT", SYM(LINEFROMTEXT)}, + { "LINEFROMWKB", SYM(GEOMFROMWKB)}, + { "LINESTRINGFROMTEXT",SYM(LINEFROMTEXT)}, + { "LINESTRINGFROMWKB",SYM(GEOMFROMWKB)}, + { "LOAD_FILE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_load_file)}, + { "LOCATE", SYM(LOCATE)}, + { "LOG", SYM(LOG_SYM)}, + { "LOG2", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log2)}, + { "LOG10", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log10)}, + { "LOWER", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)}, + { "LPAD", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_lpad)}, + { "LTRIM", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ltrim)}, + { "MAKE_SET", SYM(MAKE_SET_SYM)}, + { "MAKEDATE", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_makedate)}, + { "MAKETIME", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_maketime)}, + { "MASTER_POS_WAIT", SYM(MASTER_POS_WAIT)}, + { "MAX", SYM(MAX_SYM)}, + { "MBRCONTAINS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_contains)}, + { "MBRDISJOINT", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_disjoint)}, + { "MBREQUAL", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_equals)}, + { "MBRINTERSECTS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_intersects)}, + { "MBROVERLAPS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_overlaps)}, + { "MBRTOUCHES", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_touches)}, + { "MBRWITHIN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_within)}, + { "MD5", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_md5)}, + { "MID", SYM(SUBSTRING)}, /* unireg function */ + { "MIN", SYM(MIN_SYM)}, + { "MLINEFROMTEXT", SYM(MLINEFROMTEXT)}, + { "MLINEFROMWKB", SYM(GEOMFROMWKB)}, + { "MPOINTFROMTEXT", SYM(MPOINTFROMTEXT)}, + { "MPOINTFROMWKB", SYM(GEOMFROMWKB)}, + { "MPOLYFROMTEXT", SYM(MPOLYFROMTEXT)}, + { "MPOLYFROMWKB", SYM(GEOMFROMWKB)}, + { "MONTHNAME", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_monthname)}, + { "MULTILINESTRINGFROMTEXT",SYM(MLINEFROMTEXT)}, + { "MULTILINESTRINGFROMWKB",SYM(GEOMFROMWKB)}, + { "MULTIPOINTFROMTEXT",SYM(MPOINTFROMTEXT)}, + { "MULTIPOINTFROMWKB",SYM(GEOMFROMWKB)}, + { "MULTIPOLYGONFROMTEXT",SYM(MPOLYFROMTEXT)}, + { "MULTIPOLYGONFROMWKB",SYM(GEOMFROMWKB)}, + { "NOW", SYM(NOW_SYM)}, + { "NULLIF", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_nullif)}, + { "NUMGEOMETRIES", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_numgeometries)}, + { "NUMINTERIORRINGS", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_numinteriorring)}, + { "NUMPOINTS", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_numpoints)}, + { "OCTET_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)}, + { "OCT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)}, + { "ORD", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ord)}, + { "OVERLAPS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_overlaps)}, + { "PERIOD_ADD", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)}, + { "PERIOD_DIFF", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_diff)}, + { "PI", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_pi)}, + { "POINTFROMTEXT", SYM(POINTFROMTEXT)}, + { "POINTFROMWKB", SYM(GEOMFROMWKB)}, + { "POINTN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_pointn)}, + { "POLYFROMTEXT", SYM(POLYFROMTEXT)}, + { "POLYFROMWKB", SYM(GEOMFROMWKB)}, + { "POLYGONFROMTEXT", SYM(POLYFROMTEXT)}, + { "POLYGONFROMWKB", SYM(GEOMFROMWKB)}, + { "POSITION", SYM(POSITION_SYM)}, + { "POW", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, + { "POWER", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, + { "QUOTE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quote)}, + { "RADIANS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)}, + { "RAND", SYM(RAND)}, + { "RELEASE_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)}, + { "REVERSE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)}, + { "ROUND", SYM(ROUND)}, + { "RPAD", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)}, + { "RTRIM", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_rtrim)}, + { "SEC_TO_TIME", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sec_to_time)}, + { "SESSION_USER", SYM(USER)}, + { "SUBDATE", SYM(SUBDATE_SYM)}, + { "SIGN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sign)}, + { "SIN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sin)}, + { "SHA", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)}, + { "SHA1", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)}, + { "SOUNDEX", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_soundex)}, + { "SPACE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_space)}, + { "SQRT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sqrt)}, + { "SRID", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_srid)}, + { "STARTPOINT", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_startpoint)}, + { "STD", SYM(STD_SYM)}, + { "STDDEV", SYM(STD_SYM)}, + { "STR_TO_DATE", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_str_to_date)}, + { "STRCMP", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)}, + { "SUBSTR", SYM(SUBSTRING)}, + { "SUBSTRING", SYM(SUBSTRING)}, + { "SUBSTRING_INDEX", SYM(SUBSTRING_INDEX)}, + { "SUBTIME", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_subtime)}, + { "SUM", SYM(SUM_SYM)}, + { "SYSDATE", SYM(NOW_SYM)}, + { "SYSTEM_USER", SYM(USER)}, + { "TAN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_tan)}, + { "TIME_FORMAT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_time_format)}, + { "TIME_TO_SEC", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_time_to_sec)}, + { "TIMEDIFF", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_timediff)}, + { "TO_DAYS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_to_days)}, + { "TOUCHES", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_touches)}, + { "TRIM", SYM(TRIM)}, + { "UCASE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, + { "UNCOMPRESS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompress)}, + { "UNCOMPRESSED_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompressed_length)}, + { "UNIQUE_USERS", SYM(UNIQUE_USERS)}, + { "UNIX_TIMESTAMP", SYM(UNIX_TIMESTAMP)}, + { "UPPER", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, + { "VARIANCE", SYM(VARIANCE_SYM)}, + { "VERSION", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)}, + { "WEEKDAY", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)}, + { "WEEKOFYEAR", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekofyear)}, + { "WITHIN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_within)}, + { "X", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_x)}, + { "Y", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_y)}, + { "YEARWEEK", SYM(YEARWEEK)} }; diff --git a/sql/lex_symbol.h b/sql/lex_symbol.h index 9fff1751b1b..d1d30a73669 100644 --- a/sql/lex_symbol.h +++ b/sql/lex_symbol.h @@ -20,11 +20,14 @@ #ifndef _lex_symbol_h #define _lex_symbol_h +struct st_sym_group; + typedef struct st_symbol { const char *name; uint tok; uint length; void *create_func; + struct st_sym_group *group; } SYMBOL; typedef struct st_lex_symbol diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 225be6e7ffd..e17847ebe24 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -47,6 +47,7 @@ typedef ulong key_part_map; /* Used for finding key parts */ /* useful constants */ extern const key_map key_map_empty; extern const key_map key_map_full; +extern const char *primary_key_name; #include "mysql_com.h" #include <violite.h> @@ -286,7 +287,9 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; // uncachable cause #define UNCACHEABLE_DEPENDENT 1 #define UNCACHEABLE_RAND 2 -#define UNCACHEABLE_SIDEEFFECT 4 +#define UNCACHEABLE_SIDEEFFECT 4 +// forcing to save JOIN for explain +#define UNCACHEABLE_EXPLAIN 8 #ifdef EXTRA_DEBUG /* @@ -520,14 +523,13 @@ int mysql_select(THD *thd, Item ***rref_pointer_array, SELECT_LEX *select_lex); void free_underlaid_joins(THD *thd, SELECT_LEX *select); void fix_tables_pointers(SELECT_LEX *select_lex); -void fix_tables_pointers(SELECT_LEX_UNIT *select_lex); int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result); int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type, select_result *result); int mysql_union(THD *thd, LEX *lex, select_result *result, SELECT_LEX_UNIT *unit); -int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t); +int mysql_handle_derived(LEX *lex); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item ***copy_func, Field **from_field, bool group,bool modify_item); @@ -548,7 +550,6 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, List<Key> &keys,List<Alter_drop> &drop_list, List<Alter_column> &alter_list, uint order_num, ORDER *order, - bool drop_primary, enum enum_duplicates handle_duplicates, enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS, enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP, @@ -704,7 +705,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator<Item> *it); -bool setup_tables(TABLE_LIST *tables); +bool setup_tables(TABLE_LIST *tables, my_bool reinit); int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, List<Item> *sum_func_list, uint wild_num); int setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables, @@ -714,9 +715,10 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); int setup_ftfuncs(SELECT_LEX* select); int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order); void wait_for_refresh(THD *thd); -int open_tables(THD *thd,TABLE_LIST *tables); +int open_tables(THD *thd, TABLE_LIST *tables, uint *counter); +int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables); int open_and_lock_tables(THD *thd,TABLE_LIST *tables); -int lock_tables(THD *thd,TABLE_LIST *tables); +int lock_tables(THD *thd, TABLE_LIST *tables, uint counter); TABLE *open_temporary_table(THD *thd, const char *path, const char *db, const char *table_name, bool link_in_list); bool rm_temporary_table(enum db_type base, char *path); @@ -799,6 +801,15 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match); uint check_word(TYPELIB *lib, const char *val, const char *end, const char **end_of_word); +bool is_keyword(const char *name, uint len); + +/* sql_parse.cc */ +void free_items(Item *item); +void cleanup_items(Item *item); + +#define MY_DB_OPT_FILE "db.opt" +bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create); + /* External variables */ @@ -1140,4 +1151,13 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr) table->force_index= table_list->force_index; } +typedef struct st_sym_group { + const char *name; + const char *needed_define; +} SYM_GROUP; + +extern SYM_GROUP sym_group_common; +extern SYM_GROUP sym_group_geom; +extern SYM_GROUP sym_group_rtree; + #endif /* MYSQL_CLIENT */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e465d310259..0a05da7491b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2154,8 +2154,12 @@ static int init_common_variables(const char *conf_file_name, int argc, { CHARSET_INFO *default_collation; default_collation= get_charset_by_name(default_collation_name, MYF(0)); - if (!default_collation || !my_charset_same(default_charset_info, - default_collation)) + if (!default_collation) + { + sql_print_error(ER(ER_UNKNOWN_COLLATION), default_collation_name); + return 1; + } + if (!my_charset_same(default_charset_info, default_collation)) { sql_print_error(ER(ER_COLLATION_CHARSET_MISMATCH), default_collation_name, @@ -4386,7 +4390,7 @@ log and this option does nothing anymore.", (gptr*) 0, 0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0}, - {"key_cache_division_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD, + {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD, "This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache", (gptr*) &dflt_key_cache_var.param_age_threshold, (gptr*) 0, @@ -4606,7 +4610,7 @@ The minimum value for this variable is 4096.", "Use compression on master/slave protocol.", (gptr*) &opt_slave_compressed_protocol, (gptr*) &opt_slave_compressed_protocol, - 0, GET_BOOL, REQUIRED_ARG, 0, 0, 1, 0, 1, 0}, + 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0}, {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT, "Number of seconds to wait for more data from a master/slave connection before aborting the read.", (gptr*) &slave_net_timeout, (gptr*) &slave_net_timeout, 0, @@ -4669,7 +4673,7 @@ The minimum value for this variable is 4096.", (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS, - "Logs will be rotated after expire-log-days days ", + "Binary logs will be rotated after expire-log-days days ", (gptr*) &expire_logs_days, (gptr*) &expire_logs_days, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 99, 0, 1, 0}, @@ -5816,8 +5820,9 @@ static void fix_paths(void) { strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff, CHARSET_DIR, NullS); - charsets_dir=mysql_charsets_dir; } + (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff); + charsets_dir=mysql_charsets_dir; if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) exit(1); @@ -5968,7 +5973,7 @@ static ulong find_bit_type(const char *x, TYPELIB *bit_lib) { if (my_toupper(mysqld_charset,*i++) != my_toupper(mysqld_charset,*j++)) - goto skipp; + goto skip; } found_int=bit; if (! *i) @@ -5980,7 +5985,7 @@ static ulong find_bit_type(const char *x, TYPELIB *bit_lib) { found_count++; // Could be one of two values } -skipp: ; +skip: ; } if (found_count != 1) DBUG_RETURN(~(ulong) 0); // No unique value diff --git a/sql/opt_ft.cc b/sql/opt_ft.cc deleted file mode 100644 index 9d1fc55c777..00000000000 --- a/sql/opt_ft.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* 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 */ - -#ifdef __GNUC__ -#pragma implementation // gcc: Class implementation -#endif - -#include "mysql_priv.h" -#include "sql_select.h" -#include "opt_ft.h" - -/**************************************************************************** -** Create a FT or QUICK RANGE based on a key -****************************************************************************/ - -QUICK_RANGE_SELECT *get_ft_or_quick_select_for_ref(THD *thd, TABLE *table, - JOIN_TAB *tab) -{ - if (tab->type == JT_FT) - return new FT_SELECT(thd, table, &tab->ref); - return get_quick_select_for_ref(thd, table, &tab->ref); -} - diff --git a/sql/opt_ft.h b/sql/opt_ft.h deleted file mode 100644 index 954c25b6caa..00000000000 --- a/sql/opt_ft.h +++ /dev/null @@ -1,42 +0,0 @@ -/* 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 use when handling where clause */ - -#ifndef _opt_ft_h -#define _opt_ft_h - -#ifdef __GNUC__ -#pragma interface /* gcc class implementation */ -#endif - -class FT_SELECT: public QUICK_RANGE_SELECT { -public: - TABLE_REF *ref; - - FT_SELECT(THD *thd, TABLE *table, TABLE_REF *tref) : - QUICK_RANGE_SELECT (thd, table, tref->key, 1), ref(tref) { init(); } - - int init() { return error=file->ft_init(); } - int get_next() { return error=file->ft_read(record); } - int get_type() { return QS_TYPE_FULLTEXT; } -}; - -QUICK_RANGE_SELECT *get_ft_or_quick_select_for_ref(THD *thd, TABLE *table, - JOIN_TAB *tab); - -#endif diff --git a/sql/opt_range.h b/sql/opt_range.h index 7c2981795a2..1e5f58bc1f5 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -295,14 +295,23 @@ class SQL_SELECT :public Sql_alloc { SQL_SELECT(); ~SQL_SELECT(); + void cleanup(); bool check_quick(THD *thd, bool force_quick_range, ha_rows limit) { return test_quick_select(thd, key_map(~0), 0, limit, force_quick_range) < 0; } - inline bool skipp_record() { return cond ? cond->val_int() == 0 : 0; } + inline bool skip_record() { return cond ? cond->val_int() == 0 : 0; } int test_quick_select(THD *thd, key_map keys, table_map prev_tables, ha_rows limit, bool force_quick_range=0); }; -QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, - struct st_table_ref *ref); + +class FT_SELECT: public QUICK_RANGE_SELECT { +public: + FT_SELECT(THD *thd, TABLE *table, uint key) : + QUICK_RANGE_SELECT (thd, table, key, 1) { init(); } + + int init() { return error=file->ft_init(); } + int get_next() { return error=file->ft_read(record); } + int get_type() { return QS_TYPE_FULLTEXT; } +}; #endif diff --git a/sql/protocol.cc b/sql/protocol.cc index 89aa7203e17..4be74c74134 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -128,7 +128,7 @@ void send_error(THD *thd, uint sql_errno, const char *err) /* Abort multi-result sets */ thd->lex->found_colon= 0; - thd->server_status= ~SERVER_MORE_RESULTS_EXISTS; + thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; DBUG_VOID_RETURN; } @@ -326,6 +326,7 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message) DBUG_VOID_RETURN; } +static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */ /* Send eof (= end of result set) to the client @@ -352,12 +353,11 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message) void send_eof(THD *thd, bool no_flush) { - static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */ NET *net= &thd->net; DBUG_ENTER("send_eof"); if (net->vio != 0 && !net->no_send_eof) { - if (!no_flush && (thd->client_capabilities & CLIENT_PROTOCOL_41)) + if (thd->client_capabilities & CLIENT_PROTOCOL_41) { uchar buff[5]; uint tmp= min(thd->total_warn_count, 65535); @@ -369,7 +369,7 @@ send_eof(THD *thd, bool no_flush) other queries (see the if test in dispatch_command / COM_QUERY) */ if (thd->is_fatal_error) - thd->server_status= ~SERVER_MORE_RESULTS_EXISTS; + thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; int2store(buff+3, thd->server_status); VOID(my_net_write(net,(char*) buff,5)); VOID(net_flush(net)); @@ -397,9 +397,8 @@ send_eof(THD *thd, bool no_flush) bool send_old_password_request(THD *thd) { - static char buff[1]= { (char) 254 }; NET *net= &thd->net; - return my_net_write(net, buff, 1) || net_flush(net); + return my_net_write(net, eof_buff, 1) || net_flush(net); } #endif /* EMBEDDED_LIBRARY */ @@ -598,7 +597,7 @@ bool Protocol::send_fields(List<Item> *list, uint flag) #endif } - send_eof(thd, 1); + my_net_write(&thd->net, eof_buff, 1); DBUG_RETURN(prepare_for_send(list)); err: diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 81ea9d9e2ac..d125c95e839 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -732,7 +732,7 @@ static int fetch_db_tables(THD *thd, MYSQL *mysql, const char *db, int error; if (table_rules_on) { - table.next= 0; + bzero((char*) &table, sizeof(table)); //just for safe table.db= (char*) db; table.real_name= (char*) table_name; table.updating= 1; diff --git a/sql/set_var.cc b/sql/set_var.cc index 4cf9f07b4ba..b74bf3e5f7b 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -696,7 +696,6 @@ struct show_var_st init_vars[]= { {"port", (char*) &mysqld_port, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, - {sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS}, {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size, SHOW_SYS}, #ifdef HAVE_QUERY_CACHE @@ -2655,11 +2654,6 @@ ulong fix_sql_mode(ulong sql_mode) MODE_IGNORE_SPACE | MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS); - if (sql_mode & MODE_MSSQL) - sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | - MODE_IGNORE_SPACE | - MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | - MODE_NO_FIELD_OPTIONS); if (sql_mode & MODE_POSTGRESQL) sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | @@ -2670,11 +2664,6 @@ ulong fix_sql_mode(ulong sql_mode) MODE_IGNORE_SPACE | MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS); - if (sql_mode & MODE_DB2) - sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | - MODE_IGNORE_SPACE | - MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | - MODE_NO_FIELD_OPTIONS); if (sql_mode & MODE_MAXDB) sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | diff --git a/sql/share/charsets/Index.xml b/sql/share/charsets/Index.xml index 3661784325c..f21e03de8b2 100644 --- a/sql/share/charsets/Index.xml +++ b/sql/share/charsets/Index.xml @@ -1,6 +1,6 @@ <?xml version='1.0' encoding="utf-8"?> -<charsets max-id="93"> +<charsets max-id="94"> <description> This file lists all of the available character sets. @@ -100,6 +100,7 @@ To make maintaining easier please: <collation name="latin1_swedish_ci" id="8" order="Finnish, Swedish" flag="primary"/> <collation name="latin1_danish_ci" id="15" order="Danish"/> <collation name="latin1_german2_ci" id="31" order="German Phonebook" flag="compiled"/> + <collation name="latin1_spanish_ci" id="94" order="Spanish"/> <collation name="latin1_bin" id="47" order="Binary"> <flag>binary</flag> <flag>compiled</flag> diff --git a/sql/share/charsets/languages.html b/sql/share/charsets/languages.html new file mode 100644 index 00000000000..6d1a8aafc5c --- /dev/null +++ b/sql/share/charsets/languages.html @@ -0,0 +1,257 @@ +#!/bin/sh +#<pre> +( +echo "DROP TABLE lang;" +echo "CREATE TABLE lang (lang varchar(128), letters text character set utf8);" +( +grep -v "^#" << END +# +Greenlandic ÁÂÃÊÍÎÔÚÛáâãêíîôúûĨĩĸŨũ +#Use of these letters was abolished in a spelling reform in 1973: +#Greenlandic ÅÆØåæø +#Characters not found in the UCS: +# K LATIN CAPITAL LETTER KRA +############################################################# +#Basque ÑÜñüŔŕ +#Characters not found in the UCS: +# D LATIN CAPITAL LETTER D WITH MACRON +# d LATIN SMALL LETTER D WITH MACRON +# L LATIN CAPITAL LETTER L WITH MACRON +# l LATIN SMALL LETTER L WITH MACRON +# T LATIN CAPITAL LETTER T WITH MACRON +# t LATIN SMALL LETTER T WITH MACRON +############################################################# +#Maltese #ÀÁÂÈÉÊÌÍÎÒÓÔÙÚÛ#àáâèéêìíîòÓôùúû#ĊċĠġĦħŻżʼ +#BosnianCyr ЂЈЉЊЋЏАБВГДЕЖЗИКЛМНОПРСТУФХЦЧШабвгдежзиклмнопрстуфхцчшђјљњћџ +#Scots A +#Scots1 ƷȜȝʒ +########################################### +#### Hiragana 3040-309F +Hiragana ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをん +Hiragana1 ゔ゙゚ +Hiragana2 ゛゜ゝゞ +#### Katakana 30A0-30FF +Katakana ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ +Katakana1 ヷヸヹヺ +Katakana2 ・ーヽヾ +############################################ +Albanian ÂÇËâçë +Bosnian ĆćČčĐ𩹮ž +Breton ÂÊÑÙÜâêñùü +Catalan ÀÇÈÉÍÏÒÓÚÜàçèéíïòóúü +#Catalan1 ·Ŀŀ +Croatian ĆćČčĐ𩹮ž +CroatianLig DZDzdzDŽDždžLJLjljNJNjnj +Czech ÁÉÍÓÚÝáéíóúýČčĎďĚěŇňŘřŠšŤťŮůŽž +Danish ÁÄÅÆÉÓÖØÜáäåæéóöøü +Dutch ÀÂÄÆÇÈÉÊËÎÏÑÒÓÔÖÙÚÛÜàâäæçèéêëîïñòóôöùúûü +Esperanto ĈĉĜĝĤĥĴĵŜŝŬŭ +Estonian ÄÕÖÜäõöüŠšŽž +Faroese ÅÆÐÓÖØÚÝåæðóöøúý +Finnish ÄÅÖÜäåöü +#Finnish1 ŠšŽž +French(limited) ÀÂÆÇÈÉÊËÎÏÑÔÙÛàâæçèéêëîïñôùûÿ +French ŒœŸ +German ÄÖÜßäöü +Hungarian ÁÉÍÓÖÚÜáéíóöúüŐőŰű +Icelandic ÁÆÉÍÐÓÖÚÝÞáæéíðóöúýþ +Italian ÀÈÉÌÍÏÒÓÙÚàèéìíïòóùú +#Latin A +Latvian ĀāČčĒēĢģĪīĶķĻļŅņŠšŪūŽž +Lithuanian ĄąČčĖėĘęĮįŠšŪūŲųŽž +Norwegian ÅÆØåæø +Polish ÓóĄąĆćĘꣳŃńŚśŹźŻż +Portuguese ÀÁÂÃÇÉÊÍÓÔÕÚÜàáâãçéêíóôõúü +#http://en.wikipedia.org/wiki/Special_Romanian_Unicode_characters +Romanian ÂÎâîĂăȘșȚț +Romanian(ErrorST) ÂÎâîĂ㪺Ţţ +Slovak ÁÄÉÍÓÔÚÝáäéíóôúýČčĎďĹ弾ŇňŔ੹ŤťŽž +Slovene Č芚Žž +Sorbian-Lower ĆćČčĚ죳ŃńŘřŚśŠšŹźŽž +Sorbian-Upper ÓóĆćČčĚ죳ŃńŘřŠšŽž +Spanish ÁÉÍÑÓÚÜáéíñóúü +Swedish ÄÅÖäåö +Turkish ÂÇÖÛÜâçöûüĞğİı +Welsh ÀÁÂÄÈÉÊËÌÍÎÏÒÓÔÖÙÚÛÜÝàáâäèéêëìíîïòóôöùúûüýÿŴŵŶŷŸẀẁẂẃẄẅỲỳ +################################## +Belarusian ЁІЎАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяёіў +Bulgarian АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя +Bulgarian1 ЀҭѐѝѢѣѪѫ +Macedonian ЃЅЈЉЊЌЏАБВГДЕЖЗИКЛМНОПРСТУФХЦЧШабвгдежзиклмнопрстуфхцчшѓѕјљњќџ +Russian ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё +RussianOLD ІіѢѣѲѳѴѵ +Serbian ЂЈЉЊЋЏАБВГДЕЖЗИКЛМНОПРСТУФХЦЧШабвгдежзиклмнопрстуфхцчшђјљњћџ +Ukrainian ЄІЇАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЭЮЯабвгдежзийклмнопрстуфхцчшщьэюяєіїҐґ +################################## +Armenian ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՑՒՓՔՕՖ՛՜՝՞՟աբգդեֆ։ +#Armenian1 ՚֊ +#Characters not found in the UCS: +# ARMENIAN ETERNITY SIGN +# +GeorgianOld ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ +Georgian აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰ +GeorgianArc ჱჲჳჴჵჶ +GeorgianPunc ჻ +# +GreekExt1 ΄΅Ά·ΈΉΊ»Ό½ΎΏΐ +Greek ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψω +GreekExt2 ΪΫάέήίΰϊϋόύώ +GreekExt4 ς +# +Hebrew אבגדהוזחטיךכלםמןנסעףפץצקרשת +################################## +#Abaza +#Abkhaz +#Adyghe +#Agul * +#(Aisor) +#Akhvakh * +#(?lvdalska) +#(Andi) * +#(Aragonese) +#Archi * +#Arumanian +#(Arvanite) +#Asturian +#Avar +#Azerbaijani +#(Bagulal) * +#Balkar +#Bashkir +#Basque ! +#Bats * +#Bezhta * +#(Botlikh) * +#Budukh * +#(Chamalal) +#Chechen +#Chuvash +#Cornish ! +#(Corsican) +#Dargwa +#Erzya +#(Franco-Proven?al) +#(Frisian, East) +#(Frisian, North) +#Frisian, West +#Friulian +#Gagauz +#Gaelic, Irish ! +#Gaelic, Manx ! +#Gaelic, Scottish ! +#Galician ! +#(German, Low) ! +#(German, Swiss) ! +#Godoberi * +#(Hinukh) * +#(Hunzib) * +#Ingrian +#Ingush +#Istro-Romanian +#(Judeo-Georgian) +#(Judeo-Kurdish) +#(Judeo-Tati) +#Kabardian +#Kalmyk +#Karachay +#(Karaim) +#(Karata) * +#Karelian +#Kashubian +#Kazakh +#Khinalug +#(Khvarshi) * +#(Kirmanji) +#Komi +#Komi-Permyak +#(Kryts) +#Kumyk +#(Kurdish) +#(Ladin) +#(Ladino) +#Lak +#Laz +#Lezgian +#Livonian +#(Ludian) +#Luxemburgish ! +#Mari, Hill +#Mari, Meadow +#Megleno-Romanian +#(Mingrelian) +#Moksha +#Moldavian +#Nenets, Tundra +#Nogai +#Occitan +#Old Church Slavonic +#(Olonets) +#Ossetian +#(Romani) +#Romansch +#(Rusyn) +#Rutul +#Sami, Inari +#Sami, Kildin +#Sami, Lule +#Sami, Northern +#Sami, Skolt +#Sami, Southern +#(Sami, Ter) * +#(Sami, Ume) * +#(Sardinian) * +#Scots ! +#Svan +#Tabasaran +#(Talysh) +#Tatar, Crimean +#Tatar, Kazan +#Tati +#(Tindi) * +#(Tsakonian) * +#Tsakhur * +#(Tsez) * +#(Turkish, Crimean) +#Ubykh * +#Udi +#Udmurt +#(V?mhusm?l) +#Vepsian +#Votic +#(Walloon) +#(Yiddish) +################################ +# 4 Gaelic-new-orthography +# 4 Frisian +# 3 Rhaeto-Romanic +# 2 S&AACUTEmi-with-restrictions +# 1 Rhjaeto-Romanic +# 1 Gaelic-old-and-new-orthographies +END +) | + +while read a b +do + c=`echo $b | replace "&#x" "" ";" ""` + printf "INSERT INTO lang VALUES ('$a',_ucs2 X'$c');\n" +done +) | mysql -f test + +#mysql test << END +#SELECT * FROM lang WHERE CONVERT(letters USING latin1) NOT LIKE _binary'%?%'; +#SELECT * FROM lang WHERE CONVERT(letters USING latin2) NOT LIKE _binary'%?%'; +#END + + + +list="big5 dec8 cp850 hp8 koi8r latin1 latin2 swe7 ascii ujis sjis hebrew euckr koi8u gb2312 greek cp1250 gbk latin5 armscii8 cp866 keybcs2 macce macroman cp852 latin7 cp1251 cp1256 cp1257 geostd8" + +for p in $list +do +echo "-----------------" +echo $p: +mysql -sss test << END +SELECT lang FROM lang WHERE CONVERT(letters USING $p) NOT LIKE _binary'%?%' ORDER BY lang; +END +done + diff --git a/sql/share/charsets/latin1.xml b/sql/share/charsets/latin1.xml index 9e11be39ad6..178fd07e7f6 100644 --- a/sql/share/charsets/latin1.xml +++ b/sql/share/charsets/latin1.xml @@ -209,6 +209,27 @@ </collation> +<collation name="latin1_spanish_ci"> +<map> + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 51 53 57 5B 65 67 69 6B 75 77 79 7B 7D 81 + 8F 91 93 95 98 9A A4 A6 A8 AA AF B3 B4 B5 B6 B7 + B8 41 51 53 57 5B 65 67 69 6B 75 77 79 7B 7D 81 + 8F 91 93 95 98 9A A4 A6 A8 AA AF B9 BA BB BC BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + 41 41 41 41 41 41 41 53 5B 5B 5B 5B 6B 6B 6B 6B + 57 7F 81 81 81 81 81 BD 81 9A 9A 9A 9A AA B1 97 + 41 41 41 41 41 41 41 53 5B 5B 5B 5B 6B 6B 6B 6B + 57 7F 81 81 81 81 81 BE 81 9A 9A 9A 9A AA B1 AA +</map> +</collation> + </charset> </charsets> diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index ae040fd92ac..117bf4b37d4 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -299,6 +299,9 @@ character-set=latin2 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index b7f947d346e..ba012e0eea3 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -293,6 +293,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 9e2bb859a45..0349929f0d3 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -301,6 +301,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index cffbdeeeca2..6bf4bde9b22 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -290,6 +290,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 34158b491b2..03e2d4d6c90 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -295,6 +295,9 @@ character-set=latin7 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 9a2b3a5ec6a..dab2ab9f51d 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -290,6 +290,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 36b8d4b98d6..5b2378dde22 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -302,6 +302,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 95c00ec2dd9..a840e95de97 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -290,6 +290,9 @@ character-set=greek "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 4a10797e1d1..0b24ca6afb8 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -292,6 +292,9 @@ character-set=latin2 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 2b8a7ea5632..a298baa7682 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -290,6 +290,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 752ed402190..a25357ae079 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -292,6 +292,9 @@ character-set=ujis "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 8d98d5cb610..d3799d881ed 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -290,6 +290,9 @@ character-set=euckr "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index f1dd2cb8371..d69d52408ff 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -292,6 +292,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 44705db0af5..5fbbaf19480 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -292,6 +292,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 622e127dc5e..92572db5fdc 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -294,6 +294,9 @@ character-set=latin2 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index cb9c0e745f9..580fec472b6 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -291,6 +291,9 @@ character-set=latin1 "MySQL foi inicializado em modo --skip-name-resolve. Você necesita reincializá-lo sem esta opção para este grant funcionar", "Motor de tabela desconhecido '%s'", "'%s' é desatualizado. Use '%s' em seu lugar.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index a37f29b8a33..3e6bff75591 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -294,6 +294,9 @@ character-set=latin2 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 2dbe6b9184c..b04cda84efd 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -292,6 +292,9 @@ character-set=koi8r "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"ôÁÂÌÉÃÁ %-.100s × %s ÎÅ ÍÏÖÅÔ ÉÚÍÅÎÑÔÓÑ.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 97bef4e1714..2737ce26873 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -285,6 +285,9 @@ character-set=cp1250 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index e841214ba1c..bf9fe6d3519 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -298,6 +298,9 @@ character-set=latin2 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index cdabd339e1e..fec6bbb4342 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -292,6 +292,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index aab70294ec8..8b2892172ba 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -290,6 +290,9 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"The target table %-.100s of the %s is not updatable.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 828c0a46cad..393c765a8ca 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -295,6 +295,9 @@ character-set=koi8u "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated. Use '%s' instead.", +"ôÁÂÌÉÃÑ %-.100s Õ %s ÎÅ ÍÏÖÅ ÏÎÏ×ÌÀ×ÁÔÉÓØ.", +"The '%s' feature was disabled. You need MySQL built with '%s' define to have it working" +"MySQL is started in --skip-grant-tables mode. You can't use this command" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/slave.cc b/sql/slave.cc index 99f7eb8d019..e3d9e0dab58 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2866,7 +2866,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) rli->is_until_satisfied()) { sql_print_error("Slave SQL thread stopped because it reached its" - " UNTIL position"); + " UNTIL position %ld", (long) rli->until_pos()); /* Setting abort_slave flag because we do not want additional message about error in query execution to be printed. @@ -3342,6 +3342,7 @@ slave_begin: sql_print_error("Failed during slave thread initialization"); goto err; } + thd->init_for_queries(); rli->sql_thd= thd; thd->temporary_tables = rli->save_temporary_tables; // restore temp tables pthread_mutex_lock(&LOCK_thread_count); diff --git a/sql/slave.h b/sql/slave.h index 3313f587b3d..016944534f7 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -347,6 +347,11 @@ typedef struct st_relay_log_info /* Check if UNTIL condition is satisfied. See slave.cc for more. */ bool is_until_satisfied(); + inline ulonglong until_pos() + { + return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos : + group_relay_log_pos); + } } RELAY_LOG_INFO; diff --git a/sql/sp.cc b/sql/sp.cc index 0d657cddc37..83fbd8c5173 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -504,7 +504,7 @@ db_show_routine_status(THD *thd, int type, const char *wild) } /* Init fields */ - setup_tables(&tables); + setup_tables(&tables, 0); for (used_field= &used_fields[0]; used_field->field_name; used_field++) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index b263fb22c0e..a68118cecd1 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -94,8 +94,14 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) } else { + /* There's some difference between Item::new_item() and the + * constructor; the former crashes, the latter works... weird. */ + uint8 decimals= it->decimals; + uint32 max_length= it->max_length; DBUG_PRINT("info", ("REAL_RESULT: %g", d)); it= new Item_real(it->val()); + it->decimals= decimals; + it->max_length= max_length; } break; } @@ -271,6 +277,12 @@ sp_head::execute(THD *thd) int ret= 0; uint ip= 0; +#ifndef EMBEDDED_LIBRARY + if (check_stack_overrun(thd, olddbptr)) + { + DBUG_RETURN(-1); + } +#endif if (olddbptr) { uint i= 0; @@ -840,6 +852,11 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) { TABLE_LIST *tabs; + if (lex->sql_command == SQLCOM_CREATE_TABLE || + lex->sql_command == SQLCOM_INSERT_SELECT) + { // Restore sl->table_list.first + sl->table_list.first= sl->table_list_first_copy; + } // We have closed all tables, get rid of pointers to them for (tabs=(TABLE_LIST *)sl->table_list.first ; tabs ; @@ -847,11 +864,6 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) { tabs->table= NULL; } - if (lex->sql_command == SQLCOM_CREATE_TABLE || - lex->sql_command == SQLCOM_INSERT_SELECT) - { // Restore sl->table_list.first - sl->table_list.first= sl->table_list_first_copy; - } for (ORDER *order= (ORDER *)sl->order_list.first ; order ; order= order->next) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 2feb9594715..5febb49e110 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -52,7 +52,7 @@ static byte* acl_entry_get_key(acl_entry *entry,uint *length, return (byte*) entry->key; } -#define IP_ADDR_STRLEN +#define IP_ADDR_STRLEN (3+1+3+1+3+1+3) #define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1) static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs; @@ -173,7 +173,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ; tables[0].db=tables[1].db=tables[2].db=thd->db; - if (open_tables(thd,tables)) + uint counter; + if (open_tables(thd, tables, &counter)) { sql_print_error("Fatal error: Can't open privilege tables: %s", thd->net.last_error); @@ -1174,8 +1175,8 @@ bool check_change_password(THD *thd, const char *host, const char *user) { if (!initialized) { - send_error(thd, ER_PASSWORD_NOT_ALLOWED); /* purecov: inspected */ - return(1); /* purecov: inspected */ + send_error(thd, ER_SKIP_GRANT_TABLES); /* purecov: inspected */ + return(1); /* purecov: inspected */ } if (!thd->slave_thread && (strcmp(thd->user,user) || @@ -1649,8 +1650,14 @@ static int replace_db_table(TABLE *table, const char *db, char what= (revoke_grant) ? 'N' : 'Y'; DBUG_ENTER("replace_db_table"); + if (!initialized) + { + my_error(ER_SKIP_GRANT_TABLES, MYF(0)); + DBUG_RETURN(-1); + } + /* Check if there is such a user in user table in memory? */ - if (!initialized || !find_acl_user(combo.host.str,combo.user.str)) + if (!find_acl_user(combo.host.str,combo.user.str)) { my_error(ER_PASSWORD_NO_MATCH,MYF(0)); DBUG_RETURN(-1); @@ -2226,7 +2233,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (!initialized) { - send_error(thd, ER_UNKNOWN_COM_ERROR); /* purecov: inspected */ + send_error(thd, ER_SKIP_GRANT_TABLES); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if (rights & ~TABLE_ACLS) @@ -2300,7 +2307,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } #endif - if (open_and_lock_tables(thd,tables)) + if (simple_open_n_lock_tables(thd,tables)) { // Should never happen close_thread_tables(thd); /* purecov: deadcode */ DBUG_RETURN(-1); /* purecov: deadcode */ @@ -2436,8 +2443,8 @@ int mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, DBUG_ENTER("mysql_grant"); if (!initialized) { - my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); /* purecov: tested */ - return -1; /* purecov: tested */ + my_error(ER_SKIP_GRANT_TABLES, MYF(0)); /* purecov: tested */ + DBUG_RETURN(-1); /* purecov: tested */ } if (lower_case_table_names && db) @@ -2448,7 +2455,7 @@ int mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, } /* open the mysql.user and mysql.db tables */ - + bzero((char*) &tables,sizeof(tables)); tables[0].alias=tables[0].real_name=(char*) "user"; tables[1].alias=tables[1].real_name=(char*) "db"; tables[0].next=tables+1; @@ -2474,7 +2481,7 @@ int mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, } #endif - if (open_and_lock_tables(thd,tables)) + if (simple_open_n_lock_tables(thd,tables)) { // This should never happen close_thread_tables(thd); /* purecov: deadcode */ DBUG_RETURN(-1); /* purecov: deadcode */ @@ -2570,14 +2577,15 @@ my_bool grant_init(THD *org_thd) thd->store_globals(); thd->db= my_strdup("mysql",MYF(0)); thd->db_length=5; // Safety - bzero((char*) &tables,sizeof(tables)); + bzero((char*) &tables, sizeof(tables)); tables[0].alias=tables[0].real_name= (char*) "tables_priv"; tables[1].alias=tables[1].real_name= (char*) "columns_priv"; tables[0].next=tables+1; tables[0].lock_type=tables[1].lock_type=TL_READ; tables[0].db=tables[1].db=thd->db; - if (open_tables(thd,tables)) + uint counter; + if (open_tables(thd, tables, &counter)) goto end; TABLE *ptr[2]; // Lock tables for quick update @@ -2602,7 +2610,7 @@ my_bool grant_init(THD *org_thd) do { GRANT_TABLE *mem_check; - if (!(mem_check=new GRANT_TABLE(t_table,c_table)) || mem_check->ok()) + if (!(mem_check=new GRANT_TABLE(t_table,c_table)) || !mem_check->ok()) { /* This could only happen if we are out memory */ grant_option= FALSE; /* purecov: deadcode */ @@ -3041,8 +3049,8 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) LINT_INIT(acl_user); if (!initialized) { - send_error(thd, ER_UNKNOWN_COM_ERROR); - DBUG_RETURN(-1); + send_error(thd, ER_SKIP_GRANT_TABLES); + DBUG_RETURN(1); } if (lex_user->host.length > HOSTNAME_LENGTH || lex_user->user.length > USERNAME_LENGTH) @@ -3394,7 +3402,7 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables) if (!initialized) { - send_error(thd, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES)); + send_error(thd, ER_SKIP_GRANT_TABLES); DBUG_RETURN(-1); } @@ -3429,7 +3437,7 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables) } #endif - if (open_and_lock_tables(thd, tables)) + if (simple_open_n_lock_tables(thd, tables)) { // This should never happen close_thread_tables(thd); DBUG_RETURN(-1); @@ -3475,7 +3483,7 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list) DBUG_ENTER("mysql_drop_user"); if ((result= open_grant_tables(thd, tables))) - DBUG_RETURN(result == 1 ? 0 : -1); + DBUG_RETURN(result == 1 ? 0 : 1); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -3588,7 +3596,7 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list) DBUG_ENTER("mysql_revoke_all"); if ((result= open_grant_tables(thd, tables))) - DBUG_RETURN(result == 1 ? 0 : -1); + DBUG_RETURN(result == 1 ? 0 : 1); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 02ecb158ebe..8f319ee645d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1305,9 +1305,9 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, goto err; // Can't repair the table TABLE_LIST table_list; + bzero((char*) &table_list, sizeof(table_list)); // just for safe table_list.db=(char*) db; table_list.real_name=(char*) name; - table_list.next=0; safe_mutex_assert_owner(&LOCK_open); if ((error=lock_table_name(thd,&table_list))) @@ -1356,27 +1356,45 @@ err: DBUG_RETURN(1); } -/***************************************************************************** -** open all tables in list -*****************************************************************************/ +/* + Open all tables in list -int open_tables(THD *thd,TABLE_LIST *start) + SYNOPSIS + open_tables() + thd - thread handler + start - list of tables + counter - number of opened tables will be return using this parameter + + RETURN + 0 - OK + -1 - error +*/ + +int open_tables(THD *thd, TABLE_LIST *start, uint *counter) { TABLE_LIST *tables; bool refresh; int result=0; DBUG_ENTER("open_tables"); + *counter= 0; thd->current_tablenr= 0; restart: thd->proc_info="Opening tables"; for (tables=start ; tables ; tables=tables->next) { + /* + Ignore placeholders for derived tables. After derived tables + processing, link to created temporary table will be put here. + */ + if (tables->derived) + continue; + (*counter)++; if (!tables->table && - !(tables->table=open_table(thd, - tables->db, - tables->real_name, - tables->alias, &refresh))) + !(tables->table= open_table(thd, + tables->db, + tables->real_name, + tables->alias, &refresh))) { if (refresh) // Refresh in progress { @@ -1522,15 +1540,57 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) /* - Open all tables in list and locks them for read. - The lock will automaticly be freed by close_thread_tables() + Open all tables in list and locks them for read without derived + tables processing. + + SYNOPSIS + simple_open_n_lock_tables() + thd - thread handler + tables - list of tables for open&locking + + RETURN + 0 - ok + -1 - error + + NOTE + The lock will automaticly be freed by close_thread_tables() */ -int open_and_lock_tables(THD *thd,TABLE_LIST *tables) +int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) { - if (open_tables(thd,tables) || lock_tables(thd,tables)) - return -1; /* purecov: inspected */ - return 0; + DBUG_ENTER("simple_open_n_lock_tables"); + uint counter; + if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter)) + DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(0); +} + + +/* + Open all tables in list, locks them and process derived tables + tables processing. + + SYNOPSIS + open_and_lock_tables() + thd - thread handler + tables - list of tables for open&locking + + RETURN + 0 - ok + -1 - error + + NOTE + The lock will automaticly be freed by close_thread_tables() +*/ + +int open_and_lock_tables(THD *thd, TABLE_LIST *tables) +{ + DBUG_ENTER("open_and_lock_tables"); + uint counter; + if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter)) + DBUG_RETURN(-1); /* purecov: inspected */ + fix_tables_pointers(thd->lex->all_selects_list); + DBUG_RETURN(mysql_handle_derived(thd->lex)); } @@ -1541,6 +1601,7 @@ int open_and_lock_tables(THD *thd,TABLE_LIST *tables) lock_tables() thd Thread handler tables Tables to lock + count umber of opened tables NOTES You can't call lock_tables twice, as this would break the dead-lock-free @@ -1552,7 +1613,7 @@ int open_and_lock_tables(THD *thd,TABLE_LIST *tables) -1 Error */ -int lock_tables(THD *thd,TABLE_LIST *tables) +int lock_tables(THD *thd, TABLE_LIST *tables, uint count) { TABLE_LIST *table; if (!tables) @@ -1561,14 +1622,14 @@ int lock_tables(THD *thd,TABLE_LIST *tables) if (!thd->locked_tables) { DBUG_ASSERT(thd->lock == 0); // You must lock everything at once - uint count=0; - for (table = tables ; table ; table=table->next) - count++; TABLE **start,**ptr; if (!(ptr=start=(TABLE**) sql_alloc(sizeof(TABLE*)*count))) return -1; for (table = tables ; table ; table=table->next) - *(ptr++)= table->table; + { + if (!table->derived) + *(ptr++)= table->table; + } if (!(thd->lock=mysql_lock_tables(thd,start,count))) return -1; /* purecov: inspected */ } @@ -1576,7 +1637,8 @@ int lock_tables(THD *thd,TABLE_LIST *tables) { for (table = tables ; table ; table=table->next) { - if (check_lock_and_start_stmt(thd, table->table, table->lock_type)) + if (!table->derived && + check_lock_and_start_stmt(thd, table->table, table->lock_type)) { ha_rollback_stmt(thd); return -1; @@ -2039,15 +2101,28 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, /* - Remap table numbers if INSERT ... SELECT - Check also that the 'used keys' and 'ignored keys' exists and set up the - table structure accordingly + prepare tables + + SYNOPSIS + setup_tables() + tables - tables list + reinit - true if called for table reinitialization before + subquery reexecuting + + RETURN + 0 ok; In this case *map will includes the choosed index + 1 error + + NOTE + Remap table numbers if INSERT ... SELECT + Check also that the 'used keys' and 'ignored keys' exists and set up the + table structure accordingly - This has to be called for all tables that are used by items, as otherwise - table->map is not set and all Item_field will be regarded as const items. + This has to be called for all tables that are used by items, as otherwise + table->map is not set and all Item_field will be regarded as const items. */ -bool setup_tables(TABLE_LIST *tables) +bool setup_tables(TABLE_LIST *tables, my_bool reinit) { DBUG_ENTER("setup_tables"); uint tablenr=0; @@ -2074,7 +2149,7 @@ bool setup_tables(TABLE_LIST *tables) table->keys_in_use_for_query.subtract(map); } table->used_keys.intersect(table->keys_in_use_for_query); - if (table_list->shared || table->clear_query_id) + if ((table_list->shared || table->clear_query_id) && !reinit) { table->clear_query_id= 0; /* Clear query_id that may have been set by previous select */ @@ -2382,7 +2457,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) create_info.default_table_charset= thd->variables.collation_database; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, - fields, keys, drop, alter, 0, (ORDER*)0, FALSE, + fields, keys, drop, alter, 0, (ORDER*)0, DUP_ERROR)); } @@ -2399,7 +2474,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) create_info.default_table_charset= thd->variables.collation_database; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, - fields, keys, drop, alter, 0, (ORDER*)0, FALSE, + fields, keys, drop, alter, 0, (ORDER*)0, DUP_ERROR)); } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 02df644f3b4..fd5c339a6ff 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -308,6 +308,10 @@ TODO list: #include "../myisammrg/myrg_def.h" #endif +#ifdef EMBEDDED_LIBRARY +#include "emb_qcache.h" +#endif + #if defined(EXTRA_DEBUG) && !defined(DBUG_OFF) #define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \ pthread_mutex_lock(M);} @@ -646,7 +650,7 @@ void query_cache_abort(NET *net) } -void query_cache_end_of_result(NET *net) +void query_cache_end_of_result(THD *thd) { DBUG_ENTER("query_cache_end_of_result"); @@ -655,11 +659,15 @@ void query_cache_end_of_result(NET *net) if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN; #endif - if (net->query_cache_query != 0) // Quick check on unlocked structure + if (thd->net.query_cache_query != 0) // Quick check on unlocked structure { +#ifdef EMBEDDED_LIBRARY + query_cache_insert(&thd->net, (byte*)thd, + emb_count_querycache_size(thd)); +#endif STRUCT_LOCK(&query_cache.structure_guard_mutex); Query_cache_block *query_block = ((Query_cache_block*) - net->query_cache_query); + thd->net.query_cache_query); if (query_block) { DUMP(&query_cache); @@ -691,7 +699,7 @@ void query_cache_end_of_result(NET *net) // Cache was flushed or resized and query was deleted => do nothing STRUCT_UNLOCK(&query_cache.structure_guard_mutex); } - net->query_cache_query=0; + thd->net.query_cache_query=0; DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0);); } DBUG_VOID_RETURN; @@ -1057,23 +1065,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) /* Send cached result to client */ +#ifndef EMBEDDED_LIBRARY do { DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)", - result_block->length, result_block->used, - result_block->headers_len()+ - ALIGN_SIZE(sizeof(Query_cache_result)))); - + result_block->length, result_block->used, + result_block->headers_len()+ + ALIGN_SIZE(sizeof(Query_cache_result)))); + Query_cache_result *result = result_block->result(); -#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ if (net_real_write(&thd->net, result->data(), result_block->used - result_block->headers_len() - ALIGN_SIZE(sizeof(Query_cache_result)))) break; // Client aborted -#endif result_block = result_block->next; } while (result_block != first_result_block); +#else + { + Querycache_stream qs(result_block, result_block->headers_len() + + ALIGN_SIZE(sizeof(Query_cache_result))); + emb_load_querycache_result(thd, &qs); + } +#endif /*!EMBEDDED_LIBRARY*/ thd->limit_found_rows = query->found_rows(); @@ -1809,18 +1823,23 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block, Query_cache_block *block = *result_block; uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) + ALIGN_SIZE(sizeof(Query_cache_result))); +#ifndef EMBEDDED_LIBRARY // Now fill list of blocks that created by allocate_data_chain do { block->type = type; ulong length = block->used - headers_len; DBUG_PRINT("qcache", ("write %lu byte in block 0x%lx",length, - (ulong)block)); + (ulong)block)); memcpy((void*)(((byte*) block)+headers_len), (void*) rest, length); rest += length; block = block->next; type = Query_cache_block::RES_CONT; } while (block != *result_block); +#else + Querycache_stream qs(*result_block, headers_len); + emb_store_querycache_result(&qs, (THD*)data); +#endif /*!EMBEDDED_LIBRARY*/ } else { diff --git a/sql/sql_cache.h b/sql/sql_cache.h index 68e69ab523f..ac4f465bf79 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -392,7 +392,7 @@ protected: void destroy(); friend void query_cache_insert(NET *net, const char *packet, ulong length); - friend void query_cache_end_of_result(NET *net); + friend void query_cache_end_of_result(THD *thd); friend void query_cache_abort(NET *net); /* @@ -416,7 +416,7 @@ protected: extern Query_cache query_cache; extern TYPELIB query_cache_type_typelib; -void query_cache_end_of_result(NET *net); +void query_cache_end_of_result(THD *thd); void query_cache_abort(NET *net); #endif diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 93a2db50876..635e6807516 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -149,9 +149,6 @@ THD::THD():user_time(0), is_fatal_error(0), *scramble= '\0'; init(); - init_sql_alloc(&mem_root, // must be after init() - variables.query_alloc_block_size, - variables.query_prealloc_size); /* Initialize sub structures */ init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); user_connect=(USER_CONN *)0; @@ -188,9 +185,6 @@ THD::THD():user_time(0), is_fatal_error(0), transaction.trans_log.end_of_file= max_binlog_cache_size; } #endif - init_sql_alloc(&transaction.mem_root, - variables.trans_alloc_block_size, - variables.trans_prealloc_size); /* We need good random number initialization for new thread Just coping global one will not work @@ -234,6 +228,23 @@ void THD::init(void) /* + Init THD for query processing. + This has to be called once before we call mysql_parse. + See also comments in sql_class.h. +*/ + +void THD::init_for_queries() +{ + init_sql_alloc(&mem_root, + variables.query_alloc_block_size, + variables.query_prealloc_size); + init_sql_alloc(&transaction.mem_root, + variables.trans_alloc_block_size, + variables.trans_prealloc_size); +} + + +/* Do what's needed when one invokes change user SYNOPSIS @@ -330,8 +341,8 @@ THD::~THD() safeFree(host); if (user != delayed_user) safeFree(user); - safeFree(db); safeFree(ip); + safeFree(db); free_root(&warn_root,MYF(0)); free_root(&transaction.mem_root,MYF(0)); mysys_var=0; // Safety (shouldn't be needed) @@ -339,6 +350,8 @@ THD::~THD() #ifndef DBUG_OFF dbug_sentry= THD_SENTRY_GONE; #endif + /* Reset stmt_backup.mem_root to not double-free memory from thd.mem_root */ + init_alloc_root(&stmt_backup.mem_root, 0, 0); DBUG_VOID_RETURN; } @@ -678,12 +691,24 @@ bool select_send::send_eof() } -/*************************************************************************** -** Export of select to textfile -***************************************************************************/ +/************************************************************************ + Handling writing to file +************************************************************************/ +void select_to_file::send_error(uint errcode,const char *err) +{ + ::send_error(thd,errcode,err); + if (file > 0) + { + (void) end_io_cache(&cache); + (void) my_close(file,MYF(0)); + (void) my_delete(path,MYF(0)); // Delete file on error + file= -1; + } +} -select_export::~select_export() + +select_to_file::~select_to_file() { if (file >= 0) { // This only happens in case of error @@ -691,42 +716,78 @@ select_export::~select_export() (void) my_close(file,MYF(0)); file= -1; } +} + +/*************************************************************************** +** Export of select to textfile +***************************************************************************/ + +select_export::~select_export() +{ thd->sent_row_count=row_count; } -int -select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u) + +/* + Create file with IO cache + + SYNOPSIS + create_file() + thd Thread handle + path File name + exchange Excange class + cache IO cache + + RETURN + >= 0 File handle + -1 Error +*/ + + +static File create_file(THD *thd, char *path, sql_exchange *exchange, + IO_CACHE *cache) { - char path[FN_REFLEN]; - uint option=4; - bool blob_flag=0; - unit= u; + File file; + uint option= MY_UNPACK_FILENAME; + #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS - option|=1; // Force use of db directory + option|= MY_REPLACE_DIR; // Force use of db directory #endif - if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN) - strmake(path,exchange->file_name,FN_REFLEN-1); - (void) fn_format(path,exchange->file_name, thd->db ? thd->db : "", "", + (void) fn_format(path, exchange->file_name, thd->db ? thd->db : "", "", option); - if (!access(path,F_OK)) + if (!access(path, F_OK)) { my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name); - return 1; + return -1; } /* Create the file world readable */ - if ((file=my_create(path, 0666, O_WRONLY, MYF(MY_WME))) < 0) - return 1; + if ((file= my_create(path, 0666, O_WRONLY, MYF(MY_WME))) < 0) + return file; #ifdef HAVE_FCHMOD - (void) fchmod(file,0666); // Because of umask() + (void) fchmod(file, 0666); // Because of umask() #else - (void) chmod(path,0666); + (void) chmod(path, 0666); #endif - if (init_io_cache(&cache,file,0L,WRITE_CACHE,0L,1,MYF(MY_WME))) + if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME))) { - my_close(file,MYF(0)); - file= -1; - return 1; + my_close(file, MYF(0)); + my_delete(path, MYF(0)); // Delete file on error, it was just created + return -1; } + return file; +} + + +int +select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u) +{ + bool blob_flag=0; + unit= u; + if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN) + strmake(path,exchange->file_name,FN_REFLEN-1); + + if ((file= create_file(thd, path, exchange, &cache)) < 0) + return 1; /* Check if there is any blobs in data */ { List_iterator_fast<Item> li(list); @@ -897,15 +958,6 @@ err: } -void select_export::send_error(uint errcode, const char *err) -{ - ::send_error(thd,errcode,err); - (void) end_io_cache(&cache); - (void) my_close(file,MYF(0)); - file= -1; -} - - bool select_export::send_eof() { int error=test(end_io_cache(&cache)); @@ -923,48 +975,12 @@ bool select_export::send_eof() ***************************************************************************/ -select_dump::~select_dump() -{ - if (file >= 0) - { // This only happens in case of error - (void) end_io_cache(&cache); - (void) my_close(file,MYF(0)); - file= -1; - } -} - int select_dump::prepare(List<Item> &list __attribute__((unused)), SELECT_LEX_UNIT *u) { - uint option=4; unit= u; -#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS - option|=1; // Force use of db directory -#endif - (void) fn_format(path,exchange->file_name, thd->db ? thd->db : "", "", - option); - if (!access(path,F_OK)) - { - my_error(ER_FILE_EXISTS_ERROR,MYF(0),exchange->file_name); - return 1; - } - /* Create the file world readable */ - if ((file=my_create(path, 0666, O_WRONLY, MYF(MY_WME))) < 0) - return 1; -#ifdef HAVE_FCHMOD - (void) fchmod(file,0666); // Because of umask() -#else - (void) chmod(path,0666); -#endif - if (init_io_cache(&cache,file,0L,WRITE_CACHE,0L,1,MYF(MY_WME))) - { - my_close(file,MYF(0)); - my_delete(path,MYF(0)); - file= -1; - return 1; - } - return 0; + return (int) ((file= create_file(thd, path, exchange, &cache)) < 0); } @@ -1007,15 +1023,6 @@ err: } -void select_dump::send_error(uint errcode,const char *err) -{ - ::send_error(thd,errcode,err); - (void) end_io_cache(&cache); - (void) my_close(file,MYF(0)); - (void) my_delete(path,MYF(0)); // Delete file on error - file= -1; -} - bool select_dump::send_eof() { int error=test(end_io_cache(&cache)); @@ -1027,18 +1034,20 @@ bool select_dump::send_eof() return error; } + select_subselect::select_subselect(Item_subselect *item_arg) { item= item_arg; } + bool select_singlerow_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_singlerow_subselect::send_data"); Item_singlerow_subselect *it= (Item_singlerow_subselect *)item; if (it->assigned()) { - my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0)); + my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0)); DBUG_RETURN(1); } if (unit->offset_limit_cnt) @@ -1054,6 +1063,7 @@ bool select_singlerow_subselect::send_data(List<Item> &items) DBUG_RETURN(0); } + bool select_max_min_finder_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_max_min_finder_subselect::send_data"); @@ -1159,8 +1169,9 @@ bool select_exists_subselect::send_data(List<Item> &items) /*************************************************************************** -** Dump of select to variables + Dump of select to variables ***************************************************************************/ + int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) { List_iterator_fast<Item> li(list); diff --git a/sql/sql_class.h b/sql/sql_class.h index 91ffb9bb7d9..b7ef30b4e79 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -428,7 +428,6 @@ struct system_variables void free_tmp_table(THD *thd, TABLE *entry); -class Prepared_statement; /* State of a single command executed against this connection. @@ -589,6 +588,7 @@ public: struct st_mysql_bind *client_params; char *extra_data; ulong extra_length; + String query_rest; #endif NET net; // client connection descriptor MEM_ROOT warn_root; // For warnings and errors @@ -606,8 +606,7 @@ public: Statement_map stmt_map; /* keeps THD state while it is used for active statement - Note, that double free_root() is safe, so we don't need to do any - special cleanup for it in THD destructor. + Note: we perform special cleanup for it in THD destructor. */ Statement stmt_backup; /* @@ -657,6 +656,19 @@ public: and are still in use by this thread */ TABLE *open_tables,*temporary_tables, *handler_tables, *derived_tables; + /* + During a MySQL session, one can lock tables in two modes: automatic + or manual. In automatic mode all necessary tables are locked just before + statement execution, and all acquired locks are stored in 'lock' + member. Unlocking takes place automatically as well, when the + statement ends. + Manual mode comes into play when a user issues a 'LOCK TABLES' + statement. In this mode the user can only use the locked tables. + Trying to use any other tables will give an error. The locked tables are + stored in 'locked_tables' member. Manual locking is described in + the 'LOCK_TABLES' chapter of the MySQL manual. + See also lock_tables() for details. + */ MYSQL_LOCK *lock; /* Current locks */ MYSQL_LOCK *locked_tables; /* Tables locked with LOCK */ /* @@ -806,6 +818,16 @@ public: ~THD(); void init(void); + /* + Initialize memory roots necessary for query processing and (!) + pre-allocate memory for it. We can't do that in THD constructor because + there are use cases (acl_init, delayed inserts, watcher threads, + killing mysqld) where it's vital to not allocate excessive and not used + memory. Note, that we still don't return error from init_for_queries(): + if preallocation fails, we should notice that at the first call to + alloc_root. + */ + void init_for_queries(); void change_user(void); void cleanup(void); bool store_globals(); @@ -987,41 +1009,41 @@ public: }; -class select_export :public select_result { +class select_to_file :public select_result { +protected: sql_exchange *exchange; File file; IO_CACHE cache; ha_rows row_count; + char path[FN_REFLEN]; + +public: + select_to_file(sql_exchange *ex) :exchange(ex), file(-1),row_count(0L) + { path[0]=0; } + ~select_to_file(); + bool send_fields(List<Item> &list, uint flag) { return 0; } + void send_error(uint errcode,const char *err); +}; + + +class select_export :public select_to_file { uint field_term_length; int field_sep_char,escape_char,line_sep_char; bool fixed_row_size; public: - select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) {} + select_export(sql_exchange *ex) :select_to_file(ex) {} ~select_export(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_fields(List<Item> &list, - uint flag) { return 0; } bool send_data(List<Item> &items); - void send_error(uint errcode,const char *err); bool send_eof(); }; -class select_dump :public select_result { - sql_exchange *exchange; - File file; - IO_CACHE cache; - ha_rows row_count; - char path[FN_REFLEN]; +class select_dump :public select_to_file { public: - select_dump(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) - { path[0]=0; } - ~select_dump(); + select_dump(sql_exchange *ex) :select_to_file(ex) {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_fields(List<Item> &list, - uint flag) { return 0; } bool send_data(List<Item> &items); - void send_error(uint errcode,const char *err); bool send_eof(); }; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 2d636c51dd4..bc6b30040d6 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -25,8 +25,6 @@ #include <direct.h> #endif -#define MY_DB_OPT_FILE "db.opt" - const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS}; static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts}; @@ -92,7 +90,7 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) */ -static bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) +bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) { File file; char buf[256]; @@ -269,11 +267,8 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); // do not alter database if another thread is holding read lock - if (wait_if_global_read_lock(thd,0)) - { - error= -1; + if ((error=wait_if_global_read_lock(thd,0))) goto exit2; - } /* Check directory */ (void)sprintf(path,"%s/%s/%s", mysql_data_home, db, MY_DB_OPT_FILE); @@ -305,7 +300,7 @@ exit: start_waiting_global_read_lock(thd); exit2: VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); - DBUG_RETURN(error); + DBUG_RETURN(error ? -1 : 0); /* -1 to delegate send_error() */ } @@ -408,7 +403,7 @@ exit: when the slave is replicating a DROP DATABASE: - garbage characters in the error message: "Error 'Can't drop database 'test2'; database doesn't exist' on query - 'h4zI¿'" + 'h4zI©'" - segfault - hang in "free(vio)" (yes!) in the I/O or SQL slave threads (so slave server hangs at shutdown etc). @@ -417,7 +412,8 @@ exit: { if (!(thd->slave_thread)) /* a slave thread will free it itself */ x_free(thd->db); - thd->db= 0; + thd->db= 0; + thd->db_length= 0; } exit2: VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); @@ -667,90 +663,3 @@ bool mysql_change_db(THD *thd, const char *name) DBUG_RETURN(0); } - -int mysqld_show_create_db(THD *thd, char *dbname, - HA_CREATE_INFO *create_info) -{ - int length; - char path[FN_REFLEN], *to; - uint db_access; - bool found_libchar; - HA_CREATE_INFO create; - uint create_options = create_info ? create_info->options : 0; - Protocol *protocol=thd->protocol; - DBUG_ENTER("mysql_show_create_db"); - - if (check_db_name(dbname)) - { - net_printf(thd,ER_WRONG_DB_NAME, dbname); - DBUG_RETURN(1); - } - -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (test_all_bits(thd->master_access,DB_ACLS)) - db_access=DB_ACLS; - else - db_access= (acl_get(thd->host,thd->ip, thd->priv_user,dbname,0) | - thd->master_access); - if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) - { - net_printf(thd,ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->host_or_ip, - dbname); - mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), - thd->priv_user, - thd->host_or_ip, - dbname); - DBUG_RETURN(1); - } -#endif - - (void) sprintf(path,"%s/%s",mysql_data_home, dbname); - length=unpack_dirname(path,path); // Convert if not unix - found_libchar= 0; - if (length && path[length-1] == FN_LIBCHAR) - { - found_libchar= 1; - path[length-1]=0; // remove ending '\' - } - if (access(path,F_OK)) - { - net_printf(thd,ER_BAD_DB_ERROR,dbname); - DBUG_RETURN(1); - } - if (found_libchar) - path[length-1]= FN_LIBCHAR; - strmov(path+length, MY_DB_OPT_FILE); - load_db_opt(thd, path, &create); - - List<Item> field_list; - field_list.push_back(new Item_empty_string("Database",NAME_LEN)); - field_list.push_back(new Item_empty_string("Create Database",1024)); - - if (protocol->send_fields(&field_list,1)) - DBUG_RETURN(1); - - protocol->prepare_for_resend(); - protocol->store(dbname, strlen(dbname), system_charset_info); - to= strxmov(path, "CREATE DATABASE ", NullS); - if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS) - to= strxmov(to,"/*!32312 IF NOT EXISTS*/ ", NullS); - to=strxmov(to,"`",dbname,"`", NullS); - - if (create.default_table_charset) - { - int cl= (create.default_table_charset->state & MY_CS_PRIMARY) ? 0 : 1; - to= strxmov(to," /*!40100" - " DEFAULT CHARACTER SET ",create.default_table_charset->csname, - cl ? " COLLATE " : "", - cl ? create.default_table_charset->name : "", - " */",NullS); - } - protocol->store(path, (uint) (to-path), system_charset_info); - - if (protocol->write()) - DBUG_RETURN(1); - send_eof(thd); - DBUG_RETURN(0); -} diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 22cb11eed41..1fa216fdb58 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -43,7 +43,6 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, if ((open_and_lock_tables(thd, table_list))) DBUG_RETURN(-1); - fix_tables_pointers(thd->lex->all_selects_list); table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); thd->proc_info="init"; @@ -159,7 +158,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, !thd->net.report_error) { // thd->net.report_error is tested to disallow delete row on error - if (!(select && select->skipp_record())&& !thd->net.report_error ) + if (!(select && select->skip_record())&& !thd->net.report_error ) { if (!(error=table->file->delete_row(table->record[0]))) { diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index e8f1c5d87de..0e04316a2e7 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -25,6 +25,58 @@ #include "sql_select.h" #include "sql_acl.h" +static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, + TABLE_LIST *t); + +/* + Resolve derived tables in all queries + + SYNOPSIS + mysql_handle_derived() + lex LEX for this thread + + RETURN + 0 ok + -1 Error + 1 Error and error message given +*/ + +int +mysql_handle_derived(LEX *lex) +{ + if (lex->derived_tables) + { + for (SELECT_LEX *sl= lex->all_selects_list; + sl; + sl= sl->next_select_in_list()) + { + for (TABLE_LIST *cursor= sl->get_table_list(); + cursor; + cursor= cursor->next) + { + int res; + if (cursor->derived && (res=mysql_derived(lex->thd, lex, + cursor->derived, + cursor))) + { + return res; + } + } + if (lex->describe) + { + /* + Force join->join_tmp creation, because we will use this JOIN + twice for EXPLAIN and we have to have unchanged join for EXPLAINing + */ + sl->uncacheable|= UNCACHEABLE_EXPLAIN; + sl->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; + } + } + } + return 0; +} + + /* Resolve derived tables in all queries @@ -49,9 +101,6 @@ Derived tables is stored in thd->derived_tables and freed in close_thread_tables() - TODO - Move creation of derived tables in open_and_lock_tables() - RETURN 0 ok 1 Error @@ -59,8 +108,8 @@ */ -int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, - TABLE_LIST *org_table_list) +static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, + TABLE_LIST *org_table_list) { SELECT_LEX *first_select= unit->first_select(); TABLE *table; @@ -72,80 +121,39 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, bool is_subsel= first_select->first_inner_unit() ? 1: 0; SELECT_LEX *save_current_select= lex->current_select; DBUG_ENTER("mysql_derived"); - - /* - In create_total_list, derived tables have to be treated in case of - EXPLAIN, This is because unit/node is not deleted in that - case. Current code in this function has to be improved to - recognize better when this function is called from derived tables - and when from other functions. - */ - if ((is_union || is_subsel) && unit->create_total_list(thd, lex, &tables, 1)) - DBUG_RETURN(-1); + if (!(derived_result= new select_union(0))) + DBUG_RETURN(1); // out of memory + + // st_select_lex_unit::prepare correctly work for single select + if ((res= unit->prepare(thd, derived_result, 0))) + goto exit; + + + derived_result->tmp_table_param.init(); + derived_result->tmp_table_param.field_count= unit->types.elements; /* - We have to do access checks here as this code is executed before any - sql command is started to execute. + Temp table is created so that it hounours if UNION without ALL is to be + processed */ -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (tables) - res= check_table_access(thd,SELECT_ACL, tables,0); - else - res= check_access(thd, SELECT_ACL, any_db,0,0,0); - if (res) - DBUG_RETURN(1); -#endif - - if (!(res=open_and_lock_tables(thd,tables))) + if (!(table= create_tmp_table(thd, &derived_result->tmp_table_param, + unit->types, (ORDER*) 0, + is_union && !unit->union_option, 1, + (first_select->options | thd->options | + TMP_TABLE_ALL_COLUMNS), + HA_POS_ERROR, + org_table_list->alias))) { - if (is_union || is_subsel) - { - /* - The following code is a re-do of fix_tables_pointers() found - in sql_select.cc for UNION's within derived tables. The only - difference is in navigation, as in derived tables we care for - this level only. - - */ - fix_tables_pointers(unit); - } - - if (!(derived_result= new select_union(0))) - DBUG_RETURN(1); // out of memory + res= -1; + goto exit; + } + derived_result->set_table(table); - // st_select_lex_unit::prepare correctly work for single select - if ((res= unit->prepare(thd, derived_result))) - goto exit; - - /* - This is done in order to redo all field optimisations when any of the - involved tables is used in the outer query - */ - if (tables) - { - for (TABLE_LIST *cursor= tables; cursor; cursor= cursor->next) - cursor->table->clear_query_id= 1; - } - - derived_result->tmp_table_param.init(); - derived_result->tmp_table_param.field_count= unit->types.elements; - /* - Temp table is created so that it hounours if UNION without ALL is to be - processed - */ - if (!(table= create_tmp_table(thd, &derived_result->tmp_table_param, - unit->types, (ORDER*) 0, - is_union && !unit->union_option, 1, - (first_select->options | thd->options | - TMP_TABLE_ALL_COLUMNS), - HA_POS_ERROR, - org_table_list->alias))) - { - res= -1; - goto exit; - } - derived_result->set_table(table); + if (is_union) + res= mysql_union(thd, lex, derived_result, unit); + else + { unit->offset_limit_cnt= first_select->offset_limit; unit->select_limit_cnt= first_select->select_limit+ first_select->offset_limit; @@ -154,57 +162,50 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, if (unit->select_limit_cnt == HA_POS_ERROR) first_select->options&= ~OPTION_FOUND_ROWS; - if (is_union) - res= mysql_union(thd, lex, derived_result, unit); + lex->current_select= first_select; + res= mysql_select(thd, &first_select->ref_pointer_array, + (TABLE_LIST*) first_select->table_list.first, + first_select->with_wild, + first_select->item_list, first_select->where, + (first_select->order_list.elements+ + first_select->group_list.elements), + (ORDER *) first_select->order_list.first, + (ORDER *) first_select->group_list.first, + first_select->having, (ORDER*) NULL, + (first_select->options | thd->options | + SELECT_NO_UNLOCK), + derived_result, unit, first_select); + } + + if (!res) + { + /* + Here we entirely fix both TABLE_LIST and list of SELECT's as + there were no derived tables + */ + if (derived_result->flush()) + res= 1; else - res= mysql_select(thd, &first_select->ref_pointer_array, - (TABLE_LIST*) first_select->table_list.first, - first_select->with_wild, - first_select->item_list, first_select->where, - (first_select->order_list.elements+ - first_select->group_list.elements), - (ORDER *) first_select->order_list.first, - (ORDER *) first_select->group_list.first, - first_select->having, (ORDER*) NULL, - (first_select->options | thd->options | - SELECT_NO_UNLOCK), - derived_result, unit, first_select); - - if (!res) { - /* - Here we entirely fix both TABLE_LIST and list of SELECT's as - there were no derived tables - */ - if (derived_result->flush()) - res= 1; - else + org_table_list->real_name= table->real_name; + org_table_list->table= table; + if (org_table_list->table_list) { - org_table_list->real_name=table->real_name; - org_table_list->table=table; - table->derived_select_number= first_select->select_number; - table->tmp_table= TMP_TABLE; + org_table_list->table_list->real_name= table->real_name; + org_table_list->table_list->table= table; + } + table->derived_select_number= first_select->select_number; + table->tmp_table= TMP_TABLE; #ifndef NO_EMBEDDED_ACCESS_CHECKS - org_table_list->grant.privilege= SELECT_ACL; + table->grant.privilege= SELECT_ACL; #endif - if (lex->describe) - { - // to fix a problem in EXPLAIN - if (tables) - { - for (TABLE_LIST *cursor= tables; cursor; cursor= cursor->next) - if (cursor->table_list) - cursor->table_list->table=cursor->table; - } - } - else - unit->exclude_tree(); - org_table_list->db= (char *)""; - // Force read of table stats in the optimizer - table->file->info(HA_STATUS_VARIABLE); - } + org_table_list->db= (char *)""; + // Force read of table stats in the optimizer + table->file->info(HA_STATUS_VARIABLE); } + if (!lex->describe) + unit->cleanup(); if (res) free_tmp_table(thd, table); else @@ -217,7 +218,6 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, exit: delete derived_result; lex->current_select= save_current_select; - close_thread_tables(thd, 0, 1); } DBUG_RETURN(res); } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 405cfdb5bdc..897aa37ba11 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -48,7 +48,8 @@ static TABLE **find_table_ptr_by_name(THD *thd,const char *db, int mysql_ha_open(THD *thd, TABLE_LIST *tables) { HANDLER_TABLES_HACK(thd); - int err=open_tables(thd,tables); + uint counter; + int err=open_tables(thd, tables, &counter); HANDLER_TABLES_HACK(thd); if (err) return -1; diff --git a/sql/sql_help.cc b/sql/sql_help.cc index c40133c04a8..3c98b7b0bb4 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -274,9 +274,9 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, DBUG_ENTER("get_topics_for_keyword"); - if ((iindex_topic= find_type((char*) "PRIMARY", + if ((iindex_topic= find_type((char*) primary_key_name, &topics->keynames, 1+2)-1)<0 || - (iindex_relations= find_type((char*) "PRIMARY", + (iindex_relations= find_type((char*) primary_key_name, &relations->keynames, 1+2)-1)<0) { send_error(thd,ER_CORRUPT_HELP_DB); @@ -686,7 +686,7 @@ int mysqld_help(THD *thd, const char *mask) goto end; } /* Init tables and fields to be usable from items */ - setup_tables(tables); + setup_tables(tables, 0); memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields)); if (init_fields(thd, tables, used_fields, array_elements(used_fields))) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 010ebc3b798..3a7e2a8d285 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -81,7 +81,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields, table_list.grant=table->grant; thd->dupp_field=0; - if (setup_tables(&table_list) || + if (setup_tables(&table_list, 0) || setup_fields(thd, 0, &table_list,fields,1,0,0)) return -1; if (thd->dupp_field) @@ -175,7 +175,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, res= open_and_lock_tables(thd, table_list); if (res) DBUG_RETURN(-1); - fix_tables_pointers(thd->lex->all_selects_list); table= table_list->table; thd->proc_info="init"; @@ -185,13 +184,14 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, if (duplic == DUP_UPDATE && !table->insert_values) { /* it should be allocated before Item::fix_fields() */ - table->insert_values=(byte *)alloc_root(&table->mem_root, table->rec_buff_length); + table->insert_values= + (byte *)alloc_root(&thd->mem_root, table->rec_buff_length); if (!table->insert_values) goto abort; } if (check_insert_fields(thd,table,fields,*values,1) || - setup_tables(insert_table_list) || + setup_tables(insert_table_list, 0) || setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) || (duplic == DUP_UPDATE && (setup_fields(thd, 0, insert_table_list, update_fields, 0, 0, 0) || @@ -633,7 +633,8 @@ public: thd.command=COM_DELAYED_INSERT; thd.lex->current_select= 0; /* for my_message_sql */ - bzero((char*) &thd.net,sizeof(thd.net)); // Safety + bzero((char*) &thd.net, sizeof(thd.net)); // Safety + bzero((char*) &table_list, sizeof(table_list)); // Safety thd.system_thread= SYSTEM_THREAD_DELAYED_INSERT; thd.host_or_ip= ""; bzero((char*) &info,sizeof(info)); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index b0381ae1d30..f37f133f105 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -130,6 +130,8 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->select_lex.expr_list.empty(); lex->select_lex.ftfunc_list_alloc.empty(); lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc; + lex->select_lex.group_list.empty(); + lex->select_lex.order_list.empty(); lex->current_select= &lex->select_lex; lex->yacc_yyss=lex->yacc_yyvs=0; lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); @@ -201,6 +203,23 @@ static int find_keyword(LEX *lex, uint len, bool function) return 0; } +/* + Check if name is a keyword + + SYNOPSIS + is_keyword() + name checked name + len length of checked name + + RETURN VALUES + 0 name is a keyword + 1 name isn't a keyword +*/ + +bool is_keyword(const char *name, uint len) +{ + return get_hash_symbol(name,len,0)!=0; +} /* make a copy of token before ptr and set yytoklen */ @@ -213,6 +232,13 @@ static LEX_STRING get_token(LEX *lex,uint length) return tmp; } +/* + todo: + There are no dangerous charsets in mysql for function + get_quoted_token yet. But it should be fixed in the + future to operate multichar strings (like ucs2) +*/ + static LEX_STRING get_quoted_token(LEX *lex,uint length, char quote) { LEX_STRING tmp; @@ -440,7 +466,6 @@ inline static uint int_token(const char *str,uint length) return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger; } - /* yylex remember the following states from the following yylex() @@ -687,32 +712,17 @@ int yylex(void *arg, void *yythd) case MY_LEX_USER_VARIABLE_DELIMITER: { - char delim= c; // Used char + uint double_quotes= 0; + char quote_char= c; // Used char lex->tok_start=lex->ptr; // Skip first ` + while ((c=yyGet())) + { #ifdef USE_MB - if (use_mb(cs)) - { - while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR) - { - if (my_mbcharlen(cs, c) > 1) - { - int l; - if ((l = my_ismbchar(cs, - (const char *)lex->ptr-1, - (const char *)lex->end_of_query)) == 0) - break; - lex->ptr += l-1; - } - } - yylval->lex_str=get_token(lex,yyLength()); - } - else + if (my_mbcharlen(cs, c) == 1) #endif - { - uint double_quotes= 0; - char quote_char= c; - while ((c=yyGet())) { + if (c == (uchar) NAMES_SEP_CHAR) + break; /* Old .frm format can't handle this char */ if (c == quote_char) { if (yyPeek() != quote_char) @@ -721,16 +731,25 @@ int yylex(void *arg, void *yythd) double_quotes++; continue; } - if (c == (uchar) NAMES_SEP_CHAR) - break; } - if (double_quotes) - yylval->lex_str=get_quoted_token(lex,yyLength() - double_quotes, - quote_char); +#ifdef USE_MB else - yylval->lex_str=get_token(lex,yyLength()); + { + int l; + if ((l = my_ismbchar(cs, + (const char *)lex->ptr-1, + (const char *)lex->end_of_query)) == 0) + break; + lex->ptr += l-1; + } +#endif } - if (c == delim) + if (double_quotes) + yylval->lex_str=get_quoted_token(lex,yyLength() - double_quotes, + quote_char); + else + yylval->lex_str=get_token(lex,yyLength()); + if (c == quote_char) yySkip(); // Skip end ` lex->next_state= MY_LEX_START; return(IDENT_QUOTED); @@ -905,8 +924,13 @@ int yylex(void *arg, void *yythd) } /* fall true */ case MY_LEX_EOL: - lex->next_state=MY_LEX_END; // Mark for next loop - return(END_OF_INPUT); + if (lex->ptr >= lex->end_of_query) + { + lex->next_state=MY_LEX_END; // Mark for next loop + return(END_OF_INPUT); + } + state=MY_LEX_CHAR; + break; case MY_LEX_END: lex->next_state=MY_LEX_END; return(0); // We found end of input last time @@ -1008,6 +1032,7 @@ void st_select_lex_unit::init_query() union_result= 0; table= 0; fake_select_lex= 0; + cleaned= 0; } void st_select_lex::init_query() @@ -1197,7 +1222,6 @@ void st_select_lex_unit::exclude_level() */ void st_select_lex_unit::exclude_tree() { - SELECT_LEX_UNIT *units= 0; for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) { // unlink current level from global SELECTs list @@ -1244,11 +1268,6 @@ void st_select_lex::mark_as_dependent(SELECT_LEX *last) s->uncacheable|= UNCACHEABLE_DEPENDENT; SELECT_LEX_UNIT *munit= s->master_unit(); munit->uncacheable|= UNCACHEABLE_DEPENDENT; - //Tables will be reopened many times - for (TABLE_LIST *tbl= s->get_table_list(); - tbl; - tbl= tbl->next) - tbl->shared= 1; } } @@ -1312,12 +1331,10 @@ bool st_select_lex::test_limit() !0 - error */ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex, - TABLE_LIST **result_arg, - bool check_derived) + TABLE_LIST **result_arg) { *result_arg= 0; - res= create_total_list_n_last_return(thd_arg, lex, &result_arg, - check_derived); + res= create_total_list_n_last_return(thd_arg, lex, &result_arg); return res; } @@ -1329,8 +1346,7 @@ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex, thd THD pointer lex pointer on LEX stricture result pointer on pointer on result list of tables pointer - check_derived force derived table chacking (used for creating - table list for derived query) + DESCRIPTION This is used for UNION & subselect to create a new table list of all used tables. @@ -1344,8 +1360,7 @@ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex, bool st_select_lex_unit:: create_total_list_n_last_return(THD *thd_arg, st_lex *lex, - TABLE_LIST ***result_arg, - bool check_derived) + TABLE_LIST ***result_arg) { TABLE_LIST *slave_list_first=0, **slave_list_last= &slave_list_first; TABLE_LIST **new_table_list= *result_arg, *aux; @@ -1371,15 +1386,12 @@ create_total_list_n_last_return(THD *thd_arg, return 1; } - if (sl->linkage == DERIVED_TABLE_TYPE && !check_derived) - goto end; - for (SELECT_LEX_UNIT *inner= sl->first_inner_unit(); inner; inner= inner->next_unit()) { if (inner->create_total_list_n_last_return(thd, lex, - &slave_list_last, 0)) + &slave_list_last)) return 1; } @@ -1426,63 +1438,75 @@ end: return 0; } + st_select_lex_unit* st_select_lex_unit::master_unit() { return this; } + st_select_lex* st_select_lex_unit::outer_select() { return (st_select_lex*) master; } + bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc) { return add_to_list(thd, order_list, item, asc); } + bool st_select_lex::add_item_to_list(THD *thd, Item *item) { return item_list.push_back(item); } + bool st_select_lex::add_group_to_list(THD *thd, Item *item, bool asc) { return add_to_list(thd, group_list, item, asc); } + bool st_select_lex::add_ftfunc_to_list(Item_func_match *func) { return !func || ftfunc_list->push_back(func); // end of memory? } + st_select_lex_unit* st_select_lex::master_unit() { return (st_select_lex_unit*) master; } + st_select_lex* st_select_lex::outer_select() { return (st_select_lex*) master->get_master(); } + bool st_select_lex::set_braces(bool value) { braces= value; return 0; } + bool st_select_lex::inc_in_sum_expr() { in_sum_expr++; return 0; } + uint st_select_lex::get_in_sum_expr() { return in_sum_expr; } + TABLE_LIST* st_select_lex::get_table_list() { return (TABLE_LIST*) table_list.first; @@ -1493,21 +1517,25 @@ List<Item>* st_select_lex::get_item_list() return &item_list; } + List<String>* st_select_lex::get_use_index() { return use_index_ptr; } + List<String>* st_select_lex::get_ignore_index() { return ignore_index_ptr; } + ulong st_select_lex::get_table_join_options() { return table_join_options; } + bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) { if (ref_pointer_array) @@ -1519,6 +1547,58 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) order_group_num)* 5)) == 0; } + +/* + Find db.table which will be updated in this unit + + SYNOPSIS + st_select_lex_unit::check_updateable() + db - data base name + table - real table name + + RETURN + 1 - found + 0 - OK (table did not found) +*/ +bool st_select_lex_unit::check_updateable(char *db, char *table) +{ + for(SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + if (sl->check_updateable(db, table)) + return 1; + return 0; +} + + +/* + Find db.table which will be updated in this select and + underlayed ones (except derived tables) + + SYNOPSIS + st_select_lex::check_updateable() + db - data base name + table - real table name + + RETURN + 1 - found + 0 - OK (table did not found) +*/ +bool st_select_lex::check_updateable(char *db, char *table) +{ + if (find_real_table_in_list(get_table_list(), db, table)) + return 1; + + for (SELECT_LEX_UNIT *un= first_inner_unit(); + un; + un= un->next_unit()) + { + if (un->first_select()->linkage != DERIVED_TABLE_TYPE && + un->check_updateable(db, table)) + return 1; + } + return 0; +} + + void st_select_lex_unit::print(String *str) { for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) @@ -1561,6 +1641,7 @@ void st_select_lex::print_order(String *str, ORDER *order) } } + void st_select_lex::print_limit(THD *thd, String *str) { if (!thd) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index fb7d8415e91..50b8f322731 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -243,6 +243,7 @@ public: UNCACHEABLE_DEPENDENT UNCACHEABLE_RAND UNCACHEABLE_SIDEEFFECT + UNCACHEABLE_EXPLAIN */ uint8 uncacheable; enum sub_select_type linkage; @@ -315,7 +316,8 @@ protected: ulong found_rows_for_union; bool prepared, // prepare phase already performed for UNION (unit) optimized, // optimize phase already performed for UNION (unit) - executed; // already executed + executed, // already executed + cleaned; public: // list of fields which points to temporary table for union @@ -347,8 +349,7 @@ public: uint union_option; void init_query(); - bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result, - bool check_current_derived); + bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); st_select_lex_unit* master_unit(); st_select_lex* outer_select(); st_select_lex* first_select() { return (st_select_lex*) slave; } @@ -362,18 +363,19 @@ public: void exclude_tree(); /* UNION methods */ - int prepare(THD *thd, select_result *result); + int prepare(THD *thd, select_result *result, ulong additional_options); int exec(); int cleanup(); + bool check_updateable(char *db, char *table); void print(String *str); + friend void mysql_init_query(THD *thd, bool lexonly); friend int subselect_union_engine::exec(); private: bool create_total_list_n_last_return(THD *thd, st_lex *lex, - TABLE_LIST ***result, - bool check_current_derived); + TABLE_LIST ***result); }; typedef class st_select_lex_unit SELECT_LEX_UNIT; @@ -510,6 +512,7 @@ public: init_select(); } bool setup_ref_array(THD *thd, uint order_group_num); + bool check_updateable(char *db, char *table); void print(THD *thd, String *str); static void print_order(String *str, ORDER *order); void print_limit(THD *thd, String *str); @@ -596,7 +599,7 @@ typedef struct st_lex uint param_count; uint slave_thd_opt; uint8 describe; - bool drop_primary, drop_if_exists, drop_temporary, local_file; + bool drop_if_exists, drop_temporary, local_file; bool in_comment, ignore_space, verbose, simple_alter, no_write_to_binlog; bool derived_tables; bool safe_to_cache_query; diff --git a/sql/sql_list.h b/sql/sql_list.h index 5318237b786..e8b15974924 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -21,6 +21,12 @@ /* mysql standard class memoryallocator */ +#ifdef PEDANTIC_SAFEMALLOC +#define TRASH(XX,YY) bfill((XX), (YY), 0x8F) +#else +#define TRASH(XX,YY) /* no-op */ +#endif + class Sql_alloc { public: @@ -34,8 +40,8 @@ public: } static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, (uint) size); } - static void operator delete(void *ptr, size_t size) {} /*lint -e715 */ - static void operator delete[](void *ptr, size_t size) {} + static void operator delete(void *ptr, size_t size) { TRASH(ptr, size); } + static void operator delete[](void *ptr, size_t size) { TRASH(ptr, size); } #ifdef HAVE_purify bool dummy; inline Sql_alloc() :dummy(0) {} diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 2f8a979b5ee..f128601d281 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -123,7 +123,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, else { // Part field list thd->dupp_field=0; - if (setup_tables(table_list) || + if (setup_tables(table_list, 0) || setup_fields(thd, 0, table_list, fields, 1, 0, 0)) DBUG_RETURN(-1); if (thd->dupp_field) diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc index ef7bf013be8..efc4cf0921d 100644 --- a/sql/sql_olap.cc +++ b/sql/sql_olap.cc @@ -143,18 +143,6 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex) int count=select_lex->group_list.elements; int sl_return=0; -// a fix for UNION's - for (TABLE_LIST *cursor= (TABLE_LIST *)select_lex->table_list.first; - cursor; - cursor=cursor->next) - { - if (cursor->do_redirect) - { - //Sinisa TODO: there are function for this purpose: fix_tables_pointers - cursor->table= cursor->table_list->table; - cursor->do_redirect= 0; - } - } lex->last_selects=select_lex; @@ -164,7 +152,7 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex) List<Item> all_fields(select_lex->item_list); - if (setup_tables((TABLE_LIST *)select_lex->table_list.first) || + if (setup_tables((TABLE_LIST *)select_lex->table_list.first, 0) || setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first, select_lex->item_list, 1, &all_fields,1) || setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5a06e835d88..ae507c34272 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -846,6 +846,7 @@ static int check_connection(THD *thd) char *passwd= strend(user)+1; char *db= passwd; char db_buff[NAME_LEN+1]; // buffer to store db in utf8 + char user_buff[USERNAME_LENGTH+1]; // buffer to store user in utf8 /* Old clients send null-terminated string as password; new clients send the size (1 byte) + string (not null-terminated). Hence in case of empty @@ -866,6 +867,14 @@ static int check_connection(THD *thd) db= db_buff; } + if (user) + { + user_buff[copy_and_convert(user_buff, sizeof(user_buff)-1, + system_charset_info, user, strlen(user), + thd->charset())]= '\0'; + user= user_buff; + } + if (thd->user) x_free(thd->user); if (!(thd->user= my_strdup(user, MYF(0)))) @@ -986,6 +995,7 @@ pthread_handler_decl(handle_one_connection,arg) thd->proc_info=0; thd->set_time(); + thd->init_for_queries(); while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION)) { if (do_command(thd)) @@ -1065,6 +1075,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) thd->priv_user=thd->user=(char*) my_strdup("boot", MYF(MY_WME)); buff= (char*) thd->net.buff; + thd->init_for_queries(); while (fgets(buff, thd->net.max_packet, file)) { uint length=(uint) strlen(buff); @@ -1109,7 +1120,7 @@ end: void free_items(Item *item) { for (; item ; item=item->next) - delete item; + item->delete_self(); } /* This works because items are allocated with sql_alloc() */ @@ -1400,11 +1411,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char *packet= thd->lex->found_colon; /* Multiple queries exits, execute them individually + in embedded server - just store them to be executed later */ +#ifndef EMBEDDED_LIBRARY if (thd->lock || thd->open_tables || thd->derived_tables) close_thread_tables(thd); - - ulong length= thd->query_length-(ulong)(thd->lex->found_colon-thd->query); +#endif + ulong length= thd->query_length-(ulong)(packet-thd->query); /* Remove garbage at start of query */ while (my_isspace(thd->charset(), *packet) && length > 0) @@ -1417,7 +1430,22 @@ bool dispatch_command(enum enum_server_command command, THD *thd, VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id= query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); +#ifndef EMBEDDED_LIBRARY mysql_parse(thd, packet, length); +#else + /* + 'packet' can point inside the query_rest's buffer + so we have to do memmove here + */ + if (thd->query_rest.length() > length) + { + memmove(thd->query_rest.c_ptr(), packet, length); + thd->query_rest.length(length); + } + else + thd->query_rest.copy(length); + break; +#endif /*EMBEDDED_LIBRARY*/ } if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -1625,9 +1653,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, switch (command) { case MYSQL_OPTION_MULTI_STATEMENTS_ON: thd->client_capabilities|= CLIENT_MULTI_STATEMENTS; + send_eof(thd); break; case MYSQL_OPTION_MULTI_STATEMENTS_OFF: thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS; + send_eof(thd); break; default: send_error(thd, ER_UNKNOWN_COM_ERROR); @@ -1796,34 +1826,9 @@ mysql_execute_command(THD *thd) #endif } #endif /* !HAVE_REPLICATION */ - /* - TODO: make derived tables processing 'inside' SELECT processing. - TODO: solve problem with depended derived tables in subselects - */ - if (lex->derived_tables) - { - for (SELECT_LEX *sl= lex->all_selects_list; - sl; - sl= sl->next_select_in_list()) - { - for (TABLE_LIST *cursor= sl->get_table_list(); - cursor; - cursor= cursor->next) - { - if (cursor->derived && (res=mysql_derived(thd, lex, - cursor->derived, - cursor))) - { - if (res < 0 || thd->net.report_error) - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); - DBUG_RETURN(res); - } - } - } - } if (&lex->select_lex != lex->all_selects_list && lex->sql_command != SQLCOM_CREATE_TABLE && - lex->unit.create_total_list(thd, lex, &tables, 0)) + lex->unit.create_total_list(thd, lex, &tables)) DBUG_RETURN(0); /* @@ -1882,7 +1887,6 @@ mysql_execute_command(THD *thd) } else thd->send_explain_fields(result); - fix_tables_pointers(lex->all_selects_list); res= mysql_explain_union(thd, &thd->lex->unit, result); MYSQL_LOCK *save_lock= thd->lock; thd->lock= (MYSQL_LOCK *)0; @@ -1906,10 +1910,6 @@ mysql_execute_command(THD *thd) if (!(result=new select_send())) { res= -1; -#ifdef DELETE_ITEMS - delete select_lex->having; - delete select_lex->where; -#endif break; } } @@ -1925,7 +1925,6 @@ mysql_execute_command(THD *thd) (res= open_and_lock_tables(thd,tables)))) break; - fix_tables_pointers(lex->all_selects_list); res= mysql_do(thd, *lex->insert_list); if (thd->net.report_error) res= -1; @@ -2134,7 +2133,7 @@ mysql_execute_command(THD *thd) lex->select_lex.table_list.first= (byte*) (tables); create_table->next= 0; if (&lex->select_lex != lex->all_selects_list && - lex->unit.create_total_list(thd, lex, &tables, 0)) + lex->unit.create_total_list(thd, lex, &tables)) DBUG_RETURN(-1); ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ? @@ -2326,7 +2325,7 @@ mysql_execute_command(THD *thd) lex->key_list, lex->drop_list, lex->alter_list, select_lex->order_list.elements, (ORDER *) select_lex->order_list.first, - lex->drop_primary, lex->duplicates, + lex->duplicates, lex->alter_keys_onoff, lex->tablespace_op, lex->simple_alter); @@ -2349,6 +2348,8 @@ mysql_execute_command(THD *thd) if (grant_option) { TABLE_LIST old_list,new_list; + bzero((char*) &old_list, sizeof(old_list)); + bzero((char*) &new_list, sizeof(new_list)); // Safety old_list=table[0]; new_list=table->next[0]; old_list.next=new_list.next=0; @@ -2471,7 +2472,7 @@ mysql_execute_command(THD *thd) tables, lex->create_list, lex->key_list, lex->drop_list, lex->alter_list, 0, (ORDER *) 0, - 0, DUP_ERROR); + DUP_ERROR); } else res = mysql_optimize_table(thd, tables, &lex->check_opt); @@ -2669,15 +2670,21 @@ mysql_execute_command(THD *thd) table_count++; /* All tables in aux_tables must be found in FROM PART */ TABLE_LIST *walk; - for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next) + for (walk= (TABLE_LIST*) tables; walk; walk= walk->next) { - if (!strcmp(auxi->real_name,walk->real_name) && - !strcmp(walk->db,auxi->db)) + if (!strcmp(auxi->real_name, walk->alias) && + !strcmp(walk->db, auxi->db)) break; } if (!walk) { - net_printf(thd,ER_NONUNIQ_TABLE,auxi->real_name); + net_printf(thd, ER_NONUNIQ_TABLE, auxi->real_name); + goto error; + } + if (walk->derived) + { + net_printf(thd, ER_NON_UPDATABLE_TABLE, + auxi->real_name, "DELETE"); goto error; } walk->lock_type= auxi->lock_type; @@ -2693,21 +2700,27 @@ mysql_execute_command(THD *thd) break; /* Fix tables-to-be-deleted-from list to point at opened tables */ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) - auxi->table= auxi->table_list->table; - if (&lex->select_lex != lex->all_selects_list) { - for (TABLE_LIST *t= select_lex->get_table_list(); - t; t= t->next) + auxi->table= auxi->table_list->table; + /* + Multi-delete can't be constructed over-union => we always have + single SELECT on top and have to check underlaying SELECTs of it + */ + for (SELECT_LEX_UNIT *un= lex->select_lex.first_inner_unit(); + un; + un= un->next_unit()) { - if (find_real_table_in_list(t->table_list->next, t->db, t->real_name)) + if (un->first_select()->linkage != DERIVED_TABLE_TYPE && + un->check_updateable(auxi->table_list->db, + auxi->table_list->real_name)) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), t->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), auxi->table_list->real_name); res= -1; break; } } } - fix_tables_pointers(lex->all_selects_list); + if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables, table_count))) { @@ -2952,7 +2965,6 @@ mysql_execute_command(THD *thd) if (tables && ((res= check_table_access(thd, SELECT_ACL, tables,0)) || (res= open_and_lock_tables(thd,tables)))) break; - fix_tables_pointers(lex->all_selects_list); if (!(res= sql_set_variables(thd, &lex->var_list))) send_ok(thd); if (thd->net.report_error) @@ -4147,7 +4159,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) else { mysql_execute_command(thd); - query_cache_end_of_result(&thd->net); + query_cache_end_of_result(thd); } } } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 165e1bf28c9..43bf3e3651c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -680,7 +680,7 @@ static bool mysql_test_upd_fields(Prepared_statement *stmt, #endif if (open_and_lock_tables(thd, table_list)) DBUG_RETURN(1); - if (setup_tables(table_list) || + if (setup_tables(table_list, 0) || setup_fields(thd, 0, table_list, fields, 1, 0, 0) || setup_conds(thd, table_list, &conds) || thd->net.report_error) DBUG_RETURN(1); @@ -734,7 +734,7 @@ static bool mysql_test_select_fields(Prepared_statement *stmt, DBUG_RETURN(1); #endif if ((&lex->select_lex != lex->all_selects_list && - lex->unit.create_total_list(thd, lex, &tables, 0))) + lex->unit.create_total_list(thd, lex, &tables))) DBUG_RETURN(1); if (open_and_lock_tables(thd, tables)) @@ -747,7 +747,6 @@ static bool mysql_test_select_fields(Prepared_statement *stmt, } else { - fix_tables_pointers(lex->all_selects_list); if (!result && !(result= new select_send())) { send_error(thd, ER_OUT_OF_RESOURCES); @@ -757,7 +756,8 @@ static bool mysql_test_select_fields(Prepared_statement *stmt, JOIN *join= new JOIN(thd, fields, select_options, result); thd->used_tables= 0; // Updated by setup_fields - if (join->prepare(&select_lex->ref_pointer_array, tables, + if (join->prepare(&select_lex->ref_pointer_array, + (TABLE_LIST*)select_lex->get_table_list(), wild_num, conds, og_num, order, group, having, proc, select_lex, unit)) DBUG_RETURN(1); @@ -926,6 +926,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) sl->prep_where= sl->where; } + cleanup_items(thd->free_list); stmt->set_statement(thd); thd->set_statement(&thd->stmt_backup); @@ -983,14 +984,10 @@ void mysql_stmt_execute(THD *thd, char *packet) DBUG_VOID_RETURN; } - /* - XXX: while thd->query_id is incremented for each command, stmt->query_id - holds query_id of prepare stage. Keeping old query_id seems to be more - natural, but differs from the way prepared statements work in 4.1: - */ - /* stmt->query_id= thd->query_id; */ + stmt->query_id= thd->query_id; thd->stmt_backup.set_statement(thd); thd->set_statement(stmt); + thd->free_list= 0; /* To make sure that all runtime data is stored in its own memory root and @@ -1014,6 +1011,13 @@ void mysql_stmt_execute(THD *thd, char *packet) if (sl->prep_where) sl->where= sl->prep_where->copy_andor_structure(thd); DBUG_ASSERT(sl->join == 0); + ORDER *order; + /* Fix GROUP list */ + for (order=(ORDER *)sl->group_list.first ; order ; order=order->next) + order->item= (Item **)(order+1); + /* Fix ORDER list */ + for (order=(ORDER *)sl->order_list.first ; order ; order=order->next) + order->item= (Item **)(order+1); } /* @@ -1050,6 +1054,8 @@ void mysql_stmt_execute(THD *thd, char *packet) if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), WAIT_PRIOR); + free_items(thd->free_list); + cleanup_items(stmt->free_list); free_root(&thd->mem_root, MYF(0)); thd->set_statement(&thd->stmt_backup); DBUG_VOID_RETURN; @@ -1201,7 +1207,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg) #ifndef EMBEDDED_LIBRARY setup_params= insert_params; // not fully qualified query #else - setup_params_data= setup_params_data; + setup_params_data= ::setup_params_data; #endif } diff --git a/sql/sql_select.h b/sql/sql_select.h index 086e181d523..491710f5b3e 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -46,6 +46,8 @@ typedef struct st_table_ref store_key **key_copy; // Item **items; // val()'s for each keypart table_map depend_map; // Table depends on these tables. + byte *null_ref_key; // null byte position in the key_buf. + // used for REF_OR_NULL optimization. } TABLE_REF; /* @@ -88,7 +90,6 @@ typedef struct st_join_table { QUICK_SELECT_I *quick; Item *on_expr; const char *info; - byte *null_ref_key; int (*read_first_record)(struct st_join_table *tab); int (*next_select)(JOIN *,struct st_join_table *,bool); READ_RECORD read_record; @@ -107,6 +108,8 @@ typedef struct st_join_table { TABLE_REF ref; JOIN_CACHE cache; JOIN *join; + + void cleanup(); } JOIN_TAB; @@ -433,7 +436,6 @@ public: bool cp_buffer_from_ref(TABLE_REF *ref); bool error_if_full_join(JOIN *join); -void relink_tables(SELECT_LEX *select_lex); int report_error(TABLE *table, int error); int safe_index_read(JOIN_TAB *tab); COND *eliminate_not_funcs(COND *cond); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 3dfef4b7189..158d9b1acb0 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -519,7 +519,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) protocol->store_null(); // Send error to Comment field protocol->store(thd->net.last_error, system_charset_info); - thd->net.last_error[0]=0; + thd->clear_error(); } else { @@ -812,6 +812,94 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(0); } +int mysqld_show_create_db(THD *thd, char *dbname, + HA_CREATE_INFO *create_info) +{ + int length; + char path[FN_REFLEN]; + char buff[2048]; + String buffer(buff, sizeof(buff), system_charset_info); + uint db_access; + bool found_libchar; + HA_CREATE_INFO create; + uint create_options = create_info ? create_info->options : 0; + Protocol *protocol=thd->protocol; + DBUG_ENTER("mysql_show_create_db"); + + if (check_db_name(dbname)) + { + net_printf(thd,ER_WRONG_DB_NAME, dbname); + DBUG_RETURN(1); + } + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (test_all_bits(thd->master_access,DB_ACLS)) + db_access=DB_ACLS; + else + db_access= (acl_get(thd->host,thd->ip, thd->priv_user,dbname,0) | + thd->master_access); + if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) + { + net_printf(thd,ER_DBACCESS_DENIED_ERROR, + thd->priv_user, thd->host_or_ip, dbname); + mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), + thd->priv_user, thd->host_or_ip, dbname); + DBUG_RETURN(1); + } +#endif + + (void) sprintf(path,"%s/%s",mysql_data_home, dbname); + length=unpack_dirname(path,path); // Convert if not unix + found_libchar= 0; + if (length && path[length-1] == FN_LIBCHAR) + { + found_libchar= 1; + path[length-1]=0; // remove ending '\' + } + if (access(path,F_OK)) + { + net_printf(thd,ER_BAD_DB_ERROR,dbname); + DBUG_RETURN(1); + } + if (found_libchar) + path[length-1]= FN_LIBCHAR; + strmov(path+length, MY_DB_OPT_FILE); + load_db_opt(thd, path, &create); + + List<Item> field_list; + field_list.push_back(new Item_empty_string("Database",NAME_LEN)); + field_list.push_back(new Item_empty_string("Create Database",1024)); + + if (protocol->send_fields(&field_list,1)) + DBUG_RETURN(1); + + protocol->prepare_for_resend(); + protocol->store(dbname, strlen(dbname), system_charset_info); + buffer.length(0); + buffer.append("CREATE DATABASE ", 16); + if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS) + buffer.append("/*!32312 IF NOT EXISTS*/ ", 25); + append_identifier(thd, &buffer, dbname, strlen(dbname)); + + if (create.default_table_charset) + { + buffer.append(" /*!40100", 9); + buffer.append(" DEFAULT CHARACTER SET ", 23); + buffer.append(create.default_table_charset->csname); + if (!(create.default_table_charset->state & MY_CS_PRIMARY)) + { + buffer.append(" COLLATE ", 9); + buffer.append(create.default_table_charset->name); + } + buffer.append(" */", 3); + } + protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); + + if (protocol->write()) + DBUG_RETURN(1); + send_eof(thd); + DBUG_RETURN(0); +} int mysqld_show_logs(THD *thd) @@ -997,25 +1085,99 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd) DBUG_RETURN(0); } +static inline const char *require_quotes(const char *name, uint length) +{ + uint i, d, c; + for (i=0; i<length; i+=d) + { + c=((uchar *)name)[i]; + d=my_mbcharlen(system_charset_info, c); + if (d==1 && !system_charset_info->ident_map[c]) + return name+i; + } + return 0; +} + +/* + Looking for char in multibyte string + + SYNOPSIS + look_for_char() + name string for looking at + length length of name + q '\'' or '\"' for looking for + + RETURN VALUES + # pointer to found char in string + 0 string doesn't contain required char +*/ + +static inline const char *look_for_char(const char *name, + uint length, char q) +{ + const char *cur= name; + const char *end= cur+length; + uint symbol_length; + for (; cur<end; cur+= symbol_length) + { + char c= *cur; + symbol_length= my_mbcharlen(system_charset_info, c); + if (symbol_length==1 && c==q) + return cur; + } + return 0; +} void append_identifier(THD *thd, String *packet, const char *name, uint length) { char qtype; + uint part_len; + const char *qplace; if (thd->variables.sql_mode & MODE_ANSI_QUOTES) qtype= '\"'; else qtype= '`'; - if (thd->options & OPTION_QUOTE_SHOW_CREATE) + if (is_keyword(name,length)) { - packet->append(&qtype, 1); + packet->append(&qtype, 1, system_charset_info); packet->append(name, length, system_charset_info); - packet->append(&qtype, 1); + packet->append(&qtype, 1, system_charset_info); } else { - packet->append(name, length, system_charset_info); + if (!(qplace= require_quotes(name, length))) + { + if (!(thd->options & OPTION_QUOTE_SHOW_CREATE)) + packet->append(name, length, system_charset_info); + else + { + packet->append(&qtype, 1, system_charset_info); + packet->append(name, length, system_charset_info); + packet->append(&qtype, 1, system_charset_info); + } + } + else + { + packet->shrink(packet->length()+length+2); + packet->append(&qtype, 1, system_charset_info); + if (*qplace != qtype) + qplace= look_for_char(qplace+1,length-(qplace-name)-1,qtype); + while (qplace) + { + if ((part_len= qplace-name)) + { + packet->append(name, part_len, system_charset_info); + length-= part_len; + } + packet->append(qplace, 1, system_charset_info); + name= qplace; + qplace= look_for_char(name+1,length-1,qtype); + } + packet->append(name, length, system_charset_info); + packet->append(&qtype, 1, system_charset_info); + } } } @@ -1167,7 +1329,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) bool found_primary=0; packet->append(",\n ", 4); - if (i == primary_key && !strcmp(key_info->name,"PRIMARY")) + if (i == primary_key && !strcmp(key_info->name, primary_key_name)) { found_primary=1; packet->append("PRIMARY ", 8); @@ -1235,7 +1397,10 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append("\n)", 2); if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode) { - packet->append(" ENGINE=", 8); + if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) + packet->append(" TYPE=", 6); + else + packet->append(" ENGINE=", 8); packet->append(file->table_type()); if (table->table_charset && diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 61070f07266..093b85b46b7 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -24,6 +24,7 @@ #include <my_sys.h> #include <m_string.h> #include <m_ctype.h> +#include <assert.h> #ifdef HAVE_FCONVERT #include <floatingpoint.h> #endif @@ -228,15 +229,117 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) return FALSE; } + +/* + Checks that the source string can be just copied to the destination string + without conversion. + + SYNPOSIS + + needs_conversion() + arg_length Length of string to copy. + from_cs Character set to copy from + to_cs Character set to copy to + uint32 *offset Returns number of unaligned characters. + + RETURN + 0 No conversion needed + 1 Either character set conversion or adding leading zeros + (e.g. for UCS-2) must be done +*/ + +bool String::needs_conversion(uint32 arg_length, + CHARSET_INFO *from_cs, + CHARSET_INFO *to_cs, + uint32 *offset) +{ + *offset= 0; + if ((to_cs == &my_charset_bin) || + (to_cs == from_cs) || + my_charset_same(from_cs, to_cs) || + ((from_cs == &my_charset_bin) && + (!(*offset=(arg_length % to_cs->mbminlen))))) + return FALSE; + return TRUE; +} + + +/* + Copy a multi-byte character sets with adding leading zeros. + + SYNOPSIS + + copy_aligned() + str String to copy + arg_length Length of string. This should NOT be dividable with + cs->mbminlen. + offset arg_length % cs->mb_minlength + cs Character set for 'str' + + NOTES + For real multi-byte, ascii incompatible charactser sets, + like UCS-2, add leading zeros if we have an incomplete character. + Thus, + SELECT _ucs2 0xAA + will automatically be converted into + SELECT _ucs2 0x00AA + + RETURN + 0 ok + 1 error +*/ + +bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset, + CHARSET_INFO *cs) +{ + /* How many bytes are in incomplete character */ + offset= cs->mbmaxlen - offset; /* How many zeros we should prepend */ + DBUG_ASSERT(offset && offset != cs->mbmaxlen); + + uint32 aligned_length= arg_length + offset; + if (alloc(aligned_length)) + return TRUE; + + /* + Note, this is only safe for little-endian UCS-2. + If we add big-endian UCS-2 sometimes, this code + will be more complicated. But it's OK for now. + */ + bzero((char*) Ptr, offset); + memcpy(Ptr + offset, str, arg_length); + Ptr[aligned_length]=0; + /* str_length is always >= 0 as arg_length is != 0 */ + str_length= aligned_length; + str_charset= cs; + return FALSE; +} + + +bool String::set_or_copy_aligned(const char *str,uint32 arg_length, + CHARSET_INFO *cs) +{ + /* How many bytes are in incomplete character */ + uint32 offset= (arg_length % cs->mbminlen); + + if (!offset) /* All characters are complete, just copy */ + { + set(str, arg_length, cs); + return FALSE; + } + return copy_aligned(str, arg_length, offset, cs); +} + /* Copy with charset convertion */ bool String::copy(const char *str, uint32 arg_length, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs) { - if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin)) - { - return copy(str, arg_length, &my_charset_bin); - } + uint32 offset; + if (!needs_conversion(arg_length, from_cs, to_cs, &offset)) + return copy(str, arg_length, to_cs); + if ((from_cs == &my_charset_bin) && offset) + return copy_aligned(str, arg_length, offset, to_cs); + uint32 new_length= to_cs->mbmaxlen*arg_length; if (alloc(new_length)) return TRUE; @@ -434,7 +537,7 @@ int String::strstr(const String &s,uint32 offset) register const char *search=s.ptr(); const char *end=Ptr+str_length-s.length()+1; const char *search_end=s.ptr()+s.length(); -skipp: +skip: while (str != end) { if (*str++ == *search) @@ -442,7 +545,7 @@ skipp: register char *i,*j; i=(char*) str; j=(char*) search+1; while (j != search_end) - if (*i++ != *j++) goto skipp; + if (*i++ != *j++) goto skip; return (int) (str-Ptr) -1; } } @@ -466,7 +569,7 @@ int String::strstr_case(const String &s,uint32 offset) register const char *search=s.ptr(); const char *end=Ptr+str_length-s.length()+1; const char *search_end=s.ptr()+s.length(); -skipp: +skip: while (str != end) { if (str_charset->sort_order[*str++] == str_charset->sort_order[*search]) @@ -476,7 +579,7 @@ skipp: while (j != search_end) if (str_charset->sort_order[*i++] != str_charset->sort_order[*j++]) - goto skipp; + goto skip; return (int) (str-Ptr) -1; } } @@ -499,7 +602,7 @@ int String::strrstr(const String &s,uint32 offset) const char *end=Ptr+s.length()-2; const char *search_end=s.ptr()-1; -skipp: +skip: while (str != end) { if (*str-- == *search) @@ -507,7 +610,7 @@ skipp: register char *i,*j; i=(char*) str; j=(char*) search-1; while (j != search_end) - if (*i-- != *j--) goto skipp; + if (*i-- != *j--) goto skip; return (int) (i-Ptr) +1; } } @@ -657,7 +760,8 @@ copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, while (1) { - if ((cnvres=from_cs->cset->mb_wc(from_cs, &wc, (uchar*) from, from_end)) > 0) + if ((cnvres= from_cs->cset->mb_wc(from_cs, &wc, (uchar*) from, + from_end)) > 0) from+= cnvres; else if (cnvres == MY_CS_ILSEQ) { diff --git a/sql/sql_string.h b/sql/sql_string.h index 325611737ca..163156fdfe2 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -183,6 +183,12 @@ public: bool copy(); // Alloc string if not alloced bool copy(const String &s); // Allocate new string bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string + static bool needs_conversion(uint32 arg_length, + CHARSET_INFO *cs_from, CHARSET_INFO *cs_to, + uint32 *offset); + bool copy_aligned(const char *s, uint32 arg_length, uint32 offset, + CHARSET_INFO *cs); + bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs); bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, CHARSET_INFO *csto); bool append(const String &s); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index fe2cfcf2b41..3b593e57d82 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -29,7 +29,7 @@ #include <io.h> #endif -static const char *primary_key_name="PRIMARY"; +const char *primary_key_name= "PRIMARY"; static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end); static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end); @@ -506,6 +506,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, blob_columns++; break; case FIELD_TYPE_GEOMETRY: +#ifdef HAVE_SPATIAL if (!(file->table_flags() & HA_HAS_GEOMETRY)) { my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED), @@ -521,6 +522,11 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, sql_field->unireg_check=Field::BLOB_FIELD; blob_columns++; break; +#else + my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); + DBUG_RETURN(-1); +#endif /*HAVE_SPATIAL*/ case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_STRING: sql_field->pack_flag=0; @@ -654,8 +660,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_info->flags = HA_FULLTEXT; break; case Key::SPATIAL: +#ifdef HAVE_SPATIAL key_info->flags = HA_SPATIAL; break; +#else + my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); + DBUG_RETURN(-1); +#endif case Key::FOREIGN_KEY: key_number--; // Skip this key continue; @@ -694,8 +706,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } } - else if (key_info->algorithm == HA_KEY_ALG_RTREE) + else + if (key_info->algorithm == HA_KEY_ALG_RTREE) { +#ifdef HAVE_RTREE_KEYS if ((key_info->key_parts & 1) == 1) { my_printf_error(ER_WRONG_ARGUMENTS, @@ -706,6 +720,11 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, my_printf_error(ER_NOT_SUPPORTED_YET, ER(ER_NOT_SUPPORTED_YET), MYF(0), "RTREE INDEX"); DBUG_RETURN(-1); +#else + my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), + sym_group_rtree.name, sym_group_rtree.needed_define); + DBUG_RETURN(-1); +#endif } List_iterator<key_part_spec> cols(key->columns); @@ -775,6 +794,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } } +#ifdef HAVE_SPATIAL if (key->type == Key::SPATIAL) { if (!column->length ) @@ -786,6 +806,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, column->length=4*sizeof(double); } } +#endif if (!(sql_field->flags & NOT_NULL_FLAG)) { if (key->type == Key::PRIMARY) @@ -830,6 +851,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } } + /* TODO HF What's this for??? */ else if (f_is_geom(sql_field->pack_flag)) { } @@ -851,7 +873,12 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, column->field_name); DBUG_RETURN(-1); } - key_part_info->length=(uint8) length; + if (length > file->max_key_part_length()) + { + my_error(ER_WRONG_SUB_KEY,MYF(0)); + DBUG_RETURN(-1); + } + key_part_info->length=(uint16) length; /* Use packed keys for long strings on the first column */ if (!(db_options & HA_OPTION_NO_PACK_KEYS) && (length >= KEY_DEFAULT_PACK_LENGTH && @@ -1930,7 +1957,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, List<Key> &keys,List<Alter_drop> &drop_list, List<Alter_column> &alter_list, uint order_num, ORDER *order, - bool drop_primary, enum enum_duplicates handle_duplicates, enum enum_enable_or_disable keys_onoff, enum tablespace_op_type tablespace_op, @@ -2138,7 +2164,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, def_it.rewind(); while ((def=def_it++)) { - if (def->change && + if (def->change && !my_strcasecmp(system_charset_info,field->field_name, def->change)) break; } @@ -2231,13 +2257,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, KEY *key_info=table->key_info; for (uint i=0 ; i < table->keys ; i++,key_info++) { - if (drop_primary && (key_info->flags & HA_NOSAME)) - { - drop_primary=0; - continue; - } - - char *key_name=key_info->name; + char *key_name= key_info->name; Alter_drop *drop; drop_it.rewind(); while ((drop=drop_it++)) @@ -2280,7 +2300,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { // Check if sub key if (cfield->field->type() != FIELD_TYPE_BLOB && (cfield->field->pack_length() == key_part_length || - cfield->length <= key_part_length / + cfield->length <= key_part_length / key_part->field->charset()->mbmaxlen)) key_part_length=0; // Use whole field } @@ -2292,7 +2312,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL : (key_info->flags & HA_NOSAME ? (!my_strcasecmp(system_charset_info, - key_name, "PRIMARY") ? + key_name, primary_key_name) ? Key::PRIMARY : Key::UNIQUE) : (key_info->flags & HA_FULLTEXT ? Key::FULLTEXT : Key::MULTIPLE)), diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 337f2540a39..6e8aae54b23 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -149,7 +149,7 @@ void udf_init() tables.lock_type = TL_READ; tables.db=new_thd->db; - if (open_and_lock_tables(new_thd, &tables)) + if (simple_open_n_lock_tables(new_thd, &tables)) { DBUG_PRINT("error",("Can't open udf table")); sql_print_error("Can't open mysql/func table"); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 25620229844..75fd9be88bd 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -29,7 +29,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result, { DBUG_ENTER("mysql_union"); int res= 0; - if (!(res= unit->prepare(thd, result))) + if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK))) res= unit->exec(); res|= unit->cleanup(); DBUG_RETURN(res); @@ -106,7 +106,8 @@ bool select_union::flush() } -int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result) +int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, + ulong additional_options) { SELECT_LEX *lex_select_save= thd_arg->lex->current_select; SELECT_LEX *sl, *first_select; @@ -145,8 +146,9 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result) for (;sl; sl= sl->next_select()) { + sl->options|= SELECT_NO_UNLOCK; JOIN *join= new JOIN(thd_arg, sl->item_list, - sl->options | thd_arg->options | SELECT_NO_UNLOCK, + sl->options | thd_arg->options | additional_options, tmp_result); thd_arg->lex->current_select= sl; offset_limit_cnt= sl->offset_limit; @@ -440,9 +442,16 @@ int st_select_lex_unit::cleanup() int error= 0; DBUG_ENTER("st_select_lex_unit::cleanup"); + if (cleaned) + { + DBUG_RETURN(0); + } + cleaned= 0; + if (union_result) { delete union_result; + union_result=0; // Safety if (table) free_tmp_table(thd, table); table= 0; // Safety diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 6b4d2f9b659..03ab3d01c1a 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -79,7 +79,6 @@ int mysql_update(THD *thd, if ((open_and_lock_tables(thd, table_list))) DBUG_RETURN(-1); thd->proc_info="init"; - fix_tables_pointers(thd->lex->all_selects_list); table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); @@ -95,7 +94,7 @@ int mysql_update(THD *thd, tables.table= table; tables.alias= table_list->alias; - if (setup_tables(update_table_list) || + if (setup_tables(update_table_list, 0) || setup_conds(thd,update_table_list,&conds) || thd->lex->select_lex.setup_ref_array(thd, order_num) || setup_order(thd, thd->lex->select_lex.ref_pointer_array, @@ -253,7 +252,7 @@ int mysql_update(THD *thd, while (!(error=info.read_record(&info)) && !thd->killed) { - if (!(select && select->skipp_record())) + if (!(select && select->skip_record())) { table->file->position(table->record[0]); if (my_b_write(&tempfile,table->file->ref, @@ -310,7 +309,7 @@ int mysql_update(THD *thd, while (!(error=info.read_record(&info)) && !thd->killed) { - if (!(select && select->skipp_record())) + if (!(select && select->skip_record())) { store_record(table,record[1]); if (fill_record(fields,values, 0) || thd->net.report_error) @@ -440,16 +439,38 @@ int mysql_multi_update(THD *thd, #endif if ((res=open_and_lock_tables(thd,table_list))) DBUG_RETURN(res); - fix_tables_pointers(thd->lex->all_selects_list); select_lex->select_limit= HA_POS_ERROR; + + table_map item_tables= 0, derived_tables= 0; + if (thd->lex->derived_tables) + { + // Assign table map values to check updatability of derived tables + uint tablenr=0; + for (TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first; + table_list; + table_list= table_list->next, tablenr++) + { + table_list->table->map= (table_map) 1 << tablenr; + } + } if (setup_fields(thd, 0, table_list, *fields, 1, 0, 0)) DBUG_RETURN(-1); + if (thd->lex->derived_tables) + { + // Find tables used in items + List_iterator_fast<Item> it(*fields); + Item *item; + while ((item= it++)) + { + item_tables|= item->used_tables(); + } + } /* Count tables and setup timestamp handling */ - for (tl= select_lex->get_table_list() ; tl ; tl=tl->next) + for (tl= select_lex->get_table_list() ; tl ; tl= tl->next) { TABLE *table= tl->table; if (table->timestamp_field) @@ -459,6 +480,21 @@ int mysql_multi_update(THD *thd, if (table->timestamp_field->query_id != thd->query_id) table->time_stamp= table->timestamp_field->offset() +1; } + if (tl->derived) + derived_tables|= table->map; + } + if (thd->lex->derived_tables && (item_tables & derived_tables)) + { + // find derived table which cause error + for (tl= select_lex->get_table_list() ; tl ; tl= tl->next) + { + if (tl->derived && (item_tables & tl->table->map)) + { + my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), + MYF(0), tl->alias, "UPDATE"); + DBUG_RETURN(-1); + } + } } if (!(result=new multi_update(thd, table_list, fields, values, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f35b7f12fd1..4c217b325ec 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -660,7 +660,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); udf_type if_exists opt_local opt_table_options table_options table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct - opt_ignore_leaves fulltext_options + opt_ignore_leaves fulltext_options spatial_type %type <ulong_num> ULONG_NUM raid_types merge_insert_types @@ -677,8 +677,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_wild no_in_expr expr_expr simple_expr no_and_expr udf_expr using_list expr_or_default set_expr_or_default interval_expr param_marker singlerow_subselect singlerow_subselect_init + exists_subselect exists_subselect_init geometry_function signed_literal NUM_literal - exists_subselect exists_subselect_init sp_opt_default + sp_opt_default simple_ident_nospvar simple_ident_q %type <item_list> @@ -717,7 +718,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type <ha_rkey_mode> handler_rkey_mode -%type <cast_type> cast_type cast_type_finalize +%type <cast_type> cast_type %type <udf_type> udf_func_type @@ -985,7 +986,7 @@ create: &tmp_table_alias : (LEX_STRING*) 0), TL_OPTION_UPDATING, - ((using_update_log)? + (using_update_log ? TL_READ_NO_INSERT: TL_READ))) YYABORT; @@ -2108,7 +2109,7 @@ create_table_options: create_table_option: ENGINE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; } - | TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=database_engine","ENGINE=database_engine"); } + | TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=storage_engine","ENGINE=storage_engine"); } | MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;} | MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;} | AVG_ROW_LENGTH opt_equal ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;} @@ -2328,30 +2329,19 @@ type: $$=FIELD_TYPE_TINY_BLOB; } | BLOB_SYM opt_len { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_BLOB; } - | GEOMETRY_SYM { Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint) Field::GEOM_GEOMETRY; - $$=FIELD_TYPE_GEOMETRY; } - | GEOMETRYCOLLECTION { Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint) Field::GEOM_GEOMETRYCOLLECTION; - $$=FIELD_TYPE_GEOMETRY; } - | POINT_SYM { Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint) Field::GEOM_POINT; - $$=FIELD_TYPE_GEOMETRY; } - | MULTIPOINT { Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint) Field::GEOM_MULTIPOINT; - $$=FIELD_TYPE_GEOMETRY; } - | LINESTRING { Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint) Field::GEOM_LINESTRING; - $$=FIELD_TYPE_GEOMETRY; } - | MULTILINESTRING { Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint) Field::GEOM_MULTILINESTRING; - $$=FIELD_TYPE_GEOMETRY; } - | POLYGON { Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint) Field::GEOM_POLYGON; - $$=FIELD_TYPE_GEOMETRY; } - | MULTIPOLYGON { Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint) Field::GEOM_MULTIPOLYGON; - $$=FIELD_TYPE_GEOMETRY; } + | spatial_type { +#ifdef HAVE_SPATIAL + Lex->charset=&my_charset_bin; + Lex->uint_geom_type= (uint)$1; + $$=FIELD_TYPE_GEOMETRY; +#else + net_printf(Lex->thd, ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + sym_group_geom.name, + sym_group_geom.needed_define); + YYABORT; +#endif + } | MEDIUMBLOB { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_MEDIUM_BLOB; } | LONGBLOB { Lex->charset=&my_charset_bin; @@ -2390,6 +2380,17 @@ type: } ; +spatial_type: + GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; } + | GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; } + | POINT_SYM { $$= Field::GEOM_POINT; } + | MULTIPOINT { $$= Field::GEOM_MULTIPOINT; } + | LINESTRING { $$= Field::GEOM_LINESTRING; } + | MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; } + | POLYGON { $$= Field::GEOM_POLYGON; } + | MULTIPOLYGON { $$= Field::GEOM_MULTIPOLYGON; } + ; + char: CHAR_SYM {} ; @@ -2620,23 +2621,30 @@ delete_option: key_type: key_or_index { $$= Key::MULTIPLE; } - | FULLTEXT_SYM { $$= Key::FULLTEXT; } - | FULLTEXT_SYM key_or_index { $$= Key::FULLTEXT; } - | SPATIAL_SYM { $$= Key::SPATIAL; } - | SPATIAL_SYM key_or_index { $$= Key::SPATIAL; }; + | FULLTEXT_SYM opt_key_or_index { $$= Key::FULLTEXT; } + | SPATIAL_SYM opt_key_or_index + { +#ifdef HAVE_SPATIAL + $$= Key::SPATIAL; +#else + net_printf(Lex->thd, ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + sym_group_geom.name, sym_group_geom.needed_define); + YYABORT; +#endif + }; constraint_key_type: PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; } - | UNIQUE_SYM { $$= Key::UNIQUE; } - | UNIQUE_SYM key_or_index { $$= Key::UNIQUE; }; + | UNIQUE_SYM opt_key_or_index { $$= Key::UNIQUE; }; key_or_index: KEY_SYM {} | INDEX {}; -opt_keys_or_index: +opt_key_or_index: /* empty */ {} - | keys_or_index + | key_or_index ; keys_or_index: @@ -2648,7 +2656,17 @@ opt_unique_or_fulltext: /* empty */ { $$= Key::MULTIPLE; } | UNIQUE_SYM { $$= Key::UNIQUE; } | FULLTEXT_SYM { $$= Key::FULLTEXT;} - | SPATIAL_SYM { $$= Key::SPATIAL; } + | SPATIAL_SYM + { +#ifdef HAVE_SPATIAL + $$= Key::SPATIAL; +#else + net_printf(Lex->thd, ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + sym_group_geom.name, sym_group_geom.needed_define); + YYABORT; +#endif + } ; key_alg: @@ -2658,7 +2676,10 @@ key_alg: opt_btree_or_rtree: BTREE_SYM { $$= HA_KEY_ALG_BTREE; } - | RTREE_SYM { $$= HA_KEY_ALG_RTREE; } + | RTREE_SYM + { + $$= HA_KEY_ALG_RTREE; + } | HASH_SYM { $$= HA_KEY_ALG_HASH; }; key_list: @@ -2695,7 +2716,6 @@ alter: if (!lex->select_lex.add_table_to_list(thd, $4, NULL, TL_OPTION_UPDATING)) YYABORT; - lex->drop_primary=0; lex->create_list.empty(); lex->key_list.empty(); lex->col_list.empty(); @@ -2797,12 +2817,14 @@ alter_list_item: lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN, $3.str)); lex->simple_alter=0; } + | DROP FOREIGN KEY_SYM opt_ident { Lex->simple_alter=0; } | DROP PRIMARY_SYM KEY_SYM { LEX *lex=Lex; - lex->drop_primary=1; lex->simple_alter=0; + lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY, + primary_key_name)); + lex->simple_alter=0; } - | DROP FOREIGN KEY_SYM opt_ident { Lex->simple_alter=0; } | DROP key_or_index field_ident { LEX *lex=Lex; @@ -2859,7 +2881,6 @@ opt_to: /* SLAVE START and SLAVE STOP are deprecated. We keep them for compatibility. - To use UNTIL, one must use START SLAVE, not SLAVE START. */ slave: @@ -2870,6 +2891,7 @@ slave: lex->type = 0; /* We'll use mi structure for UNTIL options */ bzero((char*) &lex->mi, sizeof(lex->mi)); + /* If you change this code don't forget to update SLAVE START too */ } slave_until {} @@ -2878,13 +2900,18 @@ slave: LEX *lex=Lex; lex->sql_command = SQLCOM_SLAVE_STOP; lex->type = 0; + /* If you change this code don't forget to update SLAVE STOP too */ } | SLAVE START_SYM slave_thread_opts { LEX *lex=Lex; lex->sql_command = SQLCOM_SLAVE_START; lex->type = 0; - } + /* We'll use mi structure for UNTIL options */ + bzero((char*) &lex->mi, sizeof(lex->mi)); + } + slave_until + {} | SLAVE STOP_SYM slave_thread_opts { LEX *lex=Lex; @@ -3150,7 +3177,7 @@ cache_keys_spec: cache_key_list_or_empty: /* empty */ { Lex->select_lex.use_index_ptr= 0; } - | opt_keys_or_index '(' key_usage_list2 ')' + | opt_key_or_index '(' key_usage_list2 ')' { SELECT_LEX *sel= &Lex->select_lex; sel->use_index_ptr= &sel->use_index; @@ -3224,10 +3251,9 @@ select_init2: select_part2: { - LEX *lex=Lex; - SELECT_LEX * sel= lex->current_select; - if (lex->current_select == &lex->select_lex) - lex->lock_option= TL_READ; /* Only for global SELECT */ + LEX *lex= Lex; + SELECT_LEX *sel= lex->current_select; + lex->lock_option= TL_READ; if (sel->linkage != UNION_TYPE) mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST; @@ -3610,20 +3636,58 @@ simple_expr: } | CONVERT_SYM '(' expr USING charset_name ')' { $$= new Item_func_conv_charset($3,$5); } - | CONVERT_SYM '(' expr ',' expr ',' expr ')' - { $$= new Item_func_conv_charset3($3,$7,$5); } | DEFAULT '(' simple_ident ')' { $$= new Item_default_value($3); } | VALUES '(' simple_ident ')' { $$= new Item_insert_value($3); } | FUNC_ARG0 '(' ')' - { $$= ((Item*(*)(void))($1.symbol->create_func))();} + { + if (!$1.symbol->create_func) + { + net_printf(Lex->thd, ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + $1.symbol->group->name, + $1.symbol->group->needed_define); + YYABORT; + } + $$= ((Item*(*)(void))($1.symbol->create_func))(); + } | FUNC_ARG1 '(' expr ')' - { $$= ((Item*(*)(Item*))($1.symbol->create_func))($3);} + { + if (!$1.symbol->create_func) + { + net_printf(Lex->thd, ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + $1.symbol->group->name, + $1.symbol->group->needed_define); + YYABORT; + } + $$= ((Item*(*)(Item*))($1.symbol->create_func))($3); + } | FUNC_ARG2 '(' expr ',' expr ')' - { $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5);} + { + if (!$1.symbol->create_func) + { + net_printf(Lex->thd, ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + $1.symbol->group->name, + $1.symbol->group->needed_define); + YYABORT; + } + $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5); + } | FUNC_ARG3 '(' expr ',' expr ',' expr ')' - { $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7);} + { + if (!$1.symbol->create_func) + { + net_printf(Lex->thd, ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + $1.symbol->group->name, + $1.symbol->group->needed_define); + YYABORT; + } + $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7); + } | ADDDATE_SYM '(' expr ',' expr ')' { $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 0);} | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' @@ -3708,18 +3772,17 @@ simple_expr: } | FIELD_FUNC '(' expr ',' expr_list ')' { $5->push_front($3); $$= new Item_func_field(*$5); } - | GEOMFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3); } - | GEOMFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3, $5); } - | GEOMFROMWKB '(' expr ')' - { $$= new Item_func_geometry_from_wkb($3); } - | GEOMFROMWKB '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_wkb($3, $5); } - | GEOMETRYCOLLECTION '(' expr_list ')' - { $$= new Item_func_spatial_collection(* $3, - Geometry::wkbGeometryCollection, - Geometry::wkbPoint); } + | geometry_function + { +#ifdef HAVE_SPATIAL + $$= $1; +#else + net_printf(Lex->thd, ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + sym_group_geom.name, sym_group_geom.needed_define); + YYABORT; +#endif + } | GET_FORMAT '(' date_time_type ',' expr ')' { $$= new Item_func_get_format($3, $5); } | HOUR_SYM '(' expr ')' @@ -3753,17 +3816,10 @@ simple_expr: } | LEFT '(' expr ',' expr ')' { $$= new Item_func_left($3,$5); } - | LINESTRING '(' expr_list ')' - { $$= new Item_func_spatial_collection(* $3, - Geometry::wkbLineString, Geometry::wkbPoint); } | LOCATE '(' expr ',' expr ')' { $$= new Item_func_locate($5,$3); } | LOCATE '(' expr ',' expr ',' expr ')' { $$= new Item_func_locate($5,$3,$7); } - | GEOMCOLLFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3); } - | GEOMCOLLFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3, $5); } | GREATEST_SYM '(' expr ',' expr_list ')' { $5->push_front($3); $$= new Item_func_max(*$5); } | LEAST_SYM '(' expr ',' expr_list ')' @@ -3772,10 +3828,6 @@ simple_expr: { $$= new Item_func_log($3); } | LOG_SYM '(' expr ',' expr ')' { $$= new Item_func_log($3, $5); } - | LINEFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3); } - | LINEFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3, $5); } | MASTER_POS_WAIT '(' expr ',' expr ')' { $$= new Item_master_pos_wait($3, $5); @@ -3794,27 +3846,6 @@ simple_expr: { $$ = new Item_func_mod( $3, $5); } | MONTH_SYM '(' expr ')' { $$= new Item_func_month($3); } - | MULTILINESTRING '(' expr_list ')' - { $$= new Item_func_spatial_collection(* $3, - Geometry::wkbMultiLineString, Geometry::wkbLineString); } - | MLINEFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3); } - | MLINEFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3, $5); } - | MPOINTFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3); } - | MPOINTFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3, $5); } - | MPOLYFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3); } - | MPOLYFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3, $5); } - | MULTIPOINT '(' expr_list ')' - { $$= new Item_func_spatial_collection(* $3, - Geometry::wkbMultiPoint, Geometry::wkbPoint); } - | MULTIPOLYGON '(' expr_list ')' - { $$= new Item_func_spatial_collection(* $3, - Geometry::wkbMultiPolygon, Geometry::wkbPolygon ); } | NOW_SYM optional_braces { $$= new Item_func_now_local(); Lex->safe_to_cache_query=0;} | NOW_SYM '(' expr ')' @@ -3827,19 +3858,6 @@ simple_expr: } | OLD_PASSWORD '(' expr ')' { $$= new Item_func_old_password($3); } - | POINT_SYM '(' expr ',' expr ')' - { $$= new Item_func_point($3,$5); } - | POINTFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3); } - | POINTFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3, $5); } - | POLYFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3); } - | POLYFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3, $5); } - | POLYGON '(' expr_list ')' - { $$= new Item_func_spatial_collection(* $3, - Geometry::wkbPolygon, Geometry::wkbLineString); } | POSITION_SYM '(' no_in_expr IN_SYM expr ')' { $$ = new Item_func_locate($5,$3); } | QUARTER_SYM '(' expr ')' @@ -3991,6 +4009,66 @@ simple_expr: | EXTRACT_SYM '(' interval FROM expr ')' { $$=new Item_extract( $3, $5); }; +geometry_function: + GEOMFROMTEXT '(' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3)); } + | GEOMFROMTEXT '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); } + | GEOMFROMWKB '(' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_wkb($3)); } + | GEOMFROMWKB '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_wkb($3, $5)); } + | GEOMETRYCOLLECTION '(' expr_list ')' + { $$= GEOM_NEW(Item_func_spatial_collection(* $3, + Geometry::wkbGeometryCollection, + Geometry::wkbPoint)); } + | LINESTRING '(' expr_list ')' + { $$= GEOM_NEW(Item_func_spatial_collection(* $3, + Geometry::wkbLineString, Geometry::wkbPoint)); } + | MULTILINESTRING '(' expr_list ')' + { $$= GEOM_NEW( Item_func_spatial_collection(* $3, + Geometry::wkbMultiLineString, Geometry::wkbLineString)); } + | MLINEFROMTEXT '(' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3)); } + | MLINEFROMTEXT '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); } + | MPOINTFROMTEXT '(' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3)); } + | MPOINTFROMTEXT '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); } + | MPOLYFROMTEXT '(' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3)); } + | MPOLYFROMTEXT '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); } + | MULTIPOINT '(' expr_list ')' + { $$= GEOM_NEW(Item_func_spatial_collection(* $3, + Geometry::wkbMultiPoint, Geometry::wkbPoint)); } + | MULTIPOLYGON '(' expr_list ')' + { $$= GEOM_NEW(Item_func_spatial_collection(* $3, + Geometry::wkbMultiPolygon, Geometry::wkbPolygon)); } + | POINT_SYM '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_point($3,$5)); } + | POINTFROMTEXT '(' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3)); } + | POINTFROMTEXT '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); } + | POLYFROMTEXT '(' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3)); } + | POLYFROMTEXT '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); } + | POLYGON '(' expr_list ')' + { $$= GEOM_NEW(Item_func_spatial_collection(* $3, + Geometry::wkbPolygon, Geometry::wkbLineString)); } + | GEOMCOLLFROMTEXT '(' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3)); } + | GEOMCOLLFROMTEXT '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); } + | LINEFROMTEXT '(' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3)); } + | LINEFROMTEXT '(' expr ',' expr ')' + { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); } + ; + fulltext_options: /* nothing */ { $$= FT_NL; } | WITH QUERY_SYM EXPANSION_SYM { $$= FT_NL | FT_EXPAND; } @@ -4101,7 +4179,7 @@ opt_gorder_clause: | order_clause { LEX *lex=Lex; - lex->gorder_list= + lex->gorder_list= (SQL_LIST*) sql_memdup((char*) &lex->current_select->order_list, sizeof(st_sql_list)); lex->current_select->order_list.empty(); @@ -4124,25 +4202,17 @@ in_sum_expr: $$= $3; }; -cast_type_init: - { Lex->charset= NULL; Lex->length= (char*)0; } - ; - -cast_type_finalize: - BINARY { $$=ITEM_CAST_BINARY; } +cast_type: + BINARY { $$=ITEM_CAST_BINARY; Lex->charset= NULL; Lex->length= (char*)0; } | CHAR_SYM opt_len opt_binary { $$=ITEM_CAST_CHAR; } | NCHAR_SYM opt_len { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; } - | SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; } - | SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; } - | UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; } - | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; } - | DATE_SYM { $$=ITEM_CAST_DATE; } - | TIME_SYM { $$=ITEM_CAST_TIME; } - | DATETIME { $$=ITEM_CAST_DATETIME; } - ; - -cast_type: - cast_type_init cast_type_finalize { $$= $2; } + | SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->length= (char*)0; } + | SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->length= (char*)0; } + | UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->length= (char*)0; } + | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->length= (char*)0; } + | DATE_SYM { $$=ITEM_CAST_DATE; Lex->charset= NULL; Lex->length= (char*)0; } + | TIME_SYM { $$=ITEM_CAST_TIME; Lex->charset= NULL; Lex->length= (char*)0; } + | DATETIME { $$=ITEM_CAST_DATETIME; Lex->charset= NULL; Lex->length= (char*)0; } ; expr_list: @@ -4276,13 +4346,6 @@ join_table: | '(' SELECT_SYM select_derived ')' opt_table_alias { LEX *lex=Lex; - if (lex->sql_command == SQLCOM_UPDATE && - &lex->select_lex == lex->current_select->outer_select()) - { - send_error(lex->thd, ER_SYNTAX_ERROR); - YYABORT; - } - SELECT_LEX_UNIT *unit= lex->current_select->master_unit(); lex->current_select= unit->outer_select(); if (!($$= lex->current_select-> @@ -4984,6 +5047,7 @@ update: LEX *lex= Lex; mysql_init_select(lex); lex->sql_command= SQLCOM_UPDATE; + lex->lock_option= TL_UNLOCK; /* Will be set later */ } opt_low_priority opt_ignore join_table_list SET update_list where_clause opt_order_clause delete_limit_clause @@ -4992,6 +5056,13 @@ update: Select->set_lock_for_tables($3); if (lex->select_lex.table_list.elements > 1) lex->sql_command= SQLCOM_UPDATE_MULTI; + else if (lex->select_lex.get_table_list()->derived) + { + /* it is single table update and it is update of derived table */ + net_printf(lex->thd, ER_NON_UPDATABLE_TABLE, + lex->select_lex.get_table_list()->alias, "UPDATE"); + YYABORT; + } } ; @@ -5679,9 +5750,9 @@ simple_ident: $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,NullS,$1.str) : - (Item*) new Item_ref(NullS,NullS,$1.str); + (Item*) new Item_ref(0,0, NullS,NullS,$1.str); } - } + } | simple_ident_q { $$= $1; } ; @@ -5692,7 +5763,7 @@ simple_ident_nospvar: $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,NullS,$1.str) : - (Item*) new Item_ref(NullS,NullS,$1.str); + (Item*) new Item_ref(0,0,NullS,NullS,$1.str); } | simple_ident_q { $$= $1; } ; @@ -5712,7 +5783,7 @@ simple_ident_q: $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,$1.str,$3.str) : - (Item*) new Item_ref(NullS,$1.str,$3.str); + (Item*) new Item_ref(0,0,NullS,$1.str,$3.str); } | '.' ident '.' ident { @@ -5728,7 +5799,7 @@ simple_ident_q: $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,$2.str,$4.str) : - (Item*) new Item_ref(NullS,$2.str,$4.str); + (Item*) new Item_ref(0,0,NullS,$2.str,$4.str); } | ident '.' ident '.' ident { @@ -5746,8 +5817,8 @@ simple_ident_q: (Item*) new Item_field((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS : $1.str), $3.str, $5.str) : - (Item*) new Item_ref((YYTHD->client_capabilities & - CLIENT_NO_SCHEMA ? NullS : $1.str), + (Item*) new Item_ref(0,0,(YYTHD->client_capabilities & + CLIENT_NO_SCHEMA ? NullS : $1.str), $3.str, $5.str); }; diff --git a/sql/table.cc b/sql/table.cc index 912c133e571..8fe061af530 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -405,8 +405,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, // charset and geometry_type share the same byte in frm if (field_type == FIELD_TYPE_GEOMETRY) { +#ifdef HAVE_SPATIAL geom_type= (Field::geometry_type) strpos[14]; charset= &my_charset_bin; +#else + error= 4; // unsupported field type + goto err_not_open; +#endif } else { @@ -481,8 +486,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, /* Fix key->name and key_part->field */ if (key_parts) { - uint primary_key=(uint) (find_type((char*) "PRIMARY",&outparam->keynames, - 3)-1); + uint primary_key=(uint) (find_type((char*) primary_key_name, + &outparam->keynames, 3) - 1); uint ha_option=outparam->file->table_flags(); keyinfo=outparam->key_info; key_part=keyinfo->key_part; diff --git a/sql/unireg.cc b/sql/unireg.cc index fc948ddd5a6..6ebba313442 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -471,7 +471,12 @@ static bool pack_fields(File file,List<create_field> &create_fields) buff[12]= (uchar) field->interval_id; buff[13]= (uchar) field->sql_type; if (field->sql_type == FIELD_TYPE_GEOMETRY) + { buff[14]= (uchar) field->geom_type; +#ifndef HAVE_SPATIAL + DBUG_ASSERT(0); // Should newer happen +#endif + } else if (field->charset) buff[14]= (uchar) field->charset->number; else diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 85f066c4eba..574156a99ed 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -377,7 +377,7 @@ static my_bool my_like_range_big5(CHARSET_INFO *cs __attribute__((unused)), *min_length= (uint) (min_str-min_org); *max_length= res_length; do { - *min_str++ = '\0'; /* Because if key compression */ + *min_str++ = ' '; /* Because if key compression */ *max_str++ = max_sort_char; } while (min_str != min_end); return 0; @@ -6245,6 +6245,7 @@ static MY_CHARSET_HANDLER my_charset_big5_handler= mbcharlen_big5, my_numchars_mb, my_charpos_mb, + my_wellformedlen_mb, my_lengthsp_8bit, my_mb_wc_big5, /* mb_wc */ my_wc_mb_big5, /* wc_mb */ @@ -6281,6 +6282,7 @@ CHARSET_INFO my_charset_big5_chinese_ci= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_big5_handler, @@ -6304,6 +6306,7 @@ CHARSET_INFO my_charset_big5_bin= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_big5_handler, diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 6f28c43b2c6..fc22938d46e 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -294,7 +294,7 @@ uint my_instr_bin(CHARSET_INFO *cs __attribute__((unused)), end= (const uchar*) b+b_length-s_length+1; search_end= (const uchar*) s + s_length; -skipp: +skip: while (str != end) { if ( (*str++) == (*search)) @@ -306,7 +306,7 @@ skipp: while (j != search_end) if ((*i++) != (*j++)) - goto skipp; + goto skip; if (nmatch > 0) { @@ -347,6 +347,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_mbcharlen_8bit, /* mbcharlen */ my_numchars_8bit, my_charpos_8bit, + my_wellformedlen_8bit, my_lengthsp_8bit, my_mb_wc_bin, my_wc_mb_bin, @@ -381,6 +382,7 @@ CHARSET_INFO my_charset_bin = NULL, /* tab_from_uni */ "","", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 1, /* mbmaxlen */ (char) 255, /* max_sort_char */ &my_charset_handler, diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index b2e4f1886ed..1a07a5eba7e 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -631,6 +631,7 @@ CHARSET_INFO my_charset_latin2_czech_ci = idx_uni_8859_2, /* tab_from_uni */ "","", 4, /* strxfrm_multiply */ + 1, /* mbminlen */ 1, /* mbmaxlen */ 0, &my_charset_8bit_handler, diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index addd7803680..278e8529e83 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8653,6 +8653,7 @@ static MY_CHARSET_HANDLER my_charset_handler= mbcharlen_euc_kr, my_numchars_mb, my_charpos_mb, + my_wellformedlen_mb, my_lengthsp_8bit, my_mb_wc_euc_kr, /* mb_wc */ my_wc_mb_euc_kr, /* wc_mb */ @@ -8689,6 +8690,7 @@ CHARSET_INFO my_charset_euckr_korean_ci= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_handler, @@ -8712,6 +8714,7 @@ CHARSET_INFO my_charset_euckr_bin= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-extra.c b/strings/ctype-extra.c index 55bfa09ea5f..0085d264416 100644 --- a/strings/ctype-extra.c +++ b/strings/ctype-extra.c @@ -34,6 +34,7 @@ CHARSET_INFO compiled_charsets[] = { 0, 0, 0, + 0, NULL, NULL } diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index b84ddc9081b..722f00f0f7a 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5704,6 +5704,7 @@ static MY_CHARSET_HANDLER my_charset_handler= mbcharlen_gb2312, my_numchars_mb, my_charpos_mb, + my_wellformedlen_mb, my_lengthsp_8bit, my_mb_wc_gb2312, /* mb_wc */ my_wc_mb_gb2312, /* wc_mb */ @@ -5740,6 +5741,7 @@ CHARSET_INFO my_charset_gb2312_chinese_ci= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_handler, @@ -5762,6 +5764,7 @@ CHARSET_INFO my_charset_gb2312_bin= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 585dc66be4c..9e71a18e531 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9900,6 +9900,7 @@ static MY_CHARSET_HANDLER my_charset_handler= mbcharlen_gbk, my_numchars_mb, my_charpos_mb, + my_wellformedlen_mb, my_lengthsp_8bit, my_mb_wc_gbk, my_wc_mb_gbk, @@ -9936,6 +9937,7 @@ CHARSET_INFO my_charset_gbk_chinese_ci= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_handler, @@ -9958,6 +9960,7 @@ CHARSET_INFO my_charset_gbk_bin= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index 15798abb85b..933737b5f61 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -180,6 +180,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_mbcharlen_8bit, my_numchars_8bit, my_charpos_8bit, + my_wellformedlen_8bit, my_lengthsp_8bit, my_mb_wc_latin1, my_wc_mb_latin1, @@ -215,6 +216,7 @@ CHARSET_INFO my_charset_latin1= NULL, /* tab_from_uni */ "","", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 1, /* mbmaxlen */ 0, &my_charset_handler, @@ -410,6 +412,7 @@ CHARSET_INFO my_charset_latin1_german2_ci= NULL, /* tab_from_uni */ "","", 2, /* strxfrm_multiply */ + 1, /* mbminlen */ 1, /* mbmaxlen */ 0, &my_charset_handler, @@ -433,6 +436,7 @@ CHARSET_INFO my_charset_latin1_bin= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 1, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 271c56b8a0a..46f3e2f4fc3 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -271,9 +271,28 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1; pos--; } - return b-b0; + return pos ? e+2-b0 : b-b0; } +uint my_wellformedlen_mb(CHARSET_INFO *cs, + const char *b, const char *e, uint pos) +{ + my_wc_t wc; + int mblen; + const char *b0= b; + + while (pos) + { + if ((mblen= cs->cset->mb_wc(cs, &wc, b, e)) <0) + break; + b+= mblen; + pos--; + } + return b - b0; +} + + + uint my_instr_mb(CHARSET_INFO *cs, const char *b, uint b_length, const char *s, uint s_length, diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 6f77d6f3e16..233251e16a8 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1020,6 +1020,15 @@ uint my_charpos_8bit(CHARSET_INFO *cs __attribute__((unused)), return pos; } +uint my_wellformedlen_8bit(CHARSET_INFO *cs __attribute__((unused)), + const char *start, + const char *end, + uint nchars) +{ + uint nbytes= (uint) (end-start); + return nbytes < nchars ? nbytes : nchars; +} + uint my_lengthsp_8bit(CHARSET_INFO *cs __attribute__((unused)), const char *ptr, uint length) { @@ -1055,7 +1064,7 @@ uint my_instr_simple(CHARSET_INFO *cs, end= (const uchar*) b+b_length-s_length+1; search_end= (const uchar*) s + s_length; -skipp: +skip: while (str != end) { if (cs->sort_order[*str++] == cs->sort_order[*search]) @@ -1067,7 +1076,7 @@ skipp: while (j != search_end) if (cs->sort_order[*i++] != cs->sort_order[*j++]) - goto skipp; + goto skip; if (nmatch > 0) { @@ -1096,6 +1105,7 @@ MY_CHARSET_HANDLER my_charset_8bit_handler= my_mbcharlen_8bit, /* mbcharlen */ my_numchars_8bit, my_charpos_8bit, + my_wellformedlen_8bit, my_lengthsp_8bit, my_mb_wc_8bit, my_wc_mb_8bit, diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index a84fbd16e5d..feff0fff227 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4489,6 +4489,7 @@ static MY_CHARSET_HANDLER my_charset_handler= mbcharlen_sjis, my_numchars_mb, my_charpos_mb, + my_wellformedlen_mb, my_lengthsp_8bit, my_mb_wc_sjis, /* mb_wc */ my_wc_mb_sjis, /* wc_mb */ @@ -4525,6 +4526,7 @@ CHARSET_INFO my_charset_sjis_japanese_ci= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_handler, @@ -4547,6 +4549,7 @@ CHARSET_INFO my_charset_sjis_bin= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index a2edc33b3d2..d577b964405 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -701,6 +701,207 @@ void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length) } #endif /* NOT_NEEDED */ +static unsigned short cs_to_uni[256]={ +0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, +0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, +0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, +0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F, +0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027, +0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F, +0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037, +0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F, +0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047, +0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F, +0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057, +0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F, +0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067, +0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F, +0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, +0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, +0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087, +0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F, +0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097, +0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F, +0xFFFD,0x0E01,0x0E02,0x0E03,0x0E04,0x0E05,0x0E06,0x0E07, +0x0E08,0x0E09,0x0E0A,0x0E0B,0x0E0C,0x0E0D,0x0E0E,0x0E0F, +0x0E10,0x0E11,0x0E12,0x0E13,0x0E14,0x0E15,0x0E16,0x0E17, +0x0E18,0x0E19,0x0E1A,0x0E1B,0x0E1C,0x0E1D,0x0E1E,0x0E1F, +0x0E20,0x0E21,0x0E22,0x0E23,0x0E24,0x0E25,0x0E26,0x0E27, +0x0E28,0x0E29,0x0E2A,0x0E2B,0x0E2C,0x0E2D,0x0E2E,0x0E2F, +0x0E30,0x0E31,0x0E32,0x0E33,0x0E34,0x0E35,0x0E36,0x0E37, +0x0E38,0x0E39,0x0E3A,0xFFFD,0xFFFD,0xFFFD,0xFFFD,0x0E3F, +0x0E40,0x0E41,0x0E42,0x0E43,0x0E44,0x0E45,0x0E46,0x0E47, +0x0E48,0x0E49,0x0E4A,0x0E4B,0x0E4C,0x0E4D,0x0E4E,0x0E4F, +0x0E50,0x0E51,0x0E52,0x0E53,0x0E54,0x0E55,0x0E56,0x0E57, +0x0E58,0x0E59,0x0E5A,0x0E5B,0xFFFD,0xFFFD,0xFFFD,0xFFFD +}; +static unsigned char pl00[256]={ +0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, +0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, +0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, +0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F, +0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027, +0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F, +0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037, +0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F, +0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047, +0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F, +0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057, +0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F, +0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067, +0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F, +0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, +0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, +0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087, +0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F, +0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097, +0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 +}; +static unsigned char pl0E[256]={ +0x0000,0x00A1,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7, +0x00A8,0x00A9,0x00AA,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF, +0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7, +0x00B8,0x00B9,0x00BA,0x00BB,0x00BC,0x00BD,0x00BE,0x00BF, +0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x00C6,0x00C7, +0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,0x00CD,0x00CE,0x00CF, +0x00D0,0x00D1,0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D7, +0x00D8,0x00D9,0x00DA,0x0000,0x0000,0x0000,0x0000,0x00DF, +0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x00E6,0x00E7, +0x00E8,0x00E9,0x00EA,0x00EB,0x00EC,0x00ED,0x00EE,0x00EF, +0x00F0,0x00F1,0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F7, +0x00F8,0x00F9,0x00FA,0x00FB,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 +}; +static unsigned char plFF[256]={ +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, +0x0000,0x0000,0x0000,0x0000,0x0000,0x00FF,0x0000,0x0000 +}; +static unsigned char *uni_to_cs[256]={ +pl00,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,pl0E,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +NULL,NULL,NULL,NULL,NULL,NULL,NULL,plFF +}; + + +static +int my_mb_wc_tis620(CHARSET_INFO *cs __attribute__((unused)), + my_wc_t *wc, + const unsigned char *str, + const unsigned char *end __attribute__((unused))) +{ + if (str >= end) + return MY_CS_TOOFEW(0); + + *wc=cs_to_uni[*str]; + return (!wc[0] && str[0]) ? MY_CS_ILSEQ : 1; +} + +static +int my_wc_mb_tis620(CHARSET_INFO *cs __attribute__((unused)), + my_wc_t wc, + unsigned char *str, + unsigned char *end __attribute__((unused))) +{ + unsigned char *pl; + + if (str >= end) + return MY_CS_TOOSMALL; + + pl= uni_to_cs[(wc>>8) & 0xFF]; + str[0]= pl ? pl[wc & 0xFF] : '\0'; + return (!str[0] && wc) ? MY_CS_ILUNI : 1; +} + static MY_COLLATION_HANDLER my_collation_ci_handler = { @@ -720,9 +921,10 @@ static MY_CHARSET_HANDLER my_charset_handler= my_mbcharlen_8bit, /* mbcharlen */ my_numchars_8bit, my_charpos_8bit, + my_wellformedlen_8bit, my_lengthsp_8bit, - my_mb_wc_8bit, /* mb_wc */ - my_wc_mb_8bit, /* wc_mb */ + my_mb_wc_tis620, /* mb_wc */ + my_wc_mb_tis620, /* wc_mb */ my_caseup_str_8bit, my_casedn_str_8bit, my_caseup_8bit, @@ -757,6 +959,7 @@ CHARSET_INFO my_charset_tis620_thai_ci= "", "", 4, /* strxfrm_multiply */ + 1, /* mbminlen */ 1, /* mbmaxlen */ 0, &my_charset_handler, @@ -779,6 +982,7 @@ CHARSET_INFO my_charset_tis620_bin= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 1, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index beb803a69f2..bb74e0cf56b 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1002,6 +1002,17 @@ uint my_charpos_ucs2(CHARSET_INFO *cs __attribute__((unused)), } static +uint my_wellformedlen_ucs2(CHARSET_INFO *cs __attribute__((unused)), + const char *b, + const char *e, + uint nchars) +{ + uint nbytes= (e-b) & ~ (uint)1; + nchars*= 2; + return nbytes < nchars ? nbytes : nchars; +} + +static void my_fill_ucs2(CHARSET_INFO *cs __attribute__((unused)), char *s, uint l, int fill) { @@ -1044,14 +1055,13 @@ int my_wildcmp_ucs2(CHARSET_INFO *cs, scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); if (scan <= 0) return 1; - wildstr+= scan; if (w_wc == (my_wc_t)escape) { + wildstr+= scan; scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); if (scan <= 0) return 1; - wildstr+= scan; } if (w_wc == (my_wc_t)w_many) @@ -1060,6 +1070,7 @@ int my_wildcmp_ucs2(CHARSET_INFO *cs, break; } + wildstr+= scan; scan= my_ucs2_uni(cs, &s_wc, (const uchar*)str, (const uchar*)str_end); if (scan <=0) return 1; @@ -1095,13 +1106,16 @@ int my_wildcmp_ucs2(CHARSET_INFO *cs, scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); if (scan <= 0) return 1; - wildstr+= scan; if (w_wc == (my_wc_t)w_many) + { + wildstr+= scan; continue; + } if (w_wc == (my_wc_t)w_one) { + wildstr+= scan; scan= my_ucs2_uni(cs, &s_wc, (const uchar*)str, (const uchar*)str_end); if (scan <=0) return 1; @@ -1120,17 +1134,16 @@ int my_wildcmp_ucs2(CHARSET_INFO *cs, scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); if (scan <= 0) return 1; - wildstr+= scan; if (w_wc == (my_wc_t)escape) { + wildstr+= scan; scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); if (scan <= 0) return 1; - wildstr+= scan; } - do + while (1) { /* Skip until the first character from wildstr is found */ while (str != str_end) @@ -1138,8 +1151,6 @@ int my_wildcmp_ucs2(CHARSET_INFO *cs, scan= my_ucs2_uni(cs,&s_wc, (const uchar*)str, (const uchar*)str_end); if (scan <= 0) return 1; - str+= scan; - if (weights) { plane=(s_wc>>8) & 0xFF; @@ -1150,17 +1161,19 @@ int my_wildcmp_ucs2(CHARSET_INFO *cs, if (s_wc == w_wc) break; + str+= scan; } if (str == str_end) return -1; result= my_wildcmp_ucs2(cs,str,str_end,wildstr,wildend,escape, w_one,w_many,weights); + if (result <= 0) return result; - } while (str != str_end && w_wc != (my_wc_t)w_many); - return -1; + str+= scan; + } } } return (str != str_end ? 1 : 0); @@ -1285,6 +1298,7 @@ static MY_CHARSET_HANDLER my_charset_ucs2_handler= my_mbcharlen_ucs2, /* mbcharlen */ my_numchars_ucs2, my_charpos_ucs2, + my_wellformedlen_ucs2, my_lengthsp_ucs2, my_ucs2_uni, /* mb_wc */ my_uni_ucs2, /* wc_mb */ @@ -1322,6 +1336,7 @@ CHARSET_INFO my_charset_ucs2_general_ci= "", "", 1, /* strxfrm_multiply */ + 2, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_ucs2_handler, @@ -1345,6 +1360,7 @@ CHARSET_INFO my_charset_ucs2_bin= "", "", 1, /* strxfrm_multiply */ + 2, /* mbminlen */ 2, /* mbmaxlen */ 0, &my_charset_ucs2_handler, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 2815b70351b..f27ddcf3e30 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8444,6 +8444,7 @@ static MY_CHARSET_HANDLER my_charset_handler= mbcharlen_ujis, my_numchars_mb, my_charpos_mb, + my_wellformedlen_mb, my_lengthsp_8bit, my_mb_wc_euc_jp, /* mb_wc */ my_wc_mb_euc_jp, /* wc_mb */ @@ -8480,6 +8481,7 @@ CHARSET_INFO my_charset_ujis_japanese_ci= NULL, /* tab_from_uni */ "","", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 3, /* mbmaxlen */ 0, &my_charset_handler, @@ -8502,6 +8504,7 @@ CHARSET_INFO my_charset_ujis_bin= NULL, /* tab_from_uni */ "","", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 3, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index b5716c53ea2..ef9719bf040 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1969,6 +1969,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_mbcharlen_utf8, my_numchars_mb, my_charpos_mb, + my_wellformedlen_mb, my_lengthsp_8bit, my_utf8_uni, my_uni_utf8, @@ -2006,6 +2007,7 @@ CHARSET_INFO my_charset_utf8_general_ci= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 3, /* mbmaxlen */ 0, &my_charset_handler, @@ -2029,6 +2031,7 @@ CHARSET_INFO my_charset_utf8_bin= "", "", 1, /* strxfrm_multiply */ + 1, /* mbminlen */ 3, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 60a5737009f..d3b5c9d1796 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -671,6 +671,7 @@ CHARSET_INFO my_charset_cp1250_czech_ci = idx_uni_cp1250, /* tab_from_uni */ "","", 2, /* strxfrm_multiply */ + 1, /* mbminlen */ 1, /* mbmaxlen */ 0, &my_charset_8bit_handler, diff --git a/strings/dump_map.c b/strings/dump_map.c new file mode 100644 index 00000000000..f999160d0d4 --- /dev/null +++ b/strings/dump_map.c @@ -0,0 +1,72 @@ +#include <stdio.h> +#include <string.h> + +static void print_short_array(unsigned short *a) +{ + int i; + printf("{\n"); + for (i=0; i<=0xFF; i++) + { + printf("0x%04X%s%s",(int)a[i],i<0xFF?",":"",(i+1) % 8 ? "" :"\n"); + } + printf("};\n"); + +} + + + +int main(void) +{ + char str[160]; + unsigned short touni[256]; + unsigned short fromuni[65536]; + unsigned short fromstat[256]; + int i; + + bzero((void*)touni,sizeof(touni)); + bzero((void*)fromuni,sizeof(fromuni)); + bzero((void*)fromstat,sizeof(fromstat)); + + while (fgets(str,sizeof(str),stdin)) + { + unsigned int c,u; + + if ((str[0]=='#') || (2!=sscanf(str,"%x%x",&c,&u))) + continue; + if (c>0xFF || u>0xFFFF) + continue; + + touni[c]= u; + fromuni[u]= c; + } + + printf("unsigned short cs_to_uni[256]="); + print_short_array(touni); + + for (i=0;i<=0xFF;i++) + { + fromstat[touni[i]>>8]++; + } + + for (i=0;i<=256;i++) + { + if (fromstat[i]) + { + printf("unsigned char pl%02X[256]=",i); + print_short_array(fromuni+i*256); + } + } + + printf("unsigned short *uni_to_cs[256]={\n"); + for (i=0;i<=255;i++) + { + if (fromstat[i]) + printf("pl%02X",i); + else + printf("NULL"); + printf("%s%s",i<255?",":"",((i+1) % 8) ? "":"\n"); + } + printf("};\n"); + + return 0; +} diff --git a/strings/r_strinstr.c b/strings/r_strinstr.c index 76d310a3fda..fdd6e010a22 100644 --- a/strings/r_strinstr.c +++ b/strings/r_strinstr.c @@ -35,7 +35,7 @@ uint r_strinstr(reg1 my_string str,int from, reg4 my_string search) /* pointer to the last char of search */ my_string search_end = search + len - 1; - skipp: + skip: while (start >= str) /* Cant be != because the first char */ { if (*start-- == *search_end) @@ -43,7 +43,7 @@ uint r_strinstr(reg1 my_string str,int from, reg4 my_string search) i = start; j = search_end - 1; while (j >= search && start > str) if (*i-- != *j--) - goto skipp; + goto skip; return (uint) ((start - len) - str + 3); } } diff --git a/strings/strinstr.c b/strings/strinstr.c index 1c814d19d47..457581af950 100644 --- a/strings/strinstr.c +++ b/strings/strinstr.c @@ -34,14 +34,14 @@ uint strinstr(reg1 const char *str,reg4 const char *search) reg2 my_string i,j; my_string start = (my_string) str; - skipp: + skip: while (*str != '\0') { if (*str++ == *search) { i=(my_string) str; j= (my_string) search+1; while (*j) - if (*i++ != *j++) goto skipp; + if (*i++ != *j++) goto skip; return ((uint) (str - start)); } } diff --git a/strings/strstr.c b/strings/strstr.c index ca845568ddb..bd65ef654b1 100644 --- a/strings/strstr.c +++ b/strings/strstr.c @@ -37,12 +37,12 @@ char *strstr(register const char *str,const char *search) register char *i,*j; register char first= *search; -skipp: +skip: while (*str != '\0') { if (*str++ == first) { i=(char*) str; j=(char*) search+1; while (*j) - if (*i++ != *j++) goto skipp; + if (*i++ != *j++) goto skip; return ((char*) str-1); } } diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh index 18e926b1400..ba92856df0e 100644 --- a/support-files/my-huge.cnf.sh +++ b/support-files/my-huge.cnf.sh @@ -10,8 +10,8 @@ # ~/.my.cnf to set user-specific options. # # One can in this file use all long options that the program supports. -# If you want to know which options a program support, run the program -# with --help option. +# If you want to know which options a program supports, run the program +# with the --help option. # The following options will be passed to all MySQL clients [client] diff --git a/support-files/my-innodb-heavy-4G.cnf.sh b/support-files/my-innodb-heavy-4G.cnf.sh index ed2c2ce9dfd..9c772269749 100644 --- a/support-files/my-innodb-heavy-4G.cnf.sh +++ b/support-files/my-innodb-heavy-4G.cnf.sh @@ -317,7 +317,7 @@ key_buffer_size = 32M read_buffer_size = 2M # When reading rows in sorted order after a sort, the rows are read -# through this buffer to avoid a disk seeks. You can improve ORDER BY +# through this buffer to avoid disk seeks. You can improve ORDER BY # performance a lot, if set this to a high value. # Allocated per thread, when needed. read_rnd_buffer_size = 16M @@ -331,7 +331,7 @@ read_rnd_buffer_size = 16M bulk_insert_buffer_size = 64M # This buffer is allocated when MySQL needs to rebuild the index in -# REPAIR, OPTIMZE, ALTER table statements as well as in LOAD DATA INFILE +# REPAIR, OPTIMIZE, ALTER table statements as well as in LOAD DATA INFILE # into an empty table. It is allocated per thread so be careful with # large settings. myisam_sort_buffer_size = 128M diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh index 2b92dc61053..ba865a5bfd0 100644 --- a/support-files/my-large.cnf.sh +++ b/support-files/my-large.cnf.sh @@ -10,8 +10,8 @@ # ~/.my.cnf to set user-specific options. # # One can in this file use all long options that the program supports. -# If you want to know which options a program support, run the program -# with --help option. +# If you want to know which options a program supports, run the program +# with the --help option. # The following options will be passed to all MySQL clients [client] diff --git a/support-files/my-medium.cnf.sh b/support-files/my-medium.cnf.sh index 601ffc503c0..d4ae0061a95 100644 --- a/support-files/my-medium.cnf.sh +++ b/support-files/my-medium.cnf.sh @@ -11,8 +11,8 @@ # ~/.my.cnf to set user-specific options. # # One can in this file use all long options that the program supports. -# If you want to know which options a program support, run the program -# with --help option. +# If you want to know which options a program supports, run the program +# with the --help option. # The following options will be passed to all MySQL clients [client] diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh index 3c4cafa688f..ca26a10a397 100644 --- a/support-files/my-small.cnf.sh +++ b/support-files/my-small.cnf.sh @@ -11,8 +11,8 @@ # ~/.my.cnf to set user-specific options. # # One can in this file use all long options that the program supports. -# If you want to know which options a program support, run the program -# with --help option. +# If you want to know which options a program supports, run the program +# with the --help option. # The following options will be passed to all MySQL clients [client] diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 5a9fbf64b1c..1ee88096def 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -220,7 +220,8 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --includedir=%{_includedir} \ --mandir=%{_mandir} \ --enable-thread-safe-client \ - --with-comment=\"Official MySQL RPM\"; + --with-comment=\"Official MySQL RPM\" \ + --with-readline ; # Add this for more debugging support # --with-debug # Add this for MyISAM RAID support: @@ -574,6 +575,10 @@ fi # The spec file changelog only includes changes made to the spec file # itself %changelog +* Tue Jan 13 2004 Lenz Grimmer <lenz@mysql.com> + +- link the mysql client against libreadline instead of libedit (BUG 2289) + * Fri Dec 13 2003 Lenz Grimmer <lenz@mysql.com> - fixed file permissions (BUG 1672) diff --git a/tests/client_test.c b/tests/client_test.c index b7ba580438f..6792652b708 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -153,6 +153,17 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg) else if (msg) fprintf(stderr, " [MySQL] %s\n", msg); } +/* + This is to be what mysql_query() is for mysql_real_query(), for + mysql_prepare(): a variant without the 'length' parameter. +*/ +MYSQL_STMT *STDCALL +mysql_simple_prepare(MYSQL *mysql, const char *query) +{ + return mysql_prepare(mysql, query, strlen(query)); +} + + /******************************************************** * connect to the server * *********************************************************/ @@ -459,14 +470,14 @@ uint my_process_stmt_result(MYSQL_STMT *stmt) /******************************************************** * process the stmt result set * *********************************************************/ -uint my_stmt_result(const char *buff, unsigned long length) +uint my_stmt_result(const char *buff) { MYSQL_STMT *stmt; uint row_count; int rc; fprintf(stdout,"\n\n %s", buff); - stmt= mysql_prepare(mysql,buff,length); + stmt= mysql_simple_prepare(mysql,buff); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -605,7 +616,7 @@ static void execute_prepare_query(const char *query, ulonglong exp_count) ulonglong affected_rows; int rc; - stmt= mysql_prepare(mysql,query,strlen(query)); + stmt= mysql_simple_prepare(mysql,query); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -913,7 +924,7 @@ static void test_prepare_simple() /* alter table */ strmov(query,"ALTER TABLE test_prepare_simple ADD new char(20)"); - stmt = mysql_prepare(mysql, query, 70); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,0); @@ -921,7 +932,7 @@ static void test_prepare_simple() /* insert */ strmov(query,"INSERT INTO test_prepare_simple VALUES(?,?)"); - stmt = mysql_prepare(mysql, query, 70); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -929,7 +940,7 @@ static void test_prepare_simple() /* update */ strmov(query,"UPDATE test_prepare_simple SET id=? WHERE id=? AND name= ?"); - stmt = mysql_prepare(mysql, query, 100); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,3); @@ -937,7 +948,7 @@ static void test_prepare_simple() /* delete */ strmov(query,"DELETE FROM test_prepare_simple WHERE id=10"); - stmt = mysql_prepare(mysql, query, 60); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,0); @@ -948,18 +959,16 @@ static void test_prepare_simple() /* delete */ strmov(query,"DELETE FROM test_prepare_simple WHERE id=?"); - stmt = mysql_prepare(mysql, query, 50); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,1); - rc = mysql_execute(stmt); - mystmt_r(stmt, rc); mysql_stmt_close(stmt); /* select */ strmov(query,"SELECT * FROM test_prepare_simple WHERE id=? AND name= ?"); - stmt = mysql_prepare(mysql, query, 100); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -997,7 +1006,7 @@ static void test_prepare_field_result() /* insert */ strmov(query,"SELECT int_c,var_c,date_c as date,ts_c,char_c FROM \ test_prepare_field_result as t1 WHERE int_c=?"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,1); @@ -1045,11 +1054,11 @@ static void test_prepare_syntax() myquery(rc); strmov(query,"INSERT INTO test_prepare_syntax VALUES(?"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init_r(stmt); strmov(query,"SELECT id,name FROM test_prepare_syntax WHERE id=? AND WHERE"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init_r(stmt); /* now fetch the results ..*/ @@ -1095,7 +1104,7 @@ static void test_prepare() /* insert by prepare */ strxmov(query,"INSERT INTO my_prepare VALUES(?,?,?,?,?,?,?)",NullS); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,7); @@ -1159,9 +1168,9 @@ static void test_prepare() myquery(rc); /* test the results now, only one row should exists */ - assert(tiny_data == (char) my_stmt_result("SELECT * FROM my_prepare",50)); + assert(tiny_data == (char) my_stmt_result("SELECT * FROM my_prepare")); - stmt = mysql_prepare(mysql,"SELECT * FROM my_prepare",50); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM my_prepare"); mystmt_init(stmt); rc = mysql_bind_result(stmt, bind); @@ -1266,7 +1275,7 @@ static void test_double_compare() myquery(rc); strmov(query, "UPDATE test_double_compare SET col1=100 WHERE col1 = ? AND col2 = ? AND COL3 = ?"); - stmt = mysql_prepare(mysql,query, strlen(query)); + stmt = mysql_simple_prepare(mysql,query); mystmt_init(stmt); verify_param_count(stmt,3); @@ -1347,11 +1356,11 @@ static void test_null() /* insert by prepare, wrong column name */ strmov(query,"INSERT INTO test_null(col3,col2) VALUES(?,?)"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init_r(stmt); strmov(query,"INSERT INTO test_null(col1,col2) VALUES(?,?)"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -1393,7 +1402,7 @@ static void test_null() myquery(rc); nData*= 2; - assert(nData == my_stmt_result("SELECT * FROM test_null", 30)); + assert(nData == my_stmt_result("SELECT * FROM test_null")); /* Fetch results */ bind[0].buffer_type= MYSQL_TYPE_LONG; @@ -1403,7 +1412,7 @@ static void test_null() bind[0].is_null= &is_null[0]; bind[1].is_null= &is_null[1]; - stmt = mysql_prepare(mysql,"SELECT * FROM test_null",30); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_null"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -1475,9 +1484,9 @@ static void test_fetch_null() strmov((char *)query , "SELECT * FROM test_fetch_null"); - assert(3 == my_stmt_result(query,50)); + assert(3 == my_stmt_result(query)); - stmt = mysql_prepare(mysql, query, 50); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); rc = mysql_bind_result(stmt,bind); @@ -1516,7 +1525,7 @@ static void test_select_version() myheader("test_select_version"); - stmt = mysql_prepare(mysql, "SELECT @@version", 30); + stmt = mysql_simple_prepare(mysql, "SELECT @@version"); mystmt_init(stmt); verify_param_count(stmt,0); @@ -1538,7 +1547,7 @@ static void test_select_simple() myheader("test_select_simple"); - stmt = mysql_prepare(mysql, "SHOW TABLES FROM mysql", 50); + stmt = mysql_simple_prepare(mysql, "SHOW TABLES FROM mysql"); mystmt_init(stmt); verify_param_count(stmt,0); @@ -1630,7 +1639,7 @@ static void test_select_prepare() rc = mysql_commit(mysql); myquery(rc); - stmt = mysql_prepare(mysql,"SELECT * FROM test_select",50); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_select"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -1660,7 +1669,7 @@ static void test_select_prepare() rc = mysql_commit(mysql); myquery(rc); - stmt = mysql_prepare(mysql,"SELECT * FROM test_select",25); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_select"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -1715,7 +1724,7 @@ static void test_select() myquery(rc); strmov(query,"SELECT * FROM test_select WHERE id=? AND name=?"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -1774,7 +1783,7 @@ session_id char(9) NOT NULL, \ myquery(rc); strmov(query,"SELECT * FROM test_select WHERE session_id = ?"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,1); @@ -1852,7 +1861,7 @@ static void test_bug1180() myquery(rc); strmov(query,"SELECT * FROM test_select WHERE ?=\"1111\" and session_id = \"abc\""); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,1); @@ -1932,7 +1941,7 @@ static void test_bug1644() myquery(rc); strmov(query, "INSERT INTO foo_dfr VALUES (?,?,?,? )"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt, 4); @@ -2030,7 +2039,7 @@ static void test_select_show() rc = mysql_query(mysql, "CREATE TABLE test_show(id int(4) NOT NULL primary key, name char(2))"); myquery(rc); - stmt = mysql_prepare(mysql, "show columns from test_show", 30); + stmt = mysql_simple_prepare(mysql, "show columns from test_show"); mystmt_init(stmt); verify_param_count(stmt,0); @@ -2041,11 +2050,11 @@ static void test_select_show() my_process_stmt_result(stmt); mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql, "show tables from mysql like ?", 50); + stmt = mysql_simple_prepare(mysql, "show tables from mysql like ?"); mystmt_init_r(stmt); strxmov(query,"show tables from ", current_db, " like \'test_show\'", NullS); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -2054,7 +2063,7 @@ static void test_select_show() my_process_stmt_result(stmt); mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql, "describe test_show", 30); + stmt = mysql_simple_prepare(mysql, "describe test_show"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -2063,7 +2072,7 @@ static void test_select_show() my_process_stmt_result(stmt); mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql, "show keys from test_show", 30); + stmt = mysql_simple_prepare(mysql, "show keys from test_show"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -2115,7 +2124,7 @@ static void test_simple_update() /* insert by prepare */ strmov(query,"UPDATE test_update SET col2=? WHERE col1=?"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -2190,11 +2199,11 @@ static void test_long_data() myquery(rc); strmov(query,"INSERT INTO test_long_data(col1,col2) VALUES(?)"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init_r(stmt); strmov(query,"INSERT INTO test_long_data(col1,col2,col3) VALUES(?,?,?)"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,3); @@ -2282,7 +2291,7 @@ static void test_long_data_str() myquery(rc); strmov(query,"INSERT INTO test_long_data_str VALUES(?,?)"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -2373,7 +2382,7 @@ static void test_long_data_str1() myquery(rc); strmov(query,"INSERT INTO test_long_data_str VALUES(?,?)"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -2462,7 +2471,7 @@ static void test_long_data_bin() myquery(rc); strmov(query,"INSERT INTO test_long_data_bin VALUES(?,?)"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -2557,7 +2566,7 @@ static void test_simple_delete() /* insert by prepare */ strmov(query,"DELETE FROM test_simple_delete WHERE col1=? AND col2=? AND col3=100"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -2637,7 +2646,7 @@ static void test_update() myquery(rc); strmov(query,"INSERT INTO test_update(col2,col3) VALUES(?,?)"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -2667,7 +2676,7 @@ static void test_update() mysql_stmt_close(stmt); strmov(query,"UPDATE test_update SET col2=? WHERE col3=?"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -2733,7 +2742,7 @@ static void test_prepare_noparam() /* insert by prepare */ strmov(query,"INSERT INTO my_prepare VALUES(10,'venu')"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,0); @@ -2812,7 +2821,7 @@ static void test_bind_result() bind[1].length= &length1; bind[1].is_null= &is_null[1]; - stmt = mysql_prepare(mysql, "SELECT * FROM test_bind_result", 50); + stmt = mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result"); mystmt_init(stmt); rc = mysql_bind_result(stmt,bind); @@ -2933,7 +2942,7 @@ static void test_bind_result_ext() bind[7].length= &bLength; bind[7].buffer_length= sizeof(bData); - stmt = mysql_prepare(mysql, "select * from test_bind_result", 50); + stmt = mysql_simple_prepare(mysql, "select * from test_bind_result"); mystmt_init(stmt); rc = mysql_bind_result(stmt,bind); @@ -3058,7 +3067,7 @@ static void test_bind_result_ext1() bind[i].length= &length[i]; } - stmt = mysql_prepare(mysql, "select * from test_bind_result", 50); + stmt = mysql_simple_prepare(mysql, "select * from test_bind_result"); mystmt_init(stmt); rc = mysql_bind_result(stmt,bind); @@ -3118,7 +3127,7 @@ static void bind_fetch(int row_count) MYSQL_BIND bind[7]; my_bool is_null[7]; - stmt = mysql_prepare(mysql,"INSERT INTO test_bind_fetch VALUES(?,?,?,?,?,?,?)",100); + stmt = mysql_simple_prepare(mysql,"INSERT INTO test_bind_fetch VALUES(?,?,?,?,?,?,?)"); mystmt_init(stmt); verify_param_count(stmt, 7); @@ -3151,9 +3160,9 @@ static void bind_fetch(int row_count) mysql_stmt_close(stmt); assert(row_count == (int) - my_stmt_result("SELECT * FROM test_bind_fetch",50)); + my_stmt_result("SELECT * FROM test_bind_fetch")); - stmt = mysql_prepare(mysql,"SELECT * FROM test_bind_fetch",50); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_bind_fetch"); myquery(rc); for (i= 0; i < (int) array_elements(bind); i++) @@ -3321,9 +3330,9 @@ static void test_fetch_date() bind[6].buffer_length= sizeof(ts_6); bind[6].length= &ts6_length; - assert(1 == my_stmt_result("SELECT * FROM test_bind_result",50)); + assert(1 == my_stmt_result("SELECT * FROM test_bind_result")); - stmt = mysql_prepare(mysql, "SELECT * FROM test_bind_result", 50); + stmt = mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result"); mystmt_init(stmt); rc = mysql_bind_result(stmt,bind); @@ -3651,7 +3660,7 @@ static void test_prepare_ext() /* insert by prepare - all integers */ strmov(query,(char *)"INSERT INTO test_prepare_ext(c1,c2,c3,c4,c5,c6) VALUES(?,?,?,?,?,?)"); - stmt = mysql_prepare(mysql,query, strlen(query)); + stmt = mysql_simple_prepare(mysql,query); mystmt_init(stmt); verify_param_count(stmt,6); @@ -3704,7 +3713,7 @@ static void test_prepare_ext() rc = mysql_commit(mysql); myquery(rc); - stmt = mysql_prepare(mysql,"SELECT c1,c2,c3,c4,c5,c6 FROM test_prepare_ext",100); + stmt = mysql_simple_prepare(mysql,"SELECT c1,c2,c3,c4,c5,c6 FROM test_prepare_ext"); mystmt_init(stmt); /* get the result */ @@ -3850,7 +3859,7 @@ static void test_insert() myquery(rc); /* insert by prepare */ - stmt = mysql_prepare(mysql, "INSERT INTO test_prep_insert VALUES(?,?)", 70); + stmt = mysql_simple_prepare(mysql, "INSERT INTO test_prep_insert VALUES(?,?)"); mystmt_init(stmt); verify_param_count(stmt,2); @@ -3922,7 +3931,7 @@ static void test_prepare_resultset() name varchar(50),extra double)"); myquery(rc); - stmt = mysql_prepare(mysql, "SELECT * FROM test_prepare_resultset", 60); + stmt = mysql_simple_prepare(mysql, "SELECT * FROM test_prepare_resultset"); mystmt_init(stmt); verify_param_count(stmt,0); @@ -4034,25 +4043,25 @@ static void test_stmt_close() myquery(rc); strmov(query,"ALTER TABLE test_stmt_close ADD name varchar(20)"); - stmt1= mysql_prepare(lmysql, query, 70); + stmt1= mysql_simple_prepare(lmysql, query); mystmt_init(stmt1); verify_param_count(stmt1, 0); strmov(query,"INSERT INTO test_stmt_close(id) VALUES(?)"); - stmt_x= mysql_prepare(mysql, query, 70); + stmt_x= mysql_simple_prepare(mysql, query); mystmt_init(stmt_x); verify_param_count(stmt_x, 1); strmov(query,"UPDATE test_stmt_close SET id=? WHERE id=?"); - stmt3= mysql_prepare(lmysql, query, 70); + stmt3= mysql_simple_prepare(lmysql, query); mystmt_init(stmt3); verify_param_count(stmt3, 2); strmov(query,"SELECT * FROM test_stmt_close WHERE id=?"); - stmt2= mysql_prepare(lmysql, query, 70); + stmt2= mysql_simple_prepare(lmysql, query); mystmt_init(stmt2); verify_param_count(stmt2, 1); @@ -4119,7 +4128,7 @@ static void test_set_variable() mysql_autocommit(mysql, TRUE); - stmt1 = mysql_prepare(mysql, "show variables like 'max_error_count'", 50); + stmt1 = mysql_simple_prepare(mysql, "show variables like 'max_error_count'"); mystmt_init(stmt1); get_bind[0].buffer_type= MYSQL_TYPE_STRING; @@ -4150,7 +4159,7 @@ static void test_set_variable() rc = mysql_fetch(stmt1); assert(rc == MYSQL_NO_DATA); - stmt = mysql_prepare(mysql, "set max_error_count=?", 50); + stmt = mysql_simple_prepare(mysql, "set max_error_count=?"); mystmt_init(stmt); set_bind[0].buffer_type= MYSQL_TYPE_LONG; @@ -4225,7 +4234,7 @@ static void test_insert_meta() myquery(rc); strmov(query,"INSERT INTO test_prep_insert VALUES(10,'venu1','test')"); - stmt = mysql_prepare(mysql, query, 70); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,0); @@ -4236,7 +4245,7 @@ static void test_insert_meta() mysql_stmt_close(stmt); strmov(query,"INSERT INTO test_prep_insert VALUES(?,'venu',?)"); - stmt = mysql_prepare(mysql, query, 70); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -4288,7 +4297,7 @@ static void test_update_meta() myquery(rc); strmov(query,"UPDATE test_prep_update SET col1=10, col2='venu1' WHERE col3='test'"); - stmt = mysql_prepare(mysql, query, 100); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,0); @@ -4299,7 +4308,7 @@ static void test_update_meta() mysql_stmt_close(stmt); strmov(query,"UPDATE test_prep_update SET col1=?, col2='venu' WHERE col3=?"); - stmt = mysql_prepare(mysql, query, 100); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -4355,7 +4364,7 @@ static void test_select_meta() myquery(rc); strmov(query,"SELECT * FROM test_prep_select WHERE col1=10"); - stmt = mysql_prepare(mysql, query, 70); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,0); @@ -4364,7 +4373,7 @@ static void test_select_meta() mytest_r(result); strmov(query,"SELECT col1, col3 from test_prep_select WHERE col1=? AND col3='test' AND col2= ?"); - stmt = mysql_prepare(mysql, query, 120); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); verify_param_count(stmt,2); @@ -4499,10 +4508,10 @@ static void test_multi_stmt() rc = mysql_query(mysql,"INSERT INTO test_multi_table values(10,'mysql')"); myquery(rc); - stmt = mysql_prepare(mysql, "SELECT * FROM test_multi_table WHERE id = ?", 100); + stmt = mysql_simple_prepare(mysql, "SELECT * FROM test_multi_table WHERE id = ?"); mystmt_init(stmt); - stmt2 = mysql_prepare(mysql, "UPDATE test_multi_table SET name='updated' WHERE id=10",100); + stmt2 = mysql_simple_prepare(mysql, "UPDATE test_multi_table SET name='updated' WHERE id=10"); mystmt_init(stmt2); verify_param_count(stmt,1); @@ -4544,7 +4553,7 @@ static void test_multi_stmt() assert(rc == MYSQL_NO_DATA); /* alter the table schema now */ - stmt1 = mysql_prepare(mysql,"DELETE FROM test_multi_table WHERE id = ? AND name=?",100); + stmt1 = mysql_simple_prepare(mysql,"DELETE FROM test_multi_table WHERE id = ? AND name=?"); mystmt_init(stmt1); verify_param_count(stmt1,2); @@ -4584,7 +4593,7 @@ static void test_multi_stmt() rc = mysql_fetch(stmt); assert(rc == MYSQL_NO_DATA); - assert(0 == my_stmt_result("SELECT * FROM test_multi_table",50)); + assert(0 == my_stmt_result("SELECT * FROM test_multi_table")); mysql_stmt_close(stmt); mysql_stmt_close(stmt2); @@ -4631,7 +4640,7 @@ static void test_manual_sample() /* Prepare a insert query with 3 parameters */ strmov(query, "INSERT INTO test_table(col1,col2,col3) values(?,?,?)"); - if (!(stmt = mysql_prepare(mysql,query,strlen(query)))) + if (!(stmt = mysql_simple_prepare(mysql,query))) { fprintf(stderr, "\n prepare, insert failed"); fprintf(stderr, "\n %s", mysql_error(mysql)); @@ -4735,7 +4744,7 @@ static void test_manual_sample() fprintf(stderr, "\n %s", mysql_stmt_error(stmt)); exit(0); } - assert(2 == my_stmt_result("SELECT * FROM test_table",50)); + assert(2 == my_stmt_result("SELECT * FROM test_table")); /* DROP THE TABLE */ if (mysql_query(mysql,"DROP TABLE test_table")) @@ -4770,7 +4779,7 @@ static void test_prepare_alter() rc = mysql_query(mysql,"INSERT INTO test_prep_alter values(10,'venu'),(20,'mysql')"); myquery(rc); - stmt = mysql_prepare(mysql, "INSERT INTO test_prep_alter VALUES(?,'monty')", 100); + stmt = mysql_simple_prepare(mysql, "INSERT INTO test_prep_alter VALUES(?,'monty')"); mystmt_init(stmt); verify_param_count(stmt,1); @@ -4796,7 +4805,7 @@ static void test_prepare_alter() rc = mysql_execute(stmt); mystmt(stmt, rc); - assert(4 == my_stmt_result("SELECT * FROM test_prep_alter",50)); + assert(4 == my_stmt_result("SELECT * FROM test_prep_alter")); mysql_stmt_close(stmt); } @@ -4978,7 +4987,7 @@ static void test_store_result() bind[1].is_null= &is_null[1]; length1= 0; - stmt = mysql_prepare(mysql, "SELECT * FROM test_store_result", 50); + stmt = mysql_simple_prepare(mysql, "SELECT * FROM test_store_result"); mystmt_init(stmt); rc = mysql_bind_result(stmt,bind); @@ -5089,7 +5098,7 @@ static void test_store_result1() rc = mysql_commit(mysql); myquery(rc); - stmt = mysql_prepare(mysql,"SELECT * FROM test_store_result",100); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_store_result"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -5160,7 +5169,7 @@ static void test_store_result2() bind[0].is_null= 0; strmov((char *)query , "SELECT col1 FROM test_store_result where col1= ?"); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); rc = mysql_bind_param(stmt,bind); @@ -5252,7 +5261,7 @@ static void test_subselect() bind[0].length= 0; bind[0].is_null= 0; - stmt = mysql_prepare(mysql, "INSERT INTO test_sub2(id) SELECT * FROM test_sub1 WHERE id=?", 100); + stmt = mysql_simple_prepare(mysql, "INSERT INTO test_sub2(id) SELECT * FROM test_sub1 WHERE id=?", 100); mystmt_init(stmt); rc = mysql_bind_param(stmt,bind); @@ -5275,13 +5284,13 @@ static void test_subselect() mysql_stmt_close(stmt); - assert(3 == my_stmt_result("SELECT * FROM test_sub2",50)); + assert(3 == my_stmt_result("SELECT * FROM test_sub2")); strmov((char *)query , "SELECT ROW(1,7) IN (select id, id1 from test_sub2 WHERE id1=?)"); - assert(1 == my_stmt_result("SELECT ROW(1,7) IN (select id, id1 from test_sub2 WHERE id1=8)",100)); - assert(1 == my_stmt_result("SELECT ROW(1,7) IN (select id, id1 from test_sub2 WHERE id1=7)",100)); + assert(1 == my_stmt_result("SELECT ROW(1,7) IN (select id, id1 from test_sub2 WHERE id1=8)")); + assert(1 == my_stmt_result("SELECT ROW(1,7) IN (select id, id1 from test_sub2 WHERE id1=7)")); - stmt = mysql_prepare(mysql, query, 150); + stmt = mysql_simple_prepare(mysql, query, 150); mystmt_init(stmt); rc = mysql_bind_param(stmt,bind); @@ -5335,7 +5344,7 @@ static void test_bind_date_conv(uint row_count) ulong second_part; uint year, month, day, hour, minute, sec; - stmt = mysql_prepare(mysql,"INSERT INTO test_date VALUES(?,?,?,?)", 100); + stmt = mysql_simple_prepare(mysql,"INSERT INTO test_date VALUES(?,?,?,?)"); mystmt_init(stmt); verify_param_count(stmt, 4); @@ -5389,9 +5398,9 @@ static void test_bind_date_conv(uint row_count) mysql_stmt_close(stmt); - assert(row_count == my_stmt_result("SELECT * FROM test_date",50)); + assert(row_count == my_stmt_result("SELECT * FROM test_date")); - stmt = mysql_prepare(mysql,"SELECT * FROM test_date",50); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_date"); myquery(rc); rc = mysql_bind_result(stmt, bind); @@ -5586,30 +5595,27 @@ static void test_pure_coverage() rc = mysql_query(mysql,"CREATE TABLE test_pure(c1 int, c2 varchar(20))"); myquery(rc); - stmt = mysql_prepare(mysql,"insert into test_pure(c67788) values(10)",100); + stmt = mysql_simple_prepare(mysql,"insert into test_pure(c67788) values(10)"); mystmt_init_r(stmt); -#ifndef DBUG_OFF - stmt = mysql_prepare(mysql,(const char *)0,0); - mystmt_init_r(stmt); - - stmt = mysql_prepare(mysql,"insert into test_pure(c2) values(10)",100); + /* Query without params and result should allow to bind 0 arrays */ + stmt = mysql_simple_prepare(mysql,"insert into test_pure(c2) values(10)"); mystmt_init(stmt); + + rc = mysql_bind_param(stmt, (MYSQL_BIND*)0); + mystmt(stmt, rc); + + rc = mysql_execute(stmt); + mystmt(stmt, rc); - rc = mysql_bind_param(stmt, bind); - mystmt_r(stmt, rc); - + rc = mysql_bind_result(stmt, (MYSQL_BIND*)0); + mystmt(stmt, rc); + mysql_stmt_close(stmt); -#endif - stmt = mysql_prepare(mysql,"insert into test_pure(c2) values(?)",100); + stmt = mysql_simple_prepare(mysql,"insert into test_pure(c2) values(?)"); mystmt_init(stmt); -#ifndef DBUG_OFF - rc = mysql_execute(stmt); - mystmt_r(stmt, rc);/* No parameters supplied */ -#endif - bind[0].length= &length; bind[0].is_null= 0; bind[0].buffer_length= 0; @@ -5622,28 +5628,20 @@ static void test_pure_coverage() rc = mysql_bind_param(stmt, bind); mystmt(stmt, rc); - rc = mysql_send_long_data(stmt, 20, (char *)"venu", 4); - mystmt_r(stmt, rc); /* wrong param number */ - rc = mysql_stmt_store_result(stmt); mystmt(stmt, rc); mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql,"select * from test_pure",100); + stmt = mysql_simple_prepare(mysql,"select * from test_pure"); mystmt(stmt, rc); rc = mysql_execute(stmt); mystmt(stmt, rc); -#ifndef DBUG_OFF - rc = mysql_bind_result(stmt, (MYSQL_BIND *)0); - mystmt_r(stmt, rc); - bind[0].buffer_type= MYSQL_TYPE_GEOMETRY; rc = mysql_bind_result(stmt, bind); mystmt_r(stmt, rc); /* unsupported buffer type */ -#endif rc = mysql_stmt_store_result(stmt); mystmt(stmt, rc); @@ -5682,7 +5680,7 @@ static void test_buffers() ,('Database'),('Open-Source'),('Popular')"); myquery(rc); - stmt = mysql_prepare(mysql,"select str from test_buffer",100); + stmt = mysql_simple_prepare(mysql,"select str from test_buffer"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -5760,7 +5758,7 @@ static void test_open_direct() rc = mysql_query(mysql,"CREATE TABLE test_open_direct(id int, name char(6))"); myquery(rc); - stmt = mysql_prepare(mysql,"INSERT INTO test_open_direct values(10,'mysql')", 100); + stmt = mysql_simple_prepare(mysql,"INSERT INTO test_open_direct values(10,'mysql')"); mystmt_init(stmt); rc = mysql_query(mysql, "SELECT * FROM test_open_direct"); @@ -5799,7 +5797,7 @@ static void test_open_direct() mysql_stmt_close(stmt); /* run a direct query in the middle of a fetch */ - stmt= mysql_prepare(mysql,"SELECT * FROM test_open_direct",100); + stmt= mysql_simple_prepare(mysql,"SELECT * FROM test_open_direct"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -5818,7 +5816,7 @@ static void test_open_direct() myquery(rc); /* run a direct query with store result */ - stmt= mysql_prepare(mysql,"SELECT * FROM test_open_direct",100); + stmt= mysql_simple_prepare(mysql,"SELECT * FROM test_open_direct"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -5849,8 +5847,8 @@ static void test_fetch_nobuffs() myheader("test_fetch_nobuffs"); - stmt = mysql_prepare(mysql,"SELECT DATABASE(), CURRENT_USER(), \ - CURRENT_DATE(), CURRENT_TIME()",100); + stmt = mysql_simple_prepare(mysql,"SELECT DATABASE(), CURRENT_USER(), \ + CURRENT_DATE(), CURRENT_TIME()"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -5923,7 +5921,7 @@ static void test_ushort_bug() myquery(rc); - stmt = mysql_prepare(mysql,"SELECT * FROM test_ushort",50); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_ushort"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6007,7 +6005,7 @@ static void test_sshort_bug() myquery(rc); - stmt = mysql_prepare(mysql,"SELECT * FROM test_sshort",50); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_sshort"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6091,7 +6089,7 @@ static void test_stiny_bug() myquery(rc); - stmt = mysql_prepare(mysql,"SELECT * FROM test_stiny",50); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_stiny"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6176,7 +6174,7 @@ static void test_field_misc() mysql_free_result(result); - stmt = mysql_prepare(mysql,"SELECT @@autocommit",20); + stmt = mysql_simple_prepare(mysql,"SELECT @@autocommit"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6196,7 +6194,7 @@ static void test_field_misc() mysql_free_result(result); mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql, "SELECT @@table_type", 30); + stmt = mysql_simple_prepare(mysql, "SELECT @@table_type"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6220,7 +6218,7 @@ static void test_field_misc() mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql, "SELECT @@table_type", 30); + stmt = mysql_simple_prepare(mysql, "SELECT @@table_type"); mystmt_init(stmt); result = mysql_get_metadata(stmt); @@ -6240,7 +6238,7 @@ static void test_field_misc() mysql_free_result(result); mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql, "SELECT @@max_error_count", 30); + stmt = mysql_simple_prepare(mysql, "SELECT @@max_error_count"); mystmt_init(stmt); result = mysql_get_metadata(stmt); @@ -6260,7 +6258,7 @@ static void test_field_misc() mysql_free_result(result); mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql, "SELECT @@max_allowed_packet", 30); + stmt = mysql_simple_prepare(mysql, "SELECT @@max_allowed_packet"); mystmt_init(stmt); result = mysql_get_metadata(stmt); @@ -6280,7 +6278,7 @@ static void test_field_misc() mysql_free_result(result); mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql, "SELECT @@sql_warnings", 30); + stmt = mysql_simple_prepare(mysql, "SELECT @@sql_warnings"); mystmt_init(stmt); result = mysql_get_metadata(stmt); @@ -6341,7 +6339,7 @@ static void test_set_option() mysql_free_result(result); fprintf(stdout,"\n with SQL_SELECT_LIMIT=2 (prepare)"); - stmt = mysql_prepare(mysql, "SELECT * FROM test_limit", 50); + stmt = mysql_simple_prepare(mysql, "SELECT * FROM test_limit"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6356,7 +6354,7 @@ static void test_set_option() rc= mysql_query(mysql,"SET OPTION SQL_SELECT_LIMIT=DEFAULT"); myquery(rc); - stmt = mysql_prepare(mysql, "SELECT * FROM test_limit", 50); + stmt = mysql_simple_prepare(mysql, "SELECT * FROM test_limit"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6433,18 +6431,20 @@ static void test_prepare_grant() execute_prepare_query("INSERT INTO test_grant(a) VALUES(NULL)",1); execute_prepare_query("INSERT INTO test_grant VALUES(NULL)",1); execute_prepare_query("UPDATE test_grant SET a=9 WHERE a=1",1); - assert(4 == my_stmt_result("SELECT a FROM test_grant",50)); - + assert(4 == my_stmt_result("SELECT a FROM test_grant")); + + /* Both DELETE expected to fail as user does not have DELETE privs */ + rc = mysql_query(mysql,"DELETE FROM test_grant"); myquery_r(rc); - stmt= mysql_prepare(mysql,"DELETE FROM test_grant",50); + stmt= mysql_simple_prepare(mysql,"DELETE FROM test_grant"); mystmt_init(stmt); rc = mysql_execute(stmt); myquery_r(rc); - assert(4 == my_stmt_result("SELECT * FROM test_grant",50)); + assert(4 == my_stmt_result("SELECT * FROM test_grant")); mysql_close(lmysql); mysql= org_mysql; @@ -6487,7 +6487,7 @@ static void test_frm_bug() rc= mysql_query(mysql,"flush tables"); myquery(rc); - stmt = mysql_prepare(mysql, "show variables like 'datadir'", 50); + stmt = mysql_simple_prepare(mysql, "show variables like 'datadir'"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6570,7 +6570,7 @@ static void test_decimal_bug() rc = mysql_query(mysql, "insert into test_decimal_bug value(8),(10.22),(5.61)"); myquery(rc); - stmt = mysql_prepare(mysql,"select c1 from test_decimal_bug where c1= ?",50); + stmt = mysql_simple_prepare(mysql,"select c1 from test_decimal_bug where c1= ?"); mystmt_init(stmt); bind[0].buffer_type= MYSQL_TYPE_DOUBLE; @@ -6666,7 +6666,7 @@ static void test_explain_bug() rc = mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))"); myquery(rc); - stmt = mysql_prepare(mysql, "explain test_explain", 30); + stmt = mysql_simple_prepare(mysql, "explain test_explain"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6702,7 +6702,7 @@ static void test_explain_bug() mysql_free_result(result); mysql_stmt_close(stmt); - stmt = mysql_prepare(mysql, "explain select id, name FROM test_explain", 50); + stmt = mysql_simple_prepare(mysql, "explain select id, name FROM test_explain"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -6950,10 +6950,10 @@ static void test_logs() myheader("test_logs"); - rc = mysql_real_query(mysql, "DROP TABLE IF EXISTS test_logs", 100); + rc = mysql_query(mysql, "DROP TABLE IF EXISTS test_logs"); myquery(rc); - rc = mysql_real_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))", 100); + rc = mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))"); myquery(rc); length= (ulong)(strmov((char *)data,"INSERT INTO test_logs VALUES(?,?)") - data); @@ -7015,7 +7015,7 @@ static void test_logs() mysql_stmt_close(stmt); length= (ulong)(strmov((char *)data, "SELECT * FROM test_logs WHERE id=?") - data); - stmt = mysql_prepare(mysql, data, length+2); + stmt = mysql_prepare(mysql, data, length); mystmt_init(stmt); rc = mysql_bind_param(stmt, bind); @@ -7125,7 +7125,7 @@ static void test_nstmts() mysql_stmt_close(stmt); } - stmt = mysql_prepare(mysql," select count(*) from test_nstmts", 50); + stmt = mysql_simple_prepare(mysql," select count(*) from test_nstmts"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -7172,7 +7172,7 @@ static void test_fetch_seek() rc = mysql_query(mysql, "insert into test_seek(c2) values('venu'),('mysql'),('open'),('source')"); myquery(rc); - stmt = mysql_prepare(mysql,"select * from test_seek",50); + stmt = mysql_simple_prepare(mysql,"select * from test_seek"); mystmt_init(stmt); bind[0].buffer_type= MYSQL_TYPE_LONG; @@ -7267,7 +7267,7 @@ static void test_fetch_offset() rc = mysql_query(mysql, "insert into test_column values('abcdefghij'),(null)"); myquery(rc); - stmt = mysql_prepare(mysql,"select * from test_column",50); + stmt = mysql_simple_prepare(mysql,"select * from test_column"); mystmt_init(stmt); bind[0].buffer_type= MYSQL_TYPE_STRING; @@ -7291,9 +7291,6 @@ static void test_fetch_offset() rc = mysql_fetch(stmt); mystmt(stmt,rc); - rc = mysql_fetch_column(stmt,bind,4,0); - mystmt_r(stmt,rc); - data[0]= '\0'; rc = mysql_fetch_column(stmt,bind,0,0); mystmt(stmt,rc); @@ -7350,7 +7347,7 @@ static void test_fetch_column() rc = mysql_query(mysql, "insert into test_column(c2) values('venu'),('mysql')"); myquery(rc); - stmt = mysql_prepare(mysql,"select * from test_column order by c2 desc", 50); + stmt = mysql_simple_prepare(mysql,"select * from test_column order by c2 desc"); mystmt_init(stmt); bind[0].buffer_type= MYSQL_TYPE_LONG; @@ -7411,9 +7408,6 @@ static void test_fetch_column() fprintf(stdout, "\n col 0: %d(%ld)", c1, l1); assert(c1 == 1 && l1 == 4); - rc = mysql_fetch_column(stmt,bind,10,0); - mystmt_r(stmt,rc); - rc = mysql_fetch(stmt); mystmt(stmt,rc); @@ -7537,7 +7531,7 @@ static void test_mem_overun() assert(1 == my_process_result(mysql)); - stmt = mysql_prepare(mysql, "select * from t_mem_overun",30); + stmt = mysql_simple_prepare(mysql, "select * from t_mem_overun"); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -7583,7 +7577,7 @@ static void test_free_result() rc = mysql_query(mysql, "insert into test_free_result values(),(),()"); myquery(rc); - stmt = mysql_prepare(mysql,"select * from test_free_result",50); + stmt = mysql_simple_prepare(mysql,"select * from test_free_result"); mystmt_init(stmt); bind[0].buffer_type= MYSQL_TYPE_LONG; @@ -7662,7 +7656,7 @@ static void test_free_store_result() rc = mysql_query(mysql, "insert into test_free_result values(),(),()"); myquery(rc); - stmt = mysql_prepare(mysql,"select * from test_free_result",50); + stmt = mysql_simple_prepare(mysql,"select * from test_free_result"); mystmt_init(stmt); bind[0].buffer_type= MYSQL_TYPE_LONG; @@ -7749,7 +7743,7 @@ static void test_sqlmode() strcpy(query, "INSERT INTO test_piping VALUES(?||?)"); fprintf(stdout,"\n query: %s", query); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); fprintf(stdout,"\n total parameters: %ld", mysql_param_count(stmt)); @@ -7781,7 +7775,7 @@ static void test_sqlmode() strcpy(query, "SELECT connection_id ()"); fprintf(stdout,"\n query: %s", query); - stmt = mysql_prepare(mysql, query, 70); + stmt = mysql_simple_prepare(mysql, query); mystmt_init_r(stmt); /* ANSI */ @@ -7792,7 +7786,7 @@ static void test_sqlmode() strcpy(query, "INSERT INTO test_piping VALUES(?||?)"); fprintf(stdout,"\n query: %s", query); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); fprintf(stdout,"\n total parameters: %ld", mysql_param_count(stmt)); @@ -7809,7 +7803,7 @@ static void test_sqlmode() /* ANSI mode spaces ... */ strcpy(query, "SELECT connection_id ()"); fprintf(stdout,"\n query: %s", query); - stmt = mysql_prepare(mysql, query, 70); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -7832,7 +7826,7 @@ static void test_sqlmode() strcpy(query, "SELECT connection_id ()"); fprintf(stdout,"\n query: %s", query); - stmt = mysql_prepare(mysql, query, 70); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); rc = mysql_execute(stmt); @@ -7873,7 +7867,7 @@ static void test_ts() rc = mysql_commit(mysql); myquery(rc); - stmt = mysql_prepare(mysql,"INSERT INTO test_ts VALUES(?,?,?),(?,?,?)",50); + stmt = mysql_simple_prepare(mysql,"INSERT INTO test_ts VALUES(?,?,?),(?,?,?)"); mystmt_init(stmt); ts.year= 2003; @@ -7912,7 +7906,7 @@ static void test_ts() verify_col_data("test_ts","b","21:07:46"); verify_col_data("test_ts","c","2003-07-12 21:07:46"); - stmt = mysql_prepare(mysql,"SELECT * FROM test_ts",50); + stmt = mysql_simple_prepare(mysql,"SELECT * FROM test_ts"); mystmt_init(stmt); prep_res = mysql_get_metadata(stmt); @@ -7983,7 +7977,7 @@ static void test_bug1500() rc= mysql_commit(mysql); myquery(rc); - stmt= mysql_prepare(mysql,"SELECT i FROM test_bg1500 WHERE i IN (?,?,?)",44); + stmt= mysql_simple_prepare(mysql,"SELECT i FROM test_bg1500 WHERE i IN (?,?,?)"); mystmt_init(stmt); verify_param_count(stmt,3); @@ -8018,8 +8012,8 @@ static void test_bug1500() rc= mysql_commit(mysql); myquery(rc); - stmt= mysql_prepare(mysql, - "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)",53); + stmt= mysql_simple_prepare(mysql, + "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)"); mystmt_init(stmt); verify_param_count(stmt,1); @@ -8046,8 +8040,8 @@ static void test_bug1500() mysql_stmt_close(stmt); /* This should work too */ - stmt= mysql_prepare(mysql, - "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?,'digger'))", 70); + stmt= mysql_simple_prepare(mysql, + "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?,'digger'))"); mystmt_init(stmt); verify_param_count(stmt,1); @@ -8084,7 +8078,7 @@ static void test_bug1946() rc= mysql_query(mysql,"CREATE TABLE prepare_command(ID INT)"); myquery(rc); - stmt = mysql_prepare(mysql, query, strlen(query)); + stmt = mysql_simple_prepare(mysql, query); mystmt_init(stmt); rc= mysql_real_query(mysql, query, strlen(query)); assert(rc != 0); @@ -8095,6 +8089,163 @@ static void test_bug1946() rc= mysql_query(mysql,"DROP TABLE prepare_command"); } +static void test_parse_error_and_bad_length() +{ + MYSQL_STMT *stmt; + int rc; + + /* check that we get 4 syntax errors over the 4 calls */ + myheader("test_parse_error_and_bad_length"); + + rc= mysql_query(mysql,"SHOW DATABAAAA"); + assert(rc); + fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql)); + rc= mysql_real_query(mysql,"SHOW DATABASES",100); + assert(rc); + fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql)); + + stmt= mysql_simple_prepare(mysql,"SHOW DATABAAAA"); + assert(!stmt); + fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql)); + stmt= mysql_prepare(mysql,"SHOW DATABASES",100); + assert(!stmt); + fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql)); +} + + +static void test_bug2247() +{ + MYSQL_STMT *stmt; + MYSQL_RES *res; + int rc; + int i; + const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)"; + const char *insert= "INSERT INTO bug2247 VALUES (NULL)"; + const char *select= "SELECT id FROM bug2247"; + const char *update= "UPDATE bug2247 SET id=id+10"; + const char *drop= "DROP TABLE IF EXISTS bug2247"; + ulonglong exp_count; + enum { NUM_ROWS= 5 }; + + myheader("test_bug2247"); + + fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n" + "mysql_query ... "); + /* create table and insert few rows */ + rc = mysql_query(mysql, drop); + myquery(rc); + + rc= mysql_query(mysql, create); + myquery(rc); + + stmt= mysql_prepare(mysql, insert, strlen(insert)); + mystmt_init(stmt); + for (i= 0; i < NUM_ROWS; ++i) + { + rc= mysql_execute(stmt); + mystmt(stmt, rc); + } + exp_count= mysql_stmt_affected_rows(stmt); + assert(exp_count == 1); + + rc= mysql_query(mysql, select); + myquery(rc); + /* + mysql_store_result overwrites mysql->affected_rows. Check that + mysql_stmt_affected_rows() returns the same value, whereas + mysql_affected_rows() value is correct. + */ + res= mysql_store_result(mysql); + mytest(res); + + assert(mysql_affected_rows(mysql) == NUM_ROWS); + assert(exp_count == mysql_stmt_affected_rows(stmt)); + + rc= mysql_query(mysql, update); + myquery(rc); + assert(mysql_affected_rows(mysql) == NUM_ROWS); + assert(exp_count == mysql_stmt_affected_rows(stmt)); + + mysql_free_result(res); + mysql_stmt_close(stmt); + + /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */ + stmt= mysql_prepare(mysql, select, strlen(select)); + mystmt_init(stmt); + + rc= mysql_execute(stmt); + mystmt(stmt, rc); + rc= mysql_stmt_store_result(stmt); + mystmt(stmt, rc); + exp_count= mysql_stmt_affected_rows(stmt); + assert(exp_count == NUM_ROWS); + + rc= mysql_query(mysql, insert); + myquery(rc); + assert(mysql_affected_rows(mysql) == 1); + assert(mysql_stmt_affected_rows(stmt) == exp_count); + + mysql_stmt_close(stmt); + fprintf(stdout, "OK"); +} + +/* + Test for bug#2248 "mysql_fetch without prior mysql_execute hangs" +*/ + +static void test_bug2248() +{ + MYSQL_STMT *stmt; + int rc; + const char *query1= "SELECT DATABASE()"; + const char *query2= "INSERT INTO test_bug2248 VALUES (10)"; + + myheader("test_bug2248"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bug2248"); + myquery(rc); + + rc= mysql_query(mysql, "CREATE TABLE test_bug2248 (id int)"); + myquery(rc); + + stmt= mysql_prepare(mysql, query1, strlen(query1)); + mystmt_init(stmt); + + /* This should not hang */ + rc= mysql_fetch(stmt); + mystmt_r(stmt,rc); + + /* And this too */ + rc= mysql_stmt_store_result(stmt); + mystmt_r(stmt,rc); + + mysql_stmt_close(stmt); + + stmt= mysql_prepare(mysql, query2, strlen(query2)); + mystmt_init(stmt); + + rc= mysql_execute(stmt); + mystmt(stmt,rc); + + /* This too should not hang but should return proper error */ + rc= mysql_fetch(stmt); + assert(rc==MYSQL_NO_DATA); + + /* This too should not hang but should not bark */ + rc= mysql_stmt_store_result(stmt); + mystmt(stmt,rc); + + /* This should return proper error */ + rc= mysql_fetch(stmt); + mystmt_r(stmt,rc); + assert(rc==MYSQL_NO_DATA); + + mysql_stmt_close(stmt); + + rc= mysql_query(mysql,"DROP TABLE test_bug2248"); + myquery(rc); +} + /* Read and parse arguments and MySQL options from my.cnf @@ -8340,6 +8491,12 @@ int main(int argc, char **argv) test_bug1644(); /* BUG#1644 */ test_bug1946(); /* test that placeholders are allowed only in prepared queries */ + test_bug2248(); /* BUG#2248 */ + test_parse_error_and_bad_length(); /* test if bad length param in + mysql_prepare() triggers error */ + test_bug2247(); /* test that mysql_stmt_affected_rows() returns + number of rows affected by last prepared + statement execution */ end_time= time((time_t *)0); total_time+= difftime(end_time, start_time); |