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:
commit
41de6f9a7c
145
.bzrignore
145
.bzrignore
@ -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
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
@ -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 )
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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 ---
|
||||||
|
@ -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 //
|
||||||
|
43
mysql-test/r/read_only.result
Normal file
43
mysql-test/r/read_only.result
Normal 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;
|
@ -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 ########
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
40
mysql-test/r/trigger-compat.result
Normal file
40
mysql-test/r/trigger-compat.result
Normal 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
|
238
mysql-test/r/trigger-grant.result
Normal file
238
mysql-test/r/trigger-grant.result
Normal 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.
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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'
|
||||||
|
@ -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
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -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
103
mysql-test/t/read_only.test
Normal 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;
|
@ -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;
|
||||||
|
@ -1 +1 @@
|
|||||||
--log_bin_trust_routine_creators=0
|
--log_bin_trust_routine_creators=0 --slave-skip-errors=1062
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
#
|
#
|
||||||
|
@ -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;
|
||||||
|
83
mysql-test/t/trigger-compat.test
Normal file
83
mysql-test/t/trigger-compat.test
Normal 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;
|
475
mysql-test/t/trigger-grant.test
Normal file
475
mysql-test/t/trigger-grant.test
Normal 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;
|
@ -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)
|
||||||
#
|
#
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
184
mysys/my_open.c
184
mysys/my_open.c
@ -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__ */
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
sql/field.cc
13
sql/field.cc
@ -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 ||
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
31
sql/item.cc
31
sql/item.cc
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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; }
|
||||||
|
@ -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 *);
|
||||||
|
@ -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)
|
||||||
{}
|
{}
|
||||||
|
64
sql/log.cc
64
sql/log.cc
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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},
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -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
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -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=
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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];
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
141
sql/sql_parse.cc
141
sql/sql_parse.cc
@ -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;
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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())
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
361
sql/sql_yacc.yy
361
sql/sql_yacc.yy
@ -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;
|
||||||
|
10
sql/table.h
10
sql/table.h
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user