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 a7eb7c81105..2eb24c49273 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -54,6 +54,7 @@ jani@janikt.pp.saunalahti.fi 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/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 2cdcd23165e..eb466a86c91 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -44,7 +44,7 @@ #include #endif -const char *VER= "14.4"; +const char *VER= "14.5"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -839,7 +839,9 @@ static int get_options(int argc, char **argv) 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) @@ -2703,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) @@ -2748,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 921ffbaab5b..345c7f0b945 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -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, @@ -140,6 +140,10 @@ static struct my_option my_long_options[] = "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.", @@ -347,15 +351,19 @@ static void write_header(FILE *sql_file, char *db_name) fputs("\n", sql_file); fputs("\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,"\ @@ -371,17 +379,18 @@ static void write_header(FILE *sql_file, char *db_name) static void write_footer(FILE *sql_file) { if (opt_xml) - fputs("", sql_file); - else + fputs("\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 */ @@ -448,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; @@ -521,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)) @@ -649,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; @@ -1270,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)) { @@ -1647,7 +1663,7 @@ static int dump_all_tables_in_db(char *database) if (opt_xml) fputs("\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/configure.in b/configure.in index e607f87747b..9cdb9d209c2 100644 --- a/configure.in +++ b/configure.in @@ -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/include/m_ctype.h b/include/m_ctype.h index 4a9415f43f9..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 */ @@ -311,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); @@ -327,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/mysql.h b/include/mysql.h index d1b467f9649..0bb42c7f5eb 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' */ @@ -575,6 +572,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/libmysql/libmysql.c b/libmysql/libmysql.c index 977657f8998..5c5898dfd7d 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -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)))) @@ -2086,19 +2078,6 @@ 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); - } -#ifdef CHECK_EXTRA_ARGUMENTS - if (stmt->param_count && !stmt->param_buffers) - { - /* Parameters exists, but no bound buffers */ - set_stmt_error(stmt, CR_NOT_ALL_PARAMS_BOUND, unknown_sqlstate); - DBUG_RETURN(1); - } -#endif if ((*stmt->mysql->methods->stmt_execute)(stmt)) DBUG_RETURN(1); @@ -2144,19 +2123,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 +2245,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) @@ -2853,18 +2814,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 +2984,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, @@ -3065,7 +3023,7 @@ no_data: mysql_fetch_column() stmt Prepared statement handler bind Where data should be placed. Should be filled in as - when calling mysql_bind_param() + 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 +3041,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) @@ -3510,7 +3460,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"); @@ -3529,8 +3478,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/lib_sql.cc b/libmysqld/lib_sql.cc index e36e878d4b1..101e129d615 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -245,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,thd->query_rest_length,1) + || emb_mysql_read_query_result(mysql)) + DBUG_RETURN(1); + + DBUG_RETURN(0); /* No more results */ +} MYSQL_METHODS embedded_methods= { @@ -259,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 @@ -676,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; } @@ -749,6 +765,11 @@ bool Protocol::net_store_data(const char *from, uint length) return false; } +char *memdup_mysql(struct st_mysql *mysql, const char*data, int length) +{ + return memdup_root(&mysql->field_alloc, data, length); +} + #if 0 /* The same as Protocol::net_store_data but does the converstion */ 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 -#ifdef __WIN__ -#include -#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 -#endif int mi_delete_table(const char *name) { 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 #endif -#ifdef __WIN__ -#include -#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 -#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 #include #ifndef __WIN__ #include 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 -#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 -#endif int mi_rename(const char *old_name, const char *new_name) { 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 -#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 060d4431de6..88e7f070642 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -20,10 +20,6 @@ #include "rt_index.h" #include -#ifdef __WIN__ -#include -#endif - #define MAX_POINTER_LENGTH 8 /* Functions declared in this file */ diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index 893452290b2..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 @@ -36,6 +42,21 @@ cast("1:2:3" as TIME) 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) 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_utf8.result b/mysql-test/r/ctype_utf8.result index 7c05b1ea446..658a7b8f5f6 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -73,9 +73,97 @@ 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(4) character set utf8 default NULL + `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; 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 170c393524b..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 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 @@ -141,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 ) @@ -189,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 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 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 @@ -229,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 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); @@ -252,9 +252,7 @@ drop table t1; CREATE TABLE `t1` ( `N` int(11) unsigned NOT NULL default '0', `M` tinyint(1) default '0', -) TYPE=MyISAM DEFAULT CHARSET=latin1; -Warnings: -Warning 1286 'TYPE=storage_engine' is deprecated. Use 'ENGINE=storage_engine' instead. +) 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; @@ -267,21 +265,23 @@ N M 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) -) TYPE=MyISAM DEFAULT CHARSET=latin1; -Warnings: -Warning 1286 'TYPE=storage_engine' is deprecated. Use 'ENGINE=storage_engine' instead. +) ENGINE=MyISAM DEFAULT CHARSET=latin1; CREATE TABLE t2 ( ID int(11) default NULL, PARID int(11) default NULL, @@ -298,3 +298,25 @@ INSERT INTO t3 VALUES (1000,0.00),(1001,0.25),(1002,0.50),(1003,0.75),(1008,1.00 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 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 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_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/mysqldump.result b/mysql-test/r/mysqldump.result index f51caee39d6..fd9e2a1f42b 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -21,6 +21,11 @@ DROP TABLE t1; CREATE TABLE t1 (a decimal(240, 20)); INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), ("0987654321098765432109876543210987654321"); + +/*!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 @@ -41,6 +46,11 @@ UNLOCK TABLES; DROP TABLE t1; CREATE TABLE t1 (a double); INSERT INTO t1 VALUES (-9e999999); + +/*!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 @@ -105,6 +115,11 @@ 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'); + +/*!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 @@ -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/query_cache.result b/mysql-test/r/query_cache.result index 49ae082dead..04bcb56d48d 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 diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result index c179351551d..82b1ed233ec 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 561 slave-relay-bin.000002 332 master-bin.000001 Yes No 0 0 244 649 Master master-bin.000001 244 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 Yes No 0 0 244 # Master master-bin.000001 244 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 290f916ae72..235c6cd0ecf 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -265,3 +265,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/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 4b3197d7d34..cbb9eaa4c32 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1340,8 +1340,8 @@ a explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index -2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 Using index -2 DEPENDENT SUBQUERY t1 ref a a 10 func,test.t3.a 1000 Using where; Using index +2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 Using where; Using index +2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 Using where; Using index Warnings: Note 1003 select high_priority test.t2.a AS `a` from test.t2 where (test.t2.a,(select 1 AS `Not_used` from test.t1 join test.t3 where ((test.t1.b = test.t3.a) and ((test.t2.a) = test.t1.a)) limit 1)) insert into t1 values (3,31); @@ -1578,52 +1578,30 @@ select * from t1; a b 1 0.123 drop table t1; -CREATE TABLE t1 ( -id int(11) NOT NULL auto_increment, -ts timestamp NOT NULL, -id_cns tinyint(3) unsigned NOT NULL default '0', -id_desc_nota int(11) NOT NULL default '1', -id_publ_uff int(11) NOT NULL default '0', -tipo enum('','UNO','DUE') NOT NULL default '', -f_aggiunte set('TRE','TRETRE','QUATTRO','CINQUE','SEI','SETTE') NOT NULL -default '', -anno_dep smallint(4) unsigned zerofill NOT NULL default '0000', -data_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) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 PACK_KEYS=1; -INSERT INTO t1 (id, ts, id_cns, id_desc_nota, id_publ_uff, tipo, f_aggiunte, -anno_dep, data_dep, particolare, generale, bis) VALUES -(NULL, NULL, 16, 29, 622, 'UNO', '', 1987, 1218, 2048, 9681, 0), -(NULL, NULL, 50, 23, 1717, 'UNO', '', 1987, 1126, 1536, 13987, 0), -(NULL, NULL, 16, 123, 123, 'UNO', '', 1987, 1221, 2432, 14594, 0), -(NULL, NULL, 16, 124, 124, 'UNO', '', 1987, 1201, 1792, 13422, 0), -(NULL, NULL, 16, 125, 125, 'UNO', '', 1987, 0723, 1025, 10240, 0), -(NULL, NULL, 16, 126, 126, 'UNO', '', 1987, 1204, 1026, 7089, 0); -CREATE TABLE t2 ( -id tinyint(3) unsigned NOT NULL auto_increment, -descr varchar(40) NOT NULL default '', -f_servizi set('UNO','DUE') NOT NULL default '', -data_uno_min int(8) unsigned NOT NULL default '0', -data_due_min int(8) unsigned NOT NULL default '0', -max_anno_dep smallint(6) unsigned NOT NULL default '0', -data_agg int(8) unsigned NOT NULL default '0', -PRIMARY KEY (id) +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 t2 (id, descr, f_servizi, data_uno_min, data_due_min, -max_anno_dep, data_agg) VALUES -(16, 'C_UNO', 'UNO,DUE', 19000000, 30000000, 1987, 0), -(50, 'C_TRE', 'UNO', 19000000, 30000000, 1990, 0); -SELECT 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; -PIPPO -1 -NULL +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; create table t1 (a int); insert into t1 values (1), (2), (3); 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/warnings.result b/mysql-test/r/warnings.result index c3d9f165fed..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); diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index e1cfe5760ee..fab35bb334a 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -10,10 +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 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_utf8.test b/mysql-test/t/ctype_utf8.test index 5e9324dd68f..0615de99b7a 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -53,3 +53,48 @@ 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; 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 154fc4b3834..a9341ada416 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -147,16 +147,20 @@ drop table t1; CREATE TABLE `t1` ( `N` int(11) unsigned NOT NULL default '0', `M` tinyint(1) default '0', -) TYPE=MyISAM DEFAULT CHARSET=latin1; +) 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; # @@ -167,7 +171,7 @@ CREATE TABLE t1 ( SORTORDER int(11) NOT NULL auto_increment, KEY t1_SortIndex (SORTORDER), KEY t1_IdIndex (OBJECTID) -) TYPE=MyISAM DEFAULT CHARSET=latin1; +) ENGINE=MyISAM DEFAULT CHARSET=latin1; CREATE TABLE t2 ( ID int(11) default NULL, PARID int(11) default NULL, @@ -183,3 +187,22 @@ CREATE TABLE t3 ( 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_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/mysqldump.test b/mysql-test/t/mysqldump.test index 93b0dd4a75d..dc0d45187b4 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -53,3 +53,21 @@ CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'); --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/query_cache.test b/mysql-test/t/query_cache.test index dba5619b777..5ae2039138d 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; diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test index 9bc4ea4e7b1..40d36110296 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 immideately start slave until master_log_file='master-bin.000001', master_log_pos=561; -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 d262f02c978..1d64cfd2105 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -142,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/subselect.test b/mysql-test/t/subselect.test index e4ecddc447f..4f33e321063 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1026,53 +1026,27 @@ drop table t1; # Bug 2479 # -CREATE TABLE t1 ( -id int(11) NOT NULL auto_increment, -ts timestamp NOT NULL, -id_cns tinyint(3) unsigned NOT NULL default '0', -id_desc_nota int(11) NOT NULL default '1', -id_publ_uff int(11) NOT NULL default '0', -tipo enum('','UNO','DUE') NOT NULL default '', -f_aggiunte set('TRE','TRETRE','QUATTRO','CINQUE','SEI','SETTE') NOT NULL -default '', -anno_dep smallint(4) unsigned zerofill NOT NULL default '0000', -data_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) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 PACK_KEYS=1; - -INSERT INTO t1 (id, ts, id_cns, id_desc_nota, id_publ_uff, tipo, f_aggiunte, -anno_dep, data_dep, particolare, generale, bis) VALUES -(NULL, NULL, 16, 29, 622, 'UNO', '', 1987, 1218, 2048, 9681, 0), -(NULL, NULL, 50, 23, 1717, 'UNO', '', 1987, 1126, 1536, 13987, 0), -(NULL, NULL, 16, 123, 123, 'UNO', '', 1987, 1221, 2432, 14594, 0), -(NULL, NULL, 16, 124, 124, 'UNO', '', 1987, 1201, 1792, 13422, 0), -(NULL, NULL, 16, 125, 125, 'UNO', '', 1987, 0723, 1025, 10240, 0), -(NULL, NULL, 16, 126, 126, 'UNO', '', 1987, 1204, 1026, 7089, 0); - -CREATE TABLE t2 ( -id tinyint(3) unsigned NOT NULL auto_increment, -descr varchar(40) NOT NULL default '', -f_servizi set('UNO','DUE') NOT NULL default '', -data_uno_min int(8) unsigned NOT NULL default '0', -data_due_min int(8) unsigned NOT NULL default '0', -max_anno_dep smallint(6) unsigned NOT NULL default '0', -data_agg int(8) unsigned NOT NULL default '0', -PRIMARY KEY (id) +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); -INSERT INTO t2 (id, descr, f_servizi, data_uno_min, data_due_min, -max_anno_dep, data_agg) VALUES -(16, 'C_UNO', 'UNO,DUE', 19000000, 30000000, 1987, 0), -(50, 'C_TRE', 'UNO', 19000000, 30000000, 1990, 0); - -SELECT 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; +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/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/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 40a026f161f..5bf0ea972a5 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -537,15 +537,15 @@ 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); + 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; } - cs= (cs && cs->state & MY_CS_AVAILABLE) ? cs : NULL; pthread_mutex_unlock(&THR_LOCK_charset); return cs; } diff --git a/sql/field.cc b/sql/field.cc index 9f25b770ab0..d26534b5ac7 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4058,36 +4058,42 @@ void Field_datetime::sql_type(String &res) const 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 (String::needs_conversion(from, length, 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; @@ -4246,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 (String::needs_conversion(from, length, cs, field_charset)) + if (String::needs_conversion(length, cs, field_charset, ¬_used)) { tmpstr.copy(from, length, cs, field_charset); from= tmpstr.ptr(); @@ -4477,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) { @@ -4500,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: @@ -4565,21 +4558,33 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) 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 ((was_conversion= String::needs_conversion(from, length, - 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 (was_conversion || 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(); } } @@ -5079,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 (String::needs_conversion(from, length, cs, field_charset)) + if (String::needs_conversion(length, cs, field_charset, ¬_used)) { tmpstr.copy(from, length, cs, field_charset); from= tmpstr.ptr(); @@ -5259,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 (String::needs_conversion(from, length, cs, field_charset)) + if (String::needs_conversion(length, cs, field_charset, ¬_used_offset)) { tmpstr.copy(from, length, cs, field_charset); from= tmpstr.ptr(); diff --git a/sql/field.h b/sql/field.h index 9a12fd48e54..b62b7a7859e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -949,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); 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/item.cc b/sql/item.cc index 4d06d0d7765..850d5a3cad3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -568,6 +568,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; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 55d511bb39d..4046a4d6414 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1657,26 +1657,19 @@ Item_cond::Item_cond(THD *thd, Item_cond *item) and_tables_cache(item->and_tables_cache) { /* - here should be following text: - - List_iterator_fast 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 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) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 7079fcf193d..7e1749ef7a0 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -929,7 +929,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; } @@ -950,7 +950,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_func.cc b/sql/item_func.cc index f90fcd5149e..34a61ba0353 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1068,9 +1068,8 @@ String *Item_func_min_max::val_str(String *str) } } } - if (!res) // If NULL - return 0; - res->set_charset(collation.collation); + if (res) // If !NULL + res->set_charset(collation.collation); return res; } case ROW_RESULT: @@ -1553,7 +1552,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); } @@ -1566,7 +1565,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); @@ -2648,10 +2647,15 @@ longlong Item_func_inet_aton::val_int() } if (c != '.') // IP number can't end on '.' { - switch (dot_count) - { - case 1: result<<= 8; - case 2: result<<= 8; + /* + 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; } diff --git a/sql/item_func.h b/sql/item_func.h index be20a9b4fc7..30f817d133b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -211,20 +211,28 @@ class Item_func_signed :public Item_int_func { public: Item_func_signed(Item *a) :Item_int_func(a) {} - double val() { null_value=args[0]->null_value; return args[0]->val(); } - longlong val_int() { null_value=args[0]->null_value; 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() { null_value=args[0]->null_value; return args[0]->val(); } - longlong val_int() { null_value=args[0]->null_value; 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); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index f5922d03868..ed6e44262c7 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2124,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); @@ -2262,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; } @@ -2273,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 fd0afb19726..4832ddbd1b1 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -518,7 +518,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; } }; @@ -618,16 +619,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: @@ -636,8 +627,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 }; }; @@ -649,8 +640,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_sum.cc b/sql/item_sum.cc index e01f9db3463..10b50fa5b3b 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1092,15 +1092,21 @@ void Item_sum_count_distinct::cleanup() 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); - table= 0; - use_tree= 0; + use_tree= 0; + } } } + bool Item_sum_count_distinct::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { @@ -1674,13 +1680,21 @@ void Item_func_group_concat::cleanup() { 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() { /* diff --git a/sql/item_sum.h b/sql/item_sum.h index dc84e4d4ab7..bb03f029997 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -397,12 +397,13 @@ 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), + 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) {} diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index ed5b9ecc0db..32fbe192d8f 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1283,14 +1283,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); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 35740ff8bf1..c79c942979a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -247,7 +247,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 /* @@ -481,14 +483,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); @@ -674,9 +675,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); @@ -759,6 +761,8 @@ 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); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 53cf792a86c..509c18d3dda 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4619,7 +4619,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}, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d39636fdc6c..4c9f3700ef1 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -370,14 +370,25 @@ SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0) } -SQL_SELECT::~SQL_SELECT() +void SQL_SELECT::cleanup() { delete quick; + quick= 0; if (free_cond) + { + free_cond=0; delete cond; + cond= 0; + } close_cached_file(&file); } + +SQL_SELECT::~SQL_SELECT() +{ + cleanup(); +} + #undef index // Fix for Unixware 7 QUICK_SELECT::QUICK_SELECT(THD *thd, TABLE *table, uint key_nr, bool no_alloc) @@ -994,7 +1005,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, } /* - We can't use an index when comparing stings of + We can't use an index when comparing strings of different collations */ if (field->result_type() == STRING_RESULT && @@ -2195,6 +2206,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree) param->table->quick_rows[key]=records; param->table->quick_key_parts[key]=param->max_key_part+1; } + DBUG_PRINT("exit", ("Records: %lu", (ulong) records)); DBUG_RETURN(records); } @@ -2569,12 +2581,7 @@ int QUICK_SELECT::get_next() int result; if (range) { // Already read through key -/* result=((range->flag & EQ_RANGE) ? - file->index_next_same(record, (byte*) range->min_key, - range->min_length) : - file->index_next(record)); -*/ - result=((range->flag & (EQ_RANGE | GEOM_FLAG) ) ? + result=((range->flag & (EQ_RANGE | GEOM_FLAG)) ? file->index_next_same(record, (byte*) range->min_key, range->min_length) : file->index_next(record)); diff --git a/sql/opt_range.h b/sql/opt_range.h index bb1cd0f7513..bf10c02c295 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -127,6 +127,7 @@ 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 skip_record() { return cond ? cond->val_int() == 0 : 0; } diff --git a/sql/protocol.cc b/sql/protocol.cc index 2d2736b20d2..40adc9e8961 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -123,7 +123,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; } @@ -313,6 +313,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 @@ -339,12 +340,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) { - 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); @@ -356,7 +356,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)); @@ -384,9 +384,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 */ @@ -585,7 +584,7 @@ bool Protocol::send_fields(List *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 c8b11eb0f58..073330e06be 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -695,7 +695,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 @@ -2629,11 +2628,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 | @@ -2644,11 +2638,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/slave.cc b/sql/slave.cc index 8af38624df6..968293369a8 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2682,7 +2682,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. diff --git a/sql/slave.h b/sql/slave.h index e42b93a47ef..d92c44dd2ba 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -324,6 +324,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/sql_acl.cc b/sql/sql_acl.cc index 77131a37869..c500f0cf1f7 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -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); @@ -2247,7 +2248,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 */ @@ -2395,7 +2396,7 @@ int mysql_grant(THD *thd, const char *db, List &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; @@ -2421,7 +2422,7 @@ int mysql_grant(THD *thd, const char *db, List &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 */ @@ -2517,14 +2518,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 @@ -2549,7 +2551,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 */ @@ -3376,7 +3378,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); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 2a4f73a986c..0ededa80ad6 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; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7b3d1fd3cd2..cbac11ac42e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -677,12 +677,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 @@ -690,55 +702,77 @@ 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; } -static int create_file(THD *thd, char *path, sql_exchange *exchange, - File *file, IO_CACHE *cache) +/* + 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) { - uint option= 4; + 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 (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; + 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); #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)); + my_close(file, MYF(0)); my_delete(path, MYF(0)); // Delete file on error, it was just created - *file= -1; - end_io_cache(cache); - return 1; + return -1; } - return 0; + return file; } int select_export::prepare(List &list, SELECT_LEX_UNIT *u) { - char path[FN_REFLEN]; 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 (create_file(thd, path, exchange, &file, &cache)) + if ((file= create_file(thd, path, exchange, &cache)) < 0) return 1; /* Check if there is any blobs in data */ { @@ -910,14 +944,6 @@ err: } -void select_export::send_error(uint errcode, const char *err) -{ - ::send_error(thd,errcode,err); - (void) my_close(file,MYF(0)); - file= -1; -} - - bool select_export::send_eof() { int error=test(end_io_cache(&cache)); @@ -935,24 +961,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 &list __attribute__((unused)), SELECT_LEX_UNIT *u) { unit= u; - if (create_file(thd, path, exchange, &file, &cache)) - return 1; - return 0; + return (int) ((file= create_file(thd, path, exchange, &cache)) < 0); } @@ -995,13 +1009,6 @@ err: } -void select_dump::send_error(uint errcode,const char *err) -{ - ::send_error(thd,errcode,err); - (void) my_close(file,MYF(0)); - file= -1; -} - bool select_dump::send_eof() { int error=test(end_io_cache(&cache)); @@ -1013,11 +1020,13 @@ 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 &items) { DBUG_ENTER("select_singlerow_subselect::send_data"); @@ -1040,6 +1049,7 @@ bool select_singlerow_subselect::send_data(List &items) DBUG_RETURN(0); } + bool select_max_min_finder_subselect::send_data(List &items) { DBUG_ENTER("select_max_min_finder_subselect::send_data"); @@ -1145,8 +1155,9 @@ bool select_exists_subselect::send_data(List &items) /*************************************************************************** -** Dump of select to variables + Dump of select to variables ***************************************************************************/ + int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) { List_iterator_fast li(list); @@ -1163,7 +1174,8 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) { ls= gl++; Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item); - xx->fix_fields(thd,(TABLE_LIST*) thd->lex->select_lex.table_list.first,&item); + xx->fix_fields(thd,(TABLE_LIST*) thd->lex->select_lex.table_list.first, + &item); xx->fix_length_and_dec(); vars.push_back(xx); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 7971137d848..5034007cd4d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -565,6 +565,8 @@ public: struct st_mysql_bind *client_params; char *extra_data; ulong extra_length; + char *query_rest; + uint32 query_rest_length; #endif NET net; // client connection descriptor MEM_ROOT warn_root; // For warnings and errors @@ -962,41 +964,41 @@ public: }; -class select_export :public select_result { - sql_exchange *exchange; - File file; - IO_CACHE cache; - ha_rows row_count; - 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(); - int prepare(List &list, SELECT_LEX_UNIT *u); - bool send_fields(List &list, - uint flag) { return 0; } - bool send_data(List &items); - void send_error(uint errcode,const char *err); - bool send_eof(); -}; - - -class select_dump :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_dump(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) + select_to_file(sql_exchange *ex) :exchange(ex), file(-1),row_count(0L) { path[0]=0; } - ~select_dump(); - int prepare(List &list, SELECT_LEX_UNIT *u); - bool send_fields(List &list, - uint flag) { return 0; } - bool send_data(List &items); + ~select_to_file(); + bool send_fields(List &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) :select_to_file(ex) {} + ~select_export(); + int prepare(List &list, SELECT_LEX_UNIT *u); + bool send_data(List &items); + bool send_eof(); +}; + + +class select_dump :public select_to_file { +public: + select_dump(sql_exchange *ex) :select_to_file(ex) {} + int prepare(List &list, SELECT_LEX_UNIT *u); + bool send_data(List &items); bool send_eof(); }; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index ed9136a6d5b..46dd4d7996e 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"; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 374e56ecdd4..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,145 +121,91 @@ 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); - /* - We have to do access checks here as this code is executed before any - sql command is started to execute. - */ -#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 (!(derived_result= new select_union(0))) + DBUG_RETURN(1); // out of memory - if (!(res=open_and_lock_tables(thd,tables))) - { - 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. + // st_select_lex_unit::prepare correctly work for single select + if ((res= unit->prepare(thd, derived_result, 0))) + goto exit; - */ - fix_tables_pointers(unit); - } - - 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; - - /* - 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); + 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); + + 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; + if (unit->select_limit_cnt < first_select->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; + if (unit->select_limit_cnt == HA_POS_ERROR) + first_select->options&= ~OPTION_FOUND_ROWS; + + 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 { - unit->offset_limit_cnt= first_select->offset_limit; - unit->select_limit_cnt= first_select->select_limit+ - first_select->offset_limit; - if (unit->select_limit_cnt < first_select->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; - if (unit->select_limit_cnt == HA_POS_ERROR) - first_select->options&= ~OPTION_FOUND_ROWS; - - 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 + 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; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - org_table_list->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(); - unit->cleanup(); - } - org_table_list->db= (char *)""; - // Force read of table stats in the optimizer - table->file->info(HA_STATUS_VARIABLE); + 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 + table->grant.privilege= SELECT_ACL; +#endif + 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 @@ -223,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_insert.cc b/sql/sql_insert.cc index 74de1772555..58c3d143a4f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -188,7 +188,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"; @@ -647,7 +646,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 c6322b116ec..f10ddd89f35 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -181,6 +181,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 */ @@ -193,6 +210,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; @@ -420,7 +444,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() @@ -667,32 +690,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) @@ -701,16 +709,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); @@ -885,8 +902,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 @@ -988,6 +1010,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() @@ -1286,12 +1309,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; } @@ -1303,8 +1324,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. @@ -1318,8 +1338,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; @@ -1345,15 +1364,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; } @@ -1400,63 +1416,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; @@ -1467,21 +1495,25 @@ List* st_select_lex::get_item_list() return &item_list; } + List* st_select_lex::get_use_index() { return use_index_ptr; } + List* 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) @@ -1493,6 +1525,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()) @@ -1535,6 +1619,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 68385bc7bba..3f56be18c4a 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -232,6 +232,7 @@ public: UNCACHEABLE_DEPENDENT UNCACHEABLE_RAND UNCACHEABLE_SIDEEFFECT + UNCACHEABLE_EXPLAIN */ uint8 uncacheable; enum sub_select_type linkage; @@ -304,7 +305,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 @@ -336,8 +338,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; } @@ -355,14 +356,15 @@ public: int exec(); int cleanup(); + bool check_updateable(char *db, char *table); void print(String *str); + friend void mysql_init_query(THD *thd); 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; @@ -497,6 +499,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); diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc index 1d16771c1a4..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; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index da00965471a..2108f5513c0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -48,6 +48,7 @@ extern "C" int gethostname(char *name, int namelen); #endif +char *memdup_mysql(struct st_mysql *mysql, const char*data, int length); static int check_for_max_user_connections(THD *thd, USER_CONN *uc); static void decrease_user_connections(USER_CONN *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); @@ -1397,11 +1398,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) @@ -1414,7 +1417,13 @@ 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 + thd->query_rest= (char*)memdup_mysql(thd->mysql, packet, length); + thd->query_rest_length= length; + break; +#endif /*EMBEDDED_LIBRARY*/ } if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -1789,34 +1798,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_VOID_RETURN; - } - } - } - } 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_VOID_RETURN; /* @@ -1875,7 +1859,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; @@ -1914,7 +1897,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; @@ -2123,7 +2105,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_VOID_RETURN; ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ? @@ -2338,6 +2320,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; @@ -2669,23 +2653,15 @@ mysql_execute_command(THD *thd) } if (!walk) { - if (lex->derived_tables) - { - // are we trying to delete derived table? - for (walk= (TABLE_LIST*) tables; walk; walk= walk->next) - { - if (!strcmp(auxi->real_name,walk->alias) && - walk->derived) - { - net_printf(thd, ER_NON_UPDATABLE_TABLE, - auxi->real_name, "DELETE"); - goto error; - } - } - } 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; auxi->table_list= walk; // Remember corresponding table } @@ -2699,21 +2675,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))) { @@ -2958,7 +2940,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) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index de0d0c8aca8..2cf0000d973 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -733,7 +733,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)) @@ -746,7 +746,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); @@ -1005,8 +1004,10 @@ void mysql_stmt_execute(THD *thd, char *packet) 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); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index aeaad4559e2..ea5050f2550 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -173,7 +173,6 @@ int handle_select(THD *thd, LEX *lex, select_result *result) register SELECT_LEX *select_lex = &lex->select_lex; DBUG_ENTER("handle_select"); - fix_tables_pointers(lex->all_selects_list); if (select_lex->next_select()) res=mysql_union(thd, lex, result, &lex->unit); else @@ -1511,12 +1510,7 @@ JOIN::cleanup() JOIN_TAB *tab, *end; for (tab= join_tab, end= tab+tables ; tab != end ; tab++) { - delete tab->select; - delete tab->quick; - tab->select=0; - tab->quick=0; - x_free(tab->cache.buff); - tab->cache.buff= 0; + tab->cleanup(); } } tmp_join->tmp_join= 0; @@ -1580,8 +1574,8 @@ mysql_select(THD *thd, Item ***rref_pointer_array, goto err; } } - free_join= 0; } + free_join= 0; join->select_options= select_options; } else @@ -1648,8 +1642,8 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, { select->head=table; table->reginfo.impossible_range=0; - if ((error=select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,limit)) - == 1) + if ((error=select->test_quick_select(thd, *(key_map *)keys,(table_map) 0, + limit)) == 1) DBUG_RETURN(select->quick->records); if (error == -1) { @@ -2700,22 +2694,35 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, do { uint keypart=keyuse->keypart; - uint found_part_ref_or_null= KEY_OPTIMIZE_REF_OR_NULL; + table_map best_part_found_ref= 0; + double best_prev_record_reads= DBL_MAX; do { if (!(rest_tables & keyuse->used_tables) && !(found_ref_or_null & keyuse->optimize)) { found_part|=keyuse->keypart_map; - found_ref|= keyuse->used_tables; + double tmp= prev_record_reads(join, + (found_ref | + keyuse->used_tables)); + if (tmp < best_prev_record_reads) + { + best_part_found_ref= keyuse->used_tables; + best_prev_record_reads= tmp; + } if (rec > keyuse->ref_table_rows) rec= keyuse->ref_table_rows; - found_part_ref_or_null&= keyuse->optimize; + /* + If there is one 'key_column IS NULL' expression, we can + use this ref_or_null optimsation of this field + */ + found_ref_or_null|= (keyuse->optimize & + KEY_OPTIMIZE_REF_OR_NULL); } keyuse++; - found_ref_or_null|= found_part_ref_or_null; } while (keyuse->table == table && keyuse->key == key && keyuse->keypart == keypart); + found_ref|= best_part_found_ref; } while (keyuse->table == table && keyuse->key == key); /* @@ -3747,6 +3754,41 @@ bool error_if_full_join(JOIN *join) } +/* + cleanup JOIN_TAB + + SYNOPSIS + JOIN_TAB::cleanup() +*/ + +void JOIN_TAB::cleanup() +{ + delete select; + select= 0; + delete quick; + quick= 0; + x_free(cache.buff); + cache.buff= 0; + if (table) + { + if (table->key_read) + { + table->key_read= 0; + table->file->extra(HA_EXTRA_NO_KEYREAD); + } + /* Don't free index if we are using read_record */ + if (!read_record.table) + table->file->index_end(); + /* + We need to reset this for next select + (Tested in part_of_refkey) + */ + table->reginfo.join_tab= 0; + } + end_read_record(&read_record); +} + + /* Free resources of given join @@ -3781,11 +3823,6 @@ JOIN::join_free(bool full) { if (tab->table) { - if (tab->table->key_read) - { - tab->table->key_read= 0; - tab->table->file->extra(HA_EXTRA_NO_KEYREAD); - } /* Don't free index if we are using read_record */ if (!tab->read_record.table) tab->table->file->index_end(); @@ -3796,29 +3833,7 @@ JOIN::join_free(bool full) { for (tab= join_tab, end= tab+tables; tab != end; tab++) { - delete tab->select; - delete tab->quick; - tab->select=0; - tab->quick=0; - x_free(tab->cache.buff); - tab->cache.buff= 0; - if (tab->table) - { - if (tab->table->key_read) - { - tab->table->key_read= 0; - tab->table->file->extra(HA_EXTRA_NO_KEYREAD); - } - /* Don't free index if we are using read_record */ - if (!tab->read_record.table) - tab->table->file->index_end(); - /* - We need to reset this for next select - (Tested in part_of_refkey) - */ - tab->table->reginfo.join_tab= 0; - } - end_read_record(&tab->read_record); + tab->cleanup(); } table= 0; } @@ -7203,9 +7218,12 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, table->file->info(HA_STATUS_VARIABLE); // Get record count table->sort.found_records=filesort(thd, table,sortorder, length, select, filesort_limit, &examined_rows); - tab->records=table->sort.found_records; // For SQL_CALC_ROWS - delete select; - tab->select=0; + tab->records= table->sort.found_records; // For SQL_CALC_ROWS + if (select) + { + select->cleanup(); // filesort did select + tab->select= 0; + } tab->select_cond=0; tab->type=JT_ALL; // Read with normal read_record tab->read_first_record= join_init_read_record; @@ -9133,6 +9151,9 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) sl; sl= sl->next_select()) { + // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only + uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN); + res= mysql_explain_select(thd, sl, (((&thd->lex->select_lex)==sl)? ((thd->lex->all_selects_list != sl) ? @@ -9140,13 +9161,13 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ((sl == first)? ((sl->linkage == DERIVED_TABLE_TYPE) ? "DERIVED": - ((sl->uncacheable & UNCACHEABLE_DEPENDENT) ? + ((uncacheable & UNCACHEABLE_DEPENDENT) ? "DEPENDENT SUBQUERY": - (sl->uncacheable?"UNCACHEABLE SUBQUERY": + (uncacheable?"UNCACHEABLE SUBQUERY": "SUBQUERY"))): - ((sl->uncacheable & UNCACHEABLE_DEPENDENT) ? + ((uncacheable & UNCACHEABLE_DEPENDENT) ? "DEPENDENT UNION": - sl->uncacheable?"UNCACHEABLE UNION": + uncacheable?"UNCACHEABLE UNION": "UNION"))), result); if (res) diff --git a/sql/sql_select.h b/sql/sql_select.h index ed650c450c0..36526bee066 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -108,6 +108,8 @@ typedef struct st_join_table { TABLE_REF ref; JOIN_CACHE cache; JOIN *join; + + void cleanup(); } JOIN_TAB; @@ -428,7 +430,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 3b937f97089..f076e2fe802 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -519,8 +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->net.last_errno= 0; + thd->clear_error(); } else { @@ -1086,8 +1085,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd) DBUG_RETURN(0); } -/* possible TODO: call find_keyword() from sql_lex.cc here */ -static bool require_quotes(const char *name, uint length) +static inline const char *require_quotes(const char *name, uint length) { uint i, d, c; for (i=0; iident_map[c]) - return 1; + 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 (; curvariables.sql_mode & MODE_ANSI_QUOTES) qtype= '\"'; else qtype= '`'; - if ((thd->options & OPTION_QUOTE_SHOW_CREATE) || - require_quotes(name, length)) + 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); + } } } @@ -1338,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 7f26a0febda..093b85b46b7 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef HAVE_FCONVERT #include #endif @@ -230,68 +231,86 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) /* - Checks that the source string can be just copied - to the destination string without conversion. - If either character set conversion or adding leading - zeros (e.g. for UCS-2) must be done then return - value is TRUE else 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(const char *str, uint32 arg_length, - CHARSET_INFO *from_cs, - CHARSET_INFO *to_cs) + +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) && (!(arg_length % to_cs->mbminlen)))) + ((from_cs == &my_charset_bin) && + (!(*offset=(arg_length % to_cs->mbminlen))))) return FALSE; - return TRUE; } + /* -** 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 + 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, +bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset, CHARSET_INFO *cs) { /* How many bytes are in incomplete character */ - uint32 offs= (arg_length % cs->mbminlen); + offset= cs->mbmaxlen - offset; /* How many zeros we should prepend */ + DBUG_ASSERT(offset && offset != cs->mbmaxlen); - if (!offs) /* All characters are complete, just copy */ - { - copy(str, arg_length, cs); - return FALSE; - } - - offs= cs->mbmaxlen - offs; /* How many zeros we should prepend */ - uint32 aligned_length= arg_length + offs; + uint32 aligned_length= arg_length + offset; if (alloc(aligned_length)) return TRUE; /* - Probably this condition is not really necessary - because if aligned_length is 0 then offs is 0 too - and we'll return after calling set(). + 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. */ - if ((str_length= aligned_length)) - { - /* - 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, offs); - memcpy(Ptr + offs, str, arg_length); - } + bzero((char*) Ptr, offset); + memcpy(Ptr + offset, str, arg_length); Ptr[aligned_length]=0; - str_charset=cs; + /* str_length is always >= 0 as arg_length is != 0 */ + str_length= aligned_length; + str_charset= cs; return FALSE; } @@ -300,14 +319,14 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length, CHARSET_INFO *cs) { /* How many bytes are in incomplete character */ - uint32 offs= (arg_length % cs->mbminlen); + uint32 offset= (arg_length % cs->mbminlen); - if (!offs) /* All characters are complete, just copy */ + if (!offset) /* All characters are complete, just copy */ { set(str, arg_length, cs); return FALSE; } - return copy_aligned(str, arg_length, cs); + return copy_aligned(str, arg_length, offset, cs); } /* Copy with charset convertion */ @@ -315,14 +334,11 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length, bool String::copy(const char *str, uint32 arg_length, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs) { - if (!needs_conversion(str, arg_length, from_cs, to_cs)) - { + 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) && (arg_length % to_cs->mbminlen)) - { - return copy_aligned(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)) @@ -744,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 9c0900137e3..163156fdfe2 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -183,9 +183,11 @@ 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(const char *s, uint32 arg_length, - CHARSET_INFO *cs_from, CHARSET_INFO *cs_to); - bool copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs); + 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); 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 226086d0d24..75fd9be88bd 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -442,6 +442,12 @@ 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; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c6e470fd09f..df7b2cf809f 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); @@ -431,7 +430,6 @@ 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; @@ -482,8 +480,11 @@ int mysql_multi_update(THD *thd, 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); + } } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f25f4689352..9e0ed496f70 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -918,7 +918,7 @@ create: &tmp_table_alias : (LEX_STRING*) 0), TL_OPTION_UPDATING, - ((using_update_log)? + (using_update_log ? TL_READ_NO_INSERT: TL_READ))) YYABORT; @@ -2189,10 +2189,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; @@ -2575,8 +2574,6 @@ 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 ')' @@ -3060,7 +3057,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(); @@ -3084,16 +3081,16 @@ in_sum_expr: }; cast_type: - BINARY { $$=ITEM_CAST_BINARY; } + 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; } + | 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: @@ -3898,6 +3895,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 diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 8d4081fb2aa..574156a99ed 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -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 */ diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 43575bbc277..fc22938d46e 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -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, diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 366a5d500ed..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 */ diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index 44a58b2b906..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 */ diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 5475c3bd363..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, diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index c00ded21575..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, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index b5e8c4598a0..46f3e2f4fc3 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -274,6 +274,25 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), 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 62eb1418970..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) { @@ -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 42f32fe739b..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 */ diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 09552a0dc23..d577b964405 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -874,7 +874,8 @@ NULL,NULL,NULL,NULL,NULL,NULL,NULL,plFF static -int my_mb_wc_tis620(CHARSET_INFO *cs,my_wc_t *wc, +int my_mb_wc_tis620(CHARSET_INFO *cs __attribute__((unused)), + my_wc_t *wc, const unsigned char *str, const unsigned char *end __attribute__((unused))) { @@ -886,7 +887,8 @@ int my_mb_wc_tis620(CHARSET_INFO *cs,my_wc_t *wc, } static -int my_wc_mb_tis620(CHARSET_INFO *cs,my_wc_t wc, +int my_wc_mb_tis620(CHARSET_INFO *cs __attribute__((unused)), + my_wc_t wc, unsigned char *str, unsigned char *end __attribute__((unused))) { @@ -919,6 +921,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_tis620, /* mb_wc */ my_wc_mb_tis620, /* wc_mb */ diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 775501027d0..bb74e0cf56b 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1001,6 +1001,17 @@ uint my_charpos_ucs2(CHARSET_INFO *cs __attribute__((unused)), return pos*2; } +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) @@ -1287,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 */ diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index f6928e9426e..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 */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 8004fba75b7..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, diff --git a/tests/client_test.c b/tests/client_test.c index 66637dcb04b..681d4013eec 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,29 +5595,26 @@ 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); + /* 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); - stmt = mysql_prepare(mysql,"insert into test_pure(c2) values(10)",100); - mystmt_init(stmt); - - rc = mysql_bind_param(stmt, bind); - mystmt_r(stmt, rc); - - mysql_stmt_close(stmt); -#endif - - stmt = mysql_prepare(mysql,"insert into test_pure(c2) values(?)",100); - mystmt_init(stmt); - -#ifndef DBUG_OFF rc = mysql_execute(stmt); - mystmt_r(stmt, rc);/* No parameters supplied */ -#endif + mystmt(stmt, rc); + + rc = mysql_bind_result(stmt, (MYSQL_BIND*)0); + mystmt(stmt, rc); + + mysql_stmt_close(stmt); + + stmt = mysql_simple_prepare(mysql,"insert into test_pure(c2) values(?)"); + mystmt_init(stmt); bind[0].length= &length; bind[0].is_null= 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,86 @@ 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)); +} + +/* + 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 +8414,9 @@ 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 */ end_time= time((time_t *)0); total_time+= difftime(end_time, start_time);