summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BitKeeper/etc/logging_ok1
-rwxr-xr-xBuild-tools/Do-compile32
-rwxr-xr-xBuild-tools/mysql-copyright27
-rw-r--r--client/mysqltest.c10
-rw-r--r--configure.in4
-rw-r--r--extra/comp_err.c37
-rw-r--r--include/config-win.h1
-rw-r--r--include/hash.h2
-rw-r--r--include/m_ctype.h15
-rw-r--r--include/my_pthread.h1
-rw-r--r--include/my_sys.h4
-rw-r--r--include/mysql.h27
-rw-r--r--include/sql_common.h9
-rw-r--r--libmysql/client_settings.h16
-rw-r--r--libmysql/dll.c2
-rw-r--r--libmysql/libmysql.c162
-rw-r--r--libmysqld/embedded_priv.h4
-rw-r--r--libmysqld/lib_sql.cc346
-rw-r--r--libmysqld/libmysqld.c148
-rw-r--r--mysql-test/r/ctype_recoding.result8
-rw-r--r--mysql-test/r/ctype_ucs.result127
-rw-r--r--mysql-test/r/ctype_ujis.result58
-rw-r--r--mysql-test/r/ctype_utf8.result61
-rw-r--r--mysql-test/r/func_compress.result6
-rw-r--r--mysql-test/r/have_ujis.require2
-rw-r--r--mysql-test/r/mysqldump.result20
-rw-r--r--mysql-test/r/openssl_1.result8
-rw-r--r--mysql-test/r/subselect.result5
-rw-r--r--mysql-test/r/union.result4
-rw-r--r--mysql-test/t/ctype_recoding.test5
-rw-r--r--mysql-test/t/ctype_ucs.test46
-rw-r--r--mysql-test/t/ctype_ujis.test26
-rw-r--r--mysql-test/t/ctype_utf8.test35
-rw-r--r--mysql-test/t/func_compress.test6
-rw-r--r--mysql-test/t/mysqldump.test10
-rw-r--r--mysql-test/t/subselect.test1
-rw-r--r--mysys/charset.c123
-rw-r--r--mysys/hash.c2
-rw-r--r--mysys/my_getopt.c2
-rw-r--r--mysys/testhash.c4
-rw-r--r--sql-common/client.c43
-rw-r--r--sql/client_settings.h2
-rw-r--r--sql/derror.cc19
-rw-r--r--sql/filesort.cc1
-rw-r--r--sql/gen_lex_hash.cc15
-rw-r--r--sql/ha_berkeley.cc2
-rw-r--r--sql/ha_innodb.cc2
-rw-r--r--sql/hash_filo.h2
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_cmpfunc.cc2
-rw-r--r--sql/item_func.cc58
-rw-r--r--sql/item_strfunc.cc50
-rw-r--r--sql/lock.cc2
-rw-r--r--sql/mysql_priv.h4
-rw-r--r--sql/net_serv.cc4
-rw-r--r--sql/protocol.cc13
-rw-r--r--sql/protocol.h14
-rw-r--r--sql/records.cc1
-rw-r--r--sql/repl_failsafe.cc4
-rw-r--r--sql/set_var.cc5
-rw-r--r--sql/share/Makefile.am2
-rw-r--r--sql/share/czech/errmsg.txt2
-rw-r--r--sql/share/danish/errmsg.txt2
-rw-r--r--sql/share/dutch/errmsg.txt2
-rw-r--r--sql/share/english/errmsg.txt2
-rw-r--r--sql/share/estonian/errmsg.txt2
-rw-r--r--sql/share/french/errmsg.txt2
-rw-r--r--sql/share/german/errmsg.txt2
-rw-r--r--sql/share/greek/errmsg.txt2
-rw-r--r--sql/share/hungarian/errmsg.txt2
-rw-r--r--sql/share/italian/errmsg.txt2
-rw-r--r--sql/share/japanese/errmsg.txt2
-rw-r--r--sql/share/korean/errmsg.txt2
-rw-r--r--sql/share/norwegian-ny/errmsg.txt2
-rw-r--r--sql/share/norwegian/errmsg.txt2
-rw-r--r--sql/share/polish/errmsg.txt2
-rw-r--r--sql/share/portuguese/errmsg.txt3
-rw-r--r--sql/share/romanian/errmsg.txt2
-rw-r--r--sql/share/russian/errmsg.txt2
-rw-r--r--sql/share/serbian/errmsg.txt2
-rw-r--r--sql/share/slovak/errmsg.txt2
-rw-r--r--sql/share/spanish/errmsg.txt3
-rw-r--r--sql/share/swedish/errmsg.txt2
-rw-r--r--sql/share/ukrainian/errmsg.txt2
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sql_acl.cc10
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_cache.cc4
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h8
-rw-r--r--sql/sql_parse.cc6
-rw-r--r--sql/sql_prepare.cc42
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_show.cc14
-rw-r--r--sql/sql_udf.cc2
-rw-r--r--sql/sql_union.cc32
-rw-r--r--sql/table.cc2
-rw-r--r--strings/ctype-big5.c3
-rw-r--r--strings/ctype-bin.c43
-rw-r--r--strings/ctype-czech.c1
-rw-r--r--strings/ctype-euc_kr.c7
-rw-r--r--strings/ctype-gb2312.c9
-rw-r--r--strings/ctype-gbk.c3
-rw-r--r--strings/ctype-latin1.c3
-rw-r--r--strings/ctype-mb.c223
-rw-r--r--strings/ctype-simple.c39
-rw-r--r--strings/ctype-sjis.c3
-rw-r--r--strings/ctype-tis620.c3
-rw-r--r--strings/ctype-ucs2.c264
-rw-r--r--strings/ctype-ujis.c3
-rw-r--r--strings/ctype-utf8.c3
-rw-r--r--strings/ctype-win1250ch.c1
-rw-r--r--strings/xml.c2
-rw-r--r--tests/client_test.c2
-rw-r--r--tools/mysqlmanager.c4
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(&currentTime);
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> &params= 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> &params= 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));