summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2001-11-04 16:14:09 +0200
committerunknown <monty@hundin.mysql.fi>2001-11-04 16:14:09 +0200
commit0d1ba873aa11ea581ebbda9f450027329f2e1a3b (patch)
tree689c9d0271e23431f1ab0ac09e1af4d68a58ca76
parent9f90ff3f12f1fc2bcb70cde74dbd6f27e33e230c (diff)
parent0176dacd54b7eb62ebc4a81909b189517aee2cb4 (diff)
downloadmariadb-git-0d1ba873aa11ea581ebbda9f450027329f2e1a3b.tar.gz
merge with 3.23.44
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union Docs/manual.texi: Auto merged include/my_base.h: Auto merged mysql-test/t/func_time.test: Auto merged mysql-test/t/join.test: Auto merged mysql-test/t/rpl000012.test: Auto merged BUILD/FINISH.sh: Auto merged BitKeeper/deleted/.del-db_ext.h~a1e210bbd0de0a48: Auto merged BitKeeper/deleted/.del-mutex_ext.h~f20f47ddc346598b: Auto merged BitKeeper/deleted/.del-violite.c~984c09cffe14a11b: Auto merged BitKeeper/deleted/.del-violite.c~d7b85be615595ace: Auto merged Build-tools/Do-all-build-steps: Auto merged client/client_priv.h: Auto merged client/mysqladmin.c: Auto merged innobase/include/srv0srv.h: Auto merged innobase/include/univ.i: Auto merged innobase/log/log0log.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/srv/srv0start.c: Auto merged isam/pack_isam.c: Auto merged libmysql_r/Makefile.am: Auto merged myisam/myisamchk.c: Auto merged mysql-test/t/having.test: Auto merged mysql-test/t/rpl000015-slave.sh: Auto merged mysql-test/t/rpl000016-slave.sh: Auto merged mysys/mf_cache.c: Auto merged mysys/mf_casecnv.c: Auto merged mysys/mf_tempfile.c: Auto merged readline/vi_mode.c: Auto merged strings/strto.c: Auto merged sql/field.cc: Auto merged sql/field.h: Auto merged sql/ha_berkeley.cc: Auto merged sql/ha_myisammrg.cc: Auto merged sql/handler.cc: Auto merged sql/item.h: Auto merged sql/log_event.cc: Auto merged sql/sql_acl.cc: Auto merged sql/time.cc: Auto merged BUILD/SETUP.sh: Use -mcpu as default (safe for all x86 cpu's) client/mysqldump.c: Merge from 3.23.44 configure.in: Update version number extra/resolveip.c: Portability fix
-rw-r--r--.bzrignore32
-rw-r--r--BUILD/FINISH.sh2
-rw-r--r--BUILD/SETUP.sh13
-rwxr-xr-xBuild-tools/Do-all-build-steps2
-rw-r--r--Docs/manual.texi132
-rw-r--r--client/client_priv.h1
-rw-r--r--client/mysqladmin.c4
-rw-r--r--client/mysqldump.c11
-rw-r--r--configure.in8
-rw-r--r--extra/resolveip.c6
-rw-r--r--include/my_base.h3
-rw-r--r--innobase/btr/btr0btr.c148
-rw-r--r--innobase/buf/buf0flu.c11
-rw-r--r--innobase/buf/buf0lru.c68
-rw-r--r--innobase/dict/dict0boot.c59
-rw-r--r--innobase/dict/dict0crea.c6
-rw-r--r--innobase/dict/dict0dict.c62
-rw-r--r--innobase/ibuf/ibuf0ibuf.c2
-rw-r--r--innobase/include/dict0boot.h4
-rw-r--r--innobase/include/dict0boot.ic52
-rw-r--r--innobase/include/dict0dict.h9
-rw-r--r--innobase/include/os0file.h4
-rw-r--r--innobase/include/os0sync.h2
-rw-r--r--innobase/include/page0page.ic39
-rw-r--r--innobase/include/read0read.h7
-rw-r--r--innobase/include/row0mysql.h6
-rw-r--r--innobase/include/srv0srv.h35
-rw-r--r--innobase/include/srv0start.h11
-rw-r--r--innobase/include/trx0purge.h6
-rw-r--r--innobase/include/trx0rec.h7
-rw-r--r--innobase/include/trx0trx.h13
-rw-r--r--innobase/include/univ.i6
-rw-r--r--innobase/lock/lock0lock.c8
-rw-r--r--innobase/log/log0log.c17
-rw-r--r--innobase/log/log0recv.c35
-rw-r--r--innobase/os/os0file.c138
-rw-r--r--innobase/page/page0page.c53
-rw-r--r--innobase/read/read0read.c40
-rw-r--r--innobase/rem/rem0cmp.c2
-rw-r--r--innobase/rem/rem0rec.c20
-rw-r--r--innobase/row/row0ins.c7
-rw-r--r--innobase/row/row0mysql.c40
-rw-r--r--innobase/row/row0purge.c19
-rw-r--r--innobase/row/row0row.c19
-rw-r--r--innobase/row/row0sel.c10
-rw-r--r--innobase/row/row0umod.c18
-rw-r--r--innobase/row/row0upd.c30
-rw-r--r--innobase/row/row0vers.c2
-rw-r--r--innobase/srv/srv0srv.c263
-rw-r--r--innobase/srv/srv0start.c94
-rw-r--r--innobase/sync/sync0arr.c15
-rw-r--r--innobase/trx/trx0purge.c37
-rw-r--r--innobase/trx/trx0rec.c148
-rw-r--r--innobase/trx/trx0roll.c16
-rw-r--r--innobase/trx/trx0sys.c4
-rw-r--r--innobase/trx/trx0trx.c40
-rw-r--r--innobase/trx/trx0undo.c10
-rw-r--r--innobase/ut/ut0mem.c4
-rw-r--r--isam/create.c11
-rw-r--r--isam/pack_isam.c2
-rw-r--r--libmysql/Makefile.am2
-rw-r--r--libmysql/configure.in230
-rw-r--r--libmysql_r/Makefile.am2
-rw-r--r--myisam/mi_log.c2
-rw-r--r--myisam/myisamchk.c4
-rw-r--r--myisam/myisampack.c4
-rw-r--r--mysql-test/r/func_time.result167
-rw-r--r--mysql-test/r/having.result9
-rw-r--r--mysql-test/r/join.result88
-rw-r--r--mysql-test/t/func_time.test19
-rw-r--r--mysql-test/t/having.test42
-rw-r--r--mysql-test/t/join.test14
-rw-r--r--mysql-test/t/rpl000012.test1
-rwxr-xr-xmysql-test/t/rpl000015-slave.sh2
-rwxr-xr-xmysql-test/t/rpl000016-slave.sh2
-rw-r--r--mysys/mf_cache.c4
-rw-r--r--mysys/mf_tempfile.c3
-rw-r--r--mysys/my_compress.c2
-rw-r--r--mysys/my_os2file64.c58
-rw-r--r--mysys/my_tempnam.c14
-rw-r--r--os2/BldLevel.cmd10
-rw-r--r--os2/BldLevel.rc1
-rw-r--r--os2/BldLevelInf.cmd570
-rw-r--r--os2/ChangeLog.os210
-rw-r--r--os2/MySQL-Client.icc46
-rw-r--r--os2/MySQL-Opt.icc47
-rw-r--r--os2/MySQL-Source.icc81
-rw-r--r--os2/MySQL-Sql.icc89
-rw-r--r--os2/MySQL-Util.icc80
-rw-r--r--os2/ReadMe.txt177
-rw-r--r--os2/mysql-inf.wis15
-rw-r--r--os2/mysql.wis127
-rw-r--r--os2/mysqlalt.wis15
-rw-r--r--readline/vi_mode.c2
-rw-r--r--sql/field.cc42
-rw-r--r--sql/field.h17
-rw-r--r--sql/ha_berkeley.cc14
-rw-r--r--sql/ha_innobase.cc259
-rw-r--r--sql/ha_innobase.h10
-rw-r--r--sql/ha_myisammrg.cc4
-rw-r--r--sql/handler.cc9
-rw-r--r--sql/item.h1
-rw-r--r--sql/item_timefunc.cc4
-rw-r--r--sql/log.cc58
-rw-r--r--sql/mysqld.cc52
-rw-r--r--sql/nt_servc.cc380
-rw-r--r--sql/nt_servc.h3
-rwxr-xr-xsql/share/norwegian-ny/.cvsignore1
-rwxr-xr-xsql/share/norwegian/.cvsignore1
-rw-r--r--sql/sql_lex.cc27
-rw-r--r--sql/sql_select.cc51
-rw-r--r--sql/time.cc6
-rw-r--r--strings/ctype.c1
-rw-r--r--strings/strto.c2
-rw-r--r--strings/t_ctype.h8
115 files changed, 3380 insertions, 1382 deletions
diff --git a/.bzrignore b/.bzrignore
index 41303ef4ba6..6113e896ea7 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -120,17 +120,32 @@ bdb/dist/template/rec_txn
bdb/examples_java
bdb/hash/hash_auto.c
bdb/include/btree_auto.h
+bdb/include/btree_ext.h
+bdb/include/clib_ext.h
+bdb/include/common_ext.h
bdb/include/crdel_auto.h
bdb/include/db_auto.h
+bdb/include/db_ext.h
bdb/include/db_server.h
+bdb/include/env_ext.h
bdb/include/gen_client_ext.h
bdb/include/gen_server_ext.h
bdb/include/hash_auto.h
+bdb/include/hash_ext.h
+bdb/include/lock_ext.h
bdb/include/log_auto.h
+bdb/include/log_ext.h
+bdb/include/mp_ext.h
+bdb/include/mutex_ext.h
+bdb/include/os_ext.h
bdb/include/qam_auto.h
+bdb/include/qam_ext.h
bdb/include/rpc_client_ext.h
bdb/include/rpc_server_ext.h
+bdb/include/tcl_ext.h
bdb/include/txn_auto.h
+bdb/include/txn_ext.h
+bdb/include/xa_ext.h
bdb/java/src/com/sleepycat/db/DbConstants.java
bdb/log/log_auto.c
bdb/qam/qam_auto.c
@@ -250,6 +265,7 @@ libmysqld/lock.cc
libmysqld/log.cc
libmysqld/log_event.cc
libmysqld/md5.c
+libmysqld/mf_iocache.cc
libmysqld/mini_client.cc
libmysqld/net_pkg.cc
libmysqld/net_serv.cc
@@ -424,19 +440,3 @@ vio/test-ssl
vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
-libmysqld/mf_iocache.cc
-bdb/include/btree_ext.h
-bdb/include/clib_ext.h
-bdb/include/common_ext.h
-bdb/include/db_ext.h
-bdb/include/env_ext.h
-bdb/include/hash_ext.h
-bdb/include/lock_ext.h
-bdb/include/log_ext.h
-bdb/include/mp_ext.h
-bdb/include/mutex_ext.h
-bdb/include/os_ext.h
-bdb/include/qam_ext.h
-bdb/include/tcl_ext.h
-bdb/include/txn_ext.h
-bdb/include/xa_ext.h
diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh
index 5e0ca925de1..2e2ba1f7358 100644
--- a/BUILD/FINISH.sh
+++ b/BUILD/FINISH.sh
@@ -20,7 +20,7 @@ then
(cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
fi
-CFLAGS=\"$cflags\" CXX=gcc CXXFLAGS=\"$cxxflags\" $configure"
+CFLAGS=\"$cflags\" CXX=$CXX CXXFLAGS=\"$cxxflags\" $configure"
if [ -z "$just_configure" ]
then
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index fdd0154fc99..f878123db59 100644
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -35,12 +35,12 @@ AM_MAKEFLAGS="-j 4"
# -Wshadow -Wunused -Winline (The later isn't usable in C++ as
# __attribute()__ doesn't work with gnu C++)
global_warnings="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings"
-debug_extra_warnings="-Wuninitialized"
+#debug_extra_warnings="-Wuninitialized"
c_warnings="$global_warnings -Wunused"
cxx_warnings="$global_warnings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor"
alpha_cflags="-mcpu=ev6 -Wa,-mev6" # Not used yet
-pentium_cflags=""
+pentium_cflags="-mcpu=pentiumpro"
sparc_cflags=""
# be as fast as we can be without losing our ability to backtrace
@@ -48,7 +48,7 @@ fast_cflags="-O3 -fno-omit-frame-pointer"
# this is one is for someone who thinks 1% speedup is worth not being
# able to backtrace
reckless_cflags="-O3 -fomit-frame-pointer "
-debug_cflags="-DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DSAFE_MUTEX -O2"
+debug_cflags="-DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DSAFE_MUTEX -O1"
base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti"
@@ -66,3 +66,10 @@ then
else
make=make
fi
+
+if gcc -v 2>&1 | grep 'version 3' > /dev/null 2>&1
+then
+ CXX=c++
+else
+ CXX=gcc
+fi
diff --git a/Build-tools/Do-all-build-steps b/Build-tools/Do-all-build-steps
index ad3868733fa..48461c31508 100755
--- a/Build-tools/Do-all-build-steps
+++ b/Build-tools/Do-all-build-steps
@@ -18,7 +18,7 @@ to_host=`hostname`
cc=gcc
ccc=gcc
EXTRA_CONFIG="--without-perl"
-AM_MAKEFLAGS="-j 2"
+#AM_MAKEFLAGS="-j 2"
echo "Building on $to_host"
rm -rf $BD/*
diff --git a/Docs/manual.texi b/Docs/manual.texi
index ec1e0c2d05f..2658bf26394 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -5772,9 +5772,6 @@ Change sort to allocate memory in ``hunks'' to get better memory utilisation.
@code{Field_decimal::store(const char *from,uint len)} must be recoded
to fix this.
@item
-Fix @code{mysql.cc} to do fewer @code{malloc()} calls when hashing field
-names.
-@item
Functions:
ADD_TO_SET(value,set) and REMOVE_FROM_SET(value,set)
@item
@@ -5809,8 +5806,6 @@ join type.
@item
Oracle like @code{CONNECT BY PRIOR ...} to search hierarchy structures.
@item
-@code{RENAME DATABASE}
-@item
@code{mysqladmin copy database new-database}. -- Requires COPY command to be
added to @code{mysqld}
@item
@@ -24006,7 +24001,7 @@ By default, the @code{mysql.server} script starts the MySQL
server with the @code{-l} option. If you need better performance when
you start using MySQL in a production environment, you can
remove the @code{-l} option from @code{mysql.server} or change it to
-@code{--log-binary}.
+@code{--log-bin}.
The entries in this log are written as @code{mysqld} receives the questions.
This may be different than the order in which the statements are executed.
@@ -24080,8 +24075,8 @@ and the crash.
@cindex binary log
@cindex files, binary log
-In the future the binary log will replace the update log, so we
-recommend you to switch to this log format as soon as possible!
+The intention is that the binary log should replace the update log, so
+we recommend you to switch to this log format as soon as possible!
The binary log contains all information that is available in the update
log in a more efficient format. It also contains information about how long
@@ -24096,6 +24091,14 @@ file name is given, it defaults to the name of the host machine followed
by @code{-bin}. If file name is given, but it doesn't contain a path, the
file is written in the data directory.
+If you supply an extension to @code{--log-bin=filename.extension}, the
+extension will be silenty removed.
+
+To the binary log filename @code{mysqld} will append an extension that is a
+number that is incremented each time you execute @code{mysqladmin
+refresh}, execute @code{mysqladmin flush-logs}, execute the @code{FLUSH LOGS}
+statement or restart the server.
+
You can use the following options to @code{mysqld} to affect what is logged
to the binary log:
@@ -24110,11 +24113,6 @@ Tells the master that updates to the given database should not be logged
to the binary log (Example: @code{binlog-ignore-db=some_database})
@end multitable
-To the binary log filename @code{mysqld} will append an extension that is a
-number that is incremented each time you execute @code{mysqladmin
-refresh}, execute @code{mysqladmin flush-logs}, execute the @code{FLUSH LOGS}
-statement or restart the server.
-
To be able to know which different binary log files have been used,
@code{mysqld} will also create a binary log index file that
contains the name of all used binary log files. By default this has the
@@ -48950,6 +48948,7 @@ users use this code as the rest of the code and because of this we are
not yet 100% confident in this code.
@menu
+* News-3.23.45:: Changes in release 3.23.45
* News-3.23.44:: Changes in release 3.23.44
* News-3.23.43:: Changes in release 3.23.43
* News-3.23.42:: Changes in release 3.23.42
@@ -48998,10 +48997,42 @@ not yet 100% confident in this code.
* News-3.23.0:: Changes in release 3.23.0
@end menu
-@node News-3.23.44, News-3.23.43, News-3.23.x, News-3.23.x
+@node News-3.23.45, News-3.23.44, News-3.23.x, News-3.23.x
+@appendixsubsec Changes in release 3.23.45
+@itemize @bullet
+@item
+Fixed problem with @code{t1 LEFT_JOIN t2 ... WHERE t2.date_column IS NULL} when
+date_column was declared as @code{NOT NULL}.
+@item
+Fixed bug with BDB tables and keys on @code{BLOB}'s.
+@item
+Fixed bug in @code{MERGE} tables on OS with 32 bit file pointers.
+@item
+Fixed bug in @code{TIME_TO_SEC()} when using negative values.
+@end itemize
+
+@node News-3.23.44, News-3.23.43, News-3.23.45, News-3.23.x
@appendixsubsec Changes in release 3.23.44
@itemize @bullet
@item
+Fixed @code{Rows_examined} count in slow query log.
+@item
+Fixed bug when using a reference to a @code{AVG()} column in @code{HAVING}.
+@item
+Fixed that date functions that require correct dates, like
+@code{DAYOFYEAR(column)} will return @code{NULL} for @code{0000-00-00} dates.
+@item
+Fixed bug in const-propagation when comparing columns of different
+types. (@code{SELECT * FROM date_col="2001-01-01" and date_col=time_col})
+@item
+Fixed bug that caused error message @code{Can't write, because of unique
+constraint} with some @code{GROUP BY} queries.
+@item
+Fixed problem with sjis character strings used within quoted table names.
+@item
+Fixed coredump when using @code{CREATE ... FULLTEXT} keys with other table
+handlers than MyISAM.
+@item
Don't use @code{signal()} on windows because this appears to not be
100 % reliable.
@item
@@ -49011,9 +49042,62 @@ that had @code{NULL} values.
Fixed bug when doing @code{LEFT JOIN ... ON (column_name = constant) WHERE column_name = constant}.
@item
When using replications, aborted queries that contained @code{%} could cause
-a core dum.
+a core dump.
+@item
+@code{TCP_NODELAY} was not used on some systems. (Speed problem).
+@item
+Applied portability fixes for OS/2 (Patch by Yuri Dario).
+@end itemize
+
+The following changes are for @code{InnoDB} tables:
+
+@itemize @bullet
+@item
+Add missing @code{InnoDB} variables to @code{SHOW VARIABLES}.
+@item
+Foreign keys checking is now done for @code{InnoDB} tables.
+@item
+@code{DROP DATABASE} now works also for @code{InnoDB} tables.
+@item
+@code{InnoDB} now supports data files and raw disk partitions bigger
+than 4 GB on those operating systems which have big files.
+@item
+@code{InnoDB} calculates better table cardinality estimates for the
+MySQL optimizer.
+@item
+Accent characters in the default character set latin1 are ordered
+according to the MySQL ordering.
+
+NOTE: if you are using latin1 and have inserted characters whose code is >
+127 to an indexed CHAR column, you should run CHECK TABLE on your table when
+you upgrade to 3.23.44, and drop and reimport the table if CHECK TABLE
+reports an error!
+@item
+A new @file{my.cnf} parameter @code{innodb_thread_concurrency} helps in
+performance tuning in heavily concurrent environments.
+@item
+A new @code{my.cnf} parameter @code{innodb_fast_shutdown} speeds up
+server shutdown.
+@item
+A new @code{my.cnf} parameter @code{innodb_force_recovery} helps to save
+your data in case the disk image of the database becomes corrupt.
+@item
+@code{innodb_monitor} has been improved and a new
+@code{innodb_table_monitor} added.
+@item
+Increased maximum key length from 500 to 7000 bytes.
+@item
+Fixed a bug in replication of auto-inc columns with multiline inserts.
+@item
+Fixed a bug when the case of letters changes in an update of an indexed
+secondary column.
+@item
+Fixed a hang when there are > 24 data files.
+@item
+Fixed a crash when @code{MAX(col)} is selected from an empty table, and
+col is a not the first column in a multi-column index.
@item
-TCP_NODELAY was not used on some systems. (Speed problem).
+Fixed a bug in purge which could cause crashes.
@end itemize
@node News-3.23.43, News-3.23.42, News-3.23.44, News-3.23.x
@@ -49117,15 +49201,15 @@ Fixed possible problem with @code{shutdown} on Solaris where the
@item
InnoDB now supports < 4 GB rows. The former limit was 8000 bytes.
@item
-The @code{doublewrite} file flush method is used in InnoDB.
+The @code{doublewrite} file flush method is used in @code{InnoDB}.
It reduces the need for Unix fsync calls to a fraction and
improves performance on most Unix flavors.
@item
-You can now use the InnoDB Monitor to print a lot of InnoDB state
+You can now use the @code{InnoDB} Monitor to print a lot of @code{InnoDB} state
information, including locks, to the standard output; useful in
performance tuning.
@item
-Several bugs which could cause hangs in InnoDB have been fixed.
+Several bugs which could cause hangs in @code{InnoDB} have been fixed.
@item
Split @code{record_buffer} to @code{record_buffer} and
@code{record_rnd_buffer}. To make things compatible to previous MySQL
@@ -49239,7 +49323,7 @@ Extended argument length in option files from 256 to 512 chars.
Fixed problem with shutdown when @code{INSERT DELAYED} was waiting for
a @code{LOCK TABLE}.
@item
-Fixed coredump bug in InnoDB when tablespace was full.
+Fixed coredump bug in @code{InnoDB} when tablespace was full.
@item
Fixed problem with @code{MERGE} tables and big tables (> 4G) when using
@code{ORDER BY}.
@@ -49284,7 +49368,7 @@ New program @code{mysqlcheck}.
Added database name to output for administrative commands like @code{CHECK},
@code{REPAIR}, @code{OPTIMIZE}.
@item
-Lots of portability fixes for InnoDB.
+Lots of portability fixes for @code{InnoDB}.
@item
Changed optimiser so that queries like
@code{SELECT * FROM table_name,table_name2 ... ORDER BY key_part1 LIMIT #}
@@ -54880,15 +54964,15 @@ Make a second backup of the tables.
Remove (or move away) any old log files from the MySQL data
directory if you need more space.
@item
-Start @code{mysqld} with @code{--log-binary}. @xref{Binary log}.
+Start @code{mysqld} with @code{--log-bin}. @xref{Binary log}.
If you want to find a query that crashes @code{mysqld}, you should use
-@code{--log --log-binary}.
+@code{--log --log-bin}.
@item
When you have gotten a crashed table, stop the @code{mysqld server}.
@item
Restore the backup.
@item
-Restart the @code{mysqld} server @strong{without} @code{--log-binary}
+Restart the @code{mysqld} server @strong{without} @code{--log-bin}
@item
Re-execute the commands with @code{mysqlbinlog update-log-file | mysql}.
The update log is saved in the MySQL database directory with
diff --git a/client/client_priv.h b/client/client_priv.h
index b015e378127..79c03c3dc07 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -29,4 +29,5 @@
enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE,
OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS,
+ OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE,
OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES};
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index 7cddcfc8e04..8a260289ca9 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -23,7 +23,7 @@
#include <my_pthread.h> /* because of signal() */
#endif
-#define ADMIN_VERSION "8.22"
+#define ADMIN_VERSION "8.23"
#define MAX_MYSQL_VAR 64
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
@@ -1130,7 +1130,7 @@ static void wait_pidfile(char *pidfile)
system_filename(buff,pidfile);
while ((fd = my_open(buff, O_RDONLY, MYF(0))) >= 0 &&
- count++ < opt_shutdown_timeout)
+ count++ < opt_shutdown_timeout && !interrupted)
{
my_close(fd,MYF(0));
sleep(1);
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 64e7ae0fd82..aae6cdc14a1 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -33,13 +33,14 @@
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
**/
-#define DUMP_VERSION "8.17"
+#define DUMP_VERSION "8.18"
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
+#include "client_priv.h"
#include "mysql.h"
#include "mysql_version.h"
#include "mysqld_error.h"
@@ -95,12 +96,12 @@ static struct option long_options[] =
{"add-drop-table", no_argument, 0, OPT_DROP},
{"add-locks", no_argument, 0, OPT_LOCKS},
{"allow-keywords", no_argument, 0, OPT_KEYWORDS},
- {"character-sets-dir",required_argument,0, MD_OPT_CHARSETS_DIR},
+ {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
{"complete-insert", no_argument, 0, 'c'},
{"compress", no_argument, 0, 'C'},
{"databases", no_argument, 0, 'B'},
{"debug", optional_argument, 0, '#'},
- {"default-character-set", required_argument, 0, MD_OPT_DEFAULT_CHARSET},
+ {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
{"delayed-insert", no_argument, 0, OPT_DELAYED},
{"extended-insert", no_argument, 0, 'e'},
{"fields-terminated-by", required_argument, 0, (int) OPT_FTB},
@@ -318,10 +319,10 @@ static int get_options(int *argc,char ***argv)
case 'A':
opt_alldbs=1;
break;
- case MD_OPT_DEFAULT_CHARSET:
+ case OPT_DEFAULT_CHARSET:
default_charset= optarg;
break;
- case MD_OPT_CHARSETS_DIR:
+ case OPT_CHARSETS_DIR:
charsets_dir= optarg;
break;
case 'f':
diff --git a/configure.in b/configure.in
index b3927ac6961..d2f5eee5c23 100644
--- a/configure.in
+++ b/configure.in
@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
-AM_INIT_AUTOMAKE(mysql, 4.0.0-alpha)
+AM_INIT_AUTOMAKE(mysql, 4.0.1-alpha)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
@@ -1318,6 +1318,12 @@ AC_ARG_WITH(client-ldflags,
[CLIENT_EXTRA_LDFLAGS=])
AC_SUBST(CLIENT_EXTRA_LDFLAGS)
+AC_ARG_WITH(lib-ccflags,
+ [ --with-lib-ccflags Extra CC options for libraries],
+ [LIB_EXTRA_CCFLAGS=$withval],
+ [LIB_EXTRA_CCFLAGS=])
+AC_SUBST(LIB_EXTRA_CCFLAGS)
+
# Avoid stupid bug on some OS
AC_ARG_WITH(low-memory,
[ --with-low-memory Try to use less memory to compile to avoid
diff --git a/extra/resolveip.c b/extra/resolveip.c
index 9f59a2892f6..cb33e275b9d 100644
--- a/extra/resolveip.c
+++ b/extra/resolveip.c
@@ -24,6 +24,12 @@
#include <my_net.h>
#include <my_sys.h>
#include <m_string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifndef HAVE_BROKEN_NETINET_INCLUDES
+#include <netinet/in.h>
+#endif
+#include <arpa/inet.h>
#include <netdb.h>
#include <getopt.h>
diff --git a/include/my_base.h b/include/my_base.h
index 4fdc2c33a39..065ac073099 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -219,6 +219,9 @@ enum ha_base_keytype {
#define HA_ERR_LOCK_TABLE_FULL 147
#define HA_ERR_READ_ONLY_TRANSACTION 148 /* Updates not allowed */
#define HA_ERR_LOCK_DEADLOCK 149
+#define HA_ERR_CANNOT_ADD_FOREIGN 150 /* Cannot add a foreign key constr. */
+#define HA_ERR_NO_REFERENCED_ROW 151 /* Cannot add a child row */
+#define HA_ERR_ROW_IS_REFERENCED 152 /* Cannot delete a parent row */
/* Other constants */
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index e4e957ea7b6..33a3ac70c90 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -21,7 +21,7 @@ Created 6/2/1994 Heikki Tuuri
#include "lock0lock.h"
#include "ibuf0ibuf.h"
-/*
+/**
Node pointers
-------------
Leaf pages of a B-tree contain the index records stored in the
@@ -2255,6 +2255,7 @@ btr_index_rec_validate(
ulint len;
ulint n;
ulint i;
+ char err_buf[1000];
n = dict_index_get_n_fields(index);
@@ -2262,6 +2263,9 @@ btr_index_rec_validate(
fprintf(stderr, "Record has %lu fields, should have %lu\n",
rec_get_n_fields(rec), n);
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
+
return(FALSE);
}
@@ -2276,6 +2280,9 @@ btr_index_rec_validate(
"Record field %lu len is %lu, should be %lu\n",
i, len, dtype_get_fixed_size(type));
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
+
return(FALSE);
}
}
@@ -2330,7 +2337,6 @@ btr_validate_level(
ulint level) /* in: level number */
{
ulint space;
- mtr_t mtr;
page_t* page;
page_t* right_page;
page_t* father_page;
@@ -2344,6 +2350,8 @@ btr_validate_level(
dtuple_t* node_ptr_tuple;
ibool ret = TRUE;
dict_index_t* index;
+ mtr_t mtr;
+ char err_buf[1000];
mtr_start(&mtr);
@@ -2382,9 +2390,9 @@ loop:
if (level == 0) {
if (!btr_index_page_validate(page, index)) {
fprintf(stderr,
- "Error in page %lu in index %s\n",
- buf_frame_get_page_no(page), index->name);
-
+ "Error in page %lu in index %s, level %lu\n",
+ buf_frame_get_page_no(page), index->name,
+ level);
ret = FALSE;
}
}
@@ -2402,12 +2410,32 @@ loop:
right_page = btr_page_get(space, right_page_no, RW_X_LATCH,
&mtr);
- ut_a(cmp_rec_rec(page_rec_get_prev(page_get_supremum_rec(page)),
+ if (cmp_rec_rec(page_rec_get_prev(page_get_supremum_rec(page)),
page_rec_get_next(page_get_infimum_rec(right_page)),
- UT_LIST_GET_FIRST(tree->tree_indexes)) < 0);
+ UT_LIST_GET_FIRST(tree->tree_indexes)) >= 0) {
+
+ fprintf(stderr,
+ "InnoDB: Error on pages %lu and %lu in index %s\n",
+ buf_frame_get_page_no(page),
+ right_page_no,
+ index->name);
+
+ fprintf(stderr,
+ "InnoDB: records in wrong order on adjacent pages\n");
+
+ rec_sprintf(err_buf, 900,
+ page_rec_get_prev(page_get_supremum_rec(page)));
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
+
+ rec_sprintf(err_buf, 900,
+ page_rec_get_next(page_get_infimum_rec(right_page)));
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
+
+ ret = FALSE;
+ }
}
- if ((level > 0) && (left_page_no == FIL_NULL)) {
+ if (level > 0 && left_page_no == FIL_NULL) {
ut_a(REC_INFO_MIN_REC_FLAG & rec_get_info_bits(
page_rec_get_next(page_get_infimum_rec(page))));
}
@@ -2418,8 +2446,38 @@ loop:
node_ptr = btr_page_get_father_node_ptr(tree, page, &mtr);
- ut_a(node_ptr == btr_page_get_father_for_rec(tree, page,
- page_rec_get_prev(page_get_supremum_rec(page)), &mtr));
+ if (btr_node_ptr_get_child_page_no(node_ptr) !=
+ buf_frame_get_page_no(page)
+ || node_ptr != btr_page_get_father_for_rec(tree, page,
+ page_rec_get_prev(page_get_supremum_rec(page)),
+ &mtr)) {
+ fprintf(stderr,
+ "InnoDB: Error on page %lu in index %s\n",
+ buf_frame_get_page_no(page),
+ index->name);
+
+ fprintf(stderr,
+ "InnoDB: node pointer to the page is wrong\n");
+
+ rec_sprintf(err_buf, 900, node_ptr);
+
+ fprintf(stderr, "InnoDB: node ptr %s\n", err_buf);
+
+ fprintf(stderr,
+ "InnoDB: node ptr child page n:o %lu\n",
+ btr_node_ptr_get_child_page_no(node_ptr));
+
+ rec_sprintf(err_buf, 900,
+ btr_page_get_father_for_rec(tree, page,
+ page_rec_get_prev(page_get_supremum_rec(page)),
+ &mtr));
+
+ fprintf(stderr, "InnoDB: record on page %s\n",
+ err_buf);
+ ret = FALSE;
+
+ goto node_ptr_fails;
+ }
father_page = buf_frame_align(node_ptr);
@@ -2431,7 +2489,33 @@ loop:
page_rec_get_next(
page_get_infimum_rec(page)),
0, heap);
- ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr) == 0);
+
+ if (cmp_dtuple_rec(node_ptr_tuple, node_ptr) != 0) {
+
+ fprintf(stderr,
+ "InnoDB: Error on page %lu in index %s\n",
+ buf_frame_get_page_no(page),
+ index->name);
+
+ fprintf(stderr,
+ "InnoDB: Error: node ptrs differ on levels > 0\n");
+
+ rec_sprintf(err_buf, 900, node_ptr);
+
+ fprintf(stderr, "InnoDB: node ptr %s\n",
+ err_buf);
+ rec_sprintf(err_buf, 900,
+ page_rec_get_next(
+ page_get_infimum_rec(page)));
+
+ fprintf(stderr, "InnoDB: first rec %s\n",
+ err_buf);
+ ret = FALSE;
+ mem_heap_free(heap);
+
+ goto node_ptr_fails;
+ }
+
mem_heap_free(heap);
}
@@ -2454,21 +2538,51 @@ loop:
if (page_rec_get_next(node_ptr) !=
page_get_supremum_rec(father_page)) {
- ut_a(right_node_ptr ==
- page_rec_get_next(node_ptr));
+ if (right_node_ptr !=
+ page_rec_get_next(node_ptr)) {
+ ret = FALSE;
+ fprintf(stderr,
+ "InnoDB: node pointer to the right page is wrong\n");
+
+ fprintf(stderr,
+ "InnoDB: Error on page %lu in index %s\n",
+ buf_frame_get_page_no(page),
+ index->name);
+ }
} else {
right_father_page = buf_frame_align(
right_node_ptr);
- ut_a(right_node_ptr == page_rec_get_next(
+ if (right_node_ptr != page_rec_get_next(
page_get_infimum_rec(
- right_father_page)));
- ut_a(buf_frame_get_page_no(right_father_page)
- == btr_page_get_next(father_page, &mtr));
+ right_father_page))) {
+ ret = FALSE;
+ fprintf(stderr,
+ "InnoDB: node pointer 2 to the right page is wrong\n");
+
+ fprintf(stderr,
+ "InnoDB: Error on page %lu in index %s\n",
+ buf_frame_get_page_no(page),
+ index->name);
+ }
+
+ if (buf_frame_get_page_no(right_father_page)
+ != btr_page_get_next(father_page, &mtr)) {
+
+ ret = FALSE;
+ fprintf(stderr,
+ "InnoDB: node pointer 3 to the right page is wrong\n");
+
+ fprintf(stderr,
+ "InnoDB: Error on page %lu in index %s\n",
+ buf_frame_get_page_no(page),
+ index->name);
+ }
}
}
}
+node_ptr_fails:
mtr_commit(&mtr);
if (right_page_no != FIL_NULL) {
diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c
index 25c74f21fd3..4217a3ba99b 100644
--- a/innobase/buf/buf0flu.c
+++ b/innobase/buf/buf0flu.c
@@ -410,9 +410,9 @@ buf_flush_try_page(
block->io_fix = BUF_IO_WRITE;
block->flush_type = flush_type;
- if (buf_pool->n_flush[block->flush_type] == 0) {
+ if (buf_pool->n_flush[flush_type] == 0) {
- os_event_reset(buf_pool->no_flush[block->flush_type]);
+ os_event_reset(buf_pool->no_flush[flush_type]);
}
(buf_pool->n_flush[flush_type])++;
@@ -460,6 +460,11 @@ buf_flush_try_page(
block->io_fix = BUF_IO_WRITE;
block->flush_type = flush_type;
+ if (buf_pool->n_flush[flush_type] == 0) {
+
+ os_event_reset(buf_pool->no_flush[flush_type]);
+ }
+
(buf_pool->n_flush[flush_type])++;
rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE);
@@ -609,7 +614,7 @@ buf_flush_batch(
ut_ad((flush_type == BUF_FLUSH_LRU) || (flush_type == BUF_FLUSH_LIST));
ut_ad((flush_type != BUF_FLUSH_LIST) ||
sync_thread_levels_empty_gen(TRUE));
-
+
mutex_enter(&(buf_pool->mutex));
if ((buf_pool->n_flush[flush_type] > 0)
diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c
index eb63fa99f4a..c3118544492 100644
--- a/innobase/buf/buf0lru.c
+++ b/innobase/buf/buf0lru.c
@@ -10,6 +10,7 @@ Created 11/5/1995 Heikki Tuuri
#ifdef UNIV_NONINL
#include "buf0lru.ic"
+#include "srv0srv.h" /* Needed to getsrv_print_innodb_monitor */
#endif
#include "ut0byte.h"
@@ -107,20 +108,15 @@ buf_LRU_search_and_free_block(
means that we should search farther */
{
buf_block_t* block;
- ulint distance;
ibool freed;
- ulint i;
mutex_enter(&(buf_pool->mutex));
freed = FALSE;
- distance = BUF_LRU_FREE_SEARCH_LEN * (1 + n_iterations / 5);
-
- i = 0;
block = UT_LIST_GET_LAST(buf_pool->LRU);
- while (i < distance && block != NULL) {
+ while (block != NULL) {
if (buf_flush_ready_for_replace(block)) {
@@ -203,6 +199,8 @@ buf_LRU_get_free_block(void)
buf_block_t* block = NULL;
ibool freed;
ulint n_iterations = 0;
+ ibool mon_value_was;
+ ibool started_monitor = FALSE;
loop:
mutex_enter(&(buf_pool->mutex));
@@ -222,7 +220,11 @@ loop:
block->state = BUF_BLOCK_READY_FOR_USE;
mutex_exit(&(buf_pool->mutex));
-
+
+ if (started_monitor) {
+ srv_print_innodb_monitor = mon_value_was;
+ }
+
return(block);
}
@@ -237,14 +239,41 @@ loop:
goto loop;
}
- /* No free block was found near the end of the list: try to flush
- the LRU list */
-
- buf_flush_free_margin();
+ if (n_iterations > 30) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " ***********************************************\n"
+ "InnoDB: Warning: difficult to find free blocks from\n"
+ "InnoDB: the buffer pool (%lu search iterations)! Consider\n"
+ "InnoDB: increasing the buffer pool size.\n",
+ n_iterations);
+ fprintf(stderr,
+ "InnoDB: It is also possible that in your Unix version\n"
+ "InnoDB: fsync is very slow, or completely frozen inside\n"
+ "InnoDB: the OS kernel. Then upgrading to a newer version\n"
+ "InnoDB: of your operating system may help. Look at the\n"
+ "InnoDB: number of fsyncs in diagnostic info below.\n");
+
+ fprintf(stderr,
+ "InnoDB: Pending flushes (fsync) log: %lu; buffer pool: %lu\n",
+ fil_n_pending_log_flushes,
+ fil_n_pending_tablespace_flushes);
+ fprintf(stderr,
+ "InnoDB: %lu OS file reads, %lu OS file writes, %lu OS fsyncs\n",
+ os_n_file_reads, os_n_file_writes, os_n_fsyncs);
+
+ fprintf(stderr,
+ "InnoDB: Starting InnoDB Monitor to print further\n"
+ "InnoDB: diagnostics to the standard output.\n");
+
+ mon_value_was = srv_print_innodb_monitor;
+ started_monitor = TRUE;
+ srv_print_innodb_monitor = TRUE;
+ }
- os_event_wait(buf_pool->no_flush[BUF_FLUSH_LRU]);
+ /* No free block was found: try to flush the LRU list */
- n_iterations++;
+ buf_flush_free_margin();
os_aio_simulated_wake_handler_threads();
@@ -253,18 +282,7 @@ loop:
os_thread_sleep(500000);
}
- if (n_iterations > 20) {
-/* buf_print();
- os_aio_print();
- rw_lock_list_print_info();
-*/
- if (n_iterations > 30) {
- fprintf(stderr,
- "InnoDB: Warning: difficult to find free blocks from\n"
- "InnoDB: the buffer pool (%lu search iterations)! Consider\n"
- "InnoDB: increasing the buffer pool size.\n", n_iterations);
- }
- }
+ n_iterations++;
goto loop;
}
diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c
index 35fdfce16a6..206fbe32940 100644
--- a/innobase/dict/dict0boot.c
+++ b/innobase/dict/dict0boot.c
@@ -24,6 +24,65 @@ Created 4/18/1996 Heikki Tuuri
#include "os0file.h"
/**************************************************************************
+Gets a pointer to the dictionary header and x-latches its page. */
+
+dict_hdr_t*
+dict_hdr_get(
+/*=========*/
+ /* out: pointer to the dictionary header,
+ page x-latched */
+ mtr_t* mtr) /* in: mtr */
+{
+ dict_hdr_t* header;
+
+ ut_ad(mtr);
+
+ header = DICT_HDR + buf_page_get(DICT_HDR_SPACE, DICT_HDR_PAGE_NO,
+ RW_X_LATCH, mtr);
+ buf_page_dbg_add_level(header, SYNC_DICT_HEADER);
+
+ return(header);
+}
+
+/**************************************************************************
+Returns a new table, index, or tree id. */
+
+dulint
+dict_hdr_get_new_id(
+/*================*/
+ /* out: the new id */
+ ulint type) /* in: DICT_HDR_ROW_ID, ... */
+{
+ dict_hdr_t* dict_hdr;
+ dulint id;
+ mtr_t mtr;
+
+ ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID)
+ || (type == DICT_HDR_MIX_ID));
+
+ mtr_start(&mtr);
+
+ dict_hdr = dict_hdr_get(&mtr);
+
+ id = mtr_read_dulint(dict_hdr + type, MLOG_8BYTES, &mtr);
+
+ /* Add some dummy code here because otherwise pgcc seems to
+ compile wrong */
+
+ if (0 == ut_dulint_cmp(id, ut_dulint_max)) {
+ printf("Max id\n");
+ }
+
+ id = ut_dulint_add(id, 1);
+
+ mlog_write_dulint(dict_hdr + type, id, MLOG_8BYTES, &mtr);
+
+ mtr_commit(&mtr);
+
+ return(id);
+}
+
+/**************************************************************************
Writes the current value of the row id counter to the dictionary header file
page. */
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index 9d79983c9e5..b3bf9157e18 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -1076,7 +1076,7 @@ dict_create_or_check_foreign_constraint_tables(void)
}
fprintf(stderr,
- "InnoDB: creating foreign key constraint system tables\n");
+ "InnoDB: Creating foreign key constraint system tables\n");
/* NOTE: in dict_load_foreigns we use the fact that
there are 2 secondary indexes on SYS_FOREIGN, and they
@@ -1112,6 +1112,8 @@ dict_create_or_check_foreign_constraint_tables(void)
error = trx->error_state;
if (error != DB_SUCCESS) {
+ fprintf(stderr, "InnoDB: error %lu in creation\n", error);
+
ut_a(error == DB_OUT_OF_FILE_SPACE);
fprintf(stderr, "InnoDB: creation failed\n");
@@ -1133,7 +1135,7 @@ dict_create_or_check_foreign_constraint_tables(void)
if (error == DB_SUCCESS) {
fprintf(stderr,
- "InnoDB: foreign key constraint system tables created\n");
+ "InnoDB: Foreign key constraint system tables created\n");
}
mutex_exit(&(dict_sys->mutex));
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index e0a7fd327a5..07a9b472d66 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -246,7 +246,7 @@ dict_table_get_index_noninline(
}
/************************************************************************
-Initializes the autoinc counter. It is not an error to initialize already
+Initializes the autoinc counter. It is not an error to initialize an already
initialized counter. */
void
@@ -2811,3 +2811,63 @@ dict_field_print_low(
printf(" %s", field->name);
}
+
+/**************************************************************************
+Sprintfs to a string info on foreign keys of a table. */
+
+void
+dict_print_info_on_foreign_keys(
+/*============================*/
+ char* str, /* in/out: pointer to a string */
+ ulint len, /* in: space in str available for info */
+ dict_table_t* table) /* in: table */
+{
+ dict_foreign_t* foreign;
+ ulint i;
+ char* buf2;
+ char buf[10000];
+
+ buf2 = buf;
+
+ mutex_enter(&(dict_sys->mutex));
+
+ foreign = UT_LIST_GET_FIRST(table->foreign_list);
+
+ if (foreign == NULL) {
+ mutex_exit(&(dict_sys->mutex));
+
+ return;
+ }
+
+ while (foreign != NULL) {
+ buf2 += sprintf(buf2, "; (");
+
+ for (i = 0; i < foreign->n_fields; i++) {
+ buf2 += sprintf(buf2, "%s",
+ foreign->foreign_col_names[i]);
+ if (i + 1 < foreign->n_fields) {
+ buf2 += sprintf(buf2, " ");
+ }
+ }
+
+ buf2 += sprintf(buf2, ") REFER %s(",
+ foreign->referenced_table_name);
+
+ for (i = 0; i < foreign->n_fields; i++) {
+ buf2 += sprintf(buf2, "%s",
+ foreign->referenced_col_names[i]);
+ if (i + 1 < foreign->n_fields) {
+ buf2 += sprintf(buf2, " ");
+ }
+ }
+
+ buf2 += sprintf(buf2, ")");
+
+ foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
+ }
+
+ mutex_exit(&(dict_sys->mutex));
+
+ buf[len - 1] = '\0';
+ ut_memcpy(str, buf, len);
+}
diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c
index d289b176efa..bd1f0e6e1d8 100644
--- a/innobase/ibuf/ibuf0ibuf.c
+++ b/innobase/ibuf/ibuf0ibuf.c
@@ -2024,7 +2024,7 @@ ibuf_insert_low(
ulint n_stored;
ulint bits;
- ut_ad(!(index->type & (DICT_UNIQUE | DICT_CLUSTERED)));
+ ut_a(!(index->type & (DICT_UNIQUE | DICT_CLUSTERED)));
ut_ad(dtuple_check_typed(entry));
do_merge = FALSE;
diff --git a/innobase/include/dict0boot.h b/innobase/include/dict0boot.h
index 71180439913..cb631be7e35 100644
--- a/innobase/include/dict0boot.h
+++ b/innobase/include/dict0boot.h
@@ -22,7 +22,7 @@ typedef byte dict_hdr_t;
/**************************************************************************
Gets a pointer to the dictionary header and x-latches its page. */
-UNIV_INLINE
+
dict_hdr_t*
dict_hdr_get(
/*=========*/
@@ -31,7 +31,7 @@ dict_hdr_get(
mtr_t* mtr); /* in: mtr */
/**************************************************************************
Returns a new row, table, index, or tree id. */
-UNIV_INLINE
+
dulint
dict_hdr_get_new_id(
/*================*/
diff --git a/innobase/include/dict0boot.ic b/innobase/include/dict0boot.ic
index 8f1e214701f..8a91feed018 100644
--- a/innobase/include/dict0boot.ic
+++ b/innobase/include/dict0boot.ic
@@ -16,58 +16,6 @@ dict_hdr_flush_row_id(void);
/**************************************************************************
-Gets a pointer to the dictionary header and x-latches its page. */
-UNIV_INLINE
-dict_hdr_t*
-dict_hdr_get(
-/*=========*/
- /* out: pointer to the dictionary header,
- page x-latched */
- mtr_t* mtr) /* in: mtr */
-{
- dict_hdr_t* header;
-
- ut_ad(mtr);
-
- header = DICT_HDR + buf_page_get(DICT_HDR_SPACE, DICT_HDR_PAGE_NO,
- RW_X_LATCH, mtr);
- buf_page_dbg_add_level(header, SYNC_DICT_HEADER);
-
- return(header);
-}
-
-/**************************************************************************
-Returns a new table, index, or tree id. */
-UNIV_INLINE
-dulint
-dict_hdr_get_new_id(
-/*================*/
- /* out: the new id */
- ulint type) /* in: DICT_HDR_ROW_ID, ... */
-{
- dict_hdr_t* dict_hdr;
- dulint id;
- mtr_t mtr;
-
- ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID)
- || (type == DICT_HDR_MIX_ID));
-
- mtr_start(&mtr);
-
- dict_hdr = dict_hdr_get(&mtr);
-
- id = mtr_read_dulint(dict_hdr + type, MLOG_8BYTES, &mtr);
-
- id = ut_dulint_add(id, 1);
-
- mlog_write_dulint(dict_hdr + type, id, MLOG_8BYTES, &mtr);
-
- mtr_commit(&mtr);
-
- return(id);
-}
-
-/**************************************************************************
Returns a new row id. */
UNIV_INLINE
dulint
diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h
index 56b55b8a417..a4ab4faa25c 100644
--- a/innobase/include/dict0dict.h
+++ b/innobase/include/dict0dict.h
@@ -261,6 +261,15 @@ void
dict_table_print_by_name(
/*=====================*/
char* name);
+/**************************************************************************
+Sprintfs to a string info on foreign keys of a table. */
+
+void
+dict_print_info_on_foreign_keys(
+/*============================*/
+ char* str, /* in/out: pointer to a string */
+ ulint len, /* in: space in str available for info */
+ dict_table_t* table); /* in: table */
/************************************************************************
Gets the first index on the table (the clustered index). */
UNIV_INLINE
diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h
index 75bbbba549f..411a9fb2c21 100644
--- a/innobase/include/os0file.h
+++ b/innobase/include/os0file.h
@@ -106,6 +106,10 @@ log. */
#define OS_WIN95 2
#define OS_WINNT 3
+extern ulint os_n_file_reads;
+extern ulint os_n_file_writes;
+extern ulint os_n_fsyncs;
+
/***************************************************************************
Gets the operating system version. Currently works only on Windows. */
diff --git a/innobase/include/os0sync.h b/innobase/include/os0sync.h
index 78374cf8ede..26f7dff5d8b 100644
--- a/innobase/include/os0sync.h
+++ b/innobase/include/os0sync.h
@@ -14,7 +14,7 @@ Created 9/6/1995 Heikki Tuuri
#ifdef __WIN__
#define os_fast_mutex_t CRITICAL_SECTION
-typedef void* os_event_t;
+typedef void* os_event_t;
#else
diff --git a/innobase/include/page0page.ic b/innobase/include/page0page.ic
index a029604c2bc..6e33fe2ca5d 100644
--- a/innobase/include/page0page.ic
+++ b/innobase/include/page0page.ic
@@ -396,45 +396,6 @@ page_rec_check(
return(TRUE);
}
-/******************************************************************
-Used to check the consistency of a directory slot. */
-UNIV_INLINE
-ibool
-page_dir_slot_check(
-/*================*/
- /* out: TRUE if succeed */
- page_dir_slot_t* slot) /* in: slot */
-{
- page_t* page;
- ulint n_slots;
- ulint n_owned;
-
- ut_a(slot);
-
- page = buf_frame_align(slot);
-
- n_slots = page_header_get_field(page, PAGE_N_DIR_SLOTS);
-
- ut_a(slot <= page_dir_get_nth_slot(page, 0));
- ut_a(slot >= page_dir_get_nth_slot(page, n_slots - 1));
-
- ut_a(page_rec_check(page + mach_read_from_2(slot)));
-
- n_owned = rec_get_n_owned(page + mach_read_from_2(slot));
-
- if (slot == page_dir_get_nth_slot(page, 0)) {
- ut_a(n_owned == 1);
- } else if (slot == page_dir_get_nth_slot(page, n_slots - 1)) {
- ut_a(n_owned >= 1);
- ut_a(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED);
- } else {
- ut_a(n_owned >= PAGE_DIR_SLOT_MIN_N_OWNED);
- ut_a(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED);
- }
-
- return(TRUE);
-}
-
/*******************************************************************
Gets the record pointed to by a directory slot. */
UNIV_INLINE
diff --git a/innobase/include/read0read.h b/innobase/include/read0read.h
index dea952c8547..cebb2d6701c 100644
--- a/innobase/include/read0read.h
+++ b/innobase/include/read0read.h
@@ -53,6 +53,13 @@ read_view_sees_trx_id(
/* out: TRUE if sees */
read_view_t* view, /* in: read view */
dulint trx_id); /* in: trx id */
+/*************************************************************************
+Prints a read view to stderr. */
+
+void
+read_view_print(
+/*============*/
+ read_view_t* view); /* in: read view */
/* Read view lists the trx ids of those transactions for which a consistent
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index 4e90c0ac590..32354219e64 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -342,6 +342,12 @@ struct row_prebuilt_struct {
the row id: in this case this flag
is set to TRUE */
dict_index_t* index; /* current index for a search, if any */
+ ulint read_just_key; /* set to 1 when MySQL calls
+ ha_innobase::extra with the
+ argument HA_EXTRA_KEYREAD; it is enough
+ to read just columns defined in
+ the index (i.e., no read of the
+ clustered index record necessary) */
ulint template_type; /* ROW_MYSQL_WHOLE_ROW,
ROW_MYSQL_REC_FIELDS,
ROW_MYSQL_DUMMY_TEMPLATE, or
diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
index ca89de4b9a8..df8e85d05f7 100644
--- a/innobase/include/srv0srv.h
+++ b/innobase/include/srv0srv.h
@@ -15,6 +15,7 @@ Created 10/10/1995 Heikki Tuuri
#include "os0sync.h"
#include "com0com.h"
#include "que0types.h"
+#include "trx0types.h"
/* When this event is set the lock timeout and InnoDB monitor
@@ -64,6 +65,8 @@ extern ulint srv_lock_wait_timeout;
extern char* srv_unix_file_flush_method_str;
extern ulint srv_unix_file_flush_method;
extern ulint srv_force_recovery;
+extern ulint srv_thread_concurrency;
+extern ibool srv_fast_shutdown;
extern ibool srv_use_doublewrite_buf;
@@ -83,6 +86,9 @@ extern ibool srv_print_innodb_tablespace_monitor;
extern ibool srv_print_verbose_log;
extern ibool srv_print_innodb_table_monitor;
+extern ibool srv_lock_timeout_and_monitor_active;
+extern ibool srv_error_monitor_active;
+
extern ulint srv_n_spin_wait_rounds;
extern ulint srv_spin_wait_delay;
extern ibool srv_priority_boost;
@@ -160,7 +166,11 @@ of lower numbers are included. */
#define SRV_FORCE_NO_IBUF_MERGE 4 /* prevent also ibuf operations:
if they would cause a crash, better
not do them */
-#define SRV_FORCE_NO_LOG_REDO 5 /* do not do the log roll-forward
+#define SRV_FORCE_NO_UNDO_LOG_SCAN 5 /* do not look at undo logs when
+ starting the database: InnoDB will
+ treat even incomplete transactions
+ as committed */
+#define SRV_FORCE_NO_LOG_REDO 6 /* do not do the log roll-forward
in connection with recovery */
/*************************************************************************
@@ -235,6 +245,29 @@ mutex, for performace reasons). */
void
srv_active_wake_master_thread(void);
/*===============================*/
+/*************************************************************************
+Puts an OS thread to wait if there are too many concurrent threads
+(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
+
+void
+srv_conc_enter_innodb(
+/*==================*/
+ trx_t* trx); /* in: transaction object associated with the
+ thread */
+/*************************************************************************
+This lets a thread enter InnoDB regardless of the number of threads inside
+InnoDB. This must be called when a thread ends a lock wait. */
+
+void
+srv_conc_force_enter_innodb(void);
+/*=============================*/
+/*************************************************************************
+This must be called when a thread exits InnoDB. This must also be called
+when a thread goes to wait for a lock. */
+
+void
+srv_conc_exit_innodb(void);
+/*======================*/
/*******************************************************************
Puts a MySQL OS thread to wait for a lock to be released. */
diff --git a/innobase/include/srv0start.h b/innobase/include/srv0start.h
index e2b20f3b5fc..6dbdcd27250 100644
--- a/innobase/include/srv0start.h
+++ b/innobase/include/srv0start.h
@@ -29,6 +29,15 @@ innobase_shutdown_for_mysql(void);
/*=============================*/
/* out: DB_SUCCESS or error code */
-extern ibool srv_startup_is_before_trx_rollback_phase;
+extern ibool srv_startup_is_before_trx_rollback_phase;
+extern ibool srv_is_being_shut_down;
+
+/* At a shutdown the value first climbs from 0 to SRV_SHUTDOWN_CLEANUP
+and then to SRV_SHUTDOWN_LAST_PHASE */
+
+extern ulint srv_shutdown_state;
+
+#define SRV_SHUTDOWN_CLEANUP 1
+#define SRV_SHUTDOWN_LAST_PHASE 2
#endif
diff --git a/innobase/include/trx0purge.h b/innobase/include/trx0purge.h
index 8870ebc936c..087be2f060e 100644
--- a/innobase/include/trx0purge.h
+++ b/innobase/include/trx0purge.h
@@ -94,6 +94,12 @@ trx_purge(void);
/*===========*/
/* out: number of undo log pages handled in
the batch */
+/**********************************************************************
+Prints information of the purge system to stderr. */
+
+void
+trx_purge_sys_print(void);
+/*======================*/
/* The control structure used in the purge operation */
struct trx_purge_struct{
diff --git a/innobase/include/trx0rec.h b/innobase/include/trx0rec.h
index edfc283d1b2..50d942d9040 100644
--- a/innobase/include/trx0rec.h
+++ b/innobase/include/trx0rec.h
@@ -127,7 +127,9 @@ Builds an update vector based on a remaining part of an undo log record. */
byte*
trx_undo_update_rec_get_update(
/*===========================*/
- /* out: remaining part of the record */
+ /* out: remaining part of the record,
+ NULL if an error detected, which means that
+ the record is corrupted */
byte* ptr, /* in: remaining part in update undo log
record, after reading the row reference
NOTE that this copy of the undo log record must
@@ -235,7 +237,8 @@ trx_undo_prev_version_build(
/*========================*/
/* out: DB_SUCCESS, or DB_MISSING_HISTORY if
the previous version is not >= purge_view,
- which means that it may have been removed */
+ which means that it may have been removed,
+ DB_ERROR if corrupted record */
rec_t* index_rec,/* in: clustered index record in the
index tree */
mtr_t* index_mtr,/* in: mtr which contains the latch to
diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h
index 8db0b39d3b4..58cef01b376 100644
--- a/innobase/include/trx0trx.h
+++ b/innobase/include/trx0trx.h
@@ -17,11 +17,6 @@ Created 3/26/1996 Heikki Tuuri
#include "mem0mem.h"
#include "read0types.h"
-/* If this flag is defined, then unneeded update undo logs are discarded,
-saving CPU time. The kernel mutex contention is increased, however. */
-
-#define TRX_UPDATE_UNDO_OPT
-
extern ulint trx_n_mysql_transactions;
/************************************************************************
@@ -130,14 +125,6 @@ void
trx_mark_sql_stat_end(
/*==================*/
trx_t* trx); /* in: trx handle */
-/**************************************************************************
-Marks the latest SQL statement ended but does not start a new transaction
-if the trx is not started. */
-
-void
-trx_mark_sql_stat_end_do_not_start_new(
-/*===================================*/
- trx_t* trx); /* in: trx handle */
/************************************************************************
Assigns a read view for a consistent read query. All the consistent reads
within the same transaction will get the same read view, which is created
diff --git a/innobase/include/univ.i b/innobase/include/univ.i
index c56f21d6617..584757529cf 100644
--- a/innobase/include/univ.i
+++ b/innobase/include/univ.i
@@ -104,8 +104,12 @@ memory is read outside the allocated blocks. */
#define UNIV_INLINE __inline
#else
/* config.h contains the right def for 'inline' for the current compiler */
+#if (__GNUC__ == 2)
#define UNIV_INLINE extern inline
-
+#else
+/* extern inline doesn't work with gcc 3.0.2 */
+#define UNIV_INLINE static inline
+#endif
#endif
#else
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index fa0641bad73..0b2b85d0337 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -3472,14 +3472,18 @@ lock_print_info(void)
ulint i;
mtr_t mtr;
+ printf("Trx id counter %lu %lu\n",
+ ut_dulint_get_high(trx_sys->max_trx_id),
+ ut_dulint_get_low(trx_sys->max_trx_id));
+
printf(
- "Purge done for all trx's with n:o < %lu %lu, undo n:o < %lu %lu\n",
+ "Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu\n",
ut_dulint_get_high(purge_sys->purge_trx_no),
ut_dulint_get_low(purge_sys->purge_trx_no),
ut_dulint_get_high(purge_sys->purge_undo_no),
ut_dulint_get_low(purge_sys->purge_undo_no));
- lock_mutex_enter_kernel();
+ lock_mutex_enter_kernel();
printf("Total number of lock structs in row lock hash table %lu\n",
lock_get_n_rec_locks());
diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c
index 06ac7a578a5..e787176bb21 100644
--- a/innobase/log/log0log.c
+++ b/innobase/log/log0log.c
@@ -20,6 +20,7 @@ Created 12/9/1995 Heikki Tuuri
#include "fil0fil.h"
#include "dict0boot.h"
#include "srv0srv.h"
+#include "srv0start.h"
#include "trx0sys.h"
#include "trx0trx.h"
@@ -2656,6 +2657,8 @@ logs_empty_and_mark_files_at_shutdown(void)
}
/* Wait until the master thread and all other operations are idle: our
algorithm only works if the server is idle at shutdown */
+
+ srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
loop:
os_thread_sleep(100000);
@@ -2737,7 +2740,21 @@ loop:
goto loop;
}
+
+ if (srv_lock_timeout_and_monitor_active) {
+
+ goto loop;
+ }
+
+ /* We now suspend also the InnoDB error monitor thread */
+ srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
+
+ if (srv_error_monitor_active) {
+
+ goto loop;
+ }
+
fil_write_flushed_lsn_to_data_files(lsn, arch_log_no);
fil_flush_file_spaces(FIL_TABLESPACE);
diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c
index eb3eadcede9..999429cbfcd 100644
--- a/innobase/log/log0recv.c
+++ b/innobase/log/log0recv.c
@@ -61,7 +61,11 @@ buffer pool before the pages have been recovered to the up-to-date state */
/* Recovery is running and no operations on the log files are allowed
yet: the variable name is misleading */
-ibool recv_no_ibuf_operations = FALSE;
+ibool recv_no_ibuf_operations = FALSE;
+
+/* the following counter is used to decide when to print info on
+log scan */
+ulint recv_scan_print_counter = 0;
/************************************************************
Creates the recovery system. */
@@ -1812,10 +1816,19 @@ recv_scan_log_recs(
*group_scanned_lsn = scanned_lsn;
if (more_data) {
- fprintf(stderr,
+ recv_scan_print_counter++;
+
+ if (recv_scan_print_counter < 10
+ || (recv_scan_print_counter % 10 == 0)) {
+ fprintf(stderr,
"InnoDB: Doing recovery: scanned up to log sequence number %lu %lu\n",
ut_dulint_get_high(*group_scanned_lsn),
ut_dulint_get_low(*group_scanned_lsn));
+ if (recv_scan_print_counter == 10) {
+ fprintf(stderr,
+"InnoDB: After this prints a line for every 10th scan sweep:\n");
+ }
+ }
/* Try to parse more log records */
@@ -1911,6 +1924,15 @@ recv_recovery_from_checkpoint_start(
recv_sys_init();
}
+ if (srv_force_recovery >= SRV_FORCE_NO_LOG_REDO) {
+ fprintf(stderr,
+ "InnoDB: The user has set SRV_FORCE_NO_LOG_REDO on\n");
+ fprintf(stderr,
+ "InnoDB: Skipping log redo\n");
+
+ return(DB_SUCCESS);
+ }
+
sync_order_checks_on = TRUE;
recv_recovery_on = TRUE;
@@ -2028,10 +2050,8 @@ recv_recovery_from_checkpoint_start(
while (group) {
old_scanned_lsn = recv_sys->scanned_lsn;
- if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
- recv_group_scan_log_recs(group, &contiguous_lsn,
+ recv_group_scan_log_recs(group, &contiguous_lsn,
&group_scanned_lsn);
- }
group->scanned_lsn = group_scanned_lsn;
@@ -2124,7 +2144,10 @@ recv_recovery_from_checkpoint_finish(void)
/* Apply the hashed log records to the respective file pages */
- recv_apply_hashed_log_recs(TRUE);
+ if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
+
+ recv_apply_hashed_log_recs(TRUE);
+ }
if (log_debug_writes) {
fprintf(stderr,
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index ced601d4de1..9fecf2c04fd 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -235,7 +235,7 @@ os_file_handle_error(
fprintf(stderr,
"InnoDB: Cannot continue operation.\n"
"InnoDB: Disk is full. Try to clean the disk to free space.\n"
- "InnoDB: Delete possible created file and restart.\n");
+ "InnoDB: Delete a possible created file and restart.\n");
exit(1);
@@ -453,8 +453,17 @@ os_file_get_size(
return(TRUE);
#else
- *size = (ulint) lseek(file, 0, SEEK_END);
- *size_high = 0;
+ off_t offs;
+
+ offs = lseek(file, 0, SEEK_END);
+
+ if (sizeof(off_t) > 4) {
+ *size = (ulint)(offs & 0xFFFFFFFF);
+ *size_high = (ulint)(offs >> 32);
+ } else {
+ *size = (ulint) offs;
+ *size_high = 0;
+ }
return(TRUE);
#endif
@@ -474,17 +483,19 @@ os_file_set_size(
size */
ulint size_high)/* in: most significant 32 bits of size */
{
- ulint offset;
- ulint n_bytes;
- ulint low;
- ibool ret;
- ibool retry;
- ulint i;
- byte* buf;
+ ib_longlong offset;
+ ib_longlong low;
+ ulint n_bytes;
+ ibool ret;
+ ibool retry;
+ byte* buf;
+ ulint i;
+
+ ut_a(size == (size & 0xFFFFFFFF));
try_again:
/* We use a very big 8 MB buffer in writing because Linux may be
- extremely slow in fdatasync on 1 MB writes */
+ extremely slow in fsync on 1 MB writes */
buf = ut_malloc(UNIV_PAGE_SIZE * 512);
@@ -494,21 +505,19 @@ try_again:
}
offset = 0;
- low = size;
-#if (UNIV_WORD_SIZE == 8)
- low = low + (size_high << 32);
-#else
- UT_NOT_USED(size_high);
-#endif
+ low = (ib_longlong)size + (((ib_longlong)size_high) << 32);
+
while (offset < low) {
if (low - offset < UNIV_PAGE_SIZE * 512) {
- n_bytes = low - offset;
+ n_bytes = (ulint)(low - offset);
} else {
- n_bytes = UNIV_PAGE_SIZE * 512;
+ n_bytes = UNIV_PAGE_SIZE * 512;
}
- ret = os_file_write(name, file, buf, offset, 0, n_bytes);
-
+ ret = os_file_write(name, file, buf,
+ (ulint)(offset & 0xFFFFFFFF),
+ (ulint)(offset >> 32),
+ n_bytes);
if (!ret) {
ut_free(buf);
goto error_handling;
@@ -582,7 +591,6 @@ os_file_flush(
#endif
}
-
#ifndef __WIN__
/***********************************************************************
Does a synchronous read operation in Posix. */
@@ -594,9 +602,29 @@ os_file_pread(
os_file_t file, /* in: handle to a file */
void* buf, /* in: buffer where to read */
ulint n, /* in: number of bytes to read */
- ulint offset) /* in: offset from where to read */
+ ulint offset, /* in: least significant 32 bits of file
+ offset from where to read */
+ ulint offset_high) /* in: most significant 32 bits of
+ offset */
{
- off_t offs = (off_t)offset;
+ off_t offs;
+
+ ut_a((offset & 0xFFFFFFFF) == offset);
+
+ /* If off_t is > 4 bytes in size, then we assume we can pass a
+ 64-bit address */
+
+ if (sizeof(off_t) > 4) {
+ offs = (off_t)offset + (((off_t)offset_high) << 32);
+
+ } else {
+ offs = (off_t)offset;
+
+ if (offset_high > 0) {
+ fprintf(stderr,
+ "InnoDB: Error: file read at offset > 4 GB\n");
+ }
+ }
os_n_file_reads++;
@@ -639,10 +667,30 @@ os_file_pwrite(
os_file_t file, /* in: handle to a file */
void* buf, /* in: buffer from where to write */
ulint n, /* in: number of bytes to write */
- ulint offset) /* in: offset where to write */
+ ulint offset, /* in: least significant 32 bits of file
+ offset where to write */
+ ulint offset_high) /* in: most significant 32 bits of
+ offset */
{
ssize_t ret;
- off_t offs = (off_t)offset;
+ off_t offs;
+
+ ut_a((offset & 0xFFFFFFFF) == offset);
+
+ /* If off_t is > 4 bytes in size, then we assume we can pass a
+ 64-bit address */
+
+ if (sizeof(off_t) > 4) {
+ offs = (off_t)offset + (((off_t)offset_high) << 32);
+
+ } else {
+ offs = (off_t)offset;
+
+ if (offset_high > 0) {
+ fprintf(stderr,
+ "InnoDB: Error: file write at offset > 4 GB\n");
+ }
+ }
os_n_file_writes++;
@@ -724,6 +772,8 @@ os_file_read(
ibool retry;
ulint i;
+ ut_a((offset & 0xFFFFFFFF) == offset);
+
os_n_file_reads++;
try_again:
@@ -758,21 +808,18 @@ try_again:
#else
ibool retry;
ssize_t ret;
-
-#if (UNIV_WORD_SIZE == 8)
- offset = offset + (offset_high << 32);
-#else
- UT_NOT_USED(offset_high);
-#endif
+
try_again:
- ret = os_file_pread(file, buf, n, offset);
+ ret = os_file_pread(file, buf, n, offset, offset_high);
if ((ulint)ret == n) {
return(TRUE);
}
#endif
+#ifdef __WIN__
error_handling:
+#endif
retry = os_file_handle_error(file, NULL);
if (retry) {
@@ -811,6 +858,8 @@ os_file_write(
ibool retry;
ulint i;
+ ut_a((offset & 0xFFFFFFFF) == offset);
+
os_n_file_writes++;
try_again:
ut_ad(file);
@@ -852,19 +901,16 @@ try_again:
ibool retry;
ssize_t ret;
-#if (UNIV_WORD_SIZE == 8)
- offset = offset + (offset_high << 32);
-#else
- UT_NOT_USED(offset_high);
-#endif
try_again:
- ret = os_file_pwrite(file, buf, n, offset);
+ ret = os_file_pwrite(file, buf, n, offset, offset_high);
if ((ulint)ret == n) {
return(TRUE);
}
#endif
+#ifdef __WIN__
error_handling:
+#endif
retry = os_file_handle_error(file, name);
if (retry) {
@@ -1108,6 +1154,8 @@ os_aio_get_array_and_local_segment(
/***********************************************************************
Gets an integer value designating a specified aio array. This is used
to give numbers to signals in Posix aio. */
+
+#if !defined(WIN_ASYNC_IO) && defined(POSIX_ASYNC_IO)
static
ulint
os_aio_get_array_no(
@@ -1161,6 +1209,7 @@ os_aio_get_array_from_no(
return(NULL);
}
}
+#endif /* if !defined(WIN_ASYNC_IO) && defined(POSIX_ASYNC_IO) */
/***********************************************************************
Requests for a slot in the aio array. If no slot is available, waits until
@@ -1321,8 +1370,8 @@ os_aio_simulated_wake_handler_thread(
arrays */
{
os_aio_array_t* array;
- ulint segment;
os_aio_slot_t* slot;
+ ulint segment;
ulint n;
ulint i;
@@ -1817,7 +1866,8 @@ restart:
n_consecutive = 0;
- /* Look for an i/o request at the lowest offset in the array */
+ /* Look for an i/o request at the lowest offset in the array
+ (we ignore the high 32 bits of the offset in these heuristics) */
lowest_offset = ULINT_MAX;
@@ -1912,7 +1962,7 @@ consecutive_loop:
}
}
- srv_io_thread_op_info[global_segment] = "doing file i/o";
+ srv_io_thread_op_info[global_segment] = (char*) "doing file i/o";
/* Do the i/o with ordinary, synchronous i/o functions: */
if (slot->type == OS_FILE_WRITE) {
@@ -1924,7 +1974,7 @@ consecutive_loop:
}
ut_a(ret);
- srv_io_thread_op_info[global_segment] = "file i/o done";
+ srv_io_thread_op_info[global_segment] = (char*) "file i/o done";
/* printf("aio: %lu consecutive %lu:th segment, first offs %lu blocks\n",
n_consecutive, global_segment, slot->offset
@@ -1981,7 +2031,7 @@ wait_for_io:
os_mutex_exit(array->mutex);
- srv_io_thread_op_info[global_segment] = "waiting for i/o request";
+ srv_io_thread_op_info[global_segment] = (char*) "waiting for i/o request";
os_event_wait(os_aio_segment_wait_events[global_segment]);
diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c
index 427064bc89c..a75a7279fb5 100644
--- a/innobase/page/page0page.c
+++ b/innobase/page/page0page.c
@@ -63,6 +63,45 @@ Assuming a page size of 8 kB, a typical index page of a secondary
index contains 300 index entries, and the size of the page directory
is 50 x 4 bytes = 200 bytes. */
+/******************************************************************
+Used to check the consistency of a directory slot. */
+static
+ibool
+page_dir_slot_check(
+/*================*/
+ /* out: TRUE if succeed */
+ page_dir_slot_t* slot) /* in: slot */
+{
+ page_t* page;
+ ulint n_slots;
+ ulint n_owned;
+
+ ut_a(slot);
+
+ page = buf_frame_align(slot);
+
+ n_slots = page_header_get_field(page, PAGE_N_DIR_SLOTS);
+
+ ut_a(slot <= page_dir_get_nth_slot(page, 0));
+ ut_a(slot >= page_dir_get_nth_slot(page, n_slots - 1));
+
+ ut_a(page_rec_check(page + mach_read_from_2(slot)));
+
+ n_owned = rec_get_n_owned(page + mach_read_from_2(slot));
+
+ if (slot == page_dir_get_nth_slot(page, 0)) {
+ ut_a(n_owned == 1);
+ } else if (slot == page_dir_get_nth_slot(page, n_slots - 1)) {
+ ut_a(n_owned >= 1);
+ ut_a(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED);
+ } else {
+ ut_a(n_owned >= PAGE_DIR_SLOT_MIN_N_OWNED);
+ ut_a(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED);
+ }
+
+ return(TRUE);
+}
+
/*****************************************************************
Sets the max trx id field value. */
@@ -1228,7 +1267,6 @@ page_validate(
mem_heap_t* heap;
page_cur_t cur;
byte* buf;
- ulint i;
ulint count;
ulint own_count;
ulint slot_no;
@@ -1238,6 +1276,8 @@ page_validate(
ulint offs;
ulint n_slots;
ibool ret = FALSE;
+ ulint i;
+ char err_buf[1000];
heap = mem_heap_create(UNIV_PAGE_SIZE);
@@ -1285,9 +1325,14 @@ page_validate(
if ((count >= 2) && (!page_cur_is_after_last(&cur))) {
if (!(1 == cmp_rec_rec(rec, old_rec, index))) {
fprintf(stderr,
- "Records in wrong order in index %s\n",
- index->name);
-
+ "Records in wrong order in index %s\n",
+ index->name);
+ rec_sprintf(err_buf, 900, old_rec);
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
+
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
+
goto func_exit;
}
}
diff --git a/innobase/read/read0read.c b/innobase/read/read0read.c
index 84e2c93b30c..a5048c0c909 100644
--- a/innobase/read/read0read.c
+++ b/innobase/read/read0read.c
@@ -38,8 +38,8 @@ read_view_create_low(
/*************************************************************************
Makes a copy of the oldest existing read view, with the exception that also
the creating trx of the oldest view is set as not visible in the 'copied'
-view. Opens a new view if no views currently exist. The view must be
-closed with ..._close. This is used in purge. */
+view. Opens a new view if no views currently exist. The view must be closed
+with ..._close. This is used in purge. */
read_view_t*
read_view_oldest_copy_or_open_new(
@@ -160,7 +160,7 @@ read_view_open_now(
/* NOTE that a transaction whose trx number is <
trx_sys->max_trx_id can still be active, if it is
- in the middle of the commit! Note that when a
+ in the middle of its commit! Note that when a
transaction starts, we initialize trx->no to
ut_dulint_max. */
@@ -199,3 +199,37 @@ read_view_close(
UT_LIST_REMOVE(view_list, trx_sys->view_list, view);
}
+
+/*************************************************************************
+Prints a read view to stderr. */
+
+void
+read_view_print(
+/*============*/
+ read_view_t* view) /* in: read view */
+{
+ ulint n_ids;
+ ulint i;
+
+ fprintf(stderr, "Read view low limit trx n:o %lu %lu\n",
+ ut_dulint_get_high(view->low_limit_no),
+ ut_dulint_get_low(view->low_limit_no));
+
+ fprintf(stderr, "Read view up limit trx id %lu %lu\n",
+ ut_dulint_get_high(view->up_limit_id),
+ ut_dulint_get_low(view->up_limit_id));
+
+ fprintf(stderr, "Read view low limit trx id %lu %lu\n",
+ ut_dulint_get_high(view->low_limit_id),
+ ut_dulint_get_low(view->low_limit_id));
+
+ fprintf(stderr, "Read view individually stored trx ids:\n");
+
+ n_ids = view->n_trx_ids;
+
+ for (i = 0; i < n_ids; i++) {
+ fprintf(stderr, "Read view trx id %lu %lu\n",
+ ut_dulint_get_high(read_view_get_nth_trx_id(view, i)),
+ ut_dulint_get_low(read_view_get_nth_trx_id(view, i)));
+ }
+}
diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c
index c3687ebb0e0..f3d9d579aa0 100644
--- a/innobase/rem/rem0cmp.c
+++ b/innobase/rem/rem0cmp.c
@@ -84,7 +84,7 @@ cmp_collate(
record */
{
ut_ad((type->mtype == DATA_CHAR) || (type->mtype == DATA_VARCHAR));
-
+
return((ulint) srv_latin1_ordering[code]);
}
diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c
index 88009f2f5c9..749e19575bc 100644
--- a/innobase/rem/rem0rec.c
+++ b/innobase/rem/rem0rec.c
@@ -451,24 +451,31 @@ rec_validate(
/* out: TRUE if ok */
rec_t* rec) /* in: physical record */
{
- ulint i;
byte* data;
ulint len;
ulint n_fields;
ulint len_sum = 0;
ulint sum = 0;
+ ulint i;
ut_a(rec);
n_fields = rec_get_n_fields(rec);
if ((n_fields == 0) || (n_fields > REC_MAX_N_FIELDS)) {
- ut_a(0);
+ fprintf(stderr, "InnoDB: Error: record has %lu fields\n",
+ n_fields);
+ return(FALSE);
}
for (i = 0; i < n_fields; i++) {
data = rec_get_nth_field(rec, i, &len);
- ut_a((len < UNIV_PAGE_SIZE) || (len == UNIV_SQL_NULL));
+ if (!((len < UNIV_PAGE_SIZE) || (len == UNIV_SQL_NULL))) {
+ fprintf(stderr,
+ "InnoDB: Error: record field %lu len %lu\n", i,
+ len);
+ return(FALSE);
+ }
if (len != UNIV_SQL_NULL) {
len_sum += len;
@@ -481,7 +488,12 @@ rec_validate(
}
}
- ut_a(len_sum == (ulint)(rec_get_end(rec) - rec));
+ if (len_sum != (ulint)(rec_get_end(rec) - rec)) {
+ fprintf(stderr,
+ "InnoDB: Error: record len should be %lu, len %lu\n",
+ len_sum, (ulint)(rec_get_end(rec) - rec));
+ return(FALSE);
+ }
rec_dummy = sum; /* This is here only to fool the compiler */
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index 92cac5a55cf..2c6d3b0ed00 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -277,7 +277,8 @@ row_ins_clust_index_entry_by_modify(
heap = mem_heap_create(1024);
/* Build an update vector containing all the fields to be modified;
- NOTE that this vector may contain also system columns! */
+ NOTE that this vector may NOT contain system columns trx_id or
+ roll_ptr */
update = row_upd_build_difference_binary(cursor->index, entry, ext_vec,
n_ext_vec, rec, heap);
@@ -1221,6 +1222,8 @@ row_ins_step(
trx = thr_get_trx(thr);
+ trx_start_if_not_started(trx);
+
node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_INSERT);
@@ -1241,8 +1244,6 @@ row_ins_step(
/* It may be that the current session has not yet started
its transaction, or it has been committed: */
- trx_start_if_not_started(trx);
-
if (UT_DULINT_EQ(trx->id, node->trx_id)) {
/* No need to do IX-locking or write trx id to buf */
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 13c0332dcef..19d2fb744c9 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -571,6 +571,8 @@ row_insert_for_mysql(
trx->op_info = "inserting";
+ trx_start_if_not_started(trx);
+
if (node == NULL) {
row_get_prebuilt_insert_row(prebuilt);
node = prebuilt->ins_node;
@@ -754,6 +756,8 @@ row_update_for_mysql(
trx->op_info = "updating or deleting";
+ trx_start_if_not_started(trx);
+
node = prebuilt->upd_node;
clust_index = dict_table_get_first_index(table);
@@ -947,6 +951,8 @@ row_create_table_for_mysql(
trx->op_info = "creating table";
+ trx_start_if_not_started(trx);
+
namelen = ut_strlen(table->name);
keywordlen = ut_strlen("innodb_monitor");
@@ -1034,7 +1040,7 @@ row_create_table_for_mysql(
"InnoDB: Error: table %s already exists in InnoDB internal\n"
"InnoDB: data dictionary. Have you deleted the .frm file\n"
"InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n"
- "InnoDB: for InnoDB tables in MySQL version <= 3.23.42?\n"
+ "InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n"
"InnoDB: See the Restrictions section of the InnoDB manual.\n",
table->name);
fprintf(stderr,
@@ -1077,6 +1083,8 @@ row_create_index_for_mysql(
trx->op_info = "creating index";
+ trx_start_if_not_started(trx);
+
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
@@ -1146,6 +1154,8 @@ row_table_add_foreign_constraints(
trx->op_info = "adding foreign keys";
+ trx_start_if_not_started(trx);
+
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
@@ -1218,6 +1228,8 @@ row_drop_table_for_mysql(
trx->op_info = "dropping table";
+ trx_start_if_not_started(trx);
+
namelen = ut_strlen(name);
keywordlen = ut_strlen("innodb_monitor");
@@ -1435,6 +1447,8 @@ row_drop_database_for_mysql(
trx->op_info = "dropping database";
+ trx_start_if_not_started(trx);
+
mutex_enter(&(dict_sys->mutex));
while (table_name = dict_get_first_table_name_in_db(name)) {
@@ -1454,6 +1468,8 @@ row_drop_database_for_mysql(
mutex_exit(&(dict_sys->mutex));
+ trx_commit_for_mysql(trx);
+
trx->op_info = "";
return(err);
@@ -1496,6 +1512,7 @@ row_rename_table_for_mysql(
}
trx->op_info = "renaming table";
+ trx_start_if_not_started(trx);
str1 =
"PROCEDURE RENAME_TABLE_PROC () IS\n"
@@ -1602,6 +1619,7 @@ row_scan_and_check_index(
rec_t* rec;
ibool is_ok = TRUE;
int cmp;
+ char err_buf[1000];
*n_rows = 0;
@@ -1649,15 +1667,27 @@ loop:
if (cmp > 0) {
fprintf(stderr,
"Error: index records in a wrong order in index %s\n",
- index->name);
+ index->name);
+
+ dtuple_sprintf(err_buf, 900, prev_entry);
+ fprintf(stderr, "InnoDB: prev record %s\n", err_buf);
+
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
is_ok = FALSE;
} else if ((index->type & DICT_UNIQUE)
&& matched_fields >=
dict_index_get_n_ordering_defined_by_user(index)) {
- fprintf(stderr,
- "Error: duplicate key in index %s\n",
- index->name);
+
+ fprintf(stderr, "Error: duplicate key in index %s\n",
+ index->name);
+
+ dtuple_sprintf(err_buf, 900, prev_entry);
+ fprintf(stderr, "InnoDB: prev record %s\n", err_buf);
+
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
is_ok = FALSE;
}
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c
index 0dffa273938..390f1b59a4d 100644
--- a/innobase/row/row0purge.c
+++ b/innobase/row/row0purge.c
@@ -208,7 +208,7 @@ row_purge_remove_sec_if_poss_low(
ibool found;
ulint err;
mtr_t mtr;
- mtr_t mtr_vers;
+ mtr_t* mtr_vers;
UT_NOT_USED(thr);
@@ -235,17 +235,21 @@ row_purge_remove_sec_if_poss_low(
which cannot be purged yet, requires its existence. If some requires,
we should do nothing. */
- mtr_start(&mtr_vers);
+ mtr_vers = mem_alloc(sizeof(mtr_t));
+
+ mtr_start(mtr_vers);
- success = row_purge_reposition_pcur(BTR_SEARCH_LEAF, node, &mtr_vers);
+ success = row_purge_reposition_pcur(BTR_SEARCH_LEAF, node, mtr_vers);
if (success) {
old_has = row_vers_old_has_index_entry(TRUE,
btr_pcur_get_rec(&(node->pcur)),
- &mtr_vers, index, entry);
+ mtr_vers, index, entry);
}
- btr_pcur_commit_specify_mtr(&(node->pcur), &mtr_vers);
+ btr_pcur_commit_specify_mtr(&(node->pcur), mtr_vers);
+
+ mem_free(mtr_vers);
if (!success || !old_has) {
/* Remove the index record */
@@ -489,11 +493,6 @@ row_purge_parse_undo_rec(
return(FALSE);
}
- /* NOTE that the table has to be explicitly released later */
-
- /* TODO: currently nothing prevents dropping of table when purge
- is accessing it! */
-
mutex_enter(&(dict_sys->mutex));
node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr));
diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c
index 59169ef2a98..40a775143f4 100644
--- a/innobase/row/row0row.c
+++ b/innobase/row/row0row.c
@@ -455,12 +455,25 @@ row_build_row_ref_in_tuple(
ulint pos;
ulint i;
- ut_ad(ref && index && rec);
+ ut_a(ref && index && rec);
table = index->table;
+
+ if (!table) {
+ fprintf(stderr, "InnoDB: table %s for index %s not found\n",
+ index->table_name, index->name);
+ ut_a(0);
+ }
clust_index = dict_table_get_first_index(table);
-
+
+ if (!clust_index) {
+ fprintf(stderr,
+ "InnoDB: clust index for table %s for index %s not found\n",
+ index->table_name, index->name);
+ ut_a(0);
+ }
+
ref_len = dict_index_get_n_unique(clust_index);
ut_ad(ref_len == dtuple_get_n_fields(ref));
@@ -555,6 +568,8 @@ row_search_on_row_ref(
index = dict_table_get_first_index(table);
+ ut_a(dtuple_get_n_fields(ref) == dict_index_get_n_unique(index));
+
btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, mtr);
low_match = btr_pcur_get_low_match(pcur);
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index e42486f1e17..2cccc217621 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -2671,6 +2671,8 @@ no_shortcut:
trx->has_search_latch = FALSE;
}
+ trx_start_if_not_started(trx);
+
/* Note that if the search mode was GE or G, then the cursor
naturally moves upward (in fetch next) in alphabetical order,
otherwise downward */
@@ -2715,16 +2717,12 @@ no_shortcut:
/* No need to set an intention lock or assign a read view */
} else if (prebuilt->select_lock_type == LOCK_NONE) {
- /* This is a consistent read */
- trx_start_if_not_started(trx);
-
+ /* This is a consistent read */
/* Assign a read view for the query */
trx_assign_read_view(trx);
prebuilt->sql_stat_start = FALSE;
- } else {
- trx_start_if_not_started(trx);
-
+ } else {
if (prebuilt->select_lock_type == LOCK_S) {
err = lock_table(0, index->table, LOCK_IS, thr);
} else {
diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c
index 37f5b1f0bc1..9e8ba87fc2f 100644
--- a/innobase/row/row0umod.c
+++ b/innobase/row/row0umod.c
@@ -299,13 +299,13 @@ row_undo_mod_del_mark_or_remove_sec_low(
BTR_MODIFY_TREE */
{
ibool found;
- mtr_t mtr;
- mtr_t mtr_vers;
btr_pcur_t pcur;
btr_cur_t* btr_cur;
ibool success;
ibool old_has;
ulint err;
+ mtr_t mtr;
+ mtr_t mtr_vers;
log_free_check();
mtr_start(&mtr);
@@ -338,7 +338,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur),
&mtr_vers);
- ut_ad(success);
+ ut_a(success);
old_has = row_vers_old_has_index_entry(FALSE,
btr_pcur_get_rec(&(node->pcur)),
@@ -361,7 +361,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
ut_ad(mode == BTR_MODIFY_TREE);
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
- TRUE, &mtr);
+ TRUE, &mtr);
/* The delete operation may fail if we have little
file space left: TODO: easiest to crash the database
@@ -413,12 +413,12 @@ row_undo_mod_del_unmark_sec(
dict_index_t* index, /* in: index */
dtuple_t* entry) /* in: index entry */
{
- mtr_t mtr;
btr_pcur_t pcur;
btr_cur_t* btr_cur;
ulint err;
ibool found;
- char* err_buf;
+ mtr_t mtr;
+ char err_buf[1000];
UT_NOT_USED(node);
@@ -428,12 +428,10 @@ row_undo_mod_del_unmark_sec(
found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
&mtr);
if (!found) {
- err_buf = mem_alloc(1000);
- dtuple_sprintf(err_buf, 900, entry);
-
fprintf(stderr, "InnoDB: error in sec index entry del undo in\n"
"InnoDB: index %s table %s\n", index->name,
index->table->name);
+ dtuple_sprintf(err_buf, 900, entry);
fprintf(stderr, "InnoDB: tuple %s\n", err_buf);
rec_sprintf(err_buf, 900, btr_pcur_get_rec(&pcur));
@@ -444,8 +442,6 @@ row_undo_mod_del_unmark_sec(
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
trx_print(thr_get_trx(thr));
-
- mem_free(err_buf);
} else {
btr_cur = btr_pcur_get_btr_cur(&pcur);
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index fa859729141..435cfa3485e 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -700,7 +700,7 @@ row_upd_build_difference_binary(
ulint i;
/* This function is used only for a clustered index */
- ut_ad(index->type & DICT_CLUSTERED);
+ ut_a(index->type & DICT_CLUSTERED);
update = upd_create(dtuple_get_n_fields(entry), heap);
@@ -718,10 +718,14 @@ row_upd_build_difference_binary(
/* NOTE: we compare the fields as binary strings!
(No collation) */
- if ((rec_get_nth_field_extern_bit(rec, i)
- != upd_ext_vec_contains(ext_vec, n_ext_vec, i))
- || ((i != trx_id_pos) && (i != roll_ptr_pos)
- && !dfield_data_is_binary_equal(dfield, len, data))) {
+ if (i == trx_id_pos || i == roll_ptr_pos) {
+
+ goto skip_compare;
+ }
+
+ if (rec_get_nth_field_extern_bit(rec, i)
+ != upd_ext_vec_contains(ext_vec, n_ext_vec, i)
+ || !dfield_data_is_binary_equal(dfield, len, data)) {
upd_field = upd_get_nth_field(update, n_diff);
@@ -737,6 +741,8 @@ row_upd_build_difference_binary(
n_diff++;
}
+skip_compare:
+ ;
}
update->n_fields = n_diff;
@@ -1011,13 +1017,13 @@ row_upd_sec_index_entry(
ibool found;
dict_index_t* index;
dtuple_t* entry;
- mtr_t mtr;
btr_pcur_t pcur;
btr_cur_t* btr_cur;
mem_heap_t* heap;
rec_t* rec;
- char* err_buf;
ulint err = DB_SUCCESS;
+ mtr_t mtr;
+ char err_buf[1000];
index = node->index;
@@ -1038,12 +1044,10 @@ row_upd_sec_index_entry(
rec = btr_cur_get_rec(btr_cur);
if (!found) {
- err_buf = mem_alloc(1000);
- dtuple_sprintf(err_buf, 900, entry);
-
fprintf(stderr, "InnoDB: error in sec index entry update in\n"
"InnoDB: index %s table %s\n", index->name,
index->table->name);
+ dtuple_sprintf(err_buf, 900, entry);
fprintf(stderr, "InnoDB: tuple %s\n", err_buf);
rec_sprintf(err_buf, 900, rec);
@@ -1054,8 +1058,6 @@ row_upd_sec_index_entry(
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
trx_print(thr_get_trx(thr));
-
- mem_free(err_buf);
} else {
/* Delete mark the old index record; it can already be
delete marked if we return after a lock wait in
@@ -1620,6 +1622,8 @@ row_upd_step(
trx = thr_get_trx(thr);
+ trx_start_if_not_started(trx);
+
node = thr->run_node;
sel_node = node->select;
@@ -1638,8 +1642,6 @@ row_upd_step(
/* It may be that the current session has not yet
started its transaction, or it has been committed: */
- trx_start_if_not_started(thr_get_trx(thr));
-
err = lock_table(0, node->table, LOCK_IX, thr);
if (err != DB_SUCCESS) {
diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c
index 5b62cd2b7e3..9508e73f45d 100644
--- a/innobase/row/row0vers.c
+++ b/innobase/row/row0vers.c
@@ -300,7 +300,7 @@ row_vers_old_has_index_entry(
if heap2 != NULL */
}
- if ((err != DB_SUCCESS) || !prev_version) {
+ if (err != DB_SUCCESS || !prev_version) {
/* Versions end here */
mem_heap_free(heap);
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 45f7b1b6879..a00f5c95c7c 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -24,7 +24,7 @@ thread library. This might confuse NT though.
Created 10/8/1995 Heikki Tuuri
*******************************************************/
-
+/* Dummy comment */
#include "srv0srv.h"
#include "ut0mem.h"
@@ -48,11 +48,15 @@ Created 10/8/1995 Heikki Tuuri
#include "buf0flu.h"
#include "btr0sea.h"
#include "dict0load.h"
+#include "srv0start.h"
/* The following counter is incremented whenever there is some user activity
in the server */
ulint srv_activity_count = 0;
+ibool srv_lock_timeout_and_monitor_active = FALSE;
+ibool srv_error_monitor_active = FALSE;
+
char* srv_main_thread_op_info = "";
/* Server parameters which are read from the initfile */
@@ -106,9 +110,48 @@ char* srv_unix_file_flush_method_str = NULL;
ulint srv_unix_file_flush_method = 0;
/* If the following is != 0 we do not allow inserts etc. This protects
-the user from forgetting innodb_force_recovery keyword to my.cnf */
+the user from forgetting the innodb_force_recovery keyword to my.cnf */
ulint srv_force_recovery = 0;
+/*-----------------------*/
+/* The following controls how many threads we let inside InnoDB concurrently:
+threads waiting for locks are not counted into the number because otherwise
+we could get a deadlock. MySQL creates a thread for each user session, and
+semaphore contention and convoy problems can occur withput this restriction.
+Value 10 should be good if there are less than 4 processors + 4 disks in the
+computer. Bigger computers need bigger values. */
+
+ulint srv_thread_concurrency = 4;
+
+os_fast_mutex_t srv_conc_mutex; /* this mutex protects srv_conc data
+ structures */
+ulint srv_conc_n_threads = 0; /* number of OS threads currently
+ inside InnoDB */
+
+typedef struct srv_conc_slot_struct srv_conc_slot_t;
+struct srv_conc_slot_struct{
+ os_event_t event; /* event to wait */
+ ibool reserved; /* TRUE if slot
+ reserved */
+ ibool wait_ended; /* TRUE when another
+ thread has already set
+ the event and the
+ thread in this slot is
+ free to proceed; but
+ reserved may still be
+ TRUE at that point */
+ UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue node */
+};
+
+UT_LIST_BASE_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue of threads
+ waiting to get in */
+srv_conc_slot_t srv_conc_slots[OS_THREAD_MAX_N]; /* array of wait
+ slots */
+/*-----------------------*/
+/* If the following is set TRUE then we do not run purge and insert buffer
+merge to completion before shutdown */
+
+ibool srv_fast_shutdown = FALSE;
ibool srv_use_doublewrite_buf = TRUE;
@@ -1512,8 +1555,9 @@ void
srv_init(void)
/*==========*/
{
- srv_slot_t* slot;
- ulint i;
+ srv_conc_slot_t* conc_slot;
+ srv_slot_t* slot;
+ ulint i;
srv_sys = mem_alloc(sizeof(srv_sys_t));
@@ -1556,6 +1600,19 @@ srv_init(void)
ut_a(srv_sys->operational);
UT_LIST_INIT(srv_sys->tasks);
+
+ /* Init the server concurrency restriction data structures */
+
+ os_fast_mutex_init(&srv_conc_mutex);
+
+ UT_LIST_INIT(srv_conc_queue);
+
+ for (i = 0; i < OS_THREAD_MAX_N; i++) {
+ conc_slot = srv_conc_slots + i;
+ conc_slot->reserved = FALSE;
+ conc_slot->event = os_event_create(NULL);
+ ut_a(conc_slot->event);
+ }
}
/*************************************************************************
@@ -1572,6 +1629,140 @@ srv_general_init(void)
}
/*************************************************************************
+Puts an OS thread to wait if there are too many concurrent threads
+(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
+
+void
+srv_conc_enter_innodb(
+/*==================*/
+ trx_t* trx) /* in: transaction object associated with the
+ thread */
+{
+ srv_conc_slot_t* slot;
+ ulint i;
+
+ os_fast_mutex_lock(&srv_conc_mutex);
+
+ if (srv_conc_n_threads < srv_thread_concurrency) {
+ srv_conc_n_threads++;
+
+ os_fast_mutex_unlock(&srv_conc_mutex);
+
+ return;
+ }
+
+ /* Too many threads inside: put to the current thread to a queue */
+
+ for (i = 0; i < OS_THREAD_MAX_N; i++) {
+ slot = srv_conc_slots + i;
+
+ if (!slot->reserved) {
+ break;
+ }
+ }
+
+ if (i == OS_THREAD_MAX_N) {
+ /* Could not find a free wait slot, we must let the
+ thread enter */
+
+ srv_conc_n_threads++;
+
+ os_fast_mutex_unlock(&srv_conc_mutex);
+
+ return;
+ }
+
+ /* Release possible search system latch this thread has */
+ if (trx->has_search_latch) {
+ trx_search_latch_release_if_reserved(trx);
+ }
+
+ /* Add to the queue */
+ slot->reserved = TRUE;
+ slot->wait_ended = FALSE;
+
+ UT_LIST_ADD_LAST(srv_conc_queue, srv_conc_queue, slot);
+
+ os_event_reset(slot->event);
+
+ os_fast_mutex_unlock(&srv_conc_mutex);
+
+ /* Go to wait for the event; when a thread leaves InnoDB it will
+ release this thread */
+
+ os_event_wait(slot->event);
+
+ os_fast_mutex_lock(&srv_conc_mutex);
+
+ /* NOTE that the thread which released this thread already
+ incremented the thread counter on behalf of this thread */
+
+ slot->reserved = FALSE;
+
+ UT_LIST_REMOVE(srv_conc_queue, srv_conc_queue, slot);
+
+ os_fast_mutex_unlock(&srv_conc_mutex);
+}
+
+/*************************************************************************
+This lets a thread enter InnoDB regardless of the number of threads inside
+InnoDB. This must be called when a thread ends a lock wait. */
+
+void
+srv_conc_force_enter_innodb(void)
+/*=============================*/
+{
+ os_fast_mutex_lock(&srv_conc_mutex);
+
+ srv_conc_n_threads++;
+
+ os_fast_mutex_unlock(&srv_conc_mutex);
+}
+
+/*************************************************************************
+This must be called when a thread exits InnoDB. This must also be called
+when a thread goes to wait for a lock. */
+
+void
+srv_conc_exit_innodb(void)
+/*======================*/
+{
+ srv_conc_slot_t* slot = NULL;
+
+ os_fast_mutex_lock(&srv_conc_mutex);
+
+ ut_a(srv_conc_n_threads > 0);
+
+ srv_conc_n_threads--;
+
+ if (srv_conc_n_threads < srv_thread_concurrency) {
+ /* Look for a slot where a thread is waiting and no other
+ thread has yet released the thread */
+
+ slot = UT_LIST_GET_FIRST(srv_conc_queue);
+
+ while (slot && slot->wait_ended == TRUE) {
+ slot = UT_LIST_GET_NEXT(srv_conc_queue, slot);
+ }
+
+ if (slot != NULL) {
+ slot->wait_ended = TRUE;
+
+ /* We increment the count on behalf of the released
+ thread */
+
+ srv_conc_n_threads++;
+ }
+ }
+
+ os_fast_mutex_unlock(&srv_conc_mutex);
+
+ if (slot != NULL) {
+ os_event_set(slot->event);
+ }
+}
+
+/*************************************************************************
Normalizes init parameter values to use units we use inside InnoDB. */
static
ulint
@@ -1713,10 +1904,20 @@ srv_suspend_mysql_thread(
mutex_exit(&kernel_mutex);
+ /* We must declare this OS thread to exit InnoDB, since a possible
+ other thread holding a lock which this thread waits for must be
+ allowed to enter, sooner or later */
+
+ srv_conc_exit_innodb();
+
/* Wait for the release */
os_event_wait(event);
+ /* Return back inside InnoDB */
+
+ srv_conc_force_enter_innodb();
+
mutex_enter(&kernel_mutex);
/* Release the slot for others to use */
@@ -1792,6 +1993,8 @@ srv_lock_timeout_and_monitor_thread(
UT_NOT_USED(arg);
last_monitor_time = time(NULL);
loop:
+ srv_lock_timeout_and_monitor_active = TRUE;
+
/* When someone is waiting for a lock, we wake up every second
and check if a timeout has passed for a lock wait */
@@ -1809,9 +2012,9 @@ loop:
if (time_elapsed > 15) {
- last_monitor_time = time(NULL);
-
if (srv_print_innodb_monitor) {
+
+ last_monitor_time = time(NULL);
printf("=====================================\n");
ut_print_timestamp(stdout);
@@ -1849,8 +2052,9 @@ loop:
printf("--------------\n"
"ROW OPERATIONS\n"
"--------------\n");
- printf("InnoDB main thread state: %s\n",
- srv_main_thread_op_info);
+ printf(
+ "%lu queries inside InnoDB; main thread: %s\n",
+ srv_conc_n_threads, srv_main_thread_op_info);
printf(
"Number of rows inserted %lu, updated %lu, deleted %lu, read %lu\n",
srv_n_rows_inserted,
@@ -1934,7 +2138,7 @@ loop:
(wait_time > (double) srv_lock_wait_timeout
|| wait_time < 0)) {
- /* Timeout exceeded or a wrap over in system
+ /* Timeout exceeded or a wrap-around in system
time counter: cancel the lock request queued
by the transaction and release possible
other transactions waiting behind */
@@ -1949,6 +2153,10 @@ loop:
mutex_exit(&kernel_mutex);
+ if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
+ goto exit_func;
+ }
+
if (some_waits || srv_print_innodb_monitor
|| srv_print_innodb_lock_monitor
|| srv_print_innodb_tablespace_monitor
@@ -1958,11 +2166,16 @@ loop:
/* No one was waiting for a lock and no monitor was active:
suspend this thread */
-
+
+ srv_lock_timeout_and_monitor_active = FALSE;
+
os_event_wait(srv_lock_timeout_thread_event);
goto loop;
+exit_func:
+ srv_lock_timeout_and_monitor_active = FALSE;
+
#ifndef __WIN__
return(NULL);
#else
@@ -1987,11 +2200,18 @@ srv_error_monitor_thread(
{
UT_NOT_USED(arg);
loop:
+ srv_error_monitor_active = TRUE;
+
os_thread_sleep(10000000);
sync_array_print_long_waits();
- goto loop;
+ if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) {
+
+ goto loop;
+ }
+
+ srv_error_monitor_active = FALSE;
#ifndef __WIN__
return(NULL);
@@ -2079,13 +2299,12 @@ loop:
for (i = 0; i < 10; i++) {
n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
-
srv_main_thread_op_info = "sleeping";
os_thread_sleep(1000000);
if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) {
- goto loop;
+ goto suspend_thread;
}
/* We flush the log once in a second even if no commit
@@ -2112,6 +2331,11 @@ loop:
log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
}
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
+
+ goto background_loop;
+ }
+
if (srv_activity_count == old_activity_count) {
if (srv_print_thread_releases) {
@@ -2160,6 +2384,11 @@ loop:
while (n_pages_purged) {
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
+
+ goto background_loop;
+ }
+
srv_main_thread_op_info = "purging";
n_pages_purged = trx_purge();
@@ -2247,7 +2476,12 @@ background_loop:
log_archive_do(FALSE, &n_bytes_archived);
- if (n_pages_purged + n_bytes_merged + n_pages_flushed
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
+ if (n_pages_flushed + n_bytes_archived != 0) {
+
+ goto background_loop;
+ }
+ } else if (n_pages_purged + n_bytes_merged + n_pages_flushed
+ n_bytes_archived != 0) {
goto background_loop;
}
@@ -2261,6 +2495,7 @@ background_loop:
/* There is no work for background operations either: suspend
master thread to wait for more server activity */
+suspend_thread:
srv_main_thread_op_info = "suspending";
mutex_enter(&kernel_mutex);
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index bdc8225a14f..7a429bdfed5 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -60,6 +60,10 @@ ibool srv_startup_is_before_trx_rollback_phase = FALSE;
ibool srv_is_being_started = FALSE;
ibool srv_was_started = FALSE;
+/* At a shutdown the value first climbs to SRV_SHUTDOWN_CLEANUP
+and then to SRV_SHUTDOWN_LAST_PHASE */
+ulint srv_shutdown_state = 0;
+
ibool measure_cont = FALSE;
os_file_t files[1000];
@@ -175,6 +179,34 @@ srv_add_path_separator_if_needed(
}
/*************************************************************************
+Calculates the low 32 bits when a file size which is given as a number
+database pages is converted to the number of bytes. */
+static
+ulint
+srv_calc_low32(
+/*===========*/
+ /* out: low 32 bytes of file size when
+ expressed in bytes */
+ ulint file_size) /* in: file size in database pages */
+{
+ return(0xFFFFFFFF & (file_size << UNIV_PAGE_SIZE_SHIFT));
+}
+
+/*************************************************************************
+Calculates the high 32 bits when a file size which is given as a number
+database pages is converted to the number of bytes. */
+static
+ulint
+srv_calc_high32(
+/*============*/
+ /* out: high 32 bytes of file size when
+ expressed in bytes */
+ ulint file_size) /* in: file size in database pages */
+{
+ return(file_size >> (32 - UNIV_PAGE_SIZE_SHIFT));
+}
+
+/*************************************************************************
Creates or opens the log files. */
static
ulint
@@ -214,8 +246,7 @@ open_or_create_log_file(
return(DB_ERROR);
}
- files[i] = os_file_create(
- name, OS_FILE_OPEN, OS_FILE_AIO,
+ files[i] = os_file_create(name, OS_FILE_OPEN, OS_FILE_AIO,
OS_LOG_FILE, &ret);
if (!ret) {
fprintf(stderr,
@@ -227,8 +258,9 @@ open_or_create_log_file(
ret = os_file_get_size(files[i], &size, &size_high);
ut_a(ret);
- if (size != UNIV_PAGE_SIZE * srv_log_file_size
- || size_high != 0) {
+ if (size != srv_calc_low32(srv_log_file_size)
+ || size_high != srv_calc_high32(srv_log_file_size)) {
+
fprintf(stderr,
"InnoDB: Error: log file %s is of different size\n"
"InnoDB: than specified in the .cnf file!\n", name);
@@ -241,11 +273,13 @@ open_or_create_log_file(
fprintf(stderr,
"InnoDB: Log file %s did not exist: new to be created\n",
name);
- fprintf(stderr, "InnoDB: Setting log file %s size to %lu\n",
- name, UNIV_PAGE_SIZE * srv_log_file_size);
+ fprintf(stderr, "InnoDB: Setting log file %s size to %lu MB\n",
+ name, srv_log_file_size
+ >> (20 - UNIV_PAGE_SIZE_SHIFT));
ret = os_file_set_size(name, files[i],
- UNIV_PAGE_SIZE * srv_log_file_size, 0);
+ srv_calc_low32(srv_log_file_size),
+ srv_calc_high32(srv_log_file_size));
if (!ret) {
fprintf(stderr,
"InnoDB: Error in creating %s: probably out of disk space\n",
@@ -277,8 +311,7 @@ open_or_create_log_file(
if (k == 0 && i == 0) {
arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID;
- fil_space_create("arch_log_space", arch_space_id,
- FIL_LOG);
+ fil_space_create("arch_log_space", arch_space_id, FIL_LOG);
} else {
arch_space_id = ULINT_UNDEFINED;
}
@@ -396,9 +429,14 @@ open_or_create_data_files(
&size_high);
ut_a(ret);
- if (size !=
- UNIV_PAGE_SIZE * srv_data_file_sizes[i]
- || size_high != 0) {
+ /* File sizes in srv_... are given in
+ database pages */
+
+ if (size != srv_calc_low32(
+ srv_data_file_sizes[i])
+ || size_high != srv_calc_high32(
+ srv_data_file_sizes[i])) {
+
fprintf(stderr,
"InnoDB: Error: data file %s is of different size\n"
"InnoDB: than specified in the .cnf file!\n", name);
@@ -426,14 +464,17 @@ open_or_create_data_files(
*create_new_db = TRUE;
}
- fprintf(stderr, "InnoDB: Setting file %s size to %lu\n",
- name, UNIV_PAGE_SIZE * srv_data_file_sizes[i]);
+ fprintf(stderr,
+ "InnoDB: Setting file %s size to %lu MB\n",
+ name, (srv_data_file_sizes[i]
+ >> (20 - UNIV_PAGE_SIZE_SHIFT)));
fprintf(stderr,
"InnoDB: Database physically writes the file full: wait...\n");
ret = os_file_set_size(name, files[i],
- UNIV_PAGE_SIZE * srv_data_file_sizes[i], 0);
+ srv_calc_low32(srv_data_file_sizes[i]),
+ srv_calc_high32(srv_data_file_sizes[i]));
if (!ret) {
fprintf(stderr,
@@ -673,16 +714,28 @@ innobase_start_or_create_for_mysql(void)
return(DB_ERROR);
}
- sum_of_new_sizes = 0;
+ if (sizeof(ulint) == 4
+ && srv_n_log_files * srv_log_file_size >= 262144) {
+
+ fprintf(stderr,
+ "InnoDB: Error: combined size of log files must be < 4 GB\n"
+ "InnoDB: on 32-bit computers\n");
+ return(DB_ERROR);
+ }
+
+ sum_of_new_sizes = 0;
+
for (i = 0; i < srv_n_data_files; i++) {
- if (srv_data_file_sizes[i] >= 262144) {
+#ifndef __WIN__
+ if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= 262144) {
fprintf(stderr,
- "InnoDB: Error: file size must be < 4 GB, or on some OS's < 2 GB\n");
+ "InnoDB: Error: file size must be < 4 GB with this MySQL binary\n"
+ "InnoDB: and operating system combination, in some OS's < 2 GB\n");
return(DB_ERROR);
}
-
+#endif
sum_of_new_sizes += srv_data_file_sizes[i];
}
@@ -889,7 +942,6 @@ innobase_start_or_create_for_mysql(void)
/* Create the thread which warns of long semaphore waits */
os_thread_create(&srv_error_monitor_thread, NULL,
thread_ids + 3 + SRV_MAX_N_IO_THREADS);
-
srv_was_started = TRUE;
srv_is_being_started = FALSE;
@@ -945,7 +997,7 @@ innobase_shutdown_for_mysql(void)
the tablespace header(s), and copy all log data to archive */
logs_empty_and_mark_files_at_shutdown();
-
+
ut_free_all_mem();
return((int) DB_SUCCESS);
diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c
index e4c351b9d21..b82c2a4a2df 100644
--- a/innobase/sync/sync0arr.c
+++ b/innobase/sync/sync0arr.c
@@ -48,6 +48,8 @@ struct sync_cell_struct {
void* wait_object; /* pointer to the object the
thread is waiting for; if NULL
the cell is free for use */
+ mutex_t* old_wait_mutex; /* the latest wait mutex in cell */
+ rw_lock_t* old_wait_rw_lock;/* the latest wait rw-lock in cell */
ulint request_type; /* lock type requested on the
object */
char* file; /* in debug version file where
@@ -353,6 +355,13 @@ sync_array_reserve_cell(
cell->thread = os_thread_get_curr_id();
cell->wait_object = object;
+
+ if (type == SYNC_MUTEX) {
+ cell->old_wait_mutex = object;
+ } else {
+ cell->old_wait_rw_lock = object;
+ }
+
cell->request_type = type;
cell->waiting = FALSE;
@@ -448,7 +457,9 @@ sync_array_cell_print(
difftime(time(NULL), cell->reservation_time));
if (type == SYNC_MUTEX) {
- mutex = (mutex_t*)cell->wait_object;
+ /* We use old_wait_mutex in case the cell has already
+ been freed meanwhile */
+ mutex = cell->old_wait_mutex;
fprintf(file,
"Mutex at %lx created file %s line %lu, lock var %lu\n",
@@ -466,7 +477,7 @@ sync_array_cell_print(
fprintf(file, "S-lock on");
}
- rwlock = (rw_lock_t*)cell->wait_object;
+ rwlock = cell->old_wait_rw_lock;
fprintf(file, " RW-latch at %lx created in file %s line %lu\n",
(ulint)rwlock, rwlock->cfile_name, rwlock->cline);
diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c
index c50ffb65e00..a91ac135f81 100644
--- a/innobase/trx/trx0purge.c
+++ b/innobase/trx/trx0purge.c
@@ -537,13 +537,13 @@ trx_purge_truncate_history(void)
/* We play safe and set the truncate limit at most to the purge view
low_limit number, though this is not necessary */
- if (ut_dulint_cmp(limit_trx_no, (purge_sys->view)->low_limit_no) >= 0) {
- limit_trx_no = (purge_sys->view)->low_limit_no;
+ if (ut_dulint_cmp(limit_trx_no, purge_sys->view->low_limit_no) >= 0) {
+ limit_trx_no = purge_sys->view->low_limit_no;
limit_undo_no = ut_dulint_zero;
}
ut_ad((ut_dulint_cmp(limit_trx_no,
- (purge_sys->view)->low_limit_no) <= 0));
+ purge_sys->view->low_limit_no) <= 0));
rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
@@ -565,7 +565,7 @@ trx_purge_truncate_if_arr_empty(void)
{
ut_ad(mutex_own(&(purge_sys->mutex)));
- if ((purge_sys->arr)->n_used == 0) {
+ if (purge_sys->arr->n_used == 0) {
trx_purge_truncate_history();
@@ -783,7 +783,7 @@ trx_purge_get_next_rec(
ut_ad(mutex_own(&(purge_sys->mutex)));
ut_ad(purge_sys->next_stored);
- space = (purge_sys->rseg)->space;
+ space = purge_sys->rseg->space;
page_no = purge_sys->page_no;
offset = purge_sys->offset;
@@ -936,7 +936,7 @@ trx_purge_fetch_next_rec(
}
if (ut_dulint_cmp(purge_sys->purge_trx_no,
- (purge_sys->view)->low_limit_no) >= 0) {
+ purge_sys->view->low_limit_no) >= 0) {
purge_sys->state = TRX_STOP_PURGE;
trx_purge_truncate_if_arr_empty();
@@ -1072,3 +1072,28 @@ trx_purge(void)
return(purge_sys->n_pages_handled - old_pages_handled);
}
+
+/**********************************************************************
+Prints information of the purge system to stderr. */
+
+void
+trx_purge_sys_print(void)
+/*=====================*/
+{
+ fprintf(stderr, "InnoDB: Purge system view:\n");
+ read_view_print(purge_sys->view);
+
+ fprintf(stderr, "InnoDB: Purge trx n:o %lu %lu, undo n_o %lu %lu\n",
+ ut_dulint_get_high(purge_sys->purge_trx_no),
+ ut_dulint_get_low(purge_sys->purge_trx_no),
+ ut_dulint_get_high(purge_sys->purge_undo_no),
+ ut_dulint_get_low(purge_sys->purge_undo_no));
+ fprintf(stderr,
+ "InnoDB: Purge next stored %lu, page_no %lu, offset %lu,\n"
+ "InnoDB: Purge hdr_page_no %lu, hdr_offset %lu\n",
+ purge_sys->next_stored,
+ purge_sys->page_no,
+ purge_sys->offset,
+ purge_sys->hdr_page_no,
+ purge_sys->hdr_offset);
+}
diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c
index 73153cfaa37..abce470bd1c 100644
--- a/innobase/trx/trx0rec.c
+++ b/innobase/trx/trx0rec.c
@@ -329,7 +329,7 @@ trx_undo_rec_get_pars(
/**************************************************************************
Reads from an undo log record a stored column value. */
-UNIV_INLINE
+static
byte*
trx_undo_rec_get_col_val(
/*=====================*/
@@ -374,13 +374,14 @@ trx_undo_rec_get_row_ref(
mem_heap_t* heap) /* in: memory heap from which the memory
needed is allocated */
{
- ulint i;
dfield_t* dfield;
byte* field;
ulint len;
ulint ref_len;
+ ulint i;
ut_ad(index && ptr && ref && heap);
+ ut_a(index->type & DICT_CLUSTERED);
ref_len = dict_index_get_n_unique(index);
@@ -411,12 +412,13 @@ trx_undo_rec_skip_row_ref(
record, at the start of the row reference */
dict_index_t* index) /* in: clustered index */
{
- ulint i;
- byte* field;
- ulint len;
- ulint ref_len;
+ byte* field;
+ ulint len;
+ ulint ref_len;
+ ulint i;
ut_ad(index && ptr);
+ ut_a(index->type & DICT_CLUSTERED);
ref_len = dict_index_get_n_unique(index);
@@ -468,7 +470,7 @@ trx_undo_page_report_modify(
byte* type_cmpl_ptr;
ulint i;
- ut_ad(index->type & DICT_CLUSTERED);
+ ut_a(index->type & DICT_CLUSTERED);
ut_ad(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
+ TRX_UNDO_PAGE_TYPE) == TRX_UNDO_UPDATE);
table = index->table;
@@ -603,7 +605,7 @@ trx_undo_page_report_modify(
/* Notify purge that it eventually has to free the old
externally stored field */
- (trx->update_undo)->del_marks = TRUE;
+ trx->update_undo->del_marks = TRUE;
*type_cmpl_ptr = *type_cmpl_ptr | TRX_UNDO_UPD_EXTERN;
} else {
@@ -634,7 +636,7 @@ trx_undo_page_report_modify(
if (!update || !(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
- (trx->update_undo)->del_marks = TRUE;
+ trx->update_undo->del_marks = TRUE;
if (trx_undo_left(undo_page, ptr) < 5) {
@@ -787,7 +789,9 @@ Builds an update vector based on a remaining part of an undo log record. */
byte*
trx_undo_update_rec_get_update(
/*===========================*/
- /* out: remaining part of the record */
+ /* out: remaining part of the record,
+ NULL if an error detected, which means that
+ the record is corrupted */
byte* ptr, /* in: remaining part in update undo log
record, after reading the row reference
NOTE that this copy of the undo log record must
@@ -816,6 +820,8 @@ trx_undo_update_rec_get_update(
ulint field_no;
ulint i;
+ ut_a(index->type & DICT_CLUSTERED);
+
if (type != TRX_UNDO_DEL_MARK_REC) {
ptr = trx_undo_update_rec_get_n_upd_fields(ptr, &n_fields);
} else {
@@ -846,11 +852,28 @@ trx_undo_update_rec_get_update(
index);
dfield_set_data(&(upd_field->new_val), buf, DATA_ROLL_PTR_LEN);
- /* Store then the updated ordinary columns to update vector */
+ /* Store then the updated ordinary columns to the update vector */
for (i = 0; i < n_fields; i++) {
ptr = trx_undo_update_rec_get_field_no(ptr, &field_no);
+
+ if (field_no >= dict_index_get_n_fields(index)) {
+ fprintf(stderr,
+ "InnoDB: Error: trying to access update undo rec field %lu in table %s\n"
+ "InnoDB: index %s, but index has only %lu fields\n",
+ field_no, index->table_name, index->name,
+ dict_index_get_n_fields(index));
+ fprintf(stderr,
+ "InnoDB: Send a detailed bug report to mysql@lists.mysql.com");
+
+ fprintf(stderr,
+ "InnoDB: Run also CHECK TABLE on table %s\n", index->table_name);
+ fprintf(stderr,
+ "InnoDB: n_fields = %lu, i = %lu, ptr %lx\n", n_fields, i, (ulint)ptr);
+ return(NULL);
+ }
+
ptr = trx_undo_rec_get_col_val(ptr, &field, &len);
upd_field = upd_get_nth_field(update, i);
@@ -1005,7 +1028,7 @@ trx_undo_report_row_operation(
the update vector, otherwise NULL */
ulint cmpl_info, /* in: compiler info on secondary
index updates */
- rec_t* rec, /* in: case of an update or delete
+ rec_t* rec, /* in: in case of an update or delete
marking, the record in the clustered
index, otherwise NULL */
dulint* roll_ptr) /* out: rollback pointer to the
@@ -1017,11 +1040,13 @@ trx_undo_report_row_operation(
trx_undo_t* undo;
page_t* undo_page;
ulint offset;
- mtr_t mtr;
ulint page_no;
ibool is_insert;
trx_rseg_t* rseg;
+ mtr_t mtr;
+ ut_a(index->type & DICT_CLUSTERED);
+
if (flags & BTR_NO_UNDO_LOG_FLAG) {
*roll_ptr = ut_dulint_zero;
@@ -1030,7 +1055,7 @@ trx_undo_report_row_operation(
}
ut_ad(thr);
- ut_ad(index->type & DICT_CLUSTERED);
+ ut_a(index->type & DICT_CLUSTERED);
ut_ad((op_type != TRX_UNDO_INSERT_OP)
|| (clust_entry && !update && !rec));
@@ -1165,6 +1190,7 @@ trx_undo_get_undo_rec_low(
dulint roll_ptr, /* in: roll pointer to record */
mem_heap_t* heap) /* in: memory heap where copied */
{
+ trx_undo_rec_t* undo_rec;
ulint rseg_id;
ulint page_no;
ulint offset;
@@ -1172,7 +1198,6 @@ trx_undo_get_undo_rec_low(
trx_rseg_t* rseg;
ibool is_insert;
mtr_t mtr;
- trx_undo_rec_t* undo_rec;
trx_undo_decode_roll_ptr(roll_ptr, &is_insert, &rseg_id, &page_no,
&offset);
@@ -1234,7 +1259,8 @@ trx_undo_prev_version_build(
/*========================*/
/* out: DB_SUCCESS, or DB_MISSING_HISTORY if
the previous version is not >= purge_view,
- which means that it may have been removed */
+ which means that it may have been removed,
+ DB_ERROR if corrupted record */
rec_t* index_rec,/* in: clustered index record in the
index tree */
mtr_t* index_mtr,/* in: mtr which contains the latch to
@@ -1255,6 +1281,7 @@ trx_undo_prev_version_build(
dulint table_id;
dulint trx_id;
dulint roll_ptr;
+ dulint old_roll_ptr;
upd_t* update;
byte* ptr;
ulint info_bits;
@@ -1263,19 +1290,38 @@ trx_undo_prev_version_build(
byte* buf;
ulint err;
ulint i;
+ char err_buf[1000];
ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
ut_ad(mtr_memo_contains(index_mtr, buf_block_align(index_rec),
MTR_MEMO_PAGE_S_FIX) ||
mtr_memo_contains(index_mtr, buf_block_align(index_rec),
MTR_MEMO_PAGE_X_FIX));
+ if (!(index->type & DICT_CLUSTERED)) {
+ fprintf(stderr,
+ "InnoDB: Error: trying to access update undo rec for table %s\n"
+ "InnoDB: index %s which is not a clustered index\n",
+ index->table_name, index->name);
+ fprintf(stderr,
+ "InnoDB: Send a detailed bug report to mysql@lists.mysql.com");
+
+ rec_sprintf(err_buf, 900, index_rec);
+ fprintf(stderr, "InnoDB: index record %s\n", err_buf);
+
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record version %s\n", err_buf);
+
+ return(DB_ERROR);
+ }
roll_ptr = row_get_rec_roll_ptr(rec, index);
+ old_roll_ptr = roll_ptr;
+
+ *old_vers = NULL;
if (trx_undo_roll_ptr_is_insert(roll_ptr)) {
/* The record rec is the first inserted version */
- *old_vers = NULL;
return(DB_SUCCESS);
}
@@ -1286,8 +1332,6 @@ trx_undo_prev_version_build(
if (err != DB_SUCCESS) {
- *old_vers = NULL;
-
return(err);
}
@@ -1298,8 +1342,70 @@ trx_undo_prev_version_build(
&info_bits);
ptr = trx_undo_rec_skip_row_ref(ptr, index);
- trx_undo_update_rec_get_update(ptr, index, type, trx_id, roll_ptr,
- info_bits, heap, &update);
+ ptr = trx_undo_update_rec_get_update(ptr, index, type, trx_id,
+ roll_ptr, info_bits, heap, &update);
+
+ if (ut_dulint_cmp(table_id, index->table->id) != 0) {
+ ptr = NULL;
+
+ fprintf(stderr,
+ "InnoDB: Error: trying to access update undo rec for table %s\n"
+ "InnoDB: but the table id in the undo record is wrong\n",
+ index->table_name);
+ fprintf(stderr,
+ "InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n");
+
+ fprintf(stderr,
+ "InnoDB: Run also CHECK TABLE on table %s\n", index->table_name);
+ }
+
+ if (ptr == NULL) {
+ /* The record was corrupted, return an error; these printfs
+ should catch an elusive bug in row_vers_old_has_index_entry */
+
+ fprintf(stderr,
+ "InnoDB: Table name %s, index name %s, n_uniq %lu\n",
+ index->table_name, index->name,
+ dict_index_get_n_unique(index));
+
+ fprintf(stderr,
+ "InnoDB: undo rec address %lx, type %lu cmpl_info %lu\n",
+ (ulint)undo_rec, type, cmpl_info);
+ fprintf(stderr,
+ "InnoDB: undo rec table id %lu %lu, index table id %lu %lu\n",
+ ut_dulint_get_high(table_id),
+ ut_dulint_get_low(table_id),
+ ut_dulint_get_high(index->table->id),
+ ut_dulint_get_low(index->table->id));
+
+ ut_sprintf_buf(err_buf, undo_rec, 150);
+
+ fprintf(stderr, "InnoDB: dump of 150 bytes in undo rec: %s\n",
+ err_buf);
+ rec_sprintf(err_buf, 900, index_rec);
+ fprintf(stderr, "InnoDB: index record %s\n", err_buf);
+
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record version %s\n", err_buf);
+
+ fprintf(stderr,
+ "InnoDB: Record trx id %lu %lu, update rec trx id %lu %lu\n",
+ ut_dulint_get_high(rec_trx_id),
+ ut_dulint_get_low(rec_trx_id),
+ ut_dulint_get_high(trx_id),
+ ut_dulint_get_low(trx_id));
+
+ fprintf(stderr,
+ "InnoDB: Roll ptr in rec %lu %lu, in update rec %lu %lu\n",
+ ut_dulint_get_high(old_roll_ptr),
+ ut_dulint_get_low(old_roll_ptr),
+ ut_dulint_get_high(roll_ptr),
+ ut_dulint_get_low(roll_ptr));
+
+ trx_purge_sys_print();
+
+ return(DB_ERROR);
+ }
if (row_upd_changes_field_size(rec, index, update)) {
diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c
index 2adeb1cf57c..47fffea5e40 100644
--- a/innobase/trx/trx0roll.c
+++ b/innobase/trx/trx0roll.c
@@ -45,6 +45,8 @@ trx_general_rollback_for_mysql(
que_thr_t* thr;
roll_node_t* roll_node;
+ trx_start_if_not_started(trx);
+
heap = mem_heap_create(512);
roll_node = roll_node_create(heap);
@@ -108,6 +110,8 @@ trx_rollback_for_mysql(
err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_mark_sql_stat_end(trx);
+
/* Tell Innobase server that there might be work for
utility threads: */
@@ -144,7 +148,7 @@ trx_rollback_last_sql_stat_for_mysql(
err = trx_general_rollback_for_mysql(trx, TRUE,
&(trx->last_sql_stat_start));
trx_mark_sql_stat_end(trx);
-
+
/* Tell Innobase server that there might be work for
utility threads: */
@@ -229,8 +233,9 @@ loop:
ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0));
- fprintf(stderr, "InnoDB: Rolling back trx no %lu\n",
- ut_dulint_get_low(trx->id));
+ fprintf(stderr, "InnoDB: Rolling back trx with id %lu %lu\n",
+ ut_dulint_get_high(trx->id),
+ ut_dulint_get_low(trx->id));
mutex_exit(&kernel_mutex);
if (trx->dict_operation) {
@@ -246,7 +251,7 @@ loop:
mutex_exit(&kernel_mutex);
fprintf(stderr,
- "InnoDB: Waiting rollback of trx no %lu to end\n",
+ "InnoDB: Waiting for rollback of trx id %lu to end\n",
ut_dulint_get_low(trx->id));
os_thread_sleep(100000);
@@ -272,7 +277,8 @@ loop:
mutex_exit(&(dict_sys->mutex));
}
- fprintf(stderr, "InnoDB: Rolling back of trx no %lu completed\n",
+ fprintf(stderr, "InnoDB: Rolling back of trx id %lu %lu completed\n",
+ ut_dulint_get_high(trx->id),
ut_dulint_get_low(trx->id));
mem_heap_free(heap);
diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c
index 0b8664013d7..e79e4594637 100644
--- a/innobase/trx/trx0sys.c
+++ b/innobase/trx/trx0sys.c
@@ -518,6 +518,10 @@ trx_sys_init_at_db_start(void)
fprintf(stderr,
"InnoDB: %lu uncommitted transaction(s) which must be rolled back\n",
UT_LIST_GET_LEN(trx_sys->trx_list));
+
+ fprintf(stderr, "Trx id counter is %lu %lu\n",
+ ut_dulint_get_high(trx_sys->max_trx_id),
+ ut_dulint_get_low(trx_sys->max_trx_id));
}
UT_LIST_INIT(trx_sys->view_list);
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index 13b37775dce..18c80819245 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -499,7 +499,7 @@ trx_commit_off_kernel(
rseg = trx->rseg;
- if ((trx->insert_undo != NULL) || (trx->update_undo != NULL)) {
+ if (trx->insert_undo != NULL || trx->update_undo != NULL) {
mutex_exit(&kernel_mutex);
@@ -524,7 +524,13 @@ trx_commit_off_kernel(
if (undo) {
mutex_enter(&kernel_mutex);
-#ifdef TRX_UPDATE_UNDO_OPT
+#ifdef notdefined
+ /* ########## There is a bug here: purge and rollback
+ need the whole stack of old record versions even if no
+ consistent read would need them!! This is because they
+ decide on the basis of the old versions when we can
+ remove delete marked secondary index records! */
+
if (!undo->del_marks && (undo->size == 1)
&& (UT_LIST_GET_LEN(trx_sys->view_list) == 1)) {
@@ -584,9 +590,7 @@ trx_commit_off_kernel(
mutex_enter(&kernel_mutex);
}
-#ifdef TRX_UPDATE_UNDO_OPT
-shortcut:
-#endif
+
ut_ad(trx->conc_state == TRX_ACTIVE);
ut_ad(mutex_own(&kernel_mutex));
@@ -1286,6 +1290,8 @@ trx_commit_for_mysql(
sig to the transaction, we must here make sure that trx has been
started. */
+ ut_a(trx);
+
trx->op_info = "committing";
trx_start_if_not_started(trx);
@@ -1309,29 +1315,13 @@ trx_mark_sql_stat_end(
/*==================*/
trx_t* trx) /* in: trx handle */
{
- trx_start_if_not_started(trx);
-
- mutex_enter(&kernel_mutex);
-
- trx->last_sql_stat_start.least_undo_no = trx->undo_no;
-
- mutex_exit(&kernel_mutex);
-}
-
-/**************************************************************************
-Marks the latest SQL statement ended but does not start a new transaction
-if the trx is not started. */
+ ut_a(trx);
-void
-trx_mark_sql_stat_end_do_not_start_new(
-/*===================================*/
- trx_t* trx) /* in: trx handle */
-{
- mutex_enter(&kernel_mutex);
+ if (trx->conc_state == TRX_NOT_STARTED) {
+ trx->undo_no = ut_dulint_zero;
+ }
trx->last_sql_stat_start.least_undo_no = trx->undo_no;
-
- mutex_exit(&kernel_mutex);
}
/**************************************************************************
diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c
index 598090bdee2..8b83163bfc2 100644
--- a/innobase/trx/trx0undo.c
+++ b/innobase/trx/trx0undo.c
@@ -1220,8 +1220,14 @@ trx_undo_lists_init(
for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
page_no = trx_rsegf_get_nth_undo(rseg_header, i, &mtr);
- if (page_no != FIL_NULL) {
-
+ /* In forced recovery: try to avoid operations which look
+ at database pages; undo logs are rapidly changing data, and
+ the probability that they are in an inconsistent state is
+ high */
+
+ if (page_no != FIL_NULL
+ && srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
+
undo = trx_undo_mem_create_at_db_start(rseg, i,
page_no, &mtr);
size += undo->size;
diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c
index 630bd3a9b71..84a79d39556 100644
--- a/innobase/ut/ut0mem.c
+++ b/innobase/ut/ut0mem.c
@@ -78,7 +78,7 @@ ut_malloc_low(
fprintf(stderr,
"InnoDB: Fatal error: cannot allocate %lu bytes of\n"
"InnoDB: memory with malloc! Total allocated memory\n"
- "InnoDB: by InnoDB %lu bytes. Operating system errno: %lu\n"
+ "InnoDB: by InnoDB %lu bytes. Operating system errno: %d\n"
"InnoDB: Cannot continue operation!\n"
"InnoDB: Check if you should increase the swap file or\n"
"InnoDB: ulimits of your operating system.\n",
@@ -155,7 +155,7 @@ ut_free_all_mem(void)
os_fast_mutex_lock(&ut_list_mutex);
- while (block = UT_LIST_GET_FIRST(ut_mem_block_list)) {
+ while ((block = UT_LIST_GET_FIRST(ut_mem_block_list))) {
ut_a(block->magic_n == UT_MEM_MAGIC_N);
ut_a(ut_total_allocated_memory >= block->size);
diff --git a/isam/create.c b/isam/create.c
index bcdd6b0892a..fcf54ddc731 100644
--- a/isam/create.c
+++ b/isam/create.c
@@ -253,14 +253,15 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo,
share.base.fields=fields;
share.base.pack_fields=packed;
share.base.sortkey= (ushort) ~0;
- share.base.max_data_file_length= (pointer == 4) ? ~0L :
+ share.base.max_data_file_length= (pointer == 4) ? (ulong) ~0L :
(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
- (1L << (pointer*8)) :
- (pointer == 3 && reclength >= 256L) ? NI_POS_ERROR :
+ (ulong) (1L << (pointer*8)) :
+ (pointer == 3 && reclength >= 256L) ? (ulong) NI_POS_ERROR :
((ulong) reclength * (1L << (pointer*8)));
share.base.max_key_file_length= (share.base.key_reflength == 3 ?
- NI_POS_ERROR :
- (1L << (share.base.key_reflength*8))*512);
+ NI_POS_ERROR :
+ (ulong)
+ (1L << (share.base.key_reflength*8))*512);
share.base.min_block_length=
(share.base.pack_reclength+3 < N_EXTEND_BLOCK_LENGTH &&
! share.base.blobs) ?
diff --git a/isam/pack_isam.c b/isam/pack_isam.c
index b8814527af2..55f6fbf077b 100644
--- a/isam/pack_isam.c
+++ b/isam/pack_isam.c
@@ -288,7 +288,7 @@ static void usage(void)
-?, --help display this help and exit\n\
-V, --version output version information and exit\n");
print_defaults("my",load_default_groups);
-};
+}
/* reads options */
/* Initiates DEBUG - but no debugging here ! */
diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am
index eb9cf3b78ff..2eaf9709a36 100644
--- a/libmysql/Makefile.am
+++ b/libmysql/Makefile.am
@@ -18,7 +18,7 @@
# This file is public domain and comes with NO WARRANTY of any kind
target = libmysqlclient.la
-target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID -DMYSQL_CLIENT
+target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -DMYSQL_CLIENT
LIBS = @CLIENT_LIBS@
INCLUDES = -I$(srcdir)/../include -I../include \
-I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes)
diff --git a/libmysql/configure.in b/libmysql/configure.in
deleted file mode 100644
index 22179a33971..00000000000
--- a/libmysql/configure.in
+++ /dev/null
@@ -1,230 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-AC_INIT(libmysql.c)
-dnl The version number should be autogenerated from the toplevel configure.in
-AM_INIT_AUTOMAKE(libmysql, 3.23.11-alpha)
-AM_CONFIG_HEADER(my_config.h)
-
-dnl Checks for programs.
-AC_PROG_CC
-AC_PROG_LN_S
-AC_PROG_RANLIB
-
-# We use libtool
-AM_PROG_LIBTOOL
-
-dnl Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS(sgtty.h sys/ioctl.h)
-# Maybe some can be removed but I got sick of adding them on at a time
-# /David
-AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \
- memory.h pwd.h select.h \
- stdlib.h stddef.h \
- strings.h string.h synch.h sys/mman.h sys/socket.h \
- sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
- unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h)
-
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_C_INLINE
-AC_CHECK_SIZEOF(char, 1)
-if test "$ac_cv_sizeof_char" -eq 0
-then
- AC_MSG_ERROR([No size for char type.
-A likely cause for this could be that there isn't any static libraries
-installed. You can verify this by checking if you have libm.a in /lib,
-/usr/lib or some other standard place. If this is the problem,
-install the static libraries and try again. If this isn't the
-problem, examine config.log for possible errors. If you want to
-report this include ALL system information and include at least the
-last 20 rows from config.log!])
-fi
-AC_CHECK_SIZEOF(int, 4)
-if test "$ac_cv_sizeof_int" -eq 0
-then
- AC_MSG_ERROR("No size for int type.")
-fi
-AC_CHECK_SIZEOF(long, 4)
-if test "$ac_cv_sizeof_long" -eq 0
-then
- AC_MSG_ERROR("No size for long type.")
-fi
-AC_CHECK_SIZEOF(long long, 8)
-if test "$ac_cv_sizeof_long_long" -eq 0
-then
- AC_MSG_ERROR("MySQL needs a long long type.")
-fi
-AC_TYPE_SIZE_T
-AC_HEADER_TIME
-AC_TYPE_UID_T
-
-# Do the system files define ulong
-MYSQL_CHECK_ULONG
-# Do the system files define uchar
-MYSQL_CHECK_UCHAR
-# Do the system files define uint
-MYSQL_CHECK_UINT
-
-#---START: Used in for client configure
-# Check base type of last arg to accept
-MYSQL_TYPE_ACCEPT
-#---END:
-
-dnl Checks for library functions.
-AC_TYPE_SIGNAL
-# Standard MySQL list
-AC_CHECK_FUNCS(alarm bmove \
- chsize ftruncate rint finite fpsetmask fpresetsticky\
- cuserid fcntl fconvert \
- getrusage getpwuid getcwd getrlimit getwd index locking longjmp \
- perror pread realpath rename \
- socket strnlen madvise \
- strtoul strtoull snprintf tempnam thr_setconcurrency \
- gethostbyaddr_r gethostbyname_r getpwnam \
- bfill bzero bcmp strstr strpbrk strerror\
- tell atod memcpy memmove \
- setupterm strcasecmp sighold \
- vidattr setupterm lrand48 localtime_r \
- sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \
- pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \
- pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \
- pthread_condattr_create rwlock_init \
- crypt dlopen dlerror fchmod getpass getpassphrase)
-
-# This is special for libmysql
-AC_CHECK_FUNCS(strtok_r)
-
-#---START: Used in for client configure
-
-# Check definition of gethostbyname_r (glibc2.0.100 is different from Solaris)
-ac_save_CXXFLAGS="$CXXFLAGS"
-AC_CACHE_CHECK([style of gethostname_r routines], mysql_cv_gethostname_style,
-AC_LANG_SAVE
-AC_LANG_CPLUSPLUS
-if test "$ac_cv_prog_gxx" = "yes"
-then
- CXXFLAGS="$CXXFLAGS -Werror"
-fi
-AC_TRY_COMPILE(
-[#ifndef SCO
-#define _REENTRANT
-#endif
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>],
-[int skr;
-
- int res = gethostbyname_r((const char *) 0,
- (struct hostent*) 0, (char*) 0, 0, (struct hostent **) 0, &skr);],
-mysql_cv_gethostname_style=glibc2, mysql_cv_gethostname_style=other))
-AC_LANG_RESTORE
-CXXFLAGS="$ac_save_CXXFLAGS"
-if test "$mysql_cv_gethostname_style" = "glibc2"
-then
- AC_DEFINE(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R)
-fi
-
-if test "$with_mit_threads" = "no"
-then
- # Check definition of pthread_getspecific
- AC_CACHE_CHECK("args to pthread_getspecific", mysql_cv_getspecific_args,
- AC_TRY_COMPILE(
-[#ifndef SCO
-#define _REENTRANT
-#endif
-#define _POSIX_PTHREAD_SEMANTICS
-#include <pthread.h> ],
-[ void *pthread_getspecific(pthread_key_t key);
-pthread_getspecific((pthread_key_t) NULL); ],
-mysql_cv_getspecific_args=POSIX, mysql_cv_getspecific_args=other))
- if test "$mysql_cv_getspecific_args" = "other"
- then
- AC_DEFINE(HAVE_NONPOSIX_PTHREAD_GETSPECIFIC)
- fi
-
- # Check definition of pthread_mutex_init
- AC_CACHE_CHECK("args to pthread_mutex_init", mysql_cv_mutex_init_args,
- AC_TRY_COMPILE(
-[#ifndef SCO
-#define _REENTRANT
-#endif
-#define _POSIX_PTHREAD_SEMANTICS
-#include <pthread.h> ],
-[
- pthread_mutexattr_t attr;
- pthread_mutex_t mp;
- pthread_mutex_init(&mp,&attr); ],
-mysql_cv_mutex_init_args=POSIX, mysql_cv_mutex_init_args=other))
- if test "$mysql_cv_mutex_init_args" = "other"
- then
- AC_DEFINE(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT)
- fi
-fi
-#---END:
-
-#---START: Used in for client configure
-# Check definition of readdir_r
-AC_CACHE_CHECK("args to readdir_r", mysql_cv_readdir_r,
-AC_TRY_LINK(
-[#ifndef SCO
-#define _REENTRANT
-#endif
-#define _POSIX_PTHREAD_SEMANTICS
-#include <pthread.h>
-#include <dirent.h>],
-[ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
-readdir_r((DIR *) NULL, (struct dirent *) NULL, (struct dirent **) NULL); ],
-mysql_cv_readdir_r=POSIX, mysql_cv_readdir_r=other))
-if test "$mysql_cv_readdir_r" = "POSIX"
-then
- AC_DEFINE(HAVE_READDIR_R)
-fi
-
-# Check definition av posix sigwait()
-AC_CACHE_CHECK("style of sigwait", mysql_cv_sigwait,
-AC_TRY_LINK(
-[#ifndef SCO
-#define _REENTRANT
-#endif
-#define _POSIX_PTHREAD_SEMANTICS
-#include <pthread.h>
-#include <signal.h>],
-[#ifndef _AIX
-sigset_t set;
-int sig;
-sigwait(&set,&sig);
-#endif],
-mysql_cv_sigwait=POSIX, mysql_cv_sigwait=other))
-if test "$mysql_cv_sigwait" = "POSIX"
-then
- AC_DEFINE(HAVE_SIGWAIT)
-fi
-
-if test "$mysql_cv_sigwait" != "POSIX"
-then
-unset mysql_cv_sigwait
-# Check definition av posix sigwait()
-AC_CACHE_CHECK("style of sigwait", mysql_cv_sigwait,
-AC_TRY_LINK(
-[#ifndef SCO
-#define _REENTRANT
-#endif
-#define _POSIX_PTHREAD_SEMANTICS
-#include <pthread.h>
-#include <signal.h>],
-[sigset_t set;
-int sig;
-sigwait(&set);],
-mysql_cv_sigwait=NONPOSIX, mysql_cv_sigwait=other))
-if test "$mysql_cv_sigwait" = "NONPOSIX"
-then
- AC_DEFINE(HAVE_NONPOSIX_SIGWAIT)
-fi
-fi
-#---END:
-
-AC_OUTPUT(Makefile)
diff --git a/libmysql_r/Makefile.am b/libmysql_r/Makefile.am
index 88a566bdbf9..22d71e00752 100644
--- a/libmysql_r/Makefile.am
+++ b/libmysql_r/Makefile.am
@@ -18,7 +18,7 @@
target = libmysqlclient_r.la
-target_defs = -DDONT_USE_RAID
+target_defs = -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@
## LIBS = @LIBS@
INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include \
diff --git a/myisam/mi_log.c b/myisam/mi_log.c
index 2d00387a945..5c64c130212 100644
--- a/myisam/mi_log.c
+++ b/myisam/mi_log.c
@@ -33,7 +33,7 @@
#undef GETPID /* For HPUX */
#ifdef THREAD
-#define GETPID() (log_type == 1 ? myisam_pid : (long) my_thread_id());
+#define GETPID() (log_type == 1 ? (long) myisam_pid : (long) my_thread_id());
#else
#define GETPID() myisam_pid
#endif
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index b4c9e2f0fd6..853c1de5ed7 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -35,6 +35,10 @@ SET_STACK_SIZE(9000) /* Minimum stack size for program */
#define my_raid_delete(A,B,C) my_delete(A,B)
#endif
+#ifdef OS2
+#define _sanity(a,b)
+#endif
+
static uint decode_bits;
static char **default_argv;
static const char *load_default_groups[]= { "myisamchk", 0 };
diff --git a/myisam/myisampack.c b/myisam/myisampack.c
index a19c5e4d88e..85e55df167a 100644
--- a/myisam/myisampack.c
+++ b/myisam/myisampack.c
@@ -230,7 +230,7 @@ int main(int argc, char **argv)
#endif
}
-enum options {OPT_CHARSETS_DIR_MP=256};
+enum options_mp {OPT_CHARSETS_DIR_MP=256};
static struct option long_options[] =
{
@@ -894,7 +894,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
DBUG_RETURN(error != HA_ERR_END_OF_FILE);
}
-static int compare_huff_elements(void* cmp_arg __attribute__((unused)),
+static int compare_huff_elements(void *not_used __attribute__((unused)),
byte *a, byte *b)
{
return *((my_off_t*) a) < *((my_off_t*) b) ? -1 :
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index c5183ef72c6..71fc7e4b90b 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1,341 +1,222 @@
-drop table if exists t1,t2;
-select from_days(to_days("960101")),to_days(960201)-to_days("19960101"),to_days(date_add(curdate(), interval 1 day))-to_days(curdate()),weekday("1997-11-29");
from_days(to_days("960101")) to_days(960201)-to_days("19960101") to_days(date_add(curdate(), interval 1 day))-to_days(curdate()) weekday("1997-11-29")
1996-01-01 31 1 5
-select period_add("9602",-12),period_diff(199505,"9404") ;
period_add("9602",-12) period_diff(199505,"9404")
199502 13
-select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now());
now()-now() weekday(curdate())-weekday(now()) unix_timestamp()-unix_timestamp(now())
0 0 0
-select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0;
from_unixtime(unix_timestamp("1994-03-02 10:11:12")) from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s") from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0
1994-03-02 10:11:12 1994-03-02 10:11:12 19940302101112
-select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
-sec_to_time(time_to_sec("0:30:47")/6.21);
sec_to_time(9001) sec_to_time(9001)+0 time_to_sec("15:12:22") sec_to_time(time_to_sec("0:30:47")/6.21)
02:30:01 23001 54742 00:04:57
-select now()-curdate()*1000000-curtime();
+sec_to_time(time_to_sec('-838:59:59'))
+-838:59:59
now()-curdate()*1000000-curtime()
0
-select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
strcmp(current_timestamp(),concat(current_date()," ",current_time()))
0
-select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w");
date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")
January Thursday 2nd 1997 97 01 02 03 04 05 4
-select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w"));
date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w"))
January Thursday 2nd 1997 97 01 02 12 00 00 4
-select dayofmonth("1997-01-02"),dayofmonth(19970323);
dayofmonth("1997-01-02") dayofmonth(19970323)
2 23
-select month("1997-01-02"),year("98-02-03"),dayofyear("1997-12-31");
month("1997-01-02") year("98-02-03") dayofyear("1997-12-31")
1 1998 365
-select month("2001-02-00"),year("2001-00-00");
month("2001-02-00") year("2001-00-00")
2 2001
-select DAYOFYEAR("1997-03-03"), WEEK("1998-03-03"), QUARTER(980303);
DAYOFYEAR("1997-03-03") WEEK("1998-03-03") QUARTER(980303)
62 9 1
-select HOUR("1997-03-03 23:03:22"), MINUTE("23:03:22"), SECOND(230322);
HOUR("1997-03-03 23:03:22") MINUTE("23:03:22") SECOND(230322)
23 3 22
-select week(19980101),week(19970101),week(19980101,1),week(19970101,1);
week(19980101) week(19970101) week(19980101,1) week(19970101,1)
-0 0 1 1
-select week(19981231),week(19971231),week(19981231,1),week(19971231,1);
+0 1 1 1
week(19981231) week(19971231) week(19981231,1) week(19971231,1)
-52 52 53 53
-select week(19950101),week(19950101,1);
+52 53 53 53
week(19950101) week(19950101,1)
1 0
-select yearweek('1981-12-31',1),yearweek('1982-01-01',1),yearweek('1982-12-31',1),yearweek('1983-01-01',1);
yearweek('1981-12-31',1) yearweek('1982-01-01',1) yearweek('1982-12-31',1) yearweek('1983-01-01',1)
198153 198153 198252 198252
-select yearweek('1987-01-01',1),yearweek('1987-01-01');
-yearweek('1987-01-01',1) yearweek('1987-01-01')
-198701 198652
-select week("2000-01-01",0) as '2000', week("2001-01-01",0) as '2001', week("2002-01-01",0) as '2002',week("2003-01-01",0) as '2003', week("2004-01-01",0) as '2004', week("2005-01-01",0) as '2005', week("2006-01-01",0) as '2006';
-2000 2001 2002 2003 2004 2005 2006
-0 0 0 0 0 0 1
-select week("2000-01-06",0) as '2000', week("2001-01-06",0) as '2001', week("2002-01-06",0) as '2002',week("2003-01-06",0) as '2003', week("2004-01-06",0) as '2004', week("2005-01-06",0) as '2005', week("2006-01-06",0) as '2006';
-2000 2001 2002 2003 2004 2005 2006
-1 0 1 1 1 1 1
-select week("2000-01-01",1) as '2000', week("2001-01-01",1) as '2001', week("2002-01-01",1) as '2002',week("2003-01-01",1) as '2003', week("2004-01-01",1) as '2004', week("2005-01-01",1) as '2005', week("2006-01-01",1) as '2006';
-2000 2001 2002 2003 2004 2005 2006
-0 1 1 1 1 0 0
-select week("2000-01-06",1) as '2000', week("2001-01-06",1) as '2001', week("2002-01-06",1) as '2002',week("2003-01-06",1) as '2003', week("2004-01-06",1) as '2004', week("2005-01-06",1) as '2005', week("2006-01-06",1) as '2006';
-2000 2001 2002 2003 2004 2005 2006
-1 1 1 2 2 1 1
-select yearweek("2000-01-01",0) as '2000', yearweek("2001-01-01",0) as '2001', yearweek("2002-01-01",0) as '2002',yearweek("2003-01-01",0) as '2003', yearweek("2004-01-01",0) as '2004', yearweek("2005-01-01",0) as '2005', yearweek("2006-01-01",0) as '2006';
-2000 2001 2002 2003 2004 2005 2006
-199952 200053 200152 200252 200352 200452 200601
-select yearweek("2000-01-06",0) as '2000', yearweek("2001-01-06",0) as '2001', yearweek("2002-01-06",0) as '2002',yearweek("2003-01-06",0) as '2003', yearweek("2004-01-06",0) as '2004', yearweek("2005-01-06",0) as '2005', yearweek("2006-01-06",0) as '2006';
-2000 2001 2002 2003 2004 2005 2006
-200001 200053 200201 200301 200401 200501 200601
-select yearweek("2000-01-01",1) as '2000', yearweek("2001-01-01",1) as '2001', yearweek("2002-01-01",1) as '2002',yearweek("2003-01-01",1) as '2003', yearweek("2004-01-01",1) as '2004', yearweek("2005-01-01",1) as '2005', yearweek("2006-01-01",1) as '2006';
-2000 2001 2002 2003 2004 2005 2006
-199952 200101 200201 200301 200401 200453 200552
-select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', yearweek("2002-01-06",1) as '2002',yearweek("2003-01-06",1) as '2003', yearweek("2004-01-06",1) as '2004', yearweek("2005-01-06",1) as '2005', yearweek("2006-01-06",1) as '2006';
-2000 2001 2002 2003 2004 2005 2006
-200001 200101 200201 200302 200402 200501 200601
-select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v');
date_format('1998-12-31','%x-%v') date_format('1999-01-01','%x-%v')
1998-53 1998-53
-select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v');
date_format('1999-12-31','%x-%v') date_format('2000-01-01','%x-%v')
1999-52 1999-52
-select dayname("1962-03-03"),dayname("1962-03-03")+0;
+yearweek('1987-01-01',1) yearweek('1987-01-01')
+198701 198653
dayname("1962-03-03") dayname("1962-03-03")+0
Saturday 5
-select monthname("1972-03-04"),monthname("1972-03-04")+0;
monthname("1972-03-04") monthname("1972-03-04")+0
March 3
-select time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
00|12|0|12|00|AM|12:00:00 AM|00|00:00:00
-select time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
01|01|1|1|02|AM|01:02:03 AM|03|01:02:03
-select time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
13|01|13|1|14|PM|01:14:15 PM|15|13:14:15
-select time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
01|01|1|1|00|AM|01:00:15 AM|15|01:00:15
-select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w');
date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w')
13|01|13|1|14|PM|01:14:15 PM|15|13:14:15| January|Saturday|31st|1998|98|Sat|Jan|031|01|31|01|15|6
-select date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w');
date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w')
NULL
-select date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND);
date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)
1998-01-01 00:00:00
-select date_add("1997-12-31 23:59:59",INTERVAL 1 MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL 1 MINUTE)
1998-01-01 00:00:59
-select date_add("1997-12-31 23:59:59",INTERVAL 1 HOUR);
date_add("1997-12-31 23:59:59",INTERVAL 1 HOUR)
1998-01-01 00:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL 1 DAY);
date_add("1997-12-31 23:59:59",INTERVAL 1 DAY)
1998-01-01 23:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL 1 MONTH);
date_add("1997-12-31 23:59:59",INTERVAL 1 MONTH)
1998-01-31 23:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL 1 YEAR);
date_add("1997-12-31 23:59:59",INTERVAL 1 YEAR)
1998-12-31 23:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL "1:1" MINUTE_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "1:1" MINUTE_SECOND)
1998-01-01 00:01:00
-select date_add("1997-12-31 23:59:59",INTERVAL "1:1" HOUR_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL "1:1" HOUR_MINUTE)
1998-01-01 01:00:59
-select date_add("1997-12-31 23:59:59",INTERVAL "1:1" DAY_HOUR);
date_add("1997-12-31 23:59:59",INTERVAL "1:1" DAY_HOUR)
1998-01-02 00:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL "1 1" YEAR_MONTH);
date_add("1997-12-31 23:59:59",INTERVAL "1 1" YEAR_MONTH)
1999-01-31 23:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL "1:1:1" HOUR_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "1:1:1" HOUR_SECOND)
1998-01-01 01:01:00
-select date_add("1997-12-31 23:59:59",INTERVAL "1 1:1" DAY_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL "1 1:1" DAY_MINUTE)
1998-01-02 01:00:59
-select date_add("1997-12-31 23:59:59",INTERVAL "1 1:1:1" DAY_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "1 1:1:1" DAY_SECOND)
1998-01-02 01:01:00
-select date_sub("1998-01-01 00:00:00",INTERVAL 1 SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL 1 SECOND)
1997-12-31 23:59:59
-select date_sub("1998-01-01 00:00:00",INTERVAL 1 MINUTE);
date_sub("1998-01-01 00:00:00",INTERVAL 1 MINUTE)
1997-12-31 23:59:00
-select date_sub("1998-01-01 00:00:00",INTERVAL 1 HOUR);
date_sub("1998-01-01 00:00:00",INTERVAL 1 HOUR)
1997-12-31 23:00:00
-select date_sub("1998-01-01 00:00:00",INTERVAL 1 DAY);
date_sub("1998-01-01 00:00:00",INTERVAL 1 DAY)
1997-12-31 00:00:00
-select date_sub("1998-01-01 00:00:00",INTERVAL 1 MONTH);
date_sub("1998-01-01 00:00:00",INTERVAL 1 MONTH)
1997-12-01 00:00:00
-select date_sub("1998-01-01 00:00:00",INTERVAL 1 YEAR);
date_sub("1998-01-01 00:00:00",INTERVAL 1 YEAR)
1997-01-01 00:00:00
-select date_sub("1998-01-01 00:00:00",INTERVAL "1:1" MINUTE_SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1" MINUTE_SECOND)
1997-12-31 23:58:59
-select date_sub("1998-01-01 00:00:00",INTERVAL "1:1" HOUR_MINUTE);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1" HOUR_MINUTE)
1997-12-31 22:59:00
-select date_sub("1998-01-01 00:00:00",INTERVAL "1:1" DAY_HOUR);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1" DAY_HOUR)
1997-12-30 23:00:00
-select date_sub("1998-01-01 00:00:00",INTERVAL "1 1" YEAR_MONTH);
date_sub("1998-01-01 00:00:00",INTERVAL "1 1" YEAR_MONTH)
1996-12-01 00:00:00
-select date_sub("1998-01-01 00:00:00",INTERVAL "1:1:1" HOUR_SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1:1" HOUR_SECOND)
1997-12-31 22:58:59
-select date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1" DAY_MINUTE);
date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1" DAY_MINUTE)
1997-12-30 22:59:00
-select date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1:1" DAY_SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1:1" DAY_SECOND)
1997-12-30 22:58:59
-select date_add("1997-12-31 23:59:59",INTERVAL 100000 SECOND);
date_add("1997-12-31 23:59:59",INTERVAL 100000 SECOND)
1998-01-02 03:46:39
-select date_add("1997-12-31 23:59:59",INTERVAL -100000 MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL -100000 MINUTE)
1997-10-23 13:19:59
-select date_add("1997-12-31 23:59:59",INTERVAL 100000 HOUR);
date_add("1997-12-31 23:59:59",INTERVAL 100000 HOUR)
2009-05-29 15:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL -100000 DAY);
date_add("1997-12-31 23:59:59",INTERVAL -100000 DAY)
1724-03-17 23:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL 100000 MONTH);
date_add("1997-12-31 23:59:59",INTERVAL 100000 MONTH)
NULL
-select date_add("1997-12-31 23:59:59",INTERVAL -100000 YEAR);
date_add("1997-12-31 23:59:59",INTERVAL -100000 YEAR)
NULL
-select date_add("1997-12-31 23:59:59",INTERVAL "10000:1" MINUTE_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "10000:1" MINUTE_SECOND)
1998-01-07 22:40:00
-select date_add("1997-12-31 23:59:59",INTERVAL "-10000:1" HOUR_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL "-10000:1" HOUR_MINUTE)
1996-11-10 07:58:59
-select date_add("1997-12-31 23:59:59",INTERVAL "10000:1" DAY_HOUR);
date_add("1997-12-31 23:59:59",INTERVAL "10000:1" DAY_HOUR)
2025-05-19 00:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL "-100 1" YEAR_MONTH);
date_add("1997-12-31 23:59:59",INTERVAL "-100 1" YEAR_MONTH)
1897-11-30 23:59:59
-select date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND)
1999-02-21 17:40:38
-select date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE)
1970-08-11 19:20:59
-select date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND)
2025-05-23 04:40:38
-select "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
"1997-12-31 23:59:59" + INTERVAL 1 SECOND
1998-01-01 00:00:00
-select INTERVAL 1 DAY + "1997-12-31";
INTERVAL 1 DAY + "1997-12-31"
1998-01-01
-select "1998-01-01 00:00:00" - INTERVAL 1 SECOND;
"1998-01-01 00:00:00" - INTERVAL 1 SECOND
1997-12-31 23:59:59
-select date_sub("1998-01-02",INTERVAL 31 DAY);
date_sub("1998-01-02",INTERVAL 31 DAY)
1997-12-02
-select date_add("1997-12-31",INTERVAL 1 SECOND);
date_add("1997-12-31",INTERVAL 1 SECOND)
1997-12-31 00:00:01
-select date_add("1997-12-31",INTERVAL 1 DAY);
date_add("1997-12-31",INTERVAL 1 DAY)
1998-01-01
-select date_add(NULL,INTERVAL 100000 SECOND);
date_add(NULL,INTERVAL 100000 SECOND)
NULL
-select date_add("1997-12-31 23:59:59",INTERVAL NULL SECOND);
date_add("1997-12-31 23:59:59",INTERVAL NULL SECOND)
NULL
-select date_add("1997-12-31 23:59:59",INTERVAL NULL MINUTE_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL NULL MINUTE_SECOND)
NULL
-select date_add("9999-12-31 23:59:59",INTERVAL 1 SECOND);
date_add("9999-12-31 23:59:59",INTERVAL 1 SECOND)
NULL
-select date_sub("0000-00-00 00:00:00",INTERVAL 1 SECOND);
date_sub("0000-00-00 00:00:00",INTERVAL 1 SECOND)
NULL
-select date_add('1998-01-30',Interval 1 month);
date_add('1998-01-30',Interval 1 month)
1998-02-28
-select date_add('1998-01-30',Interval '2:1' year_month);
date_add('1998-01-30',Interval '2:1' year_month)
2000-02-29
-select date_add('1996-02-29',Interval '1' year);
date_add('1996-02-29',Interval '1' year)
1997-02-28
-select extract(YEAR FROM "1999-01-02 10:11:12");
extract(YEAR FROM "1999-01-02 10:11:12")
1999
-select extract(YEAR_MONTH FROM "1999-01-02");
extract(YEAR_MONTH FROM "1999-01-02")
199901
-select extract(DAY FROM "1999-01-02");
extract(DAY FROM "1999-01-02")
2
-select extract(DAY_HOUR FROM "1999-01-02 10:11:12");
extract(DAY_HOUR FROM "1999-01-02 10:11:12")
210
-select extract(DAY_MINUTE FROM "02 10:11:12");
extract(DAY_MINUTE FROM "02 10:11:12")
21011
-select extract(DAY_SECOND FROM "225 10:11:12");
extract(DAY_SECOND FROM "225 10:11:12")
225101112
-select extract(HOUR FROM "1999-01-02 10:11:12");
extract(HOUR FROM "1999-01-02 10:11:12")
10
-select extract(HOUR_MINUTE FROM "10:11:12");
extract(HOUR_MINUTE FROM "10:11:12")
1011
-select extract(HOUR_SECOND FROM "10:11:12");
extract(HOUR_SECOND FROM "10:11:12")
101112
-select extract(MINUTE FROM "10:11:12");
extract(MINUTE FROM "10:11:12")
11
-select extract(MINUTE_SECOND FROM "10:11:12");
extract(MINUTE_SECOND FROM "10:11:12")
1112
-select extract(SECOND FROM "1999-01-02 10:11:12");
extract(SECOND FROM "1999-01-02 10:11:12")
12
-select extract(MONTH FROM "2001-02-00");
extract(MONTH FROM "2001-02-00")
2
-create table t1 (ctime varchar(20));
-insert into t1 values ('2001-01-12 12:23:40');
-select ctime, hour(ctime) from t1;
ctime hour(ctime)
2001-01-12 12:23:40 12
-drop table t1;
-create table t1 (id int);
-create table t2 (id int, date date);
-insert into t1 values (1);
-insert into t2 values (1, "0000-00-00");
-insert into t1 values (2);
-insert into t2 values (2, "2000-01-01");
-select monthname(date) from t1 inner join t2 on t1.id = t2.id;
monthname(date)
NULL
January
-select monthname(date) from t1 inner join t2 on t1.id = t2.id order by t1.id;
monthname(date)
NULL
January
-drop table t1,t2;
-CREATE TABLE t1 (updated text) TYPE=MyISAM;
-INSERT INTO t1 VALUES ('');
-SELECT month(updated) from t1;
month(updated)
NULL
-SELECT year(updated) from t1;
year(updated)
NULL
-drop table t1;
+dayofyear("0000-00-00") dayofyear(d) dayofyear(dt) dayofyear(t) dayofyear(c)
+NULL NULL NULL NULL NULL
+dayofmonth("0000-00-00") dayofmonth(d) dayofmonth(dt) dayofmonth(t) dayofmonth(c)
+0 0 0 0 0
+month("0000-00-00") month(d) month(dt) month(t) month(c)
+0 0 0 0 0
+quarter("0000-00-00") quarter(d) quarter(dt) quarter(t) quarter(c)
+0 0 0 0 0
+week("0000-00-00") week(d) week(dt) week(t) week(c)
+NULL NULL NULL NULL NULL
+year("0000-00-00") year(d) year(dt) year(t) year(c)
+0 0 0 0 0
+yearweek("0000-00-00") yearweek(d) yearweek(dt) yearweek(t) yearweek(c)
+NULL NULL NULL NULL NULL
+to_days("0000-00-00") to_days(d) to_days(dt) to_days(t) to_days(c)
+NULL NULL NULL NULL NULL
+extract(MONTH FROM "0000-00-00") extract(MONTH FROM d) extract(MONTH FROM dt) extract(MONTH FROM t) extract(MONTH FROM c)
+0 0 0 0 0
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index 229604034d8..69943c505f0 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -1,11 +1,6 @@
-drop table if exists t1;
-create table t1 (a int);
-select count(a) as b from t1 where a=0 having b > 0;
b
-insert into t1 values (null);
-select count(a) as b from t1 where a=0 having b > 0;
b
-select count(a) as b from t1 where a=0 having b >=0;
b
0
-drop table t1;
+id start end chr_strand
+133197 813898 813898 -1.0000
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 828c769fdcd..e48c209fed6 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1,107 +1,29 @@
-drop table if exists t1,t2;
-create table t1 (id int primary key);
-create table t2 (id int);
-insert into t1 values (75);
-insert into t1 values (79);
-insert into t1 values (78);
-insert into t1 values (77);
-replace into t1 values (76);
-replace into t1 values (76);
-insert into t1 values (104);
-insert into t1 values (103);
-insert into t1 values (102);
-insert into t1 values (101);
-insert into t1 values (105);
-insert into t1 values (106);
-insert into t1 values (107);
-insert into t2 values (107);
-insert into t2 values (75);
-select t1.id, t2.id from t1, t2 where t2.id = t1.id;
id id
107 107
75 75
-select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id;
id count(t2.id)
75 1
107 1
-select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
id count(t2.id)
75 1
107 1
-drop table t1,t2;
-CREATE TABLE t1 (
-id int(11) NOT NULL auto_increment,
-token varchar(100) DEFAULT '' NOT NULL,
-count int(11) DEFAULT '0' NOT NULL,
-qty int(11),
-phone char(1) DEFAULT '' NOT NULL,
-timestamp datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
-PRIMARY KEY (id),
-KEY token (token(15)),
-KEY timestamp (timestamp),
-UNIQUE token_2 (token(75),count,phone)
-);
-INSERT INTO t1 VALUES (21,'e45703b64de71482360de8fec94c3ade',3,7800,'n','1999-12-23 17:22:21');
-INSERT INTO t1 VALUES (22,'e45703b64de71482360de8fec94c3ade',4,5000,'y','1999-12-23 17:22:21');
-INSERT INTO t1 VALUES (18,'346d1cb63c89285b2351f0ca4de40eda',3,13200,'b','1999-12-23 11:58:04');
-INSERT INTO t1 VALUES (17,'ca6ddeb689e1b48a04146b1b5b6f936a',4,15000,'b','1999-12-23 11:36:53');
-INSERT INTO t1 VALUES (16,'ca6ddeb689e1b48a04146b1b5b6f936a',3,13200,'b','1999-12-23 11:36:53');
-INSERT INTO t1 VALUES (26,'a71250b7ed780f6ef3185bfffe027983',5,1500,'b','1999-12-27 09:44:24');
-INSERT INTO t1 VALUES (24,'4d75906f3c37ecff478a1eb56637aa09',3,5400,'y','1999-12-23 17:29:12');
-INSERT INTO t1 VALUES (25,'4d75906f3c37ecff478a1eb56637aa09',4,6500,'y','1999-12-23 17:29:12');
-INSERT INTO t1 VALUES (27,'a71250b7ed780f6ef3185bfffe027983',3,6200,'b','1999-12-27 09:44:24');
-INSERT INTO t1 VALUES (28,'a71250b7ed780f6ef3185bfffe027983',3,5400,'y','1999-12-27 09:44:36');
-INSERT INTO t1 VALUES (29,'a71250b7ed780f6ef3185bfffe027983',4,17700,'b','1999-12-27 09:45:05');
-CREATE TABLE t2 (
-id int(11) NOT NULL auto_increment,
-category int(11) DEFAULT '0' NOT NULL,
-county int(11) DEFAULT '0' NOT NULL,
-state int(11) DEFAULT '0' NOT NULL,
-phones int(11) DEFAULT '0' NOT NULL,
-nophones int(11) DEFAULT '0' NOT NULL,
-PRIMARY KEY (id),
-KEY category (category,county,state)
-);
-INSERT INTO t2 VALUES (3,2,11,12,5400,7800);
-INSERT INTO t2 VALUES (4,2,25,12,6500,11200);
-INSERT INTO t2 VALUES (5,1,37,6,10000,12000);
-select a.id, b.category as catid, b.state as stateid, b.county as
-countyid from t1 a, t2 b where (a.token =
-'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id);
id catid stateid countyid
27 2 12 11
28 2 12 11
29 2 12 25
26 1 6 37
-select a.id, b.category as catid, b.state as stateid, b.county as
-countyid from t1 a, t2 b where (a.token =
-'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id) order by a.id;
id catid stateid countyid
26 1 6 37
27 2 12 11
28 2 12 11
29 2 12 25
-drop table t1, t2;
-create table t1 (a int primary key);
-insert into t1 values(1),(2);
-select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a);
a
1
2
-select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a) left join t1 as t32 using (a) left join t1 as t33 using (a) left join t1 as t34 using (a) left join t1 as t35 using (a) left join t1 as t36 using (a) left join t1 as t37 using (a) left join t1 as t38 using (a) left join t1 as t39 using (a) left join t1 as t40 using (a) left join t1 as t41 using (a) left join t1 as t42 using (a) left join t1 as t43 using (a) left join t1 as t44 using (a) left join t1 as t45 using (a) left join t1 as t46 using (a) left join t1 as t47 using (a) left join t1 as t48 using (a) left join t1 as t49 using (a) left join t1 as t50 using (a) left join t1 as t51 using (a) left join t1 as t52 using (a) left join t1 as t53 using (a) left join t1 as t54 using (a) left join t1 as t55 using (a) left join t1 as t56 using (a) left join t1 as t57 using (a) left join t1 as t58 using (a) left join t1 as t59 using (a) left join t1 as t60 using (a) left join t1 as t61 using (a) left join t1 as t62 using (a) left join t1 as t63 using (a) left join t1 as t64 using (a) left join t1 as t65 using (a);
-Too many tables. MySQL can only use $MAX_TABLES tables in a join
-drop table t1;
-CREATE TABLE t1 (
-a int(11) NOT NULL,
-b int(11) NOT NULL,
-PRIMARY KEY (a,b)
-) TYPE=MyISAM;
-INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(2,3);
-CREATE TABLE t2 (
-a int(11) default NULL
-) TYPE=MyISAM;
-INSERT INTO t2 VALUES (2),(3);
-SELECT t1.a,t2.a,b FROM t1,t2 WHERE t1.a=t2.a AND (t1.a=1 OR t1.a=2) AND b>=1 AND b<=3;
a a b
2 2 3
-DROP TABLE t1, t2;
+d d
+2001-08-01 NULL
+0000-00-00 NULL
+d
+0000-00-00
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index ec1f64307e4..a052f5f2d92 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -9,6 +9,7 @@ select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_times
select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0;
select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
sec_to_time(time_to_sec("0:30:47")/6.21);
+select sec_to_time(time_to_sec('-838:59:59'));
select now()-curdate()*1000000-curtime();
select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w");
@@ -141,3 +142,21 @@ INSERT INTO t1 VALUES ('');
SELECT month(updated) from t1;
SELECT year(updated) from t1;
drop table t1;
+
+#
+# Check that functions work identically on 0000-00-00 as a constant and on a
+# column
+#
+
+create table t1 (d date, dt datetime, t timestamp, c char(10));
+insert into t1 values ("0000-00-00", "0000-00-00", "0000-00-00", "0000-00-00");
+select dayofyear("0000-00-00"),dayofyear(d),dayofyear(dt),dayofyear(t),dayofyear(c) from t1;
+select dayofmonth("0000-00-00"),dayofmonth(d),dayofmonth(dt),dayofmonth(t),dayofmonth(c) from t1;
+select month("0000-00-00"),month(d),month(dt),month(t),month(c) from t1;
+select quarter("0000-00-00"),quarter(d),quarter(dt),quarter(t),quarter(c) from t1;
+select week("0000-00-00"),week(d),week(dt),week(t),week(c) from t1;
+select year("0000-00-00"),year(d),year(dt),year(t),year(c) from t1;
+select yearweek("0000-00-00"),yearweek(d),yearweek(dt),yearweek(t),yearweek(c) from t1;
+select to_days("0000-00-00"),to_days(d),to_days(dt),to_days(t),to_days(c) from t1;
+select extract(MONTH FROM "0000-00-00"),extract(MONTH FROM d),extract(MONTH FROM dt),extract(MONTH FROM t),extract(MONTH FROM c) from t1;
+drop table t1;
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index a952f5e8d5c..fff5415976c 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -1,10 +1,50 @@
# test of problems with having (Reported by Mark Rogers)
#
-drop table if exists t1;
+drop table if exists t1,t2;
create table t1 (a int);
select count(a) as b from t1 where a=0 having b > 0;
insert into t1 values (null);
select count(a) as b from t1 where a=0 having b > 0;
select count(a) as b from t1 where a=0 having b >=0;
drop table t1;
+
+#
+# Test of problem with HAVING and AVG()
+#
+
+CREATE TABLE t1 (
+ raw_id int(10) NOT NULL default '0',
+ chr_start int(10) NOT NULL default '0',
+ chr_end int(10) NOT NULL default '0',
+ raw_start int(10) NOT NULL default '0',
+ raw_end int(10) NOT NULL default '0',
+ raw_ori int(2) NOT NULL default '0'
+);
+
+INSERT INTO t1 VALUES (469713,1,164123,1,164123,1),(317330,164124,317193,101,153170,1),(469434,317194,375620,101,58527,1),(591816,375621,484273,1,108653,1),(591807,484274,534671,91,50488,1),(318885,534672,649362,101,114791,1),(318728,649363,775520,102,126259,1),(336829,775521,813997,101,38577,1),(317740,813998,953227,101,139330,1),(1,813998,953227,101,139330,1);
+
+CREATE TABLE t2 (
+ id int(10) unsigned NOT NULL default '0',
+ contig_id int(10) unsigned NOT NULL default '0',
+ seq_start int(10) NOT NULL default '0',
+ seq_end int(10) NOT NULL default '0',
+ strand tinyint(2) NOT NULL default '0',
+ KEY id (id)
+);
+INSERT INTO t2 VALUES (133195,469713,61327,61384,1),(133196,469713,64113,64387,1),(133197,1,1,1,0),(133197,1,1,1,-2);
+SELECT e.id,
+ MIN( IF(sgp.raw_ori=1,
+ (e.seq_start+sgp.chr_start-sgp.raw_start),
+ (sgp.chr_start+sgp.raw_end-e.seq_end))) as start,
+ MAX( IF(sgp.raw_ori=1,
+ (e.seq_end+sgp.chr_start-sgp.raw_start),
+ (sgp.chr_start+sgp.raw_end-e.seq_start))) as end,
+ AVG(IF (sgp.raw_ori=1,e.strand,(-e.strand))) as chr_strand
+FROM t1 sgp,
+ t2 e
+WHERE sgp.raw_id=e.contig_id
+GROUP BY e.id
+HAVING chr_strand= -1 and end >= 0
+ AND start <= 999660;
+drop table t1,t2;
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 8ada3fc1142..4bc4b12a22a 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -106,9 +106,17 @@ INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(2,3);
CREATE TABLE t2 (
a int(11) default NULL
) TYPE=MyISAM;
-
INSERT INTO t2 VALUES (2),(3);
-
SELECT t1.a,t2.a,b FROM t1,t2 WHERE t1.a=t2.a AND (t1.a=1 OR t1.a=2) AND b>=1 AND b<=3;
-
DROP TABLE t1, t2;
+
+#
+# TEST LEFT JOIN with DATE columns
+#
+
+CREATE TABLE t1 (d DATE NOT NULL);
+CREATE TABLE t2 (d DATE NOT NULL);
+INSERT INTO t1 (d) VALUES ('2001-08-01'),('0000-00-00');
+SELECT * FROM t1 LEFT JOIN t2 USING (d) WHERE t2.d IS NULL;
+SELECT * from t1 WHERE t1.d IS NULL;
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/rpl000012.test b/mysql-test/t/rpl000012.test
index 01ff9ec8a37..9f8ba9a4f91 100644
--- a/mysql-test/t/rpl000012.test
+++ b/mysql-test/t/rpl000012.test
@@ -9,6 +9,7 @@ insert into t2 select * from t1;
drop table if exists test.t3;
create temporary table test.t3 (n int not null);
alter table test.t3 add primary key(n);
+flush logs;
insert into t3 values (100);
insert into t2 select * from t3;
drop table if exists test.t3;
diff --git a/mysql-test/t/rpl000015-slave.sh b/mysql-test/t/rpl000015-slave.sh
index a421a6f287b..62748605af1 100755
--- a/mysql-test/t/rpl000015-slave.sh
+++ b/mysql-test/t/rpl000015-slave.sh
@@ -1 +1 @@
-rm $MYSQL_TEST_DIR/var/slave-data/master.info
+rm -f $MYSQL_TEST_DIR/var/slave-data/master.info
diff --git a/mysql-test/t/rpl000016-slave.sh b/mysql-test/t/rpl000016-slave.sh
index a421a6f287b..62748605af1 100755
--- a/mysql-test/t/rpl000016-slave.sh
+++ b/mysql-test/t/rpl000016-slave.sh
@@ -1 +1 @@
-rm $MYSQL_TEST_DIR/var/slave-data/master.info
+rm -f $MYSQL_TEST_DIR/var/slave-data/master.info
diff --git a/mysys/mf_cache.c b/mysys/mf_cache.c
index 4b8fc6fed17..85b6b19b328 100644
--- a/mysys/mf_cache.c
+++ b/mysys/mf_cache.c
@@ -38,11 +38,11 @@ static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)),
#else
int length;
if (!(cache->file_name=
- (char*) my_malloc((length=strlen(name)+1),MYF(MY_WME)))
+ (char*) my_malloc((length=strlen(name)+1),MYF(MY_WME))))
{
my_close(cache->file,MYF(0));
cache->file = -1;
- errno=my_error=ENOMEM;
+ errno=my_errno=ENOMEM;
return 1;
}
memcpy(cache->file_name,name,length);
diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c
index d8a67990a52..262fce64277 100644
--- a/mysys/mf_tempfile.c
+++ b/mysys/mf_tempfile.c
@@ -126,6 +126,9 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
// changing environ variable doesn't work with VACPP
char buffer[256];
sprintf( buffer, "TMP=%s", dir);
+ // remove ending backslash
+ if (buffer[strlen(buffer)-1] == '\\')
+ buffer[strlen(buffer)-1] = '\0';
putenv( buffer);
#else
old_env= (char**) environ;
diff --git a/mysys/my_compress.c b/mysys/my_compress.c
index 3f93e55af9c..f68c7607ed2 100644
--- a/mysys/my_compress.c
+++ b/mysys/my_compress.c
@@ -20,8 +20,8 @@
#include <my_global.h>
#ifdef HAVE_COMPRESS
#include <my_sys.h>
-#include <zlib.h>
#include <m_string.h>
+#include <zlib.h>
/*
** This replaces the packet with a compressed packet
diff --git a/mysys/my_os2file64.c b/mysys/my_os2file64.c
index 8964e562ea1..b7ee40d292e 100644
--- a/mysys/my_os2file64.c
+++ b/mysys/my_os2file64.c
@@ -22,7 +22,6 @@ void _OS2errno( APIRET rc);
longlong _lseek64( int fd, longlong offset, int seektype);
int _lock64( int fd, int locktype, my_off_t start,
my_off_t length, myf MyFlags);
-int _sopen64( const char *name, int oflag, int shflag, int mask);
//
// this class is used to define a global c++ variable, that
@@ -255,7 +254,7 @@ int _lock64( int fd, int locktype, my_off_t start,
return(-1);
}
-int _sopen64( const char *name, int oflag, int shflag, int mask)
+int _sopen( const char *name, int oflag, int shflag, int mask)
{
int fail_errno;
APIRET rc = 0;
@@ -325,17 +324,60 @@ int _sopen64( const char *name, int oflag, int shflag, int mask)
return hf;
}
-inline int open( const char *name, int oflag)
+int read( int fd, void *buffer, unsigned int count)
{
- return _sopen64( name, oflag, OPEN_SHARE_DENYNONE, S_IREAD | S_IWRITE);
+ APIRET rc;
+ ULONG actual;
+
+ rc = DosRead( fd, (PVOID) buffer, count, &actual);
+
+ if (!rc)
+ return( actual);/* NO_ERROR */
+
+ // set errno
+ _OS2errno( rc);
+ // write failed
+ return(-1);
}
-inline int open( const char *name, int oflag, int mask)
+int write( int fd, const void *buffer, unsigned int count)
{
- return _sopen64( name, oflag, OPEN_SHARE_DENYNONE, mask);
+ APIRET rc;
+ ULONG actual;
+
+ rc = DosWrite( fd, (PVOID) buffer, count, &actual);
+
+ if (!rc)
+ return( actual);/* NO_ERROR */
+
+ // set errno
+ _OS2errno( rc);
+ // write failed
+ return(-1);
+}
+
+int close( int fd)
+{
+ APIRET rc;
+ ULONG actual;
+
+ rc = DosClose( fd);
+
+ if (!rc)
+ return( 0);/* NO_ERROR */
+
+ // set errno
+ _OS2errno( rc);
+ // write failed
+ return(-1);
}
-inline int sopen( const char *name, int oflag, int shflag, int mask)
+inline int open( const char *name, int oflag)
+{
+ return sopen( name, oflag, OPEN_SHARE_DENYNONE, S_IREAD | S_IWRITE);
+}
+
+inline int open( const char *name, int oflag, int mask)
{
- return _sopen64( name, oflag, shflag, mask);
+ return sopen( name, oflag, OPEN_SHARE_DENYNONE, mask);
}
diff --git a/mysys/my_tempnam.c b/mysys/my_tempnam.c
index 7da037e8d49..fdaf018af0d 100644
--- a/mysys/my_tempnam.c
+++ b/mysys/my_tempnam.c
@@ -15,6 +15,13 @@
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
+/*
+ This function is only used by some old ISAM code.
+ When we remove ISAM support from MySQL, we should also delete this file
+
+ One should instead use the functions in mf_tempfile.c
+*/
+
#include "mysys_priv.h"
#include <m_string.h>
#include "my_static.h"
@@ -95,18 +102,21 @@ my_string my_tempnam(const char *dir, const char *pfx,
// changing environ variable doesn't work with VACPP
char buffer[256];
sprintf( buffer, "TMP=%s", dir);
+ // remove ending backslash
+ if (buffer[strlen(buffer)-1] == '\\')
+ buffer[strlen(buffer)-1] = '\0';
putenv( buffer);
#else
old_env=(char**)environ;
if (dir)
{ /* Don't use TMPDIR if dir is given */
- environ=(const char**)temp_env;
+ environ=(const char**)temp_env; /* May give warning */
temp_env[0]=0;
}
#endif
res=tempnam((char*) dir,(my_string) pfx); /* Use stand. dir with prefix */
#ifndef OS2
- environ=(const char**)old_env;
+ environ=(const char**)old_env; /* May give warning */
#endif
if (!res)
DBUG_PRINT("error",("Got error: %d from tempnam",errno));
diff --git a/os2/BldLevel.cmd b/os2/BldLevel.cmd
new file mode 100644
index 00000000000..2bc85a06abb
--- /dev/null
+++ b/os2/BldLevel.cmd
@@ -0,0 +1,10 @@
+@echo off
+
+REM I'm using resources for BLDLEVEL info, because VA4 linker has the bad
+REM feature of using versionstring content for padding files.
+
+REM To set fixpak level: -P"fixpak level"
+SET MYSQL_VERSION=3.23.42
+SET MYSQL_BUILD=1
+
+BldLevelInf -V%MYSQL_VERSION% -N"MySQL AB, Yuri Dario" -D"MySQL %MYSQL_VERSION% for OS/2 - Build %MYSQL_BUILD%" -Len BldLevel.rc
diff --git a/os2/BldLevel.rc b/os2/BldLevel.rc
new file mode 100644
index 00000000000..fe266a25c3c
--- /dev/null
+++ b/os2/BldLevel.rc
@@ -0,0 +1 @@
+RCDATA 1 { "@#MySQL AB, Yuri Dario:3.23.42#@##1## 10 Sep 2001 11:57:17 paperino::en::::@@MySQL 3.23.42 for OS/2 - Build 1" }
diff --git a/os2/BldLevelInf.cmd b/os2/BldLevelInf.cmd
new file mode 100644
index 00000000000..40a85f3782a
--- /dev/null
+++ b/os2/BldLevelInf.cmd
@@ -0,0 +1,570 @@
+/* $Id: BldLevelInf.cmd,v 1.5 2001/01/26 21:33:13 phaller Exp $
+ *
+ * Adds a Description string to the given .def-file.
+ * Fills in default values; like build time and host.
+ *
+ */
+
+if RxFuncQuery('SysLoadFuncs') = 1 then
+do
+ call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs';
+ call SysLoadFuncs;
+end
+
+
+/*
+ * Set default parameter values.
+ */
+sDefFileIn = '';
+sDefFileOut = '';
+sASDFeatureId = '';
+sCountryCode = '';
+sDateTime = left(' 'date()' 'time(), 26);
+sDescription = 'Odin32';
+sFixPakVer = '';
+sHostname = strip(substr(VALUE('HOSTNAME',,'OS2ENVIRONMENT'), 1, 11));
+sLanguageCode = '';
+sMiniVer = '';
+sVendor = 'Project Odin';
+sVersion = '0.5';
+
+
+/*
+ * Parse parameters.
+ */
+parse arg sArgs
+if (sArgs = '') then
+do
+ call syntax;
+ exit(1);
+end
+
+do while (sArgs <> '')
+ sArgs = strip(sArgs);
+ if (substr(sArgs, 1, 1) = '-' | substr(sArgs, 1, 1) = '/') then
+ do /*
+ * Option.
+ */
+ ch = translate(substr(sArgs, 2, 1));
+ if (pos(ch, 'ACDHLMNPRTV') < 1) then
+ do
+ say 'invalid option:' substr(sArgs, 1, 2);
+ call syntax;
+ exit(2);
+ end
+
+ /* get value and advance sArgs to next or to end. */
+ if (substr(sArgs, 3, 1) = '"') then
+ do
+ iNext = pos('"', sArgs, 4);
+ fQuote = 1;
+ end
+ else
+ do
+ iNext = pos(' ', sArgs, 3);
+ if (iNext <= 0) then
+ iNext = length(sArgs);
+ fQuote = 0;
+ end
+
+ if (iNext > 3 | ch = 'R') then
+ do
+ sValue = substr(sArgs, 3 + fQuote, iNext - 3 - fQuote);
+ sArgs = strip(substr(sArgs, iNext+1));
+ /*say 'iNext:' iNext 'sValue:' sValue 'sArgs:' sArgs; */
+
+ /* check if we're gonna search for something in an file. */
+ if (sValue <> '' & pos('#define=', sValue) > 0) then
+ sValue = LookupDefine(sValue);
+ end
+ else
+ do
+ say 'syntax error near' substr(sArgs, 1, 2)'.';
+ call syntax;
+ exit(3);
+ end
+
+
+ /* set value */
+ select
+ when (ch = 'A') then /* ASD Feature Id */
+ sASDFeatureId = sValue;
+
+ when (ch = 'C') then /* Country code */
+ sCountryCode = sValue;
+
+ when (ch = 'D') then /* Description */
+ sDescription = sValue;
+
+ when (ch = 'H') then /* Hostname */
+ sHostname = sValue;
+
+ when (ch = 'L') then /* Language code */
+ sLanguageCode = sValue;
+
+ when (ch = 'M') then /* MiniVer */
+ sMiniVer = sValue;
+
+ when (ch = 'N') then /* Vendor */
+ sVendor = sValue;
+
+ when (ch = 'R') then /* Vendor */
+ sDescription = ReadDescription(sValue, sDefFile);
+
+ when (ch = 'P') then /* Fixpak version */
+ sFixPakVer = sValue;
+
+ when (ch = 'T') then /* Date Time */
+ sDateTime = sValue;
+
+ when (ch = 'V') then /* Version */
+ sVersion = sValue;
+
+ /* Otherwise it's an illegal option */
+ otherwise
+ say 'invalid option:' substr(sArgs, 1, 2);
+ call syntax;
+ exit(2);
+ end /* select */
+ end
+ else
+ do /*
+ * Defition file...
+ */
+ if (sDefFileOut <> '') then
+ do
+ say 'Syntax error: Can''t specify more than two defintion files!';
+ exit(4);
+ end
+ if (sDefFileIn = '') then
+ parse value sArgs with sDefFileIn' 'sArgs
+ else
+ parse value sArgs with sDefFileOut' 'sArgs
+ sArgs = strip(sArgs);
+ end
+end
+
+
+/* check that a defintion file was specified. */
+if (sDefFileIn = '') then
+do
+ say 'Syntax error: Will have to specify a .def-file to update.';
+ call syntax;
+ exit(5);
+end
+
+
+/*
+ * Trim strings to correct lengths.
+ */
+sVendor = strip(substr(sVendor, 1, 31));
+if (substr(sDateTime, 1, 1) <> ' ') then
+ sDateTime = ' ' || sDateTime;
+sDateTime = left(sDateTime, 26);
+sHostname = strip(substr(sHostname, 1, 11));
+sMiniVer = strip(substr(sMiniVer, 1, 11));
+sDescription = strip(substr(sDescription, 1, 80));
+sCountryCode = strip(substr(sCountryCode, 1, 4));
+sLanguageCode = strip(substr(sLanguageCode, 1, 4));
+sASDFeatureId = strip(substr(sASDFeatureId, 1, 11));
+sFixPakVer = strip(substr(sFixPakVer, 1, 11));
+
+
+/*
+ * Signature
+ */
+sEnhSign = '##1##'
+
+/*
+ * Build description string.
+ */
+sDescription = '@#'sVendor':'sVersion'#@'sEnhSign||,
+ sDateTime||sHostname||,
+ ':'sASDFeatureId':'sLanguageCode':'sCountryCode':'sMiniVer||,
+ '::'sFixPakVer'@@'sDescription;
+
+/*
+ * Update .def-file.
+ */
+call SysFileDelete(sDefFileIn);
+rc = lineout( sDefFileIn, 'RCDATA 1 { "' || sDescription || '" }');
+
+/*rc = UpdateDefFile(sDefFileIn, sDefFileOut, sDescription);*/
+exit(rc);
+
+
+/**
+ * Display script syntax.
+ */
+syntax: procedure
+ say 'Syntax: MakeDesc.cmd [options] <deffile in> <deffile out> [options]'
+ say ' <deffile> Defitionfile which will have an DESCRIPTION appended.'
+ say 'Options:'
+ say ' -A<string> ASD Feature Id.'
+ say ' -C<string> Country code.'
+ say ' -D<string> Description.'
+ say ' -R[deffile] Read description from .def file.'
+ say ' -H<string> Hostname.'
+ say ' -L<string> Language code.'
+ say ' -M<string> MiniVer.'
+ say ' -N<string> Vendor.'
+ say ' -P<string> Fixpak version.'
+ say ' -T<string> Date Time.'
+ say ' -V<string> Version.'
+ say '<string> could be a double qoute qouted string or a single word.'
+ say ' You could also reference #defines in C/C++ include files.'
+ say ' The string should then have this form:'
+ say ' "#define=<DEFINE_NAME>,<includefile.h>"'
+ say '';
+
+ return;
+
+
+/**
+ * Search for a #define in an C/C++ header or source file.
+ *
+ * @returns String containing the defined value
+ * found for the define in the header file.
+ * Quits on fatal errors.
+ * @param A string on the form: "#define=DEFINETOFIND,includefile.h"
+ * @remark Write only code... - let's hope it works.
+ */
+LookupDefine: procedure
+ parse arg '#'sDefine'='sMacro','sIncludeFile
+
+ /*
+ * Validate parameters.
+ */
+ sMacro = strip(sMacro);
+ sIncludeFile = strip(sIncludeFile);
+ if (sMacro = '') then
+ do
+ say 'syntax error: #define=<DEFINE_NAME>,<includefile.h>.';
+ say ' <DEFINE_NAME> was empty.';
+ exit(-20);
+ end
+ if (sIncludeFile = '') then
+ do
+ say 'syntax error: #define=<DEFINE_NAME>,<includefile.h>.';
+ say ' <includefile.h> was empty.';
+ exit(-20);
+ end
+
+
+ sIllegal = translate(translate(sMacro),,
+ '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!',,
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_');
+
+ if (strip(translate(sIllegal, ' ', '!')) <> '') then
+ do
+ say 'syntax error: #define=<DEFINE_NAME>,<includefile.h>.';
+ say ' <DEFINE_NAME> contains illegal charater(s).'
+ say ' 'sMacro;
+ say ' 'translate(sIllegal, ' ', '!');
+ exit(-20);
+ end
+
+ /*
+ * Open include file.
+ */
+ sRc = stream(sIncludeFile, 'c', 'open read');
+ if (pos('READY', sRc) <> 1) then
+ do /* search INCLUDE variable */
+ sFile = SysSearchPath('INCLUDE', sIncludeFile);
+ if (sFile = '') then
+ do
+ say 'Can''t find include file 'sIncludeFile'.';
+ exit(-20);
+ end
+ sIncludeFile = sFile;
+
+ sRc = stream(sIncludeFile, 'c', 'open read');
+ if (pos('READY', sRc) <> 1) then
+ do
+ say 'Failed to open include file' sIncludeFile'.';
+ exit(-20);
+ end
+ end
+
+ /*
+ * Search the file line by line.
+ * We'll check for lines starting with a hash (#) char.
+ * Then check that the word after the hash is 'define'.
+ * Then match the next word with the macro name.
+ * Then then get the next rest of the line to comment or continuation char.
+ * (continuation is not supported)
+ * Finally strip quotes.
+ */
+ sValue = '';
+ do while (lines(sIncludeFile) > 0)
+ sLine = strip(linein(sIncludeFile));
+ if (sLine = '') then
+ iterate;
+ if (substr(sLine, 1, 1) <> '#') then
+ iterate;
+ sLine = substr(sLine, 2);
+ if (word(sLine, 1) <> 'define') then
+ iterate;
+ sLine = strip(substr(sLine, wordpos(sLine, 1) + length('define')+1));
+ if ( substr(sLine, 1, length(sMacro)) <> sMacro,
+ | substr(sLine, length(sMacro)+1, 1) <> ' ') then
+ iterate;
+ sLine = strip(substr(sLine, length(sMacro) + 1));
+ if (sLine = '') then
+ do
+ say 'error: #define' sMacro' is empty.';
+ call stream sIncludeFile, 'c', 'close';
+ exit(-20);
+ end
+
+ chQuote = substr(sLine, 1, 1);
+ if (chQuote = '"' | chQuote = "'") then
+ do /* quoted string */
+ iLastQuote = 0;
+ do forever
+ iLast = pos(chQuote, sLine, 2);
+ if (iLast <= 0) then
+ leave;
+ if (substr(sLine, iLast, 1) = '\') then
+ iterate;
+ iLastQuote = iLast;
+ leave;
+ end
+
+ if (iLastQuote <= 0) then
+ do
+ say 'C/C++ syntax error in 'sIncludefile': didn''t find end quote.';
+ call stream sIncludeFile, 'c', 'close';
+ exit(-20);
+ end
+
+ call stream sIncludeFile, 'c', 'close';
+ sValue = substr(sLine, 2, iLastQuote - 2);
+ say 'Found 'sMacro'='sValue;
+ return sValue;
+ end
+ else
+ do
+ iCommentCPP = pos('//',sLine);
+ iCommentC = pos('/*',sLine);
+ if (iCommentC > 0 & iCommentCPP > 0 & iCommentC > iCommentCPP) then
+ iComment = iCommentCPP;
+ else if (iCommentC > 0 & iCommentCPP > 0 & iCommentC < iCommentCPP) then
+ iComment = iCommentC;
+ else if (iCommentCPP > 0) then
+ iComment = iCommentCPP;
+ else if (iCommentC > 0) then
+ iComment = iCommentC;
+ else
+ iComment = 0;
+
+ if (iComment > 0) then
+ sValue = strip(substr(sLine, 1, iComment-1));
+ else
+ sValue = strip(sLine);
+
+ if (sValue <> '') then
+ do
+ if (substr(sValue, length(sValue)) = '\') then
+ do
+ say 'Found continuation char: Multiline definitions are not supported!\n';
+ call stream sIncludeFile, 'c', 'close';
+ exit(-20);
+ end
+ end
+
+ if (sValue = '') then
+ say 'warning: The #define has no value.';
+
+ call stream sIncludeFile, 'c', 'close';
+ say 'Found 'sMacro'='sValue;
+ return sValue;
+ end
+ end
+
+ call stream sIncludeFile, 'c', 'close';
+ say 'error: didn''t find #define' sMacro'.';
+ exit(-20);
+
+
+
+/**
+ * Reads the description line for a .def-file.
+ * @returns The Description string, with quotes removed.
+ * Empty string is acceptable.
+ * On error we'll terminate the script.
+ * @param sDefFile Filaname of .def-file to read the description from.
+ * @param sDefFile2 Used if sDefFile is empty.
+ * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
+ */
+ReadDescription: procedure;
+ parse arg sDefFile, sDefFile2
+
+ /*
+ * Validate parameters.
+ */
+ if (sDefFile = '') then
+ sDefFile = sDefFile2;
+ if (sDefFile = '') then
+ do
+ say 'error: no definition file to get description from.'
+ exit(-1);
+ end
+
+ /*
+ * Open file
+ */
+ rc = stream(sDefFile, 'c', 'open read');
+ if (pos('READY', rc) <> 1) then
+ do
+ say 'error: failed to open deffile file.';
+ exit(-1);
+ end
+
+
+ /*
+ * Search for the 'DESCRIPTION' line.
+ */
+ do while (lines(sDefFile) > 0)
+ sLine = strip(linein(sDefFile));
+ if (sLine = '') then
+ iterate;
+ if (translate(word(sLine, 1)) <> 'DESCRIPTION') then
+ iterate;
+ sLine = strip(substr(sLine, wordpos(sLine, 1) + length('DESCRIPTION')+1));
+
+ ch = substr(sLine, 1, 1);
+ if (ch <> "'" & ch <> '"') then
+ do
+ say 'syntax error: description line in' sDefFile 'is misformed.';
+ call stream sDefFile, 'c', 'close';
+ exit(-10);
+ end
+
+ iEnd = pos(ch, sLine, 2);
+ if (iEnd <= 0) then
+ do
+ say 'syntax error: description line in' sDefFile 'is misformed.';
+ call stream sDefFile, 'c', 'close';
+ exit(-10);
+ end
+
+ call stream sDefFile, 'c', 'close';
+ sValue = substr(sLine, 2, iEnd - 2);
+ say 'Found Description:' sValue;
+ return sValue;
+ end
+
+ call stream sDefFile, 'c', 'close';
+ say 'info: Didn''t find description line in' sDefFile'.';
+ return '';
+
+
+/**
+ * This is a function which reads sDefFileIn into and
+ * internal array and changes the DESCRIPTION text if found.
+ * If DESCRIPTION isn't found, it is added at the end.
+ * The array is written to sDefFileOut.
+ * @returns 0 on succes.
+ * Errorcode on error.
+ * @param sDefFileIn Input .def-file.
+ * @param sDefFileOut Output .def-file. Overwritten.
+ * @param sDescription New description string.
+ * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
+ */
+UpdateDefFile: procedure;
+ parse arg sDefFileIn, sDefFileOut, sDescription
+
+ /*
+ * Validate parameters.
+ */
+ if (sDefFileOut = '') then
+ sDefFileOut = sDefFileIn;
+
+ /*
+ * Open file input file.
+ */
+ rc = stream(sDefFileIn, 'c', 'open read');
+ if (pos('READY', rc) <> 1) then
+ do
+ say 'error: failed to open' sDefFileIn 'file.';
+ return 110;
+ end
+
+
+ /*
+ * Search for the 'BLDLEVEL' line.
+ */
+ i = 0;
+ fDescription = 0;
+ do while (lines(sDefFileIn) > 0)
+ /*
+ * Read line.
+ */
+ i = i + 1;
+ asFile.i = linein(sDefFileIn);
+
+ /*
+ * Look for BLDLEVEL;
+ */
+ if (asFile.i = '') then
+ iterate;
+ if (translate(word(strip(asFile.i), 1)) <> 'BLDLEVEL') then
+ iterate;
+ if (fDescription) then
+ do
+ say 'warning: multiple descriptions lines. Line' i 'removed';
+ i = i - 1;
+ iterate;
+ end
+
+ /*
+ * Found description - replace with new description.
+ */
+ asFile.i = "BldLevel = '"||sDescription||"'";
+ fDescription = 1;
+ end
+
+ /*
+ * Add description is none was found.
+ */
+ if (\fDescription) then
+ do
+ i = i + 1;
+ asFile.i = "BldLevel = '"||sDescription||"'";
+ end
+ asFile.0 = i;
+
+
+ /*
+ * Close input file and open output file.
+ */
+ call stream sDefFileIn, 'c', 'close';
+ call SysFileDelete(sDefFileOut);
+ rc = stream(sDefFileOut, 'c', 'open write');
+ if (pos('READY', rc) <> 1) then
+ do
+ say 'error: failed to open outputfile' sDefFileOut 'file.';
+ return 110;
+ end
+
+ /*
+ * Make firstline and write all the lines to the output file.
+ */
+ /*call lineout sDefFileOut, '; Updated by makedesc.cmd', 1;*/
+ do i = 1 to asFile.0
+ rc = lineout(sDefFileOut, asFile.i);
+ if (rc > 0) then
+ do
+ say 'error: failed to write line' i 'to' sDefFileOut'.'
+ call stream sDefFileOut, 'c', 'close';
+ return 5;
+ end
+ end
+
+ /*
+ * Close output file and return succesfully.
+ */
+ call stream sDefFileOut, 'c', 'close';
+ return 0;
+
diff --git a/os2/ChangeLog.os2 b/os2/ChangeLog.os2
index 34547262fe2..8f2604c0453 100644
--- a/os2/ChangeLog.os2
+++ b/os2/ChangeLog.os2
@@ -1,4 +1,14 @@
+2001/09/16
+ - fixed creation directory of temporary files
+ - enabled cached list file for deleting temp open files
+
+2001/09/10
+ - Build source 3.23.42, released
+
+2001/09/08
+ - fixed file api
+
2001/06/12
- fixed support for > 2GB file size, needs also DosOpenL
- mixed 64bit/32bit file size support, dinamic loading of
diff --git a/os2/MySQL-Client.icc b/os2/MySQL-Client.icc
index e00fe28a3c9..7a41567f983 100644
--- a/os2/MySQL-Client.icc
+++ b/os2/MySQL-Client.icc
@@ -6,7 +6,6 @@ include "MySQL-Opt.icc"
include "MySQL-Source.icc"
option ProjectOptions = MySQLOptions
- //, link(defaultlibsname, "readline.lib")
{
option file(genobject, "..\\OBJ\\ZLIB\\")
@@ -16,7 +15,7 @@ option ProjectOptions = MySQLOptions
// optimized precompiled headers
option macros('global', 'yes')
{
- source type('cpp') client_pch
+ source type('cpp') client_global_pch
}
// target source files
source zlib
@@ -27,6 +26,8 @@ option ProjectOptions = MySQLOptions
source type('cpp') my_sys_cli
source type('cpp') strings
source type('cpp') mysqlclientlib
+ source type('cpp') '..\libmysql\dll.c'
+ source BldLevelInfo
}
}
@@ -37,51 +38,84 @@ option ProjectOptions = MySQLOptions
// optimized precompiled headers
option macros('global', 'yes')
{
- source type('cpp') client_pch //, 'sql_string.h'
+ source type('cpp') client_global_pch
}
// target source files
- //source readline
source type('cpp') "..\\client\\mysql.cc"
+ source BldLevelInfo
}
}
+ option file(genobject, "..\\OBJ\\READLINE\\")
+ {
target "..\\bin\\mysqladmin.exe"
{
// optimized precompiled headers
option macros('global', 'yes')
{
- source type('cpp') client_pch //, 'sql_string.h'
+ source type('cpp') client_global_pch
}
// target source files
source type('cpp') "..\\client\\mysqladmin.c"
+ source BldLevelInfo
}
+ }
target "..\\bin\\mysqldump.exe"
{
// optimized precompiled headers
option macros('global', 'yes')
{
- source type('cpp') client_pch
+ source type('cpp') client_global_pch
}
// target source files
source type('cpp') "..\\client\\mysqldump.c"
+ source BldLevelInfo
}
target "..\\bin\\mysqlshow.exe"
{
// target source files
source type('cpp') "..\\client\\mysqlshow.c"
+ source BldLevelInfo
}
target "..\\bin\\mysqlimport.exe"
{
// target source files
source type('cpp') "..\\client\\mysqlimport.c"
+ source BldLevelInfo
}
target "..\\bin\\mysqltest.exe"
{
source type('cpp') "..\\client\\mysqltest.c"
+ source BldLevelInfo
+ }
+
+ target "..\\bin\\mysqlbinlog.exe"
+ {
+ // optimized precompiled headers
+ option macros('global', 'yes')
+ {
+ source type('cpp') client_global_pch
+ }
+ // target source files
+ source type('cpp') "..\\client\\mysqlbinlog.cc"
+ source BldLevelInfo
+ }
+
+ target "..\\bin\\mysqlcheck.exe"
+ {
+ // optimized precompiled headers
+ option macros('global', 'yes')
+ {
+ source type('cpp') client_global_pch
+ }
+
+ // target source files
+ source type('cpp') "..\\client\\mysqlcheck.c"
+ source BldLevelInfo
}
}
diff --git a/os2/MySQL-Opt.icc b/os2/MySQL-Opt.icc
index 5f5cdb7c72f..7045f111d9b 100644
--- a/os2/MySQL-Opt.icc
+++ b/os2/MySQL-Opt.icc
@@ -2,29 +2,30 @@
debug_build = 0
// common options
-option BaseOptions = link(defaultlibsname, "tcpip32.lib")
- ,link(libsearchpath, "..\\lib\\")
- ,link(libsearchpath, "..\\bin\\")
- ,link(pmtype, vio)
- ,link(linkwithmultithreadlib, "yes")
- ,link(linkwithsharedlib, "no")
- ,gen(initauto, "yes")
- ,define("__MT__", )
- ,define("HAVE_BSD_SIGNALS", )
- ,define("INCL_DOS", )
- ,define("INCL_DOSERRORS", )
- ,define("INCL_LONGLONG", )
- ,define("OS2", )
- ,define("USE_TLS", )
- ,lang(signedchars, yes)
- ,incl(searchpath, "..")
- ,incl(searchpath, "..\\include")
- ,incl(searchpath, "..\\my_sys")
- ,incl(searchpath, "..\\regex")
- ,incl(searchpath, "..\\sql")
- ,incl(searchpath, "\\rd\\mysql\\zlib-1.1.3")
- ,incl(searchpath, "\\rd\\mysql\\ufc")
- ,incl(searchpath, "..\\os2")
+option BaseOptions = link(defaultlibsname, "tcpip32.lib")
+ , link(libsearchpath, "..\\lib\\")
+ , link(libsearchpath, "..\\bin\\")
+ , link(pmtype, vio)
+ , link(padding, no)
+ , link(linkwithmultithreadlib, "yes")
+ , link(linkwithsharedlib, "no")
+ , gen(initauto, "yes")
+ , define("__MT__", )
+ , define("HAVE_BSD_SIGNALS", )
+ , define("INCL_DOS", )
+ , define("INCL_DOSERRORS", )
+ , define("INCL_LONGLONG", )
+ , define("OS2", )
+ , define("USE_TLS", )
+ , lang(signedchars, yes)
+ , incl(searchpath, "..")
+ , incl(searchpath, "..\\include")
+ , incl(searchpath, "..\\my_sys")
+ , incl(searchpath, "..\\regex")
+ , incl(searchpath, "..\\sql")
+ , incl(searchpath, "..\\..\\zlib-1.1.3")
+ , incl(searchpath, "..\\..\\ufc")
+ , incl(searchpath, "..\\os2")
option ReleaseOptions = link(debug, "no")
, define("DBUG_OFF", )
diff --git a/os2/MySQL-Source.icc b/os2/MySQL-Source.icc
index 48780857185..134a64dc9b0 100644
--- a/os2/MySQL-Source.icc
+++ b/os2/MySQL-Source.icc
@@ -1,4 +1,4 @@
-group client_pch =
+group client_global_pch =
'os2.h',
'assert.h', 'direct.h', 'errno.h', 'nerrno.h',
'limits.h', 'io.h', 'math.h',
@@ -9,17 +9,46 @@ group client_pch =
'my_base.h', 'config-os2.h', 'my_dir.h',
'global.h', 'thr_alarm.h', 'm_string.h',
'mysql.h', 'zconf.h', 'zlib.h', 'mysys_err.h',
- //'my_os2dirsrch.h',
- 'm_ctype.h',
- 'mysqld_error.h',
+ 'm_ctype.h', 'mysqld_error.h',
'my_list.h', 'my_sys.h', 'my_net.h',
- 'myisam.h', 'myisampack.h', '.\myisam\myisamdef.h'
+ 'myisam.h', 'myisampack.h', '.\myisam\myisamdef.h',
+ '.\regex\regex.h'
+
+group server_global_pch =
+ 'os2.h',
+ 'string.h', 'assert.h', 'share.h', 'stdarg.h', 'stdio.h',
+ 'stdlib.h', 'stddef.h', 'math.h', 'io.h', 'limits.h',
+ 'process.h', 'errno.h', 'nerrno.h', 'sys/types.h',
+ 'sys/time.h', 'sys/stat.h', 'sys/param.h', 'sys/ioccom.h',
+ 'sys/filio.h', 'sys/sockio.h', 'sys/ioctlos2.h','sys/ioctl.h', 'types.h',
+ 'sys/utime.h', 'sys/select.h', 'sys/un.h',
+ 'netinet/in_systm.h', 'netinet/tcp.h',
+
+ 'global.h', 'my_base.h', 'config-os2.h',
+ 'my_dir.h', 'my_sys.h', 'mysql.h',
+ 'my_bitmap.h', 'violite.h', 'mysql_priv.h',
+ 'm_string.h', 'm_ctype.h',
+ 'myisam.h', 'myisampack.h', '.\myisam\myisamdef.h',
+ 'sql_string.h', 'item.h', 'unireg.h',
+ 'field.h', 'sql_lex.h', 'sql_list.h',
+ 'md5.h', 'sql_acl.h', 'slave.h',
+ 'ha_myisam.h', 'procedure.h', 'sql_select.h',
+ 'errmsg.h', 't_ctype.h', 'direct.h',
+ 'mysys_err.h', 'zconf.h', 'zlib.h',
+ 'my_tree.h', '..\mysys\my_static.h', 'netdb.h',
+ 'thr_alarm.h', 'heap.h', '..\myisam\fulltext.h',
+ '..\myisam\ftdefs.h', 'myisammrg.h',
+ '.\regex\regex.h'
+
+group server_pch =
+ 'ha_heap.h', 'ha_myisammrg.h', 'opt_ft.h',
+ 'hash_filo.h', 'mini_client.h', 'sql_repl.h',
+ 'sql_analyse.h', 'item_create.h', '..\mysys\mysys_priv.h'
group mysqlclientlib =
"..\\client\\readline.cc",
"..\\client\\sql_string.cc",
"..\\client\\completion_hash.cc",
- //"..\\libmysql\\dll.c",
"..\\libmysql\\libmysql.c",
"..\\libmysql\\errmsg.c",
"..\\libmysql\\get_password.c",
@@ -28,17 +57,17 @@ group mysqlclientlib =
"..\\libmysql\\violite.c"
group zlib =
- "\\rd\\mysql\\zlib-1.1.3\\compress.c", "\\rd\\mysql\\zlib-1.1.3\\crc32.c",
- "\\rd\\mysql\\zlib-1.1.3\\deflate.c", "\\rd\\mysql\\zlib-1.1.3\\gzio.c", "\\rd\\mysql\\zlib-1.1.3\\infblock.c",
- "\\rd\\mysql\\zlib-1.1.3\\infcodes.c", "\\rd\\mysql\\zlib-1.1.3\\inffast.c",
- "\\rd\\mysql\\zlib-1.1.3\\inflate.c", "\\rd\\mysql\\zlib-1.1.3\\inftrees.c",
- "\\rd\\mysql\\zlib-1.1.3\\infutil.c", "\\rd\\mysql\\zlib-1.1.3\\trees.c", "\\rd\\mysql\\zlib-1.1.3\\uncompr.c",
- "\\rd\\mysql\\zlib-1.1.3\\zutil.c", "\\rd\\mysql\\zlib-1.1.3\\adler32.c"
+ "..\\..\\zlib-1.1.3\\compress.c", "..\\..\\zlib-1.1.3\\crc32.c",
+ "..\\..\\zlib-1.1.3\\deflate.c", "..\\..\\zlib-1.1.3\\gzio.c", "..\\..\\zlib-1.1.3\\infblock.c",
+ "..\\..\\zlib-1.1.3\\infcodes.c", "..\\..\\zlib-1.1.3\\inffast.c",
+ "..\\..\\zlib-1.1.3\\inflate.c", "..\\..\\zlib-1.1.3\\inftrees.c",
+ "..\\..\\zlib-1.1.3\\infutil.c", "..\\..\\zlib-1.1.3\\trees.c", "..\\..\\zlib-1.1.3\\uncompr.c",
+ "..\\..\\zlib-1.1.3\\zutil.c", "..\\..\\zlib-1.1.3\\adler32.c"
group ufc =
- "\\rd\\mysql\\ufc\\crypt.c",
- "\\rd\\mysql\\ufc\\crypt_util.c",
- "\\rd\\mysql\\ufc\\crypt-entry.c"
+ "..\\..\\ufc\\crypt.c",
+ "..\\..\\ufc\\crypt_util.c",
+ "..\\..\\ufc\\crypt-entry.c"
group sql =
"..\\sql\\convert.cc",
@@ -106,7 +135,7 @@ group sql =
"..\\sql\\sql_test.cc",
"..\\sql\\sql_update.cc",
"..\\sql\\sql_udf.cc",
- "..\\sql\\sql_yacc.cc",
+ "..\\sql\\sql_yacc.c",
"..\\sql\\table.cc",
"..\\sql\\thr_malloc.cc",
"..\\sql\\time.cc",
@@ -140,8 +169,6 @@ group strings =
"..\\strings\\ctype-sjis.c",
"..\\strings\\ctype-tis620.c",
"..\\strings\\ctype-ujis.c",
- "..\\strings\\ctype_extra_sources.c",
- "..\\strings\\ctype_autoconf.c",
"..\\strings\\ctype.c",
"..\\strings\\int2str.c",
"..\\strings\\is_prefix.c",
@@ -162,6 +189,8 @@ group strings =
"..\\strings\\strxmov.c",
"..\\strings\\strxnmov.c"
+/*
+*/
group heap = "..\\heap\\hp_block.c", "..\\heap\\hp_clear.c",
"..\\heap\\hp_close.c", "..\\heap\\hp_create.c", "..\\heap\\hp_delete.c",
@@ -242,7 +271,8 @@ group strings =
"..\\mysys\\my_thr_init.c", "..\\mysys\\my_vsnprintf.c",
"..\\mysys\\my_write.c", "..\\mysys\\ptr_cmp.c",
"..\\mysys\\queues.c", "..\\mysys\\raid.cc",
- "..\\mysys\\safemalloc.c", "..\\mysys\\string.c",
+ //"..\\mysys\\safemalloc.c",
+ "..\\mysys\\string.c",
"..\\mysys\\thr_alarm.c",
"..\\mysys\\thr_mutex.c", "..\\mysys\\thr_rwlock.c",
"..\\mysys\\tree.c", "..\\mysys\\typelib.c"
@@ -254,11 +284,13 @@ group strings =
"..\\myisam\\ft_search.c", "..\\myisam\\ft_static.c",
"..\\myisam\\ft_stopwords.c", "..\\myisam\\ft_update.c",
"..\\myisam\\mi_cache.c", "..\\myisam\\mi_changed.c",
- "..\\myisam\\mi_check.c", "..\\myisam\\mi_checksum.c",
+ //"..\\myisam\\mi_check.c",
+ "..\\myisam\\mi_checksum.c",
"..\\myisam\\mi_close.c", "..\\myisam\\mi_create.c",
"..\\myisam\\mi_dbug.c", "..\\myisam\\mi_delete.c",
"..\\myisam\\mi_delete_all.c", "..\\myisam\\mi_delete_table.c",
"..\\myisam\\mi_dynrec.c", "..\\myisam\\mi_extra.c",
+ //"..\\myisam\\mi_error.c",
"..\\myisam\\mi_info.c", "..\\myisam\\mi_key.c",
"..\\myisam\\mi_locking.c", "..\\myisam\\mi_log.c",
"..\\myisam\\mi_open.c", "..\\myisam\\mi_packrec.c",
@@ -271,8 +303,8 @@ group strings =
"..\\myisam\\mi_rsamepos.c", "..\\myisam\\mi_scan.c",
"..\\myisam\\mi_search.c", "..\\myisam\\mi_static.c",
"..\\myisam\\mi_statrec.c", "..\\myisam\\mi_unique.c",
- "..\\myisam\\mi_update.c", "..\\myisam\\mi_write.c",
- "..\\myisam\\sort.c"
+ "..\\myisam\\mi_update.c", "..\\myisam\\mi_write.c"
+ //"..\\myisam\\sort.c"
group dbug = "..\\dbug\\dbug.c", "..\\dbug\\factorial.c", "..\\dbug\\sanity.c"
@@ -293,6 +325,7 @@ group strings =
//"..\\readline\\vi_keymap.c",
"..\\readline\\vi_mode.c", "..\\readline\\xmalloc.c"
-group regex = "..\\regex\\regcomp.c", "..\\regex\\regerror.c",
- "..\\regex\\regexec.c", "..\\regex\\regfree.c", "..\\regex\\reginit.c"
+ group regex = "..\\regex\\regcomp.c", "..\\regex\\regerror.c",
+ "..\\regex\\regexec.c", "..\\regex\\regfree.c", "..\\regex\\reginit.c"
+ group BldLevelInfo = 'os2\BldLevel.rc'
diff --git a/os2/MySQL-Sql.icc b/os2/MySQL-Sql.icc
index addb645e2db..c1256d5e39e 100644
--- a/os2/MySQL-Sql.icc
+++ b/os2/MySQL-Sql.icc
@@ -5,6 +5,9 @@ InlineCode = "no"
include "MySQL-Opt.icc"
include "MySQL-Source.icc"
+run before sources('..\sql\sql_yacc.yy') targets('..\sql\sql_yacc.c')
+ 'bison -y -d -o ..\sql\sql_yacc.c ..\sql\sql_yacc.yy'
+
option ProjectOptions = MySQLOptions
, define( "MYSQL_SERVER", "")
{
@@ -16,68 +19,9 @@ option ProjectOptions = MySQLOptions
// optimized precompiled headers
option macros('global', 'yes')
{
- //source type('cpp') gpch
- source type('cpp') 'os2.h'
- source type('cpp')
- //'ctype.h',
- 'string.h', 'assert.h', 'share.h', 'stdarg.h', 'stdio.h',
- 'stdlib.h', 'stddef.h', 'math.h', 'io.h', 'limits.h',
- 'process.h', 'errno.h', 'nerrno.h', 'sys/types.h',
- 'sys/time.h', 'sys/stat.h', 'sys/param.h', 'sys/ioccom.h',
- 'sys/filio.h', 'sys/sockio.h', 'sys/ioctlos2.h','sys/ioctl.h', 'types.h'
-
- source type('cpp')
- 'global.h', 'my_base.h', 'config-os2.h',
- 'my_dir.h', 'my_sys.h', 'mysql.h',
- 'my_bitmap.h', 'violite.h', 'mysql_priv.h',
- 'm_string.h', 'm_ctype.h'
-
- source type('cpp') 'myisam.h'
- source type('cpp') 'myisampack.h'
- source type('cpp') '.\myisam\myisamdef.h'
-
- source type('cpp') 'sql_string.h'
- source type('cpp') 'item.h'
- source type('cpp') 'unireg.h'
- source type('cpp') 'field.h'
- source type('cpp') 'sql_lex.h'
- source type('cpp') 'sql_list.h'
- source type('cpp') 'md5.h'
- source type('cpp') 'sql_acl.h'
- source type('cpp') 'slave.h'
- source type('cpp') 'ha_myisam.h'
- source type('cpp') 'procedure.h'
- source type('cpp') 'sql_select.h'
- source type('cpp') 'errmsg.h'
- source type('cpp') 't_ctype.h'
- source type('cpp') 'direct.h'
- source type('cpp') 'mysys_err.h'
- source type('cpp') 'zconf.h'
- source type('cpp') 'zlib.h'
- source type('cpp') 'my_tree.h'
- source type('cpp') '..\mysys\my_static.h'
- source type('cpp') 'netdb.h'
- source type('cpp') 'thr_alarm.h'
- source type('cpp') 'heap.h'
- source type('cpp') '..\myisam\fulltext.h'
- source type('cpp') '..\myisam\ftdefs.h'
- source type('cpp') 'myisammrg.h'
-
+ source type('cpp') server_global_pch
}
- source type('cpp') 'sys/un.h'
- source type('cpp') 'ha_heap.h'
- source type('cpp') 'ha_myisammrg.h'
- source type('cpp') 'opt_ft.h'
- source type('cpp') 'hash_filo.h'
- source type('cpp') 'mini_client.h'
- source type('cpp') 'sql_repl.h'
- source type('cpp') 'netinet/in_systm.h'
- source type('cpp') 'netinet/tcp.h'
- source type('cpp') 'sql_analyse.h'
- source type('cpp') 'item_create.h'
- source type('cpp') '..\mysys\mysys_priv.h'
- source type('cpp') 'sys/utime.h'
- source type('cpp') 'sys/select.h'
+ source type('cpp') server_pch
// target source files
source "rint.obj"
@@ -93,25 +37,10 @@ option ProjectOptions = MySQLOptions
source type('cpp') my_sys
source type('cpp') my_sys_sql
source type('cpp') strings
- source type('cpp') sql
- }
- }
-/*
- option define( "MYSQL_SERVER", "")
- {
- target "..\\bin\\mysqlbinlog.exe"
- {
- // optimized precompiled headers
- option macros('global', 'yes')
- {
- //source type('cpp') client_pch //, 'sql_string.h'
- }
- // target source files
- source type('cpp')
- "..\\sql\\mysqlbinlog.cc",
- "..\\sql\\mini_client.cc",
- "..\\sql\\net_serv.cc"
+ source type('cpp') sql,
+ "..\\myisam\\mi_check.c",
+ "..\\myisam\\sort.c"
+ source BldLevelInfo
}
}
-*/
}
diff --git a/os2/MySQL-Util.icc b/os2/MySQL-Util.icc
index 61b1f53bc5f..5a7ae2959b9 100644
--- a/os2/MySQL-Util.icc
+++ b/os2/MySQL-Util.icc
@@ -6,20 +6,51 @@ include "MySQL-Opt.icc"
include "MySQL-Source.icc"
option ProjectOptions = MySQLOptions
- , link(defaultlibsname, "common.lib")
- , link(defaultlibsname, "myisam.lib")
- , link(defaultlibsname, "isam.lib")
- , link(defaultlibsname, "mysql.lib")
+ , link(defaultlibsname, "mysql.lib")
{
+ option file(genobject, "..\\OBJ\\ZLIB\\")
+ ,link(exportAll)
+ {
+ target "..\\bin\\mysqlu.dll"
+ {
+ // optimized precompiled headers
+ option macros('global', 'yes')
+ {
+ source type('cpp') client_global_pch
+ }
+ // target source files
+ source zlib, ufc, regex, 'strings\bmove_upp.c'
+ if debug_build {
+ source type('cpp') dbug
+ }
+ source type('cpp') heap
+ source type('cpp') merge
+ source type('cpp') myisam
+ source type('cpp') myisammrg
+ source type('cpp') isam
+ source type('cpp') my_sys
+ source type('cpp') my_sys_cli
+ source type('cpp') my_sys_sql
+ source type('cpp') strings
+ source type('cpp') '..\libmysql\dll.c'
+ source BldLevelInfo
+ }
+ }
+
+
target "..\\bin\\myisamchk.exe"
{
// optimized precompiled headers
option macros('global', 'yes')
{
- source type('cpp') client_pch
+ source type('cpp') client_global_pch
}
- source type('cpp') "..\\myisam\\myisamchk.c"
+ // target source files
+ source type('cpp') "..\\myisam\\myisamchk.c",
+ "..\\myisam\\mi_check.c",
+ "..\\myisam\\sort.c"
+ source BldLevelInfo
}
target "..\\bin\\myisamlog.exe"
@@ -27,11 +58,11 @@ option ProjectOptions = MySQLOptions
// optimized precompiled headers
option macros('global', 'yes')
{
- source type('cpp') client_pch
+ source type('cpp') client_global_pch
}
-
// target source files
source type('cpp') "..\\myisam\\myisamlog.c"
+ source BldLevelInfo
}
target "..\\bin\\myisampack.exe"
@@ -39,10 +70,23 @@ option ProjectOptions = MySQLOptions
// optimized precompiled headers
option macros('global', 'yes')
{
- source type('cpp') client_pch
+ source type('cpp') client_global_pch
}
// target source files
source type('cpp') "..\\myisam\\myisampack.c"
+ source BldLevelInfo
+ }
+
+ target "..\\bin\\test\\comp_err.exe"
+ {
+ // target source files
+ source type('cpp') "..\\extra\\comp_err.c"
+ }
+
+ target "..\\bin\\gen_lex_hash.exe"
+ {
+ // target source files
+ source type('cpp') "..\\sql\\gen_lex_hash.cc"
}
target "..\\bin\\test\\is_test1.exe"
@@ -75,13 +119,13 @@ option ProjectOptions = MySQLOptions
// target source files
source type('cpp') "..\\myisam\\ft_test1.c"
}
-
- //target "..\\bin\\test\\testhash.exe"
+/*
+ target "..\\bin\\test\\testhash.exe"
{
// target source files
- //source type('cpp') "..\\mysys\\testhash.c"
+ source type('cpp') "..\\mysys\\testhash.c"
}
-
+*/
target "..\\bin\\test\\test_charset.exe"
{
// target source files
@@ -99,6 +143,7 @@ option ProjectOptions = MySQLOptions
source type('cpp') "..\\heap\\hp_test2.c"
}
+/*
option define( "MAIN", "")
{
target "..\\bin\\test\\thr_lock.exe"
@@ -107,13 +152,13 @@ option ProjectOptions = MySQLOptions
source type('cpp') "..\\mysys\\thr_lock.c"
}
}
-
+*/
target "..\\bin\\test\\insert_test.exe"
{
// optimized precompiled headers
option macros('global', 'yes')
{
- source type('cpp') client_pch
+ source type('cpp') client_global_pch
}
source type('cpp') "..\\client\\insert_test.c"
}
@@ -126,9 +171,12 @@ option ProjectOptions = MySQLOptions
// optimized precompiled headers
option macros('global', 'yes')
{
- source type('cpp') client_pch
+ source type('cpp') client_global_pch
}
source type('cpp') "..\\client\\thread_test.c"
}
}
+
+run after sources('..\bin\gen_lex_hash.exe') targets('..\sql\lex_hash.h')
+ '..\bin\gen_lex_has.exe > ..\sql\lex_hash.h'
diff --git a/os2/ReadMe.txt b/os2/ReadMe.txt
new file mode 100644
index 00000000000..1a8158df4bf
--- /dev/null
+++ b/os2/ReadMe.txt
@@ -0,0 +1,177 @@
+====================================================
+
+Contents
+--------
+Welcome to the latest port of MySQL for OS/2 and eComStation.
+
+Modules included in this build:
+ - protocol data compression
+ - transaction support
+ - perl BDB/BDI support (not in this package)
+ - Library and header files for C/CPP developers included
+
+This package has been built using IBM VAC++ 4.0
+
+The MySQL server is distributed under the GPL license. Please refer to
+the file COPYING for the license information.
+
+The MySQL client library is distributed under the LGPL license.
+Please refer to the file COPYING for the license information.
+
+Most of the MySQL clients are distributed under the GPL license, but
+some files may be in the public domain.
+
+The latest information about MySQL can be found at: http://www.mysql.com
+
+To get the latest information about this port please subscribe to our
+newsgroup/mailinglist mysql2 at www.egroups.com.
+
+To see what MySQL can do, take a look at the features section in the
+manual. For future plans see the TODO appendix in the manual.
+
+New features/bug fixes history is in the news appendix in the manual.
+
+For the currently known bugs/misfeatures (known errors) see the bugs
+appendix in the manual. The OS/2 section contains notes that are
+specific to the MySQL OS/2 and eComStation version.
+
+Please note that MySQL is a constantly moving target. New builds for
+Linux are made available every week. This port may therefore be a few
+minor versions after the latest Linux/Win32 builds but its generally
+more stable than the "latest and greates" port.
+
+MySQL is brought to you by: TcX DataKonsult AB & MySQL Finland AB
+
+This port is brought to you by:
+
+Yuri Dario <mc6530@mclink.it>, development, porting
+Timo Maier <tam@gmx.de>, documentation, testing
+John M Alfredsson <jma@jmast.se>, documentation, testing
+
+
+Installation
+------------
+Prerequisite:
+
+- OS/2 Warp 3 with FP ?? or later,
+ OS/2 Warp 4 with FP ?? or later,
+ OS/2 Warp Server for e-Business,
+ eComStation 1.0 (prev 1/2 OK)
+- TCPIP 4.x installed (requires 32-bit tcpip stack)
+- WarpIN installer 0.9.14 (ftp://ftp.os2.org/xworkplace/warpin-0-9-14.exe)
+
+Note: probably some fixpak level is required on both Warp3&Warp4 to
+ support >2GB file sizes.
+
+Save the installation archives into a temporary folder and double click
+on the main package; otherwise you can drop the mysql package in your
+WarpIN object or type
+
+ WARPIN MYSQL-3-23-??-BLD1.WPI
+
+from the command line.
+The configuration file for MySQL is named my.cnf and it is placed into
+your %ETC% directory. Usually it located into the boot driver under
+
+ x:\MPTN\ETC
+
+If the installation detect an existing configuration file, this will be
+renamed to my.cnf.bak; your current settings aren't migrated to current
+installation. This file is not deleted by uninstall process.
+Startup options for MySQL daemon could be added there.
+
+As default, client connections uses data compression: if you don't like it,
+remove the following from your %ETC%\my.cnf
+
+ [client]
+ compress
+
+The server switches automatically compression mode on client request.
+
+This release comes with DLL client library MYSQL.DLL: it is installed by
+default into mysql\bin together with client applications. Copy it to your
+x:\OS2\DLL or another directory in your LIBPATH to run command line
+utilities from every place.
+
+
+Documentation
+-------------
+Documentation is provided in separate files. You can use either
+the PDF documentation (requires Adobe Acrobat Reader) or the
+INF documentation (requires OS/2 view or NewView).
+
+The PDF documentation is found in
+
+ MYSQL-3-23-42-PDF.WPI
+
+and the INF documentation is found in
+
+ MYSQL-3-23-28-INF.WPI
+
+The latest documentation in other formats can always be downloaded from
+http://www.mysql.com. However this documentation may not fully apply to
+this port.
+The INF documentation could contain errors because of semi-automatic
+translation from texi original. Also it is not updated as the latest PDF
+manual (sorry, but conversion from texi to ipf requires quite a lot of
+work).
+
+
+Support
+-------
+Since MySQL is a OpenSource freeware product there are no
+formal support options available.
+
+Please subscribe to mysql2 at www.yahoogroups.com to get in contact
+with other users using this port.
+
+http://www.yahoogroups.com/group/mysql2
+
+This newsgroup/mailinglist is the official "home" of this port.
+
+
+Donations
+---------
+Since this software is ported for free, donations are welcome!
+You can get also an extended support, which is not free and subject to
+custom rates.
+Ask in the mailing list for details.
+
+
+Know problems
+-------------
+alter_table.test and show_check are failing, reporting a different status
+message: actually seems only a different text, no bugs in table checking.
+
+
+Apache/2 + PHP
+--------------
+To avoid problems with different socket when you use PHP and Apache
+webserver, get the PHP4 module from the Apache Server for OS/2 homepage
+http://silk.apana.org.au/apache/
+
+
+Developing MySQL
+----------------
+If you want to help us develop MySQL for OS2/eComStation please join
+the mysql2 mailinglist at www.egroups.com and ask for help to set up
+your environment!
+
+All questions that are specific to the OS2/eComStation version should
+be posted to this list! Please remember to include all relevant
+information that may help solve your problem.
+
+Building MySQL (VAC++ 4)
+------------------------
+Apply file and patches found in the src\ directory (if exists).
+Create the following subdirectories
+
+ bin\
+ bin\test
+ lib\
+ obj\
+ obj\zlib
+
+Build os2\MySQL-Client.icc project first.
+Then os2\MySQL-Util.icc; last is os2\MySQL-Sql.icc
+
diff --git a/os2/mysql-inf.wis b/os2/mysql-inf.wis
new file mode 100644
index 00000000000..55259567a2e
--- /dev/null
+++ b/os2/mysql-inf.wis
@@ -0,0 +1,15 @@
+#include "mysql.ih"
+
+<WARPIN VERSION <$WARPIN_VERSION>>
+<HEAD>
+<MSG>
+This is not an installable archive.
+
+Please download and install the main archive:
+
+ mysql-<$MySQL-Ver>-bld1.wpi
+
+</MSG>
+</HEAD>
+</WARPIN>
+ \ No newline at end of file
diff --git a/os2/mysql.wis b/os2/mysql.wis
new file mode 100644
index 00000000000..50207a0c499
--- /dev/null
+++ b/os2/mysql.wis
@@ -0,0 +1,127 @@
+#include "mysql.ih"
+
+<WARPIN VERSION <$WARPIN_VERSION>>
+<HEAD>
+
+<PCK INDEX=1
+ PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\SQL Database Engine\<$MySQL\Ver>"
+ TARGET="?:\usr\local\mysql" BASE
+ TITLE="SQL Database Engine"
+ EXECUTE="$(1)\bootstrap.cmd [bootstrap]"
+ CONFIG.SYS="SET EMXOPT=-h1024 | UNIQUE(-h)"
+ CREATEOBJECT="WPFolder|MySQL <$MySQL.Ver>|<WP_DESKTOP>|OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>"
+ CREATEOBJECT="WPProgram|Console|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=$(1)\bin\mysql.exe;STARTUPDIR=$(1)\bin;ICONFILE=$(1)\bin\icons\mysql-client.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_CONSOLE>;"
+ CREATEOBJECT="WPProgram|Start server|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=$(1)\bin\mysqld.exe;ICONFILE=$(1)\bin\icons\mysql-startserver.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_START>;"
+ CREATEOBJECT="WPProgram|Shutdown server|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=$(1)\bin\mysqladmin.exe;STARTUPDIR=$(1)\bin;PARAMETERS=-u root shutdown;ICONFILE=$(1)\bin\icons\mysql-shutdownserver.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_SHUTDOWN>;"
+ CREATEOBJECT="WPProgram|Readme first|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=e.exe;PARAMETERS=$(1)\ReadMe.txt;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_README>;"
+ SELECT
+ >This package will install MySQL for OS/2 SQL engine
+</PCK>
+
+<PCK INDEX=2
+ PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\Developement Kit\<$MySQL\Ver>"
+ TARGET="?:\usr\local\mysql"
+ TITLE="Developement Kit"
+ SELECT
+ >This package will install MySQL for OS/2 sdk
+</PCK>
+
+<PCK INDEX=3
+ PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\PDF manual\<$MySQL\Ver>"
+ TARGET="?:\usr\local\mysql"
+ TITLE="PDF manual"
+ EXTERNAL="mysql-<$MySQL-Ver>-pdf.wpi"
+ CREATEOBJECT="WPShadow|PDF Manual|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|SHADOWID=$(1)\docs\manual.pdf"
+ SELECT
+ >This package will install MySQL for OS/2 documentation
+</PCK>
+
+<PCK INDEX=4
+ PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\INF manual\3\23\28"
+ TARGET="?:\usr\local\mysql"
+ TITLE="INF manual"
+ EXTERNAL="mysql-3-23-28-gamma-inf.wpi"
+ CREATEOBJECT="WPProgram|MySQL Manual|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=view.exe;PARAMETERS=$(1)\docs\manual.inf;ICONFILE=$(1)\bin\icons\mysql-manual.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_INFMANUAL>;"
+ SELECT
+ >This package will install MySQL for OS/2 documentation
+</PCK>
+
+<PCK INDEX=5
+ PACKAGEID="TCX Datakonsult AB\MySQL for OS/2\Test suite\<$MySQL\Ver>"
+ TARGET="?:\usr\local\mysql"
+ TITLE="Test suite"
+ EXTERNAL="mysql-<$MySQL-Ver>-test.wpi"
+ CREATEOBJECT="WPProgram|Run MySQL Test Suite|<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_FOLDER>|EXENAME=$(5)\mysql-test\mysql-test.cmd;PARAMETERS=$(1)\docs\manual.inf;ICONFILE=$(1)\bin\icons\mysql-manual.ico;OBJECTID=<MYSQL_<$MySQL.Major>_<$MySQL.Minor>_TESTSUITE>;"
+ SELECT
+ >This package will install MySQL for OS/2 test suite
+</PCK>
+
+</HEAD>
+
+<!-- Here come the different pages. They are linked by
+ the <NEXTBUTTON> tags, which must have a target.
+ Each page must have a TYPE= attribute, which tells
+ WarpIn what will be visible on that page. -->
+
+<BODY>
+
+<!-- page1: introduction ->>
+<PAGE INDEX=1 TYPE=README>
+<TEXT>
+</TEXT>
+<NEXTBUTTON TARGET=2>~Next</NEXTBUTTON>
+<README FORMAT=HTML>
+
+<P>Welcome to the latest port of <B>MySQL for OS/2 and eComStation</B>.
+<BR>
+<P>You are about to install <B>MySQL <$MySQL.Ver></B>
+
+<BR>
+<BR>
+<P>Select "Next" to continue.
+
+<P>Select "Cancel" to abort installation.
+</README>
+</PAGE>
+
+<!-- show ReadMe.txt -->
+<PAGE INDEX=2 TYPE=README>
+<NEXTBUTTON TARGET=3>~Next</NEXTBUTTON>
+<TEXT>
+</TEXT>
+<README FORMAT=PLAIN EXTRACTFROMPCK="1">ReadMe.txt</README>
+</PAGE>
+
+<!-- show GPL license -->
+<PAGE INDEX=3 TYPE=README>
+<NEXTBUTTON TARGET=4>~I agree</NEXTBUTTON>
+<TEXT>
+By pressing the "I agree" button, you agree to all terms and conditions to the below licence agreement.
+</TEXT>
+<README FORMAT=HTML EXTRACTFROMPCK="1">license.htm</README>
+</PAGE>
+
+
+<!-- The TYPE=CONTAINER will list the packages which can be installed. -->
+
+<PAGE INDEX=4 TYPE=CONTAINER>
+<NEXTBUTTON TARGET=5>~Next</NEXTBUTTON>
+<TEXT>
+Please select the packages which are to be installed. You may change the target paths for the packages.
+</TEXT>
+</PAGE>
+
+<!-- Here's another TYPE=TEXT page before we install.
+ The special target "0" indicates that after this page we
+ should start installation.
+ Note that the TYPE=INSTALL page (which we had in Alpha #3)
+ is no longer supported. -->
+
+<PAGE INDEX=5 TYPE=TEXT>
+<NEXTBUTTON TARGET=0>I~nstall</NEXTBUTTON>
+<TEXT>
+Press "Install" to begin installing this archive.</TEXT>
+</PAGE>
+
+</BODY>
+</WARPIN>
diff --git a/os2/mysqlalt.wis b/os2/mysqlalt.wis
new file mode 100644
index 00000000000..55259567a2e
--- /dev/null
+++ b/os2/mysqlalt.wis
@@ -0,0 +1,15 @@
+#include "mysql.ih"
+
+<WARPIN VERSION <$WARPIN_VERSION>>
+<HEAD>
+<MSG>
+This is not an installable archive.
+
+Please download and install the main archive:
+
+ mysql-<$MySQL-Ver>-bld1.wpi
+
+</MSG>
+</HEAD>
+</WARPIN>
+ \ No newline at end of file
diff --git a/readline/vi_mode.c b/readline/vi_mode.c
index 3db3d25cdd3..4c65400e12f 100644
--- a/readline/vi_mode.c
+++ b/readline/vi_mode.c
@@ -138,7 +138,7 @@ _rl_vi_initialize_line ()
{
register uint i;
- for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
+ for (i = 0; i < (int) sizeof (vi_mark_chars) / sizeof (int); i++)
vi_mark_chars[i] = -1;
}
diff --git a/sql/field.cc b/sql/field.cc
index 07f521abf3e..df6c2a80424 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2412,8 +2412,7 @@ String *Field_timestamp::val_str(String *val_buffer,
return val_buffer;
}
-bool Field_timestamp::get_date(TIME *ltime,
- bool fuzzydate __attribute__((unused)))
+bool Field_timestamp::get_date(TIME *ltime, bool fuzzydate)
{
long temp;
#ifdef WORDS_BIGENDIAN
@@ -2424,6 +2423,8 @@ bool Field_timestamp::get_date(TIME *ltime,
longget(temp,ptr);
if (temp == 0L)
{ /* Zero time is "000000" */
+ if (!fuzzydate)
+ return 1;
bzero((char*) ltime,sizeof(*ltime));
}
else
@@ -2447,8 +2448,7 @@ bool Field_timestamp::get_date(TIME *ltime,
bool Field_timestamp::get_time(TIME *ltime)
{
- Field_timestamp::get_date(ltime,0);
- return 0;
+ return Field_timestamp::get_date(ltime,0);
}
int Field_timestamp::cmp(const char *a_ptr, const char *b_ptr)
@@ -3029,13 +3029,12 @@ bool Field_newdate::get_date(TIME *ltime,bool fuzzydate)
ltime->month= (tmp >> 5) & 15;
ltime->year= (tmp >> 9);
ltime->time_type=TIMESTAMP_DATE;
- return (!fuzzydate && (!ltime->month || !ltime->day) && ltime->year) ? 1 : 0;
+ return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
}
bool Field_newdate::get_time(TIME *ltime)
{
- Field_newdate::get_date(ltime,0);
- return 0;
+ return Field_newdate::get_date(ltime,0);
}
int Field_newdate::cmp(const char *a_ptr, const char *b_ptr)
@@ -3214,13 +3213,12 @@ bool Field_datetime::get_date(TIME *ltime,bool fuzzydate)
ltime->day= part1%100;
ltime->month= part1/100%100;
ltime->year= part1/10000;
- return (!fuzzydate && (!ltime->month || !ltime->day) && ltime->year) ? 1 : 0;
+ return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
}
bool Field_datetime::get_time(TIME *ltime)
{
- Field_datetime::get_date(ltime,0);
- return 0;
+ return Field_datetime::get_date(ltime,0);
}
int Field_datetime::cmp(const char *a_ptr, const char *b_ptr)
@@ -3468,9 +3466,9 @@ int Field_string::pack_cmp(const char *b, uint length)
}
-uint Field_string::packed_col_length(const char *ptr)
+uint Field_string::packed_col_length(const char *ptr, uint length)
{
- if (field_length > 255)
+ if (length > 255)
return uint2korr(ptr)+2;
else
return (uint) ((uchar) *ptr)+1;
@@ -3478,7 +3476,7 @@ uint Field_string::packed_col_length(const char *ptr)
uint Field_string::max_packed_col_length(uint max_length)
{
- return (field_length > 255 ? 2 : 1)+max_length;
+ return (max_length > 255 ? 2 : 1)+max_length;
}
@@ -3687,9 +3685,9 @@ int Field_varstring::pack_cmp(const char *b, uint key_length)
return my_sortncmp(a,a_length, b,b_length);
}
-uint Field_varstring::packed_col_length(const char *ptr)
+uint Field_varstring::packed_col_length(const char *ptr, uint length)
{
- if (field_length > 255)
+ if (length > 255)
return uint2korr(ptr)+2;
else
return (uint) ((uchar) *ptr)+1;
@@ -3697,7 +3695,7 @@ uint Field_varstring::packed_col_length(const char *ptr)
uint Field_varstring::max_packed_col_length(uint max_length)
{
- return (field_length > 255 ? 2 : 1)+max_length;
+ return (max_length > 255 ? 2 : 1)+max_length;
}
/****************************************************************************
@@ -4173,6 +4171,18 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from,
return to+length;
}
+uint Field_blob::packed_col_length(const char *ptr, uint length)
+{
+ if (length > 255)
+ return uint2korr(ptr)+2;
+ else
+ return (uint) ((uchar) *ptr)+1;
+}
+
+uint Field_blob::max_packed_col_length(uint max_length)
+{
+ return (max_length > 255 ? 2 : 1)+max_length;
+}
/****************************************************************************
** enum type.
diff --git a/sql/field.h b/sql/field.h
index ddcc281d0c8..777e4388850 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -176,10 +176,10 @@ public:
{
return pack(to,from,max_length);
}
- virtual uint packed_col_length(const char *to)
- { return pack_length();}
+ virtual uint packed_col_length(const char *to, uint length)
+ { return length;}
virtual uint max_packed_col_length(uint max_length)
- { return pack_length();}
+ { return max_length;}
virtual int pack_cmp(const char *a,const char *b, uint key_length_arg)
{ return cmp(a,b); }
@@ -749,7 +749,7 @@ public:
const char *unpack(char* to, const char *from);
int pack_cmp(const char *a,const char *b,uint key_length);
int pack_cmp(const char *b,uint key_length);
- uint packed_col_length(const char *to);
+ uint packed_col_length(const char *to, uint length);
uint max_packed_col_length(uint max_length);
uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
@@ -801,7 +801,7 @@ public:
const char *unpack(char* to, const char *from);
int pack_cmp(const char *a, const char *b, uint key_length);
int pack_cmp(const char *b, uint key_length);
- uint packed_col_length(const char *to);
+ uint packed_col_length(const char *to, uint length);
uint max_packed_col_length(uint max_length);
uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return FIELD_TYPE_VAR_STRING; }
@@ -887,11 +887,8 @@ public:
char *pack_key_from_key_image(char* to, const char *from, uint max_length);
int pack_cmp(const char *a, const char *b, uint key_length);
int pack_cmp(const char *b, uint key_length);
- uint packed_col_length(const char *col_ptr)
- { return get_length(col_ptr)+packlength;}
- virtual uint max_packed_col_length(uint max_length)
- { return packlength+max_length; }
-
+ uint packed_col_length(const char *col_ptr, uint length);
+ uint max_packed_col_length(uint max_length);
inline void free() { value.free(); }
inline void clear_temporary() { bzero((char*) &value,sizeof(value)); }
friend void field_conv(Field *to,Field *from);
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index b10939227ff..f52b99f5a12 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -28,8 +28,8 @@
- Get a more accurate count of the number of rows (estimate_number_of_rows()).
We could store the found number of rows when the table is scanned and
then increment the counter for each attempted write.
- - We will need a manager thread that calls flush_logs, removes old
- logs and makes checkpoints at given intervals.
+ - We will need to extend the manager thread to makes checkpoints at
+ given intervals.
- When not using UPDATE IGNORE, don't make a sub transaction but abort
the main transaction on errors.
- Handling of drop table during autocommit=0 ?
@@ -372,10 +372,12 @@ berkeley_cmp_packed_key(DB *file, const DBT *new_key, const DBT *saved_key)
if ((cmp=key_part->field->pack_cmp(new_key_ptr,saved_key_ptr,
key_part->length)))
return cmp;
- uint length=key_part->field->packed_col_length(new_key_ptr);
+ uint length=key_part->field->packed_col_length(new_key_ptr,
+ key_part->length);
new_key_ptr+=length;
key_length-=length;
- saved_key_ptr+=key_part->field->packed_col_length(saved_key_ptr);
+ saved_key_ptr+=key_part->field->packed_col_length(saved_key_ptr,
+ key_part->length);
}
return key->handler.bdb_return_if_eq;
}
@@ -433,7 +435,7 @@ berkeley_key_cmp(TABLE *table, KEY *key_info, const char *key, uint key_length)
}
if ((cmp=key_part->field->pack_cmp(key,key_part->length)))
return cmp;
- uint length=key_part->field->packed_col_length(key);
+ uint length=key_part->field->packed_col_length(key,key_part->length);
key+=length;
key_length-=length;
}
@@ -1552,7 +1554,7 @@ DBT *ha_berkeley::get_pos(DBT *to, byte *pos)
KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts;
for ( ; key_part != end ; key_part++)
- pos+=key_part->field->packed_col_length((char*) pos);
+ pos+=key_part->field->packed_col_length((char*) pos,key_part->length);
to->size= (uint) (pos- (byte*) to->data);
}
return to;
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc
index 7e11fbe46d1..dd72bb15473 100644
--- a/sql/ha_innobase.cc
+++ b/sql/ha_innobase.cc
@@ -79,13 +79,14 @@ ulong innobase_cache_size = 0;
long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_log_file_size, innobase_log_buffer_size,
innobase_buffer_pool_size, innobase_additional_mem_pool_size,
- innobase_file_io_threads, innobase_lock_wait_timeout;
+ innobase_file_io_threads, innobase_lock_wait_timeout,
+ innobase_thread_concurrency, innobase_force_recovery;
char *innobase_data_home_dir;
char *innobase_log_group_home_dir, *innobase_log_arch_dir;
char *innobase_unix_file_flush_method;
bool innobase_flush_log_at_trx_commit, innobase_log_archive,
- innobase_use_native_aio;
+ innobase_use_native_aio, innobase_fast_shutdown;
/*
Set default InnoDB size to 64M, to let users use InnoDB without having
@@ -165,19 +166,19 @@ convert_error_code_to_mysql(
} else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
- return(1000001);
+ return(HA_ERR_LOCK_WAIT_TIMEOUT);
} else if (error == (int) DB_NO_REFERENCED_ROW) {
- return(1000010);
+ return(HA_ERR_NO_REFERENCED_ROW);
} else if (error == (int) DB_ROW_IS_REFERENCED) {
- return(1000011);
+ return(HA_ERR_ROW_IS_REFERENCED);
} else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
- return(1000012);
+ return(HA_ERR_CANNOT_ADD_FOREIGN);
} else if (error == (int) DB_OUT_OF_FILE_SPACE) {
@@ -354,12 +355,6 @@ innobase_parse_data_file_paths_and_sizes(void)
str++;
}
- if (size >= 4096) {
- fprintf(stderr,
- "InnoDB: error: data file size must not be >= 4096M\n");
- return(FALSE);
- }
-
if (strlen(str) >= 6
&& *str == 'n'
&& *(str + 1) == 'e'
@@ -566,8 +561,10 @@ innobase_init(void)
srv_query_thread_priority = QUERY_PRIOR;
}
- /* Set InnoDB initialization parameters according to the values
- read from MySQL .cnf file */
+ /*
+ Set InnoDB initialization parameters according to the values
+ read from MySQL .cnf file
+ */
// Make a copy of innobase_data_file_path to not modify the original
internal_innobase_data_file_path=my_strdup(innobase_data_file_path,
@@ -604,7 +601,7 @@ innobase_init(void)
srv_log_archive_on = (ulint) innobase_log_archive;
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
- srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
+ srv_flush_log_at_trx_commit = (ibool) innobase_flush_log_at_trx_commit;
srv_use_native_aio = 0;
@@ -614,6 +611,10 @@ innobase_init(void)
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
+ srv_thread_concurrency = (ulint) innobase_thread_concurrency;
+ srv_force_recovery = (ulint) innobase_force_recovery;
+
+ srv_fast_shutdown = (ibool) innobase_fast_shutdown;
srv_print_verbose_log = mysql_embedded ? 0 : 1;
if (strcmp(default_charset_info->name, "latin1") == 0) {
@@ -713,12 +714,15 @@ innobase_commit(
trx = check_trx_exists(thd);
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
+ srv_conc_enter_innodb(trx);
+
trx_commit_for_mysql(trx);
- trx_mark_sql_stat_end_do_not_start_new(trx);
- } else {
- trx_mark_sql_stat_end(trx);
+
+ srv_conc_exit_innodb();
}
+ trx_mark_sql_stat_end(trx);
+
#ifndef DBUG_OFF
if (error) {
DBUG_PRINT("error", ("error: %d", error));
@@ -751,14 +755,18 @@ innobase_rollback(
trx = check_trx_exists(thd);
+ srv_conc_enter_innodb(trx);
+
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
error = trx_rollback_for_mysql(trx);
- trx_mark_sql_stat_end_do_not_start_new(trx);
} else {
error = trx_rollback_last_sql_stat_for_mysql(trx);
- trx_mark_sql_stat_end(trx);
}
+ srv_conc_exit_innodb();
+
+ trx_mark_sql_stat_end(trx);
+
DBUG_RETURN(convert_error_code_to_mysql(error));
}
@@ -908,10 +916,11 @@ ha_innobase::open(
if (NULL == (ib_table = dict_table_get(norm_name, NULL))) {
fprintf(stderr,
-"InnoDB: Cannot find table %s from the internal data dictionary\n"
+"InnoDB: Error: cannot find table %s from the internal data dictionary\n"
"InnoDB: of InnoDB though the .frm file for the table exists. Maybe you\n"
"InnoDB: have deleted and recreated InnoDB data files but have forgotten\n"
-"InnoDB: to delete the corresponding .frm files of InnoDB tables?\n",
+"InnoDB: to delete the corresponding .frm files of InnoDB tables, or you\n"
+"InnoDB: have moved .frm files to another database?\n",
norm_name);
free_share(share);
@@ -956,7 +965,9 @@ ha_innobase::open(
dbug_assert(key_used_on_scan == MAX_KEY);
}
- /* Init table lock structure */
+ auto_inc_counter_for_this_stat = 0;
+
+ /* Init table lock structure */
thr_lock_data_init(&share->lock,&lock,(void*) 0);
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
@@ -1253,14 +1264,20 @@ build_template(
Field* field;
ulint n_fields;
ulint n_requested_fields = 0;
+ ibool fetch_all_in_key = FALSE;
ulint i;
clust_index = dict_table_get_first_index_noninline(prebuilt->table);
if (!prebuilt->in_update_remember_pos) {
- /* We are building a temporary table: fetch all columns */
-
- templ_type = ROW_MYSQL_WHOLE_ROW;
+ if (prebuilt->read_just_key) {
+ fetch_all_in_key = TRUE;
+ } else {
+ /* We are building a temporary table: fetch all
+ columns */
+
+ templ_type = ROW_MYSQL_WHOLE_ROW;
+ }
}
if (prebuilt->select_lock_type == LOCK_X) {
@@ -1270,7 +1287,6 @@ build_template(
templ_type = ROW_MYSQL_WHOLE_ROW;
}
-
if (templ_type == ROW_MYSQL_REC_FIELDS) {
if (prebuilt->select_lock_type != LOCK_NONE) {
@@ -1310,6 +1326,9 @@ build_template(
field = table->field[i];
if (templ_type == ROW_MYSQL_REC_FIELDS
+ && !(fetch_all_in_key &&
+ ULINT_UNDEFINED != dict_index_get_nth_col_pos(
+ index, i))
&& thd->query_id != field->query_id
&& thd->query_id != (field->query_id ^ MAX_ULONG_BIT)
&& thd->query_id !=
@@ -1408,9 +1427,6 @@ ha_innobase::write_row(
}
if (table->next_number_field && record == table->record[0]) {
- /* Set the 'in_update_remember_pos' flag to FALSE to
- make sure all columns are fetched in the select done by
- update_auto_increment */
/* Fetch the value the user possibly has set in the
autoincrement field */
@@ -1420,12 +1436,29 @@ ha_innobase::write_row(
/* In replication and also otherwise the auto-inc column
can be set with SET INSERT_ID. Then we must look at
user_thd->next_insert_id. If it is nonzero and the user
- has not supplied a value, we must use it. */
+ has not supplied a value, we must use it, and use values
+ incremented by 1 in all subsequent inserts within the
+ same SQL statement! */
if (auto_inc == 0 && user_thd->next_insert_id != 0) {
auto_inc = user_thd->next_insert_id;
+ auto_inc_counter_for_this_stat = auto_inc;
}
+ if (auto_inc == 0 && auto_inc_counter_for_this_stat) {
+ /* The user set the auto-inc counter for
+ this SQL statement with SET INSERT_ID. We must
+ assign sequential values from the counter. */
+
+ auto_inc_counter_for_this_stat++;
+
+ auto_inc = auto_inc_counter_for_this_stat;
+
+ /* We give MySQL a new value to place in the
+ auto-inc column */
+ user_thd->next_insert_id = auto_inc;
+ }
+
if (auto_inc != 0) {
/* This call will calculate the max of the
current value and the value supplied by the user, if
@@ -1449,11 +1482,14 @@ ha_innobase::write_row(
dict_table_autoinc_update(prebuilt->table, auto_inc);
} else {
+ srv_conc_enter_innodb(prebuilt->trx);
+
if (!prebuilt->trx->auto_inc_lock) {
error = row_lock_table_autoinc_for_mysql(
prebuilt);
if (error != DB_SUCCESS) {
+ srv_conc_exit_innodb();
error = convert_error_code_to_mysql(
error);
@@ -1462,6 +1498,7 @@ ha_innobase::write_row(
}
auto_inc = dict_table_autoinc_get(prebuilt->table);
+ srv_conc_exit_innodb();
/* If auto_inc is now != 0 the autoinc counter
was already initialized for the table: we can give
@@ -1472,6 +1509,10 @@ ha_innobase::write_row(
}
}
+ /* Set the 'in_update_remember_pos' flag to FALSE to
+ make sure all columns are fetched in the select done by
+ update_auto_increment */
+
prebuilt->in_update_remember_pos = FALSE;
update_auto_increment();
@@ -1482,6 +1523,14 @@ ha_innobase::write_row(
auto_inc = table->next_number_field->val_int();
+ error = row_lock_table_autoinc_for_mysql(prebuilt);
+
+ if (error != DB_SUCCESS) {
+
+ error = convert_error_code_to_mysql(error);
+ goto func_exit;
+ }
+
dict_table_autoinc_initialize(prebuilt->table,
auto_inc);
}
@@ -1510,8 +1559,12 @@ ha_innobase::write_row(
prebuilt->trx->ignore_duplicates_in_insert = FALSE;
}
+ srv_conc_enter_innodb(prebuilt->trx);
+
error = row_insert_for_mysql((byte*) record, prebuilt);
+ srv_conc_exit_innodb();
+
prebuilt->trx->ignore_duplicates_in_insert = FALSE;
error = convert_error_code_to_mysql(error);
@@ -1725,8 +1778,12 @@ ha_innobase::update_row(
assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
}
+ srv_conc_enter_innodb(prebuilt->trx);
+
error = row_update_for_mysql((byte*) old_row, prebuilt);
+ srv_conc_exit_innodb();
+
error = convert_error_code_to_mysql(error);
/* Tell InnoDB server that there might be work for
@@ -1765,8 +1822,12 @@ ha_innobase::delete_row(
prebuilt->upd_node->is_delete = TRUE;
prebuilt->in_update_remember_pos = TRUE;
+ srv_conc_enter_innodb(prebuilt->trx);
+
error = row_update_for_mysql((byte*) record, prebuilt);
+ srv_conc_exit_innodb();
+
error = convert_error_code_to_mysql(error);
/* Tell the InnoDB server that there might be work for
@@ -1789,7 +1850,7 @@ ha_innobase::index_init(
int error = 0;
DBUG_ENTER("index_init");
- change_active_index(keynr);
+ error = change_active_index(keynr);
DBUG_RETURN(error);
}
@@ -1905,8 +1966,12 @@ ha_innobase::index_read(
last_match_mode = match_mode;
+ srv_conc_enter_innodb(prebuilt->trx);
+
ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0);
+ srv_conc_exit_innodb();
+
if (ret == DB_SUCCESS) {
error = 0;
table->status = 0;
@@ -1956,11 +2021,20 @@ ha_innobase::change_active_index(
prebuilt->table);
}
+ if (!prebuilt->index) {
+ fprintf(stderr,
+ "InnoDB: Could not find key n:o %u with name %s from dict cache\n"
+ "InnoDB: for table %s\n", keynr, key->name, prebuilt->table->name);
+
+ return(1);
+ }
+
+ assert(prebuilt->search_tuple);
+
dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
prebuilt->index->n_fields);
- assert(prebuilt->index);
/* Maybe MySQL changes the active index for a handle also
during some queries, we do not know: then it is safest to build
@@ -1989,7 +2063,10 @@ ha_innobase::index_read_idx(
uint key_len, /* in: key value length */
enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
{
- change_active_index(keynr);
+ if (change_active_index(keynr)) {
+
+ return(1);
+ }
return(index_read(buf, key, key_len, find_flag));
}
@@ -2015,8 +2092,11 @@ ha_innobase::general_fetch(
DBUG_ENTER("general_fetch");
- ret = row_search_for_mysql((byte*)buf, 0, prebuilt,
- match_mode, direction);
+ srv_conc_enter_innodb(prebuilt->trx);
+
+ ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode,
+ direction);
+ srv_conc_exit_innodb();
if (ret == DB_SUCCESS) {
error = 0;
@@ -2148,17 +2228,19 @@ ha_innobase::rnd_init(
/* out: 0 or error number */
bool scan) /* in: ???????? */
{
+ int err;
+
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
if (prebuilt->clust_index_was_generated) {
- change_active_index(MAX_KEY);
+ err = change_active_index(MAX_KEY);
} else {
- change_active_index(primary_key);
+ err = change_active_index(primary_key);
}
start_of_scan = 1;
- return(0);
+ return(err);
}
/*********************************************************************
@@ -2226,11 +2308,15 @@ ha_innobase::rnd_pos(
row reference is the row id, not any key value
that MySQL knows */
- change_active_index(MAX_KEY);
+ error = change_active_index(MAX_KEY);
} else {
- change_active_index(primary_key);
+ error = change_active_index(primary_key);
}
+ if (error) {
+ DBUG_RETURN(error);
+ }
+
error = index_read(buf, pos, ref_stored_len, HA_READ_KEY_EXACT);
change_active_index(keynr);
@@ -2285,11 +2371,21 @@ ha_innobase::extra(
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
switch (operation) {
+ case HA_EXTRA_RESET:
+ case HA_EXTRA_RESET_STATE:
+ prebuilt->read_just_key = 0;
+ break;
+ case HA_EXTRA_NO_KEYREAD:
+ prebuilt->read_just_key = 0;
+ break;
case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE:
- prebuilt->in_update_remember_pos = FALSE;
- break;
- default: /* Do nothing */
- ;
+ prebuilt->in_update_remember_pos = FALSE;
+ break;
+ case HA_EXTRA_KEYREAD:
+ prebuilt->read_just_key = 1;
+ break;
+ default:/* Do nothing */
+ ;
}
return(0);
@@ -2327,6 +2423,8 @@ ha_innobase::external_lock(
prebuilt->sql_stat_start = TRUE;
prebuilt->in_update_remember_pos = TRUE;
+ prebuilt->read_just_key = 0;
+
if (lock_type == F_WRLCK) {
/* If this is a SELECT, then it is in UPDATE TABLE ...
@@ -2338,6 +2436,7 @@ ha_innobase::external_lock(
if (trx->n_mysql_tables_in_use == 0) {
trx_mark_sql_stat_end(trx);
}
+
thd->transaction.all.innodb_active_trans = 1;
trx->n_mysql_tables_in_use++;
@@ -2347,6 +2446,7 @@ ha_innobase::external_lock(
}
} else {
trx->n_mysql_tables_in_use--;
+ auto_inc_counter_for_this_stat = 0;
if (trx->n_mysql_tables_in_use == 0) {
@@ -2363,11 +2463,14 @@ ha_innobase::external_lock(
some table in this SQL statement, we release
it now */
+ srv_conc_enter_innodb(trx);
row_unlock_table_autoinc_for_mysql(trx);
+ srv_conc_exit_innodb();
}
if (!(thd->options
& (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) {
+
innobase_commit(thd, trx);
}
}
@@ -2636,6 +2739,12 @@ ha_innobase::create(
trx_commit_for_mysql(trx);
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
innobase_table = dict_table_get(norm_name, NULL);
assert(innobase_table);
@@ -2685,6 +2794,12 @@ ha_innobase::delete_table(
error = row_drop_table_for_mysql(norm_name, trx, FALSE);
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -2732,6 +2847,12 @@ innobase_drop_database(
error = row_drop_database_for_mysql(namebuf, trx);
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -2778,6 +2899,12 @@ ha_innobase::rename_table(
error = row_rename_table_for_mysql(norm_from, norm_to, trx);
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -3062,31 +3189,41 @@ ha_innobase::check(
}
/*****************************************************************
-Adds information about free space in the InnoDB tablespace to a
-table comment which is printed out when a user calls SHOW TABLE STATUS. */
+Adds information about free space in the InnoDB tablespace to a table comment
+which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
+foreign keys. */
char*
ha_innobase::update_table_comment(
/*==============================*/
- const char* comment)
+ /* out: table comment + InnoDB free space +
+ info on foreign keys */
+ const char* comment)/* in: table comment defined by user */
{
- uint length=strlen(comment);
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ uint length = strlen(comment);
+ char* str = my_malloc(length + 200, MYF(0));
+ char* pos;
- char *str=my_malloc(length + 100,MYF(0)), *pos;
+ if (!str) {
+ return((char*)comment);
+ }
- if (!str)
- return (char*)comment;
+ pos = str;
+ if (length) {
+ pos=strmov(str, comment);
+ *pos++=';';
+ *pos++=' ';
+ }
- pos=str;
- if (length)
- {
- pos=strmov(str,comment);
- *pos++=';';
- *pos++=' ';
- }
- sprintf(pos, "InnoDB free: %lu kB", (ulong) innobase_get_free_space());
+ pos += sprintf(pos, "InnoDB free: %lu kB",
+ (ulong) innobase_get_free_space());
- return(str);
+ /* We assume 150 bytes of space to print info */
+
+ dict_print_info_on_foreign_keys(pos, 150, prebuilt->table);
+
+ return(str);
}
/****************************************************************************
diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h
index 404b20edbac..95bba76c842 100644
--- a/sql/ha_innobase.h
+++ b/sql/ha_innobase.h
@@ -63,7 +63,7 @@ class ha_innobase: public handler
uint last_match_mode;/* match mode of the latest search:
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */
-
+ longlong auto_inc_counter_for_this_stat;
ulong max_row_length(const byte *buf);
uint store_key_val_for_row(uint keynr, char* buff, const byte* record);
@@ -96,7 +96,10 @@ class ha_innobase: public handler
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MAX_KEY_LENGTH; }
+ /* An InnoDB page must store >= 2 keys:
+ max key length is therefore set to 7000
+ bytes */
+ uint max_key_length() const { return 7000; }
bool fast_key_read() { return 1;}
bool has_transactions() { return 1;}
@@ -161,11 +164,12 @@ extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern long innobase_log_file_size, innobase_log_buffer_size;
extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
extern long innobase_file_io_threads, innobase_lock_wait_timeout;
+extern long innobase_force_recovery, innobase_thread_concurrency;
extern char *innobase_data_home_dir, *innobase_data_file_path;
extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
extern char *innobase_unix_file_flush_method;
extern bool innobase_flush_log_at_trx_commit, innobase_log_archive,
- innobase_use_native_aio;
+ innobase_use_native_aio, innobase_fast_shutdown;
extern TYPELIB innobase_lock_typelib;
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 0a2ef534ad1..d82c202baa3 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -181,7 +181,11 @@ void ha_myisammrg::info(uint flag)
mean_rec_length=info.reclength;
block_size=0;
update_time=0;
+#if SIZEOF_OFF_T > 4
ref_length=6; // Should be big enough
+#else
+ ref_length=4; // Can't be > than my_off_t
+#endif
}
diff --git a/sql/handler.cc b/sql/handler.cc
index 742bcd3aa0a..9bf9b25f76f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -642,6 +642,15 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_READ_ONLY_TRANSACTION:
textno=ER_READ_ONLY_TRANSACTION;
break;
+ case HA_ERR_CANNOT_ADD_FOREIGN:
+ textno=ER_CANNOT_ADD_FOREIGN;
+ break;
+ case HA_ERR_ROW_IS_REFERENCED:
+ textno=ER_ROW_IS_REFERENCED;
+ break;
+ case HA_ERR_NO_REFERENCED_ROW:
+ textno=ER_NO_REFERENCED_ROW;
+ break;
default:
{
my_error(ER_GET_ERRNO,errflag,error);
diff --git a/sql/item.h b/sql/item.h
index df2b1aa243d..1bcbc4c7f0f 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -309,6 +309,7 @@ public:
Item_result_field() :result_field(0) {}
~Item_result_field() {} /* Required with gcc 2.95 */
Field *tmp_table_field() { return result_field; }
+ table_map used_tables() const { return 1; }
virtual void fix_length_and_dec()=0;
};
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index b305b5ccec3..a8bd219eef1 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -248,8 +248,10 @@ longlong Item_func_unix_timestamp::val_int()
longlong Item_func_time_to_sec::val_int()
{
TIME ltime;
+ longlong seconds;
(void) get_arg0_time(&ltime);
- return ltime.hour*3600L+ltime.minute*60+ltime.second;
+ seconds=ltime.hour*3600L+ltime.minute*60+ltime.second;
+ return ltime.neg ? -seconds : seconds;
}
diff --git a/sql/log.cc b/sql/log.cc
index 51bf077895a..b55d514058f 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -516,36 +516,46 @@ bool MYSQL_LOG::is_active(const char* log_file_name)
void MYSQL_LOG::new_file(bool inside_mutex)
{
- // only rotate open logs that are marked non-rotatable
- // (binlog with constant name are non-rotatable)
- if (is_open() && ! no_rotate)
+ if (is_open())
{
char new_name[FN_REFLEN], *old_name=name;
if (!inside_mutex)
VOID(pthread_mutex_lock(&LOCK_log));
- if (generate_new_name(new_name, name))
- {
- if (!inside_mutex)
- VOID(pthread_mutex_unlock(&LOCK_log));
- return; // Something went wrong
- }
- if (log_type == LOG_BIN)
+
+ if (!no_rotate)
{
/*
- We log the whole file name for log file as the user may decide
- to change base names at some point.
+ only rotate open logs that are marked non-rotatable
+ (binlog with constant name are non-rotatable)
*/
- THD* thd = current_thd;
- Rotate_log_event r(thd,new_name+dirname_length(new_name));
- r.set_log_seq(0, this);
- // this log rotation could have been initiated by a master of
- // the slave running with log-bin
- // we set the flag on rotate event to prevent inifinite log rotation
- // loop
- if(thd && slave_thd && thd == slave_thd)
- r.flags |= LOG_EVENT_FORCED_ROTATE_F;
- r.write(&log_file);
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ if (generate_new_name(new_name, name))
+ {
+ if (!inside_mutex)
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ return; // Something went wrong
+ }
+ if (log_type == LOG_BIN)
+ {
+ /*
+ We log the whole file name for log file as the user may decide
+ to change base names at some point.
+ */
+ THD* thd = current_thd;
+ Rotate_log_event r(thd,new_name+dirname_length(new_name));
+ r.set_log_seq(0, this);
+
+ /*
+ This log rotation could have been initiated by a master of
+ the slave running with log-bin we set the flag on rotate
+ event to prevent inifinite log rotation loop
+ */
+ if (thd && slave_thd && thd == slave_thd)
+ r.flags |= LOG_EVENT_FORCED_ROTATE_F;
+ r.write(&log_file);
+ VOID(pthread_cond_broadcast(&COND_binlog_update));
+ }
+ else
+ strmov(new_name, old_name); // Reopen old file name
}
name=0;
close();
@@ -843,7 +853,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
{
/* For slow query log */
if (my_b_printf(&log_file,
- "# Time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
+ "# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
(ulong) (current_time - query_start),
(ulong) (thd->time_after_lock - query_start),
(ulong) thd->sent_row_count,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 61eba065f9a..45812754cad 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1237,7 +1237,7 @@ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n",
Some pointers may be invalid and cause the dump to abort...\n");
safe_print_str("thd->query", thd->query, 1024);
fprintf(stderr, "thd->thread_id=%ld\n", thd->thread_id);
- fprintf(stderr, "\n
+ fprintf(stderr, "\n\
Successfully dumped variables, if you ran with --log, take a look at the\n\
details of what thread %ld did to cause the crash. In some cases of really\n\
bad corruption, the values shown above may be invalid.\n\n",
@@ -2083,14 +2083,18 @@ int main(int argc, char **argv)
{
if (argc == 2)
{
+ char path[FN_REFLEN];
+ my_path(path, argv[0], ""); // Find name in path
+ fn_format(path,argv[0],path,"",1+4+16); // Force use of full path
+
if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install"))
{
- char path[FN_REFLEN];
- my_path(path, argv[0], ""); // Find name in path
- fn_format(path,argv[0],path,"",1+4+16); // Force use of full path
- if (!Service.Install(MYSQL_SERVICENAME,MYSQL_SERVICENAME,path))
- MessageBox(NULL,"Failed to install Service",MYSQL_SERVICENAME,
- MB_OK|MB_ICONSTOP);
+ Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
+ return 0;
+ }
+ else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual"))
+ {
+ Service.Install(0,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
return 0;
}
else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove"))
@@ -2586,6 +2590,7 @@ enum options {
OPT_INNODB_LOG_ARCHIVE,
OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
OPT_INNODB_FLUSH_METHOD,
+ OPT_INNODB_FAST_SHUTDOWN,
OPT_SAFE_SHOW_DB,
OPT_INNODB_SKIP, OPT_SKIP_SAFEMALLOC,
OPT_TEMP_POOL, OPT_TX_ISOLATION,
@@ -2648,6 +2653,8 @@ static struct option long_options[] = {
OPT_INNODB_LOG_ARCHIVE},
{"innodb_flush_log_at_trx_commit", optional_argument, 0,
OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT},
+ {"innodb_fast_shutdown", optional_argument, 0,
+ OPT_INNODB_FAST_SHUTDOWN},
{"innodb_flush_method", required_argument, 0,
OPT_INNODB_FLUSH_METHOD},
#endif
@@ -2762,6 +2769,8 @@ static struct option long_options[] = {
{0, 0, 0, 0}
};
+#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
+
CHANGEABLE_VAR changeable_vars[] = {
{ "back_log", (long*) &back_log,
50, 1, 65535, 0, 1 },
@@ -2779,15 +2788,15 @@ CHANGEABLE_VAR changeable_vars[] = {
{ "binlog_cache_size", (long*) &binlog_cache_size,
32*1024L, IO_SIZE, ~0L, 0, IO_SIZE },
{ "connect_timeout", (long*) &connect_timeout,
- CONNECT_TIMEOUT, 2, 65535, 0, 1 },
+ CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1 },
{ "delayed_insert_timeout", (long*) &delayed_insert_timeout,
- DELAYED_WAIT_TIMEOUT, 1, ~0L, 0, 1 },
+ DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "delayed_insert_limit", (long*) &delayed_insert_limit,
DELAYED_LIMIT, 1, ~0L, 0, 1 },
{ "delayed_queue_size", (long*) &delayed_queue_size,
DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1 },
{ "flush_time", (long*) &flush_time,
- FLUSH_TIME, 0, ~0L, 0, 1 },
+ FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1 },
{ "ft_min_word_len", (long*) &ft_min_word_len,
4, 1, HA_FT_MAXLEN, 0, 1 },
{ "ft_max_word_len", (long*) &ft_max_word_len,
@@ -2816,15 +2825,19 @@ CHANGEABLE_VAR changeable_vars[] = {
{"innodb_lock_wait_timeout",
(long*) &innobase_lock_wait_timeout, 1024 * 1024 * 1024, 1,
1024 * 1024 * 1024, 0, 1},
+ {"innodb_thread_concurrency",
+ (long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1},
+ {"innodb_force_recovery",
+ (long*) &innobase_force_recovery, 0, 0, 6, 0, 1},
#endif
{ "interactive_timeout", (long*) &net_interactive_timeout,
- NET_WAIT_TIMEOUT, 1, 31*24*60*60, 0, 1 },
+ NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "join_buffer_size", (long*) &join_buff_size,
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
{ "key_buffer_size", (long*) &keybuff_size,
KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
{ "long_query_time", (long*) &long_query_time,
- 10, 1, ~0L, 0, 1 },
+ 10, 1, LONG_TIMEOUT, 0, 1 },
{ "lower_case_table_names", (long*) &lower_case_table_names,
IF_WIN(1,0), 0, 1, 0, 1 },
{ "max_allowed_packet", (long*) &max_allowed_packet,
@@ -2868,9 +2881,9 @@ CHANGEABLE_VAR changeable_vars[] = {
{ "net_retry_count", (long*) &mysqld_net_retry_count,
MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1 },
{ "net_read_timeout", (long*) &net_read_timeout,
- NET_READ_TIMEOUT, 1, 65535, 0, 1 },
+ NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "net_write_timeout", (long*) &net_write_timeout,
- NET_WRITE_TIMEOUT, 1, 65535, 0, 1 },
+ NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "open_files_limit", (long*) &open_files_limit,
0, 0, 65535, 0, 1},
{ "query_buffer_size", (long*) &query_buff_size,
@@ -2880,9 +2893,9 @@ CHANGEABLE_VAR changeable_vars[] = {
{ "record_rnd_buffer", (long*) &record_rnd_cache_size,
0, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
{ "slave_net_timeout", (long*) &slave_net_timeout,
- SLAVE_NET_TIMEOUT, 1, 65535, 0, 1 },
+ SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ "slow_launch_time", (long*) &slow_launch_time,
- 2L, 0L, ~0L, 0, 1 },
+ 2L, 0L, LONG_TIMEOUT, 0, 1 },
{ "sort_buffer", (long*) &sortbuff_size,
MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, 1 },
{ "table_cache", (long*) &table_cache_size,
@@ -2896,7 +2909,7 @@ CHANGEABLE_VAR changeable_vars[] = {
{ "thread_stack", (long*) &thread_stack,
DEFAULT_THREAD_STACK, 1024*32, ~0L, 0, 1024 },
{ "wait_timeout", (long*) &net_wait_timeout,
- NET_WAIT_TIMEOUT, 1, ~0L, 0, 1 },
+ NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
{ NullS, (long*) 0, 0, 0, 0, 0, 0}
};
@@ -2942,7 +2955,10 @@ struct show_var_st init_vars[]= {
{"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR},
{"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR},
{"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
+ {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
+ {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG },
{"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_MY_BOOL},
+ {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL},
{"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
{"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
{"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR},
@@ -3869,6 +3885,8 @@ static void get_options(int argc,char **argv)
break;
case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT:
innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1;
+ case OPT_INNODB_FAST_SHUTDOWN:
+ innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1;
break;
case OPT_INNODB_FLUSH_METHOD:
innobase_unix_file_flush_method=optarg;
diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc
index 3a36f5740a9..6930800982e 100644
--- a/sql/nt_servc.cc
+++ b/sql/nt_servc.cc
@@ -5,6 +5,7 @@
-------------------------------------------------------------------------- */
#include <windows.h>
#include <process.h>
+#include <stdio.h>
#include "nt_servc.h"
@@ -52,11 +53,12 @@ NTService::NTService()
-------------------------------------------------------------------------- */
NTService::~NTService()
{
- if(ServiceName != NULL) delete[] ServiceName;
+ if (ServiceName != NULL) delete[] ServiceName;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
+
BOOL NTService::GetOS()
{
bOsNT = FALSE;
@@ -70,12 +72,14 @@ BOOL NTService::GetOS()
return bOsNT;
}
+
/* ------------------------------------------------------------------------
Init() Registers the main service thread with the service manager
ServiceThread - pointer to the main programs entry function
when the service is started
-------------------------------------------------------------------------- */
+
long NTService::Init(LPCSTR szInternName,void *ServiceThread)
{
@@ -93,6 +97,8 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread)
return StartServiceCtrlDispatcher(stb); //register with the Service Manager
}
+
+
/* ------------------------------------------------------------------------
Install() - Installs the service with Service manager
nError values:
@@ -100,41 +106,55 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread)
1 Can't open the Service manager
2 Failed to create service
-------------------------------------------------------------------------- */
-BOOL NTService::Install(LPCSTR szInternName,LPCSTR szDisplayName,
- LPCSTR szFullPath, LPCSTR szAccountName,LPCSTR szPassword)
+
+BOOL NTService::Install(int startType, LPCSTR szInternName,
+ LPCSTR szDisplayName,
+ LPCSTR szFullPath, LPCSTR szAccountName,
+ LPCSTR szPassword)
{
+ BOOL ret_val=FALSE;
SC_HANDLE newService, scm;
- nError=0;
+ if (!SeekStatus(szInternName,1))
+ return FALSE;
+
+ char szFilePath[_MAX_PATH];
+ GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
// open a connection to the SCM
- scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
- if(scm) // Install the new service
- { newService = CreateService(
- scm,
- szInternName,
- szDisplayName,
- dwDesiredAccess, //default: SERVICE_ALL_ACCESS
- dwServiceType, //default: SERVICE_WIN32_OWN_PROCESS
- dwStartType, //default: SERVICE_AUTOSTART
- dwErrorControl, //default: SERVICE_ERROR_NORMAL
- szFullPath, //exec full path
- szLoadOrderGroup, //default: NULL
- lpdwTagID, //default: NULL
- szDependencies, //default: NULL
- szAccountName, //default: NULL
- szPassword); //default: NULL
-
- if (newService) CloseServiceHandle(newService); // clean up
- else nError=2;
-
- // clean up
+ if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
+ printf("Failed to install the service (Couldn't open the SCM)\n");
+ else // Install the new service
+ {
+ if (!(newService=
+ CreateService(scm,
+ szInternName,
+ szDisplayName,
+ dwDesiredAccess,//default: SERVICE_ALL_ACCESS
+ dwServiceType, //default: SERVICE_WIN32_OWN_PROCESS
+ //default: SERVICE_AUTOSTART
+ (startType == 1 ? SERVICE_AUTO_START :
+ SERVICE_DEMAND_START),
+ dwErrorControl, //default: SERVICE_ERROR_NORMAL
+ szFullPath, //exec full path
+ szLoadOrderGroup, //default: NULL
+ lpdwTagID, //default: NULL
+ szDependencies, //default: NULL
+ szAccountName, //default: NULL
+ szPassword))) //default: NULL
+ printf("Failed to install the service (Couldn't create service)\n");
+ else
+ {
+ printf("Service successfully installed.\n");
+ CloseServiceHandle(newService);
+ ret_val=TRUE; // Everything went ok
+ }
CloseServiceHandle(scm);
}
- else nError=1;
-
- return (!nError);
+ return ret_val;
}
+
+
/* ------------------------------------------------------------------------
Remove() - Removes the service
nError values:
@@ -143,35 +163,40 @@ BOOL NTService::Install(LPCSTR szInternName,LPCSTR szDisplayName,
2 Failed to locate service
3 Failed to delete service
-------------------------------------------------------------------------- */
+
BOOL NTService::Remove(LPCSTR szInternName)
{
-
+ BOOL ret_value=FALSE;
SC_HANDLE service, scm;
+ if (!SeekStatus(szInternName,0))
+ return FALSE;
+
nError=0;
// open a connection to the SCM
- scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
-
- if (scm)
+ if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
+ {
+ printf("Failed to remove the service (Couldn't open the SCM)\n");
+ }
+ else
{
- //open the service
- service = OpenService(scm,szInternName, DELETE );
- if(service)
+ if ((service = OpenService(scm,szInternName, DELETE)))
{
- if(!DeleteService(service)) nError=3;
+ if (!DeleteService(service))
+ printf("Failed to remove the service\n");
+ else
+ {
+ printf("Service successfully removed.\n");
+ ret_value=TRUE; // everything went ok
+ }
CloseServiceHandle(service);
}
else
- {
- //MessageBox(NULL,"Can't find the service","Remove Error",MB_OK|MB_ICONHAND);
- nError=2;
- }
+ printf("Failed to remove the service (Couldn't open the service)\n");
CloseServiceHandle(scm);
}
- else nError=1;
-
- return (!nError);
+ return ret_value;
}
/* ------------------------------------------------------------------------
@@ -189,80 +214,66 @@ void NTService::Stop(void)
ServiceMain() - This is the function that is called from the
service manager to start the service
-------------------------------------------------------------------------- */
+
void NTService::ServiceMain(DWORD argc, LPTSTR *argv)
{
// registration function
- pService->hServiceStatusHandle =
- RegisterServiceCtrlHandler(pService->ServiceName,
- (LPHANDLER_FUNCTION )NTService::ServiceCtrlHandler);
-
- if(!pService->hServiceStatusHandle)
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!(pService->hServiceStatusHandle =
+ RegisterServiceCtrlHandler(pService->ServiceName,
+ (LPHANDLER_FUNCTION)
+ NTService::ServiceCtrlHandler)))
+ goto error;
// notify SCM of progress
- if(!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 1, 8000))
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 1, 8000))
+ goto error;
// create the exit event
- pService->hExitEvent = CreateEvent (0, TRUE, FALSE,0);
- if(!pService->hExitEvent)
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!(pService->hExitEvent = CreateEvent (0, TRUE, FALSE,0)))
+ goto error;
- if(!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 3, pService->nStartTimeOut))
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 3,
+ pService->nStartTimeOut))
+ goto error;
// save start arguments
pService->my_argc=argc;
pService->my_argv=argv;
// start the service
- if(!pService->StartService())
- {
- pService->Exit(GetLastError());
- return;
- }
+ if (!pService->StartService())
+ goto error;
- // the service is now running.
- if(!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0))
- {
- pService->Exit(GetLastError());
- return;
- }
+ // Check that the service is now running.
+ if (!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0))
+ goto error;
// wait for exit event
WaitForSingleObject (pService->hExitEvent, INFINITE);
// wait for thread to exit
- if (WaitForSingleObject (pService->hThreadHandle, 1000)==WAIT_TIMEOUT)
+ if (WaitForSingleObject (pService->hThreadHandle, 1000) == WAIT_TIMEOUT)
CloseHandle(pService->hThreadHandle);
pService->Exit(0);
+ return;
+
+error:
+ pService->Exit(GetLastError());
+ return;
}
/* ------------------------------------------------------------------------
StartService() - starts the appliaction thread
-------------------------------------------------------------------------- */
+
BOOL NTService::StartService()
{
-
// Start the real service's thread (application)
- hThreadHandle = (HANDLE) _beginthread((THREAD_FC)fpServiceThread,0,(void *)this);
-
- if (hThreadHandle==0) return FALSE;
-
+ if (!(hThreadHandle = (HANDLE) _beginthread((THREAD_FC)fpServiceThread,0,
+ (void *) this)))
+ return FALSE;
bRunning = TRUE;
return TRUE;
}
@@ -274,7 +285,7 @@ void NTService::StopService()
bRunning=FALSE;
// Set the event for application
- if(hShutdownEvent)
+ if (hShutdownEvent)
SetEvent(hShutdownEvent);
// Set the event for ServiceMain
@@ -285,117 +296,186 @@ void NTService::StopService()
-------------------------------------------------------------------------- */
void NTService::PauseService()
{
- bPause = TRUE;
- SuspendThread(hThreadHandle);
+ bPause = TRUE;
+ SuspendThread(hThreadHandle);
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
void NTService::ResumeService()
{
- bPause=FALSE;
- ResumeThread(hThreadHandle);
+ bPause=FALSE;
+ ResumeThread(hThreadHandle);
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
BOOL NTService::SetStatus (DWORD dwCurrentState,DWORD dwWin32ExitCode,
- DWORD dwServiceSpecificExitCode,DWORD dwCheckPoint,DWORD dwWaitHint)
+ DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
+ DWORD dwWaitHint)
{
BOOL bRet;
SERVICE_STATUS serviceStatus;
- dwState=dwCurrentState;
-
- serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- serviceStatus.dwCurrentState = dwCurrentState;
+ dwState=dwCurrentState;
- if (dwCurrentState == SERVICE_START_PENDING)
- serviceStatus.dwControlsAccepted = 0; //don't accept conrol events
- else
- serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
- SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
+ serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ serviceStatus.dwCurrentState = dwCurrentState;
- // if a specific exit code is defined,set up the win32 exit code properly
- if (dwServiceSpecificExitCode == 0)
- serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
- else
- serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
+ if (dwCurrentState == SERVICE_START_PENDING)
+ serviceStatus.dwControlsAccepted = 0; //don't accept control events
+ else
+ serviceStatus.dwControlsAccepted = (SERVICE_ACCEPT_STOP |
+ SERVICE_ACCEPT_PAUSE_CONTINUE |
+ SERVICE_ACCEPT_SHUTDOWN);
- serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
+ // if a specific exit code is defined,set up the win32 exit code properly
+ if (dwServiceSpecificExitCode == 0)
+ serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
+ else
+ serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
- serviceStatus.dwCheckPoint = dwCheckPoint;
- serviceStatus.dwWaitHint = dwWaitHint;
+ serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
- // Pass the status to the Service Manager
- bRet=SetServiceStatus (hServiceStatusHandle, &serviceStatus);
+ serviceStatus.dwCheckPoint = dwCheckPoint;
+ serviceStatus.dwWaitHint = dwWaitHint;
- if(!bRet) StopService();
+ // Pass the status to the Service Manager
+ if (!(bRet=SetServiceStatus (hServiceStatusHandle, &serviceStatus)))
+ StopService();
- return bRet;
+ return bRet;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
void NTService::ServiceCtrlHandler(DWORD ctrlCode)
{
+ DWORD dwState;
- DWORD dwState = 0;
-
- if(!pService) return;
+ if (!pService)
+ return;
dwState=pService->dwState; // get current state
- switch(ctrlCode)
- {
+ switch(ctrlCode) {
- /*********** do we need this ? *******************************
- case SERVICE_CONTROL_PAUSE:
- if (pService->bRunning && ! pService->bPause)
- {
- dwState = SERVICE_PAUSED;
- pService->SetStatus(SERVICE_PAUSE_PENDING,NO_ERROR, 0, 1, pService->nPauseTimeOut);
- pService->PauseService();
- }
- break;
-
- case SERVICE_CONTROL_CONTINUE:
- if (pService->bRunning && pService->bPause)
- {
- dwState = SERVICE_RUNNING;
- pService->SetStatus(SERVICE_CONTINUE_PENDING,NO_ERROR, 0, 1, pService->nResumeTimeOut);
- pService->ResumeService();
- }
- break;
- ****************************************************************/
-
- case SERVICE_CONTROL_SHUTDOWN:
- case SERVICE_CONTROL_STOP:
- dwState = SERVICE_STOP_PENDING;
- pService->SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1, pService->nStopTimeOut);
- pService->StopService();
- break;
-
- default:
- pService->SetStatus(dwState, NO_ERROR,0, 0, 0);
- break;
+#ifdef NOT_USED /* do we need this ? */
+ case SERVICE_CONTROL_PAUSE:
+ if (pService->bRunning && ! pService->bPause)
+ {
+ dwState = SERVICE_PAUSED;
+ pService->SetStatus(SERVICE_PAUSE_PENDING,NO_ERROR, 0, 1,
+ pService->nPauseTimeOut);
+ pService->PauseService();
+ }
+ break;
+
+ case SERVICE_CONTROL_CONTINUE:
+ if (pService->bRunning && pService->bPause)
+ {
+ dwState = SERVICE_RUNNING;
+ pService->SetStatus(SERVICE_CONTINUE_PENDING,NO_ERROR, 0, 1,
+ pService->nResumeTimeOut);
+ pService->ResumeService();
+ }
+ break;
+#endif
+
+ case SERVICE_CONTROL_SHUTDOWN:
+ case SERVICE_CONTROL_STOP:
+ dwState = SERVICE_STOP_PENDING;
+ pService->SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1,
+ pService->nStopTimeOut);
+ pService->StopService();
+ break;
+
+ default:
+ pService->SetStatus(dwState, NO_ERROR,0, 0, 0);
+ break;
}
//pService->SetStatus(dwState, NO_ERROR,0, 0, 0);
}
+
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
+
void NTService::Exit(DWORD error)
{
- if (hExitEvent) CloseHandle(hExitEvent);
+ if (hExitEvent)
+ CloseHandle(hExitEvent);
// Send a message to the scm to tell that we stop
if (hServiceStatusHandle)
- SetStatus(SERVICE_STOPPED, error,0, 0, 0);
+ SetStatus(SERVICE_STOPPED, error,0, 0, 0);
// If the thread has started kill it ???
// if (hThreadHandle) CloseHandle(hThreadHandle);
}
-/* ------------------------- the end -------------------------------------- */
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+
+BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType)
+{
+ BOOL ret_value=FALSE;
+ SC_HANDLE service, scm;
+
+ // open a connection to the SCM
+ if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
+ printf("There is a problem with the Service Control Manager!\n");
+ else
+ {
+ if (OperationType == 1)
+ {
+ /* an install operation */
+ if ((service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS )))
+ {
+ LPQUERY_SERVICE_CONFIG ConfigBuf;
+ DWORD dwSize;
+
+ ConfigBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 4096);
+ printf("The service already exists!\n");
+ if (QueryServiceConfig(service,ConfigBuf,4096,&dwSize))
+ printf("The current server installed: %s\n",
+ ConfigBuf->lpBinaryPathName);
+ LocalFree(ConfigBuf);
+ CloseServiceHandle(service);
+ }
+ else
+ ret_value=TRUE;
+ }
+ else
+ {
+ /* a remove operation */
+ if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS )))
+ printf("The service doesn't exists!\n");
+ else
+ {
+ SERVICE_STATUS ss;
+
+ memset(&ss, 0, sizeof(ss));
+ if (QueryServiceStatus(service,&ss))
+ {
+ DWORD dwState = ss.dwCurrentState;
+ if (dwState == SERVICE_RUNNING)
+ printf("Failed to remove the service because the service is running\nStop the service and try again\n");
+ else if (dwState == SERVICE_STOP_PENDING)
+ printf("\
+Failed to remove the service because the service is in stop pending state!\n\
+Wait 30 seconds and try again.\n\
+If this condition persist, reboot the machine and try again\n");
+ else
+ ret_value= TRUE;
+ }
+ CloseServiceHandle(service);
+ }
+ }
+ CloseServiceHandle(scm);
+ }
+
+ return ret_value;
+}
diff --git a/sql/nt_servc.h b/sql/nt_servc.h
index 5fda96dc4d8..40d1a8c03fa 100644
--- a/sql/nt_servc.h
+++ b/sql/nt_servc.h
@@ -48,8 +48,9 @@ class NTService
//service install / un-install
- BOOL Install(LPCSTR szInternName,LPCSTR szDisplayName,LPCSTR szFullPath,
+ BOOL Install(int startType,LPCSTR szInternName,LPCSTR szDisplayName,LPCSTR szFullPath,
LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL);
+ BOOL SeekStatus(LPCSTR szInternName, int OperationType);
BOOL Remove(LPCSTR szInternName);
void Stop(void); //to be called from app. to stop service
diff --git a/sql/share/norwegian-ny/.cvsignore b/sql/share/norwegian-ny/.cvsignore
deleted file mode 100755
index 2f68f259c40..00000000000
--- a/sql/share/norwegian-ny/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-errmsg.sys
diff --git a/sql/share/norwegian/.cvsignore b/sql/share/norwegian/.cvsignore
deleted file mode 100755
index 2f68f259c40..00000000000
--- a/sql/share/norwegian/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-errmsg.sys
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 0a553945ea1..befae9103f4 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -616,9 +616,30 @@ int yylex(void *arg)
return(IDENT);
case STATE_USER_VARIABLE_DELIMITER:
- lex->tok_start=lex->ptr; // Skip first `
- while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER &&
- c != (uchar) NAMES_SEP_CHAR) ;
+ lex->tok_start=lex->ptr; // Skipp first `
+#ifdef USE_MB
+ if (use_mb(default_charset_info))
+ {
+ while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER &&
+ c != (uchar) NAMES_SEP_CHAR)
+ {
+ if (my_ismbhead(default_charset_info, c))
+ {
+ int l;
+ if ((l = my_ismbchar(default_charset_info,
+ (const char *)lex->ptr-1,
+ (const char *)lex->end_of_query)) == 0)
+ break;
+ lex->ptr += l-1;
+ }
+ }
+ }
+ else
+#endif
+ {
+ while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER &&
+ c != (uchar) NAMES_SEP_CHAR) ;
+ }
yylval->lex_str=get_token(lex,yyLength());
if (lex->convert_set)
lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f2c25e89bd8..fea3dd7728b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3185,7 +3185,8 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
/* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
else if (((field->type() == FIELD_TYPE_DATE) ||
(field->type() == FIELD_TYPE_DATETIME)) &&
- (field->flags & NOT_NULL_FLAG))
+ (field->flags & NOT_NULL_FLAG) &&
+ !field->table->maybe_null)
{
COND *new_cond;
if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
@@ -4083,14 +4084,17 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
if (table->group && join->tmp_table_param.sum_func_count)
{
- DBUG_PRINT("info",("Using end_update"));
if (table->keys)
{
+ DBUG_PRINT("info",("Using end_update"));
end_select=end_update;
table->file->index_init(0);
}
else
+ {
+ DBUG_PRINT("info",("Using end_unique_update"));
end_select=end_unique_update;
+ }
}
else if (join->sort_and_group)
{
@@ -4206,8 +4210,6 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
int error;
bool found=0;
COND *on_expr=join_tab->on_expr, *select_cond=join_tab->select_cond;
- int (*next_select)(JOIN *,struct st_join_table *,bool)=
- join_tab->next_select;
if (!(error=(*join_tab->read_first_record)(join_tab)))
{
@@ -4215,7 +4217,6 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
bool not_used_in_distinct=join_tab->not_used_in_distinct;
ha_rows found_records=join->found_records;
READ_RECORD *info= &join_tab->read_record;
- join->examined_rows++;
do
{
@@ -4224,6 +4225,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
my_error(ER_SERVER_SHUTDOWN,MYF(0)); /* purecov: inspected */
return -2; /* purecov: inspected */
}
+ join->examined_rows++;
if (!on_expr || on_expr->val_int())
{
found=1;
@@ -4231,7 +4233,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
break; // Searching after not null columns
if (!select_cond || select_cond->val_int())
{
- if ((error=(*next_select)(join,join_tab+1,0)) < 0)
+ if ((error=(*join_tab->next_select)(join,join_tab+1,0)) < 0)
return error;
if (not_used_in_distinct && found_records != join->found_records)
return 0;
@@ -4252,7 +4254,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
mark_as_null_row(join_tab->table); // For group by without error
if (!select_cond || select_cond->val_int())
{
- if ((error=(*next_select)(join,join_tab+1,0)) < 0)
+ if ((error=(*join_tab->next_select)(join,join_tab+1,0)) < 0)
return error; /* purecov: inspected */
}
}
@@ -5449,6 +5451,41 @@ err:
DBUG_RETURN(-1);
}
+/*
+** Add the HAVING criteria to table->select
+*/
+
+#ifdef NOT_YET
+static bool fix_having(JOIN *join, Item **having)
+{
+ (*having)->update_used_tables(); // Some tables may have been const
+ JOIN_TAB *table=&join->join_tab[join->const_tables];
+ table_map used_tables= join->const_table_map | table->table->map;
+
+ DBUG_EXECUTE("where",print_where(*having,"having"););
+ Item* sort_table_cond=make_cond_for_table(*having,used_tables,used_tables);
+ if (sort_table_cond)
+ {
+ if (!table->select)
+ if (!(table->select=new SQL_SELECT))
+ return 1;
+ if (!table->select->cond)
+ table->select->cond=sort_table_cond;
+ else // This should never happen
+ if (!(table->select->cond=new Item_cond_and(table->select->cond,
+ sort_table_cond)))
+ return 1;
+ table->select_cond=table->select->cond;
+ DBUG_EXECUTE("where",print_where(table->select_cond,
+ "select and having"););
+ *having=make_cond_for_table(*having,~ (table_map) 0,~used_tables);
+ DBUG_EXECUTE("where",print_where(*having,"having after make_cond"););
+ }
+ return 0;
+}
+#endif
+
+
/*****************************************************************************
** Remove duplicates from tmp table
** This should be recoded to add a uniuqe index to the table and remove
diff --git a/sql/time.cc b/sql/time.cc
index 440cba457f4..e4565bdeea7 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -429,7 +429,6 @@ timestamp_type
str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
{
uint field_length,year_length,digits,i,number_of_fields,date[7];
- bool date_used=0;
const char *pos;
const char *end=str+length;
DBUG_ENTER("str_to_TIME");
@@ -455,8 +454,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
tmp_value=tmp_value*10 + (uint) (uchar) (*str - '0');
str++;
}
- if ((date[i]=tmp_value))
- date_used=1; // Found something
+ date[i]=tmp_value;
if (i == 2 && str != end && *str == 'T')
str++; // ISO8601: CCYYMMDDThhmmss
else if ( i != 5 ) // Skip inter-field delimiters
@@ -489,7 +487,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
number_of_fields=i;
while (i < 6)
date[i++]=0;
- if (number_of_fields < 3 || !date_used || date[1] > 12 ||
+ if (number_of_fields < 3 || date[1] > 12 ||
date[2] > 31 || date[3] > 23 || date[4] > 59 || date[5] > 59 ||
!fuzzy_date && (date[1] == 0 || date[2] == 0))
{
diff --git a/strings/ctype.c b/strings/ctype.c
index b343ff44bcd..dc827e1a471 100644
--- a/strings/ctype.c
+++ b/strings/ctype.c
@@ -16,7 +16,6 @@
MA 02111-1307, USA */
#include <my_global.h>
-
#include <m_ctype.h>
#include <m_string.h>
diff --git a/strings/strto.c b/strings/strto.c
index adada98e143..72ab29caed3 100644
--- a/strings/strto.c
+++ b/strings/strto.c
@@ -197,7 +197,7 @@ function (const char *nptr,char **endptr,int base)
}
/* Return the result of the appropriate sign. */
- return (negative ? -((longtype) i) : i);
+ return (negative ? -((longtype) i) : (longtype) i);
noconv:
/* There was no number to convert. */
diff --git a/strings/t_ctype.h b/strings/t_ctype.h
index 6aca3fa911c..6699244c1f4 100644
--- a/strings/t_ctype.h
+++ b/strings/t_ctype.h
@@ -123,7 +123,7 @@ enum l1_symbols {
L1_SARA_AE,
L1_SARA_O,
L1_SARA_AI_MAIMUAN,
- L1_SARA_AI_MAIMALAI,
+ L1_SARA_AI_MAIMALAI
};
// level 2 symbols & order
@@ -137,7 +137,7 @@ enum l2_symbols {
L2_TONE1,
L2_TONE2,
L2_TONE3,
- L2_TONE4,
+ L2_TONE4
};
// level 3 symbols & order
@@ -182,7 +182,7 @@ enum l3_symbols {
L3_LESS_THAN,
L3_EQUAL,
L3_GREATER_THAN,
- L3_V_LINE,
+ L3_V_LINE
};
// level 4 symbols & order
@@ -190,7 +190,7 @@ enum l4_symbols {
L4_BLANK = TOT_LEVELS,
L4_MIN,
L4_CAP,
- L4_EXT,
+ L4_EXT
};
enum level_symbols {