diff options
99 files changed, 1620 insertions, 390 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index dff4cec203c..177107f8779 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -73,6 +73,7 @@ monty@donna.mysql.fi monty@hundin.mysql.fi monty@mashka.(none) monty@mashka.mysql.fi +monty@mishka.mysql.fi monty@narttu. monty@narttu.mysql.fi monty@rescue. @@ -97,6 +98,7 @@ peter@linux.local peter@mysql.com peterg@mysql.com pgulutzan@linux.local +ram@gw.mysql.r18.ru ram@gw.udmsearch.izhnet.ru ram@mysql.r18.ru ram@ram.(none) diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 9f5ac657a0b..0541ebe96ce 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -8,7 +8,7 @@ use Getopt::Long; $opt_distribution=$opt_user=$opt_config_env=""; $opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix=""; $opt_tmp=$opt_version_suffix=""; -$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=0; +$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=$opt_readline=0; $opt_innodb=$opt_bdb=$opt_raid=$opt_libwrap=0; GetOptions( @@ -36,6 +36,7 @@ GetOptions( "perl-files=s", "perl-options=s", "raid", + "readline", "stage=i", "static-client", "static-perl", @@ -231,6 +232,7 @@ if ($opt_stage <= 1) $opt_config_options.= " --with-low-memory" if ($opt_with_low_memory); $opt_config_options.= " --with-mysqld-ldflags=-all-static" if ($opt_static_server); $opt_config_options.= " --with-raid" if ($opt_raid); + $opt_config_options.= " --with-readline" if ($opt_readline); $opt_config_options.= " --with-embedded-server" unless ($opt_without_embedded); # Only enable InnoDB when requested (required to be able to @@ -448,10 +450,10 @@ $0 takes the following options: --bdb Compile with support for Berkeley DB tables ---config-env <environment for configure> +--config-env=<environment for configure> To set up the environment, like 'CC=cc CXX=gcc CXXFLAGS=-O3' ---config-options <options> +--config-options=<options> To add some extra options to configure (e.g. '--with-perl=yes') --dbd-options <options> @@ -463,7 +465,7 @@ Print all shell commands on stdout. --delete Delete the distribution file. ---distribution <distribution_file> +--distribution=<distribution_file> Name of the MySQL source distribution file. --enable-shared @@ -484,7 +486,7 @@ Compile with TCP wrapper support --local-perl Install Perl modules locally ---make-options <options> +--make-options=<options> Options to make after configure. (Like 'CXXLD=gcc') --no-crash-me @@ -502,16 +504,22 @@ Do not run the benchmark test (written in perl) --no-mysqltest Do not run the the mysql-test-run test (Same as 'make test') ---perl-files=list of files +--no-perl +Do not compile or install Perl modules, use the system installed ones + +--perl-files=<list of files> Compile and install the given perl modules. ---perl-options <options> +--perl-options=<options> Build Perl modules with the additional options --raid Compile with RAID support ---stage (1-6) +--readline +Compile against readline library instead of libedit + +--stage=[1-6] Start script from some specific point. --static-client @@ -526,18 +534,18 @@ Build statically linked server binary --tcpip Connect to the server to be tested via TCP/IP instead of socket ---tmp <directory> +--tmp=<directory> Use a different temporary directory than /tmp --use-old-distribution Do not clean up the build environment and extract a fresh source distribution, use an existing one instead. ---user <user_name> +--user=<user_name> Mail 'user_name'\@mysql.com if something went wrong. If user is empty then no mail is sent. ---version-suffix suffix +--version-suffix=suffix Set name suffix (e.g. 'com' or '-max') for a distribution --with-debug @@ -546,7 +554,7 @@ Build binaries with debug information (implies "--no-strip") --with-low-memory Use less memory when compiling. ---with-other-libc <path to libc> +--with-other-libc=<path to libc> Link against libc and other standard libraries installed in the specified non-standard location overriding default. diff --git a/Build-tools/mysql-copyright b/Build-tools/mysql-copyright index 70b65d3f2cf..a798ee7ab65 100755 --- a/Build-tools/mysql-copyright +++ b/Build-tools/mysql-copyright @@ -3,8 +3,11 @@ # Untar a MySQL distribution, change the copyright texts, # pack it up again to a given directory -$VER="1.2"; +$VER="1.3"; +use Cwd; +use File::Basename; +use File::Copy; use Getopt::Long; $opt_help = 0; @@ -17,8 +20,7 @@ GetOptions("help","version","target=s") || error(); # fix the directory prefix for target dir -$WD= `pwd`; -chop $WD; +$WD= cwd(); $opt_target= $WD . '/' . $opt_target; &main(); @@ -73,11 +75,11 @@ sub main $newdistname= $1."com".$2.$3; } # find out the extract path (should be same as distname!) - $destdir= `tar tvzf ../$distfile | head -1`; - # remove leading crab - $destdir =~ s/.*\d+:\d+:\d+[ ]//; - # remove newline and slash from the end - $destdir= substr($destdir, 0, -2); + chomp($destdir= `tar ztf ../$distfile | head -1`); + # remove slash from the end + $destdir= substr($destdir, 0, -1); + print "destdir: $destdir\n"; + print "distname: $distname\n"; if ("$destdir" ne "$distname") { @@ -96,15 +98,18 @@ sub main # remove the 'PUBLIC' file from distribution and copy MySQLEULA.txt # on the toplevel of the directory instead. file 'PUBLIC' shouldn't # exist in the new mysql distributions, but let's be sure.. - `rm -f $destdir/PUBLIC $destdir/README`; - `cp -p $WD/Docs/MySQLEULA.txt $destdir/`; + unlink("$destdir/PUBLIC", "$destdir/README"); + copy("$WD/Docs/MySQLEULA.txt", "$destdir"); + # remove readline subdir + `rm -rf $destdir/cmd-line-utils/readline`; + # fix file copyrights &fix_usage_copyright(); &add_copyright(); # rename the directory with new distribution name - `mv -f $destdir $newdistname`; + rename($destdir, $newdistname); # tar the new distribution `tar cz -f $opt_target/$newdistname.tar.gz *`; diff --git a/client/mysqltest.c b/client/mysqltest.c index 92ed47221bd..fd8cf7ecc8b 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -664,7 +664,7 @@ static VAR* var_obtain(char* name, int len) if ((v = (VAR*)hash_search(&var_hash, name, len))) return v; v = var_init(0, name, len, "", 0); - hash_insert(&var_hash, (byte*)v); + my_hash_insert(&var_hash, (byte*)v); return v; } @@ -2178,7 +2178,7 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) if (!(flags & QUERY_REAP)) DBUG_RETURN(0); - if (mysql_read_query_result(mysql) || + if ((*mysql->methods->read_query_result)(mysql) || (!(last_result = res = mysql_store_result(mysql)) && mysql_field_count(mysql))) { @@ -2400,7 +2400,7 @@ static void var_from_env(const char *name, const char *def_val) tmp = def_val; v = var_init(0, name, 0, tmp, 0); - hash_insert(&var_hash, (byte*)v); + my_hash_insert(&var_hash, (byte*)v); } @@ -2416,9 +2416,9 @@ static void init_var_hash(MYSQL *mysql) var_from_env("MYSQL_TEST_DIR", "/tmp"); var_from_env("BIG_TEST", opt_big_test ? "1" : "0"); v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0); - hash_insert(&var_hash, (byte*) v); + my_hash_insert(&var_hash, (byte*) v); v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0); - hash_insert(&var_hash, (byte*) v); + my_hash_insert(&var_hash, (byte*) v); DBUG_VOID_RETURN; } diff --git a/configure.in b/configure.in index 59b81e8a709..eb8daea18d4 100644 --- a/configure.in +++ b/configure.in @@ -38,12 +38,12 @@ do case $host_os in netware* | modesto*) echo "$i/errmsg.sys: $i/errmsg.txt - \$(top_builddir)/extra/comp_err.linux \$^ $i/errmsg.sys" \ + \$(top_builddir)/extra/comp_err.linux -C\$(srcdir)/charsets/ \$^ $i/errmsg.sys" \ >> $AVAILABLE_LANGUAGES_ERRORS_RULES ;; *) echo "$i/errmsg.sys: $i/errmsg.txt - \$(top_builddir)/extra/comp_err \$^ $i/errmsg.sys" \ + \$(top_builddir)/extra/comp_err -C\$(srcdir)/charsets/ \$^ $i/errmsg.sys" \ >> $AVAILABLE_LANGUAGES_ERRORS_RULES ;; esac diff --git a/extra/comp_err.c b/extra/comp_err.c index 2ec4240392f..07369aa565e 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -70,7 +70,7 @@ int main(int argc,char *argv[]) fclose(from); goto end; } - + if (!(csnum= get_charset_number(charset_name, MY_CS_PRIMARY))) { fprintf(stderr,"Unknown character '%s' in '%s'\n",charset_name, *argv); diff --git a/include/hash.h b/include/hash.h index 6c805bc2da7..3c2ae32c70e 100644 --- a/include/hash.h +++ b/include/hash.h @@ -49,7 +49,7 @@ void hash_free(HASH *tree); byte *hash_element(HASH *hash,uint idx); gptr hash_search(HASH *info,const byte *key,uint length); gptr hash_next(HASH *info,const byte *key,uint length); -my_bool hash_insert(HASH *info,const byte *data); +my_bool my_hash_insert(HASH *info,const byte *data); my_bool hash_delete(HASH *hash,byte *record); my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length); void hash_replace(HASH *hash, uint idx, byte *new_row); diff --git a/include/m_ctype.h b/include/m_ctype.h index 8116058d687..b1557e5293b 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -63,6 +63,7 @@ typedef struct unicase_info_st #define MY_CS_STRNXFRM 64 /* if strnxfrm is used for sort */ #define MY_CS_UNICODE 128 /* is a charset is full unicode */ #define MY_CS_NONTEXT 256 /* if a charset is not sprintf() compatible */ +#define MY_CS_AVAILABLE 512 /* If either compiled-in or loaded*/ #define MY_CHARSET_UNDEFINED 0 @@ -74,6 +75,12 @@ typedef struct my_uni_idx_st uchar *tab; } MY_UNI_IDX; +typedef struct +{ + uint beg; + uint end; + uint mblen; +} my_match_t; enum my_lex_states { @@ -115,12 +122,18 @@ typedef struct my_collation_handler_st int (*strcasecmp)(struct charset_info_st *, const char *, const char *); + uint (*instr)(struct charset_info_st *, + const char *big, uint b_length, + const char *small, uint s_length, + my_match_t *match, uint nmatch); + /* Hash calculation */ void (*hash_sort)(struct charset_info_st *cs, const uchar *key, uint len, ulong *nr1, ulong *nr2); } MY_COLLATION_HANDLER; -extern MY_COLLATION_HANDLER my_collation_bin_handler; +extern MY_COLLATION_HANDLER my_collation_mb_bin_handler; +extern MY_COLLATION_HANDLER my_collation_8bit_bin_handler; extern MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler; @@ -243,6 +256,11 @@ extern void my_hash_sort_simple(CHARSET_INFO *cs, extern uint my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, uint length); +extern uint my_instr_simple(struct charset_info_st *, + const char *big, uint b_length, + const char *small, uint s_length, + my_match_t *match, uint nmatch); + /* Functions for 8bit */ extern void my_caseup_str_8bit(CHARSET_INFO *, char *); @@ -307,6 +325,10 @@ 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_instr_mb(struct charset_info_st *, + const char *big, uint b_length, + const char *small, uint s_length, + my_match_t *match, uint nmatch); extern my_bool my_parse_charset_xml(const char *bug, uint len, diff --git a/include/my_pthread.h b/include/my_pthread.h index f4976abee10..424452a9298 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -1,4 +1,3 @@ - /* Copyright (C) 2000 MySQL AB This program is free software; you can redistribute it and/or modify diff --git a/include/mysql.h b/include/mysql.h index fa65395d49b..963c35e92ea 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -360,6 +360,7 @@ int STDCALL mysql_send_query(MYSQL *mysql, const char *q, int STDCALL mysql_real_query(MYSQL *mysql, const char *q, unsigned long length); MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); +MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); /* perform query on master */ my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, @@ -461,6 +462,7 @@ int STDCALL mysql_manager_command(MYSQL_MANAGER* con, int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf, int res_buf_size); +my_bool STDCALL mysql_read_query_result(MYSQL *mysql); /* @@ -541,9 +543,6 @@ typedef struct st_mysql_stmt } MYSQL_STMT; -#define mysql_read_query_result(mysql) (*(mysql)->methods->read_query_result)(mysql) -#define mysql_use_result(mysql) (*(mysql)->methods->use_result)(mysql) - typedef struct st_mysql_methods { my_bool (STDCALL *read_query_result)(MYSQL *mysql); @@ -555,14 +554,17 @@ typedef struct st_mysql_methods unsigned long arg_length, my_bool skip_check); MYSQL_DATA *(STDCALL *read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields, - uint fields); + unsigned int fields); MYSQL_RES * (STDCALL *use_result)(MYSQL *mysql); void (STDCALL *fetch_lengths)(unsigned long *to, - MYSQL_ROW column, uint field_count); + MYSQL_ROW column, unsigned int field_count); +#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) MYSQL_FIELD * (STDCALL *list_fields)(MYSQL *mysql); my_bool (STDCALL *read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); int (STDCALL *stmt_execute)(MYSQL_STMT *stmt); MYSQL_DATA *(STDCALL *read_binary_rows)(MYSQL_STMT *stmt); + int (STDCALL *unbuffered_fetch)(MYSQL *mysql, char **row); +#endif } MYSQL_METHODS; diff --git a/include/mysql_com.h b/include/mysql_com.h index 4d2b9d7cdce..d5a70e4dfe8 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -245,7 +245,7 @@ my_bool net_realloc(NET *net, unsigned long length); #ifndef EMBEDDED_LIBRARY /* To be removed by HF */ my_bool net_flush(NET *net); #else -#define net_flush(A) ((my_bool)0) +#define net_flush(A) #endif my_bool my_net_write(NET *net,const char *packet,unsigned long len); diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h index 4fdbab08969..d0432503ee9 100644 --- a/libmysql/client_settings.h +++ b/libmysql/client_settings.h @@ -56,3 +56,4 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, uint fields); int STDCALL cli_stmt_execute(MYSQL_STMT *stmt); MYSQL_DATA *cli_read_binary_rows(MYSQL_STMT *stmt); +int STDCALL cli_unbuffered_fetch(MYSQL *mysql, char **row); diff --git a/libmysql/dll.c b/libmysql/dll.c index 92aa611000b..e9334d68a0c 100644 --- a/libmysql/dll.c +++ b/libmysql/dll.c @@ -123,7 +123,7 @@ extern "C" unsigned long _System DllMain(unsigned long modhandle, unsigned long flag) { if (flag == 0) { - tzset(); // Set tzname + tzset(); /* Set tzname */ time_t currentTime = time(NULL); struct tm *ts = localtime(¤tTime); if (ts->tm_isdst > 0) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 954eae89a2b..3efce367cae 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -279,7 +279,7 @@ my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, DBUG_ENTER("mysql_master_query"); if (mysql_master_send_query(mysql, q, length)) DBUG_RETURN(1); - DBUG_RETURN(mysql_read_query_result(mysql)); + DBUG_RETURN((*mysql->methods->read_query_result)(mysql)); } my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, @@ -301,7 +301,7 @@ my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, DBUG_ENTER("mysql_slave_query"); if (mysql_slave_send_query(mysql, q, length)) DBUG_RETURN(1); - DBUG_RETURN(mysql_read_query_result(mysql)); + DBUG_RETURN((*mysql->methods->read_query_result)(mysql)); } @@ -629,7 +629,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, } } else - *end++= '\0'; // empty password + *end++= '\0'; /* empty password */ /* Add database if needed */ end= strmov(end, db ? db : "") + 1; @@ -1982,7 +1982,7 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) if (cli_advanced_command(mysql, COM_EXECUTE, buff, MYSQL_STMT_HEADER, packet, length, 1) || - mysql_read_query_result(mysql)) + (*mysql->methods->read_query_result)(mysql)) { set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); DBUG_RETURN(1); @@ -2965,6 +2965,14 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) return 0; } +int STDCALL cli_unbuffered_fetch(MYSQL *mysql, char **row) +{ + if (packet_error == net_safe_read(mysql)) + return 1; + + *row= (mysql->net.read_pos[0] == 254) ? NULL : (mysql->net.read_pos+1); + return 0; +} /* Fetch and return row data to bound buffers, if any @@ -2994,20 +3002,20 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt) } else /* un-buffered */ { - if (packet_error == net_safe_read(mysql)) + if((*mysql->methods->unbuffered_fetch)(mysql, ( char **)&row)) { set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, mysql->net.sqlstate); DBUG_RETURN(1); } - if (mysql->net.read_pos[0] == 254) + if (!row) { mysql->status= MYSQL_STATUS_READY; stmt->current_row= 0; goto no_data; } - row= mysql->net.read_pos+1; - } + } + stmt->current_row= row; DBUG_RETURN(stmt_fetch_row(stmt, row)); @@ -3480,7 +3488,18 @@ my_bool 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_read_query_result(mysql)); + DBUG_RETURN((*mysql->methods->read_query_result)(mysql)); DBUG_RETURN(0); } + +MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql) +{ + return (*mysql->methods->use_result)(mysql); +} + +my_bool STDCALL mysql_read_query_result(MYSQL *mysql) +{ + return (*mysql->methods->read_query_result)(mysql); +} + diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h index 833cc1b1f80..75461bbfbe0 100644 --- a/libmysqld/embedded_priv.h +++ b/libmysqld/embedded_priv.h @@ -26,6 +26,7 @@ C_MODE_START extern void lib_connection_phase(NET *net, int phase); extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); extern void *create_embedded_thd(int client_flag, char *db); +extern void free_embedded_thd(MYSQL *mysql); extern MYSQL_METHODS embedded_methods; void free_old_query(MYSQL *mysql); extern my_bool server_inited; diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 8cc7a5029b0..38fc3cce9ee 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -97,7 +97,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, static MYSQL_DATA * STDCALL emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)), - uint fields __attribute__((unused))) + unsigned int fields __attribute__((unused))) { MYSQL_DATA *result= ((THD*)mysql->thd)->data; if (!result) @@ -149,7 +149,7 @@ static my_bool STDCALL emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) else the lengths are calculated from the offset between pointers. **************************************************************************/ -static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count) +static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, unsigned int field_count) { MYSQL_ROW end; @@ -190,6 +190,26 @@ MYSQL_DATA *emb_read_binary_rows(MYSQL_STMT *stmt) return emb_read_rows(stmt->mysql, 0, 0); } +int STDCALL emb_unbuffered_fetch(MYSQL *mysql, char **row) +{ + MYSQL_DATA *data= ((THD*)mysql->thd)->data; + if (!data || !data->data) + { + *row= NULL; + if (data) + { + free_rows(data); + ((THD*)mysql->thd)->data= NULL; + } + } + else + { + *row= (char *)data->data->data; + data->data= data->data->next; + } + return 0; +} + MYSQL_METHODS embedded_methods= { emb_mysql_read_query_result, @@ -200,7 +220,8 @@ MYSQL_METHODS embedded_methods= emb_list_fields, emb_read_prepare_result, emb_stmt_execute, - emb_read_binary_rows + emb_read_binary_rows, + emb_unbuffered_fetch }; C_MODE_END @@ -472,6 +493,16 @@ err: } #endif +void free_embedded_thd(MYSQL *mysql) +{ + THD *thd= (THD*)mysql->thd; + if (!thd) + return; + if (thd->data) + free_rows(thd->data); + delete thd; +} + C_MODE_END bool Protocol::send_fields(List<Item> *list, uint flag) @@ -580,9 +611,8 @@ bool Protocol_prep::write() *data->prev_ptr= cur; data->prev_ptr= &cur->next; - next_field=cur->data; - next_mysql_field= thd->mysql->fields; - + cur->next= 0; + return false; } @@ -741,7 +771,7 @@ bool setup_params_data_withlog(st_prep_stmt *stmt) if (*client_param->is_null) { param->maybe_null= param->null_value= 1; - res= &null_string; + res= &my_null_string; } else { diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index e3a46733288..59c18368279 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -254,7 +254,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, goto error; if (mysql->fields) { - if (!(res= mysql_use_result(mysql))) + if (!(res= (*mysql->methods->use_result)(mysql))) goto error; mysql_free_result(res); } diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index ee71ffff2f0..db626c8acb1 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -13,6 +13,167 @@ hex(word) 0420 2004 DROP TABLE t1; +SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'0421'); +LPAD(_ucs2 X'0420',10,_ucs2 X'0421') +óóóóóóóóóò +SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'04210422'); +LPAD(_ucs2 X'0420',10,_ucs2 X'04210422') +óôóôóôóôóò +SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'042104220423'); +LPAD(_ucs2 X'0420',10,_ucs2 X'042104220423') +óôõóôõóôõò +SELECT LPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423'); +LPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423') +òóôõæèãþûý +SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'0421'); +RPAD(_ucs2 X'0420',10,_ucs2 X'0421') +òóóóóóóóóó +SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'04210422'); +RPAD(_ucs2 X'0420',10,_ucs2 X'04210422') +òóôóôóôóôó +SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'042104220423'); +RPAD(_ucs2 X'0420',10,_ucs2 X'042104220423') +òóôõóôõóôõ +SELECT RPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423'); +RPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423') +òóôõæèãþûý +CREATE TABLE t1 SELECT +LPAD(_ucs2 X'0420',10,_ucs2 X'0421') l, +RPAD(_ucs2 X'0420',10,_ucs2 X'0421') r; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `l` char(10) character set ucs2 NOT NULL default '', + `r` char(10) character set ucs2 NOT NULL default '' +) TYPE=MyISAM CHARSET=latin1 +DROP TABLE t1; +SET NAMES koi8r; +SET character_set_connection=ucs2; +create table t1 (a varchar(10) character set ucs2, key(a)); +insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); +explain select * from t1 where a like 'abc%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 21 NULL 1 Using where; Using index +explain select * from t1 where a like concat('abc','%'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 21 NULL 1 Using where; Using index +select * from t1 where a like "abc%"; +a +abc +abcd +select * from t1 where a like concat("abc","%"); +a +abc +abcd +select * from t1 where a like "ABC%"; +a +abc +abcd +select * from t1 where a like "test%"; +a +test +select * from t1 where a like "te_t"; +a +test +select * from t1 where a like "%a%"; +a +select * from t1 where a like "%abcd%"; +a +abcd +select * from t1 where a like "%abc\d%"; +a +abcd +drop table t1; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET ucs2); +INSERT INTO t1 VALUES ('ÆÙ×Á'),('æÙ×Á'),('Æù×Á'),('ÆÙ÷Á'),('ÆÙ×á'),('æù÷á'); +INSERT INTO t1 VALUES ('ÆÙ×ÁÐÒÏÌÄÖ'),('æÙ×ÁÐÒÏÌÄÖ'),('Æù×ÁÐÒÏÌÄÖ'),('ÆÙ÷ÁÐÒÏÌÄÖ'); +INSERT INTO t1 VALUES ('ÆÙ×áÐÒÏÌÄÖ'),('ÆÙ×ÁðÒÏÌÄÖ'),('ÆÙ×ÁÐòÏÌÄÖ'),('ÆÙ×ÁÐÒïÌÄÖ'); +INSERT INTO t1 VALUES ('ÆÙ×ÁÐÒÏìÄÖ'),('ÆÙ×ÁÐÒÏÌäÖ'),('ÆÙ×ÁÐÒÏÌÄö'),('æù÷áðòïìäö'); +SELECT * FROM t1 WHERE a LIKE '%Æù×Á%'; +a +ÆÙ×Á +æÙ×Á +Æù×Á +ÆÙ÷Á +ÆÙ×á +æù÷á +ÆÙ×ÁÐÒÏÌÄÖ +æÙ×ÁÐÒÏÌÄÖ +Æù×ÁÐÒÏÌÄÖ +ÆÙ÷ÁÐÒÏÌÄÖ +ÆÙ×áÐÒÏÌÄÖ +ÆÙ×ÁðÒÏÌÄÖ +ÆÙ×ÁÐòÏÌÄÖ +ÆÙ×ÁÐÒïÌÄÖ +ÆÙ×ÁÐÒÏìÄÖ +ÆÙ×ÁÐÒÏÌäÖ +ÆÙ×ÁÐÒÏÌÄö +æù÷áðòïìäö +SELECT * FROM t1 WHERE a LIKE '%Æù×%'; +a +ÆÙ×Á +æÙ×Á +Æù×Á +ÆÙ÷Á +ÆÙ×á +æù÷á +ÆÙ×ÁÐÒÏÌÄÖ +æÙ×ÁÐÒÏÌÄÖ +Æù×ÁÐÒÏÌÄÖ +ÆÙ÷ÁÐÒÏÌÄÖ +ÆÙ×áÐÒÏÌÄÖ +ÆÙ×ÁðÒÏÌÄÖ +ÆÙ×ÁÐòÏÌÄÖ +ÆÙ×ÁÐÒïÌÄÖ +ÆÙ×ÁÐÒÏìÄÖ +ÆÙ×ÁÐÒÏÌäÖ +ÆÙ×ÁÐÒÏÌÄö +æù÷áðòïìäö +SELECT * FROM t1 WHERE a LIKE 'Æù×Á%'; +a +ÆÙ×Á +æÙ×Á +Æù×Á +ÆÙ÷Á +ÆÙ×á +æù÷á +ÆÙ×ÁÐÒÏÌÄÖ +æÙ×ÁÐÒÏÌÄÖ +Æù×ÁÐÒÏÌÄÖ +ÆÙ÷ÁÐÒÏÌÄÖ +ÆÙ×áÐÒÏÌÄÖ +ÆÙ×ÁðÒÏÌÄÖ +ÆÙ×ÁÐòÏÌÄÖ +ÆÙ×ÁÐÒïÌÄÖ +ÆÙ×ÁÐÒÏìÄÖ +ÆÙ×ÁÐÒÏÌäÖ +ÆÙ×ÁÐÒÏÌÄö +æù÷áðòïìäö +SELECT * FROM t1 WHERE a LIKE 'Æù×Á%' COLLATE ucs2_bin; +a +Æù×Á +Æù×ÁÐÒÏÌÄÖ +DROP TABLE t1; +CREATE TABLE t1 (word varchar(64) NOT NULL, PRIMARY KEY (word)) +TYPE=MyISAM CHARACTER SET ucs2 COLLATE ucs2_general_ci; +INSERT INTO t1 (word) VALUES ("cat"); +SELECT * FROM t1 WHERE word LIKE "c%"; +word +cat +SELECT * FROM t1 WHERE word LIKE "ca_"; +word +cat +SELECT * FROM t1 WHERE word LIKE "cat"; +word +cat +SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630025'; +word +cat +SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630061005F'; +word +cat +DROP TABLE t1; +SET NAMES latin1; CREATE TABLE t1 ( word VARCHAR(64), bar INT(11) default 0, diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result index ffb305a81cf..1730b17eaed 100644 --- a/mysql-test/r/ctype_ujis.result +++ b/mysql-test/r/ctype_ujis.result @@ -1,4 +1,5 @@ drop table if exists t1; +set names ujis; create table t1 (c text character set ujis); insert into t1 values (0xa4a2),(0xa4a3); select hex(left(c,1)) from t1 group by c; @@ -6,3 +7,60 @@ hex(left(c,1)) A4A2 A4A3 drop table t1; +select locate(0xa2a1,0xa1a2a1a3); +locate(0xa2a1,0xa1a2a1a3) +2 +select locate(_ujis 0xa2a1,_ujis 0xa1a2a1a3); +locate(_ujis 0xa2a1,_ujis 0xa1a2a1a3) +0 +select locate(_ujis 0xa2a1,_ujis 0xa1a2a1a3 collate ujis_bin); +locate(_ujis 0xa2a1,_ujis 0xa1a2a1a3 collate ujis_bin) +0 +select locate('he','hello'); +locate('he','hello') +1 +select locate('he','hello',2); +locate('he','hello',2) +0 +select locate('lo','hello',2); +locate('lo','hello',2) +4 +select locate('HE','hello'); +locate('HE','hello') +1 +select locate('HE','hello',2); +locate('HE','hello',2) +0 +select locate('LO','hello',2); +locate('LO','hello',2) +4 +select locate('HE','hello' collate ujis_bin); +locate('HE','hello' collate ujis_bin) +0 +select locate('HE','hello' collate ujis_bin,2); +locate('HE','hello' collate ujis_bin,2) +0 +select locate('LO','hello' collate ujis_bin,2); +locate('LO','hello' collate ujis_bin,2) +0 +select locate(_ujis 0xa1a3,_ujis 0xa1a2a1a3); +locate(_ujis 0xa1a3,_ujis 0xa1a2a1a3) +2 +select 0xa1a2a1a3 like concat(_binary'%',0xa2a1,_binary'%'); +0xa1a2a1a3 like concat(_binary'%',0xa2a1,_binary'%') +1 +select _ujis 0xa1a2a1a3 like concat(_ujis'%',_ujis 0xa2a1, _ujis'%'); +_ujis 0xa1a2a1a3 like concat(_ujis'%',_ujis 0xa2a1, _ujis'%') +0 +select _ujis 0xa1a2a1a3 like concat(_ujis'%',_ujis 0xa2a1, _ujis'%') collate ujis_bin; +_ujis 0xa1a2a1a3 like concat(_ujis'%',_ujis 0xa2a1, _ujis'%') collate ujis_bin +0 +select 'a' like 'a'; +'a' like 'a' +1 +select 'A' like 'a'; +'A' like 'a' +1 +select 'A' like 'a' collate ujis_bin; +'A' like 'a' collate ujis_bin +0 diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result new file mode 100644 index 00000000000..1f07de17b14 --- /dev/null +++ b/mysql-test/r/ctype_utf8.result @@ -0,0 +1,61 @@ +set names utf8; +select left(_utf8 0xD0B0D0B1D0B2,1); +left(_utf8 0xD0B0D0B1D0B2,1) +а +select right(_utf8 0xD0B0D0B2D0B2,1); +right(_utf8 0xD0B0D0B2D0B2,1) +в +select locate('he','hello'); +locate('he','hello') +1 +select locate('he','hello',2); +locate('he','hello',2) +0 +select locate('lo','hello',2); +locate('lo','hello',2) +4 +select locate('HE','hello'); +locate('HE','hello') +1 +select locate('HE','hello',2); +locate('HE','hello',2) +0 +select locate('LO','hello',2); +locate('LO','hello',2) +4 +select locate('HE','hello' collate utf8_bin); +locate('HE','hello' collate utf8_bin) +0 +select locate('HE','hello' collate utf8_bin,2); +locate('HE','hello' collate utf8_bin,2) +0 +select locate('LO','hello' collate utf8_bin,2); +locate('LO','hello' collate utf8_bin,2) +0 +select locate(_utf8 0xD0B1, _utf8 0xD0B0D0B1D0B2); +locate(_utf8 0xD0B1, _utf8 0xD0B0D0B1D0B2) +2 +select locate(_utf8 0xD091, _utf8 0xD0B0D0B1D0B2); +locate(_utf8 0xD091, _utf8 0xD0B0D0B1D0B2) +2 +select locate(_utf8 0xD0B1, _utf8 0xD0B0D091D0B2); +locate(_utf8 0xD0B1, _utf8 0xD0B0D091D0B2) +2 +select locate(_utf8 0xD091, _utf8 0xD0B0D0B1D0B2 collate utf8_bin); +locate(_utf8 0xD091, _utf8 0xD0B0D0B1D0B2 collate utf8_bin) +0 +select locate(_utf8 0xD0B1, _utf8 0xD0B0D091D0B2 collate utf8_bin); +locate(_utf8 0xD0B1, _utf8 0xD0B0D091D0B2 collate utf8_bin) +0 +select 'a' like 'a'; +'a' like 'a' +1 +select 'A' like 'a'; +'A' like 'a' +1 +select 'A' like 'a' collate utf8_bin; +'A' like 'a' collate utf8_bin +0 +select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%'); +_utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%') +1 diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index c4d2eacf363..57eef44b3bb 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -40,3 +40,9 @@ uncompress(compress("")) select uncompressed_length(""); uncompressed_length("") 0 +select compress(NULL); +compress(NULL) +NULL +select uncompress(NULL); +uncompress(NULL) +NULL diff --git a/mysql-test/r/func_regexp.result b/mysql-test/r/func_regexp.result index 8d22994ef2b..35742136ee6 100644 --- a/mysql-test/r/func_regexp.result +++ b/mysql-test/r/func_regexp.result @@ -52,3 +52,27 @@ select * from t1 where xxx REGEXP '^this is some text: to test - out\\.reg exp [ xxx this is some text: to test - out.reg exp (22/45) drop table t1; +select _latin1 0xFF regexp _latin1 '[[:lower:]]' COLLATE latin1_bin; +_latin1 0xFF regexp _latin1 '[[:lower:]]' COLLATE latin1_bin +1 +select _koi8r 0xFF regexp _koi8r '[[:lower:]]' COLLATE koi8r_bin; +_koi8r 0xFF regexp _koi8r '[[:lower:]]' COLLATE koi8r_bin +0 +select _latin1 0xFF regexp _latin1 '[[:upper:]]' COLLATE latin1_bin; +_latin1 0xFF regexp _latin1 '[[:upper:]]' COLLATE latin1_bin +0 +select _koi8r 0xFF regexp _koi8r '[[:upper:]]' COLLATE koi8r_bin; +_koi8r 0xFF regexp _koi8r '[[:upper:]]' COLLATE koi8r_bin +1 +select _latin1 0xF7 regexp _latin1 '[[:alpha:]]'; +_latin1 0xF7 regexp _latin1 '[[:alpha:]]' +0 +select _koi8r 0xF7 regexp _koi8r '[[:alpha:]]'; +_koi8r 0xF7 regexp _koi8r '[[:alpha:]]' +1 +select _latin1'a' regexp _latin1'A' collate latin1_general_ci; +_latin1'a' regexp _latin1'A' collate latin1_general_ci +1 +select _latin1'a' regexp _latin1'A' collate latin1_bin; +_latin1'a' regexp _latin1'A' collate latin1_bin +0 diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 82f68cdaa84..ac25277351c 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -410,7 +410,7 @@ collation(concat(_latin2'a',_latin2'b')) coercibility(concat(_latin2'a',_latin2' latin2_general_ci 3 select collation(lpad(_latin2'a',4,_latin2'b')), coercibility(lpad(_latin2'a',4,_latin2'b')); collation(lpad(_latin2'a',4,_latin2'b')) coercibility(lpad(_latin2'a',4,_latin2'b')) -binary 3 +latin2_general_ci 3 select collation(rpad(_latin2'a',4,_latin2'b')), coercibility(rpad(_latin2'a',4,_latin2'b')); collation(rpad(_latin2'a',4,_latin2'b')) coercibility(rpad(_latin2'a',4,_latin2'b')) latin2_general_ci 3 diff --git a/mysql-test/r/have_ujis.require b/mysql-test/r/have_ujis.require index b4de2234ec7..43a309ad74e 100644 --- a/mysql-test/r/have_ujis.require +++ b/mysql-test/r/have_ujis.require @@ -1,2 +1,2 @@ Collation Charset Id Default Compiled Sortlen -ujis_japanese_ci ujis 12 Yes Yes 0 +ujis_japanese_ci ujis 12 Yes Yes 1 diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result new file mode 100644 index 00000000000..cf1ef55ca69 --- /dev/null +++ b/mysql-test/r/mysqldump.result @@ -0,0 +1,20 @@ +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (1), (2); +<?xml version="1.0"?> +<mysqldump> +<database name="test"> +DROP TABLE IF EXISTS t1; +LOCK TABLES t1 WRITE; + <table name="t1"> + <row> + <field name="a">1</field> + </row> + <row> + <field name="a">2</field> + </row> + </table> +UNLOCK TABLES; +</database> +</mysqldump> +DROP TABLE t1; diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 0b80642fc70..4cf6bee6123 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -10,22 +10,22 @@ select * from t1; f1 5 delete from t1; -ERROR 42000: Access denied for user: 'ssl_user1@localhost' to database 'test' +ERROR 42000: Access denied for user: 'ssl_user1'@'localhost' to database 'test' select * from t1; f1 5 delete from t1; -ERROR 42000: Access denied for user: 'ssl_user2@localhost' to database 'test' +ERROR 42000: Access denied for user: 'ssl_user2'@'localhost' to database 'test' select * from t1; f1 5 delete from t1; -ERROR 42000: Access denied for user: 'ssl_user3@localhost' to database 'test' +ERROR 42000: Access denied for user: 'ssl_user3'@'localhost' to database 'test' select * from t1; f1 5 delete from t1; -ERROR 42000: Access denied for user: 'ssl_user4@localhost' to database 'test' +ERROR 42000: Access denied for user: 'ssl_user4'@'localhost' to database 'test' delete from mysql.user where user='ssl_user%'; delete from mysql.db where user='ssl_user%'; flush privileges; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 6cac5a9bc6c..703360dc7b5 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1046,8 +1046,9 @@ t1 CREATE TABLE `t1` ( ) TYPE=MyISAM CHARSET=latin1 drop table t1; CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a; -Warnings: -Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 1 +select * from t1; +a +2 SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 2e962190762..952ed566132 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -409,7 +409,7 @@ found_rows() SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2,2; a 3 -5 +4 select found_rows(); found_rows() 6 @@ -423,7 +423,7 @@ found_rows() 5 SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1; a -3 +5 (SELECT * FROM t1 ORDER by a) UNION ALL (SELECT * FROM t2 ORDER BY a) ORDER BY A desc LIMIT 4; a 5 diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index ee30baed008..0457c204e32 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -29,6 +29,69 @@ INSERT INTO t1 VALUES (X'042000200020'), (X'200400200020'); SELECT hex(word) FROM t1 ORDER BY word; DROP TABLE t1; +# +# Check LPAD/RPAD +# +SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'0421'); +SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'04210422'); +SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'042104220423'); +SELECT LPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423'); + +SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'0421'); +SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'04210422'); +SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'042104220423'); +SELECT RPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423'); + +CREATE TABLE t1 SELECT +LPAD(_ucs2 X'0420',10,_ucs2 X'0421') l, +RPAD(_ucs2 X'0420',10,_ucs2 X'0421') r; +SHOW CREATE TABLE t1; +DROP TABLE t1; +###################################################### +# +# Test of like +# + +SET NAMES koi8r; +SET character_set_connection=ucs2; + +create table t1 (a varchar(10) character set ucs2, key(a)); +insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); +explain select * from t1 where a like 'abc%'; +explain select * from t1 where a like concat('abc','%'); +select * from t1 where a like "abc%"; +select * from t1 where a like concat("abc","%"); +select * from t1 where a like "ABC%"; +select * from t1 where a like "test%"; +select * from t1 where a like "te_t"; +select * from t1 where a like "%a%"; +select * from t1 where a like "%abcd%"; +select * from t1 where a like "%abc\d%"; +drop table t1; + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET ucs2); +INSERT INTO t1 VALUES ('ÆÙ×Á'),('æÙ×Á'),('Æù×Á'),('ÆÙ÷Á'),('ÆÙ×á'),('æù÷á'); +INSERT INTO t1 VALUES ('ÆÙ×ÁÐÒÏÌÄÖ'),('æÙ×ÁÐÒÏÌÄÖ'),('Æù×ÁÐÒÏÌÄÖ'),('ÆÙ÷ÁÐÒÏÌÄÖ'); +INSERT INTO t1 VALUES ('ÆÙ×áÐÒÏÌÄÖ'),('ÆÙ×ÁðÒÏÌÄÖ'),('ÆÙ×ÁÐòÏÌÄÖ'),('ÆÙ×ÁÐÒïÌÄÖ'); +INSERT INTO t1 VALUES ('ÆÙ×ÁÐÒÏìÄÖ'),('ÆÙ×ÁÐÒÏÌäÖ'),('ÆÙ×ÁÐÒÏÌÄö'),('æù÷áðòïìäö'); +SELECT * FROM t1 WHERE a LIKE '%Æù×Á%'; +SELECT * FROM t1 WHERE a LIKE '%Æù×%'; +SELECT * FROM t1 WHERE a LIKE 'Æù×Á%'; +SELECT * FROM t1 WHERE a LIKE 'Æù×Á%' COLLATE ucs2_bin; +DROP TABLE t1; + +# +# Bug 1181 +# +CREATE TABLE t1 (word varchar(64) NOT NULL, PRIMARY KEY (word)) +TYPE=MyISAM CHARACTER SET ucs2 COLLATE ucs2_general_ci; +INSERT INTO t1 (word) VALUES ("cat"); +SELECT * FROM t1 WHERE word LIKE "c%"; +SELECT * FROM t1 WHERE word LIKE "ca_"; +SELECT * FROM t1 WHERE word LIKE "cat"; +SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630025'; +SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630061005F'; +DROP TABLE t1; ###################################################### @@ -53,6 +116,7 @@ DROP TABLE t1; # are not part of the index sorted on, it does a filesort, which fails. # Using a straight index yields correct results. +SET NAMES latin1; # # Two fields, index diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test index e41caf55948..bcf6507b4c7 100644 --- a/mysql-test/t/ctype_ujis.test +++ b/mysql-test/t/ctype_ujis.test @@ -7,6 +7,8 @@ drop table if exists t1; --enable_warnings +set names ujis; + # # Test problem with LEFT() # @@ -15,3 +17,27 @@ create table t1 (c text character set ujis); insert into t1 values (0xa4a2),(0xa4a3); select hex(left(c,1)) from t1 group by c; drop table t1; + +# +# +# +select locate(0xa2a1,0xa1a2a1a3); +select locate(_ujis 0xa2a1,_ujis 0xa1a2a1a3); +select locate(_ujis 0xa2a1,_ujis 0xa1a2a1a3 collate ujis_bin); +select locate('he','hello'); +select locate('he','hello',2); +select locate('lo','hello',2); +select locate('HE','hello'); +select locate('HE','hello',2); +select locate('LO','hello',2); +select locate('HE','hello' collate ujis_bin); +select locate('HE','hello' collate ujis_bin,2); +select locate('LO','hello' collate ujis_bin,2); +select locate(_ujis 0xa1a3,_ujis 0xa1a2a1a3); + +select 0xa1a2a1a3 like concat(_binary'%',0xa2a1,_binary'%'); +select _ujis 0xa1a2a1a3 like concat(_ujis'%',_ujis 0xa2a1, _ujis'%'); +select _ujis 0xa1a2a1a3 like concat(_ujis'%',_ujis 0xa2a1, _ujis'%') collate ujis_bin; +select 'a' like 'a'; +select 'A' like 'a'; +select 'A' like 'a' collate ujis_bin; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test new file mode 100644 index 00000000000..46359e84f1d --- /dev/null +++ b/mysql-test/t/ctype_utf8.test @@ -0,0 +1,35 @@ +# +# Tests with the utf8 character set +# + +set names utf8; + +select left(_utf8 0xD0B0D0B1D0B2,1); +select right(_utf8 0xD0B0D0B2D0B2,1); + +select locate('he','hello'); +select locate('he','hello',2); +select locate('lo','hello',2); +select locate('HE','hello'); +select locate('HE','hello',2); +select locate('LO','hello',2); +select locate('HE','hello' collate utf8_bin); +select locate('HE','hello' collate utf8_bin,2); +select locate('LO','hello' collate utf8_bin,2); + +select locate(_utf8 0xD0B1, _utf8 0xD0B0D0B1D0B2); +select locate(_utf8 0xD091, _utf8 0xD0B0D0B1D0B2); +select locate(_utf8 0xD0B1, _utf8 0xD0B0D091D0B2); +select locate(_utf8 0xD091, _utf8 0xD0B0D0B1D0B2 collate utf8_bin); +select locate(_utf8 0xD0B1, _utf8 0xD0B0D091D0B2 collate utf8_bin); + +select 'a' like 'a'; +select 'A' like 'a'; +select 'A' like 'a' collate utf8_bin; +select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%'); + +# +# Fix this, it should return 1: +# +#select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD091,_utf8 '%'); +# diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index 826721a4053..7462c020357 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -23,3 +23,9 @@ select uncompress(""); select uncompress(compress("")); select uncompressed_length(""); +# +# NULL (Bug #1333) +# + +select compress(NULL); +select uncompress(NULL); diff --git a/mysql-test/t/func_regexp.test b/mysql-test/t/func_regexp.test index 6e5d601844e..6ecb56ef9c4 100644 --- a/mysql-test/t/func_regexp.test +++ b/mysql-test/t/func_regexp.test @@ -45,3 +45,17 @@ create table t1 (xxx char(128)); insert into t1 (xxx) values('this is some text: to test - out.reg exp (22/45)'); select * from t1 where xxx REGEXP '^this is some text: to test - out\\.reg exp [[(][0-9]+[/\\][0-9]+[])][ ]*$'; drop table t1; + +# +# Check with different character sets and collations +# +select _latin1 0xFF regexp _latin1 '[[:lower:]]' COLLATE latin1_bin; +select _koi8r 0xFF regexp _koi8r '[[:lower:]]' COLLATE koi8r_bin; +select _latin1 0xFF regexp _latin1 '[[:upper:]]' COLLATE latin1_bin; +select _koi8r 0xFF regexp _koi8r '[[:upper:]]' COLLATE koi8r_bin; + +select _latin1 0xF7 regexp _latin1 '[[:alpha:]]'; +select _koi8r 0xF7 regexp _koi8r '[[:alpha:]]'; + +select _latin1'a' regexp _latin1'A' collate latin1_general_ci; +select _latin1'a' regexp _latin1'A' collate latin1_bin; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test new file mode 100644 index 00000000000..c98fd4050f2 --- /dev/null +++ b/mysql-test/t/mysqldump.test @@ -0,0 +1,10 @@ +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +# XML output + +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (1), (2); +--exec $MYSQL_DUMP -X test t1 +DROP TABLE t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index ef46ba7d12c..c6a574bae62 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -606,6 +606,7 @@ CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a; SHOW CREATE TABLE t1; drop table t1; CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a; +select * from t1; SHOW CREATE TABLE t1; drop table t1; diff --git a/mysys/charset.c b/mysys/charset.c index 58ce8f5b2fe..7d0516ac81b 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -119,7 +119,7 @@ static void simple_cs_init_functions(CHARSET_INFO *cs) if (cs->state & MY_CS_BINSORT) { - cs->coll= &my_collation_bin_handler; + cs->coll= &my_collation_8bit_bin_handler; } else { @@ -226,7 +226,6 @@ static my_bool create_fromuni(CHARSET_INFO *cs) static void simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from) { to->number= from->number ? from->number : to->number; - to->state|= from->state; if (from->csname) to->csname= my_once_strdup(from->csname,MYF(MY_WME)); @@ -282,8 +281,6 @@ static int add_collation(CHARSET_INFO *cs) { if (!all_charsets[cs->number]) { - if (cs->state & MY_CS_COMPILED) - goto clear; if (!(all_charsets[cs->number]= (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),MYF(0)))) return MY_XML_ERROR; @@ -296,6 +293,8 @@ static int add_collation(CHARSET_INFO *cs) if (cs->binary_number == cs->number) cs->state |= MY_CS_BINSORT; + all_charsets[cs->number]->state|= cs->state; + if (!(all_charsets[cs->number]->state & MY_CS_COMPILED)) { simple_cs_init_functions(all_charsets[cs->number]); @@ -304,15 +303,28 @@ static int add_collation(CHARSET_INFO *cs) { all_charsets[cs->number]->state |= MY_CS_LOADED; } + all_charsets[cs->number]->state|= MY_CS_AVAILABLE; } else { + /* + We need the below to make get_charset_name() + and get_charset_number() working even if a + character set has not been really incompiled. + The above functions are used for example + in error message compiler extra/comp_err.c. + If a character set was compiled, this information + will get lost and overwritten in add_compiled_collation(). + */ CHARSET_INFO *dst= all_charsets[cs->number]; - dst->state |= cs->state; + dst->number= cs->number; if (cs->comment) dst->comment= my_once_strdup(cs->comment,MYF(MY_WME)); + if (cs->csname) + dst->csname= my_once_strdup(cs->csname,MYF(MY_WME)); + if (cs->name) + dst->name= my_once_strdup(cs->name,MYF(MY_WME)); } -clear: cs->number= 0; cs->primary_number= 0; cs->binary_number= 0; @@ -389,77 +401,79 @@ char *get_charsets_dir(char *buf) CHARSET_INFO *all_charsets[256]; CHARSET_INFO *default_charset_info = &my_charset_latin1; -#define MY_ADD_CHARSET(x) all_charsets[(x)->number]=(x) +static void add_compiled_collation(CHARSET_INFO *cs) +{ + all_charsets[cs->number]= cs; + cs->state|= MY_CS_AVAILABLE; +} static my_bool init_compiled_charsets(myf flags __attribute__((unused))) { CHARSET_INFO *cs; - MY_ADD_CHARSET(&my_charset_bin); + add_compiled_collation(&my_charset_bin); - MY_ADD_CHARSET(&my_charset_latin1); - MY_ADD_CHARSET(&my_charset_latin1_bin); - MY_ADD_CHARSET(&my_charset_latin1_german2_ci); + add_compiled_collation(&my_charset_latin1); + add_compiled_collation(&my_charset_latin1_bin); + add_compiled_collation(&my_charset_latin1_german2_ci); #ifdef HAVE_CHARSET_big5 - MY_ADD_CHARSET(&my_charset_big5_chinese_ci); - MY_ADD_CHARSET(&my_charset_big5_bin); + add_compiled_collation(&my_charset_big5_chinese_ci); + add_compiled_collation(&my_charset_big5_bin); #endif #ifdef HAVE_CHARSET_cp1250 - MY_ADD_CHARSET(&my_charset_cp1250_czech_ci); + add_compiled_collation(&my_charset_cp1250_czech_ci); #endif #ifdef HAVE_CHARSET_latin2 - MY_ADD_CHARSET(&my_charset_latin2_czech_ci); + add_compiled_collation(&my_charset_latin2_czech_ci); #endif #ifdef HAVE_CHARSET_euckr - MY_ADD_CHARSET(&my_charset_euckr_korean_ci); - MY_ADD_CHARSET(&my_charset_euckr_bin); + add_compiled_collation(&my_charset_euckr_korean_ci); + add_compiled_collation(&my_charset_euckr_bin); #endif #ifdef HAVE_CHARSET_gb2312 - MY_ADD_CHARSET(&my_charset_gb2312_chinese_ci); - MY_ADD_CHARSET(&my_charset_gb2312_bin); + add_compiled_collation(&my_charset_gb2312_chinese_ci); + add_compiled_collation(&my_charset_gb2312_bin); #endif #ifdef HAVE_CHARSET_gbk - MY_ADD_CHARSET(&my_charset_gbk_chinese_ci); - MY_ADD_CHARSET(&my_charset_gbk_bin); + add_compiled_collation(&my_charset_gbk_chinese_ci); + add_compiled_collation(&my_charset_gbk_bin); #endif #ifdef HAVE_CHARSET_sjis - MY_ADD_CHARSET(&my_charset_sjis_japanese_ci); - MY_ADD_CHARSET(&my_charset_sjis_bin); + add_compiled_collation(&my_charset_sjis_japanese_ci); + add_compiled_collation(&my_charset_sjis_bin); #endif #ifdef HAVE_CHARSET_tis620 - MY_ADD_CHARSET(&my_charset_tis620_thai_ci); - MY_ADD_CHARSET(&my_charset_tis620_bin); + add_compiled_collation(&my_charset_tis620_thai_ci); + add_compiled_collation(&my_charset_tis620_bin); #endif #ifdef HAVE_CHARSET_ucs2 - MY_ADD_CHARSET(&my_charset_ucs2_general_ci); - MY_ADD_CHARSET(&my_charset_ucs2_bin); + add_compiled_collation(&my_charset_ucs2_general_ci); + add_compiled_collation(&my_charset_ucs2_bin); #endif #ifdef HAVE_CHARSET_ujis - MY_ADD_CHARSET(&my_charset_ujis_japanese_ci); - MY_ADD_CHARSET(&my_charset_ujis_bin); + add_compiled_collation(&my_charset_ujis_japanese_ci); + add_compiled_collation(&my_charset_ujis_bin); #endif #ifdef HAVE_CHARSET_utf8 - MY_ADD_CHARSET(&my_charset_utf8_general_ci); - MY_ADD_CHARSET(&my_charset_utf8_bin); + add_compiled_collation(&my_charset_utf8_general_ci); + add_compiled_collation(&my_charset_utf8_bin); #endif /* Copy compiled charsets */ for (cs=compiled_charsets; cs->name; cs++) - { - all_charsets[cs->number]=cs; - } + add_compiled_collation(cs); return FALSE; } @@ -570,7 +584,7 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) cs= all_charsets[cs_number]; - if (cs && !(cs->state & (MY_CS_COMPILED | MY_CS_LOADED))) + if (cs && !(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); diff --git a/mysys/checksum.c b/mysys/checksum.c index 664e768ef4e..92ec3d550f1 100644 --- a/mysys/checksum.c +++ b/mysys/checksum.c @@ -30,11 +30,13 @@ ha_checksum my_checksum(ha_checksum crc, const byte *pos, uint length) { -/* const byte *end=pos+length; +#ifdef NOT_USED + const byte *end=pos+length; for ( ; pos != end ; pos++) crc=((crc << 8) + *((uchar*) pos)) + (crc >> (8*sizeof(ha_checksum)-8)); return crc; -*/ +#else return (ha_checksum)crc32((uint)crc, (const uchar *)pos, length); +#endif } diff --git a/mysys/hash.c b/mysys/hash.c index 0b2dbc484bc..b0ddbd90794 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -217,7 +217,7 @@ static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length) /* Write a hash-key to the hash-index */ -my_bool hash_insert(HASH *info,const byte *record) +my_bool my_hash_insert(HASH *info,const byte *record) { int flag; uint halfbuff,hash_nr,first_index,idx; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 06e7b626bd7..edd35749633 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -461,7 +461,7 @@ static char *check_struct_option(char *cur_arg, char *key_name) { char *ptr, *end; - ptr= strcend(cur_arg + 1, '.'); // Skip the first character + ptr= strcend(cur_arg + 1, '.'); /* Skip the first character */ end= strcend(cur_arg, '='); /* diff --git a/mysys/my_static.h b/mysys/my_static.h index 1a33bcf21f3..08d1a93692f 100644 --- a/mysys/my_static.h +++ b/mysys/my_static.h @@ -19,7 +19,6 @@ a shared library */ -#include "mysys_priv.h" #include <signal.h> #define MAX_SIGNALS 10 /* Max signals under a dont-allow */ diff --git a/mysys/testhash.c b/mysys/testhash.c index a1d14dc225d..72badffdbcd 100644 --- a/mysys/testhash.c +++ b/mysys/testhash.c @@ -83,7 +83,7 @@ static int do_test() n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS)); record= (char*) my_malloc(reclength,MYF(MY_FAE)); sprintf(record,"%6d:%4d:%8d:Pos: %4d ",n1,n2,n3,write_count); - if (hash_insert(&hash,record)) + if (my_hash_insert(&hash,record)) { printf("Error: %d in write at record: %d\n",my_errno,i); goto err; @@ -199,7 +199,7 @@ static int do_test() record=(byte*) my_malloc(reclength,MYF(MY_FAE)); memcpy(record,recpos,reclength); record[reclength-1]=rnd(5)+1; - if (hash_insert(&hash2,record)) + if (my_hash_insert(&hash2,record)) { printf("Got error when inserting record: %*s",reclength,record); goto err; diff --git a/regex/cclass.h b/regex/cclass.h index e0f752f38b8..b877b5dee6b 100644 --- a/regex/cclass.h +++ b/regex/cclass.h @@ -18,4 +18,5 @@ extern struct cclass { const char *name; const char *chars; const char *multis; + uint mask; } cclasses[]; diff --git a/regex/regcomp.c b/regex/regcomp.c index d95a0ddf5d0..6af99456c28 100644 --- a/regex/regcomp.c +++ b/regex/regcomp.c @@ -36,19 +36,19 @@ struct parse { static char nuls[10]; /* place to point scanner in event of error */ struct cclass cclasses[CCLASS_LAST+1]= { - { "alnum", "","" }, - { "alpha", "","" }, - { "blank", "","" }, - { "cntrl", "","" }, - { "digit", "","" }, - { "graph", "","" }, - { "lower", "","" }, - { "print", "","" }, - { "punct", "","" }, - { "space", "","" }, - { "upper", "","" }, - { "xdigit", "","" }, - { NULL,NULL,NULL } + { "alnum", "","", _U | _L | _NMR}, + { "alpha", "","", _U | _L }, + { "blank", "","", _B }, + { "cntrl", "","", _CTR }, + { "digit", "","", _NMR }, + { "graph", "","", _PNT | _U | _L | _NMR}, + { "lower", "","", _L }, + { "print", "","", _PNT | _U | _L | _NMR | _B }, + { "punct", "","", _PNT }, + { "space", "","", _SPC }, + { "upper", "","", _U }, + { "xdigit", "","", _X }, + { NULL,NULL,NULL, 0 } }; /* @@ -747,9 +747,7 @@ register cset *cs; register char *sp = p->next; register struct cclass *cp; register size_t len; - register char *u; - register char c; - + while (MORE() && my_isalpha(p->charset,PEEK())) NEXT(); len = p->next - sp; @@ -762,11 +760,26 @@ register cset *cs; return; } - u = (char*) cp->chars; - while ((c = *u++) != '\0') - CHadd(cs, c); - for (u = (char*) cp->multis; *u != '\0'; u += strlen(u) + 1) - MCadd(p, cs, u); +#ifndef USE_ORIG_REGEX_CODE + { + register size_t i; + for (i=1 ; i<256 ; i++) + if (p->charset->ctype[i+1] & cp->mask) + CHadd(cs, i); + } +#else + { + register char *u = (char*) cp->chars; + register char c; + + while ((c = *u++) != '\0') + CHadd(cs, c); + + for (u = (char*) cp->multis; *u != '\0'; u += strlen(u) + 1) + MCadd(p, cs, u); + } +#endif + } /* diff --git a/sql-common/client.c b/sql-common/client.c index 62524bc78bf..6b3a44cf7d5 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1006,7 +1006,7 @@ void mysql_read_default_options(struct st_mysql_options *options, else the lengths are calculated from the offset between pointers. **************************************************************************/ -static void STDCALL cli_fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count) +static void STDCALL cli_fetch_lengths(ulong *to, MYSQL_ROW column, unsigned int field_count) { ulong *prev_length; byte *start=0; @@ -1138,7 +1138,7 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, /* Read all rows (fields or data) from server */ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, - uint fields) + unsigned int fields) { uint field; ulong pkt_len; @@ -1403,11 +1403,14 @@ static MYSQL_METHODS client_methods= cli_advanced_command, cli_read_rows, cli_mysql_use_result, - cli_fetch_lengths, - cli_list_fields, + cli_fetch_lengths +#ifndef MYSQL_SERVER + ,cli_list_fields, cli_read_prepare_result, cli_stmt_execute, - cli_read_binary_rows + cli_read_binary_rows, + cli_unbuffered_fetch +#endif }; MYSQL * STDCALL @@ -1996,7 +1999,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, goto error; if (mysql->fields) { - if (!(res= mysql_use_result(mysql))) + if (!(res= cli_mysql_use_result(mysql))) goto error; mysql_free_result(res); } @@ -2216,7 +2219,7 @@ static my_bool STDCALL cli_mysql_read_query_result(MYSQL *mysql) ulong field_count; MYSQL_DATA *fields; ulong length; - DBUG_ENTER("mysql_read_query_result"); + DBUG_ENTER("cli_mysql_read_query_result"); /* Read from the connection which we actually used, which @@ -2319,7 +2322,7 @@ mysql_real_query(MYSQL *mysql, const char *query, ulong length) if (mysql_send_query(mysql,query,length)) DBUG_RETURN(1); - DBUG_RETURN((int) mysql_read_query_result(mysql)); + DBUG_RETURN((int) (*mysql->methods->read_query_result)(mysql)); } @@ -2388,7 +2391,7 @@ MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql) static MYSQL_RES * STDCALL cli_mysql_use_result(MYSQL *mysql) { MYSQL_RES *result; - DBUG_ENTER("mysql_use_result"); + DBUG_ENTER("cli_mysql_use_result"); mysql = mysql->last_used_con; diff --git a/sql/client_settings.h b/sql/client_settings.h index c345021d7f5..b357e52ec9d 100644 --- a/sql/client_settings.h +++ b/sql/client_settings.h @@ -32,8 +32,3 @@ #undef HAVE_SMEM #undef _CUSTOMCONFIG_ -#define cli_list_fields NULL -#define cli_read_prepare_result NULL -#define cli_stmt_execute NULL -#define cli_read_binary_rows NULL - diff --git a/sql/derror.cc b/sql/derror.cc index 1a98b9ce371..78efdcc33f3 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -67,10 +67,18 @@ static void read_texts(const char *file_name,const char ***point, goto err; /* purecov: inspected */ textcount=head[4]; + if (!head[30]) + { + sql_print_error("Character set information not found in '%s'. \ +Please install the latest version of this file.",name); + goto err1; + } + if (!(cset= get_charset(head[30],MYF(MY_WME)))) { - funktpos= 3; - goto err; + sql_print_error("Character set #%d is not supported for messagefile '%s'", + (int)head[30],name); + goto err1; } length=uint2korr(head+6); count=uint2korr(head+8); @@ -112,9 +120,6 @@ Check that the above file is the right version for this program!", err: switch (funktpos) { - case 3: - buff="Character set is not supported for messagefile '%s'"; - break; case 2: buff="Not enough memory for messagefile '%s'"; break; @@ -125,9 +130,10 @@ err: buff="Can't find messagefile '%s'"; break; } + sql_print_error(buff,name); +err1: if (file != FERR) VOID(my_close(file,MYF(MY_WME))); - sql_print_error(buff,name); unireg_abort(1); } /* read_texts */ diff --git a/sql/filesort.cc b/sql/filesort.cc index 13989bdae8f..1b481924690 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1,4 +1,3 @@ - /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index dc4f23db3b2..7126b7ee577 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -430,18 +430,9 @@ int main(int argc,char **argv) exit(1); printf("/* Copyright (C) 2001 MySQL AB\n\ - This program is free software; you can redistribute it and/or modify\n\ - it under the terms of the GNU General Public License as published by\n\ - the Free Software Foundation; either version 2 of the License, or\n\ - (at your option) any later version.\n\n\ - This program is distributed in the hope that it will be useful,\n\ - but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ - GNU General Public License for more details.\n\n\ - You should have received a copy of the GNU General Public License\n\ - along with this program; if not, write to the Free Software\n\ - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307\ - USA */\n\n"); + This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ + and you are welcome to modify and redistribute it under the GPL license\n\ + \n*/\n\n"); printf("/* This code is generated by gen_lex_hash.cc that seeks for\ a perfect\nhash function */\n\n"); diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index ee1b54e5745..34915a6020c 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -2266,7 +2266,7 @@ static BDB_SHARE *get_share(const char *table_name, TABLE *table) strmov(share->table_name,table_name); share->key_file = key_file; share->key_type = key_type; - if (hash_insert(&bdb_open_tables, (byte*) share)) + if (my_hash_insert(&bdb_open_tables, (byte*) share)) { pthread_mutex_unlock(&bdb_mutex); /* purecov: inspected */ my_free((gptr) share,0); /* purecov: inspected */ diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index bc014c621fd..4ff5aba4a32 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4583,7 +4583,7 @@ static INNOBASE_SHARE *get_share(const char *table_name) share->table_name_length=length; share->table_name=(char*) (share+1); strmov(share->table_name,table_name); - if (hash_insert(&innobase_open_tables, (mysql_byte*) share)) + if (my_hash_insert(&innobase_open_tables, (mysql_byte*) share)) { pthread_mutex_unlock(&innobase_mutex); my_free((gptr) share,0); diff --git a/sql/hash_filo.h b/sql/hash_filo.h index 92cd2658967..d1672e1a60c 100644 --- a/sql/hash_filo.h +++ b/sql/hash_filo.h @@ -116,7 +116,7 @@ public: last_link=last_link->prev_used; hash_delete(&cache,(byte*) tmp); } - if (hash_insert(&cache,(byte*) entry)) + if (my_hash_insert(&cache,(byte*) entry)) { if (free_element) (*free_element)(entry); // This should never happen diff --git a/sql/item.h b/sql/item.h index 9f767d502ba..b2d67a661a6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 +/* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2179ef1188e..e7dc3933c10 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 +/* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/item_func.cc b/sql/item_func.cc index fe419745b60..b7979e7909c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1153,7 +1153,6 @@ longlong Item_func_locate::val_int() { String *a=args[0]->val_str(&value1); String *b=args[1]->val_str(&value2); - bool binary_cmp= (cmp_collation.collation->state & MY_CS_BINSORT) ? 1 : 0; if (!a || !b) { null_value=1; @@ -1161,55 +1160,27 @@ longlong Item_func_locate::val_int() } null_value=0; uint start=0; -#ifdef USE_MB uint start0=0; -#endif + my_match_t match; + if (arg_count == 3) { - start=(uint) args[2]->val_int()-1; -#ifdef USE_MB - if (use_mb(cmp_collation.collation)) - { - start0=start; - if (!binary_cmp) - start=a->charpos(start); - } -#endif + start0= start =(uint) args[2]->val_int()-1; + start=a->charpos(start); + if (start > a->length() || start+b->length() > a->length()) return 0; } + if (!b->length()) // Found empty string at start return (longlong) (start+1); -#ifdef USE_MB - if (use_mb(cmp_collation.collation) && !binary_cmp) - { - const char *ptr=a->ptr()+start; - const char *search=b->ptr(); - const char *strend = ptr+a->length(); - const char *end=strend-b->length()+1; - const char *search_end=search+b->length(); - register uint32 l; - while (ptr < end) - { - if (*ptr == *search) - { - register char *i,*j; - i=(char*) ptr+1; j=(char*) search+1; - while (j != search_end) - if (*i++ != *j++) goto skipp; - return (longlong) start0+1; - } - skipp: - if ((l=my_ismbchar(cmp_collation.collation,ptr,strend))) - ptr+=l; - else ++ptr; - ++start0; - } + + if (!cmp_collation.collation->coll->instr(cmp_collation.collation, + a->ptr()+start, a->length()-start, + b->ptr(), b->length(), + &match, 1)) return 0; - } -#endif /* USE_MB */ - return (longlong) (binary_cmp ? a->strstr(*b,start) : - (a->strstr_case(*b,start)))+1; + return (longlong) match.mblen + start0 + 1; } @@ -1742,7 +1713,7 @@ public: pthread_cond_init(&cond,NULL); if (key) { - if (hash_insert(&hash_user_locks,(byte*) this)) + if (my_hash_insert(&hash_user_locks,(byte*) this)) { my_free((gptr) key,MYF(0)); key=0; @@ -2103,7 +2074,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, entry->used_query_id=current_thd->query_id; entry->type=STRING_RESULT; memcpy(entry->name.str, name.str, name.length+1); - if (hash_insert(hash,(byte*) entry)) + if (my_hash_insert(hash,(byte*) entry)) { my_free((char*) entry,MYF(0)); return 0; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 1739e3fac16..86efde096c5 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -33,8 +33,9 @@ #include "md5.h" #include "sha1.h" #include "my_aes.h" +#include "../mysys/my_static.h" // For soundex_map -String empty_string("",default_charset_info); +String my_empty_string("",default_charset_info); static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { @@ -359,7 +360,7 @@ String *Item_func_des_encrypt::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; if ((res_length=res->length()) == 0) - return &empty_string; + return &my_empty_string; if (arg_count == 1) { @@ -520,7 +521,7 @@ String *Item_func_concat_ws::val_str(String *str) if ((res= args[i]->val_str(str))) break; if (i == arg_count) - return &empty_string; + return &my_empty_string; for (i++; i < arg_count ; i++) { @@ -661,7 +662,7 @@ String *Item_func_reverse::val_str(String *str) return 0; /* An empty string is a special case as the string pointer may be null */ if (!res->length()) - return &empty_string; + return &my_empty_string; res=copy_if_not_alloced(str,res,res->length()); ptr = (char *) res->ptr(); end=ptr+res->length(); @@ -914,7 +915,7 @@ String *Item_func_left::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; if (length <= 0) - return &empty_string; + return &my_empty_string; length= res->charpos(length); if (res->length() > (ulong) length) { // Safe even if const arg @@ -958,7 +959,7 @@ String *Item_func_right::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ if (length <= 0) - return &empty_string; /* purecov: inspected */ + return &my_empty_string; /* purecov: inspected */ if (res->length() <= (uint) length) return res; /* purecov: inspected */ @@ -991,7 +992,7 @@ String *Item_func_substr::val_str(String *str) start=res->charpos(start); length=res->charpos(length,start); if (start < 0 || (uint) start+1 > res->length() || length <= 0) - return &empty_string; + return &my_empty_string; tmp_length=(int32) res->length()-start; length=min(length,tmp_length); @@ -1051,7 +1052,7 @@ String *Item_func_substr_index::val_str(String *str) null_value=0; uint delimeter_length=delimeter->length(); if (!res->length() || !delimeter_length || !count) - return &empty_string; // Wrong parameters + return &my_empty_string; // Wrong parameters res->set_charset(collation.collation); @@ -1335,7 +1336,7 @@ String *Item_func_password::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; if (res->length() == 0) - return &empty_string; + return &my_empty_string; make_scrambled_password(tmp_value, res->c_ptr()); str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, res->charset()); return str; @@ -1357,7 +1358,7 @@ String *Item_func_old_password::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; if (res->length() == 0) - return &empty_string; + return &my_empty_string; make_scrambled_password_323(tmp_value, res->c_ptr()); str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, res->charset()); return str; @@ -1383,7 +1384,7 @@ String *Item_func_encrypt::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; if (res->length() == 0) - return &empty_string; + return &my_empty_string; if (arg_count == 1) { // generate random salt @@ -1473,7 +1474,7 @@ String *Item_func_user::val_str(String *str) // For system threads (e.g. replication SQL thread) user may be empty if (!thd->user) - return &empty_string; + return &my_empty_string; res_length= (strlen(thd->user)+strlen(host)+2) * cs->mbmaxlen; if (str->alloc(res_length)) @@ -1496,15 +1497,11 @@ void Item_func_soundex::fix_length_and_dec() } - /* - If alpha, map input letter to soundex code. - If not alpha and remove_garbage is set then skip to next char - else return 0 - */ - -extern "C" { -extern const char *soundex_map; // In mysys/static.c -} +/* + If alpha, map input letter to soundex code. + If not alpha and remove_garbage is set then skip to next char + else return 0 +*/ static char get_scode(CHARSET_INFO *cs,char *ptr) { @@ -1536,7 +1533,7 @@ String *Item_func_soundex::val_str(String *str) while (from != end && my_isspace(cs,*from)) // Skip pre-space from++; /* purecov: inspected */ if (from == end) - return &empty_string; // No alpha characters. + return &my_empty_string; // No alpha characters. *to++ = my_toupper(cs,*from); // Copy first letter last_ch = get_scode(cs,from); // code of the first letter // for the first 'double-letter check. @@ -1718,7 +1715,7 @@ String *Item_func_make_set::val_str(String *str) ulonglong bits; bool first_found=0; Item **ptr=args; - String *result=&empty_string; + String *result=&my_empty_string; bits=item->val_int(); if ((null_value=item->null_value)) @@ -1742,7 +1739,7 @@ String *Item_func_make_set::val_str(String *str) else { if (tmp_str.copy(*res)) // Don't use 'str' - return &empty_string; + return &my_empty_string; result= &tmp_str; } } @@ -1752,11 +1749,11 @@ String *Item_func_make_set::val_str(String *str) { // Copy data to tmp_str if (tmp_str.alloc(result->length()+res->length()+1) || tmp_str.copy(*result)) - return &empty_string; + return &my_empty_string; result= &tmp_str; } if (tmp_str.append(',') || tmp_str.append(*res)) - return &empty_string; + return &my_empty_string; } } } @@ -1853,7 +1850,7 @@ String *Item_func_repeat::val_str(String *str) goto err; // string and/or delim are null null_value=0; if (count <= 0) // For nicer SQL code - return &empty_string; + return &my_empty_string; if (count == 1) // To avoid reallocs return res; length=res->length(); @@ -1888,7 +1885,7 @@ void Item_func_rpad::fix_length_and_dec() if (args[1]->const_item()) { - uint32 length= (uint32) args[1]->val_int(); + uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen; max_length=max(args[0]->max_length,length); if (max_length >= MAX_BLOB_WIDTH) { @@ -1906,36 +1903,46 @@ void Item_func_rpad::fix_length_and_dec() String *Item_func_rpad::val_str(String *str) { - uint32 res_length,length_pad; + uint32 res_byte_length,res_char_length,pad_char_length,pad_byte_length; char *to; const char *ptr_pad; int32 count= (int32) args[1]->val_int(); + int32 byte_count= count * collation.collation->mbmaxlen; String *res =args[0]->val_str(str); String *rpad = args[2]->val_str(str); if (!res || args[1]->null_value || !rpad || count < 0) goto err; null_value=0; - if (count <= (int32) (res_length=res->length())) + if (count <= (int32) (res_char_length=res->numchars())) { // String to pad is big enough - res->length(count); // Shorten result if longer + res->length(res->charpos(count)); // Shorten result if longer return (res); } - length_pad= rpad->length(); - if ((ulong) count > current_thd->variables.max_allowed_packet || - args[2]->null_value || !length_pad) + pad_char_length= rpad->numchars(); + if ((ulong) byte_count > current_thd->variables.max_allowed_packet || + args[2]->null_value || !pad_char_length) goto err; - if (!(res= alloc_buffer(res,str,&tmp_value,count))) + res_byte_length= res->length(); /* Must be done before alloc_buffer */ + if (!(res= alloc_buffer(res,str,&tmp_value,byte_count))) goto err; - to= (char*) res->ptr()+res_length; + to= (char*) res->ptr()+res_byte_length; ptr_pad=rpad->ptr(); - for (count-= res_length; (uint32) count > length_pad; count-= length_pad) + pad_byte_length= rpad->length(); + count-= res_char_length; + for ( ; (uint32) count > pad_char_length; count-= pad_char_length) { - memcpy(to,ptr_pad,length_pad); - to+= length_pad; + memcpy(to,ptr_pad,pad_byte_length); + to+= pad_byte_length; } - memcpy(to,ptr_pad,(size_t) count); + if (count) + { + pad_byte_length= rpad->charpos(count); + memcpy(to,ptr_pad,(size_t) pad_byte_length); + to+= pad_byte_length; + } + res->length(to- (char*) res->ptr()); return (res); err: @@ -1954,7 +1961,7 @@ void Item_func_lpad::fix_length_and_dec() if (args[1]->const_item()) { - uint32 length= (uint32) args[1]->val_int(); + uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen; max_length=max(args[0]->max_length,length); if (max_length >= MAX_BLOB_WIDTH) { @@ -1972,57 +1979,52 @@ void Item_func_lpad::fix_length_and_dec() String *Item_func_lpad::val_str(String *str) { - uint32 res_length,length_pad; - char *to; - const char *ptr_pad; - ulong count= (long) args[1]->val_int(); - String *res= args[0]->val_str(str); - String *lpad= args[2]->val_str(str); + uint32 res_byte_length,res_char_length,pad_byte_length,pad_char_length; + ulong count= (long) args[1]->val_int(), byte_count; + String a1,a3; + String *res= args[0]->val_str(&a1); + String *pad= args[2]->val_str(&a3); - if (!res || args[1]->null_value || !lpad) + if (!res || args[1]->null_value || !pad) goto err; + null_value=0; - if (count <= (res_length=res->length())) - { // String to pad is big enough - res->length(count); // Shorten result if longer - return (res); + res_byte_length= res->length(); + res_char_length= res->numchars(); + + if (count <= res_char_length) + { + res->length(res->charpos(count)); + return res; } - length_pad= lpad->length(); - if (count > current_thd->variables.max_allowed_packet || - args[2]->null_value || !length_pad) + + pad_byte_length= pad->length(); + pad_char_length= pad->numchars(); + byte_count= count * collation.collation->mbmaxlen; + + if (byte_count > current_thd->variables.max_allowed_packet || + args[2]->null_value || !pad_char_length || str->alloc(byte_count)) goto err; - - if (res->alloced_length() < count) + + str->length(0); + str->set_charset(collation.collation); + count-= res_char_length; + while (count >= pad_char_length) { - if (str->alloced_length() >= count) - { - memcpy((char*) str->ptr()+(count-res_length),res->ptr(),res_length); - res=str; - } - else - { - if (tmp_value.alloc(count)) - goto err; - memcpy((char*) tmp_value.ptr()+(count-res_length),res->ptr(),res_length); - res=&tmp_value; - } + str->append(*pad); + count-= pad_char_length; } - else - bmove_upp((char*) res->ptr()+count,res->ptr()+res_length,res_length); - res->length(count); - - to= (char*) res->ptr(); - ptr_pad= lpad->ptr(); - for (count-= res_length; count > length_pad; count-= length_pad) + if (count > 0) { - memcpy(to,ptr_pad,length_pad); - to+= length_pad; + pad->length(pad->charpos(count)); + str->append(*pad); } - memcpy(to,ptr_pad,(size_t) count); - return (res); + str->append(*res); + null_value= 0; + return str; - err: - null_value=1; +err: + null_value= 1; return 0; } @@ -2050,7 +2052,7 @@ String *Item_func_conv::val_str(String *str) dec= (longlong) my_strntoull(res->charset(),res->ptr(),res->length(),from_base,&endptr,&err); ptr= longlong2str(dec,ans,to_base); if (str->copy(ans,(uint32) (ptr-ans), default_charset())) - return &empty_string; + return &my_empty_string; return str; } @@ -2240,7 +2242,7 @@ String *Item_func_hex::val_str(String *str) return 0; ptr= longlong2str(dec,ans,16); if (str->copy(ans,(uint32) (ptr-ans),default_charset())) - return &empty_string; // End of memory + return &my_empty_string; // End of memory return str; } @@ -2541,6 +2543,11 @@ longlong Item_func_crc32::val_int() String *Item_func_compress::val_str(String *str) { String *res= args[0]->val_str(str); + if (!res) + { + null_value= 1; + return 0; + } if (res->is_empty()) return res; int err= Z_OK; @@ -2591,6 +2598,11 @@ String *Item_func_compress::val_str(String *str) String *Item_func_uncompress::val_str(String *str) { String *res= args[0]->val_str(str); + if (!res) + { + null_value= 1; + return 0; + } if (res->is_empty()) return res; ulong new_size= uint4korr(res->c_ptr()) & 0x3FFFFFFF; diff --git a/sql/lock.cc b/sql/lock.cc index 82004298453..29795415720 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -75,8 +75,6 @@ TODO: #include "../myisammrg/myrg_def.h" #endif -extern HASH open_cache; - static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count, bool unlock, TABLE **write_locked); static int lock_external(THD *thd, TABLE **table,uint count); @@ -526,7 +524,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) table->locked_by_name=1; table_list->table=table; - if (hash_insert(&open_cache, (byte*) table)) + if (my_hash_insert(&open_cache, (byte*) table)) { my_free((gptr) table,MYF(0)); DBUG_RETURN(-1); diff --git a/sql/log.cc b/sql/log.cc index 32273a4ac80..9ad779a119b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -31,7 +31,6 @@ #include <m_ctype.h> // For test_if_number MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; -extern I_List<i_string> binlog_do_db, binlog_ignore_db; static bool test_if_number(const char *str, long *res, bool allow_wildcards); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 624ff524c78..23d72901404 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -713,6 +713,9 @@ bool open_log(MYSQL_LOG *log, const char *hostname, enum_log_type type, bool read_append, bool no_auto_events, ulong max_size); +/* mysqld.cc */ +extern void yyerror(const char*); + /* External variables */ @@ -793,7 +796,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_error_log, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_slave_list, LOCK_active_mi, LOCK_manager, - LOCK_global_system_variables; + LOCK_global_system_variables, LOCK_user_conn; extern rw_lock_t LOCK_grant; extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; extern pthread_attr_t connection_attrib; @@ -801,7 +804,8 @@ extern I_List<THD> threads; extern I_List<NAMED_LIST> key_caches; extern MY_BITMAP temp_pool; extern DATE_FORMAT dayord; -extern String empty_string; +extern String my_empty_string; +extern String my_null_string; extern SHOW_VAR init_vars[],status_vars[], internal_vars[]; extern struct show_table_type_st table_type_vars[]; extern SHOW_COMP_OPTION have_isam; @@ -810,7 +814,11 @@ extern SHOW_COMP_OPTION have_berkeley_db; extern struct system_variables global_system_variables; extern struct system_variables max_system_variables; extern struct rand_struct sql_rand; -extern String null_string; +extern HASH open_cache; +extern TABLE *unused_tables; +extern I_List<i_string> binlog_do_db, binlog_ignore_db; +extern const char* any_db; +extern struct my_option my_long_options[]; /* optional things, have_* variables */ @@ -945,6 +953,14 @@ bool flush_error_log(void); void free_list(I_List <i_string_pair> *list); void free_list(I_List <i_string> *list); +/* sql_yacc.cc */ +extern int yyparse(void *thd); + +/* frm_crypt.cc */ +#ifdef HAVE_CRYPTED_FRM +SQL_CRYPT *get_crypt_for_frm(void); +#endif + /* Some inline functions for more speed */ inline bool add_item_to_list(THD *thd, Item *item) diff --git a/sql/net_serv.cc b/sql/net_serv.cc index d39fca595ac..7944a528b83 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -88,10 +88,15 @@ void sql_print_error(const char *format,...); #ifdef MYSQL_SERVER #define USE_QUERY_CACHE +/* + The following variables/functions should really not be declared + extern, but as it's hard to include mysql_priv.h here, we have to + live with this for a while. +*/ extern uint test_flags; -extern void query_cache_insert(NET *net, const char *packet, ulong length); extern ulong bytes_sent, bytes_received, net_big_packet_count; extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; +extern void query_cache_insert(NET *net, const char *packet, ulong length); #else #undef statistic_add #undef statistic_increment @@ -460,7 +465,7 @@ net_real_write(NET *net,const char *packet,ulong len) #ifdef MYSQL_SERVER net->last_errno= ER_OUT_OF_RESOURCES; net->error= 2; - //TODO is it needed to set this variable if we have no socket + /* TODO is it needed to set this variable if we have no socket */ net->report_error= 1; #endif net->reading_or_writing= 0; @@ -889,7 +894,7 @@ my_net_read(NET *net) if (net->remain_in_buf) { - buf_length= net->buf_length; // Data left in old packet + buf_length= net->buf_length; /* Data left in old packet */ first_packet_offset= start_of_packet= (net->buf_length - net->remain_in_buf); /* Restore the character that was overwritten by the end 0 */ diff --git a/sql/records.cc b/sql/records.cc index 72a6d480356..7ba9ff0f42f 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -1,4 +1,3 @@ - /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 0ad13866406..7c943d4ae53 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -34,7 +34,6 @@ RPL_STATUS rpl_status=RPL_NULL; pthread_mutex_t LOCK_rpl_status; pthread_cond_t COND_rpl_status; HASH slave_list; -extern const char* any_db; const char *rpl_role_type[] = {"MASTER","SLAVE",NullS}; TYPELIB rpl_role_typelib = {array_elements(rpl_role_type)-1,"", @@ -176,7 +175,7 @@ int register_slave(THD* thd, uchar* packet, uint packet_length) pthread_mutex_lock(&LOCK_slave_list); unregister_slave(thd,0,0); - res= hash_insert(&slave_list, (byte*) si); + res= my_hash_insert(&slave_list, (byte*) si); pthread_mutex_unlock(&LOCK_slave_list); return res; @@ -539,7 +538,7 @@ HOSTS"; goto err; } si->server_id = server_id; - hash_insert(&slave_list, (byte*)si); + my_hash_insert(&slave_list, (byte*)si); } strmake(si->host, row[1], sizeof(si->host)-1); si->port = atoi(row[port_ind]); diff --git a/sql/set_var.cc b/sql/set_var.cc index e6987fa0657..a44ee96ea0e 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1302,7 +1302,7 @@ bool sys_var_collation::check(THD *thd, set_var *var) String str(buff,sizeof(buff), system_charset_info), *res; if (!(res=var->value->val_str(&str))) - res= &empty_string; + res= &my_empty_string; if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0)))) { @@ -1917,8 +1917,6 @@ static byte *get_sys_var_length(const sys_var *var, uint *length, void set_var_init() { - extern struct my_option my_long_options[]; // From mysqld - hash_init(&system_variable_hash, system_charset_info, array_elements(sys_variables),0,0, (hash_get_key) get_sys_var_length,0,0); @@ -1929,7 +1927,7 @@ void set_var_init() { (*var)->name_length= strlen((*var)->name); (*var)->option_limits= find_option(my_long_options, (*var)->name); - hash_insert(&system_variable_hash, (byte*) *var); + my_hash_insert(&system_variable_hash, (byte*) *var); } /* Special cases diff --git a/sql/slave.cc b/sql/slave.cc index 8490881f5dc..641707aab2f 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -790,7 +790,7 @@ int add_table_rule(HASH* h, const char* table_spec) e->tbl_name = e->db + (dot - table_spec) + 1; e->key_len = len; memcpy(e->db, table_spec, len); - (void)hash_insert(h, (byte*)e); + (void)my_hash_insert(h, (byte*)e); return 0; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 04b5d0c1f4d..179da6096de 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1025,7 +1025,7 @@ static void init_check_host(void) else if (!hash_search(&acl_check_hosts,(byte*) &acl_user->host, (uint) strlen(acl_user->host.hostname))) { - if (hash_insert(&acl_check_hosts,(byte*) acl_user)) + if (my_hash_insert(&acl_check_hosts,(byte*) acl_user)) { // End of memory allow_all_hosts=1; // Should never happen DBUG_VOID_RETURN; @@ -1738,7 +1738,7 @@ public: privs = cols = 0; /* purecov: deadcode */ return; /* purecov: deadcode */ } - hash_insert(&hash_columns, (byte *) mem_check); + my_hash_insert(&hash_columns, (byte *) mem_check); } while (!col_privs->file->index_next(col_privs->record[0]) && !key_cmp(col_privs,key,0,key_len)); } @@ -1900,7 +1900,7 @@ static int replace_column_table(GRANT_TABLE *g_t, goto end; /* purecov: inspected */ } GRANT_COLUMN *grant_column = new GRANT_COLUMN(xx->column,privileges); - hash_insert(&g_t->hash_columns,(byte*) grant_column); + my_hash_insert(&g_t->hash_columns,(byte*) grant_column); } } table->file->index_end(); @@ -2251,7 +2251,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, result= -1; /* purecov: deadcode */ continue; /* purecov: deadcode */ } - hash_insert(&column_priv_hash,(byte*) grant_table); + my_hash_insert(&column_priv_hash,(byte*) grant_table); } /* If revoke_grant, calculate the new column privilege for tables_priv */ @@ -2494,7 +2494,7 @@ my_bool grant_init(THD *org_thd) { GRANT_TABLE *mem_check; if (!(mem_check=new GRANT_TABLE(t_table,c_table)) || - mem_check->ok() && hash_insert(&column_priv_hash,(byte*) mem_check)) + mem_check->ok() && my_hash_insert(&column_priv_hash,(byte*) mem_check)) { /* This could only happen if we are out memory */ grant_option= FALSE; /* purecov: deadcode */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 617f6590463..73468ecf8eb 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -872,7 +872,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, table->version=refresh_version; table->flush_version=flush_version; DBUG_PRINT("info", ("inserting table %p into the cache", table)); - VOID(hash_insert(&open_cache,(byte*) table)); + VOID(my_hash_insert(&open_cache,(byte*) table)); } table->in_use=thd; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 9e3d00c27b1..9460b6cf577 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -823,7 +823,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) Query_cache_query *header = query_block->query(); header->init_n_lock(); - if (hash_insert(&queries, (byte*) query_block)) + if (my_hash_insert(&queries, (byte*) query_block)) { refused++; DBUG_PRINT("qcache", ("insertion in query hash")); @@ -2046,7 +2046,7 @@ Query_cache::insert_table(uint key_len, char *key, Query_cache_block_table *list_root = table_block->table(0); list_root->n = 0; list_root->next = list_root->prev = list_root; - if (hash_insert(&tables, (const byte *) table_block)) + if (my_hash_insert(&tables, (const byte *) table_block)) { DBUG_PRINT("qcache", ("Can't insert table to hash")); // write_block_data return locked block diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b4f1ba8b7f7..de2da5a379b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -585,7 +585,7 @@ sql_exchange::sql_exchange(char *name,bool flag) :file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0) { field_term= &default_field_term; - enclosed= line_start= &empty_string; + enclosed= line_start= &my_empty_string; line_term= &default_line_term; escaped= &default_escaped; } diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index f5721a6832e..a740bb1b3c7 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -25,8 +25,6 @@ #include "sql_select.h" #include "sql_acl.h" -extern const char *any_db; // Special symbol for check_access - /* Resolve derived tables in all queries diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 51ed3bf60be..af28d48ed8a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1574,8 +1574,6 @@ bool select_create::send_data(List<Item> &values) return 0; } -extern HASH open_cache; - bool select_create::send_eof() { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4f7e4a5e8a8..15039e331f6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -44,7 +44,6 @@ #define MIN_HANDSHAKE_SIZE 6 #endif /* HAVE_OPENSSL */ -extern int yyparse(void *thd); extern "C" pthread_mutex_t THR_LOCK_keycache; #ifdef SOLARIS extern "C" int gethostname(char *name, int namelen); @@ -124,7 +123,6 @@ static bool end_active_trans(THD *thd) static HASH hash_user_connections; -extern pthread_mutex_t LOCK_user_conn; static int get_or_create_user_conn(THD *thd, const char *user, const char *host, @@ -165,7 +163,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, if (max_user_connections && mqh->connections > max_user_connections) uc->user_resources.connections = max_user_connections; uc->intime=thd->thr_create_time; - if (hash_insert(&hash_user_connections, (byte*) uc)) + if (my_hash_insert(&hash_user_connections, (byte*) uc)) { my_free((char*) uc,0); send_error(thd, 0, NullS); // Out of memory @@ -1745,6 +1743,10 @@ mysql_execute_command(THD *thd) break; // Error message is given } #endif + /* + In case of single SELECT unit->global_parameters points on first SELECT + TODO: move counters to SELECT_LEX + */ unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit; unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+ unit->global_parameters->offset_limit); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 95e46f02f93..ff7886f87f1 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -76,8 +76,7 @@ Long data handling: #define STMT_QUERY_LOG_LENGTH 8192 -extern int yyparse(void *thd); -String null_string("NULL", 4, default_charset_info); +String my_null_string("NULL", 4, default_charset_info); /* Find prepared statement in thd @@ -429,7 +428,7 @@ static bool insert_params_withlog(PREP_STMT *stmt, uchar *pos, uchar *read_pos) if (IS_PARAM_NULL(pos,param_no)) { param->maybe_null= param->null_value= 1; - res= &null_string; + res= &my_null_string; } else { @@ -673,7 +672,9 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, DBUG_RETURN(1); if (send_prep_stmt(stmt, fields.elements) || thd->protocol_simple.send_fields(&fields, 0) || +#ifndef EMBEDDED_LIBRARY net_flush(&thd->net) || +#endif send_item_params(stmt)) DBUG_RETURN(1); join->cleanup(); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index f5bfc9c61c3..7bb51989cc3 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -24,8 +24,6 @@ #include "log_event.h" #include <my_dir.h> -extern const char* any_db; - int max_binlog_dump_events = 0; // unlimited my_bool opt_sporadic_binlog_dump_fail = 0; static int binlog_dump_count = 0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ab985ffbc6d..ff41e9fd067 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7196,7 +7196,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, goto err; } else - (void) hash_insert(&hash, key_pos-key_length); + (void) my_hash_insert(&hash, key_pos-key_length); key_pos+=extra_length; } my_free((char*) key_buffer,MYF(0)); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 18dbb04c0ed..8550973ff88 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1506,11 +1506,15 @@ int mysqld_show_collations(THD *thd, const char *wild) for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) { CHARSET_INFO **cl; + if (!cs[0] || !(cs[0]->state & MY_CS_AVAILABLE) || + !(cs[0]->state & MY_CS_PRIMARY)) + continue; for ( cl= all_charsets; cl < all_charsets+255 ;cl ++) { - if (!cs[0] || !cl[0] || !my_charset_same(cs[0],cl[0]) || !(cs[0]->state & MY_CS_PRIMARY)) + if (!cl[0] || !(cl[0]->state & MY_CS_AVAILABLE) || + !my_charset_same(cs[0],cl[0])) continue; - if (cs[0] && !(wild && wild[0] && + if (!(wild && wild[0] && wild_case_compare(system_charset_info,cl[0]->name,wild))) { if (write_collation(protocol, cl[0])) @@ -1554,8 +1558,10 @@ int mysqld_show_charsets(THD *thd, const char *wild) for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) { - if (cs[0] && (cs[0]->state & MY_CS_PRIMARY) && !(wild && wild[0] && - wild_case_compare(system_charset_info,cs[0]->name,wild))) + if (cs[0] && (cs[0]->state & MY_CS_PRIMARY) && + (cs[0]->state & MY_CS_AVAILABLE) && + !(wild && wild[0] && + wild_case_compare(system_charset_info,cs[0]->csname,wild))) { if (write_charset(protocol, cs[0])) goto err; diff --git a/sql/sql_string.cc b/sql/sql_string.cc index e7d7b08c93c..be9404ce0b8 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -28,6 +28,11 @@ #include <floatingpoint.h> #endif +/* + The following extern declarations are ok as these are interface functions + required by the string function +*/ + extern gptr sql_alloc(unsigned size); extern void sql_element_free(void *ptr); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5e4971a7372..b8f4b360dda 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -29,7 +29,6 @@ #include <io.h> #endif -extern HASH open_cache; static const char *primary_key_name="PRIMARY"; static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end); diff --git a/sql/sql_test.cc b/sql/sql_test.cc index d2f97640010..f991a09398b 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -41,7 +41,6 @@ static const char *lock_descriptions[] = "High priority write lock", "Highest priority write lock" }; -extern HASH open_cache; #ifndef DBUG_OFF @@ -65,7 +64,6 @@ print_where(COND *cond,const char *info) } /* This is for debugging purposes */ -extern TABLE *unused_tables; void print_cached_tables(void) { diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 99410bb34ac..c237b023e7b 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -345,7 +345,7 @@ static udf_func *add_udf(LEX_STRING *name, Item_result ret, char *dl, tmp->returns = ret; tmp->type = type; tmp->usage_count=1; - if (hash_insert(&udf_hash,(byte*) tmp)) + if (my_hash_insert(&udf_hash,(byte*) tmp)) return 0; using_udf_functions=1; return tmp; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 2d7bee54da8..ae596625bf7 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -262,8 +262,23 @@ int st_select_lex_unit::exec() res= sl->join->reinit(); else { - offset_limit_cnt= sl->offset_limit; - select_limit_cnt= sl->select_limit+sl->offset_limit; + if (sl != global_parameters) + { + offset_limit_cnt= sl->offset_limit; + select_limit_cnt= sl->select_limit+sl->offset_limit; + } + else + { + offset_limit_cnt= 0; + /* + We can't use LIMIT at this stage if we are using ORDER BY for the + whole query + */ + if (sl->order_list.first) + select_limit_cnt= HA_POS_ERROR; + else + select_limit_cnt= sl->select_limit+sl->offset_limit; + } if (select_limit_cnt < sl->select_limit) select_limit_cnt= HA_POS_ERROR; // no limit @@ -352,14 +367,11 @@ int st_select_lex_unit::exec() { ulong options= thd->options; thd->lex.current_select= fake_select_lex; - if (select_cursor->braces) - { - offset_limit_cnt= global_parameters->offset_limit; - select_limit_cnt= global_parameters->select_limit + - global_parameters->offset_limit; - if (select_limit_cnt < global_parameters->select_limit) - select_limit_cnt= HA_POS_ERROR; // no limit - } + offset_limit_cnt= global_parameters->offset_limit; + select_limit_cnt= global_parameters->select_limit + + global_parameters->offset_limit; + if (select_limit_cnt < global_parameters->select_limit) + select_limit_cnt= HA_POS_ERROR; // no limit if (select_limit_cnt == HA_POS_ERROR) options&= ~OPTION_FOUND_ROWS; else if (found_rows_for_union && !describe) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6491dd6cad1..0205d69da00 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -38,7 +38,6 @@ #include <myisam.h> #include <myisammrg.h> -extern void yyerror(const char*); int yylex(void *yylval, void *yythd); #define yyoverflow(A,B,C,D,E,F) if (my_yyoverflow((B),(D),(int*) (F))) { yyerror((char*) (A)); return 2; } diff --git a/sql/table.cc b/sql/table.cc index a980e086d60..c31b68fc2dc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -236,7 +236,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, #ifdef HAVE_CRYPTED_FRM else if (*(head+26) == 2) { - extern SQL_CRYPT *get_crypt_for_frm(void); my_pthread_setspecific_ptr(THR_MALLOC,old_root); crypted=get_crypt_for_frm(); my_pthread_setspecific_ptr(THR_MALLOC,&outparam->mem_root); @@ -459,7 +458,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (outparam->timestamp_field == reg_field) outparam->timestamp_field_offset=i; if (use_hash) - (void) hash_insert(&outparam->name_hash,(byte*) *field_ptr); // Will never fail + (void) my_hash_insert(&outparam->name_hash,(byte*) *field_ptr); // Will never fail } *field_ptr=0; // End marker diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index ddcec46474d..878493bc31f 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6234,6 +6234,7 @@ static MY_COLLATION_HANDLER my_collation_big5_chinese_ci_handler = my_like_range_big5, my_wildcmp_mb, my_strcasecmp_mb, + my_instr_mb, my_hash_sort_simple }; @@ -6305,7 +6306,7 @@ CHARSET_INFO my_charset_big5_bin= 2, /* mbmaxlen */ 0, &my_charset_big5_handler, - &my_collation_bin_handler + &my_collation_mb_bin_handler }; diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 9441268739a..340084ad848 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -262,8 +262,68 @@ static int my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)), return len; } +static +uint my_instr_bin(CHARSET_INFO *cs __attribute__((unused)), + const char *big, uint b_length, + const char *small, uint s_length, + my_match_t *match, uint nmatch) +{ + register const uchar *str, *search, *end, *search_end; + + if (s_length <= b_length) + { + if (!s_length) + { + if (nmatch) + { + match->beg= 0; + match->end= 0; + match->mblen= 0; + } + return 1; /* Empty string is always found */ + } + + str= (const uchar*) big; + search= (const uchar*) small; + end= (const uchar*) big+b_length-s_length+1; + search_end= (const uchar*) small + s_length; + +skipp: + while (str != end) + { + if ( (*str++) == (*search)) + { + register const uchar *i,*j; + + i= str; + j= search+1; + + while (j != search_end) + if ((*i++) != (*j++)) + goto skipp; + + if (nmatch > 0) + { + match[0].beg= 0; + match[0].end= str- (const uchar*)big-1; + match[0].mblen= match[0].end; + + if (nmatch > 1) + { + match[1].beg= match[0].end; + match[1].end= match[0].end+s_length; + match[1].mblen= match[1].end-match[1].beg; + } + } + return 2; + } + } + } + return 0; +} + -MY_COLLATION_HANDLER my_collation_bin_handler = +MY_COLLATION_HANDLER my_collation_8bit_bin_handler = { my_strnncoll_binary, my_strnncollsp_binary, @@ -271,6 +331,7 @@ MY_COLLATION_HANDLER my_collation_bin_handler = my_like_range_simple, my_wildcmp_bin, my_strcasecmp_bin, + my_instr_bin, my_hash_sort_bin }; @@ -317,5 +378,5 @@ CHARSET_INFO my_charset_bin = 1, /* mbmaxlen */ (char) 255, /* max_sort_char */ &my_charset_handler, - &my_collation_bin_handler + &my_collation_8bit_bin_handler }; diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 2398bc33d45..b2e4f1886ed 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -612,6 +612,7 @@ static MY_COLLATION_HANDLER my_collation_latin2_czech_ci_handler = my_like_range_czech, my_wildcmp_8bit, my_strcasecmp_8bit, + my_instr_simple, my_hash_sort_simple, }; diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index bb3e66a8c6f..d47c4268642 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8637,12 +8637,13 @@ my_mb_wc_euc_kr(CHARSET_INFO *cs __attribute__((unused)), static MY_COLLATION_HANDLER my_collation_ci_handler = { - my_strnncoll_simple,/* strnncoll */ + my_strnncoll_simple, /* strnncoll */ my_strnncollsp_simple, my_strnxfrm_simple, /* strnxfrm */ - my_like_range_simple,/* like_range */ + my_like_range_simple, /* like_range */ my_wildcmp_mb, /* wildcmp */ my_strcasecmp_mb, + my_instr_mb, my_hash_sort_simple, }; @@ -8714,7 +8715,7 @@ CHARSET_INFO my_charset_euckr_bin= 2, /* mbmaxlen */ 0, &my_charset_handler, - &my_collation_bin_handler + &my_collation_mb_bin_handler }; #endif diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index b8cee35b186..d429fa34eea 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5687,12 +5687,13 @@ my_mb_wc_gb2312(CHARSET_INFO *cs __attribute__((unused)), static MY_COLLATION_HANDLER my_collation_ci_handler = { - my_strnncoll_simple,/* strnncoll */ + my_strnncoll_simple, /* strnncoll */ my_strnncollsp_simple, my_strnxfrm_simple, /* strnxfrm */ - my_like_range_simple,/* like_range */ + my_like_range_simple, /* like_range */ my_wildcmp_mb, /* wildcmp */ - my_strcasecmp_mb, + my_strcasecmp_mb, /* instr */ + my_instr_mb, my_hash_sort_simple, }; @@ -5763,7 +5764,7 @@ CHARSET_INFO my_charset_gb2312_bin= 2, /* mbmaxlen */ 0, &my_charset_handler, - &my_collation_bin_handler + &my_collation_mb_bin_handler }; #endif diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 4a84eabaf8c..fa7aa175103 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9890,6 +9890,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler = my_like_range_gbk, my_wildcmp_mb, my_strcasecmp_mb, + my_instr_mb, my_hash_sort_simple, }; @@ -9960,7 +9961,7 @@ CHARSET_INFO my_charset_gbk_bin= 2, /* mbmaxlen */ 0, &my_charset_handler, - &my_collation_bin_handler + &my_collation_mb_bin_handler }; diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index edbd350f364..a8a5329f844 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -390,6 +390,7 @@ static MY_COLLATION_HANDLER my_collation_german2_ci_handler= my_like_range_simple, my_wildcmp_8bit, my_strcasecmp_8bit, + my_instr_simple, my_hash_sort_simple }; @@ -435,6 +436,6 @@ CHARSET_INFO my_charset_latin1_bin= 1, /* mbmaxlen */ 0, &my_charset_handler, - &my_collation_bin_handler + &my_collation_8bit_bin_handler }; diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 3d1abe95675..ba53ebfb64c 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -126,11 +126,7 @@ int my_strcasecmp_mb(CHARSET_INFO * cs,const char *s, const char *t) #define INC_PTR(cs,A,B) A+=((use_mb_flag && \ my_ismbchar(cs,A,B)) ? my_ismbchar(cs,A,B) : 1) -#ifdef LIKE_CMP_TOUPPER -#define likeconv(s,A) (uchar) my_toupper(s,A) -#else #define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)] -#endif int my_wildcmp_mb(CHARSET_INFO *cs, const char *str,const char *str_end, @@ -278,5 +274,247 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), return b-b0; } +uint my_instr_mb(CHARSET_INFO *cs, + const char *big, uint b_length, + const char *small, uint s_length, + my_match_t *match, uint nmatch) +{ + register const char *end, *big0; + int res= 0; + + if (s_length <= b_length) + { + if (!s_length) + { + if (nmatch) + { + match->beg= 0; + match->end= 0; + match->mblen= 0; + } + return 1; // Empty string is always found + } + + big0= big; + end= big+b_length-s_length+1; + + while (big < end) + { + int mblen; + + if (!cs->coll->strnncoll(cs, (unsigned char*) big, s_length, + (unsigned char*) small, s_length)) + { + if (nmatch) + { + match[0].beg= big0; + match[0].end= big-big0; + match[0].mblen= res; + if (nmatch > 1) + { + match[1].beg= match[0].end; + match[1].end= match[0].end+s_length; + match[1].mblen= 0; /* Not computed */ + } + } + return 2; + } + mblen= (mblen= my_ismbchar(cs, big, end)) ? mblen : 1; + big+= mblen; + b_length-= mblen; + res++; + } + } + return 0; +} + +/* BINARY collations handlers for MB charsets */ + +static int my_strnncoll_mb_bin(CHARSET_INFO * cs __attribute__((unused)), + const uchar *s, uint slen, + const uchar *t, uint tlen) +{ + int cmp= memcmp(s,t,min(slen,tlen)); + return cmp ? cmp : (int) (slen - tlen); +} + +static int my_strnncollsp_mb_bin(CHARSET_INFO * cs, + const uchar *s, uint slen, + const uchar *t, uint tlen) +{ + int len, cmp; + + for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--); + for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--); + + len = ( slen > tlen ) ? tlen : slen; + + cmp= memcmp(s,t,len); + return cmp ? cmp : (int) (slen - tlen); +} + +static int my_strnxfrm_mb_bin(CHARSET_INFO *cs __attribute__((unused)), + uchar * dest, uint len, + const uchar *src, + uint srclen __attribute__((unused))) +{ + if (dest != src) + memcpy(dest,src,len= min(len,srclen)); + return len; +} + + +static int my_strcasecmp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), + const char *s, const char *t) +{ + return strcmp(s,t); +} + +static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)), + const uchar *key, uint len,ulong *nr1, ulong *nr2) +{ + const uchar *pos = key; + + key+= len; + + for (; pos < (uchar*) key ; pos++) + { + nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * + ((uint)*pos)) + (nr1[0] << 8); + nr2[0]+=3; + } +} + +static int my_wildcmp_mb_bin(CHARSET_INFO *cs, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many) +{ + int result= -1; /* Not found, using wildcards */ + + bool use_mb_flag=use_mb(cs); + + while (wildstr != wildend) + { + while (*wildstr != w_many && *wildstr != w_one) + { + int l; + if (*wildstr == escape && wildstr+1 != wildend) + wildstr++; + if (use_mb_flag && + (l = my_ismbchar(cs, wildstr, wildend))) + { + if (str+l > str_end || memcmp(str, wildstr, l) != 0) + return 1; + str += l; + wildstr += l; + } + else + if (str == str_end || *wildstr++ != *str++) + return(1); /* No match */ + if (wildstr == wildend) + return (str != str_end); /* Match if both are at end */ + result=1; /* Found an anchor char */ + } + if (*wildstr == w_one) + { + do + { + if (str == str_end) /* Skip one char if possible */ + return (result); + INC_PTR(cs,str,str_end); + } while (++wildstr < wildend && *wildstr == w_one); + if (wildstr == wildend) + break; + } + if (*wildstr == w_many) + { /* Found w_many */ + uchar cmp; + const char* mb = wildstr; + int mblen=0; + + wildstr++; + /* Remove any '%' and '_' from the wild search string */ + for (; wildstr != wildend ; wildstr++) + { + if (*wildstr == w_many) + continue; + if (*wildstr == w_one) + { + if (str == str_end) + return (-1); + INC_PTR(cs,str,str_end); + continue; + } + break; /* Not a wild character */ + } + if (wildstr == wildend) + return(0); /* Ok if w_many is last */ + if (str == str_end) + return -1; + + if ((cmp= *wildstr) == escape && wildstr+1 != wildend) + cmp= *++wildstr; + + mb=wildstr; + LINT_INIT(mblen); + if (use_mb_flag) + mblen = my_ismbchar(cs, wildstr, wildend); + INC_PTR(cs,wildstr,wildend); /* This is compared trough cmp */ + do + { + if (use_mb_flag) + { + for (;;) + { + if (str >= str_end) + return -1; + if (mblen) + { + if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0) + { + str += mblen; + break; + } + } + else if (!my_ismbchar(cs, str, str_end) && *str == cmp) + { + str++; + break; + } + INC_PTR(cs,str, str_end); + } + } + else + { + while (str != str_end && *str != cmp) + str++; + if (str++ == str_end) return (-1); + } + { + int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,w_many); + if (tmp <= 0) + return (tmp); + } + } while (str != str_end && wildstr[0] != w_many); + return(-1); + } + } + return (str != str_end ? 1 : 0); +} + + +MY_COLLATION_HANDLER my_collation_mb_bin_handler = +{ + my_strnncoll_mb_bin, + my_strnncollsp_mb_bin, + my_strnxfrm_mb_bin, + my_like_range_simple, + my_wildcmp_mb_bin, + my_strcasecmp_mb_bin, + my_instr_mb, + my_hash_sort_mb_bin +}; + #endif diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index ca0097579bd..f85ce5e7a2b 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1030,6 +1030,66 @@ uint my_lengthsp_8bit(CHARSET_INFO *cs __attribute__((unused)), } +uint my_instr_simple(CHARSET_INFO *cs, + const char *big, uint b_length, + const char *small, uint s_length, + my_match_t *match, uint nmatch) +{ + register const uchar *str, *search, *end, *search_end; + + if (s_length <= b_length) + { + if (!s_length) + { + if (nmatch) + { + match->beg= 0; + match->end= 0; + match->mblen= 0; + } + return 1; /* Empty string is always found */ + } + + str= (const uchar*) big; + search= (const uchar*) small; + end= (const uchar*) big+b_length-s_length+1; + search_end= (const uchar*) small + s_length; + +skipp: + while (str != end) + { + if (cs->sort_order[*str++] == cs->sort_order[*search]) + { + register const uchar *i,*j; + + i= str; + j= search+1; + + while (j != search_end) + if (cs->sort_order[*i++] != cs->sort_order[*j++]) + goto skipp; + + if (nmatch > 0) + { + match[0].beg= 0; + match[0].end= str- (const uchar*)big-1; + match[0].mblen= match[0].end; + + if (nmatch > 1) + { + match[1].beg= match[0].end; + match[1].end= match[0].end+s_length; + match[1].mblen= match[1].end-match[1].beg; + } + } + return 2; + } + } + } + return 0; +} + + MY_CHARSET_HANDLER my_charset_8bit_handler= { NULL, /* ismbchar */ @@ -1063,5 +1123,6 @@ MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler = my_like_range_simple, my_wildcmp_8bit, my_strcasecmp_8bit, + my_instr_simple, my_hash_sort_simple }; diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 9827c19e7fb..f302e678b9f 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4477,6 +4477,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler = my_like_range_sjis, my_wildcmp_mb, /* wildcmp */ my_strcasecmp_8bit, + my_instr_mb, my_hash_sort_simple, }; @@ -4547,7 +4548,7 @@ CHARSET_INFO my_charset_sjis_bin= 2, /* mbmaxlen */ 0, &my_charset_handler, - &my_collation_bin_handler + &my_collation_mb_bin_handler }; #endif diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 8a6e00b973a..a4d8a7d1f79 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -710,6 +710,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler = my_like_range_tis620, my_wildcmp_8bit, /* wildcmp */ my_strcasecmp_8bit, + NULL, my_hash_sort_simple, }; @@ -781,7 +782,7 @@ CHARSET_INFO my_charset_tis620_bin= 1, /* mbmaxlen */ 0, &my_charset_handler, - &my_collation_bin_handler + &my_collation_8bit_bin_handler }; diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index a20502c65d4..cdcd91b2916 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -90,7 +90,7 @@ static uchar to_upper_ucs2[] = { }; -static int my_ucs2_uni (CHARSET_INFO *cs __attribute__((unused)) , +static int my_ucs2_uni (CHARSET_INFO *cs __attribute__((unused)), my_wc_t * pwc, const uchar *s, const uchar *e) { if (s+2 > e) /* Need 2 characters */ @@ -1018,20 +1018,268 @@ uint my_lengthsp_ucs2(CHARSET_INFO *cs __attribute__((unused)), return (uint) (end-ptr); } +/* +** Compare string against string with wildcard +** 0 if matched +** -1 if not matched with wildcard +** 1 if matched with wildcard +*/ + +static +int my_wildcmp_ucs2(CHARSET_INFO *cs, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many, + MY_UNICASE_INFO **weights) +{ + int result= -1; /* Not found, using wildcards */ + my_wc_t s_wc, w_wc; + int scan, plane; + + while (wildstr != wildend) + { + + while (1) + { + scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); + if (scan <= 0) + return 1; + wildstr+= scan; + + if (w_wc == (my_wc_t)escape) + { + scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); + if (scan <= 0) + return 1; + wildstr+= scan; + } + + if (w_wc == (my_wc_t)w_many) + { + result= 1; /* Found an anchor char */ + break; + } + + scan= my_ucs2_uni(cs, &s_wc, (const uchar*)str, (const uchar*)str_end); + if (scan <=0) + return 1; + str+= scan; + + if (w_wc == (my_wc_t)w_one) + { + result= 1; /* Found an anchor char */ + } + else + { + if (weights) + { + plane=(s_wc>>8) & 0xFF; + s_wc = weights[plane] ? weights[plane][s_wc & 0xFF].sort : s_wc; + plane=(w_wc>>8) & 0xFF; + w_wc = weights[plane] ? weights[plane][w_wc & 0xFF].sort : w_wc; + } + if (s_wc != w_wc) + return 1; /* No match */ + } + if (wildstr == wildend) + return (str != str_end); /* Match if both are at end */ + } + + + if (w_wc == (my_wc_t)w_many) + { /* Found w_many */ + + /* Remove any '%' and '_' from the wild search string */ + for ( ; wildstr != wildend ; ) + { + scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); + if (scan <= 0) + return 1; + wildstr+= scan; + + if (w_wc == (my_wc_t)w_many) + continue; + + if (w_wc == (my_wc_t)w_one) + { + scan= my_ucs2_uni(cs, &s_wc, (const uchar*)str, (const uchar*)str_end); + if (scan <=0) + return 1; + str+= scan; + continue; + } + break; /* Not a wild character */ + } + + if (wildstr == wildend) + return 0; /* Ok if w_many is last */ + + if (str == str_end) + return -1; + + scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); + if (scan <= 0) + return 1; + wildstr+= scan; + + if (w_wc == (my_wc_t)escape) + { + scan= my_ucs2_uni(cs,&w_wc, (const uchar*)wildstr, (const uchar*)wildend); + if (scan <= 0) + return 1; + wildstr+= scan; + } + + do + { + /* Skip until the first character from wildstr is found */ + while (str != str_end) + { + scan= my_ucs2_uni(cs,&s_wc, (const uchar*)str, (const uchar*)str_end); + if (scan <= 0) + return 1; + str+= scan; + + if (weights) + { + plane=(s_wc>>8) & 0xFF; + s_wc = weights[plane] ? weights[plane][s_wc & 0xFF].sort : s_wc; + plane=(w_wc>>8) & 0xFF; + w_wc = weights[plane] ? weights[plane][w_wc & 0xFF].sort : w_wc; + } + + if (s_wc == w_wc) + break; + } + if (str == str_end) + return -1; + + result= my_wildcmp_ucs2(cs,str,str_end,wildstr,wildend,escape, + w_one,w_many,weights); + if (result <= 0) + return result; + + } while (str != str_end && w_wc != (my_wc_t)w_many); + return -1; + } + } + return (str != str_end ? 1 : 0); +} + + +static +int my_wildcmp_ucs2_ci(CHARSET_INFO *cs, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many) +{ + return my_wildcmp_ucs2(cs,str,str_end,wildstr,wildend, + escape,w_one,w_many,uni_plane); +} + +static +int my_wildcmp_ucs2_bin(CHARSET_INFO *cs, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many) +{ + return my_wildcmp_ucs2(cs,str,str_end,wildstr,wildend, + escape,w_one,w_many,NULL); +} + + +static +int my_strnncoll_ucs2_bin(CHARSET_INFO *cs, + const uchar *s, uint slen, + const uchar *t, uint tlen) +{ + int s_res,t_res; + my_wc_t s_wc,t_wc; + const uchar *se=s+slen; + const uchar *te=t+tlen; + while ( s < se && t < te ) + { + s_res=my_ucs2_uni(cs,&s_wc, s, se); + t_res=my_ucs2_uni(cs,&t_wc, t, te); + + if ( s_res <= 0 || t_res <= 0 ) + { + /* Incorrect string, compare by char value */ + return ((int)s[0]-(int)t[0]); + } + if ( s_wc != t_wc ) + { + return ((int) s_wc) - ((int) t_wc); + } + + s+=s_res; + t+=t_res; + } + return ( (se-s) - (te-t) ); +} -static MY_COLLATION_HANDLER my_collation_ci_handler = +static +int my_strcasecmp_ucs2_bin(CHARSET_INFO *cs, const char *s, const char *t) +{ + uint s_len=strlen(s); + uint t_len=strlen(t); + uint len = (s_len > t_len) ? s_len : t_len; + return my_strncasecmp_ucs2(cs, s, t, len); +} + +static +int my_strnxfrm_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)), + uchar *dst, uint dstlen, + const uchar *src, uint srclen) +{ + if (dst != src) + memcpy(dst,src,srclen= min(dstlen,srclen)); + return srclen; +} + +static +void my_hash_sort_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)), + const uchar *key, uint len,ulong *nr1, ulong *nr2) +{ + const uchar *pos = key; + + key+= len; + + for (; pos < (uchar*) key ; pos++) + { + nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * + ((uint)*pos)) + (nr1[0] << 8); + nr2[0]+=3; + } +} + + +static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler = { my_strnncoll_ucs2, my_strnncoll_ucs2, my_strnxfrm_ucs2, my_like_range_simple, - my_wildcmp_mb, + my_wildcmp_ucs2_ci, my_strcasecmp_ucs2, + my_instr_mb, my_hash_sort_ucs2 }; -static MY_CHARSET_HANDLER my_charset_handler= +static MY_COLLATION_HANDLER my_collation_ucs2_bin_handler = +{ + my_strnncoll_ucs2_bin, + my_strnncoll_ucs2_bin, + my_strnxfrm_ucs2_bin, + my_like_range_simple, + my_wildcmp_ucs2_bin, + my_strcasecmp_ucs2_bin, + my_instr_mb, + my_hash_sort_ucs2_bin +}; + +static MY_CHARSET_HANDLER my_charset_ucs2_handler= { my_ismbchar_ucs2, /* ismbchar */ my_mbcharlen_ucs2, /* mbcharlen */ @@ -1076,8 +1324,8 @@ CHARSET_INFO my_charset_ucs2_general_ci= 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, - &my_charset_handler, - &my_collation_ci_handler + &my_charset_ucs2_handler, + &my_collation_ucs2_general_ci_handler }; @@ -1099,8 +1347,8 @@ CHARSET_INFO my_charset_ucs2_bin= 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, - &my_charset_handler, - &my_collation_bin_handler + &my_charset_ucs2_handler, + &my_collation_ucs2_bin_handler }; diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 5ef6c1b7486..29375aca727 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8434,6 +8434,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler = my_like_range_simple,/* like_range */ my_wildcmp_mb, /* wildcmp */ my_strcasecmp_mb, + my_instr_mb, my_hash_sort_simple, }; @@ -8504,7 +8505,7 @@ CHARSET_INFO my_charset_ujis_bin= 3, /* mbmaxlen */ 0, &my_charset_handler, - &my_collation_bin_handler + &my_collation_mb_bin_handler }; diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 450c2d7aa93..3ede1aa26f6 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1959,6 +1959,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler = my_like_range_simple, my_wildcmp_mb, my_strcasecmp_utf8, + my_instr_mb, my_hash_sort_utf8 }; @@ -2031,7 +2032,7 @@ CHARSET_INFO my_charset_utf8_bin= 3, /* mbmaxlen */ 0, &my_charset_handler, - &my_collation_bin_handler + &my_collation_mb_bin_handler }; diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 12a8edc4a8f..60a5737009f 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -652,6 +652,7 @@ static MY_COLLATION_HANDLER my_collation_czech_ci_handler = my_like_range_win1250ch, my_wildcmp_8bit, my_strcasecmp_8bit, + my_instr_simple, my_hash_sort_simple }; diff --git a/strings/xml.c b/strings/xml.c index 793c155ea63..7d7839e1603 100644 --- a/strings/xml.c +++ b/strings/xml.c @@ -255,7 +255,7 @@ int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len) if(MY_XML_EQ==(lex=my_xml_scan(p,&b))) { lex=my_xml_scan(p,&b); - if ( (lex==MY_XML_IDENT) || (lex=MY_XML_STRING) ) + if ( (lex==MY_XML_IDENT) || (lex==MY_XML_STRING) ) { if((MY_XML_OK!=my_xml_enter(p,a.beg,a.end-a.beg)) || (MY_XML_OK!=my_xml_value(p,b.beg,b.end-b.beg)) || diff --git a/tests/client_test.c b/tests/client_test.c index ac83ceda39f..388d5743cfb 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -6841,7 +6841,7 @@ static void test_logs() fprintf(stdout, "\n name : %s(%ld)", data, length); myassert(id == 9876); - myassert(length == 19);//Due to VARCHAR(20) + myassert(length == 19); /* Due to VARCHAR(20) */ myassert(strcmp(data,"MySQL - Open Source")==0); rc = mysql_fetch(stmt); diff --git a/tools/mysqlmanager.c b/tools/mysqlmanager.c index 70382c29735..f1efd3be3eb 100644 --- a/tools/mysqlmanager.c +++ b/tools/mysqlmanager.c @@ -818,7 +818,7 @@ HANDLE_DECL(handle_def_exec) update_req_len(e); hash_delete(&exec_hash,(byte*)old_e); } - hash_insert(&exec_hash,(byte*)e); + my_hash_insert(&exec_hash,(byte*)e); pthread_mutex_unlock(&lock_exec_hash); client_msg(&thd->net,MANAGER_OK,"Exec definition created"); return 0; @@ -1666,7 +1666,7 @@ static void init_user_hash() } else { - hash_insert(&user_hash,(gptr)u); + my_hash_insert(&user_hash,(gptr)u); } } my_fclose(f, MYF(0)); |