From 72ed6bc3974c3c7f112aa9704d073b4bbb86ec35 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 May 2002 18:58:50 +0300 Subject: [PATCH 1/5] A final and proper fix for HP-UX problems with pthread_cond_timedwait. This time I did it "by the book" as this function can return any of the down cited values after timeout !! This is now done 100 % according to HP-UX DCE documentation. This made Hewlett-Packard very happy. --- mysys/my_pthread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index 72409b6aa86..dc974719d70 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -420,7 +420,7 @@ int my_pthread_cond_timedwait(pthread_cond_t *cond, struct timespec *abstime) { int error=pthread_cond_timedwait(cond,mutex,abstime); - return error == EAGAIN ? ETIMEDOUT : error; + return (error == EAGAIN || error == -1) ? ETIMEDOUT : error; } #endif /* HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT */ From c2504d86b317d9d18fa3de29a4cef325e8de9dfa Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 May 2002 10:50:57 +0300 Subject: [PATCH 2/5] Fix bug in CONCAT_WS() Update of glibc patch from MySQL 4.0 Docs/glibc-2.2.5.patch: Update of patch from MySQL 4.0 Docs/manual.texi: ChangeLog sql/item_strfunc.cc: Fix bug in CONCAT_WS() sql/share/italian/errmsg.txt: Update of new error messages --- Docs/glibc-2.2.5.patch | 209 +++++++++++++++++++++----------- Docs/manual.texi | 2 + mysql-test/r/func_concat.result | 13 ++ mysql-test/t/func_concat.test | 24 ++++ sql/item_strfunc.cc | 2 +- sql/share/italian/errmsg.txt | 20 +-- 6 files changed, 186 insertions(+), 84 deletions(-) create mode 100644 mysql-test/r/func_concat.result create mode 100644 mysql-test/t/func_concat.test diff --git a/Docs/glibc-2.2.5.patch b/Docs/glibc-2.2.5.patch index c6bc2bf39a8..fc12486d7d0 100644 --- a/Docs/glibc-2.2.5.patch +++ b/Docs/glibc-2.2.5.patch @@ -1,73 +1,136 @@ -diff -Nur --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet ../glibc-2.2.5/linuxthreads/internals.h ./linuxthreads/internals.h ---- ../glibc-2.2.5/linuxthreads/internals.h Thu Nov 29 00:44:16 2001 -+++ ./linuxthreads/internals.h Fri Feb 22 21:18:09 2002 -@@ -343,7 +343,7 @@ - THREAD_SELF implementation is used, this must be a power of two and - a multiple of PAGE_SIZE. */ - #ifndef STACK_SIZE --#define STACK_SIZE (2 * 1024 * 1024) -+#define STACK_SIZE (128 * 1024) - #endif - - /* The initial size of the thread stack. Must be a multiple of PAGE_SIZE. */ -diff -Nur --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet ../glibc-2.2.5/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h ./linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h ---- ../glibc-2.2.5/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h Thu Jun 8 13:49:49 2000 -+++ ./linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h Fri Feb 22 21:18:09 2002 -@@ -64,7 +64,7 @@ - /* The number of threads per process. */ - #define _POSIX_THREAD_THREADS_MAX 64 - /* This is the value this implementation supports. */ --#define PTHREAD_THREADS_MAX 1024 -+#define PTHREAD_THREADS_MAX 4096 - - /* Maximum amount by which a process can descrease its asynchronous I/O - priority level. */ -diff -Nur --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet ../glibc-2.2.5/nss/nsswitch.c ./nss/nsswitch.c ---- ../glibc-2.2.5/nss/nsswitch.c Tue Jul 17 02:21:36 2001 -+++ ./nss/nsswitch.c Fri Feb 22 21:18:09 2002 -@@ -515,8 +515,16 @@ - + (line - name + 1)); - if (new_service == NULL) - return result; -- -+#ifdef DO_STATIC_NSS -+ if (strncmp(name,"files",5) == 0 || -+ strncmp(name,"dns",3) == 0) -+#endif - *((char *) __mempcpy (new_service->name, name, line - name)) = '\0'; -+#ifdef DO_STATIC_NSS -+ else -+ *((char *) __mempcpy (new_service->name, "files", 5)) = '\0'; -+#endif -+ - - /* Set default actions. */ - new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE; -diff -Nur --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet ../glibc-2.2.5/time/Makefile ./time/Makefile ---- ../glibc-2.2.5/time/Makefile Fri Feb 22 21:27:19 2002 -+++ ./time/Makefile Fri Feb 22 21:26:47 2002 -@@ -37,8 +37,8 @@ - - include ../Rules - --tz-cflags = -DTZDIR='"$(zonedir)"' \ -- -DTZDEFAULT='"$(localtime-file)"' \ -+tz-cflags = -DTZDIR='"/usr/share/zoneinfo/"' \ -+ -DTZDEFAULT='"/etc/localtime"' \ - -DTZDEFRULES='"$(posixrules-file)"' - - CFLAGS-tzfile.c = $(tz-cflags) -diff -Nur --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet ../glibc-2.2.5/timezone/Makefile ./timezone/Makefile ---- ../glibc-2.2.5/timezone/Makefile Wed Aug 29 16:45:25 2001 -+++ ./timezone/Makefile Fri Feb 22 21:18:09 2002 -@@ -159,8 +159,8 @@ - - $(objpfx)zic: $(objpfx)scheck.o $(objpfx)ialloc.o - --tz-cflags = -DTZDIR='"$(zonedir)"' \ -- -DTZDEFAULT='"$(localtime-file)"' \ -+tz-cflags = -DTZDIR='"/usr/share/zoneinfo/"' \ -+ -DTZDEFAULT='"/etc/localtime"' \ - -DTZDEFRULES='"$(posixrules-file)"' \ - -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone - +diff -r -c --exclude=*.info* glibc-2.2.4/linuxthreads/internals.h glibc-2.2.4-new/linuxthreads/internals.h +*** glibc-2.2.4/linuxthreads/internals.h Mon Jul 23 20:54:13 2001 +--- glibc-2.2.4-new/linuxthreads/internals.h Tue Apr 16 15:08:03 2002 +*************** +*** 339,345 **** + THREAD_SELF implementation is used, this must be a power of two and + a multiple of PAGE_SIZE. */ + #ifndef STACK_SIZE +! #define STACK_SIZE (2 * 1024 * 1024) + #endif + + /* The initial size of the thread stack. Must be a multiple of PAGE_SIZE. */ +--- 339,345 ---- + THREAD_SELF implementation is used, this must be a power of two and + a multiple of PAGE_SIZE. */ + #ifndef STACK_SIZE +! #define STACK_SIZE (128 * 1024) + #endif + + /* The initial size of the thread stack. Must be a multiple of PAGE_SIZE. */ +diff -r -c --exclude=*.info* glibc-2.2.4/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h glibc-2.2.4-new/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h +*** glibc-2.2.4/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h Fri Jun 9 22:17:35 2000 +--- glibc-2.2.4-new/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h Tue Apr 16 15:10:38 2002 +*************** +*** 64,70 **** + /* The number of threads per process. */ + #define _POSIX_THREAD_THREADS_MAX 64 + /* This is the value this implementation supports. */ +! #define PTHREAD_THREADS_MAX 1024 + + /* Maximum amount by which a process can descrease its asynchronous I/O + priority level. */ +--- 64,70 ---- + /* The number of threads per process. */ + #define _POSIX_THREAD_THREADS_MAX 64 + /* This is the value this implementation supports. */ +! #define PTHREAD_THREADS_MAX 4096 + + /* Maximum amount by which a process can descrease its asynchronous I/O + priority level. */ +diff -r -c --exclude=*.info* glibc-2.2.4/nss/nsswitch.c glibc-2.2.4-new/nss/nsswitch.c +*** glibc-2.2.4/nss/nsswitch.c Mon Jul 23 20:54:48 2001 +--- glibc-2.2.4-new/nss/nsswitch.c Fri May 3 04:17:44 2002 +*************** +*** 496,501 **** +--- 496,502 ---- + { + service_user *new_service; + const char *name; ++ int name_alloc_len; + + while (isspace (line[0])) + ++line; +*************** +*** 510,522 **** + if (name == line) + return result; + + + new_service = (service_user *) malloc (sizeof (service_user) +! + (line - name + 1)); + if (new_service == NULL) + return result; + +! *((char *) __mempcpy (new_service->name, name, line - name)) = '\0'; + + /* Set default actions. */ + new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE; +--- 511,533 ---- + if (name == line) + return result; + ++ name_alloc_len = line - name + 1; ++ ++ #ifdef DO_STATIC_NSS ++ if (!((name_alloc_len == 6 && strncmp(name,"files",5) == 0) || ++ (name_alloc_len == 4 && strncmp(name,"dns",3) == 0))) ++ { ++ name = (char*) "files"; ++ name_alloc_len=6; ++ } ++ #endif + + new_service = (service_user *) malloc (sizeof (service_user) +! + name_alloc_len); + if (new_service == NULL) + return result; + +! *((char *) __mempcpy (new_service->name, name, name_alloc_len)) = '\0'; + + /* Set default actions. */ + new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE; +diff -r -c --exclude=*.info* glibc-2.2.4/time/Makefile glibc-2.2.4-new/time/Makefile +*** glibc-2.2.4/time/Makefile Fri Aug 10 22:12:07 2001 +--- glibc-2.2.4-new/time/Makefile Tue Apr 16 15:11:09 2002 +*************** +*** 37,44 **** + + include ../Rules + +! tz-cflags = -DTZDIR='"$(zonedir)"' \ +! -DTZDEFAULT='"$(localtime-file)"' \ + -DTZDEFRULES='"$(posixrules-file)"' + + CFLAGS-tzfile.c = $(tz-cflags) +--- 37,44 ---- + + include ../Rules + +! tz-cflags = -DTZDIR='"/usr/share/zoneinfo/"' \ +! -DTZDEFAULT='"/etc/localtime"' \ + -DTZDEFRULES='"$(posixrules-file)"' + + CFLAGS-tzfile.c = $(tz-cflags) +diff -r -c --exclude=*.info* glibc-2.2.4/timezone/Makefile glibc-2.2.4-new/timezone/Makefile +*** glibc-2.2.4/timezone/Makefile Mon Jul 23 20:58:05 2001 +--- glibc-2.2.4-new/timezone/Makefile Tue Apr 16 15:11:09 2002 +*************** +*** 159,166 **** + + $(objpfx)zic: $(objpfx)scheck.o $(objpfx)ialloc.o + +! tz-cflags = -DTZDIR='"$(zonedir)"' \ +! -DTZDEFAULT='"$(localtime-file)"' \ + -DTZDEFRULES='"$(posixrules-file)"' \ + -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone + +--- 159,166 ---- + + $(objpfx)zic: $(objpfx)scheck.o $(objpfx)ialloc.o + +! tz-cflags = -DTZDIR='"/usr/share/zoneinfo/"' \ +! -DTZDEFAULT='"/etc/localtime"' \ + -DTZDEFRULES='"$(posixrules-file)"' \ + -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone + diff --git a/Docs/manual.texi b/Docs/manual.texi index c202c2c07a7..ce5c6c301ea 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46916,6 +46916,8 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.51 @itemize @bullet @item +Fixed bug in @code{CONCAT_WS()} that cut the result. +@item Changed name of variables @code{Com_show_master_stat} to @code{Com_show_master_status} and @code{Com_show_slave_stat} to @code{Com_show_slave_status}. diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result new file mode 100644 index 00000000000..75ee8f2bf79 --- /dev/null +++ b/mysql-test/r/func_concat.result @@ -0,0 +1,13 @@ +number alpha new +1413006 idlfmv 1413006<---->idlfmv +1413065 smpsfz 1413065<---->smpsfz +1413127 sljrhx 1413127<---->sljrhx +1413304 qerfnd 1413304<---->qerfnd +new +1413006<---->idlfmv +number alpha new +1413006 idlfmv 1413006<->idlfmv +number alpha new +1413006 idlfmv 1413006-idlfmv-idlfmv-idlfmv-idlfmv-idlfmv-idlfmv-idlfmv +number alpha new +1413006 idlfmv 1413006<------------------>idlfmv diff --git a/mysql-test/t/func_concat.test b/mysql-test/t/func_concat.test new file mode 100644 index 00000000000..d6da1d6a603 --- /dev/null +++ b/mysql-test/t/func_concat.test @@ -0,0 +1,24 @@ +# +# Test of problem with CONCAT_WS() and long separators. +# + +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL ); +INSERT INTO t1 VALUES (1413006,'idlfmv'), +(1413065,'smpsfz'),(1413127,'sljrhx'),(1413304,'qerfnd'); + +SELECT number, alpha, CONCAT_WS('<---->',number,alpha) AS new +FROM t1 GROUP BY number; + +SELECT CONCAT_WS('<---->',number,alpha) AS new +FROM t1 GROUP BY new LIMIT 1; + +SELECT number, alpha, CONCAT_WS('<->',number,alpha) AS new +FROM t1 GROUP BY new LIMIT 1; + +SELECT number, alpha, CONCAT_WS('-',number,alpha,alpha,alpha,alpha,alpha,alpha,alpha) AS new +FROM t1 GROUP BY new LIMIT 1; + +SELECT number, alpha, CONCAT_WS('<------------------>',number,alpha) AS new +FROM t1 GROUP BY new LIMIT 1; +drop table t1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 0321d37c0fe..54fc427edf0 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -313,7 +313,7 @@ null: void Item_func_concat_ws::fix_length_and_dec() { - max_length=0; + max_length=separator->max_length*(arg_count-1); for (uint i=0 ; i < arg_count ; i++) max_length+=args[i]->max_length; if (max_length > MAX_BLOB_WIDTH) diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 3da78e82d99..4b434573390 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -209,13 +209,13 @@ "E' scaduto il timeout per l'attesa del lock", "Il numero totale di lock e' maggiore della grandezza della tabella di lock", "I lock di aggiornamento non possono essere acquisiti durante una transazione 'READ UNCOMMITTED'", -"DROP DATABASE not allowed while thread is holding global read lock", -"CREATE DATABASE not allowed while thread is holding global read lock", -"Wrong arguments to %s", -"%-.32s@%-.64s is not allowed to create new users", -"Incorrect table definition; All MERGE tables must be in the same database", -"Deadlock found when trying to get lock; Try restarting transaction", -"The used table type doesn't support FULLTEXT indexes", -"Cannot add foreign key constraint", -"Cannot add a child row: a foreign key constraint fails", -"Cannot delete a parent row: a foreign key constraint fails", +"DROP DATABASE non e' permesso mentre il thread ha un lock globale di lettura", +"CREATE DATABASE non e' permesso mentre il thread ha un lock globale di lettura", +"Argomenti errati a %s", +"A %-.32s@%-.64s non e' permesso creare nuovi utenti", +"Definizione della tabella errata; tutte le tabelle di tipo MERGE devono essere nello stesso database", +"Trovato deadlock durante il lock; Provare a far ripartire la transazione", +"La tabella usata non supporta gli indici FULLTEXT", +"Impossibile aggiungere il vincolo di integrita' referenziale (foreign key constraint)", +"Impossibile aggiungere la riga: un vincolo d'integrita' referenziale non e' soddisfatto", +"Impossibile cancellare la riga: un vincolo d'integrita' referenziale non e' soddisfatto", From ce6ea95cfec6ad06005ab29441ccf5bff2a6e111 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 May 2002 12:01:04 +0200 Subject: [PATCH 3/5] Added os2 source directory to source distribution (thanks to Yuri Dario for pointing this out) Makefile.am: Added OS/2 subdirectory to source distribution configure.in: Added OS/2 subdirectory to source distribution --- Makefile.am | 2 +- configure.in | 2 +- os2/Makefile.am | 29 +++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 os2/Makefile.am diff --git a/Makefile.am b/Makefile.am index ac65dcda820..35db77c684e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,7 +24,7 @@ EXTRA_DIST = INSTALL-SOURCE README \ SUBDIRS = include @docs_dirs@ @readline_dir@ \ @thread_dirs@ @sql_client_dirs@ \ @sql_server_dirs@ scripts tests man \ - @bench_dirs@ support-files + @bench_dirs@ support-files os2 # Relink after clean CLEANFILES = linked_client_sources linked_server_sources linked_libmysql_sources linked_libmysql_r_sources linked_include_sources diff --git a/configure.in b/configure.in index a7102261410..183de44fdf2 100644 --- a/configure.in +++ b/configure.in @@ -2264,7 +2264,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile \ strings/Makefile regex/Makefile heap/Makefile \ bdb/Makefile \ myisam/Makefile myisammrg/Makefile \ - man/Makefile \ + man/Makefile os2/Makefile \ readline/Makefile libmysql_r/Makefile libmysql/Makefile client/Makefile \ sql/Makefile sql/share/Makefile \ merge/Makefile dbug/Makefile scripts/Makefile \ diff --git a/os2/Makefile.am b/os2/Makefile.am new file mode 100644 index 00000000000..7e626e45cf8 --- /dev/null +++ b/os2/Makefile.am @@ -0,0 +1,29 @@ +# Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to create Makefile.in + +EXTRA_DIST = BldLevel.cmd BldLevel.rc BldLevelInf.cmd ChangeLog.os2 \ + MySQL-All.icc MySQL-Client.icc MySQL-Client.irs \ + MySQL-Lib.icc MySQL-Opt.icc MySQL-ReadLine.icc \ + MySQL-Source.icc MySQL-Sql.icc MySQL-Util.icc MySQL-Util.irs \ + MySQL-binlog.icc MySQL-binlog.irs MySQL-sql.irs ReadMe.txt \ + build-all.cmd build-all.log mysql-inf.wis mysql.base \ + mysql.ih mysql.wis mysqlalt.wis readme.os2 rint.cmd rint.obj \ + rint.s + +# Don't update the files from bitkeeper +%::SCCS/s.% From 387e77d104887d45a4574a9bd1b826cfa20f01c1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 May 2002 16:45:00 +0300 Subject: [PATCH 4/5] Optimize LIKE with turbo-boyer-more algoritm Docs/manual.texi: Added info about LIKE optimization mysql-test/r/func_like.result: Test of new LIKE optimization mysql-test/t/func_like.test: Test of new LIKE optimization --- Docs/manual.texi | 8 + mysql-test/r/func_like.result | 11 ++ mysql-test/t/func_like.test | 8 + sql/item_cmpfunc.cc | 266 +++++++++++++++++++++++++++++++++- sql/item_cmpfunc.h | 27 +++- sql/unireg.h | 7 + 6 files changed, 321 insertions(+), 6 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 1d67f3f7ed1..bbe18b9f402 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -26728,6 +26728,12 @@ In the first statement, the @code{LIKE} value begins with a wildcard character. In the second statement, the @code{LIKE} value is not a constant. +MySQL 4.0 does another optimization on @code{LIKE}. If you are using +@code{... LIKE "%string%"} and @code{string} is longer than 3 characters +then MySQL will use the turbo-boyer-more algorithm to once initialize +the pattern for the string and then use this pattern to quickly search +after the given string. + @findex IS NULL, and indexes @cindex indexes, and @code{IS NULL} Searching using @code{column_name IS NULL} will use indexes if column_name @@ -49310,6 +49316,8 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @itemize @bullet @item +Use turbo-boyer-more to speed up @code{LIKE "%keyword%"} searches. +@item Fixed bug in @code{DROP DATABASE} with symlink. @item Fixed crash in @code{REPAIR ... USE_FRM}. diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result index 796674b5fa4..c2085ba12da 100644 --- a/mysql-test/r/func_like.result +++ b/mysql-test/r/func_like.result @@ -15,4 +15,15 @@ test select * from t1 where a like "te_t"; a test +select * from t1 where a like "%a%"; +a +a +abc +abcd +select * from t1 where a like "%abcd%"; +a +abcd +select * from t1 where a like "%abc\d%"; +a +abcd drop table t1; diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test index e0f1f0db9ce..6c0313d0437 100644 --- a/mysql-test/t/func_like.test +++ b/mysql-test/t/func_like.test @@ -9,4 +9,12 @@ select * from t1 where a like "abc%"; select * from t1 where a like "ABC%"; select * from t1 where a like "test%"; select * from t1 where a like "te_t"; + +# +# The following will test the boyer-more code +# +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; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 09c2bdc593a..c21ad18f08e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1228,23 +1228,23 @@ void Item_func_like::fix_length_and_dec() // cmp_type=STRING_RESULT; // For quick select } - longlong Item_func_like::val_int() { - String *res,*res2; - res=args[0]->val_str(&tmp_value1); + String* res = args[0]->val_str(&tmp_value1); if (args[0]->null_value) { null_value=1; return 0; } - res2=args[1]->val_str(&tmp_value2); + String* res2 = args[1]->val_str(&tmp_value2); if (args[1]->null_value) { null_value=1; return 0; } null_value=0; + if (canDoTurboBM) + return turboBM_matches(res->ptr(), res->length()) ? 1 : 0; if (binary) return wild_compare(*res,*res2,escape) ? 0 : 1; else @@ -1268,6 +1268,51 @@ Item_func::optimize_type Item_func_like::select_optimize() const return OPTIMIZE_NONE; } +bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist) +{ + if (Item_bool_func2::fix_fields(thd, tlist)) + return 1; + + /* + TODO--we could do it for non-const, but we'd have to + recompute the tables for each row--probably not worth it. + */ + if (args[1]->const_item() && !(specialflag & SPECIAL_NO_NEW_FUNC)) + { + String* res2 = args[1]->val_str(&tmp_value2); + const size_t len = res2->length(); + const char* first = res2->ptr(); + const char* last = first + len - 1; + /* + len must be > 2 ('%pattern%') + heuristic: only do TurboBM for pattern_len > 2 + */ + + if (len > MIN_TURBOBM_PATTERN_LEN + 2 && + *first == wild_many && + *last == wild_many) + { + const char* tmp = first + 1; + for ( ; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ; + canDoTurboBM = tmp == last; + } + + if (canDoTurboBM) + { + pattern = first + 1; + pattern_len = len - 2; + DBUG_PRINT("TurboBM", ("Initializing pattern: '%s'...", first)); + int* suff = (int*)thd->alloc(sizeof(int[pattern_len + 1])); + bmGs = (int*)thd->alloc(sizeof(int[pattern_len + 1])); + bmBc = (int*)thd->alloc(sizeof(int[alphabet_size])); + turboBM_compute_good_suffix_shifts(suff); + turboBM_compute_bad_character_shifts(); + DBUG_PRINT("turboBM",("done")); + } + } + return 0; +} + #ifdef USE_REGEX bool @@ -1307,7 +1352,6 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) return 0; } - longlong Item_func_regex::val_int() { char buff[MAX_FIELD_WIDTH]; @@ -1364,3 +1408,215 @@ Item_func_regex::~Item_func_regex() } #endif /* USE_REGEX */ + + +#ifdef LIKE_CMP_TOUPPER +#define likeconv(A) (uchar) toupper(A) +#else +#define likeconv(A) (uchar) my_sort_order[(uchar) (A)] +#endif + + +/********************************************************************** + turboBM_compute_suffixes() + Precomputation dependent only on pattern_len. +**********************************************************************/ + +void Item_func_like::turboBM_compute_suffixes(int* suff) +{ + const int plm1 = pattern_len - 1; + int f = 0; + int g = plm1; + int* const splm1 = suff + plm1; + + *splm1 = pattern_len; + + if (binary) + { + int i; + for (i = pattern_len - 2; i >= 0; i--) + { + int tmp = *(splm1 + i - f); + if (g < i && tmp < i - g) + suff[i] = tmp; + else + { + if (i < g) + g = i; // g = min(i, g) + f = i; + while (g >= 0 && pattern[g] == pattern[g + plm1 - f]) + g--; + suff[i] = f - g; + } + } + } + else + { + int i; + for (i = pattern_len - 2; 0 <= i; --i) + { + int tmp = *(splm1 + i - f); + if (g < i && tmp < i - g) + suff[i] = tmp; + else + { + if (i < g) + g = i; // g = min(i, g) + f = i; + while (g >= 0 && likeconv(pattern[g]) == likeconv(pattern[g + plm1 - f])) + g--; + suff[i] = f - g; + } + } + } +} + + +/********************************************************************** + turboBM_compute_good_suffix_shifts() + Precomputation dependent only on pattern_len. +**********************************************************************/ + +void Item_func_like::turboBM_compute_good_suffix_shifts(int* suff) +{ + turboBM_compute_suffixes(suff); + + int* end = bmGs + pattern_len; + int* k; + for (k = bmGs; k < end; k++) + *k = pattern_len; + + int tmp; + int i; + int j = 0; + const int plm1 = pattern_len - 1; + for (i = plm1; i > -1; i--) + { + if (suff[i] == i + 1) + { + for (tmp = plm1 - i; j < tmp; j++) + { + int* tmp2 = bmGs + j; + if (*tmp2 == pattern_len) + *tmp2 = tmp; + } + } + } + + int* tmp2; + for (tmp = plm1 - i; j < tmp; j++) + { + tmp2 = bmGs + j; + if (*tmp2 == pattern_len) + *tmp2 = tmp; + } + + tmp2 = bmGs + plm1; + for (i = 0; i <= pattern_len - 2; i++) + *(tmp2 - suff[i]) = plm1 - i; +} + + +/********************************************************************** + turboBM_compute_bad_character_shifts() + Precomputation dependent on pattern_len. +**********************************************************************/ + +void Item_func_like::turboBM_compute_bad_character_shifts() +{ + int* i; + int* end = bmBc + alphabet_size; + for (i = bmBc; i < end; i++) + *i = pattern_len; + + int j; + const int plm1 = pattern_len - 1; + if (binary) + for (j = 0; j < plm1; j++) + bmBc[pattern[j]] = plm1 - j; + else + for (j = 0; j < plm1; j++) + bmBc[likeconv(pattern[j])] = plm1 - j; +} + + +/********************************************************************** + turboBM_matches() + Search for pattern in text, returns true/false for match/no match +**********************************************************************/ + +bool Item_func_like::turboBM_matches(const char* text, int text_len) const +{ + register int bcShift; + register int turboShift; + int shift = pattern_len; + int j = 0; + int u = 0; + + const int plm1 = pattern_len - 1; + const int tlmpl = text_len - pattern_len; + + /* Searching */ + if (binary) + { + while (j <= tlmpl) + { + register int i = plm1; + while (i >= 0 && pattern[i] == text[i + j]) + { + i--; + if (i == plm1 - shift) + i -= u; + } + if (i < 0) + return true; + + register const int v = plm1 - i; + turboShift = u - v; + bcShift = bmBc[text[i + j]] - plm1 + i; + shift = max(turboShift, bcShift); + shift = max(shift, bmGs[i]); + if (shift == bmGs[i]) + u = min(pattern_len - shift, v); + else + { + if (turboShift < bcShift) + shift = max(shift, u + 1); + u = 0; + } + j += shift; + } + return false; + } + else + { + while (j <= tlmpl) + { + register int i = plm1; + while (i >= 0 && likeconv(pattern[i]) == likeconv(text[i + j])) + { + i--; + if (i == plm1 - shift) + i -= u; + } + if (i < 0) + return true; + + register const int v = plm1 - i; + turboShift = u - v; + bcShift = bmBc[likeconv(text[i + j])] - plm1 + i; + shift = max(turboShift, bcShift); + shift = max(shift, bmGs[i]); + if (shift == bmGs[i]) + u = min(pattern_len - shift, v); + else + { + if (turboShift < bcShift) + shift = max(shift, u + 1); + u = 0; + } + j += shift; + } + return false; + } +} diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 2048c4baea8..cd6e3d6e414 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -478,15 +478,40 @@ public: class Item_func_like :public Item_bool_func2 { char escape; + + // Turbo Boyer-Moore data + bool canDoTurboBM; // pattern is '%abcd%' case + const char* pattern; + int pattern_len; + + // TurboBM buffers, *this is owner + int* bmGs; // good suffix shift table, size is pattern_len + 1 + int* bmBc; // bad character shift table, size is alphabet_size + + void turboBM_compute_suffixes(int* suff); + void turboBM_compute_good_suffix_shifts(int* suff); + void turboBM_compute_bad_character_shifts(); + bool turboBM_matches(const char* text, int text_len) const; + enum { alphabet_size = 256 }; + public: - Item_func_like(Item *a,Item *b, char* escape_arg) :Item_bool_func2(a,b),escape(*escape_arg) + Item_func_like::Item_func_like(Item *a,Item *b, char* escape_arg) : + Item_bool_func2(a,b), + escape(*escape_arg), + canDoTurboBM(false), + pattern(0), + pattern_len(0), + bmGs(0), + bmBc(0) {} + longlong val_int(); enum Functype functype() const { return LIKE_FUNC; } optimize_type select_optimize() const; cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "like"; } void fix_length_and_dec(); + bool fix_fields(THD *thd,struct st_table_list *tlist); }; #ifdef USE_REGEX diff --git a/sql/unireg.h b/sql/unireg.h index c4d2052d1da..5a61f4a6c12 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -122,6 +122,13 @@ bfill((A)->null_flags,(A)->null_bytes,255);\ #define TE_INFO_LENGTH 3 #define MTYP_NOEMPTY_BIT 128 +/* + * Minimum length pattern before Turbo Boyer-Moore is used + * for SELECT "text" LIKE "%pattern%", excluding the two + * wildcards in class Item_func_like. + */ +#define MIN_TURBOBM_PATTERN_LEN 3 + /* Include prototypes for unireg */ #include "mysqld_error.h" From 3f8a7a587326132c6790ef28c31d243ed625f9e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 May 2002 12:11:15 +0300 Subject: [PATCH 5/5] Updated assembler code from MySQL 4.0 (to make them work with gcc 3.0) Fixed memory overrun bug in glibc patch Updated french error messages Docs/glibc-2.2.5.patch: Fixed memory overrun bug in glibc patch sql/share/french/errmsg.txt: Updated french error messages (patch from Loic Le Loarer) strings/longlong2str-x86.s: Updated from MySQL 4.0 (to make them work with gcc 3.0) strings/strings-x86.s: Updated from MySQL 4.0 (to make them work with gcc 3.0) --- Docs/glibc-2.2.5.patch | 4 +- sql/share/french/errmsg.txt | 192 +++++++++---------- strings/longlong2str-x86.s | 29 ++- strings/strings-x86.s | 365 ++++++++++++++++++------------------ 4 files changed, 294 insertions(+), 296 deletions(-) diff --git a/Docs/glibc-2.2.5.patch b/Docs/glibc-2.2.5.patch index fc12486d7d0..801984c84f7 100644 --- a/Docs/glibc-2.2.5.patch +++ b/Docs/glibc-2.2.5.patch @@ -52,7 +52,7 @@ diff -r -c --exclude=*.info* glibc-2.2.4/nss/nsswitch.c glibc-2.2.4-new/nss/nssw while (isspace (line[0])) ++line; *************** -*** 510,522 **** +522 if (name == line) return result; @@ -86,7 +86,7 @@ diff -r -c --exclude=*.info* glibc-2.2.4/nss/nsswitch.c glibc-2.2.4-new/nss/nssw if (new_service == NULL) return result; -! *((char *) __mempcpy (new_service->name, name, name_alloc_len)) = '\0'; +! *((char *) __mempcpy (new_service->name, name, name_alloc_len-1)) = '\0'; /* Set default actions. */ new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE; diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 4848a3266bc..07b88e1356e 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -122,100 +122,100 @@ "Ligne trop grande. Le taille maximale d'une ligne, sauf les BLOBs, est %d. Changez le type de quelques colonnes en BLOB", "Débordement de la pile des tâches (Thread stack). Utilisées: %ld pour une pile de %ld. Essayez 'mysqld -O thread_stack=#' pour indiquer une plus grande valeur", "Dépendance croisée dans une clause OUTER JOIN. Vérifiez la condition ON", -"Column '%-.32s' is used with UNIQUE or INDEX but is not defined as NOT NULL", -"Can't load function '%-.64s'", -"Can't initialize function '%-.64s'; %-.80s", -"No paths allowed for shared library", -"Function '%-.64s' already exist", -"Can't open shared library '%-.64s' (errno: %d %s)", -"Can't find function '%-.64s' in library'", -"Function '%-.64s' is not defined", -"Host '%-.64s' is blocked because of many connection errors. Unblock with 'mysqladmin flush-hosts'", -"Host '%-.64s' is not allowed to connect to this MySQL server", -"You are using MySQL as an anonymous users and anonymous users are not allowed to change passwords", -"You must have privileges to update tables in the mysql database to be able to change passwords for others", -"Can't find any matching row in the user table", -"Rows matched: %ld Changed: %ld Warnings: %ld", -"Can't create a new thread (errno %d). If you are not out of available memory you can consult the manual for any possible OS dependent bug", +"La colonne '%-.32s' fait partie d'un index UNIQUE ou INDEX mais n'est pas définie comme NOT NULL" +"Imposible de charger la fonction '%-.64s'", +"Impossible d'initialiser la fonction '%-.64s'; %-.80s", +"Chemin interdit pour les bibliothèques partagées", +"La fonction '%-.64s' existe déjà", +"Impossible d'ouvrir la bibliothèque partagée '%-.64s' (errno: %d %s)", +"Impossible de trouver la fonction '%-.64s' dans la bibliothèque'", +"La fonction '%-.64s' n'est pas définie", +"L'hôte '%-.64s' est bloqué à cause d'un trop grand nombre d'erreur de connection. Débloquer le par 'mysqladmin flush-hosts'", +"Le hôte '%-.64s' n'est pas authorisé à se connecter à ce serveur MySQL", +"Vous utilisez un utilisateur anonyme et les utilisateurs anonymes ne sont pas autorisés à changer les mots de passe", +"Vous devez avoir le privilège update sur les tables de la base de donnée mysql pour pouvoir changer les mots de passe des autres", +"Impossible de trouver un enregistrement correspondant dans la table user", +"Enregistrements correspondants: %ld Modifiés: %ld Warnings: %ld", +"Impossible de créer une nouvelle tâche (errno %d). S'il reste de la mémoire libre, consultez le manual pour trouver un éventuel bug dépendant de l'OS", "Column count doesn't match value count at row %ld", -"Can't reopen table: '%-.64s', -"Invalid use of NULL value", -"Got error '%-.64s' from regexp", -"Mixing of GROUP columns (MIN(),MAX(),COUNT()...) with no GROUP columns is illegal if there is no GROUP BY clause", -"There is no such grant defined for user '%-.32s' on host '%-.64s'", -"%-.16s command denied to user: '%-.32s@%-.64s' for table '%-.64s'", -"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", -"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", -"The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", -"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", -"The used command is not allowed with this MySQL version", -"Something is wrong in your syntax", -"Delayed insert thread couldn't get requested lock for table %-.64s", -"Too many delayed threads in use", -"Aborted connection %ld to db: '%-.64s' user: '%-.64s' (%s)", -"Got a packet bigger than 'max_allowed_packet'", -"Got a read error from the connection pipe", -"Got an error from fcntl()", -"Got packets out of order", -"Couldn't uncompress communication packet", -"Got an error reading communication packets" -"Got timeout reading communication packets", -"Got an error writing communication packets", -"Got timeout writing communication packets", -"Result string is longer than max_allowed_packet", -"The used table type doesn't support BLOB/TEXT columns", -"The used table type doesn't support AUTO_INCREMENT columns", -"INSERT DELAYED can't be used with table '%-.64s', because it is locked with LOCK TABLES", -"Incorrect column name '%-.100s'", -"The used table handler can't index column '%-.64s'", -"All tables in the MERGE table are not defined identically", -"Can't write, because of unique constraint, to table '%-.64s'", -"BLOB column '%-.64s' used in key specification without a key length", -"All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead", -"Result consisted of more than one row", -"This table type requires a primary key", -"This version of MySQL is not compiled with RAID support", -"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column", -"Key '%-.64s' doesn't exist in table '%-.64s'", -"Can't open table", -"The handler for the table doesn't support check/repair", -"You are not allowed to execute this command in a transaction", -"Got error %d during COMMIT", -"Got error %d during ROLLBACK", -"Got error %d during FLUSH_LOGS", -"Got error %d during CHECKPOINT", -"Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: `%-.64s' (%-.64s)", -"The handler for the table does not support binary table dump", -"Binlog closed while trying to FLUSH MASTER", -"Failed rebuilding the index of dumped table '%-.64s'", -"Error from master: '%-.64s'", -"Net error reading from master", -"Net error writing to master", -"Can't find FULLTEXT index matching the column list", -"Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64s'", -"Table '%-.64s' is marked as crashed and should be repaired", -"Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", -"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', -"This operation cannot be performed with a running slave, run SLAVE STOP first", -"This operation requires a running slave, configure slave and do SLAVE START", -"The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", -"Could not create slave thread, check system resources", -"User %-.64s has already more than 'max_user_connections' active connections", -"You may only use constant expressions with SET", -"Lock wait timeout exceeded", -"The total number of locks exceeds the lock table size", -"Update locks cannot be acquired during a READ UNCOMMITTED transaction", -"DROP DATABASE not allowed while thread is holding global read lock", -"CREATE DATABASE not allowed while thread is holding global read lock", -"Wrong arguments to %s", -"%-.32s@%-.64s is not allowed to create new users", -"Incorrect table definition; All MERGE tables must be in the same database", -"Deadlock found when trying to get lock; Try restarting transaction", -"The used table type doesn't support FULLTEXT indexes", -"Cannot add foreign key constraint", -"Cannot add a child row: a foreign key constraint fails", -"Cannot delete a parent row: a foreign key constraint fails", +"Impossible de réouvrir la table: '%-.64s', +"Utilisation incorrecte de la valeur NULL", +"Erreur '%-.64s' provenant de regexp", +"Mélanger les colonnes GROUP (MIN(),MAX(),COUNT()...) avec des colonnes normales est interdit s'il n'y a pas de clause GROUP BY", +"Un tel droit n'est pas défini pour l'utilisateur '%-.32s' sur l'hôte '%-.64s'", +"La commande '%-.16s' est interdite à l'utilisateur: '%-.32s@%-.64s' sur la table '%-.64s'", +"La commande '%-.16s' est interdite à l'utilisateur: '%-.32s@%-.64s' sur la colonne '%-.64s' de la table '%-.64s'", +"Commande GRANT/REVOKE incorrecte. Consultez le manuel.", +"L'hôte ou l'utilisateur donné en argument à GRANT est trop long", +"La table '%-64s.%s' n'existe pas", +"Un tel droit n'est pas défini pour l'utilisateur '%-.32s' sur l'hôte '%-.64s' sur la table '%-.64s'", +"Cette commande n'existe pas dans cette version de MySQL", +"Erreur de syntaxe", +"La tâche 'delayed insert' n'a pas pu obtenir le verrou démandé sur la table %-.64s", +"Trop de tâche 'delayed' en cours", +"Connection %ld avortée vers la bd: '%-.64s' utilisateur: '%-.64s' (%s)", +"Paquet plus grand que 'max_allowed_packet' reçu", +"Erreur de lecture reçue du pipe de connection", +"Erreur reçue de fcntl() ", +"Paquets reçus dans le désordre", +"Impossible de décompresser le paquet reçu", +"Erreur de lecture des paquets reçus" +"Timeout en lecture des paquets reçus", +"Erreur d'écriture des paquets envoyés", +"Timeout d'écriture des paquets envoyés", +"La chaîne résultat est plus grande que max_allowed_packet", +"Ce type de table ne supporte pas les colonnes BLOB/TEXT", +"Ce type de table ne supporte pas les colonnes AUTO_INCREMENT", +"INSERT DELAYED ne peut être utilisé avec la table '%-.64s', car elle est verrouée avec LOCK TABLES", +"Nom de colonne '%-.100s' incorrect", +"Le handler de la table ne peut indexé la colonne '%-.64s'", +"Toutes les tables de la table de type MERGE n'ont pas la même définition", +"Écriture impossible à cause d'un index UNIQUE sur la table '%-.64s'", +"La colonne '%-.64s' de type BLOB est utilisée dans une définition d'index sans longueur d'index", +"Toutes les parties d'un index PRIMARY KEY doivent être NOT NULL; Si vous avez besoin d'un NULL dans l'index, utilisez un index UNIQUE", +"Le résultat contient plus d'un enregistrement", +"Ce type de table nécessite une clé primaire (PRIMARY KEY)", +"Cette version de MySQL n'est pas compilée avec le support RAID", +"Vous êtes en mode 'safe update' et vous essayez de faire un UPDATE sans clause WHERE utilisant un index", +"L'index '%-.64s' n'existe pas sur la table '%-.64s'", +"Impossible d'ouvrir la table", +"Ce type de table ne supporte pas les check/repair", +"Vous n'êtes pas autorisé à exécute cette commande dans une transaction", +"Erreur %d lors du COMMIT", +"Erreur %d lors du ROLLBACK", +"Erreur %d lors du FLUSH_LOGS", +"Erreur %d lors du CHECKPOINT", +"Connection %ld avortée vers la bd: '%-.64s' utilisateur: '%-.32s' hôte: `%-.64s' (%-.64s)", +"Ce type de table ne supporte pas les copies binaires", +"Le 'binlog' a été fermé pendant l'exécution du FLUSH MASTER", +"La reconstruction de l'index de la table copiée '%-.64s' a échoué", +"Erreur reçue du maître: '%-.64s'", +"Erreur de lecture réseau reçue du maître", +"Erreur d'écriture réseau reçue du maître", +"Impossible de trouver un index FULLTEXT correspondant à cette liste de colonnes", +"Impossible d'exécuter la commande car vous avez des tables verrouillées ou une transaction active", +"Variable système '%-.64' inconnue", +"La table '%-.64s' est marquée 'crashed' et devrait être réparée", +"La table '%-.64s' est marquée 'crashed' et le dernier 'repair' a échoué", +"Attention: certaines tables ne supportant pas les transactions ont été changées et elles ne pourront pas être restituées", +"Cette transaction à commandes multiples nécessite plus de 'max_binlog_cache_size' octets de stockage, augmentez cette variable de mysqld et réessayez', +"Cette opération ne peut être réalisée avec un esclave actif, faites SLAVE STOP d'abord", +"Cette opération nécessite un esclave actif, configurez les esclaves et faites SLAVE START", +"Le server n'est pas configuré comme un esclave, changez le fichier de configuration ou utilisez CHANGE MASTER TO", +"Impossible d'initialiser les structures d'information de maître, vérifiez les permissions sur master.info", +"Impossible de créer une tâche esclave, vérifiez les ressources système", +"L'utilisateur %-.64s possède déjà plus de 'max_user_connections' connections actives", +"Seules les expressions constantes sont autorisées avec SET", +"Timeout sur l'obtention du verrou", +"Le nombre total de verrou dépasse la taille de la table des verrous", +"Un verrou en update ne peut être acquit pendant une transaction READ UNCOMMITTED", +"DROP DATABASE n'est pas autorisée pendant qu'une tâche possède un verrou global en lecture", +"CREATE DATABASE n'est pas autorisée pendant qu'une tâche possède un verrou global en lecture", +"Mauvais arguments à %s", +"%-.32s@%-.64s n'est pas autorisé à créer de nouveaux utilisateurs", +"Définition de table incorrecte : toutes les tables MERGE doivent être dans la même base de donnée", +"Deadlock découvert en essayant d'obtenir les verrous : essayez de redémarrer la transaction", +"Le type de table utilisé ne supporte pas les index FULLTEXT", +"Impossible d'ajouter des contraintes d'index externe", +"Impossible d'ajouter un enregistrement fils : une constrainte externe l'empèche", +"Impossible de supprimer un enregistrement père : une constrainte externe l'empèche", diff --git a/strings/longlong2str-x86.s b/strings/longlong2str-x86.s index bafc485f759..98e60acbafb 100644 --- a/strings/longlong2str-x86.s +++ b/strings/longlong2str-x86.s @@ -1,18 +1,17 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +# Copyright (C) 2000 MySQL AB +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Optimized longlong2str function for Intel 80x86 (gcc/gas syntax) # Some set sequences are optimized for pentuimpro II diff --git a/strings/strings-x86.s b/strings/strings-x86.s index 5d7cbde1b38..8b29a2db7f1 100644 --- a/strings/strings-x86.s +++ b/strings/strings-x86.s @@ -1,38 +1,37 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +# Copyright (C) 2000 MySQL AB +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -/* Optimized string functions Intel 80x86 (gcc/gas syntax) */ +# Optimized string functions Intel 80x86 (gcc/gas syntax) - .file "strings.s" + .file "strings.s" .version "1.00" .text - /* Move a alligned, not overlapped, by (long) divided memory area */ - /* Args: to,from,length */ +# Move a alligned, not overlapped, by (long) divided memory area +# Args: to,from,length .globl bmove_allign .type bmove_allign,@function bmove_allign: movl %edi,%edx movl %esi,%eax - movl 4(%esp),%edi /* to */ - movl 8(%esp),%esi /* from */ - movl 12(%esp),%ecx /* length */ - addw $3,%cx /* fix if not divisible with long */ + movl 4(%esp),%edi # to + movl 8(%esp),%esi # from + movl 12(%esp),%ecx # length + addw $3,%cx # fix if not divisible with long shrw $2,%cx rep movsl @@ -42,198 +41,198 @@ bmove_allign: .end: .size bmove_allign,.end-bmove_allign - /* Move a string from higher to lower */ - /* Arg from+1,to+1,length */ + # Move a string from higher to lower + # Arg from+1,to+1,length .globl bmove_upp .type bmove_upp,@function bmove_upp: - std /* Work downward */ + std # Work downward movl %edi,%edx movl %esi,%eax - movl 4(%esp),%edi /* p1 */ - movl 8(%esp),%esi /* p2 */ - movl 12(%esp),%ecx /* length */ - decl %edi /* Don't move last arg */ + movl 4(%esp),%edi # p1 + movl 8(%esp),%esi # p2 + movl 12(%esp),%ecx # length + decl %edi # Don't move last arg decl %esi rep - movsb /* One byte a time because overlap */ - cld /* C library wants cld */ + movsb # One byte a time because overlap + cld # C library wants cld movl %eax,%esi movl %edx,%edi ret .bmove_upp_end: .size bmove_upp,.bmove_upp_end-bmove_upp - /* Append fillchars to string */ - /* Args: dest,len,fill */ + # Append fillchars to string + # Args: dest,len,fill .globl strappend .type strappend,@function strappend: pushl %edi - movl 8(%esp),%edi /* Memory pointer */ - movl 12(%esp),%ecx /* Length */ - clrl %eax /* Find end of string */ + movl 8(%esp),%edi # Memory pointer + movl 12(%esp),%ecx # Length + clrl %eax # Find end of string repne scasb - jnz sa_99 /* String to long, shorten it */ - movzb 16(%esp),%eax /* Fillchar */ - decl %edi /* Point at end null */ - incl %ecx /* rep made one dec for null-char */ + jnz sa_99 # String to long, shorten it + movzb 16(%esp),%eax # Fillchar + decl %edi # Point at end null + incl %ecx # rep made one dec for null-char - movb %al,%ah /* (2) Set up a 32 bit pattern. */ - movw %ax,%dx /* (2) */ - shll $16,%eax /* (3) */ - movw %dx,%ax /* (2) %eax has the 32 bit pattern. */ + movb %al,%ah # (2) Set up a 32 bit pattern. + movw %ax,%dx # (2) + shll $16,%eax # (3) + movw %dx,%ax # (2) %eax has the 32 bit pattern. - movl %ecx,%edx /* (2) Save the count of bytes. */ - shrl $2,%ecx /* (2) Number of dwords. */ + movl %ecx,%edx # (2) Save the count of bytes. + shrl $2,%ecx # (2) Number of dwords. rep - stosl /* (5 + 5n) */ - movb $3,%cl /* (2) */ - and %edx,%ecx /* (2) Fill in the odd bytes*/ + stosl # (5 + 5n) + movb $3,%cl # (2) + and %edx,%ecx # (2) Fill in the odd bytes rep - stosb /* Move last bytes if any */ + stosb # Move last bytes if any -sa_99: movb $0,(%edi) /* End of string */ +sa_99: movb $0,(%edi) # End of string popl %edi ret .strappend_end: .size strappend,.strappend_end-strappend - /* Find if string contains any char in another string */ - /* Arg: str,set */ - /* Ret: Pointer to first found char in str */ + # Find if string contains any char in another string + # Arg: str,set + # Ret: Pointer to first found char in str .globl strcont .type strcont,@function strcont: movl %edi,%edx pushl %esi - movl 8(%esp),%esi /* str */ - movl 12(%esp),%ecx /* set */ - clrb %ah /* For endtest */ + movl 8(%esp),%esi # str + movl 12(%esp),%ecx # set + clrb %ah # For endtest jmp sc_60 sc_10: scasb - jz sc_fo /* Found char */ -sc_20: cmp (%edi),%ah /* Test if null */ - jnz sc_10 /* Not end of set yet */ - incl %esi /* Next char in str */ -sc_60: movl %ecx,%edi /* %edi = Set */ - movb (%esi),%al /* Test if this char exist */ + jz sc_fo # Found char +sc_20: cmp (%edi),%ah # Test if null + jnz sc_10 # Not end of set yet + incl %esi # Next char in str +sc_60: movl %ecx,%edi # %edi = Set + movb (%esi),%al # Test if this char exist andb %al,%al - jnz sc_20 /* Not end of string */ - clrl %esi /* Return Null */ -sc_fo: movl %esi,%eax /* Char found here */ - movl %edx,%edi /* Restore */ + jnz sc_20 # Not end of string + clrl %esi # Return Null +sc_fo: movl %esi,%eax # Char found here + movl %edx,%edi # Restore popl %esi ret .strcont_end: .size strcont,.strcont_end-strcont - /* Find end of string */ - /* Arg: str */ - /* ret: Pointer to end null */ + # Find end of string + # Arg: str + # ret: Pointer to end null .globl strend .type strend,@function strend: - movl %edi,%edx /* Save */ - movl 4(%esp),%edi /* str */ - clrl %eax /* Find end of string */ + movl %edi,%edx # Save + movl 4(%esp),%edi # str + clrl %eax # Find end of string movl %eax,%ecx - decl %ecx /* ECX = -1 */ + decl %ecx # ECX = -1 repne scasb movl %edi,%eax - decl %eax /* End of string */ - movl %edx,%edi /* Restore */ + decl %eax # End of string + movl %edx,%edi # Restore ret .strend_end: .size strend,.strend_end-strend - /* Make a string with len fill-chars and endnull */ - /* Args: dest,len,fill */ - /* Ret: dest+len */ + # Make a string with len fill-chars and endnull + # Args: dest,len,fill + # Ret: dest+len .globl strfill .type strfill,@function strfill: pushl %edi - movl 8(%esp),%edi /* Memory pointer */ - movl 12(%esp),%ecx /* Length */ - movzb 16(%esp),%eax /* Fill */ + movl 8(%esp),%edi # Memory pointer + movl 12(%esp),%ecx # Length + movzb 16(%esp),%eax # Fill - movb %al,%ah /* (2) Set up a 32 bit pattern */ - movw %ax,%dx /* (2) */ - shll $16,%eax /* (3) */ - movw %dx,%ax /* (2) %eax has the 32 bit pattern. */ + movb %al,%ah # (2) Set up a 32 bit pattern + movw %ax,%dx # (2) + shll $16,%eax # (3) + movw %dx,%ax # (2) %eax has the 32 bit pattern. - movl %ecx,%edx /* (2) Save the count of bytes. */ - shrl $2,%ecx /* (2) Number of dwords. */ + movl %ecx,%edx # (2) Save the count of bytes. + shrl $2,%ecx # (2) Number of dwords. rep - stosl /* (5 + 5n) */ - movb $3,%cl /* (2) */ - and %edx,%ecx /* (2) Fill in the odd bytes */ + stosl # (5 + 5n) + movb $3,%cl # (2) + and %edx,%ecx # (2) Fill in the odd bytes rep - stosb /* Move last bytes if any */ + stosb # Move last bytes if any - movb %cl,(%edi) /* End NULL */ - movl %edi,%eax /* End i %eax */ + movb %cl,(%edi) # End NULL + movl %edi,%eax # End i %eax popl %edi ret .strfill_end: .size strfill,.strfill_end-strfill - /* Find a char in or end of a string */ - /* Arg: str,char */ - /* Ret: pointer to found char or NullS */ + # Find a char in or end of a string + # Arg: str,char + # Ret: pointer to found char or NullS .globl strcend .type strcend,@function strcend: movl %edi,%edx - movl 4(%esp),%edi /* str */ - movb 8(%esp),%ah /* search */ - clrb %al /* for scasb to find end */ + movl 4(%esp),%edi # str + movb 8(%esp),%ah # search + clrb %al # for scasb to find end se_10: cmpb (%edi),%ah - jz se_20 /* Found char */ + jz se_20 # Found char scasb - jnz se_10 /* Not end */ - dec %edi /* Not found, point at end of string */ + jnz se_10 # Not end + dec %edi # Not found, point at end of string se_20: movl %edi,%eax - movl %edx,%edi /* Restore */ + movl %edx,%edi # Restore ret .strcend_end: .size strcend,.strcend_end-strcend - /* Test if string has a given suffix */ + # Test if string has a given suffix .globl is_prefix .type is_prefix,@function is_prefix: - movl %edi,%edx /* Save %edi */ - pushl %esi /* and %esi */ - movl 12(%esp),%esi /* get suffix */ - movl 8(%esp),%edi /* s1 */ - movl $1,%eax /* Ok and zero-test */ + movl %edi,%edx # Save %edi + pushl %esi # and %esi + movl 12(%esp),%esi # get suffix + movl 8(%esp),%edi # s1 + movl $1,%eax # Ok and zero-test ip_10: cmpb (%esi),%ah - jz suf_ok /* End of string/ found suffix */ - cmpsb /* Compare strings */ - jz ip_10 /* Same, possible prefix */ - xor %eax,%eax /* Not suffix */ + jz suf_ok # End of string/ found suffix + cmpsb # Compare strings + jz ip_10 # Same, possible prefix + xor %eax,%eax # Not suffix suf_ok: popl %esi movl %edx,%edi ret .is_prefix_end: .size is_prefix,.is_prefix_end-is_prefix - /* Find a substring in string */ - /* Arg: str,search */ + # Find a substring in string + # Arg: str,search .globl strstr .type strstr,@function @@ -241,31 +240,31 @@ suf_ok: popl %esi strstr: pushl %edi pushl %esi - movl 12(%esp),%esi /* str */ - movl 16(%esp),%edi /* search */ + movl 12(%esp),%esi # str + movl 16(%esp),%edi # search movl %edi,%ecx - incl %ecx /* %ecx = search+1 */ - movb (%edi),%ah /* %ah = First char in search */ + incl %ecx # %ecx = search+1 + movb (%edi),%ah # %ah = First char in search jmp sf_10 -sf_00: movl %edx,%esi /* si = Current str-pos */ -sf_10: movb (%esi),%al /* Test if this char exist */ +sf_00: movl %edx,%esi # si = Current str-pos +sf_10: movb (%esi),%al # Test if this char exist andb %al,%al - jz sf_90 /* End of string, didn't find search */ + jz sf_90 # End of string, didn't find search incl %esi cmpb %al,%ah - jnz sf_10 /* Didn't find first char, continue */ - movl %esi,%edx /* Save str-pos in %edx */ + jnz sf_10 # Didn't find first char, continue + movl %esi,%edx # Save str-pos in %edx movl %ecx,%edi sf_20: cmpb $0,(%edi) - jz sf_fo /* Found substring */ + jz sf_fo # Found substring cmpsb - jz sf_20 /* Char ok */ - jmp sf_00 /* Next str-pos */ + jz sf_20 # Char ok + jmp sf_00 # Next str-pos -sf_90: movl $1,%edx /* Return Null */ -sf_fo: movl %edx,%eax /* Char found here */ - decl %eax /* Pointed one after */ +sf_90: movl $1,%edx # Return Null +sf_fo: movl %edx,%eax # Char found here + decl %eax # Pointed one after popl %esi popl %edi ret @@ -273,8 +272,8 @@ sf_fo: movl %edx,%eax /* Char found here */ .size strstr,.strstr_end-strstr - /* Find a substring in string, return index */ - /* Arg: str,search */ + # Find a substring in string, return index + # Arg: str,search .globl strinstr .type strinstr,@function @@ -282,22 +281,22 @@ sf_fo: movl %edx,%eax /* Char found here */ strinstr: pushl %ebp movl %esp,%ebp - pushl 12(%ebp) /* search */ - pushl 8(%ebp) /* str */ + pushl 12(%ebp) # search + pushl 8(%ebp) # str call strstr add $8,%esp or %eax,%eax - jz si_99 /* Not found, return NULL */ - sub 8(%ebp),%eax /* Pos from start */ - inc %eax /* And first pos = 1 */ + jz si_99 # Not found, return NULL + sub 8(%ebp),%eax # Pos from start + inc %eax # And first pos = 1 si_99: popl %ebp ret .strinstr_end: .size strinstr,.strinstr_end-strinstr - /* Make a string of len length from another string */ - /* Arg: dst,src,length */ - /* ret: end of dst */ + # Make a string of len length from another string + # Arg: dst,src,length + # ret: end of dst .globl strmake .type strmake,@function @@ -305,48 +304,48 @@ si_99: popl %ebp strmake: pushl %edi pushl %esi - movl 12(%esp),%edi /* dst */ - movl 16(%esp),%esi /* src */ - movl 20(%esp),%ecx /* Length of memory-area */ - clrb %al /* For test of end-null */ - jecxz sm_90 /* Nothing to move, put zero at end. */ + movl 12(%esp),%edi # dst + movl 16(%esp),%esi # src + movl 20(%esp),%ecx # Length of memory-area + clrb %al # For test of end-null + jecxz sm_90 # Nothing to move, put zero at end. -sm_10: cmpb (%esi),%al /* Next char to move */ - movsb /* move arg */ - jz sm_99 /* last char, we are ready */ - loop sm_10 /* Continue moving */ -sm_90: movb %al,(%edi) /* Set end pos */ - incl %edi /* Fix that di points at end null */ -sm_99: decl %edi /* di points now at end null */ - movl %edi,%eax /* Ret value.p $ */ +sm_10: cmpb (%esi),%al # Next char to move + movsb # move arg + jz sm_99 # last char, we are ready + loop sm_10 # Continue moving +sm_90: movb %al,(%edi) # Set end pos + incl %edi # Fix that di points at end null +sm_99: decl %edi # di points now at end null + movl %edi,%eax # Ret value.p $ popl %esi popl %edi ret .strmake_end: .size strmake,.strmake_end-strmake - /* Move a string with max len chars */ - /* arg: dst,src,len */ - /* ret: pos to first null or dst+len */ + # Move a string with max len chars + # arg: dst,src,len + # ret: pos to first null or dst+len .globl strnmov .type strnmov,@function strnmov: pushl %edi pushl %esi - movl 12(%esp),%edi /* dst */ - movl 16(%esp),%esi /* src */ - movl 20(%esp),%ecx /* Length of memory-area */ - jecxz snm_99 /* Nothing to do */ - clrb %al /* For test of end-null */ + movl 12(%esp),%edi # dst + movl 16(%esp),%esi # src + movl 20(%esp),%ecx # Length of memory-area + jecxz snm_99 # Nothing to do + clrb %al # For test of end-null -snm_10: cmpb (%esi),%al /* Next char to move */ - movsb /* move arg */ - jz snm_20 /* last char, fill with null */ - loop snm_10 /* Continue moving */ - incl %edi /* Point two after last */ -snm_20: decl %edi /* Point at first null (or last+1) */ -snm_99: movl %edi,%eax /* Pointer at last char */ +snm_10: cmpb (%esi),%al # Next char to move + movsb # move arg + jz snm_20 # last char, fill with null + loop snm_10 # Continue moving + incl %edi # Point two after last +snm_20: decl %edi # Point at first null (or last+1) +snm_99: movl %edi,%eax # Pointer at last char popl %esi popl %edi ret @@ -357,17 +356,17 @@ snm_99: movl %edi,%eax /* Pointer at last char */ .globl strmov .type strmov,@function strmov: - movl %esi,%ecx /* Save old %esi and %edi */ + movl %esi,%ecx # Save old %esi and %edi movl %edi,%edx - movl 8(%esp),%esi /* get source pointer (s2) */ - movl 4(%esp),%edi /* %edi -> s1 */ + movl 8(%esp),%esi # get source pointer (s2) + movl 4(%esp),%edi # %edi -> s1 smo_10: movb (%esi),%al - movsb /* move arg */ + movsb # move arg andb %al,%al - jnz smo_10 /* Not last */ + jnz smo_10 # Not last movl %edi,%eax dec %eax - movl %ecx,%esi /* Restore */ + movl %ecx,%esi # Restore movl %edx,%edi ret .strmov_end: @@ -376,29 +375,29 @@ smo_10: movb (%esi),%al .globl strxmov .type strxmov,@function strxmov: - movl %ebx,%edx /* Save %ebx, %esi and %edi */ + movl %ebx,%edx # Save %ebx, %esi and %edi mov %esi,%ecx push %edi - leal 8(%esp),%ebx /* Get destination */ + leal 8(%esp),%ebx # Get destination movl (%ebx),%edi xorb %al,%al - jmp next_str /* Handle source ebx+4 */ + jmp next_str # Handle source ebx+4 start_str: movsb cmpb -1(%edi),%al jne start_str - decl %edi /* Don't copy last null */ + decl %edi # Don't copy last null next_str: addl $4,%ebx movl (%ebx),%esi orl %esi,%esi jne start_str - movb %al,0(%edi) /* Force last to ASCII 0 */ + movb %al,0(%edi) # Force last to ASCII 0 - movl %edi,%eax /* Return ptr to ASCII 0 */ - pop %edi /* Restore registers */ + movl %edi,%eax # Return ptr to ASCII 0 + pop %edi # Restore registers movl %ecx,%esi movl %edx,%ebx ret