diff options
115 files changed, 1896 insertions, 550 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index dff4cec203c..48144e71863 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -97,6 +97,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 806fb5052b4..07369aa565e 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -24,11 +24,13 @@ #define MAXLENGTH 1000 #define MAX_ROWS 1000 #define MAX_FILES 10 +#define MAX_CHARSET_NAME 64 int row_count; uint file_pos[MAX_ROWS],file_row_pos[MAX_FILES]; my_string saved_row[MAX_ROWS]; uchar file_head[]= { 254,254,2,1 }; +char charset_name[MAX_CHARSET_NAME]; static void get_options(int *argc,char **argv[]); static int count_rows(FILE *from,pchar c, pchar c2); @@ -40,11 +42,12 @@ static int copy_rows(FILE *to); int main(int argc,char *argv[]) { + uint csnum= 0; int i,error,files,length; uchar head[32]; FILE *from,*to; MY_INIT(argv[0]); - + get_options(&argc,&argv); error=1; row_count=files=0; @@ -61,6 +64,20 @@ int main(int argc,char *argv[]) } VOID(count_rows(from,'"','}')); /* Calculate start-info */ + if (!charset_name[0]) + { + fprintf(stderr,"Character set is not specified in '%s'\n",*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); + fclose(from); + goto end; + } + if (remember_rows(from,'}') < 0) /* Remember rows */ { fprintf(stderr,"Can't find textrows in '%s'\n",*argv); @@ -91,7 +108,8 @@ int main(int argc,char *argv[]) { int2store(head+10+i+i,file_row_pos[i]); } - + head[30]= csnum; + fseek(to,0l,0); if (fwrite(head,1,32,to) != 32) goto end; @@ -134,6 +152,10 @@ static void get_options(register int *argc,register char **argv[]) case 'V': printf("%s (Compile errormessage) Ver 1.3\n",progname); break; + case 'C': + charsets_dir= pos+1; + *(pos--)= '\0'; + break; case 'I': case '?': printf(" %s (Compile errormessage) Ver 1.3\n",progname); @@ -168,8 +190,19 @@ static int count_rows(FILE *from, pchar c, pchar c2) DBUG_ENTER("count_rows"); pos=ftell(from); count=0; + + charset_name[0]= '\0'; while (fgets(rad,MAXLENGTH,from) != NULL) { + if (!strncmp(rad,"character-set=",14)) + { + char *b= rad+14, *e; + for (e=b ; e[0] && e-b < MAX_CHARSET_NAME && + e[0] != ' ' && e[0] != '\r' && + e[0] != '\n' && e[0] != '\t' ; e++); + e[0]= '\0'; + strcpy(charset_name, b); + } if (rad[0] == c || rad[0] == c2) break; count++; diff --git a/include/config-win.h b/include/config-win.h index 7830cc8b9cd..884b2edfb63 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -280,7 +280,6 @@ inline double ulonglong2double(ulonglong value) #define HAVE_CREATESEMAPHORE #define HAVE_ISNAN #define HAVE_FINITE -#define HAVE_ISAM /* We want to have support for ISAM in 4.0 */ #define HAVE_QUERY_CACHE #define SPRINTF_RETURNS_INT #define HAVE_SETFILEPOINTER 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..a15fe3097cc 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 @@ -115,12 +116,17 @@ typedef struct my_collation_handler_st int (*strcasecmp)(struct charset_info_st *, const char *, const char *); + int (*instr)(struct charset_info_st *, + const char *big, uint b_length, + const char *small, uint s_length); + /* 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 +249,10 @@ extern void my_hash_sort_simple(CHARSET_INFO *cs, extern uint my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, uint length); +extern int my_instr_simple(struct charset_info_st *, + const char *big, uint b_length, + const char *small, uint s_length); + /* Functions for 8bit */ extern void my_caseup_str_8bit(CHARSET_INFO *, char *); @@ -307,6 +317,9 @@ 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); +int my_instr_mb(struct charset_info_st *, + const char *big, uint b_length, + const char *small, uint s_length); 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/my_sys.h b/include/my_sys.h index 47a039baddd..6f04b766aec 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -209,8 +209,10 @@ extern CHARSET_INFO *default_charset_info; extern CHARSET_INFO *all_charsets[256]; extern CHARSET_INFO compiled_charsets[]; -extern uint get_charset_number(const char *cs_name); +extern uint get_charset_number(const char *cs_name, uint cs_flags); +extern uint get_collation_number(const char *name); extern const char *get_charset_name(uint cs_number); + extern CHARSET_INFO *get_charset(uint cs_number, myf flags); extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags); extern CHARSET_INFO *get_charset_by_csname(const char *cs_name, diff --git a/include/mysql.h b/include/mysql.h index a4e4e9fcee4..2e9147894ca 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -250,7 +250,6 @@ typedef struct st_mysql LIST *stmts; /* list of all statements */ const struct st_mysql_methods *methods; - struct st_mysql_res *result; void *thd; } MYSQL; @@ -359,6 +358,9 @@ int STDCALL mysql_send_query(MYSQL *mysql, const char *q, unsigned long length); 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, unsigned long length); @@ -427,6 +429,8 @@ MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result, MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result); MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result); +MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table, + const char *wild); unsigned long STDCALL mysql_escape_string(char *to,const char *from, unsigned long from_length); unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, @@ -457,6 +461,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); /* @@ -537,11 +542,6 @@ typedef struct st_mysql_stmt } MYSQL_STMT; -#define mysql_read_query_result(mysql) (*(mysql)->methods->read_query_result)(mysql) -#define mysql_store_result(mysql) (*(mysql)->methods->store_result)(mysql) -#define mysql_use_result(mysql) (*(mysql)->methods->use_result)(mysql) -#define mysql_list_fields(mysql, table, wild) (*(mysql)->methods->list_fields)(mysql, table, wild) - typedef struct st_mysql_methods { my_bool (STDCALL *read_query_result)(MYSQL *mysql); @@ -552,12 +552,19 @@ typedef struct st_mysql_methods const char *arg, unsigned long arg_length, my_bool skip_check); - MYSQL_RES * (STDCALL *store_result)(MYSQL *mysql); + MYSQL_DATA *(STDCALL *read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_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_RES * (STDCALL *list_fields)(MYSQL *mysql, const char *table, - const char *wild); + 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; MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query, diff --git a/include/sql_common.h b/include/sql_common.h index 9fea46be298..1f442339c4f 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -28,14 +28,19 @@ my_ulonglong net_field_length_ll(uchar **packet); MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, my_bool default_value, uint server_capabilities); void free_rows(MYSQL_DATA *cur); -MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields, - uint field_count); my_bool mysql_autenticate(MYSQL *mysql, const char *passwd); void free_old_query(MYSQL *mysql); void end_server(MYSQL *mysql); my_bool mysql_reconnect(MYSQL *mysql); void mysql_read_default_options(struct st_mysql_options *options, const char *filename,const char *group); +my_bool STDCALL +cli_advanced_command(MYSQL *mysql, enum enum_server_command command, + const char *header, ulong header_length, + const char *arg, ulong arg_length, my_bool skip_check); + +void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, + const char *sqlstate); #ifdef __cplusplus } #endif diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h index 9cafd7182d0..d0432503ee9 100644 --- a/libmysql/client_settings.h +++ b/libmysql/client_settings.h @@ -41,5 +41,19 @@ my_bool send_file_to_server(MYSQL *mysql, const char *filename); #define reset_sigpipe(mysql) #endif -MYSQL_RES * STDCALL cli_list_fields(MYSQL *mysql, const char *table, const char *wild); +void mysql_read_default_options(struct st_mysql_options *options, + const char *filename,const char *group); +MYSQL * STDCALL +cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user, + const char *passwd, const char *db, + uint port, const char *unix_socket,ulong client_flag); +void STDCALL cli_mysql_close(MYSQL *mysql); + +MYSQL_FIELD * STDCALL cli_list_fields(MYSQL *mysql); +my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt); +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 68f596c833d..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; @@ -973,6 +973,19 @@ mysql_list_tables(MYSQL *mysql, const char *wild) DBUG_RETURN (mysql_store_result(mysql)); } +MYSQL_FIELD * STDCALL cli_list_fields(MYSQL *mysql) +{ + MYSQL_DATA *query; + if (!(query= cli_read_rows(mysql,(MYSQL_FIELD*) 0, + protocol_41(mysql) ? 8 : 6))) + return NULL; + + mysql->field_count= query->rows; + return unpack_fields(query,&mysql->field_alloc, + query->rows, 1, mysql->server_capabilities); +} + + /************************************************************************** List all fields in a table If wild is given then only the fields matching wild is returned @@ -981,36 +994,29 @@ mysql_list_tables(MYSQL *mysql, const char *wild) **************************************************************************/ MYSQL_RES * STDCALL -cli_list_fields(MYSQL *mysql, const char *table, const char *wild) +mysql_list_fields(MYSQL *mysql, const char *table, const char *wild) { - MYSQL_RES *result; - MYSQL_DATA *query; + MYSQL_RES *result; + MYSQL_FIELD *fields; char buff[257],*end; DBUG_ENTER("mysql_list_fields"); DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : "")); - LINT_INIT(query); - end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128); + free_old_query(mysql); if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1) || - !(query = read_rows(mysql,(MYSQL_FIELD*) 0, - protocol_41(mysql) ? 8 : 6))) + !(fields= (*mysql->methods->list_fields)(mysql))) DBUG_RETURN(NULL); - free_old_query(mysql); if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES), MYF(MY_WME | MY_ZEROFILL)))) - { - free_rows(query); DBUG_RETURN(NULL); - } + result->methods= mysql->methods; result->field_alloc=mysql->field_alloc; mysql->fields=0; - result->field_count = (uint) query->rows; - result->fields= unpack_fields(query,&result->field_alloc, - result->field_count, 1, - mysql->server_capabilities); + result->field_count = mysql->field_count; + result->fields= fields; result->eof=1; DBUG_RETURN(result); } @@ -1031,8 +1037,8 @@ mysql_list_processes(MYSQL *mysql) free_old_query(mysql); pos=(uchar*) mysql->net.read_pos; field_count=(uint) net_field_length(&pos); - if (!(fields = read_rows(mysql,(MYSQL_FIELD*) 0, - protocol_41(mysql) ? 7 : 5))) + if (!(fields = (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*) 0, + protocol_41(mysql) ? 7 : 5))) DBUG_RETURN(NULL); if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0, mysql->server_capabilities))) @@ -1488,8 +1494,8 @@ static void set_stmt_error(MYSQL_STMT * stmt, int errcode, Copy error message to statement handler */ -static void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, - const char *sqlstate) +void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, + const char *sqlstate) { DBUG_ENTER("set_stmt_error_msg"); DBUG_PRINT("enter", ("error: %d/%s '%s'", errcode, sqlstate, err)); @@ -1563,7 +1569,7 @@ static my_bool my_realloc_str(NET *net, ulong length) 1 error */ -static my_bool read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) +my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) { uchar *pos; uint field_count; @@ -1586,25 +1592,16 @@ static my_bool read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) mysql->server_status|= SERVER_STATUS_IN_TRANS; mysql->extra_info= net_field_length_ll(&pos); - if (!(fields_data= read_rows(mysql, (MYSQL_FIELD*) 0, 7))) + if (!(fields_data= (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0,7))) DBUG_RETURN(1); if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root, field_count,0, mysql->server_capabilities))) DBUG_RETURN(1); } - if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root, - sizeof(MYSQL_BIND)* - (param_count + - field_count)))) - { - set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); - DBUG_RETURN(0); - } - stmt->bind= (stmt->params + param_count); stmt->field_count= (uint) field_count; stmt->param_count= (ulong) param_count; - mysql->status= MYSQL_STATUS_READY; + DBUG_RETURN(0); } @@ -1648,14 +1645,25 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length) } init_alloc_root(&stmt->mem_root,8192,0); - if (read_prepare_result(mysql, stmt)) + if ((*mysql->methods->read_prepare_result)(mysql, stmt)) { stmt_close(stmt, 1); DBUG_RETURN(0); } + + if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root, + sizeof(MYSQL_BIND)* + (stmt->param_count + + stmt->field_count)))) + { + set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); + DBUG_RETURN(0); + } + stmt->bind= stmt->params + stmt->param_count; stmt->state= MY_ST_PREPARE; stmt->mysql= mysql; mysql->stmts= list_add(mysql->stmts, &stmt->list); + mysql->status= MYSQL_STATUS_READY; stmt->list.data= stmt; DBUG_PRINT("info", ("Parameter count: %ld", stmt->param_count)); DBUG_RETURN(stmt); @@ -1971,36 +1979,21 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) mysql->last_used_con= mysql; int4store(buff, stmt->stmt_id); /* Send stmt id to server */ - if ((*mysql->methods->advanced_command)(mysql, COM_EXECUTE, buff, - MYSQL_STMT_HEADER, packet, - length, 1) || - mysql_read_query_result(mysql)) + if (cli_advanced_command(mysql, COM_EXECUTE, buff, + MYSQL_STMT_HEADER, packet, + length, 1) || + (*mysql->methods->read_query_result)(mysql)) { set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); DBUG_RETURN(1); } - stmt->state= MY_ST_EXECUTE; - mysql_free_result(stmt->result); - stmt->result= (MYSQL_RES *)0; - stmt->result_buffered= 0; - stmt->current_row= 0; DBUG_RETURN(0); } - -/* - Execute the prepare query -*/ - -int STDCALL mysql_execute(MYSQL_STMT *stmt) +int STDCALL cli_stmt_execute(MYSQL_STMT *stmt) { - DBUG_ENTER("mysql_execute"); + DBUG_ENTER("cli_stmt_execute"); - if (stmt->state == MY_ST_UNKNOWN) - { - set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate); - DBUG_RETURN(1); - } if (stmt->param_count) { NET *net= &stmt->mysql->net; @@ -2061,6 +2054,30 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt) DBUG_RETURN((int) execute(stmt,0,0)); } +/* + Execute the prepare query +*/ + +int STDCALL mysql_execute(MYSQL_STMT *stmt) +{ + DBUG_ENTER("mysql_execute"); + + if (stmt->state == MY_ST_UNKNOWN) + { + set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate); + DBUG_RETURN(1); + } + if ((*stmt->mysql->methods->stmt_execute)(stmt)) + DBUG_RETURN(1); + + stmt->state= MY_ST_EXECUTE; + mysql_free_result(stmt->result); + stmt->result= (MYSQL_RES *)0; + stmt->result_buffered= 0; + stmt->current_row= 0; + DBUG_RETURN(0); +} + /* Return total parameters count in the statement @@ -2948,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 @@ -2977,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)); @@ -3063,7 +3088,7 @@ no_data: Read all rows of data from server (binary format) */ -static MYSQL_DATA *read_binary_rows(MYSQL_STMT *stmt) +MYSQL_DATA *cli_read_binary_rows(MYSQL_STMT *stmt) { ulong pkt_len; uchar *cp; @@ -3159,7 +3184,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) } result->methods= mysql->methods; stmt->result_buffered= 1; - if (!(result->data= read_binary_rows(stmt))) + if (!(result->data= (*stmt->mysql->methods->read_binary_rows)(stmt))) { my_free((gptr) result,MYF(0)); DBUG_RETURN(0); @@ -3463,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 dfc06e38ab2..75461bbfbe0 100644 --- a/libmysqld/embedded_priv.h +++ b/libmysqld/embedded_priv.h @@ -26,4 +26,8 @@ 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; C_MODE_END diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index c894621be54..179bbaeec91 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -50,7 +50,7 @@ static bool check_user(THD *thd, enum_server_command command, char * get_mysql_home(){ return mysql_home;}; char * get_mysql_real_data_home(){ return mysql_real_data_home;}; -my_bool STDCALL +static my_bool STDCALL emb_advanced_command(MYSQL *mysql, enum enum_server_command command, const char *header, ulong header_length, const char *arg, ulong arg_length, my_bool skip_check) @@ -80,6 +80,12 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, client). So we have to call free_old_query here */ free_old_query(mysql); + if (!arg) + { + arg= header; + arg_length= header_length; + } + result= dispatch_command(command, thd, (char *) arg, arg_length + 1); if (!skip_check) @@ -94,6 +100,135 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, return result; } +static MYSQL_DATA * STDCALL +emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)), + unsigned int fields __attribute__((unused))) +{ + MYSQL_DATA *result= ((THD*)mysql->thd)->data; + if (!result) + { + if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), + MYF(MY_WME | MY_ZEROFILL)))) + { + NET *net = &mysql->net; + net->last_errno=CR_OUT_OF_MEMORY; + strmov(net->sqlstate, unknown_sqlstate); + strmov(net->last_error,ER(net->last_errno)); + return NULL; + } + return result; + } + *result->prev_ptr= NULL; + ((THD*)mysql->thd)->data= NULL; + return result; +} + +static MYSQL_FIELD * STDCALL emb_list_fields(MYSQL *mysql) +{ + return mysql->fields; +} + +static my_bool STDCALL emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) +{ + THD *thd= (THD*)mysql->thd; + stmt->stmt_id= thd->client_stmt_id; + stmt->param_count= thd->client_param_count; + stmt->field_count= mysql->field_count; + + if (stmt->field_count != 0) + { + if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT)) + mysql->server_status|= SERVER_STATUS_IN_TRANS; + + stmt->fields= mysql->fields; + stmt->mem_root= mysql->field_alloc; + mysql->fields= NULL; + } + + return 0; +} + +/************************************************************************** + Get column lengths of the current row + If one uses mysql_use_result, res->lengths contains the length information, + else the lengths are calculated from the offset between pointers. +**************************************************************************/ + +static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, unsigned int field_count) +{ + MYSQL_ROW end; + + for (end=column + field_count; column != end ; column++,to++) + *to= *column ? *(uint *)((*column) - sizeof(uint)) : 0; +} + +static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql) +{ + if (mysql->net.last_errno) + return -1; + + if (mysql->field_count) + mysql->status=MYSQL_STATUS_GET_RESULT; + + return 0; +} + +static int STDCALL emb_stmt_execute(MYSQL_STMT *stmt) +{ + DBUG_ENTER("emb_stmt_execute"); + THD *thd= (THD*)stmt->mysql->thd; + thd->client_param_count= stmt->param_count; + thd->client_params= stmt->params; + if (emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0, + (const char*)&stmt->stmt_id,sizeof(stmt->stmt_id),1) + || emb_mysql_read_query_result(stmt->mysql)) + { + NET *net= &stmt->mysql->net; + set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + +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, + emb_advanced_command, + emb_read_rows, + mysql_store_result, + emb_fetch_lengths, + emb_list_fields, + emb_read_prepare_result, + emb_stmt_execute, + emb_read_binary_rows, + emb_unbuffered_fetch +}; + C_MODE_END void THD::clear_error() @@ -334,44 +469,50 @@ void *create_embedded_thd(int client_flag, char *db) thd->master_access= ~NO_ACCESS; thd->net.query_cache_query= 0; + thd->data= 0; + return thd; } +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) { List_iterator_fast<Item> it(*list); Item *item; - MYSQL_FIELD *field, *client_field; + MYSQL_FIELD *client_field; MYSQL *mysql= thd->mysql; + MEM_ROOT *field_alloc; DBUG_ENTER("send_fields"); field_count= list->elements; - if (!(mysql->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+ - sizeof(ulong) * (field_count + 1), - MYF(MY_WME | MY_ZEROFILL)))) + field_alloc= &mysql->field_alloc; + if (!(client_field= thd->mysql->fields= + (MYSQL_FIELD *)alloc_root(field_alloc, + sizeof(MYSQL_FIELD) * field_count))) goto err; - mysql->result->lengths= (ulong *)(mysql->result + 1); - mysql->field_count=field_count; - alloc= &mysql->field_alloc; - field= (MYSQL_FIELD *)alloc_root(alloc, sizeof(MYSQL_FIELD) * field_count); - if (!field) - goto err; - - client_field= field; while ((item= it++)) { Send_field server_field; item->make_field(&server_field); - client_field->db= strdup_root(alloc, server_field.db_name); - client_field->table= strdup_root(alloc, server_field.table_name); - client_field->name= strdup_root(alloc, server_field.col_name); - client_field->org_table= strdup_root(alloc, server_field.org_table_name); - client_field->org_name= strdup_root(alloc, server_field.org_col_name); + client_field->db= strdup_root(field_alloc, server_field.db_name); + client_field->table= strdup_root(field_alloc, server_field.table_name); + client_field->name= strdup_root(field_alloc, server_field.col_name); + client_field->org_table= strdup_root(field_alloc, server_field.org_table_name); + client_field->org_name= strdup_root(field_alloc, server_field.org_col_name); client_field->length= server_field.length; client_field->type= server_field.type; client_field->flags= server_field.flags; @@ -392,31 +533,16 @@ bool Protocol::send_fields(List<Item> *list, uint flag) String tmp(buff, sizeof(buff), default_charset_info), *res; if (!(res=item->val_str(&tmp))) - client_field->def= strdup_root(alloc, ""); + client_field->def= strdup_root(field_alloc, ""); else - client_field->def= strdup_root(alloc, tmp.ptr()); + client_field->def= strdup_root(field_alloc, tmp.ptr()); } else client_field->def=0; client_field->max_length= 0; ++client_field; } - mysql->result->fields = field; - - if (!(mysql->result->data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), - MYF(MY_WME | MY_ZEROFILL)))) - goto err; - - init_alloc_root(&mysql->result->data->alloc,8192,0); /* Assume rowlength < 8192 */ - mysql->result->data->alloc.min_malloc=sizeof(MYSQL_ROWS); - mysql->result->data->rows=0; - mysql->result->data->fields=field_count; - mysql->result->field_count=field_count; - mysql->result->data->prev_ptr= &mysql->result->data->data; - - mysql->result->field_alloc= mysql->field_alloc; - mysql->result->current_field=0; - mysql->result->current_row=0; + thd->mysql->field_count= field_count; DBUG_RETURN(prepare_for_send(list)); err: @@ -435,6 +561,42 @@ bool Protocol::write() return false; } +bool Protocol_prep::write() +{ + MYSQL_ROWS *cur; + MYSQL_DATA *data= thd->data; + + if (!data) + { + if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), + MYF(MY_WME | MY_ZEROFILL)))) + return true; + + alloc= &data->alloc; + init_alloc_root(alloc,8192,0); /* Assume rowlength < 8192 */ + alloc->min_malloc=sizeof(MYSQL_ROWS); + data->rows=0; + data->fields=field_count; + data->prev_ptr= &data->data; + thd->data= data; + } + + data->rows++; + if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+packet->length()))) + { + my_error(ER_OUT_OF_RESOURCES,MYF(0)); + return true; + } + cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS)); + memcpy(cur->data, packet->ptr()+1, packet->length()-1); + + *data->prev_ptr= cur; + data->prev_ptr= &cur->next; + cur->next= 0; + + return false; +} + void send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message) { @@ -456,13 +618,27 @@ send_eof(THD *thd, bool no_flush) void Protocol_simple::prepare_for_resend() { - MYSQL_ROWS *cur; - MYSQL_DATA *result= thd->mysql->result->data; + MYSQL_ROWS *cur; + MYSQL_DATA *data= thd->data; DBUG_ENTER("send_data"); - alloc= &result->alloc; - result->rows++; + if (!data) + { + if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), + MYF(MY_WME | MY_ZEROFILL)))) + goto err; + + alloc= &data->alloc; + init_alloc_root(alloc,8192,0); /* Assume rowlength < 8192 */ + alloc->min_malloc=sizeof(MYSQL_ROWS); + data->rows=0; + data->fields=field_count; + data->prev_ptr= &data->data; + thd->data= data; + } + + data->rows++; if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *)))) { my_error(ER_OUT_OF_RESOURCES,MYF(0)); @@ -470,11 +646,11 @@ void Protocol_simple::prepare_for_resend() } cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS)); - *result->prev_ptr= cur; - result->prev_ptr= &cur->next; + *data->prev_ptr= cur; + data->prev_ptr= &cur->next; next_field=cur->data; - next_mysql_field= thd->mysql->result->fields; - + next_mysql_field= thd->mysql->fields; +err: DBUG_VOID_RETURN; } @@ -518,3 +694,85 @@ bool Protocol::convert_str(const char *from, uint length) return false; } #endif + +bool setup_params_data(st_prep_stmt *stmt) +{ + THD *thd= stmt->thd; + List<Item> ¶ms= thd->lex.param_list; + List_iterator<Item> param_iterator(params); + Item_param *param; + ulong param_no= 0; + MYSQL_BIND *client_param= thd->client_params; + + DBUG_ENTER("setup_params_data"); + + for (;(param= (Item_param *)param_iterator++); client_param++) + { + setup_param_functions(param, client_param->buffer_type); + if (!param->long_data_supplied) + { + if (*client_param->is_null) + param->maybe_null= param->null_value= 1; + else + { + uchar *buff= (uchar*)client_param->buffer; + param->maybe_null= param->null_value= 0; + param->setup_param_func(param,&buff); + } + } + param_no++; + } + DBUG_RETURN(0); +} + +bool setup_params_data_withlog(st_prep_stmt *stmt) +{ + THD *thd= stmt->thd; + List<Item> ¶ms= thd->lex.param_list; + List_iterator<Item> param_iterator(params); + Item_param *param; + MYSQL_BIND *client_param= thd->client_params; + + DBUG_ENTER("setup_params_data"); + + String str, *res, *query= new String(stmt->query->alloced_length()); + query->copy(*stmt->query); + + ulong param_no= 0; + uint32 length= 0; + + for (;(param= (Item_param *)param_iterator++); client_param++) + { + setup_param_functions(param, client_param->buffer_type); + if (param->long_data_supplied) + res= param->query_val_str(&str); + + else + { + if (*client_param->is_null) + { + param->maybe_null= param->null_value= 1; + res= &null_string; + } + else + { + uchar *buff= (uchar*)client_param->buffer; + param->maybe_null= param->null_value= 0; + param->setup_param_func(param,&buff); + res= param->query_val_str(&str); + } + } + if (query->replace(param->pos_in_query+length, 1, *res)) + DBUG_RETURN(1); + + length+= res->length()-1; + param_no++; + } + + if (alloc_query(stmt->thd, (char *)query->ptr(), query->length()+1)) + DBUG_RETURN(1); + + query->free(); + DBUG_RETURN(0); +} + diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 56be78e3509..ddde18c1918 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -24,6 +24,7 @@ #include <sys/stat.h> #include <signal.h> #include <time.h> +#include "client_settings.h" #ifdef HAVE_PWD_H #include <pwd.h> #endif @@ -46,8 +47,6 @@ #define INADDR_NONE -1 #endif -#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | CLIENT_PROTOCOL_41) - #if defined(MSDOS) || defined(__WIN__) #define ERRNO WSAGetLastError() #define perror(A) @@ -58,29 +57,11 @@ #define closesocket(A) close(A) #endif -void free_old_query(MYSQL *mysql); -my_bool STDCALL -emb_advanced_command(MYSQL *mysql, enum enum_server_command command, - const char *header, ulong header_length, - const char *arg, ulong arg_length, my_bool skip_check); - -/* From client.c */ -void mysql_read_default_options(struct st_mysql_options *options, - const char *filename,const char *group); -MYSQL * STDCALL -cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user, - const char *passwd, const char *db, - uint port, const char *unix_socket,ulong client_flag); - -void STDCALL cli_mysql_close(MYSQL *mysql); - #ifdef HAVE_GETPWUID struct passwd *getpwuid(uid_t); char* getlogin(void); #endif -extern char server_inited; - #ifdef __WIN__ static my_bool is_NT(void) { @@ -165,73 +146,6 @@ static inline int mysql_init_charset(MYSQL *mysql) return 0; } -/************************************************************************** - Get column lengths of the current row - If one uses mysql_use_result, res->lengths contains the length information, - else the lengths are calculated from the offset between pointers. -**************************************************************************/ - -static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count) -{ - MYSQL_ROW end; - - for (end=column + field_count; column != end ; column++,to++) - *to= *column ? *(uint *)((*column) - sizeof(uint)) : 0; -} - -/************************************************************************** - List all fields in a table - If wild is given then only the fields matching wild is returned - Instead of this use query: - show fields in 'table' like "wild" -**************************************************************************/ - -static MYSQL_RES * STDCALL -emb_list_fields(MYSQL *mysql, const char *table, const char *wild) -{ - MYSQL_RES *result; - MYSQL_DATA *query; - char buff[257],*end; - DBUG_ENTER("mysql_list_fields"); - DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : "")); - - LINT_INIT(query); - - end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128); - if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1)) - DBUG_RETURN(NULL); - - result= mysql->result; - if (!result) - return 0; - - result->methods= mysql->methods; - result->eof=1; - - DBUG_RETURN(result); -} - - - -/* -** Note that the mysql argument must be initialized with mysql_init() -** before calling mysql_real_connect ! -*/ - -static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql); -static MYSQL_RES * STDCALL emb_mysql_store_result(MYSQL *mysql); -static MYSQL_RES * STDCALL emb_mysql_use_result(MYSQL *mysql); - -static MYSQL_METHODS embedded_methods= -{ - emb_mysql_read_query_result, - emb_advanced_command, - emb_mysql_store_result, - emb_mysql_use_result, - emb_fetch_lengths, - emb_list_fields -}; - MYSQL * STDCALL mysql_real_connect(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, @@ -307,7 +221,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); } @@ -375,62 +289,10 @@ void STDCALL mysql_close(MYSQL *mysql) #endif /* HAVE_OPENSSL */ if (mysql->free_me) my_free((gptr) mysql,MYF(0)); - } - DBUG_VOID_RETURN; -} - -static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql) -{ - if (mysql->net.last_errno) - return -1; + + free_embedded_thd(mysql); - if (mysql->field_count) - { - mysql->status=MYSQL_STATUS_GET_RESULT; - mysql->affected_rows= mysql->result->row_count= mysql->result->data->rows; - mysql->result->data_cursor= mysql->result->data->data; } - - return 0; -} - -/************************************************************************** -** Alloc result struct for buffered results. All rows are read to buffer. -** mysql_data_seek may be used. -**************************************************************************/ -static MYSQL_RES * STDCALL emb_mysql_store_result(MYSQL *mysql) -{ - MYSQL_RES *result= mysql->result; - if (!result) - return 0; - - result->methods= mysql->methods; - mysql->result= NULL; - *result->data->prev_ptr= 0; - result->eof= 1; - result->lengths= (ulong*)(result + 1); - mysql->affected_rows= result->row_count= result->data->rows; - result->data_cursor= result->data->data; - - mysql->status=MYSQL_STATUS_READY; /* server is ready */ - return result; + DBUG_VOID_RETURN; } -/************************************************************************** -** Alloc struct for use with unbuffered reads. Data is fetched by domand -** when calling to mysql_fetch_row. -** mysql_data_seek is a noop. -** -** No other queries may be specified with the same MYSQL handle. -** There shouldn't be much processing per row because mysql server shouldn't -** have to wait for the client (and will not wait more than 30 sec/packet). -**************************************************************************/ - -static MYSQL_RES * STDCALL emb_mysql_use_result(MYSQL *mysql) -{ - DBUG_ENTER("mysql_use_result"); - if (mysql->options.separate_thread) - DBUG_RETURN(0); - - DBUG_RETURN(emb_mysql_store_result(mysql)); -} diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index 564b5f8ea8f..5a53c1db2e1 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -70,3 +70,11 @@ SHOW TABLES IN òåñò; Tables_in_òåñò SET CHARACTER SET koi8r; DROP DATABASE ÔÅÓÔ; +SET NAMES koi8r; +SELECT hex('ÔÅÓÔ'); +hex('ÔÅÓÔ') +D4C5D3D4 +SET character_set_connection=cp1251; +SELECT hex('ÔÅÓÔ'); +hex('ÔÅÓÔ') +F2E5F1F2 diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index ee71ffff2f0..2a0b17df043 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -13,6 +13,133 @@ hex(word) 0420 2004 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/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_recoding.test b/mysql-test/t/ctype_recoding.test index bbb0d963a9d..325a8f075ed 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -45,3 +45,8 @@ SHOW TABLES; SHOW TABLES IN òåñò; SET CHARACTER SET koi8r; DROP DATABASE ÔÅÓÔ; + +SET NAMES koi8r; +SELECT hex('ÔÅÓÔ'); +SET character_set_connection=cp1251; +SELECT hex('ÔÅÓÔ'); diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index ee30baed008..80ae70c0fe2 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -29,6 +29,51 @@ INSERT INTO t1 VALUES (X'042000200020'), (X'200400200020'); SELECT hex(word) FROM t1 ORDER BY word; 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 +98,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/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 7a82f8780a0..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)); @@ -278,12 +277,10 @@ static my_bool simple_cs_is_full(CHARSET_INFO *cs) static int add_collation(CHARSET_INFO *cs) { - if (cs->name && (cs->number || (cs->number=get_charset_number(cs->name)))) + if (cs->name && (cs->number || (cs->number=get_collation_number(cs->name)))) { 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; } @@ -513,7 +527,7 @@ void free_charsets(void) } -uint get_charset_number(const char *charset_name) +uint get_collation_number(const char *name) { CHARSET_INFO **cs; if (init_available_charsets(MYF(0))) /* If it isn't initialized */ @@ -522,12 +536,27 @@ uint get_charset_number(const char *charset_name) for (cs= all_charsets; cs < all_charsets+255; ++cs) { if ( cs[0] && cs[0]->name && - !my_strcasecmp(&my_charset_latin1, cs[0]->name, charset_name)) + !my_strcasecmp(&my_charset_latin1, cs[0]->name, name)) return cs[0]->number; } return 0; /* this mimics find_type() */ } +uint get_charset_number(const char *charset_name, uint cs_flags) +{ + CHARSET_INFO **cs; + if (init_available_charsets(MYF(0))) /* If it isn't initialized */ + return 0; + + for (cs= all_charsets; cs < all_charsets+255; ++cs) + { + if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) && + !my_strcasecmp(&my_charset_latin1, cs[0]->csname, charset_name)) + return cs[0]->number; + } + return 0; +} + const char *get_charset_name(uint charset_number) { @@ -555,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); @@ -593,7 +622,7 @@ CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags) CHARSET_INFO *cs; (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ - cs_number=get_charset_number(cs_name); + cs_number=get_collation_number(cs_name); cs= cs_number ? get_internal_charset(cs_number,flags) : NULL; if (!cs && (flags & MY_WME)) @@ -611,23 +640,15 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name, uint cs_flags, myf flags) { - CHARSET_INFO *cs=NULL; - CHARSET_INFO **css; + uint cs_number; + CHARSET_INFO *cs; DBUG_ENTER("get_charset_by_csname"); DBUG_PRINT("enter",("name: '%s'", cs_name)); (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ - for (css= all_charsets; css < all_charsets+255; ++css) - { - if ( css[0] && (css[0]->state & cs_flags) && - css[0]->csname && !my_strcasecmp(&my_charset_latin1, - css[0]->csname, cs_name)) - { - cs= css[0]->number ? get_internal_charset(css[0]->number,flags) : NULL; - break; - } - } + cs_number= get_charset_number(cs_name, cs_flags); + cs= cs_number ? get_internal_charset(cs_number, flags) : NULL; if (!cs && (flags & MY_WME)) { 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/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/sql-common/client.c b/sql-common/client.c index 6372adb8550..cd3763da725 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -636,10 +636,10 @@ void free_rows(MYSQL_DATA *cur) } } -static my_bool STDCALL +my_bool STDCALL cli_advanced_command(MYSQL *mysql, enum enum_server_command command, - const char *header, ulong header_length, - const char *arg, ulong arg_length, my_bool skip_check) + const char *header, ulong header_length, + const char *arg, ulong arg_length, my_bool skip_check) { NET *net= &mysql->net; my_bool result= 1; @@ -1008,7 +1008,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; @@ -1139,8 +1139,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, /* Read all rows (fields or data) from server */ -MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, - uint fields) +MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, + unsigned int fields) { uint field; ulong pkt_len; @@ -1150,7 +1150,7 @@ MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, MYSQL_DATA *result; MYSQL_ROWS **prev_ptr,*cur; NET *net = &mysql->net; - DBUG_ENTER("read_rows"); + DBUG_ENTER("cli_read_rows"); if ((pkt_len= net_safe_read(mysql)) == packet_error) DBUG_RETURN(0); @@ -1397,17 +1397,22 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused))) */ static my_bool STDCALL cli_mysql_read_query_result(MYSQL *mysql); -static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql); static MYSQL_RES * STDCALL cli_mysql_use_result(MYSQL *mysql); static MYSQL_METHODS client_methods= { cli_mysql_read_query_result, cli_advanced_command, - cli_mysql_store_result, + 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_unbuffered_fetch +#endif }; MYSQL * STDCALL @@ -1996,7 +2001,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); } @@ -2215,7 +2220,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 @@ -2264,7 +2269,8 @@ get_info: mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */ - if (!(fields=read_rows(mysql,(MYSQL_FIELD*)0,protocol_41(mysql) ? 7 : 5))) + if (!(fields=(*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0, + protocol_41(mysql) ? 7 : 5))) DBUG_RETURN(1); if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc, (uint) field_count,0, @@ -2317,7 +2323,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)); } @@ -2326,7 +2332,7 @@ mysql_real_query(MYSQL *mysql, const char *query, ulong length) mysql_data_seek may be used. **************************************************************************/ -static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql) +MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql) { MYSQL_RES *result; DBUG_ENTER("mysql_store_result"); @@ -2355,7 +2361,8 @@ static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql) result->methods= mysql->methods; result->eof=1; /* Marker for buffered */ result->lengths=(ulong*) (result+1); - if (!(result->data=read_rows(mysql,mysql->fields,mysql->field_count))) + if (!(result->data= + (*mysql->methods->read_rows)(mysql,mysql->fields,mysql->field_count))) { my_free((gptr) result,MYF(0)); DBUG_RETURN(0); @@ -2385,7 +2392,7 @@ static MYSQL_RES * STDCALL cli_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 e31a75bdddd..b357e52ec9d 100644 --- a/sql/client_settings.h +++ b/sql/client_settings.h @@ -32,5 +32,3 @@ #undef HAVE_SMEM #undef _CUSTOMCONFIG_ -#define cli_list_fields NULL - diff --git a/sql/derror.cc b/sql/derror.cc index 7ebe6e4b3c5..78efdcc33f3 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -49,6 +49,7 @@ static void read_texts(const char *file_name,const char ***point, char name[FN_REFLEN]; const char *buff; uchar head[32],*pos; + CHARSET_INFO *cset; DBUG_ENTER("read_texts"); *point=0; // If something goes wrong @@ -65,6 +66,21 @@ static void read_texts(const char *file_name,const char ***point, head[2] != 2 || head[3] != 1) 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)))) + { + 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); if (count < error_messages) @@ -114,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..125f87aecec 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,26 @@ longlong Item_func_locate::val_int() } null_value=0; uint start=0; -#ifdef USE_MB uint start0=0; -#endif + int ind; + 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; - } - return 0; - } -#endif /* USE_MB */ - return (longlong) (binary_cmp ? a->strstr(*b,start) : - (a->strstr_case(*b,start)))+1; + + ind= cmp_collation.collation->coll->instr(cmp_collation.collation, + a->ptr()+start, a->length()-start, + b->ptr(), b->length()); + + return (longlong) (ind >= 0 ? ind + start0 + 1 : ind + 1); } @@ -1742,7 +1712,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 +2073,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 c4ad7f1e1e2..98e8ee3914e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -34,7 +34,7 @@ #include "sha1.h" #include "my_aes.h" -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 +359,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 +520,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 +661,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 +914,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 +958,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 +991,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 +1051,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 +1335,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 +1357,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 +1383,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 +1473,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)) @@ -1536,7 +1536,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 +1718,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 +1742,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 +1752,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 +1853,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(); @@ -2050,7 +2050,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 +2240,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; } @@ -2539,6 +2539,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; @@ -2589,6 +2594,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..ea5e60b558f 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -526,7 +526,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/mysql_priv.h b/sql/mysql_priv.h index d4bacb57a38..1d7dd3aa5bb 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -577,6 +577,7 @@ void mysql_stmt_reset(THD *thd, char *packet); void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length); int check_insert_fields(THD *thd,TABLE *table,List<Item> &fields, List<Item> &values, ulong counter); +void setup_param_functions(Item_param *param, uchar param_type); /* sql_error.cc */ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, @@ -794,7 +795,7 @@ 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 SHOW_VAR init_vars[],status_vars[], internal_vars[]; extern struct show_table_type_st table_type_vars[]; extern SHOW_COMP_OPTION have_isam; @@ -803,6 +804,7 @@ 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; /* optional things, have_* variables */ diff --git a/sql/net_serv.cc b/sql/net_serv.cc index d39fca595ac..eac197e530b 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -460,7 +460,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 +889,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/protocol.cc b/sql/protocol.cc index d1eb3460fc8..79420fb71d5 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -28,6 +28,9 @@ #ifndef EMBEDDED_LIBRARY bool Protocol::net_store_data(const char *from, uint length) +#else +bool Protocol_prep::net_store_data(const char *from, uint length) +#endif { ulong packet_length=packet->length(); /* @@ -43,7 +46,6 @@ bool Protocol::net_store_data(const char *from, uint length) packet->length((uint) (to+length-packet->ptr())); return 0; } -#endif /* Send a error string to client */ @@ -1130,3 +1132,12 @@ bool Protocol_prep::store_time(TIME *tm) buff[0]=(char) length; // Length is stored first return packet->append(buff, length+1, PACKET_BUFFET_EXTRA_ALLOC); } + +#ifdef EMBEDDED_LIBRARY +/* Should be removed when we define the Protocol_cursor's future */ +bool Protocol_cursor::write() +{ + return Protocol_simple::write(); +} +#endif + diff --git a/sql/protocol.h b/sql/protocol.h index f32c135ab3c..94fd303e259 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -53,7 +53,11 @@ public: bool store(const char *from, CHARSET_INFO *cs); String *storage_packet() { return packet; } inline void free() { packet->free(); } +#ifndef EMBEDDED_LIBRARY bool write(); +#else + virtual bool write(); +#endif inline bool store(uint32 from) { return store_long((longlong) from); } inline bool store(longlong from) @@ -121,6 +125,10 @@ public: Protocol_prep(THD *thd) :Protocol(thd) {} virtual bool prepare_for_send(List<Item> *item_list); virtual void prepare_for_resend(); +#ifdef EMBEDDED_LIBRARY + virtual bool write(); + bool net_store_data(const char *from, uint length); +#endif virtual bool store_null(); virtual bool store_tiny(longlong from); virtual bool store_short(longlong from); @@ -170,3 +178,9 @@ char *net_store_length(char *packet,uint length); char *net_store_data(char *to,const char *from, uint length); char *net_store_data(char *to,int32 from); char *net_store_data(char *to,longlong from); + +#ifdef EMBEDDED_LIBRARY +bool setup_params_data(struct st_prep_stmt *stmt); +bool setup_params_data_withlog(struct st_prep_stmt *stmt); +#endif + 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 5e040d26dc3..b931ce0ba8c 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -177,7 +177,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; @@ -540,7 +540,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 199a398b497..147033be660 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)))) { @@ -1343,6 +1343,7 @@ bool sys_var_character_set::check(THD *thd, set_var *var) bool sys_var_character_set::update(THD *thd, set_var *var) { ci_ptr(thd,var->type)[0]= var->save_result.charset; + thd->update_charset(); return 0; } @@ -1924,7 +1925,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/share/Makefile.am b/sql/share/Makefile.am index 35202ff4722..662159a9c63 100644 --- a/sql/share/Makefile.am +++ b/sql/share/Makefile.am @@ -30,7 +30,7 @@ install-data-local: fix_errors: for lang in @AVAILABLE_LANGUAGES@; \ do \ - ../../extra/comp_err $(srcdir)/$$lang/errmsg.txt $(srcdir)/$$lang/errmsg.sys; \ + ../../extra/comp_err -C$(srcdir)/charsets/ $(srcdir)/$$lang/errmsg.txt $(srcdir)/$$lang/errmsg.sys; \ done # Don't update the files from bitkeeper diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index e920a2139db..de7f1b43d26 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -10,6 +10,8 @@ Thu Nov 30 14:02:52 MET 2000 podle 3.23.28 */ +character-set=latin2 + "hashchk", "isamchk", "NE", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index beea26d5f51..68a383df01e 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -4,6 +4,8 @@ /* Knud Riishøjgård knudriis@post.tele.dk 99 && Carsten H. Pedersen, carsten.pedersen@bitbybit.dk oct. 1999 / aug. 2001. */ +character-set=latin1 + "hashchk", "isamchk", "NEJ", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 6eca86deba2..1ccfd0d3cd6 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -12,6 +12,8 @@ Translated new error messages. */ +character-set=latin1 + "hashchk", "isamchk", "NEE", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 8b9ed103cbb..a8ed1f95ff7 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -1,6 +1,8 @@ /* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind */ +character-set=latin1 + "hashchk", "isamchk", "NO", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index b4c17303ef0..5fcd5c830e8 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -6,6 +6,8 @@ */ +character-set=latin7 + "hashchk", "isamchk", "EI", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 9f321a908b6..cf8f38ec774 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -1,6 +1,8 @@ /* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind */ +character-set=latin1 + "hashchk", "isamchk", "NON", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index b5b47091035..20edc56f4c8 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -10,6 +10,8 @@ 2002-12-11 */ +character-set=latin1 + "hashchk", "isamchk", "Nein", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index cf6f45eea84..39429a9b0a3 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -1,6 +1,8 @@ /* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind */ +character-set=greek + "hashchk", "isamchk", "Ï×É", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 43dcfcd16d3..511f1e21743 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -3,6 +3,8 @@ Updated May, 2000 This file is public domain and comes with NO WARRANTY of any kind */ +character-set=latin2 + "hashchk", "isamchk", "NEM", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 125dca5310e..04011bc252e 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -1,6 +1,8 @@ /* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind */ +character-set=latin1 + "hashchk", "isamchk", "NO", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 1b73380df1c..944932e0d94 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -3,6 +3,8 @@ 3.22.10-beta euc-japanese (ujis) text */ +character-set=ujis + "hashchk", "isamchk", "NO", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index a32a8f1033e..642d78887ed 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -1,6 +1,8 @@ /* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB This ÈÀÏ is public domain and comes with NO WARRANTY of any kind */ +character-set=euckr + "hashchk", "isamchk", "¾Æ´Ï¿À", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 83da00a5955..94992e2ef04 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -3,6 +3,8 @@ /* Roy-Magne Mo rmo@www.hivolda.no 97 */ +character-set=latin1 + "hashchk", "isamchk", "NEI", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 81cfad7e494..7da21c399eb 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -3,6 +3,8 @@ /* Roy-Magne Mo rmo@www.hivolda.no 97 */ +character-set=latin1 + "hashchk", "isamchk", "NEI", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 69b9c898ae7..adcdb536780 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -5,6 +5,8 @@ Charset ISO-8859-2 */ +character-set=latin2 + "hashchk", "isamchk", "NIE", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 2862e8036dc..af4e210a5b7 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -1,6 +1,9 @@ /* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind */ /* Updated by Thiago Delgado Pinto - thiagodp@ieg.com.br - 06.07.2002 */ + +character-set=latin1 + "hashchk", "isamchk", "NÃO", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 0591a082490..5b6fb9e4911 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -5,6 +5,8 @@ e-mail: tzoompy@cs.washington.edu */ +character-set=latin2 + "hashchk", "isamchk", "NU", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index fe276396d92..ea9b8265b77 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -3,6 +3,8 @@ This file is public domain and comes with NO WARRANTY of any kind */ /* charset: KOI8-R */ +character-set=koi8r + "hashchk", "isamchk", "îåô", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 5869fa62c04..bb18a14c946 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -7,6 +7,8 @@ Charset: cp1250 */ +character-set=cp1250 + "hashchk", "isamchk", "NE", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 9cf4d874339..09f0517fd15 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -9,6 +9,8 @@ Date: Streda 11. November 1998 20:58:15 */ +character-set=latin2 + "hashchk", "isamchk", "NIE", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 72f4249b4c9..7a4dea69e0b 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -2,6 +2,9 @@ This file is public domain and comes with NO WARRANTY of any kind Traduccion por Miguel Angel Fernandez Roiz -- LoboCom Sistemas, s.l. From June 28, 2001 translated by Miguel Solorzano miguel@mysql.com */ + +character-set=latin1 + "hashchk", "isamchk", "NO", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index cf7859712ee..d1c14bf7e4e 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -1,6 +1,8 @@ /* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind */ +character-set=latin1 + "hashchk", "isamchk", "NO", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 2e7a01d9573..8bd060781bb 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -6,6 +6,8 @@ * Version: 13/09/2001 mysql-3.23.41 */ +character-set=koi8u + "hashchk", "isamchk", "î¶", 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 7889a583fde..508ff88a0cf 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1069,7 +1069,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; @@ -1782,7 +1782,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)); } @@ -1944,7 +1944,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(); @@ -2295,7 +2295,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 */ @@ -2538,7 +2538,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 fa4f08b5f14..1e44aa6e46d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -873,7 +873,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 f7742c6b7a7..fb86f52ab6e 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")); @@ -2044,7 +2044,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 d954d4dc22d..88e338d953b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -583,7 +583,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_class.h b/sql/sql_class.h index e0358fc25e9..da6aab8d266 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -341,7 +341,11 @@ typedef struct st_prep_stmt char last_error[MYSQL_ERRMSG_SIZE]; bool error_in_prepare, long_data_used; bool log_full_query; +#ifndef EMBEDDED_LIBRARY bool (*setup_params)(st_prep_stmt *stmt, uchar *pos, uchar *read_pos); +#else + bool (*setup_params_data)(st_prep_stmt *stmt); +#endif } PREP_STMT; @@ -422,6 +426,10 @@ class THD :public ilink public: #ifdef EMBEDDED_LIBRARY struct st_mysql *mysql; + struct st_mysql_data *data; + unsigned long client_stmt_id; + unsigned long client_param_count; + struct st_mysql_bind *client_params; #endif NET net; // client connection descriptor LEX lex; // parse tree descriptor diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 370ccd3c38b..de76fef85a9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -161,7 +161,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 @@ -1723,6 +1723,10 @@ mysql_execute_command(THD *thd) break; // Error message is given } + /* + 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 4abbbcaff1f..0ea3132eabc 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -77,7 +77,7 @@ Long data handling: #define STMT_QUERY_LOG_LENGTH 8192 extern int yyparse(void *thd); -static String null_string("NULL", 4, default_charset_info); +String null_string("NULL", 4, default_charset_info); /* Find prepared statement in thd @@ -142,6 +142,7 @@ void free_prep_stmt(PREP_STMT *stmt, TREE_FREE mode, void *not_used) Send prepared stmt info to client after prepare */ +#ifndef EMBEDDED_LIBRARY static bool send_prep_stmt(PREP_STMT *stmt, uint columns) { NET *net=&stmt->thd->net; @@ -150,14 +151,21 @@ static bool send_prep_stmt(PREP_STMT *stmt, uint columns) int4store(buff+1, stmt->stmt_id); int2store(buff+5, columns); int2store(buff+7, stmt->param_count); -#ifndef EMBEDDED_LIBRARY /* This should be fixed to work with prepared statements */ return (my_net_write(net, buff, sizeof(buff)) || net_flush(net)); +} #else - return true; -#endif +static bool send_prep_stmt(PREP_STMT *stmt, uint columns __attribute__((unused))) +{ + THD *thd= stmt->thd; + + thd->client_stmt_id= stmt->stmt_id; + thd->client_param_count= stmt->param_count; + + return 0; } +#endif /*!EMBEDDED_LIBRAYR*/ /* Send information about all item parameters @@ -345,7 +353,7 @@ static void setup_param_str(Item_param *param, uchar **pos) *pos+= len; } -static void setup_param_functions(Item_param *param, uchar param_type) +void setup_param_functions(Item_param *param, uchar param_type) { switch (param_type) { case FIELD_TYPE_TINY: @@ -391,6 +399,7 @@ static void setup_param_functions(Item_param *param, uchar param_type) } } +#ifndef EMBEDDED_LIBRARY /* Update the parameter markers by reading data from client packet and if binary/update log is set, generate the valid query. @@ -476,11 +485,7 @@ static bool setup_params_data(PREP_STMT *stmt) Item_param *param; DBUG_ENTER("setup_params_data"); -#ifndef EMBEDDED_LIBRARY uchar *pos=(uchar*) thd->net.read_pos+1+MYSQL_STMT_HEADER; //skip header -#else - uchar *pos= 0; //just to compile TODO code for embedded case -#endif uchar *read_pos= pos+(stmt->param_count+7) / 8; //skip null bits if (*read_pos++) //types supplied / first execute @@ -500,6 +505,8 @@ static bool setup_params_data(PREP_STMT *stmt) DBUG_RETURN(0); } +#endif /*!EMBEDDED_LIBRARY*/ + /* Validate the following information for INSERT statement: - field existance @@ -659,13 +666,13 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, wild_num, conds, og_num, order, group, having, proc, select_lex, unit, 0)) DBUG_RETURN(1); -#ifndef EMBEDDED_LIBRARY 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); -#endif join->cleanup(); } DBUG_RETURN(0); @@ -784,10 +791,18 @@ static bool init_param_items(PREP_STMT *stmt) if (mysql_bin_log.is_open() || mysql_update_log.is_open()) { stmt->log_full_query= 1; +#ifndef EMBEDDED_LIBRARY stmt->setup_params= insert_params_withlog; +#else + stmt->setup_params_data= setup_params_data_withlog; +#endif } else +#ifndef EMBEDDED_LIBRARY stmt->setup_params= insert_params; // not fully qualified query +#else + stmt->setup_params_data= setup_params_data; +#endif if (!stmt->param_count) stmt->param= (Item_param **)0; @@ -941,8 +956,13 @@ void mysql_stmt_execute(THD *thd, char *packet) } init_stmt_execute(stmt); +#ifndef EMBEDDED_LIBRARY if (stmt->param_count && setup_params_data(stmt)) DBUG_VOID_RETURN; +#else + if (stmt->param_count && (*stmt->setup_params_data)(stmt)) + DBUG_VOID_RETURN; +#endif if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); 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 8ea78e702e5..8ed4d6d7324 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1497,11 +1497,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])) @@ -1545,8 +1549,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_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/table.cc b/sql/table.cc index a980e086d60..5e7991436a1 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -459,7 +459,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..75070203239 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -262,8 +262,46 @@ static int my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)), return len; } +static +int my_instr_bin(CHARSET_INFO *cs __attribute__((unused)), + const char *big, uint b_length, + const char *small, uint s_length) +{ + register const uchar *str, *search, *end, *search_end; + + if (s_length <= b_length) + { + if (!s_length) + return 0; /* 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; + + return (int) (str- (const uchar*)big) -1; + } + } + } + return -1; +} + -MY_COLLATION_HANDLER my_collation_bin_handler = +MY_COLLATION_HANDLER my_collation_8bit_bin_handler = { my_strnncoll_binary, my_strnncollsp_binary, @@ -271,6 +309,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 +356,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..03323b3d3a1 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,224 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), return b-b0; } +int my_instr_mb(CHARSET_INFO *cs, + const char *big, uint b_length, + const char *small, uint s_length) +{ + register const char *end; + int res= 0; + + if (s_length <= b_length) + { + if (!s_length) + return 0; // Empty string is always found + + 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)) + return res; + + mblen= (mblen= my_ismbchar(cs, big, end)) ? mblen : 1; + big+= mblen; + b_length-= mblen; + res++; + } + } + return -1; +} + +/* 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..152980dd305 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1030,6 +1030,44 @@ uint my_lengthsp_8bit(CHARSET_INFO *cs __attribute__((unused)), } +int my_instr_simple(CHARSET_INFO *cs, + const char *big, uint b_length, + const char *small, uint s_length) +{ + register const uchar *str, *search, *end, *search_end; + + if (s_length <= b_length) + { + if (!s_length) + return 0; // 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; + + return (int) (str- (const uchar*)big) -1; + } + } + } + return -1; +} + + MY_CHARSET_HANDLER my_charset_8bit_handler= { NULL, /* ismbchar */ @@ -1063,5 +1101,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)); |