diff options
author | unknown <monty@hundin.mysql.fi> | 2002-03-07 00:23:22 +0200 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-03-07 00:23:22 +0200 |
commit | defcaaf46bde9bcde199a1d99136ea0db3de6a57 (patch) | |
tree | d99bab9328d280deb521d2098f68a637b1b9af20 | |
parent | 47e83fde9a887091bb689bf4c3b8b12567ea2e2a (diff) | |
parent | 3d490dcb2774edf265dd127a89575e4761e0e480 (diff) | |
download | mariadb-git-defcaaf46bde9bcde199a1d99136ea0db3de6a57.tar.gz |
Merge work:/home/bk/mysql-4.0 into hundin.mysql.fi:/my/bk/mysql-4.0
Docs/manual.texi:
Auto merged
36 files changed, 507 insertions, 319 deletions
diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index fbefbf0e475..dc08478aa43 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -7,7 +7,7 @@ $opt_tmp=$opt_version_suffix=""; $opt_help=$opt_Information=$opt_delete=$opt_debug=$opt_stage=$opt_rsh_mail=$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_no_mysqltest=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=0; $opt_innodb=$opt_bdb=0; -GetOptions("Information","help","distribution=s","user=s","result=s","delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution","enable-shared","no-crash-me","no-strip","version-suffix=s", "with-other-libc=s) || usage(); +GetOptions("Information","help","distribution=s","user=s","result=s","delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution","enable-shared","no-crash-me","no-strip","version-suffix=s", "with-other-libc=s") || usage(); usage() if ($opt_help || $opt_Information); usage() if (!$opt_distribution); diff --git a/Docs/manual.texi b/Docs/manual.texi index 662b27b2c53..0e37561f5b4 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -566,7 +566,8 @@ a commercial memory leakage detector. @item Works on many different platforms. @xref{Which OS}. @item -Uses GNU Automake, Autoconf (Ver 2.52 or newer), and Libtool for portability. +Uses GNU Automake (1.4), Autoconf (Ver 2.52 or newer), and Libtool for +portability. @item APIs for C, C++, Eiffel, Java, Perl, PHP, Python and Tcl. @xref{Clients}. @item @@ -6254,11 +6255,14 @@ shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf - shell> ln -s mysql-VERSION-OS mysql shell> cd mysql shell> scripts/mysql_install_db -shell> chown -R root /usr/local/mysql -shell> chown -R mysql /usr/local/mysql/data -shell> chgrp -R mysql /usr/local/mysql -shell> chown -R root /usr/local/mysql/bin +shell> chown -R root . +shell> chown -R mysql ./data +shell> chgrp -R mysql . +shell> chown -R root ./bin shell> bin/safe_mysqld --user=mysql & +or +shell> bin/mysqld_safe --user=mysql & +if you are running MySQL 4.x @end example @cindex adding, new users @@ -6522,6 +6526,9 @@ shell> chown -R mysql /usr/local/mysql/var shell> chgrp -R mysql /usr/local/mysql shell> cp support-files/my-medium.cnf /etc/my.cnf shell> /usr/local/mysql/bin/safe_mysqld --user=mysql & +or +shell> /usr/local/mysql/bin/mysqld_safe --user=mysql & +if you are running MySQL 4.x. @end example If you want have support for InnoDB tables, you should edit the @@ -7009,11 +7016,10 @@ The initial download of the source tree may take a while, depending on the speed of your connection; be patient. @item -You will need GNU @code{autoconf 2.13}, @code{automake 1.4}, +You will need GNU @code{autoconf 2.52}, @code{automake 1.4}, @code{libtool}, and @code{m4} to run the next set of commands. -If you are using the 3.23 tree the new versions of @code{autoconf} -(2.52) and @code{automake} (1.5) will not work. +@code{automake} (1.5) doesn't yet work. If you get some strange error during this stage, check that you really have @code{libtool} installed! @@ -8141,6 +8147,9 @@ version 4.0; @itemize @bullet @item +Use @code{ORDER BY column DESC} now always sorts @code{NULL} values +first; In 3.23 this was not always consistent. +@item @code{SHOW INDEX} has 2 columns more (@code{Null} and @code{Index_type}) than it had in 3.23. @item @@ -12676,9 +12685,15 @@ mysql> SELECT 1 IS NULL, 1 IS NOT NULL; +-----------+---------------+ @end example +Note that two @code{NULL} are compared as equal is when you do an +@code{GROUP BY}. + In MySQL, 0 or @code{NULL} means false and anything else means true. The default truth value from a boolean operation is 1. +When doing an @code{ORDER BY}, @code{NULL} values are always sorted first, +even if you are using @code{DESC}. + This special treatment of @code{NULL} is why, in the previous section, it was necessary to determine which animals are no longer alive using @code{death IS NOT NULL} instead of @code{death <> NULL}. @@ -13206,7 +13221,7 @@ mysql> DESCRIBE pet; @end example @code{Field} indicates the column name, @code{Type} is the data type for -the column, @code{Null} indicates whether or not the column can contain +the column, @code{NULL} indicates whether or not the column can contain @code{NULL} values, @code{Key} indicates whether or not the column is indexed, and @code{Default} specifies the column's default value. @@ -13692,6 +13707,13 @@ tell @code{mysql} to read its input from the file: shell> mysql < batch-file @end example +If you are running @code{mysql} under windows and have some special +characters in the file that causes problems, you can do: + +@example +dos> mysql -e "source batch-file" +@end example + If you need to specify connection parameters on the command line, the command might look like this: @@ -13703,6 +13725,9 @@ Enter password: ******** When you use @code{mysql} this way, you are creating a script file, then executing the script. +If you want the script to continue even if you have errors, you should +use the @code{--force} command line option. + Why use a script? Here are a few reasons: @itemize @bullet @@ -13776,6 +13801,12 @@ If you want to get the interactive output format in batch mode, use @code{mysql -t}. To echo to the output the commands that are executed, use @code{mysql -vvv}. +You can also use scripts in the @code{mysql} command line prompt by +using the @code{source} command: + +@example +mysql> source filename +@end example @node Twin, Apache, Batch mode, Tutorial @section Queries from Twin Project @@ -16496,8 +16527,10 @@ password will be set to the password specified by the @code{IDENTIFIED BY} clause, if one is given. If the user already had a password, it is replaced by the new one. -Optional @code{PASSWORD} changes behaviour of @code{IDENTIFIED BY} from -accepting plain password to accept encrypted password as argument. +If you don't want to send the password in clear text you can use the +@code{PASSWORD} option followed by a scrambled password from SQL +function @code{PASSWORD()} or the C API function +@code{make_scrambled_password(char *to, const char *password)}. @strong{Warning:} If you create a new user but do not specify an @code{IDENTIFIED BY} clause, the user has no password. This is insecure. @@ -25574,7 +25607,13 @@ You have different @code{ORDER BY} and @code{GROUP BY} expressions. @item The used table index is an index type that doesn't store rows in order. -(Like index in @code{HEAP} tables). +(Like the @code{HASH} index in @code{HEAP} tables). + +@item +The index colum may contain @code{NULL} values and one is using +@code{ORDER BY ... DESC}. This is because in SQL @code{NULL} values is +always sorted before normal values, independent of you are using +@code{DESC} or not. @end itemize @@ -26509,6 +26548,9 @@ probably much faster, as this will require us to do much fewer seeks.) Note that if such a query uses @code{LIMIT} to only retrieve part of the rows, MySQL will use an index anyway, as it can much more quickly find the few rows to return in the result. +@item +If the index range may contain @code{NULL} values and you are using +@code{ORDER BY ... DESC} @end itemize @node Indexes, Multiple-column indexes, MySQL indexes, Optimising Database Structure @@ -30018,7 +30060,7 @@ mysql> select 2 > 2; @cindex @code{NULL}, testing for null @findex <=> (Equal to) @item <=> -Null safe equal: +NULL safe equal: @example mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL; -> 1 1 0 @@ -48665,6 +48707,12 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @itemize @bullet @item +Use @code{ORDER BY column DESC} now sorts @code{NULL} values first. +@item +Fixed bug in @code{SELECT DISTINCT ... ORDER BY DESC} optimization. +@item +Fixed bug in @code{... HAVING 'GROUP_FUNCTION'(xxx) IS [NOT] NULL}. +@item Fixed bug in truncation operator for boolean fulltext search. @item Allow numeric user id to @code{mysqld --user=#}. @@ -49037,8 +49085,19 @@ not yet 100% confident in this code. @node News-3.23.50, News-3.23.49, News-3.23.x, News-3.23.x @appendixsubsec Changes in release 3.23.50 @itemize @bullet +Fixed core-dump bug when reading client groups from option files using +@code{mysql_options()}. @item Memory leak (16 bytes per every @strong{corrupted} table) closed. +@item +Fixed binary builds to use @code{--enable-local-infile}. +@item +Update source to work with new @code{bison} version. +@item +Updated shell scripts to new agree with new POSIX standard. +@item +Fixed bug where @code{DATE_FORMAT()} returned empty string when used +with @code{GROUP BY}. @end itemize @node News-3.23.49, News-3.23.48, News-3.23.50, News-3.23.x @@ -49056,6 +49115,8 @@ Added options to make @code{LOAD DATA LOCAL INFILE} more secure. MySQL binary release 3.23.48 for Linux contained a new glibc library, which has serious problems under high load and RedHat 7.2. The 3.23.49 binary release doesn't have this problem. +@item +Fixed shutdown problem on NT. @end itemize @node News-3.23.48, News-3.23.47, News-3.23.49, News-3.23.x diff --git a/acinclude.m4 b/acinclude.m4 index 830157423c1..85149d64dc7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -846,21 +846,21 @@ dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_CHECK_BDB], [ AC_ARG_WITH([berkeley-db], - [\ + [ --with-berkeley-db[=DIR] Use BerkeleyDB located in DIR], [bdb="$withval"], [bdb=no]) AC_ARG_WITH([berkeley-db-includes], - [\ + [ --with-berkeley-db-includes=DIR Find Berkeley DB headers in DIR], [bdb_includes="$withval"], [bdb_includes=default]) AC_ARG_WITH([berkeley-db-libs], - [\ + [ --with-berkeley-db-libs=DIR Find Berkeley DB libraries in DIR], [bdb_libs="$withval"], @@ -1108,7 +1108,7 @@ dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_CHECK_INNODB], [ AC_ARG_WITH([innodb], - [\ + [ --without-innodb Do not include the InnoDB table handler], [innodb="$withval"], [innodb=yes]) @@ -1182,6 +1182,7 @@ dnl END OF MYSQL_CHECK_INNODB SECTION dnl --------------------------------------------------------------------------- dnl --------------------------------------------------------------------------- + dnl Got this from the GNU tar 1.13.11 distribution dnl by Paul Eggert <eggert@twinsun.com> dnl --------------------------------------------------------------------------- diff --git a/bdb/dist/s_recover b/bdb/dist/s_recover index 0e8b3731c77..b0593cfc052 100755 --- a/bdb/dist/s_recover +++ b/bdb/dist/s_recover @@ -12,6 +12,13 @@ rm -f $loglist trap 'rm -f $t; exit 1' 1 2 3 13 15 +# Use the standard -k option if it works; +# otherwise fall back on the traditional notation. +if sort -k 1,1 /dev/null +then sort_2_etc='-k 2' +else sort_2_etc='+1' +fi + # Check to make sure we haven't duplicated a log record entry, and build # the list of log record types that the test suite uses. for i in $DIR; do @@ -19,13 +26,14 @@ for i in $DIR; do for f in ../$i/*.src; do # Grab the PREFIX; there should only be one per file, and # so it's okay to just take the first. - grep '^PREFIX' $f | head -1 + grep '^PREFIX' $f | sed q egrep '^DEPRECATED[ ]|^BEGIN[ ]' $f | \ awk '{print $1 "\t" $2 "\t" $3}' done done > $loglist -grep -v '^PREFIX' $loglist | awk '{print $2 "\t" $3}' | sort +1 -n | \ +grep -v '^PREFIX' $loglist | awk '{print $2 "\t" $3}' | \ + sort $sort_2_etc -n | \ uniq -d -f 1 > $t [ -s $t ] && { echo "DUPLICATE LOG VALUES:" diff --git a/client/mysql.cc b/client/mysql.cc index 769b4490096..df329b04481 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -38,7 +38,7 @@ #include <signal.h> #include <violite.h> -const char *VER="11.20"; +const char *VER="11.21"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 diff --git a/client/mysqldump.c b/client/mysqldump.c index da708849992..c2e3d7dad3c 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -35,7 +35,7 @@ ** and adapted to mysqldump 05/11/01 by Jani Tolonen */ -#define DUMP_VERSION "8.22" +#define DUMP_VERSION "8.23" #include <my_global.h> #include <my_sys.h> @@ -897,8 +897,6 @@ static uint getTableStructure(char *table, char* db) fputs(";\n", sql_file); } } - if (opt_disable_keys) - fprintf(sql_file,"\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",table_name); if (cFlag) { strpos=strmov(strpos,") VALUES "); @@ -1023,7 +1021,7 @@ static void dumpTable(uint numFields, char *table) strxmov(strend(query), " WHERE ",where,NullS); } if (!opt_xml) - fputs("\n\n", md_result_file); + fputs("\n", md_result_file); if (mysql_query(sock, query)) { DBerror(sock, "when retrieving data from server"); @@ -1048,6 +1046,9 @@ static void dumpTable(uint numFields, char *table) return; } + if (opt_disable_keys) + fprintf(md_result_file,"/*!40000 ALTER TABLE %s DISABLE KEYS */;\n", + quote_name(table, table_buff)); if (opt_lock) fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", quote_name(table,table_buff)); @@ -1207,11 +1208,11 @@ static void dumpTable(uint numFields, char *table) safe_exit(EX_CONSCHECK); return; } - if (opt_disable_keys) - fprintf(md_result_file,"\n/*!40000 ALTER TABLE %s ENABLE KEYS */;\n", - quote_name(table,table_buff)); if (opt_lock) fputs("UNLOCK TABLES;\n", md_result_file); + if (opt_disable_keys) + fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n", + quote_name(table,table_buff)); if (opt_autocommit) fprintf(md_result_file, "commit;\n"); mysql_free_result(res); diff --git a/configure.in b/configure.in index 8c6249319fd..5e36c1446de 100644 --- a/configure.in +++ b/configure.in @@ -602,17 +602,22 @@ AC_ARG_WITH(mysqld-user, ) AC_SUBST(MYSQLD_USER) -# compile with strings functions in assembler +# If we should allove LOAD DATA LOCAL +AC_MSG_CHECKING(if we should should enable LOAD DATA LOCAL by default) AC_ARG_ENABLE(local-infile, [ --enable-local-infile If LOAD DATA LOCAL INFILE is enabled by default.], - [ - ENABLED_LOCAL_INFILE=$enablewal - AC_DEFINE(ENABLED_LOCAL_INFILE) - ], + [ ENABLED_LOCAL_INFILE=$enableval ], [ ENABLED_LOCAL_INFILE=no ] ) - +if test "$ENABLED_LOCAL_INFILE" = "yes" +then + AC_MSG_RESULT([yes]) + AC_DEFINE([ENABLED_LOCAL_INFILE]) +else + AC_MSG_RESULT([no]) +fi + # Use Paul Eggerts macros from GNU tar to check for large file support. MYSQL_SYS_LARGEFILE diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 4e4518bbe10..8c412f88ac7 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -737,7 +737,7 @@ static void mysql_read_default_options(struct st_mysql_options *options, *end=0; /* Remove '=' */ } /* Change all '_' in variable name to '-' */ - for (end= *option ; (end= strcend(end,'_')) && *end ; ) + for (end= *option ; *(end= strcend(end,'_')) ; ) *end= '-'; switch (find_type(*option+2,&option_types,2)) { case 1: /* port */ @@ -1338,7 +1338,7 @@ mysql_init(MYSQL *mysql) /* Only enable LOAD DATA INFILE by default if configured with - --with-enabled-local-inflile + --enable-local-infile */ #ifdef ENABLED_LOCAL_INFILE mysql->options.client_flag|= CLIENT_LOCAL_FILES; diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index c421d3b5578..ca546051290 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -193,7 +193,7 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 'i', 0, 0, 0, 0, 0, 0}, {"keys-used", "Tell MyISAM to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts!", (gptr*) &check_param.keys_in_use, (gptr*) &check_param.keys_in_use, 0, - GET_LL, REQUIRED_ARG, 'k', -1LL, 0, 0, 0, 0, 0}, + GET_LL, REQUIRED_ARG, 'k',-1, 0, 0, 0, 0, 0}, {"medium-check", "Faster than extended-check, but only finds 99.99% of all errors. Should be good enough for most cases.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'm', 0, 0, 0, 0, 0, 0}, diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index a017cf5a97e..efebc5b5c86 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -79,8 +79,10 @@ sleep_until_file_created () # No paths below as we can't be sure where the program is! -BASENAME=`which basename | head -1` -DIFF=`which diff | head -1` +SED=sed + +BASENAME=`which basename | $SED q` +DIFF=`which diff | $SED q` CAT=cat CUT=cut HEAD=head @@ -88,13 +90,12 @@ TAIL=tail ECHO=echo # use internal echo if possible EXPR=expr # use internal if possible FIND=find -GCOV=`which gcov | head -1` +GCOV=`which gcov | $SED q` PRINTF=printf RM=rm TIME=time TR=tr -XARGS=`which xargs | head -1` -SED=sed +XARGS=`which xargs | $SED q` # Are we using a source or a binary distribution? diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 21f87a11a53..e347a95b037 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -77,6 +77,7 @@ NULL NULL 10 VMT select id+0 as a,max(id),concat(facility) as b from t1 group by a order by b desc,a; a max(id) b +NULL NULL NULL 10 10 VMT 9 9 SRV 8 8 RV @@ -89,7 +90,6 @@ a max(id) b 1 1 /L -1 -1 0 0 -NULL NULL NULL select id >= 0 and id <= 5 as grp,count(*) from t1 group by grp; grp count(*) 0 7 @@ -336,3 +336,16 @@ a c 4 NULL 3 NULL drop table t1; +create table t1 (a char(1), key(a)) type=myisam; +insert into t1 values('1'),('1'); +select * from t1 where a >= '1'; +a +1 +1 +select distinct a from t1 order by a desc; +a +1 +select distinct a from t1 where a >= '1' order by a desc; +a +1 +drop table t1; diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 9845e12ef5f..2affdc1b653 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -226,7 +226,7 @@ key (score) INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3); explain select userid,count(*) from t1 group by userid desc; table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 6 Using temporary +t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort select userid,count(*) from t1 group by userid desc; userid count(*) 3 3 @@ -244,6 +244,8 @@ spid count(*) 2 2 select spid,count(*) from t1 where spid between 1 and 2 group by spid desc; spid count(*) +2 2 +1 1 explain select sql_big_result spid,sum(userid) from t1 group by spid desc; table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 6 Using filesort diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index df99f2545cb..a33ce457176 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -44,3 +44,22 @@ AND start <= 999660; id start end chr_strand 133197 813898 813898 -1.0000 drop table t1,t2; +CREATE TABLE t1 (Fld1 int(11) default NULL,Fld2 int(11) default NULL); +INSERT INTO t1 VALUES (1,10),(1,20),(2,NULL),(2,NULL),(3,50); +select Fld1, max(Fld2) as q from t1 group by Fld1 having q is not null; +Fld1 q +1 20 +3 50 +select Fld1, max(Fld2) from t1 group by Fld1 having max(Fld2) is not null; +Fld1 max(Fld2) +1 20 +3 50 +select Fld1, max(Fld2) from t1 group by Fld1 having avg(Fld2) is not null; +Fld1 max(Fld2) +1 20 +3 50 +select Fld1, max(Fld2) from t1 group by Fld1 having std(Fld2) is not null; +Fld1 max(Fld2) +1 20 +3 50 +drop table t1; diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 642a8a7004d..214328eab47 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -59,3 +59,15 @@ date_add(date,INTERVAL 1 DAY) date_add(date,INTERVAL 1 SECOND) 2000-08-11 2000-08-10 00:00:01 2000-08-12 2000-08-11 00:00:01 drop table t1; +CREATE TABLE t1(AFIELD INT); +INSERT INTO t1 VALUES(1); +CREATE TABLE t2(GMT VARCHAR(32)); +INSERT INTO t2 VALUES('GMT-0800'); +SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) FROM t1, t2 GROUP BY t1.AFIELD; +DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) +Wed, 06 March 2002 10:11:12 GMT-0800 +INSERT INTO t1 VALUES(1); +SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)), DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) FROM t1,t2 GROUP BY t1.AFIELD; +DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) +Wed, 06 March 2002 10:11:12 GMT-0800 Wed, 06 March 2002 10:11:12 GMT-0800 +drop table t1,t2; diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index bf8a03ac40d..b850ec5d562 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -207,3 +207,14 @@ insert into t1 (a) values (1),(2),(3),(4),(1),(2),(3),(4); select distinct a from t1 group by b,a having a > 2 order by a desc; select distinct a,c from t1 group by b,c,a having a > 2 order by a desc; drop table t1; + +# +# Test problem with DISTINCT and ORDER BY DESC +# + +create table t1 (a char(1), key(a)) type=myisam; +insert into t1 values('1'),('1'); +select * from t1 where a >= '1'; +select distinct a from t1 order by a desc; +select distinct a from t1 where a >= '1' order by a desc; +drop table t1; diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index fff5415976c..8dd7606d82b 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -48,3 +48,15 @@ GROUP BY e.id HAVING chr_strand= -1 and end >= 0 AND start <= 999660; drop table t1,t2; + +# +# Test problem with having and MAX() IS NOT NULL +# + +CREATE TABLE t1 (Fld1 int(11) default NULL,Fld2 int(11) default NULL); +INSERT INTO t1 VALUES (1,10),(1,20),(2,NULL),(2,NULL),(3,50); +select Fld1, max(Fld2) as q from t1 group by Fld1 having q is not null; +select Fld1, max(Fld2) from t1 group by Fld1 having max(Fld2) is not null; +select Fld1, max(Fld2) from t1 group by Fld1 having avg(Fld2) is not null; +select Fld1, max(Fld2) from t1 group by Fld1 having std(Fld2) is not null; +drop table t1; diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 0d2e18bcc94..68c2d55aac9 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -62,3 +62,16 @@ create table t1 (date date); insert into t1 values ("2000-08-10"),("2000-08-11"); select date_add(date,INTERVAL 1 DAY),date_add(date,INTERVAL 1 SECOND) from t1; drop table t1; + +# +# Test problem with DATE_FORMAT +# + +CREATE TABLE t1(AFIELD INT); +INSERT INTO t1 VALUES(1); +CREATE TABLE t2(GMT VARCHAR(32)); +INSERT INTO t2 VALUES('GMT-0800'); +SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) FROM t1, t2 GROUP BY t1.AFIELD; +INSERT INTO t1 VALUES(1); +SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)), DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) FROM t1,t2 GROUP BY t1.AFIELD; +drop table t1,t2; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index a28d3dd4e3c..5ec26e3de3f 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -14,7 +14,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <my_config.h> #include <my_global.h> #include <m_string.h> #include <stdlib.h> @@ -452,7 +451,7 @@ static void init_variables(const struct my_option *options) { if (options->var_type == GET_LONG) *((long*) options->u_max_value)= *((long*) options->value)= - options->def_value; + (long) options->def_value; else if (options->var_type == GET_LL) *((longlong*) options->u_max_value)= *((longlong*) options->value)= options->def_value; diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 5504d929ede..e6ecbf6f729 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -291,7 +291,7 @@ do I=1 while test "$I" -le "$numofproces" do - PROC=`ps xa | grep $ledir/$MYSQLD | grep -v "grep" | tail -1` + PROC=`ps xa | grep $ledir/$MYSQLD | grep -v "grep" | sed -n '$p'` for T in $PROC do break diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index 063ff8be750..642b1fb78c9 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -37,7 +37,7 @@ WARNING: THIS PROGRAM IS STILL IN BETA. Comments/patches welcome. # Documentation continued at end of file -my $VERSION = "1.14"; +my $VERSION = "1.15"; my $opt_tmpdir = $ENV{TMPDIR} || "/tmp"; @@ -562,7 +562,7 @@ sub copy_files { # add recursive option for scp push @cp, "-r" if $^O =~ /m^(solaris|linux|freebsd)$/ && $method =~ /^scp\b/; - my @non_raid = grep { $_ !~ m:\d\d/: } @$files; + my @non_raid = grep { ! m:/\d{2}/[^/]+$: } @$files; # add files to copy and the destination directory safe_system( @cp, @non_raid, $target ); diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh index b8c37e5922e..a4e74fcb4f9 100644 --- a/sql-bench/server-cfg.sh +++ b/sql-bench/server-cfg.sh @@ -958,7 +958,7 @@ sub version { if ($dir && -e "$dir/bin/solcon") { - $version=`$dir/bin/solcon -e"ver" $main::opt_user $main::opt_password | grep Server | head -1`; + $version=`$dir/bin/solcon -e"ver" $main::opt_user $main::opt_password | grep Server | sed q`; if ($? == 0) { chomp($version); diff --git a/sql/filesort.cc b/sql/filesort.cc index a5f42d5731e..7e3d1c96f57 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -452,10 +452,7 @@ static void make_sortkey(register SORTPARAM *param, { if (field->is_null()) { - if (sort_field->reverse) - bfill(to,sort_field->length+1,(char) 255); - else - bzero((char*) to,sort_field->length+1); + bzero((char*) to,sort_field->length+1); to+= sort_field->length+1; continue; } diff --git a/sql/item.h b/sql/item.h index 5028f25c6b8..660a36ee967 100644 --- a/sql/item.h +++ b/sql/item.h @@ -343,6 +343,11 @@ public: null_value=(*ref)->null_value; return tmp; } + bool is_null() + { + (void) (*ref)->val_int_result(); + return (*ref)->null_value; + } bool get_date(TIME *ltime,bool fuzzydate) { return (null_value=(*ref)->get_date(ltime,fuzzydate)); diff --git a/sql/item_sum.h b/sql/item_sum.h index 4840ae8298d..a963799b6a7 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -64,6 +64,7 @@ public: { return new Item_field(field);} table_map used_tables() const { return ~(table_map) 0; } /* Not used */ bool const_item() const { return 0; } + bool is_null() { return null_value; } void update_used_tables() { } void make_field(Send_field *field); void print(String *str); @@ -202,6 +203,7 @@ public: enum Type type() const { return FIELD_AVG_ITEM; } double val(); longlong val_int() { return (longlong) val(); } + bool is_null() { (void) val_int(); return null_value; } String *val_str(String*); void make_field(Send_field *field); void fix_length_and_dec() {} @@ -239,6 +241,7 @@ public: double val(); longlong val_int() { return (longlong) val(); } String *val_str(String*); + bool is_null() { (void) val_int(); return null_value; } void make_field(Send_field *field); void fix_length_and_dec() {} }; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 8f55a02b020..9a003b79609 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -672,7 +672,7 @@ String *Item_func_date_format::val_str(String *str) else size=format_length(format); if (format == str) - str= &str_value; // Save result here + str= &value; // Save result here if (str->alloc(size)) { null_value=1; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 32b85e7f028..aa4140192ab 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -333,6 +333,7 @@ class Item_func_date_format :public Item_str_func { int fixed_length; const bool date_or_time; + String value; public: Item_func_date_format(Item *a,Item *b,bool date_or_time_arg) :Item_str_func(a,b),date_or_time(date_or_time_arg) {} diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 187a4732aa0..b754d4458cc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -484,11 +484,25 @@ static void close_connections(void) #ifdef __NT__ if ( hPipe != INVALID_HANDLE_VALUE ) { - HANDLE hTempPipe = &hPipe; + HANDLE temp; DBUG_PRINT( "quit", ("Closing named pipes") ); - hPipe = INVALID_HANDLE_VALUE; - DisconnectNamedPipe( hTempPipe ); - CloseHandle( hTempPipe ); + + /* Create connection to the handle named pipe handler to break the loop */ + if ((temp = CreateFile(szPipeName, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL )) != INVALID_HANDLE_VALUE) + { + WaitNamedPipe(szPipeName, 1000); + DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT; + SetNamedPipeHandleState(temp, &dwMode, NULL, NULL); + CancelIo(temp); + DisconnectNamedPipe(temp); + CloseHandle(temp); + } } #endif #ifdef HAVE_SYS_UN_H @@ -771,8 +785,10 @@ void clean_up(bool print_message) my_free(opt_ssl_ca,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_ssl_capath,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_ssl_cipher,MYF(MY_ALLOW_ZERO_PTR)); + my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); opt_ssl_key=opt_ssl_cert=opt_ssl_ca=opt_ssl_capath=0; #endif /* HAVE_OPENSSL */ + free_defaults(defaults_argv); my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR)); my_free(allocated_mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); @@ -1775,7 +1791,8 @@ int main(int argc, char **argv) if (opt_use_ssl) { ssl_acceptor_fd = new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, - opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); + opt_ssl_ca, opt_ssl_capath, + opt_ssl_cipher); DBUG_PRINT("info",("ssl_acceptor_fd: %p",ssl_acceptor_fd)); if (!ssl_acceptor_fd) opt_use_ssl = 0; @@ -1906,6 +1923,14 @@ The server will not act as a slave."); if (opt_slow_log) open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", LOG_NORMAL); +#ifdef __WIN__ +#define MYSQL_ERR_FILE "mysql.err" + if (!opt_console) + { + freopen(MYSQL_ERR_FILE,"a+",stdout); + freopen(MYSQL_ERR_FILE,"a+",stderr); + } +#endif if (ha_init()) { sql_print_error("Can't init databases"); @@ -1931,13 +1956,8 @@ The server will not act as a slave."); ft_init_stopwords(ft_precompiled_stopwords); #ifdef __WIN__ -#define MYSQL_ERR_FILE "mysql.err" if (!opt_console) - { - freopen(MYSQL_ERR_FILE,"a+",stdout); - freopen(MYSQL_ERR_FILE,"a+",stderr); FreeConsole(); // Remove window - } #endif /* @@ -2023,7 +2043,7 @@ The server will not act as a slave."); #ifdef __NT__ if (hPipe == INVALID_HANDLE_VALUE && !have_tcpip) { - sql_print_error("TCP/IP must be installed on Win98 platforms"); + sql_print_error("TCP/IP or Named Pipes should be installed on NT OS"); } else { @@ -2082,42 +2102,26 @@ The server will not act as a slave."); #ifdef EXTRA_DEBUG2 sql_print_error("After lock_thread_count"); #endif -#else -#if !defined(EMBEDDED_LIBRARY) - if (Service.IsNT()) - { - if(start_mode) - { - if (WaitForSingleObject(hEventShutdown,1000)==WAIT_TIMEOUT) - Service.Stop(); - } - else - { - Service.SetShutdownEvent(0); - if(hEventShutdown) CloseHandle(hEventShutdown); - } - } - else - { - Service.SetShutdownEvent(0); - if(hEventShutdown) CloseHandle(hEventShutdown); - } -#endif -#endif -#ifdef HAVE_OPENSSL - my_free((gptr)ssl_acceptor_fd,MYF(MY_ALLOW_ZERO_PTR)); -#endif /* HAVE_OPENSSL */ +#endif /* __WIN__ */ + /* Wait until cleanup is done */ (void) pthread_mutex_lock(&LOCK_thread_count); - DBUG_PRINT("quit", ("Got thread_count mutex for clean up wait")); - while (!ready_to_exit) { - DBUG_PRINT("quit", ("not yet ready to exit")); pthread_cond_wait(&COND_thread_count,&LOCK_thread_count); } - DBUG_PRINT("quit", ("ready to exit")); (void) pthread_mutex_unlock(&LOCK_thread_count); + +#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) + if (Service.IsNT() && start_mode) + Service.Stop(); + else + { + Service.SetShutdownEvent(0); + if (hEventShutdown) + CloseHandle(hEventShutdown); + } +#endif my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(0); return(0); /* purecov: deadcode */ diff --git a/sql/opt_range.cc b/sql/opt_range.cc index c3f4c91b718..20f198182f4 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2523,13 +2523,13 @@ int QUICK_SELECT::cmp_next(QUICK_RANGE *range) /* - * This is a hack: we inherit from QUICK_SELECT so that we can use the - * get_next() interface, but we have to hold a pointer to the original - * QUICK_SELECT because its data are used all over the place. What - * should be done is to factor out the data that is needed into a base - * class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC) - * which handle the ranges and implement the get_next() function. But - * for now, this seems to work right at least. + This is a hack: we inherit from QUICK_SELECT so that we can use the + get_next() interface, but we have to hold a pointer to the original + QUICK_SELECT because its data are used all over the place. What + should be done is to factor out the data that is needed into a base + class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC) + which handle the ranges and implement the get_next() function. But + for now, this seems to work right at least. */ QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts) @@ -2538,6 +2538,7 @@ QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts) bool not_read_after_key = file->option_flag() & HA_NOT_READ_AFTER_KEY; QUICK_RANGE *r; + it.rewind(); for (r = it++; r; r = it++) { rev_ranges.push_front(r); diff --git a/sql/opt_range.h b/sql/opt_range.h index 83eb10235ea..f48a3936a17 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -77,6 +77,7 @@ public: void reset(void) { next=0; it.rewind(); } int init() { return error=file->index_init(index); } virtual int get_next(); + virtual bool reverse_sorted() { return 0; } int cmp_next(QUICK_RANGE *range); bool unique_key_range(); }; @@ -87,6 +88,7 @@ class QUICK_SELECT_DESC: public QUICK_SELECT public: QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts); int get_next(); + bool reverse_sorted() { return 1; } private: int cmp_prev(QUICK_RANGE *range); bool range_reads_after_key(QUICK_RANGE *range); @@ -96,6 +98,7 @@ private: List_iterator<QUICK_RANGE> rev_it; }; + class SQL_SELECT :public Sql_alloc { public: QUICK_SELECT *quick; // If quick-select used diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index c5782f65798..869be5b327d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -221,6 +221,8 @@ int acl_init(bool dont_read_acl_tables) user.x509_issuer=get_field(&mem, table, 19); user.x509_subject=get_field(&mem, table, 20); } + else + user.ssl_type=SSL_TYPE_NONE; #endif /* HAVE_OPENSSL */ if (user.password && (length=(uint) strlen(user.password)) == 8 && protocol_version == PROTOCOL_VERSION) @@ -1201,7 +1203,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, /* We write down SSL related ACL stuff */ DBUG_PRINT("info",("table->fields=%d",table->fields)); if (table->fields >= 21) /* From 4.0.0 we have more fields */ - { + { table->field[18]->store("",0); table->field[19]->store("",0); table->field[20]->store("",0); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d28ad9eaaa5..f4a70db2e5d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -273,7 +273,6 @@ void intern_close_table(TABLE *table) free_io_cache(table); if (table->file) VOID(closefrm(table)); // close file - hash_free(&table->name_hash); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 284f6304e07..a5ca249d590 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -612,8 +612,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, HA_POS_ERROR : thd->select_limit,0)))) order=0; select_describe(&join,need_tmp, - (order != 0 && - (!need_tmp || order != group || simple_group)), + order != 0 && !skip_sort_order, select_distinct); error=0; goto err; @@ -5451,7 +5450,16 @@ static uint find_shortest_key(TABLE *table, key_map usable_keys) } -/* Return 1 if we don't have to do file sorting */ +/* + Test if we can skip the ORDER BY by using an index. + + If we can use an index, the JOIN_TAB / tab->select struct + is changed to use the index. + + Return: + 0 We have to use filesort to do the sorting + 1 We can use an index. +*/ static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, @@ -5497,15 +5505,22 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, { if (select && select->quick) { - // ORDER BY range_key DESC - QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC(select->quick, - used_key_parts); - if (!tmp || tmp->error) + /* + Don't reverse the sort order, if it's already done. + (In some cases test_if_order_by_key() can be called multiple times + */ + if (!select->quick->reverse_sorted()) { - delete tmp; - DBUG_RETURN(0); // Reverse sort not supported + // ORDER BY range_key DESC + QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC(select->quick, + used_key_parts); + if (!tmp || tmp->error) + { + delete tmp; + DBUG_RETURN(0); // Reverse sort not supported + } + select->quick=tmp; } - select->quick=tmp; DBUG_RETURN(1); } if (tab->ref.key_parts < used_key_parts) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b12dd07777f..f01c2892edc 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -32,7 +32,7 @@ extern void yyerror(const char*); int yylex(void *yylval); -#define yyoverflow(A,B,C,D,E,F) if (my_yyoverflow((B),(D),(F))) { yyerror((char*) (A)); return 2; } +#define yyoverflow(A,B,C,D,E,F) if (my_yyoverflow((B),(D),(int*) (F))) { yyerror((char*) (A)); return 2; } inline Item *or_or_concat(Item* A, Item* B) { diff --git a/sql/table.cc b/sql/table.cc index 1844c869431..b1cd63d465a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -576,6 +576,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, delete outparam->file; outparam->file=0; // For easyer errorchecking outparam->db_stat=0; + hash_free(&outparam->name_hash); free_root(&outparam->mem_root,MYF(0)); my_free(outparam->table_name,MYF(MY_ALLOW_ZERO_PTR)); DBUG_RETURN (error); @@ -603,6 +604,7 @@ int closefrm(register TABLE *table) } delete table->file; table->file=0; /* For easyer errorchecking */ + hash_free(&table->name_hash); free_root(&table->mem_root,MYF(0)); DBUG_RETURN(error); } 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 */ - -/* Optimized string functions Intel 80x86 (gcc/gas syntax) */ - - .file "strings.s" +# 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) + + .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 */ - - 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. */ + 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. + + 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. */ - -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 $ */ + 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 $ 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 */ - -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 */ + 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 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 |