Merge mysql.com:/home/mysql_src/mysql-5.0

into  mysql.com:/home/mysql_src/mysql-5.1-merge-of-5.0 (not all files are good,
I'll fix; I'll ask some devs to check their part)


BitKeeper/etc/ignore:
  auto-union
include/my_global.h:
  Auto merged
mysql-test/mysql-test-run.pl:
  Auto merged
mysql-test/mysql-test-run.sh:
  Auto merged
mysql-test/r/information_schema.result:
  Auto merged
mysql-test/t/view.test:
  Auto merged
scripts/mysql_fix_privilege_tables.sql:
  Auto merged
sql/field.cc:
  Auto merged
sql/item.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/set_var.h:
  Auto merged
sql/sp.cc:
  Auto merged
sql/sp_head.cc:
  Auto merged
sql/sql_acl.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
sql/sql_repl.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_select.h:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/table.h:
  Auto merged
storage/myisam/mi_key.c:
  Auto merged
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbImpl.hpp:
  Auto merged
storage/ndb/src/ndbapi/ndb_cluster_connection.cpp:
  Auto merged
support-files/mysql.spec.sh:
  Auto merged
configure.in:
  merge
mysql-test/r/ps_1general.result:
  merge ("ul", will fix)
sql/examples/ha_tina.cc:
  merge
sql/ha_innodb.cc:
  merge
sql/handler.h:
  merge
sql/log.cc:
  merge
sql/set_var.cc:
  merge
sql/share/errmsg.txt:
  merge (bad, will fix)
sql/sql_show.cc:
  merge (bad, will fix)
sql/sql_yacc.yy:
  merge
storage/ndb/src/ndbapi/NdbRecAttr.cpp:
  merge
This commit is contained in:
unknown 2005-11-18 16:38:01 +01:00
commit 41de6f9a7c
101 changed files with 4429 additions and 791 deletions

View File

@ -1,21 +1,39 @@
*.a *.a
*.bb *.bb
*.bbg *.bbg
*.bin
*.core *.core
*.d *.d
*.da *.da
*.exe
*.gcov *.gcov
*.idb
*.la *.la
*.lib
*.lo *.lo
*.map
*.o *.o
*.obj
*.pch
*.pdb
*.reject *.reject
*.res
*.sbr
*.so *.so
*.spec *.spec
*/*_pure_*warnings */*_pure_*warnings
*/.pure */.pure
*~ *~
.*.swp .*.swp
./README.build-files
./config.h ./config.h
./copy_mysql_files.bat
./fix-project-files
./mysql*.ds?
./mysql.ncb
./mysql.sln
./mysql.suo
./prepare
.defs.mk .defs.mk
.depend .depend
.depend.mk .depend.mk
@ -115,6 +133,8 @@ autom4te.cache/*
autom4te.cache/output.0 autom4te.cache/output.0
autom4te.cache/requests autom4te.cache/requests
autom4te.cache/traces.0 autom4te.cache/traces.0
bdb/*.ds?
bdb/*.vcproj
bdb/README bdb/README
bdb/btree/btree_auto.c bdb/btree/btree_auto.c
bdb/build_unix/* bdb/build_unix/*
@ -256,6 +276,9 @@ bkpush.log
bkpush.log* bkpush.log*
build.log build.log
build_tags.sh build_tags.sh
client/*.ds?
client/*.vcproj
client/completion_hash.cpp
client/decimal.c client/decimal.c
client/insert_test client/insert_test
client/log_event.cc client/log_event.cc
@ -265,9 +288,12 @@ client/mf_iocache.cc
client/my_decimal.cc client/my_decimal.cc
client/my_decimal.h client/my_decimal.h
client/mysql client/mysql
client/mysql.cpp
client/mysqladmin client/mysqladmin
client/mysqladmin.c client/mysqladmin.c
client/mysqladmin.cpp
client/mysqlbinlog client/mysqlbinlog
client/mysqlbinlog.cpp
client/mysqlcheck client/mysqlcheck
client/mysqldump client/mysqldump
client/mysqlimport client/mysqlimport
@ -278,14 +304,20 @@ client/mysqltest
client/mysqltestmanager-pwgen client/mysqltestmanager-pwgen
client/mysqltestmanagerc client/mysqltestmanagerc
client/mysys_priv.h client/mysys_priv.h
client/readline.cpp
client/select_test client/select_test
client/sql_string.cpp
client/ssl_test client/ssl_test
client/thimble client/thimble
client/thread_test client/thread_test
client_debug/*
client_release/*
client_test client_test
cmd-line-utils/libedit/common.h cmd-line-utils/libedit/common.h
cmd-line-utils/libedit/makelist cmd-line-utils/libedit/makelist
comon.h comon.h
comp_err/*.ds?
comp_err/*.vcproj
config.cache config.cache
config.guess config.guess
config.h config.h
@ -295,10 +327,14 @@ config.status
config.sub config.sub
configure configure
configure.lineno configure.lineno
contrib/*.ds?
contrib/*.vcproj
core core
core.* core.*
core.2430 core.2430
db-*.*.* db-*.*.*
dbug/*.ds?
dbug/*.vcproj
dbug/dbug_analyze dbug/dbug_analyze
dbug/example*.r dbug/example*.r
dbug/factorial dbug/factorial
@ -309,6 +345,9 @@ dbug/user.ps
dbug/user.t dbug/user.t
depcomp depcomp
emacs.h emacs.h
examples/*.ds?
examples/*.vcproj
examples/udf_example/udf_example.def
extra/charset2html extra/charset2html
extra/comp_err extra/comp_err
extra/created_include_files extra/created_include_files
@ -330,6 +369,8 @@ fcns.h
gdbinit gdbinit
gmon.out gmon.out
hardcopy.0 hardcopy.0
heap/*.ds?
heap/*.vcproj
heap/hp_test1 heap/hp_test1
heap/hp_test2 heap/hp_test2
help help
@ -345,6 +386,8 @@ include/readline/*.h
include/readline/readline.h include/readline/readline.h
include/sql_state.h include/sql_state.h
include/widec.h include/widec.h
innobase/*.ds?
innobase/*.vcproj
innobase/autom4te-2.53.cache/* innobase/autom4te-2.53.cache/*
innobase/autom4te-2.53.cache/output.0 innobase/autom4te-2.53.cache/output.0
innobase/autom4te-2.53.cache/requests innobase/autom4te-2.53.cache/requests
@ -363,18 +406,28 @@ innobase/stamp-h1
insert_test insert_test
install install
install-sh install-sh
isam/*.ds?
isam/*.vcproj
isam/isamchk isam/isamchk
isam/isamlog isam/isamlog
isam/pack_isam isam/pack_isam
isam/test1 isam/test1
isam/test2 isam/test2
isam/test3 isam/test3
isamchk/*.ds?
isamchk/*.vcproj
lib_debug/*
lib_release/*
libmysql/*.c libmysql/*.c
libmysql/*.ds?
libmysql/*.vcproj
libmysql/conf_to_src libmysql/conf_to_src
libmysql/debug/libmysql.exp
libmysql/my_static.h libmysql/my_static.h
libmysql/my_time.c libmysql/my_time.c
libmysql/mysys_priv.h libmysql/mysys_priv.h
libmysql/net.c libmysql/net.c
libmysql/release/libmysql.exp
libmysql/vio_priv.h libmysql/vio_priv.h
libmysql_r/*.c libmysql_r/*.c
libmysql_r/acconfig.h libmysql_r/acconfig.h
@ -382,12 +435,15 @@ libmysql_r/conf_to_src
libmysql_r/my_static.h libmysql_r/my_static.h
libmysql_r/mysys_priv.h libmysql_r/mysys_priv.h
libmysql_r/vio_priv.h libmysql_r/vio_priv.h
libmysqld/*.ds?
libmysqld/*.vcproj
libmysqld/backup_dir libmysqld/backup_dir
libmysqld/client.c libmysqld/client.c
libmysqld/client_settings.h libmysqld/client_settings.h
libmysqld/convert.cc libmysqld/convert.cc
libmysqld/derror.cc libmysqld/derror.cc
libmysqld/discover.cc libmysqld/discover.cc
libmysqld/emb_qcache.cpp
libmysqld/errmsg.c libmysqld/errmsg.c
libmysqld/examples/client_test.c libmysqld/examples/client_test.c
libmysqld/examples/client_test.cc libmysqld/examples/client_test.cc
@ -443,6 +499,7 @@ libmysqld/item_sum.cc
libmysqld/item_timefunc.cc libmysqld/item_timefunc.cc
libmysqld/item_uniq.cc libmysqld/item_uniq.cc
libmysqld/key.cc libmysqld/key.cc
libmysqld/lib_sql.cpp
libmysqld/libmysql.c libmysqld/libmysql.c
libmysqld/lock.cc libmysqld/lock.cc
libmysqld/log.cc libmysqld/log.cc
@ -500,6 +557,7 @@ libmysqld/sql_map.cc
libmysqld/sql_olap.cc libmysqld/sql_olap.cc
libmysqld/sql_parse.cc libmysqld/sql_parse.cc
libmysqld/sql_partition.cc libmysqld/sql_partition.cc
libmysqld/sql_plugin.cc
libmysqld/sql_prepare.cc libmysqld/sql_prepare.cc
libmysqld/sql_rename.cc libmysqld/sql_rename.cc
libmysqld/sql_repl.cc libmysqld/sql_repl.cc
@ -516,6 +574,8 @@ libmysqld/sql_unions.cc
libmysqld/sql_update.cc libmysqld/sql_update.cc
libmysqld/sql_view.cc libmysqld/sql_view.cc
libmysqld/sql_yacc.cc libmysqld/sql_yacc.cc
libmysqld/sql_yacc.cpp
libmysqld/sql_yacc.h
libmysqld/stacktrace.c libmysqld/stacktrace.c
libmysqld/strfunc.cc libmysqld/strfunc.cc
libmysqld/table.cc libmysqld/table.cc
@ -524,6 +584,9 @@ libmysqld/time.cc
libmysqld/tztime.cc libmysqld/tztime.cc
libmysqld/uniques.cc libmysqld/uniques.cc
libmysqld/unireg.cc libmysqld/unireg.cc
libmysqltest/*.ds?
libmysqltest/*.vcproj
libmysqltest/mytest.c
libtool libtool
linked_client_sources linked_client_sources
linked_include_sources linked_include_sources
@ -536,6 +599,8 @@ linked_tools_sources
locked locked
ltmain.sh ltmain.sh
man/*.1 man/*.1
merge/*.ds?
merge/*.vcproj
missing missing
mit-pthreads/config.flags mit-pthreads/config.flags
mit-pthreads/include/bits mit-pthreads/include/bits
@ -547,6 +612,10 @@ mit-pthreads/pg++
mit-pthreads/pgcc mit-pthreads/pgcc
mit-pthreads/syscall.S mit-pthreads/syscall.S
mkinstalldirs mkinstalldirs
my_print_defaults/*.ds?
my_print_defaults/*.vcproj
myisam/*.ds?
myisam/*.vcproj
myisam/FT1.MYD myisam/FT1.MYD
myisam/FT1.MYI myisam/FT1.MYI
myisam/ft_dump myisam/ft_dump
@ -572,17 +641,31 @@ myisam/test1.MYD
myisam/test1.MYI myisam/test1.MYI
myisam/test2.MYD myisam/test2.MYD
myisam/test2.MYI myisam/test2.MYI
myisam_ftdump/*.ds?
myisam_ftdump/*.vcproj
myisamchk/*.ds?
myisamchk/*.vcproj
myisamlog/*.ds?
myisamlog/*.vcproj
myisammrg/*.ds?
myisammrg/*.vcproj
myisampack/*.ds?
myisampack/*.vcproj
mysql-4.0.2-alpha-pc-linux-gnu-i686.tar.gz mysql-4.0.2-alpha-pc-linux-gnu-i686.tar.gz
mysql-4.0.2-alpha.tar.gz mysql-4.0.2-alpha.tar.gz
mysql-4.1.8-win-src.zip mysql-4.1.8-win-src.zip
mysql-5.0.2-alpha.tar.gz mysql-5.0.2-alpha.tar.gz
mysql-max-4.0.2-alpha-pc-linux-gnu-i686.tar.gz mysql-max-4.0.2-alpha-pc-linux-gnu-i686.tar.gz
mysql-test/*.ds?
mysql-test/*.vcproj
mysql-test/gmon.out mysql-test/gmon.out
mysql-test/install_test_db mysql-test/install_test_db
mysql-test/mysql-test-run mysql-test/mysql-test-run
mysql-test/mysql-test-run.log mysql-test/mysql-test-run.log
mysql-test/mysql_test_run_new mysql-test/mysql_test_run_new
mysql-test/ndb/ndbcluster mysql-test/ndb/ndbcluster
mysql-test/r/*.err
mysql-test/r/*.out
mysql-test/r/*.reject mysql-test/r/*.reject
mysql-test/r/alter_table.err mysql-test/r/alter_table.err
mysql-test/r/archive.err mysql-test/r/archive.err
@ -654,13 +737,25 @@ mysql-test/var/*
mysql.kdevprj mysql.kdevprj
mysql.proj mysql.proj
mysql_priv.h mysql_priv.h
mysqlbinlog/*.ds?
mysqlbinlog/*.vcproj
mysqlcheck/*.ds?
mysqlcheck/*.vcproj
mysqld.S mysqld.S
mysqld.sym mysqld.sym
mysqldemb/*.ds?
mysqldemb/*.vcproj
mysqlserver/*.ds?
mysqlserver/*.vcproj
mysys/#mf_iocache.c# mysys/#mf_iocache.c#
mysys/*.ds?
mysys/*.vcproj
mysys/charset2html mysys/charset2html
mysys/getopt.c mysys/getopt.c
mysys/getopt1.c mysys/getopt1.c
mysys/main.cc mysys/main.cc
mysys/my_new.cpp
mysys/raid.cpp
mysys/ste5KbMa mysys/ste5KbMa
mysys/test_charset mysys/test_charset
mysys/test_dir mysys/test_dir
@ -924,13 +1019,20 @@ ndbcluster-1186/ndb_3.pid
ndbcluster-1186/ndb_3_cluster.log ndbcluster-1186/ndb_3_cluster.log
ndbcluster-1186/ndb_3_out.log ndbcluster-1186/ndb_3_out.log
ndbcluster-1186/ndbcluster.pid ndbcluster-1186/ndbcluster.pid
pack_isam/*.ds?
perror/*.ds?
perror/*.vcproj
pull.log pull.log
regex/*.ds?
regex/*.vcproj
regex/re regex/re
repl-tests/test-repl-ts/repl-timestamp.master.reject repl-tests/test-repl-ts/repl-timestamp.master.reject
repl-tests/test-repl/foo-dump-slave.master. repl-tests/test-repl/foo-dump-slave.master.
repl-tests/test-repl/sum-wlen-slave.master. repl-tests/test-repl/sum-wlen-slave.master.
repl-tests/test-repl/sum-wlen-slave.master.re repl-tests/test-repl/sum-wlen-slave.master.re
repl-tests/test-repl/sum-wlen-slave.master.reje repl-tests/test-repl/sum-wlen-slave.master.reje
replace/*.ds?
replace/*.vcproj
scripts/fill_func_tables scripts/fill_func_tables
scripts/fill_func_tables.sql scripts/fill_func_tables.sql
scripts/fill_help_tables scripts/fill_help_tables
@ -961,11 +1063,31 @@ scripts/mysqlhotcopy
scripts/mysqlhotcopy.sh.rej scripts/mysqlhotcopy.sh.rej
scripts/safe_mysqld scripts/safe_mysqld
select_test select_test
server-tools/instance-manager/buffer.cpp
server-tools/instance-manager/client.c server-tools/instance-manager/client.c
server-tools/instance-manager/client_settings.h server-tools/instance-manager/client_settings.h
server-tools/instance-manager/command.cpp
server-tools/instance-manager/commands.cpp
server-tools/instance-manager/errmsg.c server-tools/instance-manager/errmsg.c
server-tools/instance-manager/guardian.cpp
server-tools/instance-manager/instance.cpp
server-tools/instance-manager/instance_map.cpp
server-tools/instance-manager/instance_options.cpp
server-tools/instance-manager/listener.cpp
server-tools/instance-manager/log.cpp
server-tools/instance-manager/manager.cpp
server-tools/instance-manager/messages.cpp
server-tools/instance-manager/mysql_connection.cpp
server-tools/instance-manager/mysqlmanager server-tools/instance-manager/mysqlmanager
server-tools/instance-manager/mysqlmanager.cpp
server-tools/instance-manager/options.cpp
server-tools/instance-manager/parse.cpp
server-tools/instance-manager/parse_output.cpp
server-tools/instance-manager/priv.cpp
server-tools/instance-manager/protocol.cpp
server-tools/instance-manager/thr_alarm.c server-tools/instance-manager/thr_alarm.c
server-tools/instance-manager/thread_registry.cpp
server-tools/instance-manager/user_map.cpp
sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686 sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686
sql-bench/bench-count-distinct sql-bench/bench-count-distinct
sql-bench/bench-init.pl sql-bench/bench-init.pl
@ -994,12 +1116,19 @@ sql-bench/test-insert
sql-bench/test-select sql-bench/test-select
sql-bench/test-transactions sql-bench/test-transactions
sql-bench/test-wisconsin sql-bench/test-wisconsin
sql/*.cpp
sql/*.ds?
sql/*.vcproj
sql/.gdbinit sql/.gdbinit
sql/client.c sql/client.c
sql/gen_lex_hash sql/gen_lex_hash
sql/gmon.out sql/gmon.out
sql/handlerton.cc sql/handlerton.cc
sql/lex_hash.h sql/lex_hash.h
sql/max/*
sql/message.h
sql/message.mc
sql/message.rc
sql/mini_client_errors.c sql/mini_client_errors.c
sql/my_time.c sql/my_time.c
sql/mysql_tzinfo_to_sql sql/mysql_tzinfo_to_sql
@ -1338,7 +1467,6 @@ storage/ndb/src/common/transporter/libtransporter.dsp
storage/ndb/src/common/util/libgeneral.dsp storage/ndb/src/common/util/libgeneral.dsp
storage/ndb/src/cw/cpcd/ndb_cpcd storage/ndb/src/cw/cpcd/ndb_cpcd
storage/ndb/src/dummy.cpp storage/ndb/src/dummy.cpp
storage/ndb/src/kernel/blocks/ndb_print_file
storage/ndb/src/kernel/blocks/backup/libbackup.dsp storage/ndb/src/kernel/blocks/backup/libbackup.dsp
storage/ndb/src/kernel/blocks/backup/ndb_print_backup_file storage/ndb/src/kernel/blocks/backup/ndb_print_backup_file
storage/ndb/src/kernel/blocks/backup/restore/ndb_restore storage/ndb/src/kernel/blocks/backup/restore/ndb_restore
@ -1355,6 +1483,7 @@ storage/ndb/src/kernel/blocks/dbtup/test_varpage
storage/ndb/src/kernel/blocks/dbtux/libdbtux.dsp storage/ndb/src/kernel/blocks/dbtux/libdbtux.dsp
storage/ndb/src/kernel/blocks/dbutil/libdbutil.dsp storage/ndb/src/kernel/blocks/dbutil/libdbutil.dsp
storage/ndb/src/kernel/blocks/grep/libgrep.dsp storage/ndb/src/kernel/blocks/grep/libgrep.dsp
storage/ndb/src/kernel/blocks/ndb_print_file
storage/ndb/src/kernel/blocks/ndbcntr/libndbcntr.dsp storage/ndb/src/kernel/blocks/ndbcntr/libndbcntr.dsp
storage/ndb/src/kernel/blocks/ndbfs/libndbfs.dsp storage/ndb/src/kernel/blocks/ndbfs/libndbfs.dsp
storage/ndb/src/kernel/blocks/qmgr/libqmgr.dsp storage/ndb/src/kernel/blocks/qmgr/libqmgr.dsp
@ -1449,6 +1578,8 @@ storage/ndb/tools/ndb_show_tables.dsp
storage/ndb/tools/ndb_test_platform storage/ndb/tools/ndb_test_platform
storage/ndb/tools/ndb_waiter storage/ndb/tools/ndb_waiter
storage/ndb/tools/ndb_waiter.dsp storage/ndb/tools/ndb_waiter.dsp
strings/*.ds?
strings/*.vcproj
strings/conf_to_src strings/conf_to_src
strings/ctype_autoconf.c strings/ctype_autoconf.c
strings/ctype_extra_sources.c strings/ctype_extra_sources.c
@ -1529,10 +1660,15 @@ test/tools/hugoScanUpdate
test/tools/ndb_cpcc test/tools/ndb_cpcc
test/tools/restart test/tools/restart
test/tools/verify_index test/tools/verify_index
test1/*
test_xml test_xml
tests/*.ds?
tests/*.vcproj
tests/client_test tests/client_test
tests/connect_test tests/connect_test
tests/mysql_client_test tests/mysql_client_test
thr_insert_test/*
thr_test/*
thread_test thread_test
tmp/* tmp/*
tools/my_vsnprintf.c tools/my_vsnprintf.c
@ -1541,8 +1677,13 @@ tools/mysqlmngd
tools/mysqltestmanager tools/mysqltestmanager
tools/mysys_priv.h tools/mysys_priv.h
vi.h vi.h
vio/*.ds?
vio/*.vcproj
vio/test-ssl vio/test-ssl
vio/test-sslclient vio/test-sslclient
vio/test-sslserver vio/test-sslserver
vio/viotest-ssl vio/viotest-ssl
libmysqld/sql_plugin.cc vio/viotest-sslconnect.cpp
vio/viotest.cpp
zlib/*.ds?
zlib/*.vcproj

View File

@ -3,13 +3,13 @@
path=`dirname $0` path=`dirname $0`
. "$path/SETUP.sh" . "$path/SETUP.sh"
extra_flags="$pentium64_cflags $debug_cflags -USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify -DMYSQL_SERVER_SUFFIX=-valgrind-max" extra_flags="$pentium64_cflags $debug_cflags $max_cflags -USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify -DMYSQL_SERVER_SUFFIX=-valgrind-max"
c_warnings="$c_warnings $debug_extra_warnings" c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs" extra_configs="$pentium_configs $debug_configs"
# We want to test isam when building with valgrind # We want to test isam when building with valgrind
extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-isam --with-embedded-server --with-openssl --with-raid --with-ndbcluster" extra_configs="$extra_configs $max_leave_isam_configs --with-isam"
. "$path/FINISH.sh" . "$path/FINISH.sh"

View File

@ -22,7 +22,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
OptimizeForProcessor="2" OptimizeForProcessor="2"
AdditionalIncludeDirectories="../include,../,../sql" AdditionalIncludeDirectories="../include,../,../sql,../strings"
PreprocessorDefinitions="_DEBUG;SAFEMALLOC;SAFE_MUTEX;_CONSOLE;_WINDOWS;MYSQL_SERVER" PreprocessorDefinitions="_DEBUG;SAFEMALLOC;SAFE_MUTEX;_CONSOLE;_WINDOWS;MYSQL_SERVER"
RuntimeLibrary="1" RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug/mysqlbinlog.pch" PrecompiledHeaderFile=".\Debug/mysqlbinlog.pch"

View File

@ -89,8 +89,9 @@ case $SYSTEM_TYPE in
fi fi
;; ;;
*) *)
if test -f "$mysql_zlib_dir/lib/libz.a" -a \ if test \( -f "$mysql_zlib_dir/lib/libz.a" -o -f "$mysql_zlib_dir/lib/libz.so" -o \
-f "$mysql_zlib_dir/include/zlib.h"; then -f "$mysql_zlib_dir/lib/libz.sl" -o -f "$mysql_zlib_dir/lib/libz.dylib" \) \
-a -f "$mysql_zlib_dir/include/zlib.h"; then
ZLIB_INCLUDES="-I$mysql_zlib_dir/include" ZLIB_INCLUDES="-I$mysql_zlib_dir/include"
ZLIB_LIBS="-L$mysql_zlib_dir/lib -lz" ZLIB_LIBS="-L$mysql_zlib_dir/lib -lz"
MYSQL_CHECK_ZLIB_DIR MYSQL_CHECK_ZLIB_DIR

View File

@ -311,6 +311,10 @@ case "$target_os" in
# Use the built-in alloca() # Use the built-in alloca()
CFLAGS="$CFLAGS -Kalloca" CFLAGS="$CFLAGS -Kalloca"
CXXFLAGS="$CFLAGS -Kalloca" CXXFLAGS="$CFLAGS -Kalloca"
# Use no_implicit for templates
CXXFLAGS="$CXXFLAGS -Tno_implicit"
AC_DEFINE([HAVE_EXPLICIT_TEMPLATE_INSTANTIATION],
[1], [Defined by configure. Use explicit template instantiation.])
fi fi
;; ;;
esac esac

View File

@ -39,7 +39,7 @@
#include <string.h> #include <string.h>
#endif // _WIN32 #endif // _WIN32
#ifdef __sun #if defined(__sun) || defined(__SCO_VERSION__)
#include <sys/filio.h> #include <sys/filio.h>
#endif #endif

View File

@ -26,13 +26,17 @@
#include "runtime.hpp" #include "runtime.hpp"
#include "timer.hpp" #include "timer.hpp"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <sys/time.h>
#endif
namespace yaSSL { namespace yaSSL {
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
timer_d timer() timer_d timer()
{ {
static bool init(false); static bool init(false);
@ -57,8 +61,6 @@ namespace yaSSL {
#else // _WIN32 #else // _WIN32
#include <sys/time.h>
timer_d timer() timer_d timer()
{ {
struct timeval tv; struct timeval tv;

View File

@ -392,8 +392,8 @@ inline double ulonglong2double(ulonglong value)
#define HAVE_SPATIAL 1 #define HAVE_SPATIAL 1
#define HAVE_RTREE_KEYS 1 #define HAVE_RTREE_KEYS 1
#define HAVE_OPENSSL 1 /* #undef HAVE_OPENSSL */
#define HAVE_YASSL 1 /* #undef HAVE_YASSL */
/* Define charsets you want */ /* Define charsets you want */
/* #undef HAVE_CHARSET_armscii8 */ /* #undef HAVE_CHARSET_armscii8 */

View File

@ -641,6 +641,15 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define O_NOFOLLOW 0 #define O_NOFOLLOW 0
#endif #endif
/* additional file share flags for win32 */
#ifdef __WIN__
#define _SH_DENYRWD 0x110 /* deny read/write mode & delete */
#define _SH_DENYWRD 0x120 /* deny write mode & delete */
#define _SH_DENYRDD 0x130 /* deny read mode & delete */
#define _SH_DENYDEL 0x140 /* deny delete only */
#endif /* __WIN__ */
/* #define USE_RECORD_LOCK */ /* #define USE_RECORD_LOCK */
/* Unsigned types supported by the compiler */ /* Unsigned types supported by the compiler */

View File

@ -601,6 +601,7 @@ extern char *_my_strdup_with_length(const byte *from, uint length,
#ifdef __WIN__ #ifdef __WIN__
extern int my_access(const char *path, int amode); extern int my_access(const char *path, int amode);
extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
#else #else
#define my_access access #define my_access access
#endif #endif

View File

@ -947,6 +947,7 @@ sub executable_setup () {
$path_client_bindir= mtr_path_exists("$glob_basedir/bin"); $path_client_bindir= mtr_path_exists("$glob_basedir/bin");
$exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck"); $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck");
$exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
$exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport");
$exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
$exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
$exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
@ -2008,7 +2009,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir); mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir);
mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir); mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir);
mtr_add_arg($args, "%s--core", $prefix); mtr_add_arg($args, "%s--core", $prefix);
mtr_add_arg($args, "%s--log-bin-trust-routine-creators", $prefix); mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
mtr_add_arg($args, "%s--default-character-set=latin1", $prefix); mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language); mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix); mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
@ -2131,7 +2132,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix); mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix);
mtr_add_arg($args, "%s--sort_buffer=256K", $prefix); mtr_add_arg($args, "%s--sort_buffer=256K", $prefix);
mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix); mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix);
mtr_add_arg($args, "%s--log-bin-trust-routine-creators", $prefix); mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
if ( $opt_ssl_supported ) if ( $opt_ssl_supported )
{ {

View File

@ -1275,7 +1275,7 @@ start_master()
--language=$LANGUAGE \ --language=$LANGUAGE \
--innodb_data_file_path=ibdata1:128M:autoextend \ --innodb_data_file_path=ibdata1:128M:autoextend \
--open-files-limit=1024 \ --open-files-limit=1024 \
--log-bin-trust-routine-creators \ --log-bin-trust-function-creators \
$MASTER_40_ARGS \ $MASTER_40_ARGS \
$SMALL_SERVER \ $SMALL_SERVER \
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
@ -1296,7 +1296,7 @@ start_master()
--tmpdir=$MYSQL_TMP_DIR \ --tmpdir=$MYSQL_TMP_DIR \
--language=$LANGUAGE \ --language=$LANGUAGE \
--innodb_data_file_path=ibdata1:128M:autoextend \ --innodb_data_file_path=ibdata1:128M:autoextend \
--log-bin-trust-routine-creators \ --log-bin-trust-function-creators \
$MASTER_40_ARGS \ $MASTER_40_ARGS \
$SMALL_SERVER \ $SMALL_SERVER \
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
@ -1429,7 +1429,7 @@ start_slave()
--report-port=$slave_port \ --report-port=$slave_port \
--master-retry-count=10 \ --master-retry-count=10 \
-O slave_net_timeout=10 \ -O slave_net_timeout=10 \
--log-bin-trust-routine-creators \ --log-bin-trust-function-creators \
$SMALL_SERVER \ $SMALL_SERVER \
$EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT" $EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT"
CUR_MYERR=$slave_err CUR_MYERR=$slave_err

View File

@ -486,7 +486,7 @@ void start_master()
#endif #endif
add_arg(&al, "--local-infile"); add_arg(&al, "--local-infile");
add_arg(&al, "--core"); add_arg(&al, "--core");
add_arg(&al, "--log-bin-trust-routine-creators"); add_arg(&al, "--log-bin-trust-function-creators");
add_arg(&al, "--datadir=%s", master_dir); add_arg(&al, "--datadir=%s", master_dir);
#ifndef __WIN__ #ifndef __WIN__
add_arg(&al, "--pid-file=%s", master_pid); add_arg(&al, "--pid-file=%s", master_pid);

View File

@ -1,4 +1,4 @@
drop table if exists t1; drop table if exists t1, t2;
select 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296; select 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296;
0 256 00000000000000065536 2147483647 -2147483648 2147483648 4294967296 0 256 00000000000000065536 2147483647 -2147483648 2147483648 4294967296
0 256 65536 2147483647 -2147483648 2147483648 4294967296 0 256 65536 2147483647 -2147483648 2147483648 4294967296

View File

@ -1,4 +1,4 @@
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3,t4,t5;
drop database if exists mysqltest; drop database if exists mysqltest;
create table t1 (b char(0)); create table t1 (b char(0));
insert into t1 values (""),(null); insert into t1 values (""),(null);
@ -654,3 +654,92 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`a`) PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
CREATE TABLE t2 (
a int(11) default NULL
);
insert into t2 values(111);
create table t1 (
a varchar(12) charset utf8 collate utf8_bin not null,
b int not null, primary key (a)
) select a, 1 as b from t2 ;
Warnings:
Warning 1364 Field 'a' doesn't have a default value
Warning 1364 Field 'b' doesn't have a default value
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(12) character set utf8 collate utf8_bin NOT NULL,
`b` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (
a varchar(12) charset utf8 collate utf8_bin not null,
b int not null, primary key (a)
) select 'a' as a , 1 as b from t2 ;
Warnings:
Warning 1364 Field 'a' doesn't have a default value
Warning 1364 Field 'b' doesn't have a default value
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(12) character set utf8 collate utf8_bin NOT NULL,
`b` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (
a varchar(12) charset utf8 collate utf8_bin,
b int not null, primary key (a)
) select 'a' as a , 1 as b from t2 ;
Warnings:
Warning 1364 Field 'b' doesn't have a default value
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(12) character set utf8 collate utf8_bin NOT NULL default '',
`b` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2;
create table t1 (
a1 int not null,
a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int
);
insert into t1 values (1,1,1, 1,1,1, 1,1,1);
create table t2 (
a1 varchar(12) charset utf8 collate utf8_bin not null,
a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int,
primary key (a1)
) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ;
Warnings:
Warning 1364 Field 'a1' doesn't have a default value
drop table t2;
create table t2 (
a1 varchar(12) charset utf8 collate utf8_bin,
a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int
) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1;
drop table t1, t2;
create table t1 (
a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int
);
insert into t1 values (1,1,1, 1,1,1, 1,1,1);
create table t2 (
a1 varchar(12) charset utf8 collate utf8_bin not null,
a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int,
primary key (a1)
) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ;
Warnings:
Warning 1364 Field 'a1' doesn't have a default value
drop table t2;
create table t2 ( a int default 3, b int default 3)
select a1,a2 from t1;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) default '3',
`b` int(11) default '3',
`a1` int(11) default NULL,
`a2` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2;

View File

@ -4929,3 +4929,50 @@ Warnings:
Note 1051 Unknown table 't2' Note 1051 Unknown table 't2'
Note 1051 Unknown table 't3' Note 1051 Unknown table 't3'
Note 1051 Unknown table 't4' Note 1051 Unknown table 't4'
DROP TABLE IF EXISTS bug13894;
CREATE TABLE bug13894 ( val integer ) ENGINE = CSV;
INSERT INTO bug13894 VALUES (5);
INSERT INTO bug13894 VALUES (10);
INSERT INTO bug13894 VALUES (11);
INSERT INTO bug13894 VALUES (10);
SELECT * FROM bug13894;
val
5
10
11
10
UPDATE bug13894 SET val=6 WHERE val=10;
SELECT * FROM bug13894;
val
5
11
6
6
DROP TABLE bug13894;
DROP TABLE IF EXISTS bug14672;
CREATE TABLE bug14672 (c1 integer) engine = CSV;
INSERT INTO bug14672 VALUES (1), (2), (3);
SELECT * FROM bug14672;
c1
1
2
3
DELETE FROM bug14672 WHERE c1 = 2;
SELECT * FROM bug14672;
c1
1
3
INSERT INTO bug14672 VALUES (4);
SELECT * FROM bug14672;
c1
1
3
4
INSERT INTO bug14672 VALUES (5);
SELECT * FROM bug14672;
c1
1
3
4
5
DROP TABLE bug14672;

View File

@ -648,12 +648,16 @@ drop function sub1;
select table_name from information_schema.views select table_name from information_schema.views
where table_schema='test'; where table_schema='test';
table_name table_name
v2
v3
Warnings: Warnings:
Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
select table_name from information_schema.views select table_name from information_schema.views
where table_schema='test'; where table_schema='test';
table_name table_name
v2
v3
Warnings: Warnings:
Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
@ -670,6 +674,16 @@ f1_key
select constraint_name from information_schema.table_constraints select constraint_name from information_schema.table_constraints
where table_schema='test'; where table_schema='test';
constraint_name constraint_name
show create view v2;
View Create View
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `test`.`t1`.`f1` AS `c` from `t1`
Warnings:
Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
show create table v3;
View Create View
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select sql_no_cache `test`.`sub1`(1) AS `c`
Warnings:
Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
drop view v2; drop view v2;
drop view v3; drop view v3;
drop table t4; drop table t4;
@ -723,6 +737,7 @@ information_schema ROUTINES SQL_MODE
information_schema TRIGGERS ACTION_CONDITION information_schema TRIGGERS ACTION_CONDITION
information_schema TRIGGERS ACTION_STATEMENT information_schema TRIGGERS ACTION_STATEMENT
information_schema TRIGGERS SQL_MODE information_schema TRIGGERS SQL_MODE
information_schema TRIGGERS DEFINER
information_schema VIEWS VIEW_DEFINITION information_schema VIEWS VIEW_DEFINITION
select table_name, column_name, data_type from information_schema.columns select table_name, column_name, data_type from information_schema.columns
where data_type = 'datetime'; where data_type = 'datetime';
@ -801,45 +816,45 @@ set @fired:= "Yes";
end if; end if;
end| end|
show triggers; show triggers;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 trg1 INSERT t1
begin begin
if new.j > 10 then if new.j > 10 then
set new.j := 10; set new.j := 10;
end if; end if;
end BEFORE NULL end BEFORE NULL root@localhost
trg2 UPDATE t1 trg2 UPDATE t1
begin begin
if old.i % 2 = 0 then if old.i % 2 = 0 then
set new.j := -1; set new.j := -1;
end if; end if;
end BEFORE NULL end BEFORE NULL root@localhost
trg3 UPDATE t1 trg3 UPDATE t1
begin begin
if new.j = -1 then if new.j = -1 then
set @fired:= "Yes"; set @fired:= "Yes";
end if; end if;
end AFTER NULL end AFTER NULL root@localhost
select * from information_schema.triggers; select * from information_schema.triggers;
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER
NULL test trg1 INSERT NULL test t1 0 NULL NULL test trg1 INSERT NULL test t1 0 NULL
begin begin
if new.j > 10 then if new.j > 10 then
set new.j := 10; set new.j := 10;
end if; end if;
end ROW BEFORE NULL NULL OLD NEW NULL end ROW BEFORE NULL NULL OLD NEW NULL root@localhost
NULL test trg2 UPDATE NULL test t1 0 NULL NULL test trg2 UPDATE NULL test t1 0 NULL
begin begin
if old.i % 2 = 0 then if old.i % 2 = 0 then
set new.j := -1; set new.j := -1;
end if; end if;
end ROW BEFORE NULL NULL OLD NEW NULL end ROW BEFORE NULL NULL OLD NEW NULL root@localhost
NULL test trg3 UPDATE NULL test t1 0 NULL NULL test trg3 UPDATE NULL test t1 0 NULL
begin begin
if new.j = -1 then if new.j = -1 then
set @fired:= "Yes"; set @fired:= "Yes";
end if; end if;
end ROW AFTER NULL NULL OLD NEW NULL end ROW AFTER NULL NULL OLD NEW NULL root@localhost
drop trigger trg1; drop trigger trg1;
drop trigger trg2; drop trigger trg2;
drop trigger trg3; drop trigger trg3;

View File

@ -1403,3 +1403,67 @@ SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
ERROR 42S22: Unknown column 'v2.x' in 'field list' ERROR 42S22: Unknown column 'v2.x' in 'field list'
DROP VIEW v1, v2; DROP VIEW v1, v2;
DROP TABLE t1, t2, t3, t4, t5, t6; DROP TABLE t1, t2, t3, t4, t5, t6;
create table t1 (id1 int(11) not null);
insert into t1 values (1),(2);
create table t2 (id2 int(11) not null);
insert into t2 values (1),(2),(3),(4);
create table t3 (id3 char(16) not null);
insert into t3 values ('100');
create table t4 (id2 int(11) not null, id3 char(16));
create table t5 (id1 int(11) not null, key (id1));
insert into t5 values (1),(2),(1);
create view v1 as
select t4.id3 from t4 join t2 on t4.id2 = t2.id2;
select t1.id1 from t1 inner join (t3 left join v1 on t3.id3 = v1.id3);
id1
1
2
drop view v1;
drop table t1, t2, t3, t4, t5;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3);
create table t1(a int);
insert into t1 select A.a + 10*(B.a) from t0 A, t0 B;
create table t2 (a int, b int);
insert into t2 values (1,1), (2,2), (3,3);
create table t3(a int, b int, filler char(200), key(a));
insert into t3 select a,a,'filler' from t1;
insert into t3 select a,a,'filler' from t1;
create table t4 like t3;
insert into t4 select * from t3;
insert into t4 select * from t3;
create table t5 like t4;
insert into t5 select * from t4;
insert into t5 select * from t4;
create table t6 like t5;
insert into t6 select * from t5;
insert into t6 select * from t5;
create table t7 like t6;
insert into t7 select * from t6;
insert into t7 select * from t6;
explain select * from t4 join
t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
1 SIMPLE t3 ref a a 5 test.t2.b X
1 SIMPLE t5 ref a a 5 test.t3.b X
1 SIMPLE t4 ref a a 5 test.t3.b X Using where
explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b
join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
1 SIMPLE t3 ref a a 5 test.t2.b X Using where
1 SIMPLE t4 ref a a 5 test.t3.b X
1 SIMPLE t6 ref a a 5 test.t4.b X
1 SIMPLE t5 ref a a 5 test.t2.b X
1 SIMPLE t7 ref a a 5 test.t5.b X
explain select * from t2 left join
(t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b
join t5 on t5.a=t3.b) on t3.a=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
1 SIMPLE t3 ref a a 5 test.t2.b X
1 SIMPLE t4 ref a a 5 test.t3.b X
1 SIMPLE t6 ref a a 5 test.t4.b X
1 SIMPLE t5 ref a a 5 test.t3.b X
drop table t0, t1, t2, t4, t5, t6;

View File

@ -701,6 +701,24 @@ t1 1 a 2 b A 0 NULL NULL YES BTREE
t1 1 a 3 c A 0 NULL NULL YES BTREE t1 1 a 3 c A 0 NULL NULL YES BTREE
t1 1 a 4 d A 0 NULL NULL YES BTREE t1 1 a 4 d A 0 NULL NULL YES BTREE
set myisam_stats_method=DEFAULT; set myisam_stats_method=DEFAULT;
drop table t1;
create table t1(
cip INT NOT NULL,
time TIME NOT NULL,
score INT NOT NULL DEFAULT 0,
bob TINYBLOB
);
insert into t1 (cip, time) VALUES (1, '00:01'), (2, '00:02'), (3,'00:03');
insert into t1 (cip, bob, time) VALUES (4, 'a', '00:04'), (5, 'b', '00:05'),
(6, 'c', '00:06');
select * from t1 where bob is null and cip=1;
cip time score bob
1 00:01:00 0 NULL
create index bug on t1 (bob(22), cip, time);
select * from t1 where bob is null and cip=1;
cip time score bob
1 00:01:00 0 NULL
drop table t1;
set storage_engine=MyISAM; set storage_engine=MyISAM;
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
--- Testing varchar --- --- Testing varchar ---

View File

@ -1614,6 +1614,16 @@ mysqldump: Couldn't find table: "t\1"
mysqldump: Couldn't find table: "t/1" mysqldump: Couldn't find table: "t/1"
mysqldump: Couldn't find table: "T_1"
mysqldump: Couldn't find table: "T%1"
mysqldump: Couldn't find table: "T'1"
mysqldump: Couldn't find table: "T_1"
mysqldump: Couldn't find table: "T_"
test_sequence test_sequence
------ Testing with illegal database names ------ ------ Testing with illegal database names ------
mysqldump: Got error: 1049: Unknown database 'mysqldump_test_d' when selecting the database mysqldump: Got error: 1049: Unknown database 'mysqldump_test_d' when selecting the database
@ -1926,23 +1936,23 @@ end if;
end| end|
set sql_mode=default| set sql_mode=default|
show triggers like "t1"; show triggers like "t1";
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 trg1 INSERT t1
begin begin
if new.a > 10 then if new.a > 10 then
set new.a := 10; set new.a := 10;
set new.a := 11; set new.a := 11;
end if; end if;
end BEFORE 0000-00-00 00:00:00 end BEFORE 0000-00-00 00:00:00 root@localhost
trg2 UPDATE t1 begin trg2 UPDATE t1 begin
if old.a % 2 = 0 then set new.b := 12; end if; if old.a % 2 = 0 then set new.b := 12; end if;
end BEFORE 0000-00-00 00:00:00 end BEFORE 0000-00-00 00:00:00 root@localhost
trg3 UPDATE t1 trg3 UPDATE t1
begin begin
if new.a = -1 then if new.a = -1 then
set @fired:= "Yes"; set @fired:= "Yes";
end if; end if;
end AFTER 0000-00-00 00:00:00 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER end AFTER 0000-00-00 00:00:00 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost
INSERT INTO t1 (a) VALUES (1),(2),(3),(22); INSERT INTO t1 (a) VALUES (1),(2),(3),(22);
update t1 set a = 4 where a=3; update t1 set a = 4 where a=3;
@ -2085,29 +2095,29 @@ Tables_in_test
t1 t1
t2 t2
show triggers; show triggers;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 trg1 INSERT t1
begin begin
if new.a > 10 then if new.a > 10 then
set new.a := 10; set new.a := 10;
set new.a := 11; set new.a := 11;
end if; end if;
end BEFORE # end BEFORE # root@localhost
trg2 UPDATE t1 begin trg2 UPDATE t1 begin
if old.a % 2 = 0 then set new.b := 12; end if; if old.a % 2 = 0 then set new.b := 12; end if;
end BEFORE # end BEFORE # root@localhost
trg3 UPDATE t1 trg3 UPDATE t1
begin begin
if new.a = -1 then if new.a = -1 then
set @fired:= "Yes"; set @fired:= "Yes";
end if; end if;
end AFTER # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER end AFTER # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost
trg4 INSERT t2 trg4 INSERT t2
begin begin
if new.a > 10 then if new.a > 10 then
set @fired:= "No"; set @fired:= "No";
end if; end if;
end BEFORE # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER end BEFORE # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost
DROP TABLE t1, t2; DROP TABLE t1, t2;
--port=1234 --port=1234
--port=1234 --port=1234
@ -2130,9 +2140,9 @@ SELECT * FROM `test2`;
a2 a2
1 1
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
testref INSERT test1 BEGIN testref INSERT test1 BEGIN
INSERT INTO test2 SET a2 = NEW.a1; END BEFORE NULL INSERT INTO test2 SET a2 = NEW.a1; END BEFORE NULL root@localhost
SELECT * FROM `test1`; SELECT * FROM `test1`;
a1 a1
1 1
@ -2147,6 +2157,7 @@ DROP FUNCTION IF EXISTS bug9056_func1;
DROP FUNCTION IF EXISTS bug9056_func2; DROP FUNCTION IF EXISTS bug9056_func2;
DROP PROCEDURE IF EXISTS bug9056_proc1; DROP PROCEDURE IF EXISTS bug9056_proc1;
DROP PROCEDURE IF EXISTS bug9056_proc2; DROP PROCEDURE IF EXISTS bug9056_proc2;
DROP PROCEDURE IF EXISTS `a'b`;
CREATE TABLE t1 (id int); CREATE TABLE t1 (id int);
INSERT INTO t1 VALUES(1), (2), (3), (4), (5); INSERT INTO t1 VALUES(1), (2), (3), (4), (5);
CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) RETURN a+b // CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) RETURN a+b //

View File

@ -0,0 +1,43 @@
DROP TABLE IF EXISTS t1,t2,t3;
grant CREATE, SELECT, DROP on *.* to test@localhost;
set global read_only=0;
create table t1 (a int);
insert into t1 values(1);
create table t2 select * from t1;
set global read_only=1;
create table t3 (a int);
drop table t3;
select @@global.read_only;
@@global.read_only
1
create table t3 (a int);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
insert into t1 values(1);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
update t1 set a=1 where 1=0;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
delete t1,t2 from t1,t2 where t1.a=t2.a;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
create temporary table t3 (a int);
create temporary table t4 (a int) select * from t3;
insert into t3 values(1);
insert into t4 select * from t3;
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a;
update t4,t3 set t4.a=t3.a+1 where t4.a=t3.a;
delete t1 from t1,t3 where t1.a=t3.a;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
delete t3 from t1,t3 where t1.a=t3.a;
delete t4 from t3,t4 where t4.a=t3.a;
create temporary table t1 (a int);
insert into t1 values(1);
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
delete t1 from t1,t3 where t1.a=t3.a;
drop table t1;
insert into t1 values(1);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
drop table t1,t2;
drop user test@localhost;

View File

@ -1465,13 +1465,13 @@ flush logs;
-------- switch to master ------- -------- switch to master -------
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 SET @a:=1 BEFORE NULL trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost
-------- switch to slave ------- -------- switch to slave -------
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 SET @a:=1 BEFORE NULL trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost
######## DROP TRIGGER trg1 ######## ######## DROP TRIGGER trg1 ########
@ -1520,11 +1520,11 @@ flush logs;
-------- switch to master ------- -------- switch to master -------
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
-------- switch to slave ------- -------- switch to slave -------
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
######## CREATE USER user1@localhost ######## ######## CREATE USER user1@localhost ########

View File

@ -4,16 +4,11 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
create database if not exists mysqltest1; drop database if exists mysqltest1;
create database mysqltest1;
use mysqltest1; use mysqltest1;
create table t1 (a varchar(100)); create table t1 (a varchar(100));
use mysqltest1; use mysqltest1;
drop procedure if exists foo;
drop procedure if exists foo2;
drop procedure if exists foo3;
drop procedure if exists foo4;
drop procedure if exists bar;
drop function if exists fn1;
create procedure foo() create procedure foo()
begin begin
declare b int; declare b int;
@ -21,21 +16,9 @@ set b = 8;
insert into t1 values (b); insert into t1 values (b);
insert into t1 values (unix_timestamp()); insert into t1 values (unix_timestamp());
end| end|
ERROR HY000: This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
show binlog events from 98|
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # create database if not exists mysqltest1
master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a varchar(100))
create procedure foo() deterministic
begin
declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end|
select * from mysql.proc where name='foo' and db='mysqltest1'; select * from mysql.proc where name='foo' and db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL YES DEFINER begin mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL NO DEFINER begin
declare b int; declare b int;
set b = 8; set b = 8;
insert into t1 values (b); insert into t1 values (b);
@ -43,7 +26,7 @@ insert into t1 values (unix_timestamp());
end root@localhost # # end root@localhost # #
select * from mysql.proc where name='foo' and db='mysqltest1'; select * from mysql.proc where name='foo' and db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL YES DEFINER begin mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL NO DEFINER begin
declare b int; declare b int;
set b = 8; set b = 8;
insert into t1 values (b); insert into t1 values (b);
@ -51,17 +34,6 @@ insert into t1 values (unix_timestamp());
end @ # # end @ # #
set timestamp=1000000000; set timestamp=1000000000;
call foo(); call foo();
show binlog events from 308;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo() deterministic
begin
declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp())
select * from t1; select * from t1;
a a
8 8
@ -72,22 +44,10 @@ a
1000000000 1000000000
delete from t1; delete from t1;
create procedure foo2() create procedure foo2()
not deterministic
reads sql data
select * from mysqltest1.t1; select * from mysqltest1.t1;
call foo2(); call foo2();
a a
show binlog events from 518;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp())
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo2()
not deterministic
reads sql data
select * from mysqltest1.t1
alter procedure foo2 contains sql; alter procedure foo2 contains sql;
ERROR HY000: This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
drop table t1; drop table t1;
create table t1 (a int); create table t1 (a int);
create table t2 like t1; create table t2 like t1;
@ -99,80 +59,62 @@ grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1;
grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1;
create procedure foo4() create procedure foo4()
deterministic deterministic
insert into t1 values (10);
ERROR HY000: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
set global log_bin_trust_routine_creators=1;
create procedure foo4()
deterministic
begin begin
insert into t2 values(3); insert into t2 values(3);
insert into t1 values (5); insert into t1 values (5);
end| end|
call foo4(); call foo4();
Got one of the listed errors Got one of the listed errors
show warnings;
Level Code Message
Error 1142 INSERT command denied to user 'zedjzlcsjhd'@'localhost' for table 't1'
Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
call foo3(); call foo3();
show warnings; show warnings;
Level Code Message Level Code Message
call foo4(); call foo4();
Got one of the listed errors Got one of the listed errors
show warnings;
Level Code Message
Error 1142 INSERT command denied to user 'zedjzlcsjhd'@'127.0.0.1' for table 't1'
Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
alter procedure foo4 sql security invoker; alter procedure foo4 sql security invoker;
call foo4(); call foo4();
show warnings; show warnings;
Level Code Message Level Code Message
show binlog events from 990; select * from t1;
Log_name Pos Event_type Server_id End_log_pos Info a
master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1 15
master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int) 5
master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1 select * from t2;
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo3() a
deterministic 3
insert into t1 values (15) 3
master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1 3
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1 select * from t1;
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1 a
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4() 15
5
select * from t2;
a
3
3
3
delete from t2;
alter table t2 add unique (a);
drop procedure foo4;
create procedure foo4()
deterministic deterministic
begin begin
insert into t2 values(3); insert into t2 values(20),(20);
insert into t1 values (5); end|
end call foo4();
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3) ERROR 23000: Duplicate entry '20' for key 1
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (15) show warnings;
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3) Level Code Message
master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo4 sql security invoker Error 1062 Duplicate entry '20' for key 1
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (5)
select * from t1;
a
15
5
select * from t2; select * from t2;
a a
3 20
3
3
select * from t1;
a
15
5
select * from t2; select * from t2;
a a
3 20
3
3
select * from mysql.proc where name="foo4" and db='mysqltest1'; select * from mysql.proc where name="foo4" and db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 foo4 PROCEDURE foo4 SQL CONTAINS_SQL YES INVOKER begin mysqltest1 foo4 PROCEDURE foo4 SQL CONTAINS_SQL YES DEFINER begin
insert into t2 values(3); insert into t2 values(20),(20);
insert into t1 values (5);
end @ # # end @ # #
drop procedure foo4; drop procedure foo4;
select * from mysql.proc where name="foo4" and db='mysqltest1'; select * from mysql.proc where name="foo4" and db='mysqltest1';
@ -184,6 +126,13 @@ drop procedure foo2;
drop procedure foo3; drop procedure foo3;
create function fn1(x int) create function fn1(x int)
returns int returns int
begin
insert into t1 values (x);
return x+2;
end|
ERROR HY000: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
create function fn1(x int)
returns int
deterministic deterministic
begin begin
insert into t1 values (x); insert into t1 values (x);
@ -211,18 +160,55 @@ a
drop function fn1; drop function fn1;
create function fn1() create function fn1()
returns int returns int
deterministic no sql
begin begin
return unix_timestamp(); return unix_timestamp();
end| end|
alter function fn1 contains sql;
ERROR HY000: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
delete from t1; delete from t1;
set timestamp=1000000000; set timestamp=1000000000;
insert into t1 values(fn1()); insert into t1 values(fn1());
create function fn2()
returns int
no sql
begin
return unix_timestamp();
end|
ERROR HY000: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
set global log_bin_trust_routine_creators=1;
Warnings:
Warning 1287 'log_bin_trust_routine_creators' is deprecated; use 'log_bin_trust_function_creators' instead
set global log_bin_trust_function_creators=0;
set global log_bin_trust_function_creators=1;
set global log_bin_trust_function_creators=1;
create function fn2()
returns int
no sql
begin
return unix_timestamp();
end|
create function fn3()
returns int
not deterministic
reads sql data
begin
return 0;
end|
select fn3();
fn3()
0
select * from mysql.proc where db='mysqltest1'; select * from mysql.proc where db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 fn1 FUNCTION fn1 SQL CONTAINS_SQL YES DEFINER int(11) begin mysqltest1 fn1 FUNCTION fn1 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp(); return unix_timestamp();
end root@localhost # # end root@localhost # #
mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp();
end zedjzlcsjhd@localhost # #
mysqltest1 fn3 FUNCTION fn3 SQL READS_SQL_DATA NO DEFINER int(11) begin
return 0;
end root@localhost # #
select * from t1; select * from t1;
a a
1000000000 1000000000
@ -232,12 +218,34 @@ a
1000000000 1000000000
select * from mysql.proc where db='mysqltest1'; select * from mysql.proc where db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 fn1 FUNCTION fn1 SQL CONTAINS_SQL YES DEFINER int(11) begin mysqltest1 fn1 FUNCTION fn1 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp(); return unix_timestamp();
end @ # # end @ # #
mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp();
end @ # #
mysqltest1 fn3 FUNCTION fn3 SQL READS_SQL_DATA NO DEFINER int(11) begin
return 0;
end @ # #
delete from t2;
alter table t2 add unique (a);
drop function fn1;
create function fn1()
returns int
begin
insert into t2 values(20),(20);
return 10;
end|
select fn1();
ERROR 23000: Duplicate entry '20' for key 1
select * from t2;
a
20
select * from t2;
a
20
create trigger trg before insert on t1 for each row set new.a= 10; create trigger trg before insert on t1 for each row set new.a= 10;
ERROR 42000: Access denied; you need the SUPER privilege for this operation ERROR 42000: Access denied; you need the SUPER privilege for this operation
flush logs;
delete from t1; delete from t1;
create trigger trg before insert on t1 for each row set new.a= 10; create trigger trg before insert on t1 for each row set new.a= 10;
insert into t1 values (1); insert into t1 values (1);
@ -253,14 +261,106 @@ insert into t1 values (1);
select * from t1; select * from t1;
a a
1 1
show binlog events in 'master-bin.000002' from 98; show binlog events in 'master-bin.000001' from 98;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Query 1 # use `mysqltest1`; delete from t1 master-bin.000001 # Query 1 # drop database if exists mysqltest1
master-bin.000002 # Query 1 # use `mysqltest1`; create trigger trg before insert on t1 for each row set new.a= 10 master-bin.000001 # Query 1 # create database mysqltest1
master-bin.000002 # Query 1 # use `mysqltest1`; insert into t1 values (1) master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a varchar(100))
master-bin.000002 # Query 1 # use `mysqltest1`; delete from t1 master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo()
master-bin.000002 # Query 1 # use `mysqltest1`; drop trigger trg begin
master-bin.000002 # Query 1 # use `mysqltest1`; insert into t1 values (1) declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp())
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo2()
select * from mysqltest1.t1
master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo2 contains sql
master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1
master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int)
master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo3()
deterministic
insert into t1 values (15)
master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4()
deterministic
begin
insert into t2 values(3);
insert into t1 values (5);
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (15)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo4 sql security invoker
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (5)
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t2
master-bin.000001 # Query 1 # use `mysqltest1`; alter table t2 add unique (a)
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo4
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4()
deterministic
begin
insert into t2 values(20),(20);
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(20),(20)
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo4
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo2
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo3
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1(x int)
returns int
deterministic
begin
insert into t1 values (x);
return x+2;
end
master-bin.000001 # Query 1 # use `mysqltest1`; delete t1,t2 from t1,t2
master-bin.000001 # Query 1 # use `mysqltest1`; DO `fn1`(20)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(fn1(21))
master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1()
returns int
no sql
begin
return unix_timestamp();
end
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(fn1())
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn2()
returns int
no sql
begin
return unix_timestamp();
end
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn3()
returns int
not deterministic
reads sql data
begin
return 0;
end
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t2
master-bin.000001 # Query 1 # use `mysqltest1`; alter table t2 add unique (a)
master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1()
returns int
begin
insert into t2 values(20),(20);
return 10;
end
master-bin.000001 # Query 1 # use `mysqltest1`; DO `fn1`()
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` trigger trg before insert on t1 for each row set new.a= 10
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (1)
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; drop trigger trg
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (1)
select * from t1; select * from t1;
a a
1 1

View File

@ -89,8 +89,24 @@ insert into t1 set a = now();
select a=b && a=c from t1; select a=b && a=c from t1;
a=b && a=c a=b && a=c
1 1
SELECT routine_name, definer
FROM information_schema.routines;
routine_name definer
bug12480 root@localhost
SELECT trigger_name, definer
FROM information_schema.triggers;
trigger_name definer
t1_first root@localhost
--- On slave -- --- On slave --
SELECT routine_name, definer
FROM information_schema.routines;
routine_name definer
bug12480 @
SELECT trigger_name, definer
FROM information_schema.triggers;
trigger_name definer
t1_first root@localhost
select a=b && a=c from t1; select a=b && a=c from t1;
a=b && a=c a=b && a=c
1 1

View File

@ -3241,3 +3241,45 @@ f1 f2
Warnings: Warnings:
Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1 Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
drop table t1; drop table t1;
create table t1 (f1 int, f2 int);
insert into t1 values (1, 30), (2, 20), (3, 10);
create algorithm=merge view v1 as select f1, f2 from t1;
create algorithm=merge view v2 (f2, f1) as select f1, f2 from t1;
create algorithm=merge view v3 as select t1.f1 as f2, t1.f2 as f1 from t1;
select t1.f1 as x1, f1 from t1 order by t1.f1;
x1 f1
1 1
2 2
3 3
select v1.f1 as x1, f1 from v1 order by v1.f1;
x1 f1
1 1
2 2
3 3
select v2.f1 as x1, f1 from v2 order by v2.f1;
x1 f1
10 10
20 20
30 30
select v3.f1 as x1, f1 from v3 order by v3.f1;
x1 f1
10 10
20 20
30 30
select f1, f2, v1.f1 as x1 from v1 order by v1.f1;
f1 f2 x1
1 30 1
2 20 2
3 10 3
select f1, f2, v2.f1 as x1 from v2 order by v2.f1;
f1 f2 x1
10 3 10
20 2 20
30 1 30
select f1, f2, v3.f1 as x1 from v3 order by v3.f1;
f1 f2 x1
10 3 10
20 2 20
30 1 30
drop table t1;
drop view v1, v2, v3;

View File

@ -4,7 +4,7 @@ drop procedure if exists f1;
use test; use test;
create table t1 (field1 INT); create table t1 (field1 INT);
CREATE VIEW v1 AS SELECT field1 FROM t1; CREATE VIEW v1 AS SELECT field1 FROM t1;
ERROR HY000: View definer is not fully qualified ERROR HY000: Definer is not fully qualified
drop table t1; drop table t1;
create procedure f1() select 1; create procedure f1() select 1;
drop procedure f1; drop procedure f1;

View File

@ -916,3 +916,16 @@ ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
DROP PROCEDURE bug13037_p1; DROP PROCEDURE bug13037_p1;
DROP PROCEDURE bug13037_p2; DROP PROCEDURE bug13037_p2;
DROP PROCEDURE bug13037_p3; DROP PROCEDURE bug13037_p3;
create database mysqltest1;
create database mysqltest2;
use mysqltest1;
drop database mysqltest1;
create procedure mysqltest2.p1() select version();
create procedure p2() select version();
ERROR 3D000: No database selected
use mysqltest2;
show procedure status;
Db Name Type Definer Modified Created Security_type Comment
mysqltest2 p1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
drop database mysqltest2;
use test;

View File

@ -172,3 +172,75 @@ group by country;
countrycount smcnt country total_funds countrycount smcnt country total_funds
1 1200 USA 1200 1 1200 USA 1200
drop table t1; drop table t1;
CREATE TABLE `t1` (
`t3_id` int NOT NULL,
`t1_id` int NOT NULL,
PRIMARY KEY (`t1_id`)
);
CREATE TABLE `t2` (
`t2_id` int NOT NULL,
`t1_id` int NOT NULL,
`b` int NOT NULL,
PRIMARY KEY (`t2_id`),
UNIQUE KEY `idx_t2_t1_b` (`t1_id`,`b`)
) ENGINE=InnoDB;
CREATE TABLE `t3` (
`t3_id` int NOT NULL
);
INSERT INTO `t3` VALUES (3);
select
(SELECT rs.t2_id
FROM t2 rs
WHERE rs.t1_id=
(SELECT lt.t1_id
FROM t1 lt
WHERE lt.t3_id=a.t3_id)
ORDER BY b DESC LIMIT 1)
from t3 AS a;
(SELECT rs.t2_id
FROM t2 rs
WHERE rs.t1_id=
(SELECT lt.t1_id
FROM t1 lt
WHERE lt.t3_id=a.t3_id)
ORDER BY b DESC LIMIT 1)
NULL
DROP PROCEDURE IF EXISTS p1;
create procedure p1()
begin
declare done int default 3;
repeat
select
(SELECT rs.t2_id
FROM t2 rs
WHERE rs.t1_id=
(SELECT lt.t1_id
FROM t1 lt
WHERE lt.t3_id=a.t3_id)
ORDER BY b DESC LIMIT 1) as x
from t3 AS a;
set done= done-1;
until done <= 0 end repeat;
end//
call p1();
x
NULL
x
NULL
x
NULL
call p1();
x
NULL
x
NULL
x
NULL
call p1();
x
NULL
x
NULL
x
NULL
drop tables t1,t2,t3;

View File

@ -0,0 +1,40 @@
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
FLUSH PRIVILEGES;
DROP DATABASE IF EXISTS mysqltest_db1;
CREATE DATABASE mysqltest_db1;
CREATE USER mysqltest_dfn@localhost;
CREATE USER mysqltest_inv@localhost;
GRANT SUPER ON *.* TO mysqltest_dfn@localhost;
GRANT CREATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
---> connection: wl2818_definer_con
CREATE TABLE t1(num_value INT);
CREATE TABLE t2(user_str TEXT);
CREATE TRIGGER wl2818_trg1 BEFORE INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
---> patching t1.TRG...
CREATE TRIGGER wl2818_trg2 AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
Warnings:
Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'wl2818_trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
trigger_name definer
wl2818_trg1
wl2818_trg2 mysqltest_dfn@localhost
Warnings:
Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'wl2818_trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER
NULL mysqltest_db1 wl2818_trg1 INSERT NULL mysqltest_db1 t1 0 NULL
INSERT INTO t2 VALUES(CURRENT_USER()) ROW BEFORE NULL NULL OLD NEW NULL
NULL mysqltest_db1 wl2818_trg2 INSERT NULL mysqltest_db1 t1 0 NULL
INSERT INTO t2 VALUES(CURRENT_USER()) ROW AFTER NULL NULL OLD NEW NULL mysqltest_dfn@localhost

View File

@ -0,0 +1,238 @@
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
FLUSH PRIVILEGES;
DROP DATABASE IF EXISTS mysqltest_db1;
CREATE DATABASE mysqltest_db1;
CREATE USER mysqltest_dfn@localhost;
CREATE USER mysqltest_inv@localhost;
GRANT SUPER ON *.* TO mysqltest_dfn@localhost;
GRANT CREATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
---> connection: wl2818_definer_con
CREATE TABLE t1(num_value INT);
CREATE TABLE t2(user_str TEXT);
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
---> connection: default
GRANT ALL PRIVILEGES ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
GRANT ALL PRIVILEGES ON mysqltest_db1.t2 TO mysqltest_dfn@localhost;
GRANT ALL PRIVILEGES ON mysqltest_db1.t1
TO 'mysqltest_inv'@localhost;
GRANT SELECT ON mysqltest_db1.t2
TO 'mysqltest_inv'@localhost;
---> connection: wl2818_definer_con
use mysqltest_db1;
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
num_value
1
SELECT * FROM t2;
user_str
mysqltest_dfn@localhost
---> connection: wl2818_invoker_con
use mysqltest_db1;
INSERT INTO t1 VALUES(2);
SELECT * FROM t1;
num_value
1
2
SELECT * FROM t2;
user_str
mysqltest_dfn@localhost
mysqltest_dfn@localhost
---> connection: default
use mysqltest_db1;
REVOKE INSERT ON mysqltest_db1.t2 FROM mysqltest_dfn@localhost;
---> connection: wl2818_invoker_con
use mysqltest_db1;
INSERT INTO t1 VALUES(3);
ERROR 42000: INSERT command denied to user 'mysqltest_dfn'@'localhost' for table 't2'
SELECT * FROM t1;
num_value
1
2
3
SELECT * FROM t2;
user_str
mysqltest_dfn@localhost
mysqltest_dfn@localhost
---> connection: default
use mysqltest_db1;
REVOKE SELECT ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
---> connection: wl2818_definer_con
use mysqltest_db1;
DROP TRIGGER trg1;
SET @new_sum = 0;
SET @old_sum = 0;
---> INSERT INTO statement; BEFORE timing
CREATE TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
INSERT INTO t1 VALUES(4);
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> INSERT INTO statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
INSERT INTO t1 VALUES(5);
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> UPDATE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
UPDATE t1 SET num_value = 10;
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> UPDATE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER UPDATE ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
UPDATE t1 SET num_value = 20;
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> DELETE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
DELETE FROM t1;
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> DELETE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
DELETE FROM t1;
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> connection: default
use mysqltest_db1;
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
REVOKE UPDATE ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
---> connection: wl2818_definer_con
use mysqltest_db1;
DROP TRIGGER trg1;
SET @new_sum = 0;
SET @old_sum = 0;
---> INSERT INTO statement; BEFORE timing
CREATE TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
INSERT INTO t1 VALUES(4);
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> INSERT INTO statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
INSERT INTO t1 VALUES(5);
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> UPDATE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
UPDATE t1 SET num_value = 10;
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> UPDATE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER UPDATE ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
UPDATE t1 SET num_value = 20;
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> DELETE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
DELETE FROM t1;
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> DELETE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
DELETE FROM t1;
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> connection: wl2818_definer_con
use mysqltest_db1;
DROP TRIGGER trg1;
CREATE DEFINER='mysqltest_inv'@'localhost'
TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @new_sum = 0;
CREATE DEFINER='mysqltest_nonexs'@'localhost'
TRIGGER trg2 AFTER INSERT ON t1
FOR EACH ROW
SET @new_sum = 0;
Warnings:
Note 1449 There is no 'mysqltest_nonexs'@'localhost' registered
INSERT INTO t1 VALUES(6);
ERROR 42000: Access denied; you need the SUPER privilege for this operation
SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1
SET @new_sum = 0 BEFORE NULL mysqltest_inv@localhost
trg2 INSERT t1
SET @new_sum = 0 AFTER NULL mysqltest_nonexs@localhost
DROP TRIGGER trg1;
DROP TRIGGER trg2;
CREATE TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @a = 1;
CREATE TRIGGER trg2 AFTER INSERT ON t1
FOR EACH ROW
SET @a = 2;
CREATE TRIGGER trg3 BEFORE UPDATE ON t1
FOR EACH ROW
SET @a = 3;
CREATE TRIGGER trg4 AFTER UPDATE ON t1
FOR EACH ROW
SET @a = 4;
CREATE TRIGGER trg5 BEFORE DELETE ON t1
FOR EACH ROW
SET @a = 5;
SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
trigger_name definer
trg1
trg2 @
trg3 @abc@def@@
trg4 @hostname
trg5 @abcdef@@@hostname
Warnings:
Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER
NULL mysqltest_db1 trg1 INSERT NULL mysqltest_db1 t1 0 NULL
SET @a = 1 ROW BEFORE NULL NULL OLD NEW NULL
NULL mysqltest_db1 trg2 INSERT NULL mysqltest_db1 t1 0 NULL
SET @a = 2 ROW AFTER NULL NULL OLD NEW NULL @
NULL mysqltest_db1 trg3 UPDATE NULL mysqltest_db1 t1 0 NULL
SET @a = 3 ROW BEFORE NULL NULL OLD NEW NULL @abc@def@@
NULL mysqltest_db1 trg4 UPDATE NULL mysqltest_db1 t1 0 NULL
SET @a = 4 ROW AFTER NULL NULL OLD NEW NULL @hostname
NULL mysqltest_db1 trg5 DELETE NULL mysqltest_db1 t1 0 NULL
SET @a = 5 ROW BEFORE NULL NULL OLD NEW NULL @abcdef@@@hostname
---> connection: default
DROP USER mysqltest_dfn@localhost;
DROP USER mysqltest_inv@localhost;
DROP DATABASE mysqltest_db1;
Warnings:
Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.

View File

@ -611,9 +611,9 @@ select @a;
@a @a
10 10
show triggers; show triggers;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
t1_bi INSERT t1 set new."t1 column" = 5 BEFORE # REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI t1_bi INSERT t1 set new."t1 column" = 5 BEFORE # REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI root@localhost
t1_af INSERT t1 set @a=10 AFTER # t1_af INSERT t1 set @a=10 AFTER # root@localhost
drop table t1; drop table t1;
set sql_mode="traditional"; set sql_mode="traditional";
create table t1 (a date); create table t1 (a date);
@ -633,8 +633,8 @@ t1 CREATE TABLE `t1` (
`a` date default NULL `a` date default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
show triggers; show triggers;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
t1_bi INSERT t1 set new.a = '2004-01-00' BEFORE # t1_bi INSERT t1 set new.a = '2004-01-00' BEFORE # root@localhost
drop table t1; drop table t1;
create table t1 (id int); create table t1 (id int);
create trigger t1_ai after insert on t1 for each row flush tables; create trigger t1_ai after insert on t1 for each row flush tables;

View File

@ -1020,6 +1020,416 @@ cast(@non_existing_user_var/2 as DECIMAL)
NULL NULL
create table t (d decimal(0,10)); create table t (d decimal(0,10));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'd'). ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'd').
CREATE TABLE t1 (
my_float FLOAT,
my_double DOUBLE,
my_varchar VARCHAR(50),
my_decimal DECIMAL(65,30)
);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`my_float` float default NULL,
`my_double` double default NULL,
`my_varchar` varchar(50) default NULL,
`my_decimal` decimal(65,30) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 SET my_float = 1.175494345e-32,
my_double = 1.175494345e-32,
my_varchar = '1.175494345e-32';
INSERT INTO t1 SET my_float = 1.175494345e-31,
my_double = 1.175494345e-31,
my_varchar = '1.175494345e-31';
INSERT INTO t1 SET my_float = 1.175494345e-30,
my_double = 1.175494345e-30,
my_varchar = '1.175494345e-30';
INSERT INTO t1 SET my_float = 1.175494345e-29,
my_double = 1.175494345e-29,
my_varchar = '1.175494345e-29';
INSERT INTO t1 SET my_float = 1.175494345e-28,
my_double = 1.175494345e-28,
my_varchar = '1.175494345e-28';
INSERT INTO t1 SET my_float = 1.175494345e-27,
my_double = 1.175494345e-27,
my_varchar = '1.175494345e-27';
INSERT INTO t1 SET my_float = 1.175494345e-26,
my_double = 1.175494345e-26,
my_varchar = '1.175494345e-26';
INSERT INTO t1 SET my_float = 1.175494345e-25,
my_double = 1.175494345e-25,
my_varchar = '1.175494345e-25';
INSERT INTO t1 SET my_float = 1.175494345e-24,
my_double = 1.175494345e-24,
my_varchar = '1.175494345e-24';
INSERT INTO t1 SET my_float = 1.175494345e-23,
my_double = 1.175494345e-23,
my_varchar = '1.175494345e-23';
INSERT INTO t1 SET my_float = 1.175494345e-22,
my_double = 1.175494345e-22,
my_varchar = '1.175494345e-22';
INSERT INTO t1 SET my_float = 1.175494345e-21,
my_double = 1.175494345e-21,
my_varchar = '1.175494345e-21';
INSERT INTO t1 SET my_float = 1.175494345e-20,
my_double = 1.175494345e-20,
my_varchar = '1.175494345e-20';
INSERT INTO t1 SET my_float = 1.175494345e-19,
my_double = 1.175494345e-19,
my_varchar = '1.175494345e-19';
INSERT INTO t1 SET my_float = 1.175494345e-18,
my_double = 1.175494345e-18,
my_varchar = '1.175494345e-18';
INSERT INTO t1 SET my_float = 1.175494345e-17,
my_double = 1.175494345e-17,
my_varchar = '1.175494345e-17';
INSERT INTO t1 SET my_float = 1.175494345e-16,
my_double = 1.175494345e-16,
my_varchar = '1.175494345e-16';
INSERT INTO t1 SET my_float = 1.175494345e-15,
my_double = 1.175494345e-15,
my_varchar = '1.175494345e-15';
INSERT INTO t1 SET my_float = 1.175494345e-14,
my_double = 1.175494345e-14,
my_varchar = '1.175494345e-14';
INSERT INTO t1 SET my_float = 1.175494345e-13,
my_double = 1.175494345e-13,
my_varchar = '1.175494345e-13';
INSERT INTO t1 SET my_float = 1.175494345e-12,
my_double = 1.175494345e-12,
my_varchar = '1.175494345e-12';
INSERT INTO t1 SET my_float = 1.175494345e-11,
my_double = 1.175494345e-11,
my_varchar = '1.175494345e-11';
INSERT INTO t1 SET my_float = 1.175494345e-10,
my_double = 1.175494345e-10,
my_varchar = '1.175494345e-10';
INSERT INTO t1 SET my_float = 1.175494345e-9,
my_double = 1.175494345e-9,
my_varchar = '1.175494345e-9';
INSERT INTO t1 SET my_float = 1.175494345e-8,
my_double = 1.175494345e-8,
my_varchar = '1.175494345e-8';
INSERT INTO t1 SET my_float = 1.175494345e-7,
my_double = 1.175494345e-7,
my_varchar = '1.175494345e-7';
INSERT INTO t1 SET my_float = 1.175494345e-6,
my_double = 1.175494345e-6,
my_varchar = '1.175494345e-6';
INSERT INTO t1 SET my_float = 1.175494345e-5,
my_double = 1.175494345e-5,
my_varchar = '1.175494345e-5';
INSERT INTO t1 SET my_float = 1.175494345e-4,
my_double = 1.175494345e-4,
my_varchar = '1.175494345e-4';
INSERT INTO t1 SET my_float = 1.175494345e-3,
my_double = 1.175494345e-3,
my_varchar = '1.175494345e-3';
INSERT INTO t1 SET my_float = 1.175494345e-2,
my_double = 1.175494345e-2,
my_varchar = '1.175494345e-2';
INSERT INTO t1 SET my_float = 1.175494345e-1,
my_double = 1.175494345e-1,
my_varchar = '1.175494345e-1';
SELECT my_float, my_double, my_varchar FROM t1;
my_float my_double my_varchar
1.17549e-32 1.175494345e-32 1.175494345e-32
1.17549e-31 1.175494345e-31 1.175494345e-31
1.17549e-30 1.175494345e-30 1.175494345e-30
1.17549e-29 1.175494345e-29 1.175494345e-29
1.17549e-28 1.175494345e-28 1.175494345e-28
1.17549e-27 1.175494345e-27 1.175494345e-27
1.17549e-26 1.175494345e-26 1.175494345e-26
1.17549e-25 1.175494345e-25 1.175494345e-25
1.17549e-24 1.175494345e-24 1.175494345e-24
1.17549e-23 1.175494345e-23 1.175494345e-23
1.17549e-22 1.175494345e-22 1.175494345e-22
1.17549e-21 1.175494345e-21 1.175494345e-21
1.17549e-20 1.175494345e-20 1.175494345e-20
1.17549e-19 1.175494345e-19 1.175494345e-19
1.17549e-18 1.175494345e-18 1.175494345e-18
1.17549e-17 1.175494345e-17 1.175494345e-17
1.17549e-16 1.175494345e-16 1.175494345e-16
1.17549e-15 1.175494345e-15 1.175494345e-15
1.17549e-14 1.175494345e-14 1.175494345e-14
1.17549e-13 1.175494345e-13 1.175494345e-13
1.17549e-12 1.175494345e-12 1.175494345e-12
1.17549e-11 1.175494345e-11 1.175494345e-11
1.17549e-10 1.175494345e-10 1.175494345e-10
1.17549e-09 1.175494345e-09 1.175494345e-9
1.17549e-08 1.175494345e-08 1.175494345e-8
1.17549e-07 1.175494345e-07 1.175494345e-7
1.17549e-06 1.175494345e-06 1.175494345e-6
1.17549e-05 1.175494345e-05 1.175494345e-5
0.000117549 0.0001175494345 1.175494345e-4
0.00117549 0.001175494345 1.175494345e-3
0.0117549 0.01175494345 1.175494345e-2
0.117549 0.1175494345 1.175494345e-1
SELECT CAST(my_float AS DECIMAL(65,30)), my_float FROM t1;
CAST(my_float AS DECIMAL(65,30)) my_float
0.000000000000000000000000000000 1.17549e-32
0.000000000000000000000000000000 1.17549e-31
0.000000000000000000000000000001 1.17549e-30
0.000000000000000000000000000012 1.17549e-29
0.000000000000000000000000000118 1.17549e-28
0.000000000000000000000000001175 1.17549e-27
0.000000000000000000000000011755 1.17549e-26
0.000000000000000000000000117549 1.17549e-25
0.000000000000000000000001175494 1.17549e-24
0.000000000000000000000011754943 1.17549e-23
0.000000000000000000000117549438 1.17549e-22
0.000000000000000000001175494332 1.17549e-21
0.000000000000000000011754943324 1.17549e-20
0.000000000000000000117549434853 1.17549e-19
0.000000000000000001175494374380 1.17549e-18
0.000000000000000011754943743802 1.17549e-17
0.000000000000000117549432474939 1.17549e-16
0.000000000000001175494324749389 1.17549e-15
0.000000000000011754943671010360 1.17549e-14
0.000000000000117549429933840000 1.17549e-13
0.000000000001175494380653563000 1.17549e-12
0.000000000011754943372854760000 1.17549e-11
0.000000000117549428524377200000 1.17549e-10
0.000000001175494368510499000000 1.17549e-09
0.000000011754943685104990000000 1.17549e-08
0.000000117549433298336200000000 1.17549e-07
0.000001175494389826781000000000 1.17549e-06
0.000011754943443520460000000000 1.17549e-05
0.000117549432616215200000000000 0.000117549
0.001175494398921728000000000000 0.00117549
0.011754943057894710000000000000 0.0117549
0.117549434304237400000000000000 0.117549
SELECT CAST(my_double AS DECIMAL(65,30)), my_double FROM t1;
CAST(my_double AS DECIMAL(65,30)) my_double
0.000000000000000000000000000000 1.175494345e-32
0.000000000000000000000000000000 1.175494345e-31
0.000000000000000000000000000001 1.175494345e-30
0.000000000000000000000000000012 1.175494345e-29
0.000000000000000000000000000118 1.175494345e-28
0.000000000000000000000000001175 1.175494345e-27
0.000000000000000000000000011755 1.175494345e-26
0.000000000000000000000000117549 1.175494345e-25
0.000000000000000000000001175494 1.175494345e-24
0.000000000000000000000011754943 1.175494345e-23
0.000000000000000000000117549435 1.175494345e-22
0.000000000000000000001175494345 1.175494345e-21
0.000000000000000000011754943450 1.175494345e-20
0.000000000000000000117549434500 1.175494345e-19
0.000000000000000001175494345000 1.175494345e-18
0.000000000000000011754943450000 1.175494345e-17
0.000000000000000117549434500000 1.175494345e-16
0.000000000000001175494345000000 1.175494345e-15
0.000000000000011754943450000000 1.175494345e-14
0.000000000000117549434500000000 1.175494345e-13
0.000000000001175494345000000000 1.175494345e-12
0.000000000011754943450000000000 1.175494345e-11
0.000000000117549434500000000000 1.175494345e-10
0.000000001175494345000000000000 1.175494345e-09
0.000000011754943450000000000000 1.175494345e-08
0.000000117549434500000000000000 1.175494345e-07
0.000001175494345000000000000000 1.175494345e-06
0.000011754943450000000000000000 1.175494345e-05
0.000117549434500000000000000000 0.0001175494345
0.001175494345000000000000000000 0.001175494345
0.011754943450000000000000000000 0.01175494345
0.117549434500000000000000000000 0.1175494345
SELECT CAST(my_varchar AS DECIMAL(65,30)), my_varchar FROM t1;
CAST(my_varchar AS DECIMAL(65,30)) my_varchar
0.000000000000000000000000000000 1.175494345e-32
0.000000000000000000000000000000 1.175494345e-31
0.000000000000000000000000000001 1.175494345e-30
0.000000000000000000000000000012 1.175494345e-29
0.000000000000000000000000000118 1.175494345e-28
0.000000000000000000000000001175 1.175494345e-27
0.000000000000000000000000011755 1.175494345e-26
0.000000000000000000000000117549 1.175494345e-25
0.000000000000000000000001175494 1.175494345e-24
0.000000000000000000000011754943 1.175494345e-23
0.000000000000000000000117549435 1.175494345e-22
0.000000000000000000001175494345 1.175494345e-21
0.000000000000000000011754943450 1.175494345e-20
0.000000000000000000117549434500 1.175494345e-19
0.000000000000000001175494345000 1.175494345e-18
0.000000000000000011754943450000 1.175494345e-17
0.000000000000000117549434500000 1.175494345e-16
0.000000000000001175494345000000 1.175494345e-15
0.000000000000011754943450000000 1.175494345e-14
0.000000000000117549434500000000 1.175494345e-13
0.000000000001175494345000000000 1.175494345e-12
0.000000000011754943450000000000 1.175494345e-11
0.000000000117549434500000000000 1.175494345e-10
0.000000001175494345000000000000 1.175494345e-9
0.000000011754943450000000000000 1.175494345e-8
0.000000117549434500000000000000 1.175494345e-7
0.000001175494345000000000000000 1.175494345e-6
0.000011754943450000000000000000 1.175494345e-5
0.000117549434500000000000000000 1.175494345e-4
0.001175494345000000000000000000 1.175494345e-3
0.011754943450000000000000000000 1.175494345e-2
0.117549434500000000000000000000 1.175494345e-1
UPDATE t1 SET my_decimal = my_float;
Warnings:
Note 1265 Data truncated for column 'my_decimal' at row 1
Note 1265 Data truncated for column 'my_decimal' at row 2
Note 1265 Data truncated for column 'my_decimal' at row 3
Note 1265 Data truncated for column 'my_decimal' at row 4
Note 1265 Data truncated for column 'my_decimal' at row 5
Note 1265 Data truncated for column 'my_decimal' at row 6
Note 1265 Data truncated for column 'my_decimal' at row 7
Note 1265 Data truncated for column 'my_decimal' at row 8
Note 1265 Data truncated for column 'my_decimal' at row 9
Note 1265 Data truncated for column 'my_decimal' at row 10
Note 1265 Data truncated for column 'my_decimal' at row 11
Note 1265 Data truncated for column 'my_decimal' at row 12
Note 1265 Data truncated for column 'my_decimal' at row 13
Note 1265 Data truncated for column 'my_decimal' at row 14
Note 1265 Data truncated for column 'my_decimal' at row 15
Note 1265 Data truncated for column 'my_decimal' at row 16
Note 1265 Data truncated for column 'my_decimal' at row 17
Note 1265 Data truncated for column 'my_decimal' at row 19
Note 1265 Data truncated for column 'my_decimal' at row 20
Note 1265 Data truncated for column 'my_decimal' at row 21
Note 1265 Data truncated for column 'my_decimal' at row 22
Note 1265 Data truncated for column 'my_decimal' at row 23
Note 1265 Data truncated for column 'my_decimal' at row 26
Note 1265 Data truncated for column 'my_decimal' at row 27
Note 1265 Data truncated for column 'my_decimal' at row 30
Note 1265 Data truncated for column 'my_decimal' at row 31
Note 1265 Data truncated for column 'my_decimal' at row 32
SELECT my_decimal, my_float FROM t1;
my_decimal my_float
0.000000000000000000000000000000 1.17549e-32
0.000000000000000000000000000000 1.17549e-31
0.000000000000000000000000000001 1.17549e-30
0.000000000000000000000000000012 1.17549e-29
0.000000000000000000000000000118 1.17549e-28
0.000000000000000000000000001175 1.17549e-27
0.000000000000000000000000011755 1.17549e-26
0.000000000000000000000000117549 1.17549e-25
0.000000000000000000000001175494 1.17549e-24
0.000000000000000000000011754943 1.17549e-23
0.000000000000000000000117549438 1.17549e-22
0.000000000000000000001175494332 1.17549e-21
0.000000000000000000011754943324 1.17549e-20
0.000000000000000000117549434853 1.17549e-19
0.000000000000000001175494374380 1.17549e-18
0.000000000000000011754943743802 1.17549e-17
0.000000000000000117549432474939 1.17549e-16
0.000000000000001175494324749389 1.17549e-15
0.000000000000011754943671010360 1.17549e-14
0.000000000000117549429933840000 1.17549e-13
0.000000000001175494380653563000 1.17549e-12
0.000000000011754943372854760000 1.17549e-11
0.000000000117549428524377200000 1.17549e-10
0.000000001175494368510499000000 1.17549e-09
0.000000011754943685104990000000 1.17549e-08
0.000000117549433298336200000000 1.17549e-07
0.000001175494389826781000000000 1.17549e-06
0.000011754943443520460000000000 1.17549e-05
0.000117549432616215200000000000 0.000117549
0.001175494398921728000000000000 0.00117549
0.011754943057894710000000000000 0.0117549
0.117549434304237400000000000000 0.117549
UPDATE t1 SET my_decimal = my_double;
Warnings:
Note 1265 Data truncated for column 'my_decimal' at row 1
Note 1265 Data truncated for column 'my_decimal' at row 2
Note 1265 Data truncated for column 'my_decimal' at row 3
Note 1265 Data truncated for column 'my_decimal' at row 4
Note 1265 Data truncated for column 'my_decimal' at row 5
Note 1265 Data truncated for column 'my_decimal' at row 6
Note 1265 Data truncated for column 'my_decimal' at row 7
Note 1265 Data truncated for column 'my_decimal' at row 8
Note 1265 Data truncated for column 'my_decimal' at row 9
Note 1265 Data truncated for column 'my_decimal' at row 10
Note 1265 Data truncated for column 'my_decimal' at row 11
Note 1265 Data truncated for column 'my_decimal' at row 13
Note 1265 Data truncated for column 'my_decimal' at row 14
Note 1265 Data truncated for column 'my_decimal' at row 16
Note 1265 Data truncated for column 'my_decimal' at row 18
Note 1265 Data truncated for column 'my_decimal' at row 20
Note 1265 Data truncated for column 'my_decimal' at row 31
SELECT my_decimal, my_double FROM t1;
my_decimal my_double
0.000000000000000000000000000000 1.175494345e-32
0.000000000000000000000000000000 1.175494345e-31
0.000000000000000000000000000001 1.175494345e-30
0.000000000000000000000000000012 1.175494345e-29
0.000000000000000000000000000118 1.175494345e-28
0.000000000000000000000000001175 1.175494345e-27
0.000000000000000000000000011755 1.175494345e-26
0.000000000000000000000000117549 1.175494345e-25
0.000000000000000000000001175494 1.175494345e-24
0.000000000000000000000011754943 1.175494345e-23
0.000000000000000000000117549435 1.175494345e-22
0.000000000000000000001175494345 1.175494345e-21
0.000000000000000000011754943450 1.175494345e-20
0.000000000000000000117549434500 1.175494345e-19
0.000000000000000001175494345000 1.175494345e-18
0.000000000000000011754943450000 1.175494345e-17
0.000000000000000117549434500000 1.175494345e-16
0.000000000000001175494345000000 1.175494345e-15
0.000000000000011754943450000000 1.175494345e-14
0.000000000000117549434500000000 1.175494345e-13
0.000000000001175494345000000000 1.175494345e-12
0.000000000011754943450000000000 1.175494345e-11
0.000000000117549434500000000000 1.175494345e-10
0.000000001175494345000000000000 1.175494345e-09
0.000000011754943450000000000000 1.175494345e-08
0.000000117549434500000000000000 1.175494345e-07
0.000001175494345000000000000000 1.175494345e-06
0.000011754943450000000000000000 1.175494345e-05
0.000117549434500000000000000000 0.0001175494345
0.001175494345000000000000000000 0.001175494345
0.011754943450000000000000000000 0.01175494345
0.117549434500000000000000000000 0.1175494345
UPDATE t1 SET my_decimal = my_varchar;
Warnings:
Note 1265 Data truncated for column 'my_decimal' at row 1
Note 1265 Data truncated for column 'my_decimal' at row 2
Note 1265 Data truncated for column 'my_decimal' at row 3
Note 1265 Data truncated for column 'my_decimal' at row 4
Note 1265 Data truncated for column 'my_decimal' at row 5
Note 1265 Data truncated for column 'my_decimal' at row 6
Note 1265 Data truncated for column 'my_decimal' at row 7
Note 1265 Data truncated for column 'my_decimal' at row 8
Note 1265 Data truncated for column 'my_decimal' at row 9
Note 1265 Data truncated for column 'my_decimal' at row 10
Note 1265 Data truncated for column 'my_decimal' at row 11
SELECT my_decimal, my_varchar FROM t1;
my_decimal my_varchar
0.000000000000000000000000000000 1.175494345e-32
0.000000000000000000000000000000 1.175494345e-31
0.000000000000000000000000000001 1.175494345e-30
0.000000000000000000000000000012 1.175494345e-29
0.000000000000000000000000000118 1.175494345e-28
0.000000000000000000000000001175 1.175494345e-27
0.000000000000000000000000011755 1.175494345e-26
0.000000000000000000000000117549 1.175494345e-25
0.000000000000000000000001175494 1.175494345e-24
0.000000000000000000000011754943 1.175494345e-23
0.000000000000000000000117549435 1.175494345e-22
0.000000000000000000001175494345 1.175494345e-21
0.000000000000000000011754943450 1.175494345e-20
0.000000000000000000117549434500 1.175494345e-19
0.000000000000000001175494345000 1.175494345e-18
0.000000000000000011754943450000 1.175494345e-17
0.000000000000000117549434500000 1.175494345e-16
0.000000000000001175494345000000 1.175494345e-15
0.000000000000011754943450000000 1.175494345e-14
0.000000000000117549434500000000 1.175494345e-13
0.000000000001175494345000000000 1.175494345e-12
0.000000000011754943450000000000 1.175494345e-11
0.000000000117549434500000000000 1.175494345e-10
0.000000001175494345000000000000 1.175494345e-9
0.000000011754943450000000000000 1.175494345e-8
0.000000117549434500000000000000 1.175494345e-7
0.000001175494345000000000000000 1.175494345e-6
0.000011754943450000000000000000 1.175494345e-5
0.000117549434500000000000000000 1.175494345e-4
0.001175494345000000000000000000 1.175494345e-3
0.011754943450000000000000000000 1.175494345e-2
0.117549434500000000000000000000 1.175494345e-1
DROP TABLE t1;
create table t1 (c1 decimal(64)); create table t1 (c1 decimal(64));
insert into t1 values( insert into t1 values(
89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000); 89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);

View File

@ -1,4 +1,4 @@
drop table if exists t1,t2,t9,`t1a``b`,v1,v2,v3,v4,v5,v6; drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6; drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
drop database if exists mysqltest; drop database if exists mysqltest;
use test; use test;
@ -2199,10 +2199,10 @@ r_object_id users_names
drop view v1, v2; drop view v1, v2;
drop table t1, t2; drop table t1, t2;
create definer=some_user@`` sql security invoker view v1 as select 1; create definer=some_user@`` sql security invoker view v1 as select 1;
ERROR HY000: View definer is not fully qualified ERROR HY000: Definer is not fully qualified
create definer=some_user@localhost sql security invoker view v1 as select 1; create definer=some_user@localhost sql security invoker view v1 as select 1;
Warnings: Warnings:
Note 1449 There is not some_user@localhost registered Note 1449 There is no 'some_user'@'localhost' registered
show create view v1; show create view v1;
View Create View View Create View
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1` v1 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
@ -2335,3 +2335,53 @@ f1 group_concat(f2 order by f2 desc)
1 3,2,1 1 3,2,1
drop view v1,v2; drop view v1,v2;
drop table t1; drop table t1;
create table t1 (x int, y int);
create table t2 (x int, y int, z int);
create table t3 (x int, y int, z int);
create table t4 (x int, y int, z int);
create view v1 as
select t1.x
from (
(t1 join t2 on ((t1.y = t2.y)))
join
(t3 left join t4 on (t3.y = t4.y) and (t3.z = t4.z))
);
prepare stmt1 from "select count(*) from v1 where x = ?";
set @parm1=1;
execute stmt1 using @parm1;
count(*)
0
execute stmt1 using @parm1;
count(*)
0
drop view v1;
drop table t1,t2,t3,t4;
CREATE TABLE t1(id INT);
CREATE VIEW v1 AS SELECT id FROM t1;
OPTIMIZE TABLE v1;
Table Op Msg_type Msg_text
test.v1 optimize note Unknown table 'test.v1'
ANALYZE TABLE v1;
Table Op Msg_type Msg_text
test.v1 analyze note Unknown table 'test.v1'
REPAIR TABLE v1;
Table Op Msg_type Msg_text
test.v1 repair note Unknown table 'test.v1'
DROP TABLE t1;
OPTIMIZE TABLE v1;
Table Op Msg_type Msg_text
test.v1 optimize note Unknown table 'test.v1'
Warnings:
Error 1146 Table 'test.t1' doesn't exist
Error 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
DROP VIEW v1;
create definer = current_user() sql security invoker view v1 as select 1;
show create view v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
drop view v1;
create definer = current_user sql security invoker view v1 as select 1;
show create view v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
drop view v1;

View File

@ -13,7 +13,7 @@ create table mysqltest.t2 (a int, b int);
grant select on mysqltest.t1 to mysqltest_1@localhost; grant select on mysqltest.t1 to mysqltest_1@localhost;
grant create view,select on test.* to mysqltest_1@localhost; grant create view,select on test.* to mysqltest_1@localhost;
create definer=root@localhost view v1 as select * from mysqltest.t1; create definer=root@localhost view v1 as select * from mysqltest.t1;
ERROR HY000: You need the SUPER privilege for creation view with root@localhost definer ERROR 42000: Access denied; you need the SUPER privilege for this operation
create view v1 as select * from mysqltest.t1; create view v1 as select * from mysqltest.t1;
alter view v1 as select * from mysqltest.t1; alter view v1 as select * from mysqltest.t1;
ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'v1' ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'v1'

View File

@ -2,7 +2,7 @@
# Initialize # Initialize
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1, t2;
--enable_warnings --enable_warnings
# #

View File

@ -3,7 +3,7 @@
# #
--disable_warnings --disable_warnings
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3,t4,t5;
drop database if exists mysqltest; drop database if exists mysqltest;
--enable_warnings --enable_warnings
@ -554,4 +554,80 @@ create table t1 (
show create table t1; show create table t1;
drop table t1; drop table t1;
#
# BUG#14480: assert failure in CREATE ... SELECT because of wrong
# calculation of number of NULLs.
#
CREATE TABLE t2 (
a int(11) default NULL
);
insert into t2 values(111);
--warning 1364
create table t1 (
a varchar(12) charset utf8 collate utf8_bin not null,
b int not null, primary key (a)
) select a, 1 as b from t2 ;
show create table t1;
drop table t1;
--warning 1364
create table t1 (
a varchar(12) charset utf8 collate utf8_bin not null,
b int not null, primary key (a)
) select 'a' as a , 1 as b from t2 ;
show create table t1;
drop table t1;
--warning 1364
create table t1 (
a varchar(12) charset utf8 collate utf8_bin,
b int not null, primary key (a)
) select 'a' as a , 1 as b from t2 ;
show create table t1;
drop table t1, t2;
create table t1 (
a1 int not null,
a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int
);
insert into t1 values (1,1,1, 1,1,1, 1,1,1);
--warning 1364
create table t2 (
a1 varchar(12) charset utf8 collate utf8_bin not null,
a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int,
primary key (a1)
) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ;
drop table t2;
--warning 1364
create table t2 (
a1 varchar(12) charset utf8 collate utf8_bin,
a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int
) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1;
drop table t1, t2;
--warning 1364
create table t1 (
a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int
);
insert into t1 values (1,1,1, 1,1,1, 1,1,1);
--warning 1364
create table t2 (
a1 varchar(12) charset utf8 collate utf8_bin not null,
a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int,
primary key (a1)
) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ;
# Test the default value
drop table t2;
create table t2 ( a int default 3, b int default 3)
select a1,a2 from t1;
show create table t2;
drop table t1, t2;
# End of 4.1 tests # End of 4.1 tests

View File

@ -1314,4 +1314,41 @@ select period from t1;
drop table if exists t1,t2,t3,t4; drop table if exists t1,t2,t3,t4;
#
# Bug #13894 Server crashes on update of CSV table
#
--disable_warnings
DROP TABLE IF EXISTS bug13894;
--enable_warnings
CREATE TABLE bug13894 ( val integer ) ENGINE = CSV;
INSERT INTO bug13894 VALUES (5);
INSERT INTO bug13894 VALUES (10);
INSERT INTO bug13894 VALUES (11);
INSERT INTO bug13894 VALUES (10);
SELECT * FROM bug13894;
UPDATE bug13894 SET val=6 WHERE val=10;
SELECT * FROM bug13894;
DROP TABLE bug13894;
#
# Bug #14672 Bug in deletion
#
--disable_warnings
DROP TABLE IF EXISTS bug14672;
--enable_warnings
CREATE TABLE bug14672 (c1 integer) engine = CSV;
INSERT INTO bug14672 VALUES (1), (2), (3);
SELECT * FROM bug14672;
DELETE FROM bug14672 WHERE c1 = 2;
SELECT * FROM bug14672;
INSERT INTO bug14672 VALUES (4);
SELECT * FROM bug14672;
INSERT INTO bug14672 VALUES (5);
SELECT * FROM bug14672;
DROP TABLE bug14672;
# End of 4.1 tests # End of 4.1 tests

View File

@ -379,6 +379,8 @@ where table_schema='test';
select index_name from information_schema.statistics where table_schema='test'; select index_name from information_schema.statistics where table_schema='test';
select constraint_name from information_schema.table_constraints select constraint_name from information_schema.table_constraints
where table_schema='test'; where table_schema='test';
show create view v2;
show create table v3;
drop view v2; drop view v2;
drop view v3; drop view v3;
drop table t4; drop table t4;

View File

@ -832,3 +832,71 @@ SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
DROP VIEW v1, v2; DROP VIEW v1, v2;
DROP TABLE t1, t2, t3, t4, t5, t6; DROP TABLE t1, t2, t3, t4, t5, t6;
#
# BUG#13126 -test case from bug report
#
create table t1 (id1 int(11) not null);
insert into t1 values (1),(2);
create table t2 (id2 int(11) not null);
insert into t2 values (1),(2),(3),(4);
create table t3 (id3 char(16) not null);
insert into t3 values ('100');
create table t4 (id2 int(11) not null, id3 char(16));
create table t5 (id1 int(11) not null, key (id1));
insert into t5 values (1),(2),(1);
create view v1 as
select t4.id3 from t4 join t2 on t4.id2 = t2.id2;
select t1.id1 from t1 inner join (t3 left join v1 on t3.id3 = v1.id3);
drop view v1;
drop table t1, t2, t3, t4, t5;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3);
create table t1(a int);
insert into t1 select A.a + 10*(B.a) from t0 A, t0 B;
create table t2 (a int, b int);
insert into t2 values (1,1), (2,2), (3,3);
create table t3(a int, b int, filler char(200), key(a));
insert into t3 select a,a,'filler' from t1;
insert into t3 select a,a,'filler' from t1;
create table t4 like t3;
insert into t4 select * from t3;
insert into t4 select * from t3;
create table t5 like t4;
insert into t5 select * from t4;
insert into t5 select * from t4;
create table t6 like t5;
insert into t6 select * from t5;
insert into t6 select * from t5;
create table t7 like t6;
insert into t7 select * from t6;
insert into t7 select * from t6;
--replace_column 9 X
explain select * from t4 join
t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b;
--replace_column 9 X
explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b
join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b;
--replace_column 9 X
explain select * from t2 left join
(t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b
join t5 on t5.a=t3.b) on t3.a=t2.b;
drop table t0, t1, t2, t4, t5, t6;

View File

@ -648,6 +648,24 @@ analyze table t1;
show index from t1; show index from t1;
set myisam_stats_method=DEFAULT; set myisam_stats_method=DEFAULT;
drop table t1;
# BUG#13814 - key value packed incorrectly for TINYBLOBs
create table t1(
cip INT NOT NULL,
time TIME NOT NULL,
score INT NOT NULL DEFAULT 0,
bob TINYBLOB
);
insert into t1 (cip, time) VALUES (1, '00:01'), (2, '00:02'), (3,'00:03');
insert into t1 (cip, bob, time) VALUES (4, 'a', '00:04'), (5, 'b', '00:05'),
(6, 'c', '00:06');
select * from t1 where bob is null and cip=1;
create index bug on t1 (bob(22), cip, time);
select * from t1 where bob is null and cip=1;
drop table t1;
# End of 4.1 tests # End of 4.1 tests
# #

View File

@ -658,19 +658,19 @@ select '------ Testing with illegal table names ------' as test_sequence ;
--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "t/1" 2>&1 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "t/1" 2>&1
--error 6 --error 6
--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T_1" --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T_1" 2>&1
--error 6 --error 6
--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T%1" --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T%1" 2>&1
--error 6 --error 6
--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T'1" --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T'1" 2>&1
--error 6 --error 6
--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T_1" --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T_1" 2>&1
--error 6 --error 6
--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T_" --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T_" 2>&1
--disable_query_log --disable_query_log
select '------ Testing with illegal database names ------' as test_sequence ; select '------ Testing with illegal database names ------' as test_sequence ;
@ -882,6 +882,7 @@ DROP FUNCTION IF EXISTS bug9056_func1;
DROP FUNCTION IF EXISTS bug9056_func2; DROP FUNCTION IF EXISTS bug9056_func2;
DROP PROCEDURE IF EXISTS bug9056_proc1; DROP PROCEDURE IF EXISTS bug9056_proc1;
DROP PROCEDURE IF EXISTS bug9056_proc2; DROP PROCEDURE IF EXISTS bug9056_proc2;
DROP PROCEDURE IF EXISTS `a'b`;
--enable_warnings --enable_warnings
CREATE TABLE t1 (id int); CREATE TABLE t1 (id int);

103
mysql-test/t/read_only.test Normal file
View File

@ -0,0 +1,103 @@
# Test of the READ_ONLY global variable:
# check that it blocks updates unless they are only on temporary tables.
--disable_warnings
DROP TABLE IF EXISTS t1,t2,t3;
--enable_warnings
# READ_ONLY does nothing to SUPER users
# so we use a non-SUPER one:
grant CREATE, SELECT, DROP on *.* to test@localhost;
connect (con1,localhost,test,,test);
connection default;
set global read_only=0;
connection con1;
create table t1 (a int);
insert into t1 values(1);
create table t2 select * from t1;
connection default;
set global read_only=1;
# We check that SUPER can:
create table t3 (a int);
drop table t3;
connection con1;
select @@global.read_only;
--error 1290
create table t3 (a int);
--error 1290
insert into t1 values(1);
# if a statement, after parse stage, looks like it will update a
# non-temp table, it will be rejected, even if at execution it would
# have turned out that 0 rows would be updated
--error 1290
update t1 set a=1 where 1=0;
# multi-update is special (see sql_parse.cc) so we test it
--error 1290
update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a;
# check multi-delete to be sure
--error 1290
delete t1,t2 from t1,t2 where t1.a=t2.a;
# With temp tables updates should be accepted:
create temporary table t3 (a int);
create temporary table t4 (a int) select * from t3;
insert into t3 values(1);
insert into t4 select * from t3;
# a non-temp table updated:
--error 1290
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
# no non-temp table updated (just swapped):
update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a;
update t4,t3 set t4.a=t3.a+1 where t4.a=t3.a;
--error 1290
delete t1 from t1,t3 where t1.a=t3.a;
delete t3 from t1,t3 where t1.a=t3.a;
delete t4 from t3,t4 where t4.a=t3.a;
# and even homonymous ones
create temporary table t1 (a int);
insert into t1 values(1);
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
delete t1 from t1,t3 where t1.a=t3.a;
drop table t1;
--error 1290
insert into t1 values(1);
connection default;
drop table t1,t2;
drop user test@localhost;

View File

@ -13,6 +13,7 @@ insert into mysqltest1.t1 values (1);
select * from mysqltest1.t1 into outfile 'mysqltest1/f1.txt'; select * from mysqltest1.t1 into outfile 'mysqltest1/f1.txt';
create table mysqltest1.t2 (n int); create table mysqltest1.t2 (n int);
create table mysqltest1.t3 (n int); create table mysqltest1.t3 (n int);
--replace_result \\ /
--error 1010 --error 1010
drop database mysqltest1; drop database mysqltest1;
use mysqltest1; use mysqltest1;
@ -29,6 +30,7 @@ while ($1)
} }
--enable_query_log --enable_query_log
--replace_result \\ /
--error 1010 --error 1010
drop database mysqltest1; drop database mysqltest1;
use mysqltest1; use mysqltest1;

View File

@ -1 +1 @@
--log_bin_trust_routine_creators=0 --log_bin_trust_routine_creators=0 --slave-skip-errors=1062

View File

@ -1,10 +1,18 @@
# Test of replication of stored procedures (WL#2146 for MySQL 5.0) # Test of replication of stored procedures (WL#2146 for MySQL 5.0)
# Modified by WL#2971.
# Note that in the .opt files we still use the old variable name
# log-bin-trust-routine-creators so that this test checks that it's
# still accepted (this test also checks that the new name is
# accepted). The old name could be removed in 5.1 or 6.0.
source include/master-slave.inc; source include/master-slave.inc;
# First let's test replication of current_user() (that's a related thing)
# we need a db != test, where we don't have automatic grants # we need a db != test, where we don't have automatic grants
create database if not exists mysqltest1; --disable_warnings
drop database if exists mysqltest1;
--enable_warnings
create database mysqltest1;
use mysqltest1; use mysqltest1;
create table t1 (a varchar(100)); create table t1 (a varchar(100));
sync_slave_with_master; sync_slave_with_master;
@ -16,18 +24,14 @@ use mysqltest1;
# (same definer, same properties...) # (same definer, same properties...)
connection master; connection master;
# cleanup
--disable_warnings
drop procedure if exists foo;
drop procedure if exists foo2;
drop procedure if exists foo3;
drop procedure if exists foo4;
drop procedure if exists bar;
drop function if exists fn1;
--enable_warnings
delimiter |; delimiter |;
--error 1418 # not deterministic
# Stored procedures don't have the limitations that functions have
# regarding binlogging: it's ok to create a procedure as not
# deterministic and updating data, while it's not ok to create such a
# function. We test this.
create procedure foo() create procedure foo()
begin begin
declare b int; declare b int;
@ -35,17 +39,6 @@ begin
insert into t1 values (b); insert into t1 values (b);
insert into t1 values (unix_timestamp()); insert into t1 values (unix_timestamp());
end| end|
--replace_column 2 # 5 #
show binlog events from 98| # check that not there
create procedure foo() deterministic
begin
declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end|
delimiter ;| delimiter ;|
# we replace columns having times # we replace columns having times
@ -54,38 +47,29 @@ delimiter ;|
--replace_column 13 # 14 # --replace_column 13 # 14 #
select * from mysql.proc where name='foo' and db='mysqltest1'; select * from mysql.proc where name='foo' and db='mysqltest1';
sync_slave_with_master; sync_slave_with_master;
# You will notice in the result that the definer does not match what
# it is on master, it is a known bug on which Alik is working
--replace_result localhost.localdomain localhost 127.0.0.1 localhost --replace_result localhost.localdomain localhost 127.0.0.1 localhost
--replace_column 13 # 14 # --replace_column 13 # 14 #
select * from mysql.proc where name='foo' and db='mysqltest1'; select * from mysql.proc where name='foo' and db='mysqltest1';
# Now when we call it, does the CALL() get into binlog,
# or the substatements?
connection master; connection master;
# see if timestamp used in SP on slave is same as on master # see if timestamp used in SP on slave is same as on master
set timestamp=1000000000; set timestamp=1000000000;
call foo(); call foo();
--replace_column 2 # 5 #
show binlog events from 308;
select * from t1; select * from t1;
sync_slave_with_master; sync_slave_with_master;
select * from t1; select * from t1;
# Now a SP which is supposed to not update tables (CALL should not be # Now a SP which is not updating tables
# binlogged) as it's "read sql data", so should not give error even if
# non-deterministic.
connection master; connection master;
delete from t1; delete from t1;
create procedure foo2() create procedure foo2()
not deterministic
reads sql data
select * from mysqltest1.t1; select * from mysqltest1.t1;
call foo2(); call foo2();
# verify CALL is not in binlog
--replace_column 2 # 5 #
show binlog events from 518;
--error 1418 # check that this is allowed (it's not for functions):
alter procedure foo2 contains sql; alter procedure foo2 contains sql;
# SP with definer's right # SP with definer's right
@ -106,15 +90,7 @@ grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1;
connect (con1,127.0.0.1,zedjzlcsjhd,,mysqltest1,$MASTER_MYPORT,); connect (con1,127.0.0.1,zedjzlcsjhd,,mysqltest1,$MASTER_MYPORT,);
connection con1; connection con1;
--error 1419 # only full-global-privs user can create a routine # this routine will fail in the second INSERT because of privileges
create procedure foo4()
deterministic
insert into t1 values (10);
connection master;
set global log_bin_trust_routine_creators=1;
connection con1;
delimiter |; delimiter |;
create procedure foo4() create procedure foo4()
deterministic deterministic
@ -128,29 +104,22 @@ delimiter ;|
# I add ,0 so that it does not print the error in the test output, # I add ,0 so that it does not print the error in the test output,
# because this error is hostname-dependent # because this error is hostname-dependent
--error 1142,0 --error 1142,0
call foo4(); # invoker has no INSERT grant on table => failure call foo4(); # invoker has no INSERT grant on table t1 => failure
show warnings;
connection master; connection master;
call foo3(); # success (definer == root) call foo3(); # success (definer == root)
show warnings; show warnings;
--replace_result localhost.localdomain localhost 127.0.0.1 localhost
--error 1142,0 --error 1142,0
call foo4(); # definer's rights => failure call foo4(); # definer's rights => failure
show warnings;
# we test replication of ALTER PROCEDURE # we test replication of ALTER PROCEDURE
alter procedure foo4 sql security invoker; alter procedure foo4 sql security invoker;
call foo4(); # invoker's rights => success call foo4(); # invoker's rights => success
show warnings; show warnings;
# Check that only successful CALLs are in binlog # Note that half-failed procedure calls are ok with binlogging;
--replace_column 2 # 5 # # if we compare t2 on master and slave we see they are identical:
show binlog events from 990;
# Note that half-failed CALLs are not in binlog, which is a known
# bug. If we compare t2 on master and slave we see they differ:
select * from t1; select * from t1;
select * from t2; select * from t2;
@ -158,6 +127,30 @@ sync_slave_with_master;
select * from t1; select * from t1;
select * from t2; select * from t2;
# Let's check another failing-in-the-middle procedure
connection master;
delete from t2;
alter table t2 add unique (a);
drop procedure foo4;
delimiter |;
create procedure foo4()
deterministic
begin
insert into t2 values(20),(20);
end|
delimiter ;|
--error 1062
call foo4();
show warnings;
select * from t2;
sync_slave_with_master;
# check that this failed-in-the-middle replicated right:
select * from t2;
# Test of DROP PROCEDURE # Test of DROP PROCEDURE
--replace_result localhost.localdomain localhost 127.0.0.1 localhost --replace_result localhost.localdomain localhost 127.0.0.1 localhost
@ -177,6 +170,14 @@ drop procedure foo2;
drop procedure foo3; drop procedure foo3;
delimiter |; delimiter |;
# check that needs "deterministic"
--error 1418
create function fn1(x int)
returns int
begin
insert into t1 values (x);
return x+2;
end|
create function fn1(x int) create function fn1(x int)
returns int returns int
deterministic deterministic
@ -202,15 +203,69 @@ drop function fn1;
create function fn1() create function fn1()
returns int returns int
deterministic no sql
begin begin
return unix_timestamp(); return unix_timestamp();
end| end|
delimiter ;| delimiter ;|
# check that needs "deterministic"
--error 1418
alter function fn1 contains sql;
delete from t1; delete from t1;
set timestamp=1000000000; set timestamp=1000000000;
insert into t1 values(fn1()); insert into t1 values(fn1());
connection con1;
delimiter |;
--error 1419 # only full-global-privs user can create a function
create function fn2()
returns int
no sql
begin
return unix_timestamp();
end|
delimiter ;|
connection master;
# test old variable name:
set global log_bin_trust_routine_creators=1;
# now use new name:
set global log_bin_trust_function_creators=0;
set global log_bin_trust_function_creators=1;
# slave needs it too otherwise will not execute what master allowed:
connection slave;
set global log_bin_trust_function_creators=1;
connection con1;
delimiter |;
create function fn2()
returns int
no sql
begin
return unix_timestamp();
end|
delimiter ;|
connection master;
# Now a function which is supposed to not update tables
# as it's "reads sql data", so should not give error even if
# non-deterministic.
delimiter |;
create function fn3()
returns int
not deterministic
reads sql data
begin
return 0;
end|
delimiter ;|
select fn3();
--replace_result localhost.localdomain localhost 127.0.0.1 localhost --replace_result localhost.localdomain localhost 127.0.0.1 localhost
--replace_column 13 # 14 # --replace_column 13 # 14 #
select * from mysql.proc where db='mysqltest1'; select * from mysql.proc where db='mysqltest1';
@ -223,18 +278,43 @@ select * from t1;
--replace_column 13 # 14 # --replace_column 13 # 14 #
select * from mysql.proc where db='mysqltest1'; select * from mysql.proc where db='mysqltest1';
# And now triggers # Let's check a failing-in-the-middle function
connection master;
delete from t2;
alter table t2 add unique (a);
drop function fn1;
delimiter |;
create function fn1()
returns int
begin
insert into t2 values(20),(20);
return 10;
end|
delimiter ;|
# Because of BUG#14769 the following statement requires that we start
# slave with --slave-skip-errors=1062. When that bug is fixed, that
# option can be removed.
--error 1062
select fn1();
select * from t2;
sync_slave_with_master;
# check that this failed-in-the-middle replicated right:
select * from t2;
# ********************** PART 3 : TRIGGERS ***************
connection con1; connection con1;
--error 1227 --error 1227
create trigger trg before insert on t1 for each row set new.a= 10; create trigger trg before insert on t1 for each row set new.a= 10;
connection master; connection master;
# fn1() above uses timestamps, so in !ps-protocol, the timezone will be
# binlogged, but in --ps-protocol it will not be (BUG#9359) so
# the binlog offsets get shifted which spoils SHOW BINLOG EVENTS.
# To be immune, we take a new binlog.
flush logs;
delete from t1; delete from t1;
# TODO: when triggers can contain an update, test that this update # TODO: when triggers can contain an update, test that this update
# does not go into binlog. # does not go into binlog.
@ -253,7 +333,7 @@ drop trigger trg;
insert into t1 values (1); insert into t1 values (1);
select * from t1; select * from t1;
--replace_column 2 # 5 # --replace_column 2 # 5 #
show binlog events in 'master-bin.000002' from 98; show binlog events in 'master-bin.000001' from 98;
sync_slave_with_master; sync_slave_with_master;
select * from t1; select * from t1;

View File

@ -87,12 +87,35 @@ insert into t1 set a = now();
select a=b && a=c from t1; select a=b && a=c from t1;
let $time=`select a from t1`; let $time=`select a from t1`;
# Check that definer attribute is replicated properly:
# - dump definers on the master;
# - wait for the slave to synchronize with the master;
# - dump definers on the slave;
SELECT routine_name, definer
FROM information_schema.routines;
SELECT trigger_name, definer
FROM information_schema.triggers;
save_master_pos; save_master_pos;
connection slave; connection slave;
sync_with_master; sync_with_master;
--disable_query_log --disable_query_log
select "--- On slave --" as ""; select "--- On slave --" as "";
--enable_query_log --enable_query_log
# XXX: Definers of stored procedures and functions are not replicated. WL#2897
# (Complete definer support in the stored routines) addresses this issue. So,
# the result file is expected to be changed after implementation of this WL
# item.
SELECT routine_name, definer
FROM information_schema.routines;
SELECT trigger_name, definer
FROM information_schema.triggers;
select a=b && a=c from t1; select a=b && a=c from t1;
--disable_query_log --disable_query_log
eval select a='$time' as 'test' from t1; eval select a='$time' as 'test' from t1;

View File

@ -2729,3 +2729,23 @@ select * from t1 where f2 >= '2005-09-3a';
select * from t1 where f2 <= '2005-09-31'; select * from t1 where f2 <= '2005-09-31';
select * from t1 where f2 <= '2005-09-3a'; select * from t1 where f2 <= '2005-09-3a';
drop table t1; drop table t1;
#
# Bug ##14662 ORDER BY on column of a view, with an alias of the same
# column causes ambiguous
#
create table t1 (f1 int, f2 int);
insert into t1 values (1, 30), (2, 20), (3, 10);
create algorithm=merge view v1 as select f1, f2 from t1;
create algorithm=merge view v2 (f2, f1) as select f1, f2 from t1;
create algorithm=merge view v3 as select t1.f1 as f2, t1.f2 as f1 from t1;
select t1.f1 as x1, f1 from t1 order by t1.f1;
select v1.f1 as x1, f1 from v1 order by v1.f1;
select v2.f1 as x1, f1 from v2 order by v2.f1;
select v3.f1 as x1, f1 from v3 order by v3.f1;
select f1, f2, v1.f1 as x1 from v1 order by v1.f1;
select f1, f2, v2.f1 as x1 from v2 order by v2.f1;
select f1, f2, v3.f1 as x1 from v3 order by v3.f1;
drop table t1;
drop view v1, v2, v3;

View File

@ -9,7 +9,7 @@ use test;
# test that we can create VIEW if privileges check switched off # test that we can create VIEW if privileges check switched off
# #
create table t1 (field1 INT); create table t1 (field1 INT);
-- error ER_NO_VIEW_USER -- error ER_MALFORMED_DEFINER
CREATE VIEW v1 AS SELECT field1 FROM t1; CREATE VIEW v1 AS SELECT field1 FROM t1;
drop table t1; drop table t1;

View File

@ -1337,6 +1337,22 @@ DROP PROCEDURE bug13037_p1;
DROP PROCEDURE bug13037_p2; DROP PROCEDURE bug13037_p2;
DROP PROCEDURE bug13037_p3; DROP PROCEDURE bug13037_p3;
#
# Bug#14569 "editing a stored procedure kills mysqld-nt"
#
create database mysqltest1;
create database mysqltest2;
use mysqltest1;
drop database mysqltest1;
create procedure mysqltest2.p1() select version();
--error ER_NO_DB_ERROR
create procedure p2() select version();
use mysqltest2;
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show procedure status;
drop database mysqltest2;
use test;
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #

View File

@ -183,3 +183,57 @@ group by country;
drop table t1; drop table t1;
#
# BUG#14342: wrong placement of subquery internals in complex queries
#
CREATE TABLE `t1` (
`t3_id` int NOT NULL,
`t1_id` int NOT NULL,
PRIMARY KEY (`t1_id`)
);
CREATE TABLE `t2` (
`t2_id` int NOT NULL,
`t1_id` int NOT NULL,
`b` int NOT NULL,
PRIMARY KEY (`t2_id`),
UNIQUE KEY `idx_t2_t1_b` (`t1_id`,`b`)
) ENGINE=InnoDB;
CREATE TABLE `t3` (
`t3_id` int NOT NULL
);
INSERT INTO `t3` VALUES (3);
select
(SELECT rs.t2_id
FROM t2 rs
WHERE rs.t1_id=
(SELECT lt.t1_id
FROM t1 lt
WHERE lt.t3_id=a.t3_id)
ORDER BY b DESC LIMIT 1)
from t3 AS a;
# repeat above query in SP
--disable_warnings
DROP PROCEDURE IF EXISTS p1;
--enable_warnings
delimiter //;
create procedure p1()
begin
declare done int default 3;
repeat
select
(SELECT rs.t2_id
FROM t2 rs
WHERE rs.t1_id=
(SELECT lt.t1_id
FROM t1 lt
WHERE lt.t3_id=a.t3_id)
ORDER BY b DESC LIMIT 1) as x
from t3 AS a;
set done= done-1;
until done <= 0 end repeat;
end//
delimiter ;//
call p1();
call p1();
call p1();
drop tables t1,t2,t3;

View File

@ -0,0 +1,83 @@
# Test case(s) in this file contain(s) GRANT/REVOKE statements, which are not
# supported in embedded server. So, this test should not be run on embedded
# server.
-- source include/not_embedded.inc
###########################################################################
#
# Tests for WL#2818:
# - Check that triggers created w/o DEFINER information work well:
# - create the first trigger;
# - manually remove definer information from corresponding TRG file;
# - create the second trigger (the first trigger will be reloaded; check
# that we receive a warning);
# - check that the triggers loaded correctly;
#
###########################################################################
#
# Prepare environment.
#
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
FLUSH PRIVILEGES;
--disable_warnings
DROP DATABASE IF EXISTS mysqltest_db1;
--enable_warnings
CREATE DATABASE mysqltest_db1;
CREATE USER mysqltest_dfn@localhost;
CREATE USER mysqltest_inv@localhost;
GRANT SUPER ON *.* TO mysqltest_dfn@localhost;
GRANT CREATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
#
# Create a table and the first trigger.
#
--connect (wl2818_definer_con,localhost,mysqltest_dfn,,mysqltest_db1)
--connection wl2818_definer_con
--echo
--echo ---> connection: wl2818_definer_con
CREATE TABLE t1(num_value INT);
CREATE TABLE t2(user_str TEXT);
CREATE TRIGGER wl2818_trg1 BEFORE INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
#
# Remove definers from TRG file.
#
--echo
--echo ---> patching t1.TRG...
--exec grep --text -v 'definers=' $MYSQL_TEST_DIR/var/master-data/mysqltest_db1/t1.TRG > $MYSQL_TEST_DIR/var/tmp/t1.TRG
--exec mv $MYSQL_TEST_DIR/var/tmp/t1.TRG $MYSQL_TEST_DIR/var/master-data/mysqltest_db1/t1.TRG
#
# Create a new trigger.
#
--echo
CREATE TRIGGER wl2818_trg2 AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
--echo
SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
--echo
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;

View File

@ -0,0 +1,475 @@
# Test case(s) in this file contain(s) GRANT/REVOKE statements, which are not
# supported in embedded server. So, this test should not be run on embedded
# server.
-- source include/not_embedded.inc
###########################################################################
#
# Tests for WL#2818:
# - Check that triggers are executed under the authorization of the definer.
# - Check that if trigger contains NEW/OLD variables, the definer must have
# SELECT privilege on the subject table.
# - Check DEFINER clause of CREATE TRIGGER statement;
# - Check that SUPER privilege required to create a trigger with different
# definer.
# - Check that if the user specified as DEFINER does not exist, a warning
# is emitted.
# - Check that the definer of a trigger does not exist, the trigger will
# not be activated.
# - Check that SHOW TRIGGERS statement provides "Definer" column.
#
# Let's also check that user name part of definer can contain '@' symbol (to
# check that triggers are not affected by BUG#13310 "incorrect user parsing
# by SP").
#
###########################################################################
#
# Prepare environment.
#
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
FLUSH PRIVILEGES;
--disable_warnings
DROP DATABASE IF EXISTS mysqltest_db1;
--enable_warnings
CREATE DATABASE mysqltest_db1;
CREATE USER mysqltest_dfn@localhost;
CREATE USER mysqltest_inv@localhost;
GRANT SUPER ON *.* TO mysqltest_dfn@localhost;
GRANT CREATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
#
# Check that triggers are executed under the authorization of the definer:
# - create two tables under "definer";
# - grant all privileges on the test db to "definer";
# - grant all privileges on the first table to "invoker";
# - grant only select privilege on the second table to "invoker";
# - create a trigger, which inserts a row into the second table after
# inserting into the first table.
# - insert a row into the first table under "invoker". A row also should be
# inserted into the second table.
#
--connect (wl2818_definer_con,localhost,mysqltest_dfn,,mysqltest_db1)
--connection wl2818_definer_con
--echo
--echo ---> connection: wl2818_definer_con
CREATE TABLE t1(num_value INT);
CREATE TABLE t2(user_str TEXT);
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
--connection default
--echo
--echo ---> connection: default
# Setup definer's privileges.
GRANT ALL PRIVILEGES ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
GRANT ALL PRIVILEGES ON mysqltest_db1.t2 TO mysqltest_dfn@localhost;
# Setup invoker's privileges.
GRANT ALL PRIVILEGES ON mysqltest_db1.t1
TO 'mysqltest_inv'@localhost;
GRANT SELECT ON mysqltest_db1.t2
TO 'mysqltest_inv'@localhost;
--connection wl2818_definer_con
--echo
--echo ---> connection: wl2818_definer_con
use mysqltest_db1;
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
SELECT * FROM t2;
--connect (wl2818_invoker_con,localhost,mysqltest_inv,,mysqltest_db1)
--connection wl2818_invoker_con
--echo
--echo ---> connection: wl2818_invoker_con
use mysqltest_db1;
INSERT INTO t1 VALUES(2);
SELECT * FROM t1;
SELECT * FROM t2;
#
# Check that if definer lost some privilege required to execute (activate) a
# trigger, the trigger will not be activated:
# - create a trigger on insert into the first table, which will insert a row
# into the second table;
# - revoke INSERT privilege on the second table from the definer;
# - insert a row into the first table;
# - check that an error has been risen;
# - check that no row has been inserted into the second table;
#
--connection default
--echo
--echo ---> connection: default
use mysqltest_db1;
REVOKE INSERT ON mysqltest_db1.t2 FROM mysqltest_dfn@localhost;
--connection wl2818_invoker_con
--echo
--echo ---> connection: wl2818_invoker_con
use mysqltest_db1;
--error ER_TABLEACCESS_DENIED_ERROR
INSERT INTO t1 VALUES(3);
SELECT * FROM t1;
SELECT * FROM t2;
#
# Check that if trigger contains NEW/OLD variables, the definer must have
# SELECT/UPDATE privilege on the subject table:
# - drop the trigger;
# - create a new trigger, which will use NEW variable;
# - create another new trigger, which will use OLD variable;
# - revoke SELECT/UPDATE privilege on the first table from "definer";
# - insert a row into the first table;
# - analyze error code;
#
#
# SELECT privilege.
#
--connection default
--echo
--echo ---> connection: default
use mysqltest_db1;
REVOKE SELECT ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
--connection wl2818_definer_con
--echo
--echo ---> connection: wl2818_definer_con
use mysqltest_db1;
DROP TRIGGER trg1;
SET @new_sum = 0;
SET @old_sum = 0;
# INSERT INTO statement; BEFORE timing
--echo ---> INSERT INTO statement; BEFORE timing
CREATE TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
INSERT INTO t1 VALUES(4);
# INSERT INTO statement; AFTER timing
--echo ---> INSERT INTO statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
INSERT INTO t1 VALUES(5);
# UPDATE statement; BEFORE timing
--echo ---> UPDATE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
UPDATE t1 SET num_value = 10;
# UPDATE statement; AFTER timing
--echo ---> UPDATE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER UPDATE ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
UPDATE t1 SET num_value = 20;
# DELETE statement; BEFORE timing
--echo ---> DELETE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
DELETE FROM t1;
# DELETE statement; AFTER timing
--echo ---> DELETE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
DELETE FROM t1;
#
# UPDATE privilege
#
# NOTE: At the moment, UPDATE privilege is required if the trigger contains
# NEW/OLD variables, whenever the trigger modifies them or not. Moreover,
# UPDATE privilege is checked for whole table, not for individual columns.
#
# The following test cases should be changed when full support of UPDATE
# privilege will be done.
#
--connection default
--echo
--echo ---> connection: default
use mysqltest_db1;
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
REVOKE UPDATE ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
--connection wl2818_definer_con
--echo
--echo ---> connection: wl2818_definer_con
use mysqltest_db1;
DROP TRIGGER trg1;
SET @new_sum = 0;
SET @old_sum = 0;
# INSERT INTO statement; BEFORE timing
--echo ---> INSERT INTO statement; BEFORE timing
CREATE TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
INSERT INTO t1 VALUES(4);
# INSERT INTO statement; AFTER timing
--echo ---> INSERT INTO statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
INSERT INTO t1 VALUES(5);
# UPDATE statement; BEFORE timing
--echo ---> UPDATE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
UPDATE t1 SET num_value = 10;
# UPDATE statement; AFTER timing
--echo ---> UPDATE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER UPDATE ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
UPDATE t1 SET num_value = 20;
# DELETE statement; BEFORE timing
--echo ---> DELETE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
DELETE FROM t1;
# DELETE statement; AFTER timing
--echo ---> DELETE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
--error ER_TABLEACCESS_DENIED_ERROR
DELETE FROM t1;
#
# Check DEFINER clause of CREATE TRIGGER statement.
#
# NOTE: there is no dedicated TRIGGER privilege for CREATE TRIGGER statement.
# SUPER privilege is used instead. I.e., if one invokes CREATE TRIGGER, it should
# have SUPER privilege, so this test is meaningless right now.
#
# - Check that SUPER privilege required to create a trigger with different
# definer:
# - try to create a trigger with DEFINER="definer@localhost" under
# "invoker";
# - analyze error code;
# - Check that if the user specified as DEFINER does not exist, a warning is
# emitted:
# - create a trigger with DEFINER="non_existent_user@localhost" from
# "definer";
# - check that a warning emitted;
# - Check that the definer of a trigger does not exist, the trigger will not
# be activated:
# - activate just created trigger;
# - check error code;
#
--connection wl2818_definer_con
--echo
--echo ---> connection: wl2818_definer_con
use mysqltest_db1;
DROP TRIGGER trg1;
# Check that SUPER is required to specify different DEFINER.
# NOTE: meaningless at the moment
CREATE DEFINER='mysqltest_inv'@'localhost'
TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @new_sum = 0;
# Create with non-existent user.
CREATE DEFINER='mysqltest_nonexs'@'localhost'
TRIGGER trg2 AFTER INSERT ON t1
FOR EACH ROW
SET @new_sum = 0;
# Check that trg2 will not be activated.
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
INSERT INTO t1 VALUES(6);
#
# Check that SHOW TRIGGERS statement provides "Definer" column.
#
SHOW TRIGGERS;
#
# Check that weird definer values do not break functionality. I.e. check the
# following definer values:
# - '';
# - '@';
# - '@abc@def@@';
# - '@hostname';
# - '@abc@def@@@hostname';
#
DROP TRIGGER trg1;
DROP TRIGGER trg2;
CREATE TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @a = 1;
CREATE TRIGGER trg2 AFTER INSERT ON t1
FOR EACH ROW
SET @a = 2;
CREATE TRIGGER trg3 BEFORE UPDATE ON t1
FOR EACH ROW
SET @a = 3;
CREATE TRIGGER trg4 AFTER UPDATE ON t1
FOR EACH ROW
SET @a = 4;
CREATE TRIGGER trg5 BEFORE DELETE ON t1
FOR EACH ROW
SET @a = 5;
--exec egrep --text -v '^definers=' $MYSQL_TEST_DIR/var/master-data/mysqltest_db1/t1.TRG > $MYSQL_TEST_DIR/var/tmp/t1.TRG
--exec echo "definers='' '@' '@abc@def@@' '@hostname' '@abcdef@@@hostname'" >> $MYSQL_TEST_DIR/var/tmp/t1.TRG
--exec mv $MYSQL_TEST_DIR/var/tmp/t1.TRG $MYSQL_TEST_DIR/var/master-data/mysqltest_db1/t1.TRG
--echo
SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
--echo
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
#
# Cleanup
#
--connection default
--echo
--echo ---> connection: default
DROP USER mysqltest_dfn@localhost;
DROP USER mysqltest_inv@localhost;
DROP DATABASE mysqltest_db1;

View File

@ -1051,6 +1051,41 @@ select cast(@non_existing_user_var/2 as DECIMAL);
--error 1427 --error 1427
create table t (d decimal(0,10)); create table t (d decimal(0,10));
#
# Bug #14268 (bad FLOAT->DECIMAL conversion)
#
CREATE TABLE t1 (
my_float FLOAT,
my_double DOUBLE,
my_varchar VARCHAR(50),
my_decimal DECIMAL(65,30)
);
SHOW CREATE TABLE t1;
let $max_power= 32;
while ($max_power)
{
eval INSERT INTO t1 SET my_float = 1.175494345e-$max_power,
my_double = 1.175494345e-$max_power,
my_varchar = '1.175494345e-$max_power';
dec $max_power;
}
SELECT my_float, my_double, my_varchar FROM t1;
SELECT CAST(my_float AS DECIMAL(65,30)), my_float FROM t1;
SELECT CAST(my_double AS DECIMAL(65,30)), my_double FROM t1;
SELECT CAST(my_varchar AS DECIMAL(65,30)), my_varchar FROM t1;
UPDATE t1 SET my_decimal = my_float;
SELECT my_decimal, my_float FROM t1;
UPDATE t1 SET my_decimal = my_double;
SELECT my_decimal, my_double FROM t1;
UPDATE t1 SET my_decimal = my_varchar;
SELECT my_decimal, my_varchar FROM t1;
DROP TABLE t1;
# #
# Bug #13573 (Wrong data inserted for too big values) # Bug #13573 (Wrong data inserted for too big values)
# #

View File

@ -1,5 +1,5 @@
--disable_warnings --disable_warnings
drop table if exists t1,t2,t9,`t1a``b`,v1,v2,v3,v4,v5,v6; drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6; drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
drop database if exists mysqltest; drop database if exists mysqltest;
--enable_warnings --enable_warnings
@ -2085,7 +2085,7 @@ drop table t1, t2;
# #
# DEFINER information check # DEFINER information check
# #
-- error ER_NO_VIEW_USER -- error ER_MALFORMED_DEFINER
create definer=some_user@`` sql security invoker view v1 as select 1; create definer=some_user@`` sql security invoker view v1 as select 1;
create definer=some_user@localhost sql security invoker view v1 as select 1; create definer=some_user@localhost sql security invoker view v1 as select 1;
show create view v1; show create view v1;
@ -2204,3 +2204,56 @@ select * from v1;
select * from v2; select * from v2;
drop view v1,v2; drop view v1,v2;
drop table t1; drop table t1;
#
# BUG#14026 Crash on second PS execution when using views
#
create table t1 (x int, y int);
create table t2 (x int, y int, z int);
create table t3 (x int, y int, z int);
create table t4 (x int, y int, z int);
create view v1 as
select t1.x
from (
(t1 join t2 on ((t1.y = t2.y)))
join
(t3 left join t4 on (t3.y = t4.y) and (t3.z = t4.z))
);
prepare stmt1 from "select count(*) from v1 where x = ?";
set @parm1=1;
execute stmt1 using @parm1;
execute stmt1 using @parm1;
drop view v1;
drop table t1,t2,t3,t4;
#
# Bug #14540: OPTIMIZE, ANALYZE, REPAIR applied to not a view
#
CREATE TABLE t1(id INT);
CREATE VIEW v1 AS SELECT id FROM t1;
OPTIMIZE TABLE v1;
ANALYZE TABLE v1;
REPAIR TABLE v1;
DROP TABLE t1;
OPTIMIZE TABLE v1;
DROP VIEW v1;
#
# BUG#14719: Views DEFINER grammar is incorrect
#
create definer = current_user() sql security invoker view v1 as select 1;
show create view v1;
drop view v1;
create definer = current_user sql security invoker view v1 as select 1;
show create view v1;
drop view v1;

View File

@ -24,7 +24,7 @@ grant create view,select on test.* to mysqltest_1@localhost;
connect (user1,localhost,mysqltest_1,,test); connect (user1,localhost,mysqltest_1,,test);
connection user1; connection user1;
-- error ER_VIEW_OTHER_USER -- error ER_SPECIFIC_ACCESS_DENIED
create definer=root@localhost view v1 as select * from mysqltest.t1; create definer=root@localhost view v1 as select * from mysqltest.t1;
create view v1 as select * from mysqltest.t1; create view v1 as select * from mysqltest.t1;
# try to modify view without DROP privilege on it # try to modify view without DROP privilege on it

View File

@ -47,13 +47,16 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
#elif defined(VMS) #elif defined(VMS)
fd = open((my_string) FileName, access_flags | O_CREAT, 0, fd = open((my_string) FileName, access_flags | O_CREAT, 0,
"ctx=stm","ctx=bin"); "ctx=stm","ctx=bin");
#elif defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2) #elif defined(MSDOS) || defined(__EMX__) || defined(OS2)
if (access_flags & O_SHARE) if (access_flags & O_SHARE)
fd = sopen((my_string) FileName, access_flags | O_CREAT | O_BINARY, fd = sopen((my_string) FileName, access_flags | O_CREAT | O_BINARY,
SH_DENYNO, MY_S_IREAD | MY_S_IWRITE); SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
else else
fd = open((my_string) FileName, access_flags | O_CREAT | O_BINARY, fd = open((my_string) FileName, access_flags | O_CREAT | O_BINARY,
MY_S_IREAD | MY_S_IWRITE); MY_S_IREAD | MY_S_IWRITE);
#elif defined(__WIN__)
fd= my_sopen((my_string) FileName, access_flags | O_CREAT | O_BINARY,
SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
#else #else
fd = open(FileName, access_flags); fd = open(FileName, access_flags);
#endif #endif

View File

@ -56,12 +56,18 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
DBUG_RETURN(my_register_filename(-1, FileName, FILE_BY_OPEN, DBUG_RETURN(my_register_filename(-1, FileName, FILE_BY_OPEN,
EE_FILENOTFOUND, MyFlags)); EE_FILENOTFOUND, MyFlags));
} }
#ifndef __WIN__
if (Flags & O_SHARE) if (Flags & O_SHARE)
fd = sopen((my_string) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO, fd = sopen((my_string) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
MY_S_IREAD | MY_S_IWRITE); MY_S_IREAD | MY_S_IWRITE);
else else
fd = open((my_string) FileName, Flags | O_BINARY, fd = open((my_string) FileName, Flags | O_BINARY,
MY_S_IREAD | MY_S_IWRITE); MY_S_IREAD | MY_S_IWRITE);
#else
fd= my_sopen((my_string) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
MY_S_IREAD | MY_S_IWRITE);
#endif
#elif !defined(NO_OPEN_3) #elif !defined(NO_OPEN_3)
fd = open(FileName, Flags, my_umask); /* Normal unix */ fd = open(FileName, Flags, my_umask); /* Normal unix */
#else #else
@ -167,3 +173,181 @@ File my_register_filename(File fd, const char *FileName, enum file_type
FileName, my_errno); FileName, my_errno);
return(fd); return(fd);
} }
#ifdef __WIN__
extern void __cdecl _dosmaperr(unsigned long);
/*
Open a file with sharing. Similar to _sopen() from libc, but allows managing
share delete on win32
SYNOPSIS
my_sopen()
path fully qualified file name
oflag operation flags
shflag share flag
pmode permission flags
RETURN VALUE
File descriptor of opened file if success
-1 and sets errno if fails.
*/
File my_sopen(const char *path, int oflag, int shflag, int pmode)
{
int fh; /* handle of opened file */
int mask;
HANDLE osfh; /* OS handle of opened file */
DWORD fileaccess; /* OS file access (requested) */
DWORD fileshare; /* OS file sharing mode */
DWORD filecreate; /* OS method of opening/creating */
DWORD fileattrib; /* OS file attribute flags */
SECURITY_ATTRIBUTES SecurityAttributes;
SecurityAttributes.nLength= sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor= NULL;
SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);
/*
* decode the access flags
*/
switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
case _O_RDONLY: /* read access */
fileaccess= GENERIC_READ;
break;
case _O_WRONLY: /* write access */
fileaccess= GENERIC_WRITE;
break;
case _O_RDWR: /* read and write access */
fileaccess= GENERIC_READ | GENERIC_WRITE;
break;
default: /* error, bad oflag */
errno= EINVAL;
_doserrno= 0L; /* not an OS error */
return -1;
}
/*
* decode sharing flags
*/
switch (shflag) {
case _SH_DENYRW: /* exclusive access except delete */
fileshare= FILE_SHARE_DELETE;
break;
case _SH_DENYWR: /* share read and delete access */
fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE;
break;
case _SH_DENYRD: /* share write and delete access */
fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
break;
case _SH_DENYNO: /* share read, write and delete access */
fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
break;
case _SH_DENYRWD: /* exclusive access */
fileshare= 0L;
break;
case _SH_DENYWRD: /* share read access */
fileshare= FILE_SHARE_READ;
break;
case _SH_DENYRDD: /* share write access */
fileshare= FILE_SHARE_WRITE;
break;
case _SH_DENYDEL: /* share read and write access */
fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE;
break;
default: /* error, bad shflag */
errno= EINVAL;
_doserrno= 0L; /* not an OS error */
return -1;
}
/*
* decode open/create method flags
*/
switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
case 0:
case _O_EXCL: // ignore EXCL w/o CREAT
filecreate= OPEN_EXISTING;
break;
case _O_CREAT:
filecreate= OPEN_ALWAYS;
break;
case _O_CREAT | _O_EXCL:
case _O_CREAT | _O_TRUNC | _O_EXCL:
filecreate= CREATE_NEW;
break;
case _O_TRUNC:
case _O_TRUNC | _O_EXCL: // ignore EXCL w/o CREAT
filecreate= TRUNCATE_EXISTING;
break;
case _O_CREAT | _O_TRUNC:
filecreate= CREATE_ALWAYS;
break;
default:
// this can't happen ... all cases are covered
errno= EINVAL;
_doserrno= 0L;
return -1;
}
/*
* decode file attribute flags if _O_CREAT was specified
*/
fileattrib= FILE_ATTRIBUTE_NORMAL; /* default */
if (oflag & _O_CREAT)
{
_umask((mask= _umask(0)));
if (!((pmode & ~mask) & _S_IWRITE))
fileattrib= FILE_ATTRIBUTE_READONLY;
}
/*
* Set temporary file (delete-on-close) attribute if requested.
*/
if (oflag & _O_TEMPORARY)
{
fileattrib|= FILE_FLAG_DELETE_ON_CLOSE;
fileaccess|= DELETE;
}
/*
* Set temporary file (delay-flush-to-disk) attribute if requested.
*/
if (oflag & _O_SHORT_LIVED)
fileattrib|= FILE_ATTRIBUTE_TEMPORARY;
/*
* Set sequential or random access attribute if requested.
*/
if (oflag & _O_SEQUENTIAL)
fileattrib|= FILE_FLAG_SEQUENTIAL_SCAN;
else if (oflag & _O_RANDOM)
fileattrib|= FILE_FLAG_RANDOM_ACCESS;
/*
* try to open/create the file
*/
if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes,
filecreate, fileattrib, NULL)) == (HANDLE)0xffffffff)
{
/*
* OS call to open/create file failed! map the error, release
* the lock, and return -1. note that it's not necessary to
* call _free_osfhnd (it hasn't been used yet).
*/
_dosmaperr(GetLastError()); /* map error */
return -1; /* return error to caller */
}
fh= _open_osfhandle((long)osfh, oflag & (_O_APPEND | _O_RDONLY | _O_TEXT));
return fh; /* return handle */
}
#endif /* __WIN__ */

View File

@ -35,7 +35,7 @@ ALTER TABLE user add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,a
ALTER TABLE host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; ALTER TABLE host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL;
ALTER TABLE db add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; ALTER TABLE db add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL;
--- Fix privileges for old tables -- Fix privileges for old tables
UPDATE user SET Grant_priv=File_priv,References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0; UPDATE user SET Grant_priv=File_priv,References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0;
UPDATE db SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0; UPDATE db SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0;
UPDATE host SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0; UPDATE host SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0;

View File

@ -76,6 +76,9 @@ int set_stacksize_n_create_thread(pthread_t *thread, pthread_attr_t *attr,
int rc= 0; int rc= 0;
#ifndef __WIN__ #ifndef __WIN__
#ifndef PTHREAD_STACK_MIN
#define PTHREAD_STACK_MIN 32768
#endif
/* /*
Set stack size to be safe on the platforms with too small Set stack size to be safe on the platforms with too small
default thread stack. default thread stack.

View File

@ -95,11 +95,15 @@ handlerton tina_hton= {
*****************************************************************************/ *****************************************************************************/
/* /*
Used for sorting chains. Used for sorting chains with qsort().
*/ */
int sort_set (tina_set *a, tina_set *b) int sort_set (tina_set *a, tina_set *b)
{ {
return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) ); /*
We assume that intervals do not intersect. So, it is enought to compare
any two points. Here we take start of intervals for comparison.
*/
return ( a->begin > b->begin ? -1 : ( a->begin < b->begin ? 1 : 0 ) );
} }
static byte* tina_get_key(TINA_SHARE *share,uint *length, static byte* tina_get_key(TINA_SHARE *share,uint *length,
@ -200,7 +204,8 @@ static TINA_SHARE *get_share(const char *table_name, TABLE *table)
thr_lock_init(&share->lock); thr_lock_init(&share->lock);
pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST); pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
if ((share->data_file= my_open(data_file_name, O_RDWR, MYF(0))) == -1) if ((share->data_file= my_open(data_file_name, O_RDWR|O_APPEND,
MYF(0))) == -1)
goto error2; goto error2;
/* /*
@ -836,14 +841,8 @@ int ha_tina::rnd_end()
(qsort_cmp)sort_set); (qsort_cmp)sort_set);
for (ptr= chain; ptr < chain_ptr; ptr++) for (ptr= chain; ptr < chain_ptr; ptr++)
{ {
/* We peek a head to see if this is the last chain */
if (ptr+1 == chain_ptr)
memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end, memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end,
length - (size_t)ptr->end); length - (size_t)ptr->end);
else
memmove((caddr_t)share->mapped_file + ptr->begin,
(caddr_t)share->mapped_file + ptr->end,
(size_t)((ptr++)->begin - ptr->end));
length= length - (size_t)(ptr->end - ptr->begin); length= length - (size_t)(ptr->end - ptr->begin);
} }

View File

@ -6224,9 +6224,16 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table)
This is done to ensure that ALTER TABLE will convert old VARCHAR fields This is done to ensure that ALTER TABLE will convert old VARCHAR fields
to now VARCHAR fields. to now VARCHAR fields.
*/ */
return new Field_varstring(field_length, maybe_null(), Field *new_field= new Field_varstring(field_length, maybe_null(),
field_name, new_table, field_name, new_table,
charset()); charset());
/*
delayed_insert::get_local_table() needs a ptr copied from old table.
This is what other new_field() methods do too. The above method of
Field_varstring sets ptr to NULL.
*/
new_field->ptr= ptr;
return new_field;
} }
/**************************************************************************** /****************************************************************************
@ -7986,7 +7993,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
{ {
int delta; int delta;
for (; !*from && length; from++, length--); // skip left 0's for (; length && !*from; from++, length--); // skip left 0's
delta= field_length - length; delta= field_length - length;
if (delta < -1 || if (delta < -1 ||
@ -8235,7 +8242,7 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
int delta; int delta;
uchar bits= create_length & 7; uchar bits= create_length & 7;
for (; !*from && length; from++, length--); // skip left 0's for (; length && !*from; from++, length--); // skip left 0's
delta= field_length - length; delta= field_length - length;
if (delta < 0 || if (delta < 0 ||

View File

@ -3031,7 +3031,7 @@ ha_innobase::store_key_val_for_row(
if (key_part->length > 0 && cs->mbmaxlen > 1) { if (key_part->length > 0 && cs->mbmaxlen > 1) {
len = (ulint) cs->cset->well_formed_len(cs, len = (ulint) cs->cset->well_formed_len(cs,
(const char *) src_start, (const char *) src_start,
(const char*)(src_start + key_part->length), (const char *) src_start + key_part->length,
key_part->length / cs->mbmaxlen, key_part->length / cs->mbmaxlen,
&error); &error);
} else { } else {

View File

@ -42,6 +42,7 @@
#define HA_ADMIN_REJECT -6 #define HA_ADMIN_REJECT -6
#define HA_ADMIN_TRY_ALTER -7 #define HA_ADMIN_TRY_ALTER -7
#define HA_ADMIN_WRONG_CHECKSUM -8 #define HA_ADMIN_WRONG_CHECKSUM -8
#define HA_ADMIN_NOT_BASE_TABLE -9
/* Bits in table_flags() to show what database can do */ /* Bits in table_flags() to show what database can do */
@ -431,10 +432,11 @@ struct show_table_alias_st {
/* Possible flags of a handlerton */ /* Possible flags of a handlerton */
#define HTON_NO_FLAGS 0 #define HTON_NO_FLAGS 0
#define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0) #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
#define HTON_ALTER_NOT_SUPPORTED (1 << 1) #define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
#define HTON_CAN_RECREATE (1 << 2) #define HTON_CAN_RECREATE (1 << 2) //Delete all is used fro truncate
#define HTON_FLUSH_AFTER_RENAME (1 << 3) #define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
#define HTON_NOT_USER_SELECTABLE (1 << 4) #define HTON_FLUSH_AFTER_RENAME (1 << 4)
#define HTON_NOT_USER_SELECTABLE (1 << 5)
typedef struct st_thd_trans typedef struct st_thd_trans
{ {

View File

@ -4943,8 +4943,7 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
} }
/* /*
Compare view field's name with item's name before call to referenced Compare two view column references for equality.
item's eq()
SYNOPSIS SYNOPSIS
Item_direct_view_ref::eq() Item_direct_view_ref::eq()
@ -4952,12 +4951,13 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
binary_cmp make binary comparison binary_cmp make binary comparison
DESCRIPTION DESCRIPTION
Consider queries: A view column reference is considered equal to another column
create view v1 as select t1.f1 as f2, t1.f2 as f1 from t1; reference if the second one is a view column and if both column
select * from v1 order by f1; references point to the same field. For views 'same field' means
In order to choose right field for sorting we need to compare the same Item_field object in the view translation table, where
given item's name (f1) to view field's name prior to calling the view translation table contains all result columns of the
referenced item's eq(). view. This definition ensures that view columns are resolved
in the same manner as table columns.
RETURN RETURN
TRUE Referenced item is equal to given item TRUE Referenced item is equal to given item
@ -4967,9 +4967,18 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
{ {
Item *it= ((Item *) item)->real_item(); if (item->type() == REF_ITEM)
return (!it->name || !my_strcasecmp(system_charset_info, it->name, {
field_name)) && ref && (*ref)->real_item()->eq(it, binary_cmp); Item_ref *item_ref= (Item_ref*) item;
if (item_ref->ref_type() == VIEW_REF)
{
Item *item_ref_ref= *(item_ref->ref);
DBUG_ASSERT((*ref)->type() == FIELD_ITEM &&
(item_ref_ref->type() == FIELD_ITEM));
return (*ref == item_ref_ref);
}
}
return FALSE;
} }
void Item_null_helper::print(String *str) void Item_null_helper::print(String *str)

View File

@ -4775,12 +4775,6 @@ Item_func_sp::execute(Item **itp)
res= m_sp->execute_function(thd, args, arg_count, itp); res= m_sp->execute_function(thd, args, arg_count, itp);
thd->restore_sub_statement_state(&statement_state); thd->restore_sub_statement_state(&statement_state);
if (res && mysql_bin_log.is_open() &&
(m_sp->m_chistics->daccess == SP_CONTAINS_SQL ||
m_sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_FAILED_ROUTINE_BREAK_BINLOG,
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
sp_restore_security_context(thd, save_ctx_func); sp_restore_security_context(thd, save_ctx_func);
error: error:
@ -4894,7 +4888,7 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
/* /*
Find the function and chack access rigths to the function Find the function and check access rights to the function
SYNOPSIS SYNOPSIS
find_and_check_access() find_and_check_access()

View File

@ -1129,7 +1129,6 @@ class user_var_entry;
class Item_func_set_user_var :public Item_func class Item_func_set_user_var :public Item_func
{ {
enum Item_result cached_result_type; enum Item_result cached_result_type;
LEX_STRING name;
user_var_entry *entry; user_var_entry *entry;
char buffer[MAX_FIELD_WIDTH]; char buffer[MAX_FIELD_WIDTH];
String value; String value;
@ -1146,6 +1145,7 @@ class Item_func_set_user_var :public Item_func
public: public:
LEX_STRING name; // keep it public
Item_func_set_user_var(LEX_STRING a,Item *b) Item_func_set_user_var(LEX_STRING a,Item *b)
:Item_func(b), cached_result_type(INT_RESULT), name(a) :Item_func(b), cached_result_type(INT_RESULT), name(a)
{} {}
@ -1168,10 +1168,10 @@ public:
class Item_func_get_user_var :public Item_func class Item_func_get_user_var :public Item_func
{ {
LEX_STRING name;
user_var_entry *var_entry; user_var_entry *var_entry;
public: public:
LEX_STRING name; // keep it public
Item_func_get_user_var(LEX_STRING a): Item_func_get_user_var(LEX_STRING a):
Item_func(), name(a) {} Item_func(), name(a) {}
enum Functype functype() const { return GUSERVAR_FUNC; } enum Functype functype() const { return GUSERVAR_FUNC; }

View File

@ -651,8 +651,8 @@ public:
class Item_func_conv_charset :public Item_str_func class Item_func_conv_charset :public Item_str_func
{ {
CHARSET_INFO *conv_charset;
public: public:
CHARSET_INFO *conv_charset; // keep it public
Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a)
{ conv_charset=cs; } { conv_charset=cs; }
String *val_str(String *); String *val_str(String *);

View File

@ -641,12 +641,12 @@ enum interval_type
class Item_date_add_interval :public Item_date_func class Item_date_add_interval :public Item_date_func
{ {
const interval_type int_type;
String value; String value;
const bool date_sub_interval;
enum_field_types cached_field_type; enum_field_types cached_field_type;
public: public:
const interval_type int_type; // keep it public
const bool date_sub_interval; // keep it public
Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg) Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg)
:Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {} :Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
String *val_str(String *); String *val_str(String *);
@ -662,10 +662,10 @@ public:
class Item_extract :public Item_int_func class Item_extract :public Item_int_func
{ {
const interval_type int_type;
String value; String value;
bool date_value; bool date_value;
public: public:
const interval_type int_type; // keep it public
Item_extract(interval_type type_arg, Item *a) Item_extract(interval_type type_arg, Item *a)
:Item_int_func(a), int_type(type_arg) {} :Item_int_func(a), int_type(type_arg) {}
longlong val_int(); longlong val_int();
@ -910,8 +910,8 @@ enum date_time_format
class Item_func_get_format :public Item_str_func class Item_func_get_format :public Item_str_func
{ {
const timestamp_type type;
public: public:
const timestamp_type type; // keep it public
Item_func_get_format(timestamp_type type_arg, Item *a) Item_func_get_format(timestamp_type type_arg, Item *a)
:Item_str_func(a), type(type_arg) :Item_str_func(a), type(type_arg)
{} {}

View File

@ -77,7 +77,7 @@ handlerton binlog_hton = {
NULL, /* Flush logs */ NULL, /* Flush logs */
NULL, /* Show status */ NULL, /* Show status */
NULL, /* Replication Report Sent Binlog */ NULL, /* Replication Report Sent Binlog */
HTON_NOT_USER_SELECTABLE HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
}; };
@ -368,8 +368,7 @@ static int find_uniq_filename(char *name)
MYSQL_LOG::MYSQL_LOG() MYSQL_LOG::MYSQL_LOG()
:bytes_written(0), last_time(0), query_start(0), name(0), :bytes_written(0), last_time(0), query_start(0), name(0),
prepared_xids(0), log_type(LOG_CLOSED), file_id(1), open_count(1), prepared_xids(0), log_type(LOG_CLOSED), file_id(1), open_count(1),
readers_count(0), reset_pending(FALSE), write_error(FALSE), inited(FALSE), write_error(FALSE), inited(FALSE), need_start_event(TRUE),
need_start_event(TRUE),
description_event_for_exec(0), description_event_for_queue(0) description_event_for_exec(0), description_event_for_queue(0)
{ {
/* /*
@ -396,9 +395,7 @@ void MYSQL_LOG::cleanup()
delete description_event_for_exec; delete description_event_for_exec;
(void) pthread_mutex_destroy(&LOCK_log); (void) pthread_mutex_destroy(&LOCK_log);
(void) pthread_mutex_destroy(&LOCK_index); (void) pthread_mutex_destroy(&LOCK_index);
(void) pthread_mutex_destroy(&LOCK_readers);
(void) pthread_cond_destroy(&update_cond); (void) pthread_cond_destroy(&update_cond);
(void) pthread_cond_destroy(&reset_cond);
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -443,9 +440,7 @@ void MYSQL_LOG::init_pthread_objects()
inited= 1; inited= 1;
(void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_readers, MY_MUTEX_INIT_SLOW);
(void) pthread_cond_init(&update_cond, 0); (void) pthread_cond_init(&update_cond, 0);
(void) pthread_cond_init(&reset_cond, 0);
} }
const char *MYSQL_LOG::generate_name(const char *log_name, const char *MYSQL_LOG::generate_name(const char *log_name,
@ -949,12 +944,6 @@ bool MYSQL_LOG::reset_logs(THD* thd)
pthread_mutex_lock(&LOCK_log); pthread_mutex_lock(&LOCK_log);
pthread_mutex_lock(&LOCK_index); pthread_mutex_lock(&LOCK_index);
/*
we need one more lock to block attempts to open a log while
we are waiting untill all log files will be closed
*/
pthread_mutex_lock(&LOCK_readers);
/* /*
The following mutex is needed to ensure that no threads call The following mutex is needed to ensure that no threads call
'delete thd' as we would then risk missing a 'rollback' from this 'delete thd' as we would then risk missing a 'rollback' from this
@ -977,19 +966,6 @@ bool MYSQL_LOG::reset_logs(THD* thd)
goto err; goto err;
} }
reset_pending= TRUE;
/*
send update signal just in case so that all reader threads waiting
for log update will leave wait condition
*/
signal_update();
/*
if there are active readers wait until all of them will
release opened files
*/
while (readers_count)
pthread_cond_wait(&reset_cond, &LOCK_log);
for (;;) for (;;)
{ {
my_delete(linfo.log_file_name, MYF(MY_WME)); my_delete(linfo.log_file_name, MYF(MY_WME));
@ -1008,10 +984,7 @@ bool MYSQL_LOG::reset_logs(THD* thd)
my_free((gptr) save_name, MYF(0)); my_free((gptr) save_name, MYF(0));
err: err:
reset_pending= FALSE;
(void) pthread_mutex_unlock(&LOCK_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count);
pthread_mutex_unlock(&LOCK_readers);
pthread_mutex_unlock(&LOCK_index); pthread_mutex_unlock(&LOCK_index);
pthread_mutex_unlock(&LOCK_log); pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(error); DBUG_RETURN(error);
@ -2086,12 +2059,6 @@ void MYSQL_LOG::wait_for_update(THD* thd, bool is_slave)
const char *old_msg; const char *old_msg;
DBUG_ENTER("wait_for_update"); DBUG_ENTER("wait_for_update");
if (reset_pending)
{
pthread_mutex_unlock(&LOCK_log);
DBUG_VOID_RETURN;
}
old_msg= thd->enter_cond(&update_cond, &LOCK_log, old_msg= thd->enter_cond(&update_cond, &LOCK_log,
is_slave ? is_slave ?
"Has read all relay log; waiting for the slave I/O " "Has read all relay log; waiting for the slave I/O "
@ -2342,33 +2309,6 @@ void MYSQL_LOG::signal_update()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
void MYSQL_LOG::readers_addref()
{
/*
There is no necessity for reference counting on *nix, since it allows to
delete opened files, however it is more clean way to wait
untill all files will be closed on *nix as well.
*/
DBUG_ENTER("MYSQL_LOG::reader_addref");
pthread_mutex_lock(&LOCK_log);
pthread_mutex_lock(&LOCK_readers);
readers_count++;
pthread_mutex_unlock(&LOCK_readers);
pthread_mutex_unlock(&LOCK_log);
DBUG_VOID_RETURN;
}
void MYSQL_LOG::readers_release()
{
DBUG_ENTER("MYSQL_LOG::reader_release");
pthread_mutex_lock(&LOCK_log);
readers_count--;
if (!readers_count)
pthread_cond_broadcast(&reset_cond);
pthread_mutex_unlock(&LOCK_log);
DBUG_VOID_RETURN;
}
#ifdef __NT__ #ifdef __NT__
void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
uint length, int buffLen) uint length, int buffLen)

View File

@ -44,6 +44,12 @@
typedef ulonglong table_map; /* Used for table bits in join */ typedef ulonglong table_map; /* Used for table bits in join */
typedef Bitmap<64> key_map; /* Used for finding keys */ typedef Bitmap<64> key_map; /* Used for finding keys */
typedef ulong key_part_map; /* Used for finding key parts */ typedef ulong key_part_map; /* Used for finding key parts */
/*
Used to identify NESTED_JOIN structures within a join (applicable only to
structures that have not been simplified away and embed more the one
element)
*/
typedef ulonglong nested_join_map;
/* query_id */ /* query_id */
typedef ulonglong query_id_t; typedef ulonglong query_id_t;
@ -519,8 +525,9 @@ bool delete_precheck(THD *thd, TABLE_LIST *tables);
bool insert_precheck(THD *thd, TABLE_LIST *tables); bool insert_precheck(THD *thd, TABLE_LIST *tables);
bool create_table_precheck(THD *thd, TABLE_LIST *tables, bool create_table_precheck(THD *thd, TABLE_LIST *tables,
TABLE_LIST *create_table); TABLE_LIST *create_table);
bool default_view_definer(Security_context *sctx, st_lex_user *definer);
bool get_default_definer(THD *thd, LEX_USER *definer);
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
enum enum_mysql_completiontype { enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7, ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
@ -863,6 +870,10 @@ bool mysqld_show_column_types(THD *thd);
bool mysqld_help (THD *thd, const char *text); bool mysqld_help (THD *thd, const char *text);
void calc_sum_of_all_status(STATUS_VAR *to); void calc_sum_of_all_status(STATUS_VAR *to);
void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
const LEX_STRING *definer_host);
/* information schema */ /* information schema */
extern LEX_STRING information_schema_name; extern LEX_STRING information_schema_name;
LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str, LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
@ -1199,7 +1210,7 @@ extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
extern my_bool opt_secure_auth; extern my_bool opt_secure_auth;
extern my_bool opt_log_slow_admin_statements; extern my_bool opt_log_slow_admin_statements;
extern my_bool sp_automatic_privileges, opt_noacl; extern my_bool sp_automatic_privileges, opt_noacl;
extern my_bool opt_old_style_user_limits, trust_routine_creators; extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb; extern uint opt_crash_binlog_innodb;
extern char *shared_memory_base_name, *mysqld_unix_port; extern char *shared_memory_base_name, *mysqld_unix_port;
extern my_bool opt_enable_shared_memory; extern my_bool opt_enable_shared_memory;

View File

@ -424,7 +424,7 @@ my_bool opt_log_slow_admin_statements= 0;
my_bool lower_case_file_system= 0; my_bool lower_case_file_system= 0;
my_bool opt_large_pages= 0; my_bool opt_large_pages= 0;
uint opt_large_page_size= 0; uint opt_large_page_size= 0;
my_bool opt_old_style_user_limits= 0, trust_routine_creators= 0; my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
/* /*
True if there is at least one per-hour limit for some user, so we should True if there is at least one per-hour limit for some user, so we should
check them before each query (and possibly reset counters when hour is check them before each query (and possibly reset counters when hour is
@ -615,7 +615,7 @@ bool mysqld_embedded=1;
static const char* default_dbug_option; static const char* default_dbug_option;
#endif #endif
#ifdef HAVE_LIBWRAP #ifdef HAVE_LIBWRAP
char *libwrapName= NULL; const char *libwrapName= NULL;
#endif #endif
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
static ulong query_cache_limit= 0; static ulong query_cache_limit= 0;
@ -4501,7 +4501,7 @@ enum options_mysqld
OPT_INNODB_FAST_SHUTDOWN, OPT_INNODB_FAST_SHUTDOWN,
OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB, OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB,
OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG, OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
OPT_LOG_BIN_TRUST_ROUTINE_CREATORS, OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG, OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG,
OPT_INNODB, OPT_ISAM, OPT_INNODB, OPT_ISAM,
OPT_ENGINE_CONDITION_PUSHDOWN, OPT_ENGINE_CONDITION_PUSHDOWN,
@ -4933,16 +4933,27 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
"File that holds the names for last binary log files.", "File that holds the names for last binary log files.",
(gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR, (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifndef TO_BE_REMOVED_IN_5_1_OR_6_0
/*
In 5.0.6 we introduced the below option, then in 5.0.16 we renamed it to
log-bin-trust-function-creators but kept also the old name for
compatibility; the behaviour was also changed to apply only to functions
(and triggers). In a future release this old name could be removed.
*/
{"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
"(deprecated) Use log-bin-trust-function-creators.",
(gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
/* /*
This option starts with "log-bin" to emphasize that it is specific of This option starts with "log-bin" to emphasize that it is specific of
binary logging. Hopefully in 5.1 nobody will need it anymore, when we have binary logging.
row-level binlog.
*/ */
{"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_ROUTINE_CREATORS, {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
"If equal to 0 (the default), then when --log-bin is used, creation of " "If equal to 0 (the default), then when --log-bin is used, creation of "
"a routine is allowed only to users having the SUPER privilege and only" "a function is allowed only to users having the SUPER privilege and only "
"if this routine may not break binary logging", "if this function may not break binary logging.",
(gptr*) &trust_routine_creators, (gptr*) &trust_routine_creators, 0, (gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-error", OPT_ERROR_LOG_FILE, "Error log file.", {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
(gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR, (gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR,
@ -5840,7 +5851,7 @@ The minimum value for this variable is 4096.",
(gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG, (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0}, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
{"read_only", OPT_READONLY, {"read_only", OPT_READONLY,
"Make all tables readonly, with the exception for replication (slave) threads and users with the SUPER privilege", "Make all non-temporary tables read-only, with the exception for replication (slave) threads and users with the SUPER privilege",
(gptr*) &opt_readonly, (gptr*) &opt_readonly,
(gptr*) &opt_readonly, (gptr*) &opt_readonly,
0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0}, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},

View File

@ -5764,10 +5764,17 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
MEM_ROOT *old_root= thd->mem_root; MEM_ROOT *old_root= thd->mem_root;
/* The following call may change thd->mem_root */ /* The following call may change thd->mem_root */
QUICK_RANGE_SELECT *quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0); QUICK_RANGE_SELECT *quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0);
/* save mem_root set by QUICK_RANGE_SELECT constructor */
MEM_ROOT *alloc= thd->mem_root;
KEY *key_info = &table->key_info[ref->key]; KEY *key_info = &table->key_info[ref->key];
KEY_PART *key_part; KEY_PART *key_part;
QUICK_RANGE *range; QUICK_RANGE *range;
uint part; uint part;
/*
return back default mem_root (thd->mem_root) changed by
QUICK_RANGE_SELECT constructor
*/
thd->mem_root= old_root;
if (!quick) if (!quick)
return 0; /* no ranges found */ return 0; /* no ranges found */
@ -5779,7 +5786,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
quick->records= records; quick->records= records;
if (cp_buffer_from_ref(thd,ref) && thd->is_fatal_error || if (cp_buffer_from_ref(thd,ref) && thd->is_fatal_error ||
!(range= new QUICK_RANGE())) !(range= new(alloc) QUICK_RANGE()))
goto err; // out of memory goto err; // out of memory
range->min_key=range->max_key=(char*) ref->key_buff; range->min_key=range->max_key=(char*) ref->key_buff;
@ -5814,8 +5821,10 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
QUICK_RANGE *null_range; QUICK_RANGE *null_range;
*ref->null_ref_key= 1; // Set null byte then create a range *ref->null_ref_key= 1; // Set null byte then create a range
if (!(null_range= new QUICK_RANGE((char*)ref->key_buff, ref->key_length, if (!(null_range= new (alloc) QUICK_RANGE((char*)ref->key_buff,
(char*)ref->key_buff, ref->key_length, ref->key_length,
(char*)ref->key_buff,
ref->key_length,
EQ_RANGE))) EQ_RANGE)))
goto err; goto err;
*ref->null_ref_key= 0; // Clear null byte *ref->null_ref_key= 0; // Clear null byte
@ -5823,11 +5832,9 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
goto err; goto err;
} }
thd->mem_root= old_root;
return quick; return quick;
err: err:
thd->mem_root= old_root;
delete quick; delete quick;
return 0; return 0;
} }

View File

@ -237,9 +237,12 @@ sys_var_key_cache_long sys_key_cache_age_threshold("key_cache_age_threshold",
param_age_threshold)); param_age_threshold));
sys_var_bool_ptr sys_local_infile("local_infile", sys_var_bool_ptr sys_local_infile("local_infile",
&opt_local_infile); &opt_local_infile);
sys_var_bool_ptr sys_var_trust_routine_creators
sys_trust_routine_creators("log_bin_trust_routine_creators", sys_trust_routine_creators("log_bin_trust_routine_creators",
&trust_routine_creators); &trust_function_creators);
sys_var_bool_ptr
sys_trust_function_creators("log_bin_trust_function_creators",
&trust_function_creators);
sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings); sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings);
sys_var_thd_ulong sys_long_query_time("long_query_time", sys_var_thd_ulong sys_long_query_time("long_query_time",
&SV::long_query_time); &SV::long_query_time);
@ -585,7 +588,6 @@ sys_var_thd_time_zone sys_time_zone("time_zone");
/* Read only variables */ /* Read only variables */
sys_var_const_str sys_os("version_compile_os", SYSTEM_TYPE); sys_var_const_str sys_os("version_compile_os", SYSTEM_TYPE);
sys_var_have_variable sys_have_archive_db("have_archive", &have_archive_db); sys_var_have_variable sys_have_archive_db("have_archive", &have_archive_db);
sys_var_have_variable sys_have_berkeley_db("have_bdb", &have_berkeley_db); sys_var_have_variable sys_have_berkeley_db("have_bdb", &have_berkeley_db);
sys_var_have_variable sys_have_blackhole_db("have_blackhole_engine", sys_var_have_variable sys_have_blackhole_db("have_blackhole_engine",
@ -609,7 +611,6 @@ sys_var_have_variable sys_have_query_cache("have_query_cache",
sys_var_have_variable sys_have_raid("have_raid", &have_raid); sys_var_have_variable sys_have_raid("have_raid", &have_raid);
sys_var_have_variable sys_have_rtree_keys("have_rtree_keys", &have_rtree_keys); sys_var_have_variable sys_have_rtree_keys("have_rtree_keys", &have_rtree_keys);
sys_var_have_variable sys_have_symlink("have_symlink", &have_symlink); sys_var_have_variable sys_have_symlink("have_symlink", &have_symlink);
/* Global read-only variable describing server license */ /* Global read-only variable describing server license */
sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE)); sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE));
@ -742,7 +743,7 @@ struct show_var_st init_vars[]= {
#endif #endif
{"log", (char*) &opt_log, SHOW_BOOL}, {"log", (char*) &opt_log, SHOW_BOOL},
{"log_bin", (char*) &opt_bin_log, SHOW_BOOL}, {"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
{sys_trust_routine_creators.name,(char*) &sys_trust_routine_creators, SHOW_SYS}, {sys_trust_function_creators.name,(char*) &sys_trust_function_creators, SHOW_SYS},
{"log_error", (char*) log_error_file, SHOW_CHAR}, {"log_error", (char*) log_error_file, SHOW_CHAR},
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
{"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL}, {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL},
@ -3332,6 +3333,26 @@ bool process_key_caches(int (* func) (const char *name, KEY_CACHE *))
} }
void sys_var_trust_routine_creators::warn_deprecated(THD *thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX,
ER(ER_WARN_DEPRECATED_SYNTAX), "log_bin_trust_routine_creators",
"log_bin_trust_function_creators");
}
void sys_var_trust_routine_creators::set_default(THD *thd, enum_var_type type)
{
warn_deprecated(thd);
sys_var_bool_ptr::set_default(thd, type);
}
bool sys_var_trust_routine_creators::update(THD *thd, set_var *var)
{
warn_deprecated(thd);
return sys_var_bool_ptr::update(thd, var);
}
/**************************************************************************** /****************************************************************************
Used templates Used templates
****************************************************************************/ ****************************************************************************/

View File

@ -771,6 +771,17 @@ public:
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
}; };
class sys_var_trust_routine_creators :public sys_var_bool_ptr
{
/* We need a derived class only to have a warn_deprecated() */
public:
sys_var_trust_routine_creators(const char *name_arg, my_bool *value_arg) :
sys_var_bool_ptr(name_arg, value_arg) {};
void warn_deprecated(THD *thd);
void set_default(THD *thd, enum_var_type type);
bool update(THD *thd, set_var *var);
};
/**************************************************************************** /****************************************************************************
Classes for parsing of the SET command Classes for parsing of the SET command
****************************************************************************/ ****************************************************************************/

View File

@ -441,8 +441,8 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
if (dbchanged && (ret= mysql_change_db(thd, olddb, 1))) if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
goto done; goto done;
*sphp= thd->lex->sphead; *sphp= thd->lex->sphead;
(*sphp)->set_info((char *)definer, (uint)strlen(definer), (*sphp)->set_definer((char*) definer, (uint) strlen(definer));
created, modified, &chistics, sql_mode); (*sphp)->set_info(created, modified, &chistics, sql_mode);
(*sphp)->optimize(); (*sphp)->optimize();
} }
thd->lex->sql_command= oldcmd; thd->lex->sql_command= oldcmd;
@ -551,12 +551,13 @@ db_create_routine(THD *thd, int type, sp_head *sp)
store(sp->m_chistics->comment.str, sp->m_chistics->comment.length, store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
system_charset_info); system_charset_info);
if (!trust_routine_creators && mysql_bin_log.is_open()) if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
!trust_function_creators && mysql_bin_log.is_open())
{ {
if (!sp->m_chistics->detistic) if (!sp->m_chistics->detistic)
{ {
/* /*
Note that for a _function_ this test is not enough; one could use Note that this test is not perfect; one could use
a non-deterministic read-only function in an update statement. a non-deterministic read-only function in an update statement.
*/ */
enum enum_sp_data_access access= enum enum_sp_data_access access=

View File

@ -1569,21 +1569,9 @@ sp_head::check_backpatch(THD *thd)
} }
void void
sp_head::set_info(char *definer, uint definerlen, sp_head::set_info(longlong created, longlong modified,
longlong created, longlong modified,
st_sp_chistics *chistics, ulong sql_mode) st_sp_chistics *chistics, ulong sql_mode)
{ {
char *p= strchr(definer, '@');
uint len;
if (! p)
p= definer; // Weird...
len= p-definer;
m_definer_user.str= strmake_root(mem_root, definer, len);
m_definer_user.length= len;
len= definerlen-len-1;
m_definer_host.str= strmake_root(mem_root, p+1, len);
m_definer_host.length= len;
m_created= created; m_created= created;
m_modified= modified; m_modified= modified;
m_chistics= (st_sp_chistics *) memdup_root(mem_root, (char*) chistics, m_chistics= (st_sp_chistics *) memdup_root(mem_root, (char*) chistics,
@ -1597,6 +1585,34 @@ sp_head::set_info(char *definer, uint definerlen,
m_sql_mode= sql_mode; m_sql_mode= sql_mode;
} }
void
sp_head::set_definer(char *definer, uint definerlen)
{
char *p= strrchr(definer, '@');
if (!p)
{
m_definer_user.str= strmake_root(mem_root, "", 0);
m_definer_user.length= 0;
m_definer_host.str= strmake_root(mem_root, "", 0);
m_definer_host.length= 0;
}
else
{
const uint user_name_len= p - definer;
const uint host_name_len= definerlen - user_name_len - 1;
m_definer_user.str= strmake_root(mem_root, definer, user_name_len);
m_definer_user.length= user_name_len;
m_definer_host.str= strmake_root(mem_root, p + 1, host_name_len);
m_definer_host.length= host_name_len;
}
}
void void
sp_head::reset_thd_mem_root(THD *thd) sp_head::reset_thd_mem_root(THD *thd)
{ {

View File

@ -251,10 +251,11 @@ public:
Field *make_field(uint max_length, const char *name, TABLE *dummy); Field *make_field(uint max_length, const char *name, TABLE *dummy);
void set_info(char *definer, uint definerlen, void set_info(longlong created, longlong modified,
longlong created, longlong modified,
st_sp_chistics *chistics, ulong sql_mode); st_sp_chistics *chistics, ulong sql_mode);
void set_definer(char *definer, uint definerlen);
void reset_thd_mem_root(THD *thd); void reset_thd_mem_root(THD *thd);
void restore_thd_mem_root(THD *thd); void restore_thd_mem_root(THD *thd);

View File

@ -178,7 +178,9 @@ static double wkb_get_double(const char *ptr, Geometry::wkbByteOrder bo)
{ {
double res; double res;
if (bo != Geometry::wkb_xdr) if (bo != Geometry::wkb_xdr)
{
float8get(res, ptr); float8get(res, ptr);
}
else else
{ {
char inv_array[8]; char inv_array[8];

View File

@ -3532,7 +3532,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
of other queries). For simple queries first_not_own_table is 0. of other queries). For simple queries first_not_own_table is 0.
*/ */
for (i= 0, table= tables; for (i= 0, table= tables;
table != first_not_own_table && i < number; table && table != first_not_own_table && i < number;
table= table->next_global, i++) table= table->next_global, i++)
{ {
/* Remove SHOW_VIEW_ACL, because it will be checked during making view */ /* Remove SHOW_VIEW_ACL, because it will be checked during making view */

View File

@ -189,11 +189,10 @@ class MYSQL_LOG: public TC_LOG
{ {
private: private:
/* LOCK_log and LOCK_index are inited by init_pthread_objects() */ /* LOCK_log and LOCK_index are inited by init_pthread_objects() */
pthread_mutex_t LOCK_log, LOCK_index, LOCK_readers; pthread_mutex_t LOCK_log, LOCK_index;
pthread_mutex_t LOCK_prep_xids; pthread_mutex_t LOCK_prep_xids;
pthread_cond_t COND_prep_xids; pthread_cond_t COND_prep_xids;
pthread_cond_t update_cond; pthread_cond_t update_cond;
pthread_cond_t reset_cond;
ulonglong bytes_written; ulonglong bytes_written;
time_t last_time,query_start; time_t last_time,query_start;
IO_CACHE log_file; IO_CACHE log_file;
@ -335,9 +334,6 @@ public:
int purge_logs_before_date(time_t purge_time); int purge_logs_before_date(time_t purge_time);
int purge_first_log(struct st_relay_log_info* rli, bool included); int purge_first_log(struct st_relay_log_info* rli, bool included);
bool reset_logs(THD* thd); bool reset_logs(THD* thd);
inline bool is_reset_pending() { return reset_pending; }
void readers_addref();
void readers_release();
void close(uint exiting); void close(uint exiting);
// iterating through the log index file // iterating through the log index file

View File

@ -558,6 +558,25 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
result->prepare(item_list, &fake_unit) || result->prepare(item_list, &fake_unit) ||
table->file->ha_rnd_init(TRUE)); table->file->ha_rnd_init(TRUE));
thd->restore_active_arena(this, &backup_arena); thd->restore_active_arena(this, &backup_arena);
if (rc == 0)
{
/*
Now send the result set metadata to the client. We need to
do it here, as in Select_materialize::send_fields the items
for column types are not yet created (send_fields requires
a list of items). The new types may differ from the original
ones sent at prepare if some of them were altered by MySQL
HEAP tables mechanism -- used when create_tmp_field_from_item
may alter the original column type.
We can't simply supply SEND_EOF flag to send_fields, because
send_fields doesn't flush the network buffer.
*/
rc= result->send_fields(item_list, Protocol::SEND_NUM_ROWS);
thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
result->send_eof();
thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
}
return rc; return rc;
} }
@ -647,14 +666,6 @@ bool Select_materialize::send_fields(List<Item> &list, uint flags)
if (create_result_table(unit->thd, unit->get_unit_column_types(), if (create_result_table(unit->thd, unit->get_unit_column_types(),
FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, "")) FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, ""))
return TRUE; return TRUE;
/*
We can't simply supply SEND_EOF flag to send_fields, because send_fields
doesn't flush the network buffer.
*/
rc= result->send_fields(list, Protocol::SEND_NUM_ROWS);
thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
result->send_eof();
thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
return rc; return rc;
} }

View File

@ -1163,8 +1163,17 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
} }
end: end:
x_free(thd->db); x_free(thd->db);
if (dbname && dbname[0] == 0)
{
x_free(dbname);
thd->db= NULL;
thd->db_length= 0;
}
else
{
thd->db= dbname; // THD::~THD will free this thd->db= dbname; // THD::~THD will free this
thd->db_length= db_length; thd->db_length= db_length;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!no_access_check) if (!no_access_check)
sctx->db_access= db_access; sctx->db_access= db_access;

View File

@ -2039,6 +2039,35 @@ void st_lex::cleanup_after_one_table_open()
} }
/*
Do end-of-prepare fixup for list of tables and their merge-VIEWed tables
SYNOPSIS
fix_prepare_info_in_table_list()
thd Thread handle
tbl List of tables to process
DESCRIPTION
Perform end-end-of prepare fixup for list of tables, if any of the tables
is a merge-algorithm VIEW, recursively fix up its underlying tables as
well.
*/
static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
{
for (; tbl; tbl= tbl->next_local)
{
if (tbl->on_expr)
{
tbl->prep_on_expr= tbl->on_expr;
tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
}
fix_prepare_info_in_table_list(thd, tbl->merge_underlying_list);
}
}
/* /*
fix some structures at the end of preparation fix some structures at the end of preparation
@ -2058,16 +2087,7 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds)
prep_where= *conds; prep_where= *conds;
*conds= where= prep_where->copy_andor_structure(thd); *conds= where= prep_where->copy_andor_structure(thd);
} }
for (TABLE_LIST *tbl= (TABLE_LIST *)table_list.first; fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first);
tbl;
tbl= tbl->next_local)
{
if (tbl->on_expr)
{
tbl->prep_on_expr= tbl->on_expr;
tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
}
}
} }
} }

View File

@ -753,12 +753,17 @@ typedef struct st_lex
TABLE_LIST **query_tables_last; TABLE_LIST **query_tables_last;
/* store original leaf_tables for INSERT SELECT and PS/SP */ /* store original leaf_tables for INSERT SELECT and PS/SP */
TABLE_LIST *leaf_tables_insert; TABLE_LIST *leaf_tables_insert;
st_lex_user *create_view_definer;
char *create_view_start; char *create_view_start;
char *create_view_select_start; char *create_view_select_start;
/* Partition info structure filled in by PARTITION BY parse part */ /* Partition info structure filled in by PARTITION BY parse part */
partition_info *part_info; partition_info *part_info;
/*
The definer of the object being created (view, trigger, stored routine).
I.e. the value of DEFINER clause.
*/
LEX_USER *definer;
List<key_part_spec> col_list; List<key_part_spec> col_list;
List<key_part_spec> ref_list; List<key_part_spec> ref_list;
List<String> interval_list; List<String> interval_list;
@ -905,6 +910,14 @@ typedef struct st_lex
*/ */
SQL_LIST trg_table_fields; SQL_LIST trg_table_fields;
/*
trigger_definition_begin points to the beginning of the word "TRIGGER" in
CREATE TRIGGER statement. This is used to add possibly omitted DEFINER
clause to the trigger definition statement before dumping it to the
binlog.
*/
const char *trigger_definition_begin;
/* /*
If non-0 then indicates that query requires prelocking and points to If non-0 then indicates that query requires prelocking and points to
next_global member of last own element in query table list (i.e. last next_global member of last own element in query table list (i.e. last

View File

@ -188,6 +188,18 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
#endif #endif
static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
{
for (TABLE_LIST *table= tables; table; table= table->next_global)
{
DBUG_ASSERT(table->db && table->table_name);
if (table->updating &&
!find_temporary_table(thd, table->db, table->table_name))
return 1;
}
return 0;
}
static HASH hash_user_connections; static HASH hash_user_connections;
static int get_or_create_user_conn(THD *thd, const char *user, static int get_or_create_user_conn(THD *thd, const char *user,
@ -2360,7 +2372,7 @@ mysql_execute_command(THD *thd)
mysql_reset_errors(thd, 0); mysql_reset_errors(thd, 0);
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
if (thd->slave_thread) if (unlikely(thd->slave_thread))
{ {
/* /*
Check if statment should be skipped because of slave filtering Check if statment should be skipped because of slave filtering
@ -2399,16 +2411,20 @@ mysql_execute_command(THD *thd)
} }
#endif #endif
} }
else
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
/* /*
When option readonly is set deny operations which change tables. When option readonly is set deny operations which change non-temporary
Except for the replication thread and the 'super' users. tables. Except for the replication thread and the 'super' users.
*/ */
if (opt_readonly && if (opt_readonly &&
!(thd->slave_thread || !(thd->security_ctx->master_access & SUPER_ACL) &&
(thd->security_ctx->master_access & SUPER_ACL)) && uc_update_queries[lex->sql_command] &&
uc_update_queries[lex->sql_command]) !((lex->sql_command == SQLCOM_CREATE_TABLE) &&
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
some_non_temp_table_to_be_updated(thd, all_tables)))
{ {
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
DBUG_RETURN(-1); DBUG_RETURN(-1);
@ -3198,13 +3214,24 @@ end_with_restore_list:
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
/* Check slave filtering rules */ /* Check slave filtering rules */
if (thd->slave_thread && all_tables_not_ok(thd, all_tables)) if (unlikely(thd->slave_thread))
{
if (all_tables_not_ok(thd, all_tables))
{ {
/* we warn the slave SQL thread */ /* we warn the slave SQL thread */
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
break; break;
} }
}
else
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
if (opt_readonly &&
!(thd->security_ctx->master_access & SUPER_ACL) &&
some_non_temp_table_to_be_updated(thd, all_tables))
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
break;
}
res= mysql_multi_update(thd, all_tables, res= mysql_multi_update(thd, all_tables,
&select_lex->item_list, &select_lex->item_list,
@ -4280,18 +4307,6 @@ end_with_restore_list:
So just execute the statement. So just execute the statement.
*/ */
res= sp->execute_procedure(thd, &lex->value_list); res= sp->execute_procedure(thd, &lex->value_list);
if (mysql_bin_log.is_open() &&
(sp->m_chistics->daccess == SP_CONTAINS_SQL ||
sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
{
if (res)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_FAILED_ROUTINE_BREAK_BINLOG,
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
else
thd->clear_error();
}
/* /*
If warnings have been cleared, we have to clear total_warn_count If warnings have been cleared, we have to clear total_warn_count
too, otherwise the clients get confused. too, otherwise the clients get confused.
@ -4350,7 +4365,8 @@ end_with_restore_list:
if (end_active_trans(thd)) if (end_active_trans(thd))
goto error; goto error;
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics)); memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
if (!trust_routine_creators && mysql_bin_log.is_open() && if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
!trust_function_creators && mysql_bin_log.is_open() &&
!sp->m_chistics->detistic && !sp->m_chistics->detistic &&
(chistics.daccess == SP_CONTAINS_SQL || (chistics.daccess == SP_CONTAINS_SQL ||
chistics.daccess == SP_MODIFIES_SQL_DATA)) chistics.daccess == SP_MODIFIES_SQL_DATA))
@ -4361,6 +4377,12 @@ end_with_restore_list:
} }
else else
{ {
/*
Note that if you implement the capability of ALTER FUNCTION to
alter the body of the function, this command should be made to
follow the restrictions that log-bin-trust-function-creators=0
already puts on CREATE FUNCTION.
*/
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics); result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
else else
@ -5033,7 +5055,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
the given table list refers to the list for prelocking (contains tables the given table list refers to the list for prelocking (contains tables
of other queries). For simple queries first_not_own_table is 0. of other queries). For simple queries first_not_own_table is 0.
*/ */
for (; tables != first_not_own_table; tables= tables->next_global) for (; tables && tables != first_not_own_table; tables= tables->next_global)
{ {
if (tables->schema_table && if (tables->schema_table &&
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL))) (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
@ -7437,32 +7459,81 @@ Item *negate_expression(THD *thd, Item *expr)
return new Item_func_not(expr); return new Item_func_not(expr);
} }
/* /*
Assign as view definer current user Set the specified definer to the default value, which is the current user in
the thread. Also check that the current user satisfies to the definers
requirements.
SYNOPSIS SYNOPSIS
default_view_definer() get_default_definer()
sctx current security context thd [in] thread handler
definer structure where it should be assigned definer [out] definer
RETURN RETURN
FALSE OK error status, that is:
TRUE Error - FALSE -- on success;
- TRUE -- on error (current user can not be a definer).
*/ */
bool default_view_definer(Security_context *sctx, st_lex_user *definer) bool get_default_definer(THD *thd, LEX_USER *definer)
{ {
definer->user.str= sctx->priv_user; /* Check that current user has non-empty host name. */
definer->user.length= strlen(sctx->priv_user);
if (!*sctx->priv_host) const Security_context *sctx= thd->security_ctx;
if (sctx->priv_host[0] == 0)
{ {
my_error(ER_NO_VIEW_USER, MYF(0)); my_error(ER_MALFORMED_DEFINER, MYF(0));
return TRUE; return TRUE;
} }
definer->host.str= sctx->priv_host; /* Fill in. */
definer->host.length= strlen(sctx->priv_host);
definer->user.str= (char *) sctx->priv_user;
definer->user.length= strlen(definer->user.str);
definer->host.str= (char *) sctx->priv_host;
definer->host.length= strlen(definer->host.str);
return FALSE; return FALSE;
} }
/*
Create definer with the given user and host names. Also check that the user
and host names satisfy definers requirements.
SYNOPSIS
create_definer()
thd [in] thread handler
user_name [in] user name
host_name [in] host name
RETURN
On success, return a valid pointer to the created and initialized
LEX_STRING, which contains definer information.
On error, return 0.
*/
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
{
LEX_USER *definer;
/* Check that specified host name is valid. */
if (host_name->length == 0)
{
my_error(ER_MALFORMED_DEFINER, MYF(0));
return 0;
}
/* Create and initialize. */
if (! (definer= (LEX_USER*) thd->alloc(sizeof (LEX_USER))))
return 0;
definer->user= *user_name;
definer->host= *host_name;
return definer;
}

View File

@ -2111,8 +2111,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
were closed in the end of previous prepare or execute call. were closed in the end of previous prepare or execute call.
*/ */
tables->table= 0; tables->table= 0;
if (tables->nested_join)
tables->nested_join->counter= 0;
if (tables->prep_on_expr) if (tables->prep_on_expr)
{ {

View File

@ -373,11 +373,6 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
goto err; goto err;
} }
/*
Call readers_addref before opening log to track count
of binlog readers
*/
mysql_bin_log.readers_addref();
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0) if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0)
{ {
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
@ -575,8 +570,7 @@ impossible position";
goto err; goto err;
if (!(flags & BINLOG_DUMP_NON_BLOCK) && if (!(flags & BINLOG_DUMP_NON_BLOCK) &&
mysql_bin_log.is_active(log_file_name) && mysql_bin_log.is_active(log_file_name))
!mysql_bin_log.is_reset_pending())
{ {
/* /*
Block until there is more data in the log Block until there is more data in the log
@ -689,13 +683,7 @@ impossible position";
else else
{ {
bool loop_breaker = 0; bool loop_breaker = 0;
// need this to break out of the for loop from switch /* need this to break out of the for loop from switch */
// if we are going to switch log file anyway, close current log first
end_io_cache(&log);
(void) my_close(file, MYF(MY_WME));
// decrease reference count of binlog readers
mysql_bin_log.readers_release();
thd->proc_info = "Finished reading one binlog; switching to next binlog"; thd->proc_info = "Finished reading one binlog; switching to next binlog";
switch (mysql_bin_log.find_next_log(&linfo, 1)) { switch (mysql_bin_log.find_next_log(&linfo, 1)) {
@ -705,25 +693,16 @@ impossible position";
case 0: case 0:
break; break;
default: default:
// need following call to do release on err label
mysql_bin_log.readers_addref();
errmsg = "could not find next log"; errmsg = "could not find next log";
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err; goto err;
} }
if (loop_breaker) if (loop_breaker)
{
// need following call to do release on end label
mysql_bin_log.readers_addref();
break; break;
}
/* end_io_cache(&log);
Call readers_addref before opening log to track count (void) my_close(file, MYF(MY_WME));
of binlog readers
*/
mysql_bin_log.readers_addref();
/* /*
Call fake_rotate_event() in case the previous log (the one which Call fake_rotate_event() in case the previous log (the one which
@ -756,8 +735,6 @@ end:
end_io_cache(&log); end_io_cache(&log);
(void)my_close(file, MYF(MY_WME)); (void)my_close(file, MYF(MY_WME));
// decrease reference count of binlog readers
mysql_bin_log.readers_release();
send_eof(thd); send_eof(thd);
thd->proc_info = "Waiting to finalize termination"; thd->proc_info = "Waiting to finalize termination";
@ -784,8 +761,6 @@ err:
pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count);
if (file >= 0) if (file >= 0)
(void) my_close(file, MYF(MY_WME)); (void) my_close(file, MYF(MY_WME));
// decrease reference count of binlog readers
mysql_bin_log.readers_release();
my_message(my_errno, errmsg, MYF(0)); my_message(my_errno, errmsg, MYF(0));
DBUG_VOID_RETURN; DBUG_VOID_RETURN;

View File

@ -98,6 +98,12 @@ static COND* substitute_for_best_equal_field(COND *cond,
void *table_join_idx); void *table_join_idx);
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
COND *conds, bool top); COND *conds, bool top);
static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next);
static void restore_prev_nj_state(JOIN_TAB *last);
static void reset_nj_counters(List<TABLE_LIST> *join_list);
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
uint first_unused);
static COND *optimize_cond(JOIN *join, COND *conds, static COND *optimize_cond(JOIN *join, COND *conds,
List<TABLE_LIST> *join_list, List<TABLE_LIST> *join_list,
Item::cond_result *cond_value); Item::cond_result *cond_value);
@ -520,12 +526,14 @@ bool JOIN::test_in_subselect(Item **where)
return 0; return 0;
} }
/* /*
global select optimisation. global select optimisation.
return 0 - success return 0 - success
1 - error 1 - error
error code saved in field 'error' error code saved in field 'error'
*/ */
int int
JOIN::optimize() JOIN::optimize()
{ {
@ -588,6 +596,7 @@ JOIN::optimize()
/* Convert all outer joins to inner joins if possible */ /* Convert all outer joins to inner joins if possible */
conds= simplify_joins(this, join_list, conds, TRUE); conds= simplify_joins(this, join_list, conds, TRUE);
build_bitmap_for_nested_joins(join_list, 0);
sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0; sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
@ -701,6 +710,7 @@ JOIN::optimize()
DBUG_RETURN(1); DBUG_RETURN(1);
} }
reset_nj_counters(join_list);
make_outerjoin_info(this); make_outerjoin_info(this);
/* /*
@ -1980,14 +1990,19 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
continue; continue;
} }
outer_join|= table->map; outer_join|= table->map;
s->embedding_map= 0;
for (;embedding; embedding= embedding->embedding)
s->embedding_map|= embedding->nested_join->nj_map;
continue; continue;
} }
if (embedding) if (embedding)
{ {
/* s belongs to a nested join, maybe to several embedded joins */ /* s belongs to a nested join, maybe to several embedded joins */
s->embedding_map= 0;
do do
{ {
NESTED_JOIN *nested_join= embedding->nested_join; NESTED_JOIN *nested_join= embedding->nested_join;
s->embedding_map|=nested_join->nj_map;
s->dependent|= embedding->dep_tables; s->dependent|= embedding->dep_tables;
embedding= embedding->embedding; embedding= embedding->embedding;
outer_join|= nested_join->used_tables; outer_join|= nested_join->used_tables;
@ -3561,6 +3576,8 @@ choose_plan(JOIN *join, table_map join_tables)
bool straight_join= join->select_options & SELECT_STRAIGHT_JOIN; bool straight_join= join->select_options & SELECT_STRAIGHT_JOIN;
DBUG_ENTER("choose_plan"); DBUG_ENTER("choose_plan");
join->cur_embedding_map= 0;
reset_nj_counters(join->join_list);
/* /*
if (SELECT_STRAIGHT_JOIN option is set) if (SELECT_STRAIGHT_JOIN option is set)
reorder tables so dependent tables come after tables they depend reorder tables so dependent tables come after tables they depend
@ -4041,7 +4058,9 @@ best_extension_by_limited_search(JOIN *join,
for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++) for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
{ {
table_map real_table_bit= s->table->map; table_map real_table_bit= s->table->map;
if ((remaining_tables & real_table_bit) && !(remaining_tables & s->dependent)) if ((remaining_tables & real_table_bit) &&
!(remaining_tables & s->dependent) &&
(!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s)))
{ {
double current_record_count, current_read_time; double current_record_count, current_read_time;
@ -4057,6 +4076,7 @@ best_extension_by_limited_search(JOIN *join,
{ {
DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx, DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
"prune_by_cost");); "prune_by_cost"););
restore_prev_nj_state(s);
continue; continue;
} }
@ -4085,6 +4105,7 @@ best_extension_by_limited_search(JOIN *join,
{ {
DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx, DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
"pruned_by_heuristic");); "pruned_by_heuristic"););
restore_prev_nj_state(s);
continue; continue;
} }
} }
@ -4119,9 +4140,11 @@ best_extension_by_limited_search(JOIN *join,
sizeof(POSITION) * (idx + 1)); sizeof(POSITION) * (idx + 1));
join->best_read= current_read_time - 0.001; join->best_read= current_read_time - 0.001;
} }
DBUG_EXECUTE("opt", DBUG_EXECUTE("opt", print_plan(join, current_read_time,
print_plan(join, current_read_time, current_record_count, idx, "full_plan");); current_record_count, idx,
"full_plan"););
} }
restore_prev_nj_state(s);
} }
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -4166,7 +4189,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++) for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++)
{ {
table_map real_table_bit=s->table->map; table_map real_table_bit=s->table->map;
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent)) if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
(!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
{ {
double best,best_time,records; double best,best_time,records;
best=best_time=records=DBL_MAX; best=best_time=records=DBL_MAX;
@ -4528,6 +4552,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
return; return;
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
} }
restore_prev_nj_state(s);
if (join->select_options & SELECT_STRAIGHT_JOIN) if (join->select_options & SELECT_STRAIGHT_JOIN)
break; // Don't test all combinations break; // Don't test all combinations
} }
@ -7277,11 +7302,11 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
ascent all attributes are calculated, all outer joins that can be ascent all attributes are calculated, all outer joins that can be
converted are replaced and then all unnecessary braces are removed. converted are replaced and then all unnecessary braces are removed.
As join list contains join tables in the reverse order sequential As join list contains join tables in the reverse order sequential
elimination of outer joins does not requite extra recursive calls. elimination of outer joins does not require extra recursive calls.
EXAMPLES EXAMPLES
Here is an example of a join query with invalid cross references: Here is an example of a join query with invalid cross references:
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN ON t3.b=t1.b SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN t3 ON t3.b=t1.b
RETURN VALUE RETURN VALUE
The new condition, if success The new condition, if success
@ -7440,6 +7465,256 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
} }
/*
Assign each nested join structure a bit in nested_join_map
SYNOPSIS
build_bitmap_for_nested_joins()
join Join being processed
join_list List of tables
first_unused Number of first unused bit in nested_join_map before the
call
DESCRIPTION
Assign each nested join structure (except "confluent" ones - those that
embed only one element) a bit in nested_join_map.
NOTE
This function is called after simplify_joins(), when there are no
redundant nested joins, #non_confluent_nested_joins <= #tables_in_join so
we will not run out of bits in nested_join_map.
RETURN
First unused bit in nested_join_map after the call.
*/
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
uint first_unused)
{
List_iterator<TABLE_LIST> li(*join_list);
TABLE_LIST *table;
DBUG_ENTER("build_bitmap_for_nested_joins");
while ((table= li++))
{
NESTED_JOIN *nested_join;
if ((nested_join= table->nested_join))
{
/*
It is guaranteed by simplify_joins() function that a nested join
that has only one child represents a single table VIEW (and the child
is an underlying table). We don't assign bits to such nested join
structures because
1. it is redundant (a "sequence" of one table cannot be interleaved
with anything)
2. we could run out bits in nested_join_map otherwise.
*/
if (nested_join->join_list.elements != 1)
{
nested_join->nj_map= 1 << first_unused++;
first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
first_unused);
}
}
}
DBUG_RETURN(first_unused);
}
/*
Set NESTED_JOIN::counter=0 in all nested joins in passed list
SYNOPSIS
reset_nj_counters()
join_list List of nested joins to process. It may also contain base
tables which will be ignored.
DESCRIPTION
Recursively set NESTED_JOIN::counter=0 for all nested joins contained in
the passed join_list.
*/
static void reset_nj_counters(List<TABLE_LIST> *join_list)
{
List_iterator<TABLE_LIST> li(*join_list);
TABLE_LIST *table;
DBUG_ENTER("reset_nj_counters");
while ((table= li++))
{
NESTED_JOIN *nested_join;
if ((nested_join= table->nested_join))
{
nested_join->counter= 0;
reset_nj_counters(&nested_join->join_list);
}
}
DBUG_VOID_RETURN;
}
/*
Check interleaving with an inner tables of an outer join for extension table
SYNOPSIS
check_interleaving_with_nj()
join Join being processed
last_tab Last table in current partial join order (this function is
not called for empty partial join orders)
next_tab Table we're going to extend the current partial join with
DESCRIPTION
Check if table next_tab can be added to current partial join order, and
if yes, record that it has been added.
The function assumes that both current partial join order and its
extension with next_tab are valid wrt table dependencies.
IMPLEMENTATION
LIMITATIONS ON JOIN ORDER
The nested [outer] joins executioner algorithm imposes these limitations
on join order:
1. "Outer tables first" - any "outer" table must be before any
corresponding "inner" table.
2. "No interleaving" - tables inside a nested join must form a continuous
sequence in join order (i.e. the sequence must not be interrupted by
tables that are outside of this nested join).
#1 is checked elsewhere, this function checks #2 provided that #1 has
been already checked.
WHY NEED NON-INTERLEAVING
Consider an example:
select * from t0 join t1 left join (t2 join t3) on cond1
The join order "t1 t2 t0 t3" is invalid:
table t0 is outside of the nested join, so WHERE condition for t0 is
attached directly to t0 (without triggers, and it may be used to access
t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss
combinations of (t1, t2, t3) that satisfy condition cond1, and produce a
null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have
been produced.
If table t0 is not between t2 and t3, the problem doesn't exist:
* If t0 is located after (t2,t3), WHERE(t0) is applied after nested join
processing has finished.
* If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are
wrapped into condition triggers, which takes care of correct nested
join processing.
HOW IT IS IMPLEMENTED
The limitations on join order can be rephrased as follows: for valid
join order one must be able to:
1. write down the used tables in the join order on one line.
2. for each nested join, put one '(' and one ')' on the said line
3. write "LEFT JOIN" and "ON (...)" where appropriate
4. get a query equivalent to the query we're trying to execute.
Calls to check_interleaving_with_nj() are equivalent to writing the
above described line from left to right.
A single check_interleaving_with_nj(A,B) call is equivalent to writing
table B and appropriate brackets on condition that table A and
appropriate brackets is the last what was written. Graphically the
transition is as follows:
+---- current position
|
... last_tab ))) | ( next_tab ) )..) | ...
X Y Z |
+- need to move to this
position.
Notes about the position:
The caller guarantees that there is no more then one X-bracket by
checking "!(remaining_tables & s->dependent)" before calling this
function. X-bracket may have a pair in Y-bracket.
When "writing" we store/update this auxilary info about the current
position:
1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
joins) we've opened but didn't close.
2. {each NESTED_JOIN structure not simplified away}->counter - number
of this nested join's children that have already been added to to
the partial join order.
RETURN
FALSE Join order extended, nested joins info about current join order
(see NOTE section) updated.
TRUE Requested join order extension not allowed.
*/
static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab)
{
TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding;
JOIN *join= last_tab->join;
if (join->cur_embedding_map & ~next_tab->embedding_map)
{
/*
next_tab is outside of the "pair of brackets" we're currently in.
Cannot add it.
*/
return TRUE;
}
/*
Do update counters for "pairs of brackets" that we've left (marked as
X,Y,Z in the above picture)
*/
for (;next_emb; next_emb= next_emb->embedding)
{
next_emb->nested_join->counter++;
if (next_emb->nested_join->counter == 1)
{
/*
next_emb is the first table inside a nested join we've "entered". In
the picture above, we're looking at the 'X' bracket. Don't exit yet as
X bracket might have Y pair bracket.
*/
join->cur_embedding_map |= next_emb->nested_join->nj_map;
}
if (next_emb->nested_join->join_list.elements !=
next_emb->nested_join->counter)
break;
/*
We're currently at Y or Z-bracket as depicted in the above picture.
Mark that we've left it and continue walking up the brackets hierarchy.
*/
join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
}
return FALSE;
}
/*
Nested joins perspective: Remove the last table from the join order
SYNOPSIS
restore_prev_nj_state()
last join table to remove, it is assumed to be the last in current
partial join order.
DESCRIPTION
Remove the last table from the partial join order and update the nested
joins counters and join->cur_embedding_map. It is ok to call this
function for the first table in join order (for which
check_interleaving_with_nj has not been called)
*/
static void restore_prev_nj_state(JOIN_TAB *last)
{
TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding;
JOIN *join= last->join;
while (last_emb && !(--last_emb->nested_join->counter))
{
join->cur_embedding_map &= last_emb->nested_join->nj_map;
last_emb= last_emb->embedding;
}
}
static COND * static COND *
optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list, optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
Item::cond_result *cond_value) Item::cond_result *cond_value)

View File

@ -137,6 +137,8 @@ typedef struct st_join_table {
TABLE_REF ref; TABLE_REF ref;
JOIN_CACHE cache; JOIN_CACHE cache;
JOIN *join; JOIN *join;
/* Bitmap of nested joins this table is part of */
nested_join_map embedding_map;
void cleanup(); void cleanup();
} JOIN_TAB; } JOIN_TAB;
@ -194,6 +196,13 @@ class JOIN :public Sql_alloc
*/ */
ha_rows fetch_limit; ha_rows fetch_limit;
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
/*
Bitmap of nested joins embedding the position at the end of the current
partial join (valid only during join optimizer run).
*/
nested_join_map cur_embedding_map;
double best_read; double best_read;
List<Item> *fields; List<Item> *fields;
List<Cached_item> group_fields, group_fields_cache; List<Cached_item> group_fields, group_fields_cache;

View File

@ -70,6 +70,8 @@ bool mysqld_show_storage_engines(THD *thd)
handlerton **types; handlerton **types;
for (types= sys_table_types; *types; types++) for (types= sys_table_types; *types; types++)
{
if (!((*types)->flags & HTON_HIDDEN))
{ {
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store((*types)->name, system_charset_info); protocol->store((*types)->name, system_charset_info);
@ -80,12 +82,13 @@ bool mysqld_show_storage_engines(THD *thd)
option_name= "DEFAULT"; option_name= "DEFAULT";
protocol->store(option_name, system_charset_info); protocol->store(option_name, system_charset_info);
protocol->store((*types)->comment, system_charset_info); protocol->store((*types)->comment, system_charset_info);
protocol->store((*types)->commit ? "YES" : "NO", system_charset_info);
protocol->store((*types)->prepare ? "YES" : "NO", system_charset_info);
protocol->store((*types)->savepoint_set ? "YES" : "NO", system_charset_info);
if (protocol->write()) if (protocol->write())
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
move protocol->store((*types)->commit ? "YES" : "NO", system_charset_info);
move protocol->store((*types)->prepare ? "YES" : "NO", system_charset_info);
move protocol->store((*types)->savepoint_set ? "YES" : "NO", system_charset_info);
}
send_eof(thd); send_eof(thd);
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
@ -395,7 +398,21 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
/* Only one table for now, but VIEW can involve several tables */ /* Only one table for now, but VIEW can involve several tables */
if (open_normal_and_derived_tables(thd, table_list, 0)) if (open_normal_and_derived_tables(thd, table_list, 0))
{
if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
/*
Clear all messages with 'error' level status and
issue a warning with 'warning' level status in
case of invalid view and last error is ER_VIEW_INVALID
*/
mysql_reset_errors(thd, true);
push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
ER_VIEW_INVALID,
ER(ER_VIEW_INVALID),
table_list->view_db.str,
table_list->view_name.str);
}
/* TODO: add environment variables show when it become possible */ /* TODO: add environment variables show when it become possible */
if (thd->lex->only_view && !table_list->view) if (thd->lex->only_view && !table_list->view)
@ -1104,18 +1121,36 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
default: default:
DBUG_ASSERT(0); // never should happen DBUG_ASSERT(0); // never should happen
} }
buff->append("DEFINER=", 8); append_definer(thd, buff, &table->definer.user, &table->definer.host);
append_identifier(thd, buff,
table->definer.user.str, table->definer.user.length);
buff->append('@');
append_identifier(thd, buff,
table->definer.host.str, table->definer.host.length);
if (table->view_suid) if (table->view_suid)
buff->append(" SQL SECURITY DEFINER ", 22); buff->append("SQL SECURITY DEFINER ", 21);
else else
buff->append(" SQL SECURITY INVOKER ", 22); buff->append("SQL SECURITY INVOKER ", 21);
} }
/*
Append DEFINER clause to the given buffer.
SYNOPSIS
append_definer()
thd [in] thread handle
buffer [inout] buffer to hold DEFINER clause
definer_user [in] user name part of definer
definer_host [in] host name part of definer
*/
void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
const LEX_STRING *definer_host)
{
buffer->append(STRING_WITH_LEN("DEFINER="));
append_identifier(thd, buffer, definer_user->str, definer_user->length);
buffer->append('@');
append_identifier(thd, buffer, definer_host->str, definer_host->length);
buffer->append(' ');
}
static int static int
view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
{ {
@ -3015,8 +3050,7 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables,
DBUG_ENTER("get_schema_views_record"); DBUG_ENTER("get_schema_views_record");
char definer[HOSTNAME_LENGTH + USERNAME_LENGTH + 2]; char definer[HOSTNAME_LENGTH + USERNAME_LENGTH + 2];
uint definer_len; uint definer_len;
if (!res)
{
if (tables->view) if (tables->view)
{ {
restore_record(table, s->default_values); restore_record(table, s->default_values);
@ -3046,16 +3080,14 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables,
table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs); table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
else else
table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs); table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
DBUG_RETURN(schema_table_store_record(thd, table)); if (schema_table_store_record(thd, table))
} DBUG_RETURN(1);
} if (res)
else
{
if (tables->view)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
thd->net.last_errno, thd->net.last_error); thd->net.last_errno, thd->net.last_error);
thd->clear_error();
} }
if (res)
thd->clear_error();
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -3138,7 +3170,8 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db,
enum trg_event_type event, enum trg_event_type event,
enum trg_action_time_type timing, enum trg_action_time_type timing,
LEX_STRING *trigger_stmt, LEX_STRING *trigger_stmt,
ulong sql_mode) ulong sql_mode,
LEX_STRING *definer_buffer)
{ {
CHARSET_INFO *cs= system_charset_info; CHARSET_INFO *cs= system_charset_info;
byte *sql_mode_str; byte *sql_mode_str;
@ -3163,6 +3196,7 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db,
sql_mode, sql_mode,
&sql_mode_len); &sql_mode_len);
table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs); table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs);
table->field[18]->store((const char *)definer_buffer->str, definer_buffer->length, cs);
return schema_table_store_record(thd, table); return schema_table_store_record(thd, table);
} }
@ -3196,15 +3230,21 @@ static int get_schema_triggers_record(THD *thd, struct st_table_list *tables,
LEX_STRING trigger_name; LEX_STRING trigger_name;
LEX_STRING trigger_stmt; LEX_STRING trigger_stmt;
ulong sql_mode; ulong sql_mode;
char definer_holder[HOSTNAME_LENGTH + USERNAME_LENGTH + 2];
LEX_STRING definer_buffer;
definer_buffer.str= definer_holder;
if (triggers->get_trigger_info(thd, (enum trg_event_type) event, if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
(enum trg_action_time_type)timing, (enum trg_action_time_type)timing,
&trigger_name, &trigger_stmt, &trigger_name, &trigger_stmt,
&sql_mode)) &sql_mode,
&definer_buffer))
continue; continue;
if (store_trigger(thd, table, base_name, file_name, &trigger_name, if (store_trigger(thd, table, base_name, file_name, &trigger_name,
(enum trg_event_type) event, (enum trg_event_type) event,
(enum trg_action_time_type) timing, &trigger_stmt, (enum trg_action_time_type) timing, &trigger_stmt,
sql_mode)) sql_mode,
&definer_buffer))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
@ -4108,6 +4148,7 @@ ST_FIELD_INFO triggers_fields_info[]=
{"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0}, {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
{"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"}, {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"},
{"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"}, {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"},
{"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer"},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0} {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
}; };

View File

@ -896,6 +896,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
else else
{ {
/* Field redefined */ /* Field redefined */
sql_field->def= dup_field->def;
sql_field->sql_type= dup_field->sql_type; sql_field->sql_type= dup_field->sql_type;
sql_field->charset= (dup_field->charset ? sql_field->charset= (dup_field->charset ?
dup_field->charset : dup_field->charset :
@ -905,8 +906,15 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->key_length= dup_field->key_length; sql_field->key_length= dup_field->key_length;
sql_field->create_length_to_internal_length(); sql_field->create_length_to_internal_length();
sql_field->decimals= dup_field->decimals; sql_field->decimals= dup_field->decimals;
sql_field->flags= dup_field->flags;
sql_field->unireg_check= dup_field->unireg_check; sql_field->unireg_check= dup_field->unireg_check;
/*
We're making one field from two, the result field will have
dup_field->flags as flags. If we've incremented null_fields
because of sql_field->flags, decrement it back.
*/
if (!(sql_field->flags & NOT_NULL_FLAG))
null_fields--;
sql_field->flags= dup_field->flags;
it2.remove(); // Remove first (create) definition it2.remove(); // Remove first (create) definition
select_field_pos--; select_field_pos--;
break; break;
@ -2338,7 +2346,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
/* if view are unsupported */ /* if view are unsupported */
if (table->view && view_operator_func == NULL) if (table->view && view_operator_func == NULL)
{ {
result_code= HA_ADMIN_NOT_IMPLEMENTED; result_code= HA_ADMIN_NOT_BASE_TABLE;
goto send_result; goto send_result;
} }
thd->open_options&= ~extra_open_options; thd->open_options&= ~extra_open_options;
@ -2473,6 +2481,16 @@ send_result_message:
} }
break; break;
case HA_ADMIN_NOT_BASE_TABLE:
{
char buf[ERRMSGSIZE+20];
uint length= my_snprintf(buf, ERRMSGSIZE,
ER(ER_BAD_TABLE_ERROR), table_name);
protocol->store("note", 4, system_charset_info);
protocol->store(buf, length, system_charset_info);
}
break;
case HA_ADMIN_OK: case HA_ADMIN_OK:
protocol->store("status", 6, system_charset_info); protocol->store("status", 6, system_charset_info);
protocol->store("OK",2, system_charset_info); protocol->store("OK",2, system_charset_info);
@ -2573,6 +2591,8 @@ send_result_message:
break; break;
} }
} }
if (table->table)
{
if (fatal_error) if (fatal_error)
table->table->s->version=0; // Force close of table table->table->s->version=0; // Force close of table
else if (open_for_modify) else if (open_for_modify)
@ -2581,9 +2601,10 @@ send_result_message:
remove_table_from_cache(thd, table->table->s->db, remove_table_from_cache(thd, table->table->s->db,
table->table->s->table_name, RTFC_NO_FLAG); table->table->s->table_name, RTFC_NO_FLAG);
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
/* May be something modified consequently we have to invalidate cache */ /* Something may be modified, that's why we have to invalidate cache */
query_cache_invalidate3(thd, table->table, 0); query_cache_invalidate3(thd, table->table, 0);
} }
}
close_thread_tables(thd); close_thread_tables(thd);
table->table=0; // For query cache table->table=0; // For query cache
if (protocol->write()) if (protocol->write())

View File

@ -32,15 +32,36 @@ const char * const triggers_file_ext= ".TRG";
*/ */
static File_option triggers_file_parameters[]= static File_option triggers_file_parameters[]=
{ {
{{(char*)"triggers", 8}, {
{ (char *) STRING_WITH_LEN("triggers") },
offsetof(class Table_triggers_list, definitions_list), offsetof(class Table_triggers_list, definitions_list),
FILE_OPTIONS_STRLIST}, FILE_OPTIONS_STRLIST
{{(char*)"sql_modes", 13}, },
{
/*
FIXME: Length specified for "sql_modes" key is erroneous, problem caused
by this are reported as BUG#14090 and should be fixed ASAP.
*/
{ (char *) "sql_modes", 13 },
offsetof(class Table_triggers_list, definition_modes_list), offsetof(class Table_triggers_list, definition_modes_list),
FILE_OPTIONS_ULLLIST}, FILE_OPTIONS_ULLLIST
},
{
{ (char *) STRING_WITH_LEN("definers") },
offsetof(class Table_triggers_list, definers_list),
FILE_OPTIONS_STRLIST
},
{ { 0, 0 }, 0, FILE_OPTIONS_STRING } { { 0, 0 }, 0, FILE_OPTIONS_STRING }
}; };
/*
This must be kept up to date whenever a new option is added to the list
above, as it specifies the number of required parameters of the trigger in
.trg file.
*/
static const int TRG_NUM_REQUIRED_PARAMETERS= 4;
static const int TRG_MAX_VERSIONS= 3;
/* /*
Structure representing contents of .TRN file which are used to support Structure representing contents of .TRN file which are used to support
@ -58,8 +79,15 @@ const char * const trigname_file_ext= ".TRN";
static File_option trigname_file_parameters[]= static File_option trigname_file_parameters[]=
{ {
{{(char*)"trigger_table", 15}, offsetof(struct st_trigname, trigger_table), {
FILE_OPTIONS_ESTRING}, /*
FIXME: Length specified for "trigger_table" key is erroneous, problem
caused by this are reported as BUG#14090 and should be fixed ASAP.
*/
{ (char *) "trigger_table", 15 },
offsetof(struct st_trigname, trigger_table),
FILE_OPTIONS_ESTRING
},
{ { 0, 0 }, 0, FILE_OPTIONS_STRING } { { 0, 0 }, 0, FILE_OPTIONS_STRING }
}; };
@ -104,6 +132,9 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
{ {
TABLE *table; TABLE *table;
bool result= TRUE; bool result= TRUE;
LEX_STRING definer_user;
LEX_STRING definer_host;
DBUG_ENTER("mysql_create_or_drop_trigger"); DBUG_ENTER("mysql_create_or_drop_trigger");
/* /*
@ -131,9 +162,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
But a trigger can in theory be used to do nasty things (if it supported But a trigger can in theory be used to do nasty things (if it supported
DROP for example) so we do the check for privileges. For now there is DROP for example) so we do the check for privileges. For now there is
already a stronger test right above; but when this stronger test will already a stronger test right above; but when this stronger test will
be removed, the test below will hold. be removed, the test below will hold. Because triggers have the same
nature as functions regarding binlogging: their body is implicitely
binlogged, so they share the same danger, so trust_function_creators
applies to them too.
*/ */
if (!trust_routine_creators && mysql_bin_log.is_open() && if (!trust_function_creators && mysql_bin_log.is_open() &&
!(thd->security_ctx->master_access & SUPER_ACL)) !(thd->security_ctx->master_access & SUPER_ACL))
{ {
my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0)); my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0));
@ -184,7 +218,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
} }
result= (create ? result= (create ?
table->triggers->create_trigger(thd, tables): table->triggers->create_trigger(thd, tables, &definer_user, &definer_host):
table->triggers->drop_trigger(thd, tables)); table->triggers->drop_trigger(thd, tables));
end: end:
@ -196,10 +230,23 @@ end:
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
/* Such a statement can always go directly to binlog, no trans cache */
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); String log_query(thd->query, thd->query_length, system_charset_info);
if (create)
{
log_query.set((char *) 0, 0, system_charset_info); /* reset log_query */
log_query.append("CREATE ");
append_definer(thd, &log_query, &definer_user, &definer_host);
log_query.append(thd->lex->trigger_definition_begin);
}
/* Such a statement can always go directly to binlog, no trans cache. */
Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), 0, FALSE);
mysql_bin_log.write(&qinfo); mysql_bin_log.write(&qinfo);
} }
send_ok(thd); send_ok(thd);
} }
@ -212,15 +259,26 @@ end:
SYNOPSIS SYNOPSIS
create_trigger() create_trigger()
thd - current thread context (including trigger definition in LEX) thd - current thread context (including trigger definition in
tables - table list containing one open table for which trigger is LEX)
created. tables - table list containing one open table for which the
trigger is created.
definer_user - [out] after a call it points to 0-terminated string,
which contains user name part of the actual trigger
definer. The caller is responsible to provide memory for
storing LEX_STRING object.
definer_host - [out] after a call it points to 0-terminated string,
which contains host name part of the actual trigger
definer. The caller is responsible to provide memory for
storing LEX_STRING object.
RETURN VALUE RETURN VALUE
False - success False - success
True - error True - error
*/ */
bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables) bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
LEX_STRING *definer_user,
LEX_STRING *definer_host)
{ {
LEX *lex= thd->lex; LEX *lex= thd->lex;
TABLE *table= tables->table; TABLE *table= tables->table;
@ -229,6 +287,8 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables)
LEX_STRING dir, file, trigname_file; LEX_STRING dir, file, trigname_file;
LEX_STRING *trg_def, *name; LEX_STRING *trg_def, *name;
ulonglong *trg_sql_mode; ulonglong *trg_sql_mode;
char trg_definer_holder[HOSTNAME_LENGTH + USERNAME_LENGTH + 2];
LEX_STRING *trg_definer;
Item_trigger_field *trg_field; Item_trigger_field *trg_field;
struct st_trigname trigname; struct st_trigname trigname;
@ -249,6 +309,31 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables)
return 1; return 1;
} }
/*
Definer attribute of the Lex instance is always set in sql_yacc.yy when
trigger is created.
*/
DBUG_ASSERT(lex->definer);
/*
If the specified definer differs from the current user, we should check
that the current user has SUPER privilege (in order to create trigger
under another user one must have SUPER privilege).
*/
if (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
my_strcasecmp(system_charset_info,
lex->definer->host.str,
thd->security_ctx->priv_host))
{
if (check_global_access(thd, SUPER_ACL))
{
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
return TRUE;
}
}
/* /*
Let us check if all references to fields in old/new versions of row in Let us check if all references to fields in old/new versions of row in
this trigger are ok. this trigger are ok.
@ -318,15 +403,39 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables)
definitions_list.push_back(trg_def, &table->mem_root) || definitions_list.push_back(trg_def, &table->mem_root) ||
!(trg_sql_mode= (ulonglong*)alloc_root(&table->mem_root, !(trg_sql_mode= (ulonglong*)alloc_root(&table->mem_root,
sizeof(ulonglong))) || sizeof(ulonglong))) ||
definition_modes_list.push_back(trg_sql_mode, &table->mem_root)) definition_modes_list.push_back(trg_sql_mode, &table->mem_root) ||
!(trg_definer= (LEX_STRING*) alloc_root(&table->mem_root,
sizeof(LEX_STRING))) ||
definers_list.push_back(trg_definer, &table->mem_root))
goto err_with_cleanup; goto err_with_cleanup;
trg_def->str= thd->query; trg_def->str= thd->query;
trg_def->length= thd->query_length; trg_def->length= thd->query_length;
*trg_sql_mode= thd->variables.sql_mode; *trg_sql_mode= thd->variables.sql_mode;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!is_acl_user(lex->definer->host.str,
lex->definer->user.str))
{
push_warning_printf(thd,
MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NO_SUCH_USER,
ER(ER_NO_SUCH_USER),
lex->definer->user.str,
lex->definer->host.str);
}
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
*definer_user= lex->definer->user;
*definer_host= lex->definer->host;
trg_definer->str= trg_definer_holder;
trg_definer->length= strxmov(trg_definer->str, definer_user->str, "@",
definer_host->str, NullS) - trg_definer->str;
if (!sql_create_definition_file(&dir, &file, &triggers_file_type, if (!sql_create_definition_file(&dir, &file, &triggers_file_type,
(gptr)this, triggers_file_parameters, 3)) (gptr)this, triggers_file_parameters,
TRG_MAX_VERSIONS))
return 0; return 0;
err_with_cleanup: err_with_cleanup:
@ -403,12 +512,14 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables)
List_iterator_fast<LEX_STRING> it_name(names_list); List_iterator_fast<LEX_STRING> it_name(names_list);
List_iterator<LEX_STRING> it_def(definitions_list); List_iterator<LEX_STRING> it_def(definitions_list);
List_iterator<ulonglong> it_mod(definition_modes_list); List_iterator<ulonglong> it_mod(definition_modes_list);
List_iterator<LEX_STRING> it_definer(definers_list);
char path[FN_REFLEN]; char path[FN_REFLEN];
while ((name= it_name++)) while ((name= it_name++))
{ {
it_def++; it_def++;
it_mod++; it_mod++;
it_definer++;
if (my_strcasecmp(table_alias_charset, lex->spname->m_name.str, if (my_strcasecmp(table_alias_charset, lex->spname->m_name.str,
name->str) == 0) name->str) == 0)
@ -419,6 +530,7 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables)
*/ */
it_def.remove(); it_def.remove();
it_mod.remove(); it_mod.remove();
it_definer.remove();
if (definitions_list.is_empty()) if (definitions_list.is_empty())
{ {
@ -446,7 +558,7 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables)
if (sql_create_definition_file(&dir, &file, &triggers_file_type, if (sql_create_definition_file(&dir, &file, &triggers_file_type,
(gptr)this, triggers_file_parameters, (gptr)this, triggers_file_parameters,
3)) TRG_MAX_VERSIONS))
return 1; return 1;
} }
@ -568,7 +680,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
DBUG_RETURN(0); DBUG_RETURN(0);
/* /*
File exists so we got to load triggers File exists so we got to load triggers.
FIXME: A lot of things to do here e.g. how about other funcs and being FIXME: A lot of things to do here e.g. how about other funcs and being
more paranoical ? more paranoical ?
*/ */
@ -584,13 +696,16 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
DBUG_RETURN(1); DBUG_RETURN(1);
/* /*
We don't have sql_modes in old versions of .TRG file, so we should We don't have the following attributes in old versions of .TRG file, so
initialize list for safety. we should initialize the list for safety:
- sql_modes;
- definers;
*/ */
triggers->definition_modes_list.empty(); triggers->definition_modes_list.empty();
triggers->definers_list.empty();
if (parser->parse((gptr)triggers, &table->mem_root, if (parser->parse((gptr)triggers, &table->mem_root,
triggers_file_parameters, 2)) triggers_file_parameters, TRG_NUM_REQUIRED_PARAMETERS))
DBUG_RETURN(1); DBUG_RETURN(1);
List_iterator_fast<LEX_STRING> it(triggers->definitions_list); List_iterator_fast<LEX_STRING> it(triggers->definitions_list);
@ -612,7 +727,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
DBUG_RETURN(1); // EOM DBUG_RETURN(1); // EOM
} }
*trg_sql_mode= global_system_variables.sql_mode; *trg_sql_mode= global_system_variables.sql_mode;
while ((trg_create_str= it++)) while (it++)
{ {
if (triggers->definition_modes_list.push_back(trg_sql_mode, if (triggers->definition_modes_list.push_back(trg_sql_mode,
&table->mem_root)) &table->mem_root))
@ -623,8 +738,43 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
it.rewind(); it.rewind();
} }
if (triggers->definers_list.is_empty() &&
!triggers->definitions_list.is_empty())
{
/*
It is old file format => we should fill list of definers.
If there is no definer information, we should not switch context to
definer when checking privileges. I.e. privileges for such triggers
are checked for "invoker" rather than for "definer".
*/
LEX_STRING *trg_definer;
if (! (trg_definer= (LEX_STRING*)alloc_root(&table->mem_root,
sizeof(LEX_STRING))))
DBUG_RETURN(1); // EOM
trg_definer->str= "";
trg_definer->length= 0;
while (it++)
{
if (triggers->definers_list.push_back(trg_definer,
&table->mem_root))
{
DBUG_RETURN(1); // EOM
}
}
it.rewind();
}
DBUG_ASSERT(triggers->definition_modes_list.elements == DBUG_ASSERT(triggers->definition_modes_list.elements ==
triggers->definitions_list.elements); triggers->definitions_list.elements);
DBUG_ASSERT(triggers->definers_list.elements ==
triggers->definitions_list.elements);
table->triggers= triggers; table->triggers= triggers;
/* /*
@ -647,6 +797,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
char *trg_name_buff; char *trg_name_buff;
List_iterator_fast<ulonglong> itm(triggers->definition_modes_list); List_iterator_fast<ulonglong> itm(triggers->definition_modes_list);
List_iterator_fast<LEX_STRING> it_definer(triggers->
definers_list);
LEX *old_lex= thd->lex, lex; LEX *old_lex= thd->lex, lex;
ulong save_sql_mode= thd->variables.sql_mode; ulong save_sql_mode= thd->variables.sql_mode;
@ -659,22 +811,55 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
while ((trg_create_str= it++)) while ((trg_create_str= it++))
{ {
trg_sql_mode= itm++; trg_sql_mode= itm++;
LEX_STRING *trg_definer= it_definer++;
thd->variables.sql_mode= (ulong)*trg_sql_mode; thd->variables.sql_mode= (ulong)*trg_sql_mode;
lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length); lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length);
if (yyparse((void *)thd) || thd->is_fatal_error) if (yyparse((void *)thd) || thd->is_fatal_error)
{ {
/* /*
Free lex associated resources Free lex associated resources.
QQ: Do we really need all this stuff here ? QQ: Do we really need all this stuff here ?
*/ */
delete lex.sphead; delete lex.sphead;
goto err_with_lex_cleanup; goto err_with_lex_cleanup;
} }
lex.sphead->m_sql_mode= *trg_sql_mode; lex.sphead->set_info(0, 0, &lex.sp_chistics, *trg_sql_mode);
triggers->bodies[lex.trg_chistics.event] triggers->bodies[lex.trg_chistics.event]
[lex.trg_chistics.action_time]= lex.sphead; [lex.trg_chistics.action_time]= lex.sphead;
if (!trg_definer->length)
{
/*
This trigger was created/imported from the previous version of
MySQL, which does not support triggers definers. We should emit
warning here.
*/
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRG_NO_DEFINER, ER(ER_TRG_NO_DEFINER),
(const char*) db,
(const char*) lex.sphead->m_name.str);
/*
Set definer to the '' to correct displaying in the information
schema.
*/
lex.sphead->set_definer("", 0);
/*
Triggers without definer information are executed under the
authorization of the invoker.
*/
lex.sphead->m_chistics->suid= SP_IS_NOT_SUID;
}
else
lex.sphead->set_definer(trg_definer->str, trg_definer->length);
if (triggers->names_list.push_back(&lex.sphead->m_name, if (triggers->names_list.push_back(&lex.sphead->m_name,
&table->mem_root)) &table->mem_root))
goto err_with_lex_cleanup; goto err_with_lex_cleanup;
@ -701,6 +886,10 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
trg_field= trg_field->next_trg_field) trg_field= trg_field->next_trg_field)
trg_field->setup_field(thd, table); trg_field->setup_field(thd, table);
triggers->m_spec_var_used[lex.trg_chistics.event]
[lex.trg_chistics.action_time]=
lex.trg_table_fields.first ? TRUE : FALSE;
lex_end(&lex); lex_end(&lex);
} }
thd->db= save_db.str; thd->db= save_db.str;
@ -744,6 +933,9 @@ err_with_lex_cleanup:
name - returns name of trigger name - returns name of trigger
stmt - returns statement of trigger stmt - returns statement of trigger
sql_mode - returns sql_mode of trigger sql_mode - returns sql_mode of trigger
definer_user - returns definer/creator of trigger. The caller is
responsible to allocate enough space for storing definer
information.
RETURN VALUE RETURN VALUE
False - success False - success
@ -754,7 +946,8 @@ bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event,
trg_action_time_type time_type, trg_action_time_type time_type,
LEX_STRING *trigger_name, LEX_STRING *trigger_name,
LEX_STRING *trigger_stmt, LEX_STRING *trigger_stmt,
ulong *sql_mode) ulong *sql_mode,
LEX_STRING *definer)
{ {
sp_head *body; sp_head *body;
DBUG_ENTER("get_trigger_info"); DBUG_ENTER("get_trigger_info");
@ -763,6 +956,18 @@ bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event,
*trigger_name= body->m_name; *trigger_name= body->m_name;
*trigger_stmt= body->m_body; *trigger_stmt= body->m_body;
*sql_mode= body->m_sql_mode; *sql_mode= body->m_sql_mode;
if (body->m_chistics->suid == SP_IS_NOT_SUID)
{
definer->str[0]= 0;
definer->length= 0;
}
else
{
definer->length= strxmov(definer->str, body->m_definer_user.str, "@",
body->m_definer_host.str, NullS) - definer->str;
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }
DBUG_RETURN(1); DBUG_RETURN(1);
@ -898,8 +1103,9 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
bool old_row_is_record1) bool old_row_is_record1)
{ {
int res= 0; int res= 0;
sp_head *sp_trigger= bodies[event][time_type];
if (bodies[event][time_type]) if (sp_trigger)
{ {
Sub_statement_state statement_state; Sub_statement_state statement_state;
@ -914,14 +1120,54 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
old_field= table->field; old_field= table->field;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *save_ctx;
if (sp_change_security_context(thd, sp_trigger, &save_ctx))
return TRUE;
/* /*
FIXME: We should juggle with security context here (because trigger NOTE: TRIGGER_ACL should be used below.
should be invoked with creator rights).
*/ */
if (check_global_access(thd, SUPER_ACL))
{
sp_restore_security_context(thd, save_ctx);
return TRUE;
}
/*
If the trigger uses special variables (NEW/OLD), check that we have
SELECT and UPDATE privileges on the subject table.
*/
if (is_special_var_used(event, time_type))
{
TABLE_LIST table_list;
bzero((char *) &table_list, sizeof (table_list));
table_list.db= (char *) table->s->db;
table_list.db_length= strlen(table_list.db);
table_list.table_name= (char *) table->s->table_name;
table_list.table_name_length= strlen(table_list.table_name);
table_list.alias= (char *) table->alias;
table_list.table= table;
if (check_table_access(thd, SELECT_ACL | UPDATE_ACL, &table_list, 0))
{
sp_restore_security_context(thd, save_ctx);
return TRUE;
}
}
#endif // NO_EMBEDDED_ACCESS_CHECKS
thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER); thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER);
res= bodies[event][time_type]->execute_function(thd, 0, 0, 0); res= sp_trigger->execute_function(thd, 0, 0, 0);
thd->restore_sub_statement_state(&statement_state); thd->restore_sub_statement_state(&statement_state);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
sp_restore_security_context(thd, save_ctx);
#endif // NO_EMBEDDED_ACCESS_CHECKS
} }
return res; return res;

View File

@ -55,6 +55,12 @@ class Table_triggers_list: public Sql_alloc
*/ */
LEX_STRING sroutines_key; LEX_STRING sroutines_key;
/*
is_special_var_used specifies whether trigger body contains special
variables (NEW/OLD).
*/
bool m_spec_var_used[TRG_EVENT_MAX][TRG_ACTION_MAX];
public: public:
/* /*
Field responsible for storing triggers definitions in file. Field responsible for storing triggers definitions in file.
@ -66,6 +72,8 @@ public:
*/ */
List<ulonglong> definition_modes_list; List<ulonglong> definition_modes_list;
List<LEX_STRING> definers_list;
Table_triggers_list(TABLE *table_arg): Table_triggers_list(TABLE *table_arg):
record1_field(0), table(table_arg) record1_field(0), table(table_arg)
{ {
@ -73,7 +81,9 @@ public:
} }
~Table_triggers_list(); ~Table_triggers_list();
bool create_trigger(THD *thd, TABLE_LIST *table); bool create_trigger(THD *thd, TABLE_LIST *table,
LEX_STRING *definer_user,
LEX_STRING *definer_host);
bool drop_trigger(THD *thd, TABLE_LIST *table); bool drop_trigger(THD *thd, TABLE_LIST *table);
bool process_triggers(THD *thd, trg_event_type event, bool process_triggers(THD *thd, trg_event_type event,
trg_action_time_type time_type, trg_action_time_type time_type,
@ -81,7 +91,8 @@ public:
bool get_trigger_info(THD *thd, trg_event_type event, bool get_trigger_info(THD *thd, trg_event_type event,
trg_action_time_type time_type, trg_action_time_type time_type,
LEX_STRING *trigger_name, LEX_STRING *trigger_stmt, LEX_STRING *trigger_name, LEX_STRING *trigger_stmt,
ulong *sql_mode); ulong *sql_mode,
LEX_STRING *definer);
static bool check_n_load(THD *thd, const char *db, const char *table_name, static bool check_n_load(THD *thd, const char *db, const char *table_name,
TABLE *table, bool names_only); TABLE *table, bool names_only);
@ -98,6 +109,11 @@ public:
return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]); return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]);
} }
inline bool is_special_var_used(int event, int action_time) const
{
return m_spec_var_used[event][action_time];
}
void set_table(TABLE *new_table); void set_table(TABLE *new_table);
friend class Item_trigger_field; friend class Item_trigger_field;

View File

@ -214,29 +214,28 @@ bool mysql_create_view(THD *thd,
- same as current user - same as current user
- current user has SUPER_ACL - current user has SUPER_ACL
*/ */
if (strcmp(lex->create_view_definer->user.str, if (strcmp(lex->definer->user.str,
thd->security_ctx->priv_user) != 0 || thd->security_ctx->priv_user) != 0 ||
my_strcasecmp(system_charset_info, my_strcasecmp(system_charset_info,
lex->create_view_definer->host.str, lex->definer->host.str,
thd->security_ctx->priv_host) != 0) thd->security_ctx->priv_host) != 0)
{ {
if (!(thd->security_ctx->master_access & SUPER_ACL)) if (!(thd->security_ctx->master_access & SUPER_ACL))
{ {
my_error(ER_VIEW_OTHER_USER, MYF(0), lex->create_view_definer->user.str, my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
lex->create_view_definer->host.str);
res= TRUE; res= TRUE;
goto err; goto err;
} }
else else
{ {
if (!is_acl_user(lex->create_view_definer->host.str, if (!is_acl_user(lex->definer->host.str,
lex->create_view_definer->user.str)) lex->definer->user.str))
{ {
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NO_SUCH_USER, ER_NO_SUCH_USER,
ER(ER_NO_SUCH_USER), ER(ER_NO_SUCH_USER),
lex->create_view_definer->user.str, lex->definer->user.str,
lex->create_view_definer->host.str); lex->definer->host.str);
} }
} }
} }
@ -658,8 +657,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
} }
view->algorithm= lex->create_view_algorithm; view->algorithm= lex->create_view_algorithm;
view->definer.user= lex->create_view_definer->user; view->definer.user= lex->definer->user;
view->definer.host= lex->create_view_definer->host; view->definer.host= lex->definer->host;
view->view_suid= lex->create_view_suid; view->view_suid= lex->create_view_suid;
view->with_check= lex->create_view_check; view->with_check= lex->create_view_check;
if ((view->updatable_view= (can_be_merged && if ((view->updatable_view= (can_be_merged &&
@ -807,7 +806,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER), ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER),
table->db, table->table_name); table->db, table->table_name);
if (default_view_definer(thd->security_ctx, &table->definer)) if (get_default_definer(thd, &table->definer))
goto err; goto err;
} }

View File

@ -795,7 +795,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword keyword_sp %type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword keyword_sp
%type <lex_user> user grant_user %type <lex_user> user grant_user get_definer
%type <charset> %type <charset>
opt_collate opt_collate
@ -846,11 +846,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
subselect_end select_var_list select_var_list_init help opt_len subselect_end select_var_list select_var_list_init help opt_len
opt_extended_describe opt_extended_describe
prepare prepare_src execute deallocate prepare prepare_src execute deallocate
statement sp_suid opt_view_list view_list or_replace algorithm statement sp_suid
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
install uninstall view_user view_suid definer view_replace_or_algorithm view_replace view_algorithm_opt
partition_entry view_algorithm view_or_trigger_tail view_suid view_tail view_list_opt
view_list view_select view_check_option trigger_tail
install uninstall partition_entry
END_OF_INPUT END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@ -1285,80 +1287,14 @@ create:
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
sp->restore_thd_mem_root(YYTHD); sp->restore_thd_mem_root(YYTHD);
} }
| CREATE or_replace algorithm view_user view_suid VIEW_SYM table_ident | CREATE
{ {
THD *thd= YYTHD; Lex->create_view_mode= VIEW_CREATE_NEW;
LEX *lex= thd->lex; Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
lex->sql_command= SQLCOM_CREATE_VIEW; Lex->create_view_suid= TRUE;
lex->create_view_start= thd->query;
/* first table in list is target VIEW name */
if (!lex->select_lex.add_table_to_list(thd, $7, NULL, 0))
YYABORT;
} }
opt_view_list AS select_view_init check_option view_or_trigger
{} {}
| CREATE TRIGGER_SYM sp_name trg_action_time trg_event
ON table_ident FOR_SYM EACH_SYM ROW_SYM
{
LEX *lex= Lex;
sp_head *sp;
if (lex->sphead)
{
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER");
YYABORT;
}
if (!(sp= new sp_head()))
YYABORT;
sp->reset_thd_mem_root(YYTHD);
sp->init(lex);
sp->m_type= TYPE_ENUM_TRIGGER;
lex->sphead= sp;
lex->spname= $3;
/*
We have to turn of CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->sphead->m_chistics= &lex->sp_chistics;
lex->sphead->m_body_begin= lex->ptr;
}
sp_proc_stmt
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
lex->sql_command= SQLCOM_CREATE_TRIGGER;
sp->init_strings(YYTHD, lex, $3);
/* Restore flag if it was cleared above */
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
sp->restore_thd_mem_root(YYTHD);
if (sp->is_not_allowed_in_function("trigger"))
YYABORT;
/*
We have to do it after parsing trigger body, because some of
sp_proc_stmt alternatives are not saving/restoring LEX, so
lex->query_tables can be wiped out.
QQ: What are other consequences of this?
QQ: Could we loosen lock type in certain cases ?
*/
if (!lex->select_lex.add_table_to_list(YYTHD, $7,
(LEX_STRING*) 0,
TL_OPTION_UPDATING,
TL_WRITE))
YYABORT;
}
| CREATE USER clear_privileges grant_list | CREATE USER clear_privileges grant_list
{ {
Lex->sql_command = SQLCOM_CREATE_USER; Lex->sql_command = SQLCOM_CREATE_USER;
@ -2598,7 +2534,7 @@ create3:
/* /*
This part of the parser is about handling of the partition information. This part of the parser is about handling of the partition information.
It's first version was written by Mikael Ronström with lots of answers to It's first version was written by Mikael Ronström with lots of answers to
questions provided by Antony Curtis. questions provided by Antony Curtis.
The partition grammar can be called from three places. The partition grammar can be called from three places.
@ -3967,7 +3903,8 @@ alter:
lex->sql_command= SQLCOM_ALTER_FUNCTION; lex->sql_command= SQLCOM_ALTER_FUNCTION;
lex->spname= $3; lex->spname= $3;
} }
| ALTER algorithm view_user view_suid VIEW_SYM table_ident | ALTER view_algorithm_opt definer view_suid
VIEW_SYM table_ident
{ {
THD *thd= YYTHD; THD *thd= YYTHD;
LEX *lex= thd->lex; LEX *lex= thd->lex;
@ -3977,7 +3914,7 @@ alter:
/* first table in list is target VIEW name */ /* first table in list is target VIEW name */
lex->select_lex.add_table_to_list(thd, $6, NULL, 0); lex->select_lex.add_table_to_list(thd, $6, NULL, 0);
} }
opt_view_list AS select_view_init check_option view_list_opt AS view_select view_check_option
{} {}
; ;
@ -3992,7 +3929,7 @@ alter_commands:
opt_partitioning opt_partitioning
| partitioning | partitioning
/* /*
This part was added for release 5.1 by Mikael Ronström. This part was added for release 5.1 by Mikael Ronström.
From here we insert a number of commands to manage the partitions of a From here we insert a number of commands to manage the partitions of a
partitioned table such as adding partitions, dropping partitions, partitioned table such as adding partitions, dropping partitions,
reorganising partitions in various manners. In future releases the list reorganising partitions in various manners. In future releases the list
@ -4636,18 +4573,6 @@ select_init:
| |
'(' select_paren ')' union_opt; '(' select_paren ')' union_opt;
select_view_init:
SELECT_SYM remember_name select_init2
{
Lex->create_view_select_start= $2;
}
|
'(' remember_name select_paren ')' union_opt
{
Lex->create_view_select_start= $2;
}
;
select_paren: select_paren:
SELECT_SYM select_part2 SELECT_SYM select_part2
{ {
@ -9612,8 +9537,119 @@ subselect_end:
lex->current_select = lex->current_select->return_after_parsing(); lex->current_select = lex->current_select->return_after_parsing();
}; };
opt_view_list: definer:
/* empty */ {} get_definer
{
THD *thd= YYTHD;
if (! (thd->lex->definer= create_definer(thd, &$1->user, &$1->host)))
YYABORT;
}
;
get_definer:
opt_current_definer
{
THD *thd= YYTHD;
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT;
if (get_default_definer(thd, $$))
YYABORT;
}
| DEFINER_SYM EQ ident_or_text '@' ident_or_text
{
if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
YYABORT;
$$->user= $3;
$$->host= $5;
}
;
opt_current_definer:
/* empty */
| DEFINER_SYM EQ CURRENT_USER optional_braces
;
/**************************************************************************
CREATE VIEW statement options.
**************************************************************************/
view_replace_or_algorithm:
view_replace
{}
| view_replace view_algorithm
{}
| view_algorithm
{}
;
view_replace:
OR_SYM REPLACE
{ Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; }
;
view_algorithm:
ALGORITHM_SYM EQ UNDEFINED_SYM
{ Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
| ALGORITHM_SYM EQ MERGE_SYM
{ Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
| ALGORITHM_SYM EQ TEMPTABLE_SYM
{ Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; }
;
view_algorithm_opt:
/* empty */
{ Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
| view_algorithm
{}
;
view_or_trigger:
definer view_or_trigger_tail
{}
| view_replace_or_algorithm definer view_tail
{}
;
view_or_trigger_tail:
view_tail
{}
| trigger_tail
{}
;
view_suid:
/* empty */
{ Lex->create_view_suid= TRUE; }
| SQL_SYM SECURITY_SYM DEFINER_SYM
{ Lex->create_view_suid= TRUE; }
| SQL_SYM SECURITY_SYM INVOKER_SYM
{ Lex->create_view_suid= FALSE; }
;
view_tail:
view_suid VIEW_SYM table_ident
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_VIEW;
lex->create_view_start= thd->query;
/* first table in list is target VIEW name */
if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))
YYABORT;
}
view_list_opt AS view_select view_check_option
{}
;
view_list_opt:
/* empty */
{}
| '(' view_list ')' | '(' view_list ')'
; ;
@ -9630,70 +9666,18 @@ view_list:
} }
; ;
or_replace: view_select:
/* empty */ { Lex->create_view_mode= VIEW_CREATE_NEW; } SELECT_SYM remember_name select_init2
| OR_SYM REPLACE { Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; }
;
algorithm:
/* empty */
{ Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
| ALGORITHM_SYM EQ UNDEFINED_SYM
{ Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
| ALGORITHM_SYM EQ MERGE_SYM
{ Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
| ALGORITHM_SYM EQ TEMPTABLE_SYM
{ Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; }
;
view_user:
/* empty */
{ {
THD *thd= YYTHD; Lex->create_view_select_start= $2;
if (!(thd->lex->create_view_definer=
(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT;
if (default_view_definer(thd->security_ctx,
thd->lex->create_view_definer))
YYABORT;
} }
| CURRENT_USER optional_braces | '(' remember_name select_paren ')' union_opt
{ {
THD *thd= YYTHD; Lex->create_view_select_start= $2;
if (!(thd->lex->create_view_definer=
(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT;
if (default_view_definer(thd->security_ctx,
thd->lex->create_view_definer))
YYABORT;
}
| DEFINER_SYM EQ ident_or_text '@' ident_or_text
{
THD *thd= YYTHD;
st_lex_user *view_user;
if (!(thd->lex->create_view_definer= view_user=
(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT;
view_user->user = $3; view_user->host=$5;
if (view_user->host.length == 0)
{
my_error(ER_NO_VIEW_USER, MYF(0));
YYABORT;
}
} }
; ;
view_suid: view_check_option:
/* empty */
{ Lex->create_view_suid= TRUE; }
|
SQL_SYM SECURITY_SYM DEFINER_SYM
{ Lex->create_view_suid= TRUE; }
| SQL_SYM SECURITY_SYM INVOKER_SYM
{ Lex->create_view_suid= FALSE; }
;
check_option:
/* empty */ /* empty */
{ Lex->create_view_check= VIEW_CHECK_NONE; } { Lex->create_view_check= VIEW_CHECK_NONE; }
| WITH CHECK_SYM OPTION | WITH CHECK_SYM OPTION
@ -9704,6 +9688,81 @@ check_option:
{ Lex->create_view_check= VIEW_CHECK_LOCAL; } { Lex->create_view_check= VIEW_CHECK_LOCAL; }
; ;
/**************************************************************************
CREATE TRIGGER statement parts.
**************************************************************************/
trigger_tail:
TRIGGER_SYM remember_name sp_name trg_action_time trg_event
ON table_ident FOR_SYM EACH_SYM ROW_SYM
{
LEX *lex= Lex;
sp_head *sp;
if (lex->sphead)
{
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER");
YYABORT;
}
if (!(sp= new sp_head()))
YYABORT;
sp->reset_thd_mem_root(YYTHD);
sp->init(lex);
lex->trigger_definition_begin= $2;
sp->m_type= TYPE_ENUM_TRIGGER;
lex->sphead= sp;
lex->spname= $3;
/*
We have to turn of CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->sphead->m_chistics= &lex->sp_chistics;
lex->sphead->m_body_begin= lex->ptr;
}
sp_proc_stmt
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
lex->sql_command= SQLCOM_CREATE_TRIGGER;
sp->init_strings(YYTHD, lex, $3);
/* Restore flag if it was cleared above */
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
sp->restore_thd_mem_root(YYTHD);
if (sp->is_not_allowed_in_function("trigger"))
YYABORT;
/*
We have to do it after parsing trigger body, because some of
sp_proc_stmt alternatives are not saving/restoring LEX, so
lex->query_tables can be wiped out.
QQ: What are other consequences of this?
QQ: Could we loosen lock type in certain cases ?
*/
if (!lex->select_lex.add_table_to_list(YYTHD, $7,
(LEX_STRING*) 0,
TL_OPTION_UPDATING,
TL_WRITE))
YYABORT;
}
;
/*************************************************************************/
xa: XA_SYM begin_or_start xid opt_join_or_resume xa: XA_SYM begin_or_start xid opt_join_or_resume
{ {
Lex->sql_command = SQLCOM_XA_START; Lex->sql_command = SQLCOM_XA_START;

View File

@ -802,7 +802,15 @@ typedef struct st_nested_join
table_map used_tables; /* bitmap of tables in the nested join */ table_map used_tables; /* bitmap of tables in the nested join */
table_map not_null_tables; /* tables that rejects nulls */ table_map not_null_tables; /* tables that rejects nulls */
struct st_join_table *first_nested;/* the first nested table in the plan */ struct st_join_table *first_nested;/* the first nested table in the plan */
uint counter; /* to count tables in the nested join */ /*
Used to count tables in the nested join in 2 isolated places:
1. In make_outerjoin_info().
2. check_interleaving_with_nj/restore_prev_nj_state (these are called
by the join optimizer.
Before each use the counters are zeroed by reset_nj_counters.
*/
uint counter;
nested_join_map nj_map; /* Bit used to identify this nested join*/
} NESTED_JOIN; } NESTED_JOIN;

View File

@ -95,11 +95,9 @@ public:
/** /**
* NOTE free lists must be _after_ theNdbObjectIdMap take * NOTE free lists must be _after_ theNdbObjectIdMap take
* assure that destructors are run in correct order * assure that destructors are run in correct order
* NOTE these has to be in this specific order to make destructor run in
* correct order
*/ */
Ndb_free_list_t<NdbTransaction> theConIdleList;
Ndb_free_list_t<NdbOperation> theOpIdleList;
Ndb_free_list_t<NdbIndexScanOperation> theScanOpIdleList;
Ndb_free_list_t<NdbIndexOperation> theIndexOpIdleList;
Ndb_free_list_t<NdbRecAttr> theRecAttrIdleList; Ndb_free_list_t<NdbRecAttr> theRecAttrIdleList;
Ndb_free_list_t<NdbApiSignal> theSignalIdleList; Ndb_free_list_t<NdbApiSignal> theSignalIdleList;
Ndb_free_list_t<NdbLabel> theLabelList; Ndb_free_list_t<NdbLabel> theLabelList;
@ -108,6 +106,10 @@ public:
Ndb_free_list_t<NdbCall> theCallList; Ndb_free_list_t<NdbCall> theCallList;
Ndb_free_list_t<NdbBlob> theNdbBlobIdleList; Ndb_free_list_t<NdbBlob> theNdbBlobIdleList;
Ndb_free_list_t<NdbReceiver> theScanList; Ndb_free_list_t<NdbReceiver> theScanList;
Ndb_free_list_t<NdbIndexScanOperation> theScanOpIdleList;
Ndb_free_list_t<NdbOperation> theOpIdleList;
Ndb_free_list_t<NdbIndexOperation> theIndexOpIdleList;
Ndb_free_list_t<NdbTransaction> theConIdleList;
}; };
#ifdef VM_TRACE #ifdef VM_TRACE

View File

@ -24,6 +24,7 @@
NdbRecAttr::NdbRecAttr(Ndb*) NdbRecAttr::NdbRecAttr(Ndb*)
{ {
theStorageX = 0;
init(); init();
} }
@ -51,6 +52,9 @@ NdbRecAttr::setup(const NdbColumnImpl* anAttrInfo, char* aValue)
m_size_in_bytes = tAttrByteSize; m_size_in_bytes = tAttrByteSize;
theValue = aValue; theValue = aValue;
if (theStorageX)
delete[] theStorageX;
// check alignment to signal data // check alignment to signal data
// a future version could check alignment per data type as well // a future version could check alignment per data type as well

View File

@ -973,7 +973,7 @@ int double2decimal(double from, decimal_t *to)
{ {
/* TODO: fix it, when we'll have dtoa */ /* TODO: fix it, when we'll have dtoa */
char s[400], *end; char s[400], *end;
sprintf(s, "%f", from); sprintf(s, "%.16G", from);
end= strend(s); end= strend(s);
return string2decimal(s, to, &end); return string2decimal(s, to, &end);
} }

View File

@ -361,8 +361,9 @@ BuildMySQL "--disable-shared \
%if %{STATIC_BUILD} %if %{STATIC_BUILD}
--with-mysqld-ldflags='-all-static' \ --with-mysqld-ldflags='-all-static' \
--with-client-ldflags='-all-static' \ --with-client-ldflags='-all-static' \
--with-zlib-dir=bundled \
$USE_OTHER_LIBC_DIR \ $USE_OTHER_LIBC_DIR \
%else
--with-zlib-dir=bundled \
%endif %endif
--with-comment=\"MySQL Community Edition - Standard (GPL)\" \ --with-comment=\"MySQL Community Edition - Standard (GPL)\" \
--with-server-suffix='%{server_suffix}' \ --with-server-suffix='%{server_suffix}' \

Some files were not shown because too many files have changed in this diff Show More