developers
Threads by month
- ----- 2025 -----
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 8 participants
- 6853 discussions

[Maria-developers] Rev 2780: bzr ignore in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 08 Apr '10
by serg@askmonty.org 08 Apr '10
08 Apr '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2780
revision-id: sergii(a)pisem.net-20100408090706-a196ebold533efvo
parent: sanja(a)askmonty.org-20100406000609-swbb13c0biged8iv
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: 5.2
timestamp: Thu 2010-04-08 11:07:06 +0200
message:
bzr ignore
=== modified file '.bzrignore'
--- a/.bzrignore 2010-03-29 15:13:53 +0000
+++ b/.bzrignore 2010-04-08 09:07:06 +0000
@@ -1934,3 +1934,4 @@ client/sql_list.h
libmysqld/client_plugin.c
sql/client_plugin.c
*.dgcov
+libmysqld/create_options.cc
1
0

[Maria-developers] Rev 2779: MWL#43 CREATE TABLE options in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 08 Apr '10
by serg@askmonty.org 08 Apr '10
08 Apr '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2779
revision-id: sanja(a)askmonty.org-20100406000609-swbb13c0biged8iv
parent: sergii(a)pisem.net-20100407150509-l5lrdmanv1flfsi7
author: sanja(a)askmonty.org
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: work-maria-5.2-createoptions5
timestamp: Tue 2010-04-06 03:06:09 +0300
message:
MWL#43 CREATE TABLE options
Diff too large for email (3333 lines, the limit is 1000).
1
0

[Maria-developers] Rev 2776: post-review changes, and merge of the MWL#43 CREATE TABLE options in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 08 Apr '10
by serg@askmonty.org 08 Apr '10
08 Apr '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2776 [merge]
revision-id: sergii(a)pisem.net-20100408085536-qjt3rz3su3oumthu
parent: sergii(a)pisem.net-20100406110456-zhkf13tvdcywb9tb
parent: sanja(a)askmonty.org-20100406000609-jl8415st523eq5jj
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: 5.2
timestamp: Thu 2010-04-08 10:55:36 +0200
message:
post-review changes, and merge of the MWL#43 CREATE TABLE options
added:
mysql-test/r/create_options.result create_options.resul-20100406150813-x9l18ft2v5asbu6u-1
mysql-test/t/create_options.test create_options.test-20100405221601-8v82yzjsbg8d5t9h-1
sql/create_options.cc create_options.cc-20100405221547-pgejz63vqubo45gk-1
sql/create_options.h create_options.h-20100405221550-zuwt433ekdv7y9u3-1
modified:
.bzrignore sp1f-ignore-20001018235455-q4gxfbritt5f42nwix354ufpsvrf5ebj
Docs/sp-imp-spec.txt sp1f-spimpspec.txt-20030202164941-cm47byoggfqjr73hhqr24vos7luqh36q
include/my_base.h sp1f-my_base.h-19700101030959-3yhq5cta6tatwfxpqmoukzvevlehtxoz
include/my_sys.h sp1f-my_sys.h-19700101030959-lyllvna5vzqfcjnmlcrutgqocylhtb54
libmysqld/CMakeLists.txt sp1f-cmakelists.txt-20060403082523-x3vxka3k56u2wpzwcrlpykznlz2akpxd
libmysqld/Makefile.am sp1f-makefile.am-20010411110351-26htpk3ynkyh7pkfvnshztqrxx3few4g
mysql-test/r/events_bugs.result sp1f-events_bugs.result-20060220225211-jzbz6uk6vlho4vlbzbfymaub54fll3ou
mysql-test/r/information_schema.result sp1f-information_schema.r-20041113105544-waoxa2fjjsicturpothmjmi6jc3yrovn
mysql-test/r/plugin.result sp1f-plugin.result-20061214230953-dljmjo3wuacc3eox3gwroufqmk3hlne7
mysql-test/r/sp.result sp1f-sp.result-20030117133802-duandg3yzagzyv7zhhbbt2kcomcegpc7
mysql-test/r/system_mysql_db.result sp1f-system_mysql_db.resu-20040310185404-f7br5g4442iqwxireltudlyu5ppbkijo
mysql-test/suite/funcs_1/r/is_columns_mysql.result sp1f-is_columns_mysql.res-20080307163304-a2ymkif2vzliwqqqzr22cglbaf75tthe
mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result is_columns_mysql_emb-20080616171935-sl04j972o55obadv-7
mysql-test/t/events_bugs.test sp1f-events_bugs.test-20060220225212-ji5acdijogityb45kk4msvs7h5gn4ld3
mysql-test/t/plugin.test sp1f-plugin.test-20061214230953-rdqkovjzpupoeypjzzvefseahkmrdz4f
mysql-test/t/sp.test sp1f-sp.test-20030117133803-b6pcfv2yscbqkur5fszep7acmdg7nf5k
scripts/mysql_system_tables.sql sp1f-mysql_system_tables.-20070226104923-4n5a67fuifobcyhhicfbacpsv5npohgv
scripts/mysql_system_tables_fix.sql sp1f-mysql_fix_privilege_-20030604152848-cz6lnrig5srcrvkt7d5m35bk3wsz4bdc
sql/CMakeLists.txt sp1f-cmakelists.txt-20060831175237-esoeu5kpdtwjvehkghwy6fzbleniq2wy
sql/Makefile.am sp1f-makefile.am-19700101030959-xsjdiakci3nqcdd4xl4yomwdl5eo2f3q
sql/event_db_repository.cc sp1f-event_db_repository.-20060627064838-k6rpjg72omnihtxhbubu6ht7wjvxggb7
sql/field.cc sp1f-field.cc-19700101030959-f4imaofclsea3n4fj4ow5m7havmyxa2r
sql/field.h sp1f-field.h-19700101030959-3n6smzxcwkjl7bikm3wg4hfkjn66uvvp
sql/ha_partition.cc sp1f-ha_partition.cc-20050718113037-eoky4qluumb5dmdyg5z6n2fvdkgutxms
sql/handler.cc sp1f-handler.cc-19700101030959-ta6zfrlbxzucylciyro3musjsdpocrdh
sql/handler.h sp1f-handler.h-19700101030959-mumq2hpilkpgxuf22ftyv5kbilysnzvn
sql/log_event.h sp1f-log_event.h-19700101030959-clq6ett55tcqbpys2i4cpfrdccq7j4om
sql/mysql_priv.h sp1f-mysql_priv.h-19700101030959-4fl65tqpop5zfgxaxkqotu2fa2ree5ci
sql/mysqld.cc sp1f-mysqld.cc-19700101030959-zpswdvekpvixxzxf7gdtofzel7nywtfj
sql/share/errmsg.txt sp1f-errmsg.txt-20041213212820-do5w642w224ja7ctyqhyl6iihdmpkzv5
sql/sp.cc sp1f-sp.cc-20021212121421-6xwuvxq5bku2b4yv655kp2e5gsvautd5
sql/sp_head.cc sp1f-sp_head.cc-20021208185920-jtgc5wvyqdnu2gvcdus3gazrfhxbofxd
sql/sql_class.cc sp1f-sql_class.cc-19700101030959-rpotnweaff2pikkozh3butrf7mv3oero
sql/sql_class.h sp1f-sql_class.h-19700101030959-jnqnbrjyqsvgncsibnumsmg3lyi7pa5s
sql/sql_insert.cc sp1f-sql_insert.cc-19700101030959-xgwqe5svnimxudzdcuitauljzz2zjk5g
sql/sql_lex.h sp1f-sql_lex.h-19700101030959-sgldb2sooc7twtw5q7pgjx7qzqiaa3sn
sql/sql_parse.cc sp1f-sql_parse.cc-19700101030959-ehcre3rwhv5l3mlxqhaxg36ujenxnrcd
sql/sql_plugin.cc sp1f-sql_plugin.cc-20051105112032-hrm64p6xfjq33ud6zy3uivpo7azm75a2
sql/sql_show.cc sp1f-sql_show.cc-19700101030959-umlljfnpplg452h7reeyqr4xnbmlkvfj
sql/sql_table.cc sp1f-sql_table.cc-19700101030959-tzdkvgigezpuaxnldqh3fx2h7h2ggslu
sql/sql_view.cc sp1f-sql_view.cc-20040715221517-nw4p4mja6nzzlvwwhzfgfqb4umxqobe4
sql/sql_yacc.yy sp1f-sql_yacc.yy-19700101030959-wvn4qyy2drpmge7kaq3dysprbhlrv27j
sql/structs.h sp1f-structs.h-19700101030959-dqulhwijezc2pwv2x4g32qdggnybj2nc
sql/table.cc sp1f-table.cc-19700101030959-nsxtem2adyqzwe6nz4cgrpcmts3o54v7
sql/table.h sp1f-table.h-19700101030959-dv72bajftxj5fbdjuajquappanuv2ija
sql/unireg.cc sp1f-unireg.cc-19700101030959-6a4wymwak6cmvk25gch56ctjvadrhu3v
storage/example/ha_example.cc sp1f-ha_example.cc-20040331231732-d55r4dr2e7cf5dutte3f74z6h6yxdywb
storage/example/ha_example.h sp1f-ha_example.h-20040331231733-ssl4zmhqjrevhtqixivtivdmlwiau2x5
storage/pbxt/src/discover_xt.cc discover_xt.cc-20090326121724-x683v32twzr3fi0y-26
Diff too large for email (3198 lines, the limit is 1000).
1
0

[Maria-developers] Rev 33: Added: in file:///Users/hakan/work/monty_program/mariadb-tools/
by Hakan Kuecuekyilmaz 08 Apr '10
by Hakan Kuecuekyilmaz 08 Apr '10
08 Apr '10
At file:///Users/hakan/work/monty_program/mariadb-tools/
------------------------------------------------------------
revno: 33
revision-id: hakan(a)askmonty.org-20100408002114-36ml405ax1h61x60
parent: hakan(a)askmonty.org-20100407121715-2k24p66xyfkgpdpn
committer: Hakan Kuecuekyilmaz <hakan(a)askmonty.org>
branch nick: mariadb-tools
timestamp: Thu 2010-04-08 02:21:14 +0200
message:
Added:
* IO utilization with iostat
* CPU utilization with mpstat
* Simple queries/second monitoring per test with mysqladmin --sleep 10 status
* Tests can have options now
** select_random_points has option for number of points
** select_random_ragnes has option for number of ranges and delta of ranges.
=== modified file 'sysbench/run-sysbench-myisam.sh'
--- a/sysbench/run-sysbench-myisam.sh 2010-04-07 12:17:15 +0000
+++ b/sysbench/run-sysbench-myisam.sh 2010-04-08 00:21:14 +0000
@@ -106,16 +106,26 @@
# We need at least 1 GB disk space in our $WORK_DIR.
SPACE_LIMIT=1000000
-SYSBENCH_TESTS="delete.lua \
- insert.lua \
- oltp_complex_ro.lua \
- oltp_complex_rw.lua \
- oltp_simple.lua \
- select.lua \
- select_random_points.lua \
- select_random_ranges.lua \
- update_index.lua \
- update_non_index.lua"
+# Interval in seconds for monitoring system status like disk IO,
+# CPU utilization, and such.
+MONITOR_INTERVAL=10
+
+SYSBENCH_TESTS[0]="delete.lua"
+SYSBENCH_TESTS[1]="insert.lua"
+SYSBENCH_TESTS[2]="oltp_complex_ro.lua"
+SYSBENCH_TESTS[3]="oltp_complex_rw.lua"
+SYSBENCH_TESTS[4]="oltp_simple.lua"
+SYSBENCH_TESTS[5]="select.lua"
+
+# Default option is --random-points=10.
+SYSBENCH_TESTS[6]="select_random_points.lua"
+
+# Default options are
+# --number-of-ranges=10
+# --random-ranges-delta=5.
+SYSBENCH_TESTS[7]="select_random_ranges.lua"
+SYSBENCH_TESTS[8]="update_index.lua"
+SYSBENCH_TESTS[9]="update_non_index.lua"
#
# Note: myisam-max-rows has to match or exceed oltp-table-size
@@ -277,7 +287,7 @@
}
#
-# Write out configurations used for future refernce.
+# Write out configurations used for future reference.
#
echo $MYSQLD_OPTIONS > ${RESULT_DIR}/${TODAY}/${PRODUCT}/mysqld_options.txt
echo $SYSBENCH_OPTIONS > ${RESULT_DIR}/${TODAY}/${PRODUCT}/sysbench_options.txt
@@ -285,8 +295,17 @@
echo "Warm up time is: $WARM_UP_TIME" >> ${RESULT_DIR}/${TODAY}/${PRODUCT}/sysbench_options.txt
echo "Run time is: $RUN_TIME" >> ${RESULT_DIR}/${TODAY}/${PRODUCT}/sysbench_options.txt
-for SYSBENCH_TEST in $SYSBENCH_TESTS
+#
+# Kill possibly left over monitoring processes.
+#
+killall -9 iostat
+killall -9 mpstat
+killall -9 mysqladmin
+
+for (( i = 0 ; i < ${#SYSBENCH_TESTS[@]} ; i++ ))
do
+ # Get rid of any options of given sysbench test.
+ SYSBENCH_TEST=$(echo "${SYSBENCH_TESTS[$i]}" | awk '{ print $1 }')
mkdir ${RESULT_DIR}/${TODAY}/${PRODUCT}/${SYSBENCH_TEST}
kill_mysqld
@@ -299,8 +318,8 @@
exit 1
fi
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Preparing and loading data for $SYSBENCH_TEST."
- SYSBENCH_OPTIONS="${SYSBENCH_OPTIONS} --test=${TEST_DIR}/${SYSBENCH_TEST}"
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Preparing and loading data for ${SYSBENCH_TESTS[$i]}."
+ SYSBENCH_OPTIONS="${SYSBENCH_OPTIONS} --test=${TEST_DIR}/${SYSBENCH_TESTS[$i]}"
$SYSBENCH $SYSBENCH_OPTIONS --max-time=$RUN_TIME prepare
$MYSQLADMIN $MYSQLADMIN_OPTIONS shutdown
@@ -308,14 +327,14 @@
rm -rf ${SYSBENCH_DB_BACKUP}
mkdir ${SYSBENCH_DB_BACKUP}
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Copying $DATA_DIR of $SYSBENCH_TEST for later usage."
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Copying $DATA_DIR of ${SYSBENCH_TESTS[$i]} for later usage."
cp -a ${DATA_DIR}/* ${SYSBENCH_DB_BACKUP}/
for THREADS in $NUM_THREADS
do
THIS_RESULT_DIR="${RESULT_DIR}/${TODAY}/${PRODUCT}/${SYSBENCH_TEST}/${THREADS}"
mkdir $THIS_RESULT_DIR
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Running $SYSBENCH_TEST with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT" | tee ${THIS_RESULT_DIR}/results.txt
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Running ${SYSBENCH_TESTS[$i]} with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT" | tee ${THIS_RESULT_DIR}/results.txt
echo '' >> ${THIS_RESULT_DIR}/results.txt
SYSBENCH_OPTIONS_WARM_UP="${SYSBENCH_OPTIONS} --num-threads=3 --max-time=$WARM_UP_TIME"
@@ -325,7 +344,7 @@
while [ $k -lt $LOOP_COUNT ]
do
echo ''
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Killing mysqld and copying back $DATA_DIR for $SYSBENCH_TEST."
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Killing mysqld and copying back $DATA_DIR for ${SYSBENCH_TESTS[$i]}."
kill_mysqld
cp -a ${SYSBENCH_DB_BACKUP}/* ${DATA_DIR}
@@ -334,7 +353,7 @@
sync
echo 3 | $SUDO tee /proc/sys/vm/drop_caches
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Starting mysqld for running $SYSBENCH_TEST with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT"
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Starting mysqld for running ${SYSBENCH_TESTS[$i]} with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT"
start_mysqld
sync
@@ -346,8 +365,25 @@
echo "[$(date "+%Y-%m-%d %H:%M:%S")] Finnished warm up."
echo "[$(date "+%Y-%m-%d %H:%M:%S")] Starting actual sysbench run."
+
+ $IOSTAT -d -k $IOSTAT_DEVICE $MONITOR_INTERVAL > ${THIS_RESULT_DIR}/iostat${k}.txt 2>&1 &
+ IOSTAT_PID=$!
+
+ $MPSTAT -u $MONITOR_INTERVAL > ${THIS_RESULT_DIR}/cpustat${k}.txt 2>&1 &
+ MPSTAT_PID=$!
+
+ $MYSQLADMIN $MYSQLADMIN_OPTIONS --sleep $MONITOR_INTERVAL status > ${THIS_RESULT_DIR}/server_status${k}.txt 2>&1 &
+ SERVER_STATUS_PID=$!
+
$SYSBENCH $SYSBENCH_OPTIONS_RUN run > ${THIS_RESULT_DIR}/result${k}.txt 2>&1
+ sync; sync; sync
+ sleep 1
+
+ kill -9 $SERVER_STATUS_PID
+ kill -9 $MPSTAT_PID
+ kill -9 $IOSTAT_PID
+
grep "write requests:" ${THIS_RESULT_DIR}/result${k}.txt | awk '{ print $4 }' | sed -e 's/(//' >> ${THIS_RESULT_DIR}/results.txt
echo 'SELECT * FROM INFORMATION_SCHEMA.KEY_CACHES' | $MYSQL $MYSQL_OPTIONS > ${THIS_RESULT_DIR}/key_cache_stats${k}.txt
@@ -356,7 +392,7 @@
done
echo '' >> ${THIS_RESULT_DIR}/results.txt
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Finnished $SYSBENCH_TEST with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT" | tee -a ${THIS_RESULT_DIR}/results.txt
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Finnished ${SYSBENCH_TESTS[$i]} with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT" | tee -a ${THIS_RESULT_DIR}/results.txt
done
done
=== modified file 'sysbench/run-sysbench.sh'
--- a/sysbench/run-sysbench.sh 2010-04-07 12:17:15 +0000
+++ b/sysbench/run-sysbench.sh 2010-04-08 00:21:14 +0000
@@ -103,16 +103,26 @@
# We need at least 1 GB disk space in our $WORK_DIR.
SPACE_LIMIT=1000000
-SYSBENCH_TESTS="delete.lua \
- insert.lua \
- oltp_complex_ro.lua \
- oltp_complex_rw.lua \
- oltp_simple.lua \
- select.lua \
- select_random_points.lua \
- select_random_ranges.lua \
- update_index.lua \
- update_non_index.lua"
+# Interval in seconds for monitoring system status like disk IO,
+# CPU utilization, and such.
+MONITOR_INTERVAL=10
+
+SYSBENCH_TESTS[0]="delete.lua"
+SYSBENCH_TESTS[1]="insert.lua"
+SYSBENCH_TESTS[2]="oltp_complex_ro.lua"
+SYSBENCH_TESTS[3]="oltp_complex_rw.lua"
+SYSBENCH_TESTS[4]="oltp_simple.lua"
+SYSBENCH_TESTS[5]="select.lua"
+
+# Default option is --random-points=10.
+SYSBENCH_TESTS[6]="select_random_points.lua"
+
+# Default options are
+# --number-of-ranges=10
+# --random-ranges-delta=5.
+SYSBENCH_TESTS[7]="select_random_ranges.lua"
+SYSBENCH_TESTS[8]="update_index.lua"
+SYSBENCH_TESTS[9]="update_non_index.lua"
SYSBENCH_OPTIONS="--oltp-table-size=$TABLE_SIZE \
--max-requests=0 \
@@ -269,7 +279,7 @@
}
#
-# Write out configurations used for future refernce.
+# Write out configurations used for future reference.
#
echo $MYSQLD_OPTIONS > ${RESULT_DIR}/${TODAY}/${PRODUCT}/mysqld_options.txt
echo $SYSBENCH_OPTIONS > ${RESULT_DIR}/${TODAY}/${PRODUCT}/sysbench_options.txt
@@ -277,8 +287,17 @@
echo "Warm up time is: $WARM_UP_TIME" >> ${RESULT_DIR}/${TODAY}/${PRODUCT}/sysbench_options.txt
echo "Run time is: $RUN_TIME" >> ${RESULT_DIR}/${TODAY}/${PRODUCT}/sysbench_options.txt
-for SYSBENCH_TEST in $SYSBENCH_TESTS
+#
+# Kill possibly left over monitoring processes.
+#
+killall -9 iostat
+killall -9 mpstat
+killall -9 mysqladmin
+
+for (( i = 0 ; i < ${#SYSBENCH_TESTS[@]} ; i++ ))
do
+ # Get rid of any options of given sysbench test.
+ SYSBENCH_TEST=$(echo "${SYSBENCH_TESTS[$i]}" | awk '{ print $1 }')
mkdir ${RESULT_DIR}/${TODAY}/${PRODUCT}/${SYSBENCH_TEST}
kill_mysqld
@@ -291,8 +310,8 @@
exit 1
fi
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Preparing and loading data for $SYSBENCH_TEST."
- SYSBENCH_OPTIONS="${SYSBENCH_OPTIONS} --test=${TEST_DIR}/${SYSBENCH_TEST}"
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Preparing and loading data for ${SYSBENCH_TESTS[$i]}."
+ SYSBENCH_OPTIONS="${SYSBENCH_OPTIONS} --test=${TEST_DIR}/${SYSBENCH_TESTS[$i]}"
$SYSBENCH $SYSBENCH_OPTIONS --max-time=$RUN_TIME prepare
$MYSQLADMIN $MYSQLADMIN_OPTIONS shutdown
@@ -300,14 +319,14 @@
rm -rf ${SYSBENCH_DB_BACKUP}
mkdir ${SYSBENCH_DB_BACKUP}
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Copying $DATA_DIR of $SYSBENCH_TEST for later usage."
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Copying $DATA_DIR of ${SYSBENCH_TESTS[$i]} for later usage."
cp -a ${DATA_DIR}/* ${SYSBENCH_DB_BACKUP}/
for THREADS in $NUM_THREADS
do
THIS_RESULT_DIR="${RESULT_DIR}/${TODAY}/${PRODUCT}/${SYSBENCH_TEST}/${THREADS}"
mkdir $THIS_RESULT_DIR
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Running $SYSBENCH_TEST with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT" | tee ${THIS_RESULT_DIR}/results.txt
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Running ${SYSBENCH_TESTS[$i]} with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT" | tee ${THIS_RESULT_DIR}/results.txt
echo '' >> ${THIS_RESULT_DIR}/results.txt
SYSBENCH_OPTIONS_WARM_UP="${SYSBENCH_OPTIONS} --num-threads=1 --max-time=$WARM_UP_TIME"
@@ -317,7 +336,7 @@
while [ $k -lt $LOOP_COUNT ]
do
echo ''
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Killing mysqld and copying back $DATA_DIR for $SYSBENCH_TEST."
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Killing mysqld and copying back $DATA_DIR for ${SYSBENCH_TESTS[$i]}."
kill_mysqld
cp -a ${SYSBENCH_DB_BACKUP}/* ${DATA_DIR}
@@ -326,7 +345,7 @@
sync
echo 3 | $SUDO tee /proc/sys/vm/drop_caches
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Starting mysqld for running $SYSBENCH_TEST with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT"
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Starting mysqld for running ${SYSBENCH_TESTS[$i]} with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT"
start_mysqld
sync
@@ -337,15 +356,32 @@
echo "[$(date "+%Y-%m-%d %H:%M:%S")] Finnished warm up."
echo "[$(date "+%Y-%m-%d %H:%M:%S")] Starting actual sysbench run."
+
+ $IOSTAT -d -k $IOSTAT_DEVICE $MONITOR_INTERVAL > ${THIS_RESULT_DIR}/iostat${k}.txt 2>&1 &
+ IOSTAT_PID=$!
+
+ $MPSTAT -u $MONITOR_INTERVAL > ${THIS_RESULT_DIR}/cpustat${k}.txt 2>&1 &
+ MPSTAT_PID=$!
+
+ $MYSQLADMIN $MYSQLADMIN_OPTIONS --sleep $MONITOR_INTERVAL status > ${THIS_RESULT_DIR}/server_status${k}.txt 2>&1 &
+ SERVER_STATUS_PID=$!
+
$SYSBENCH $SYSBENCH_OPTIONS_RUN run > ${THIS_RESULT_DIR}/result${k}.txt 2>&1
-
+
+ sync; sync; sync
+ sleep 1
+
+ kill -9 $SERVER_STATUS_PID
+ kill -9 $MPSTAT_PID
+ kill -9 $IOSTAT_PID
+
grep "write requests:" ${THIS_RESULT_DIR}/result${k}.txt | awk '{ print $4 }' | sed -e 's/(//' >> ${THIS_RESULT_DIR}/results.txt
k=$(($k + 1))
done
echo '' >> ${THIS_RESULT_DIR}/results.txt
- echo "[$(date "+%Y-%m-%d %H:%M:%S")] Finnished $SYSBENCH_TEST with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT" | tee -a ${THIS_RESULT_DIR}/results.txt
+ echo "[$(date "+%Y-%m-%d %H:%M:%S")] Finnished ${SYSBENCH_TESTS[$i]} with $THREADS threads and $LOOP_COUNT iterations for $PRODUCT" | tee -a ${THIS_RESULT_DIR}/results.txt
done
done
1
0

[Maria-developers] [Branch ~maria-captains/maria/5.1] Rev 2842: Fixed suppression of compiler/test warnings
by noreply@launchpad.net 07 Apr '10
by noreply@launchpad.net 07 Apr '10
07 Apr '10
------------------------------------------------------------
revno: 2842
committer: Michael Widenius <monty(a)askmonty.org>
branch nick: maria-5.1
timestamp: Wed 2010-04-07 18:26:30 +0300
message:
Fixed suppression of compiler/test warnings
Fixed some timing issues in test suite
modified:
mysql-test/mysql-test-run.pl
mysql-test/suite/funcs_1/datadict/processlist_priv.inc
mysql-test/suite/pbxt/t/status.test
support-files/compiler_warnings.supp
--
lp:maria
https://code.launchpad.net/~maria-captains/maria/5.1
Your team Maria developers is subscribed to branch lp:maria.
To unsubscribe from this branch go to https://code.launchpad.net/~maria-captains/maria/5.1/+edit-subscription
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2842)
by Michael Widenius 07 Apr '10
by Michael Widenius 07 Apr '10
07 Apr '10
#At lp:maria based on revid:monty@askmonty.org-20100406224708-i62wvtw3nl14fhv4
2842 Michael Widenius 2010-04-07
Fixed suppression of compiler/test warnings
Fixed some timing issues in test suite
modified:
mysql-test/mysql-test-run.pl
mysql-test/suite/funcs_1/datadict/processlist_priv.inc
mysql-test/suite/pbxt/t/status.test
support-files/compiler_warnings.supp
per-file messages:
mysql-test/mysql-test-run.pl
Added suppression of errors that comes when master is killed before slave has connect (like with rpl_udf.test)
mysql-test/suite/funcs_1/datadict/processlist_priv.inc
Wait for check thread to end
mysql-test/suite/pbxt/t/status.test
Added longer sleep to avoid timing issue
support-files/compiler_warnings.supp
Fixed wrong suppression
=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl 2010-03-10 10:32:14 +0000
+++ b/mysql-test/mysql-test-run.pl 2010-04-07 15:26:30 +0000
@@ -4015,7 +4015,10 @@ sub extract_warning_lines ($) {
qr/Slave I\/O: Get master COLLATION_SERVER failed with error:.*/,
qr/Slave I\/O: Get master TIME_ZONE failed with error:.*/,
qr/Slave I\/O: error reconnecting to master '.*' - retry-time: [1-3] retries/,
+ qr/Slave I\/0: Master command COM_BINLOG_DUMP failed/,
qr/Error reading packet/,
+ qr/Lost connection to MySQL server at 'reading initial communication packet'/,
+ qr/Failed on request_dump/,
qr/Slave: Can't drop database.* database doesn't exist/,
qr/Slave: Operation DROP USER failed for 'create_rout_db'/,
qr|Checking table: '\./mtr/test_suppressions'|,
=== modified file 'mysql-test/suite/funcs_1/datadict/processlist_priv.inc'
--- a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc 2009-10-10 09:59:06 +0000
+++ b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc 2010-04-07 15:26:30 +0000
@@ -89,18 +89,38 @@ USE information_schema;
--echo 1 Prepare test.
--echo connection default (user=root)
--echo ####################################################################################
-if (`SELECT COUNT(*) <> 1 FROM processlist`)
+
+# Check that we have only one connection around.
+# If there is more, it may be the check() connection that has not yet ended,
+# so we wait for it for up to 10 seconds.
+
+let $counter=100;
+while ($counter)
{
- --echo This test expects one connection to the server.
- --echo Expectation: USER HOST DB COMMAND STATE INFO
- --echo Expectation: root localhost information_schema Query executing SELECT USER,HOST,DB,COMMAND,STATE,INFO FROM processlist ORDER BY ID
- --echo But we found in the moment:
- SELECT USER,HOST,DB,COMMAND,STATE,INFO FROM processlist ORDER BY ID;
- --echo Maybe
- --echo - the base configuration (no of parallel auxiliary sessions) of the server has changed
- --echo - a parallel test intended for another server accidently connected to our current one
- --echo We cannot proceed in this situation. Abort
- exit;
+ dec $counter;
+ let $res= `SELECT COUNT(*) <> 1 FROM processlist`;
+ if (!$res)
+ {
+ # Success; Abort while loop
+ let $counter=0;
+ }
+ if ($res)
+ {
+ --sleep 0.1
+ if (!$counter)
+ {
+ --echo This test expects one connection to the server.
+ --echo Expectation: USER HOST DB COMMAND STATE INFO
+ --echo Expectation: root localhost information_schema Query executing SELECT USER,HOST,DB,COMMAND,STATE,INFO FROM processlist ORDER BY ID
+ --echo But we found in the moment:
+ SELECT USER,HOST,DB,COMMAND,STATE,INFO FROM processlist ORDER BY ID;
+ --echo Maybe
+ --echo - the base configuration (no of parallel auxiliary sessions) of the server has changed
+ --echo - a parallel test intended for another server accidently connected to our current one
+ --echo We cannot proceed in this situation. Abort
+ exit;
+ }
+ }
}
--echo ####################################################################################
=== modified file 'mysql-test/suite/pbxt/t/status.test'
--- a/mysql-test/suite/pbxt/t/status.test 2009-04-02 10:03:14 +0000
+++ b/mysql-test/suite/pbxt/t/status.test 2010-04-07 15:26:30 +0000
@@ -30,7 +30,7 @@ connection con1;
--send
update t1 set n = 3;
connection con2;
-sleep 0.5;
+sleep 5;
unlock tables;
connection con1;
reap;
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-04-06 22:47:08 +0000
+++ b/support-files/compiler_warnings.supp 2010-04-07 15:26:30 +0000
@@ -40,7 +40,7 @@ sync/sync0sync\.c: unused parameter
sync/sync0sync\.c: unused variable
ut/ut0ut\.c: ignoring return value of
srv/srv0srv\.c: value computed is not used
-buf/buf0buf\.c: warning: .*block_mutex.* might be used uninitialized
+buf/buf0buf\.c: .*block_mutex.* might be used uninitialized
#
# bdb is not critical to keep up to date
1
0
Hi Sanja,
On Wed, Apr 07, 2010 at 01:54:25PM +0300, Oleksandr Byelkin wrote:
> I found 1 interesting test case:
>
> create table t1 (a int, b int);
> insert into t1 values (1,2),(3,4),(1,2),(3,4),(3,4),(4,5),(4,5),(5,6),
> (5,6),(4,5);
> create table t2 (c int, d int);
> insert into t2 values (2,3),(3,4),(5,6);
>
> select a, b from t1 where b in (select d from t2);
>
> It crashes but only if test case started with --debug.
I assume this is with current lp:~maria-captains/maria/5.3-subqueries? I'll
take a look.
> Also could you give me example where Item_in_optimizer will be used for
> sure (in above example it looks like it is not used).
Basically, subquery must not be a semi-join. The easiest way to achieve this is
to make it so that the subuqery is not an AND-part of ther WHERE anymore.
The following will use Item_in_optimizer:
select a, b, b in (select d from t2) as SUBQ from t1 ;
select a, b from t1 where b in (select d from t2) or b < 3;
If you want to get lots of test coverage fast, include the standard
subselect*.test after having done:
SET optimizer_switch='semijoin=off,materialization=off';
This will cause Item_in_optimizer to be used for every IN subquery.
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
1

[Maria-developers] Rev 32: * Increased run time to 20 minutes in file:///Users/hakan/work/monty_program/mariadb-tools/
by Hakan Kuecuekyilmaz 07 Apr '10
by Hakan Kuecuekyilmaz 07 Apr '10
07 Apr '10
At file:///Users/hakan/work/monty_program/mariadb-tools/
------------------------------------------------------------
revno: 32
revision-id: hakan(a)askmonty.org-20100407121715-2k24p66xyfkgpdpn
parent: hakan(a)askmonty.org-20100331181744-71hyuyjjlijrsl68
committer: Hakan Kuecuekyilmaz <hakan(a)askmonty.org>
branch nick: mariadb-tools
timestamp: Wed 2010-04-07 14:17:15 +0200
message:
* Increased run time to 20 minutes
* Increased warm up time to 5 minutes
* Added select_random_points.lua and select_random_ranges.lua tests
* Added --log-error to mysqld startup options to catch errors and crashes.
=== modified file 'sysbench/run-sysbench-myisam.sh'
--- a/sysbench/run-sysbench-myisam.sh 2010-03-31 18:16:51 +0000
+++ b/sysbench/run-sysbench-myisam.sh 2010-04-07 12:17:15 +0000
@@ -17,6 +17,7 @@
# * oltp_complex_rw.lua 313M sbtest.MYI
# * oltp_simple.lua 325M sbtest.MYI
# * select.lua 313M sbtest.MYI
+# * select_random_points.lua 313M sbtest.MYI
# * select_random_ranges.lua 313M sbtest.MYI
# * update_index.lua 313M sbtest.MYI
# * update_non_index.lua 313M sbtest.MYI
@@ -75,6 +76,7 @@
MYSQLD_OPTIONS="--no-defaults \
--datadir=$DATA_DIR \
--language=./sql/share/english \
+ --log-error \
--key_buffer_size=32M \
--max_connections=256 \
--query_cache_size=0 \
@@ -93,7 +95,7 @@
TABLE_SIZE=20000000
# The run time we use for sysbench.
-RUN_TIME=1800
+RUN_TIME=1200
# Warm up time we use for sysbench.
WARM_UP_TIME=300
@@ -110,6 +112,7 @@
oltp_complex_rw.lua \
oltp_simple.lua \
select.lua \
+ select_random_points.lua \
select_random_ranges.lua \
update_index.lua \
update_non_index.lua"
=== modified file 'sysbench/run-sysbench.sh'
--- a/sysbench/run-sysbench.sh 2010-03-31 18:16:51 +0000
+++ b/sysbench/run-sysbench.sh 2010-04-07 12:17:15 +0000
@@ -62,6 +62,7 @@
MYSQLD_OPTIONS="--no-defaults \
--datadir=$DATA_DIR \
--language=./sql/share/english \
+ --log-error \
--max_connections=256 \
--query_cache_size=0 \
--query_cache_type=0 \
@@ -91,10 +92,10 @@
TABLE_SIZE=2000000
# The run time we use for sysbench.
-RUN_TIME=300
+RUN_TIME=1200
# Warm up time we use for sysbench.
-WARM_UP_TIME=180
+WARM_UP_TIME=300
# How many times we run each test.
LOOP_COUNT=3
@@ -108,6 +109,8 @@
oltp_complex_rw.lua \
oltp_simple.lua \
select.lua \
+ select_random_points.lua \
+ select_random_ranges.lua \
update_index.lua \
update_non_index.lua"
1
0

[Maria-developers] [Branch ~maria-captains/maria/5.1] Rev 2841: Removed compiler warnings
by noreply@launchpad.net 07 Apr '10
by noreply@launchpad.net 07 Apr '10
07 Apr '10
------------------------------------------------------------
revno: 2841
committer: Michael Widenius <monty(a)askmonty.org>
branch nick: maria-5.1
timestamp: Wed 2010-04-07 01:47:08 +0300
message:
Removed compiler warnings
Removed random failures from test suite
added:
mysql-test/suite/binlog/t/binlog_index-master.opt
mysql-test/suite/pbxt/t/multi_statement-master.opt
modified:
mysql-test/extra/rpl_tests/rpl_insert_id_pk.test
mysql-test/include/maria_empty_logs.inc
mysql-test/suite/binlog/r/binlog_index.result
mysql-test/suite/binlog/t/binlog_index.test
mysql-test/suite/pbxt/r/multi_statement.result
sql/events.cc
sql/handler.cc
sql/log.cc
sql/mysqld.cc
sql/set_var.cc
sql/slave.cc
sql/sql_plugin.cc
storage/xtradb/include/ut0lst.h
support-files/compiler_warnings.supp
--
lp:maria
https://code.launchpad.net/~maria-captains/maria/5.1
Your team Maria developers is subscribed to branch lp:maria.
To unsubscribe from this branch go to https://code.launchpad.net/~maria-captains/maria/5.1/+edit-subscription
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2841)
by Michael Widenius 07 Apr '10
by Michael Widenius 07 Apr '10
07 Apr '10
#At lp:maria based on revid:monty@askmonty.org-20100401094011-hdhc99gn00rhidy5
2841 Michael Widenius 2010-04-07
Removed compiler warnings
Removed random failures from test suite
added:
mysql-test/suite/binlog/t/binlog_index-master.opt
mysql-test/suite/pbxt/t/multi_statement-master.opt
modified:
mysql-test/extra/rpl_tests/rpl_insert_id_pk.test
mysql-test/include/maria_empty_logs.inc
mysql-test/suite/binlog/r/binlog_index.result
mysql-test/suite/binlog/t/binlog_index.test
mysql-test/suite/pbxt/r/multi_statement.result
sql/events.cc
sql/handler.cc
sql/log.cc
sql/mysqld.cc
sql/set_var.cc
sql/slave.cc
sql/sql_plugin.cc
storage/xtradb/include/ut0lst.h
support-files/compiler_warnings.supp
per-file messages:
mysql-test/extra/rpl_tests/rpl_insert_id_pk.test
Make test predicatable.
mysql-test/include/maria_empty_logs.inc
We can't use 'Threads_connected' for syncronization, as the 'check_warnings' thread that just quit may still be counted in 'Threads_connected'
Now we just wait until MySQLD answers again, which should be good enough for our purposes
mysql-test/suite/binlog/r/binlog_index.result
Updated results file
mysql-test/suite/binlog/t/binlog_index-master.opt
Added option file to not get stack traces in .err file.
mysql-test/suite/binlog/t/binlog_index.test
Added 'flush tables' to remove warning about crashed suppression file from logs
mysql-test/suite/pbxt/r/multi_statement.result
Updated results
mysql-test/suite/pbxt/t/multi_statement-master.opt
Added options so that slow query testing makes sense
sql/events.cc
Don't write Event Scheduler startup message if warnings are turned off.
sql/handler.cc
Removed compiler warning
sql/log.cc
Removed compiler warning
sql/mysqld.cc
Added option 'test-expect-abort'; If this is set, we don't write message to log in case of 'DBUG_ABORT'.
(Gives us smaller, easier to read log files)
sql/set_var.cc
Removed compiler warning
sql/slave.cc
Removed compiler warning
sql/sql_plugin.cc
Don't write warnings about disabled plugin if using --log_warnings=0
storage/xtradb/include/ut0lst.h
Removed compiler warning
support-files/compiler_warnings.supp
Supress warning from xtradb
=== modified file 'mysql-test/extra/rpl_tests/rpl_insert_id_pk.test'
--- a/mysql-test/extra/rpl_tests/rpl_insert_id_pk.test 2007-06-06 17:57:07 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_insert_id_pk.test 2010-04-06 22:47:08 +0000
@@ -82,7 +82,6 @@ SET FOREIGN_KEY_CHECKS=0;
# Duplicate Key Errors codes
--error 1022, ER_DUP_ENTRY
INSERT INTO t1 VALUES (1),(1);
-sync_slave_with_master;
-connection master;
drop table t1;
+sync_slave_with_master;
# End of 4.1 tests
=== modified file 'mysql-test/include/maria_empty_logs.inc'
--- a/mysql-test/include/maria_empty_logs.inc 2009-10-13 12:47:17 +0000
+++ b/mysql-test/include/maria_empty_logs.inc 2010-04-06 22:47:08 +0000
@@ -11,9 +11,10 @@
connection default;
let $default_db=`select database()`;
let $MYSQLD_DATADIR= `SELECT @@datadir`;
-# it will used at end of test for wait_for_status_var.inc primitive
-let $status_var= Threads_connected;
-let $status_var_value= query_get_value(SHOW STATUS LIKE 'Threads_connected', Value, 1);
+
+#it will used at end of test for wait_for_status_var.inc primitive
+#let $status_var= Threads_connected;
+#let $status_var_value= query_get_value(SHOW STATUS LIKE 'Threads_connected', Value, 1);
connection admin;
-- echo * shut down mysqld, removed logs, restarted it
@@ -77,12 +78,15 @@ append_file $MYSQLTEST_VARDIR/tmp/mysqld
restart-maria_empty_logs.inc
EOF
+connection default;
--source include/wait_until_connected_again.inc
-connection default;
# Make sure that all connections are restored
---source include/wait_for_status_var.inc
+# This is disabled as 'Threads_connected' can't be trusted'
+# (It may be affected by 'check_testcase()')
+# --source include/wait_for_status_var.inc
# Restore current database as the effect of "use" was lost after restart
+
--disable_query_log
eval use $default_db;
--enable_query_log
=== modified file 'mysql-test/suite/binlog/r/binlog_index.result'
--- a/mysql-test/suite/binlog/r/binlog_index.result 2009-12-16 19:52:56 +0000
+++ b/mysql-test/suite/binlog/r/binlog_index.result 2010-04-06 22:47:08 +0000
@@ -3,6 +3,7 @@ call mtr.add_suppression('MSYQL_BIN_LOG:
call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file');
call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.');
call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.');
+flush tables;
flush logs;
flush logs;
flush logs;
=== added file 'mysql-test/suite/binlog/t/binlog_index-master.opt'
--- a/mysql-test/suite/binlog/t/binlog_index-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/t/binlog_index-master.opt 2010-04-06 22:47:08 +0000
@@ -0,0 +1 @@
+--skip-stack-trace --test-expect-abort --log-warnings=0
=== modified file 'mysql-test/suite/binlog/t/binlog_index.test'
--- a/mysql-test/suite/binlog/t/binlog_index.test 2009-12-08 16:03:19 +0000
+++ b/mysql-test/suite/binlog/t/binlog_index.test 2010-04-06 22:47:08 +0000
@@ -11,6 +11,8 @@ call mtr.add_suppression('MSYQL_BIN_LOG:
call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file');
call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.');
call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.');
+flush tables;
+
let $old=`select @@debug`;
let $MYSQLD_DATADIR= `select @@datadir`;
=== modified file 'mysql-test/suite/pbxt/r/multi_statement.result'
--- a/mysql-test/suite/pbxt/r/multi_statement.result 2009-04-02 10:03:14 +0000
+++ b/mysql-test/suite/pbxt/r/multi_statement.result 2010-04-06 22:47:08 +0000
@@ -47,5 +47,5 @@ i
3
show status like 'Slow_queries'||||
Variable_name Value
-Slow_queries 0
+Slow_queries 3
drop table t1||||
=== added file 'mysql-test/suite/pbxt/t/multi_statement-master.opt'
--- a/mysql-test/suite/pbxt/t/multi_statement-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/multi_statement-master.opt 2010-04-06 22:47:08 +0000
@@ -0,0 +1,3 @@
+--slow-query-log
+--slow-query-log-file=slow.log
+--log-queries-not-using-indexes
=== modified file 'sql/events.cc'
--- a/sql/events.cc 2010-03-04 08:03:07 +0000
+++ b/sql/events.cc 2010-04-06 22:47:08 +0000
@@ -1263,8 +1263,9 @@ Events::load_events_from_db(THD *thd)
}
}
}
- sql_print_information("Event Scheduler: Loaded %d event%s",
- count, (count == 1) ? "" : "s");
+ if (global_system_variables.log_warnings)
+ sql_print_information("Event Scheduler: Loaded %d event%s",
+ count, (count == 1) ? "" : "s");
ret= FALSE;
end:
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-03-30 12:36:49 +0000
+++ b/sql/handler.cc 2010-04-06 22:47:08 +0000
@@ -4298,6 +4298,8 @@ int handler::index_read_idx_map(uchar *
enum ha_rkey_function find_flag)
{
int error, error1;
+ LINT_INIT(error1);
+
error= index_init(index, 0);
if (!error)
{
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-03-24 22:12:39 +0000
+++ b/sql/log.cc 2010-04-06 22:47:08 +0000
@@ -1216,6 +1216,7 @@ void LOGGER::deactivate_log_handler(THD
{
my_bool *tmp_opt= 0;
MYSQL_LOG *file_log;
+ LINT_INIT(file_log);
switch (log_type) {
case QUERY_LOG_SLOW:
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-30 12:36:49 +0000
+++ b/sql/mysqld.cc 2010-04-06 22:47:08 +0000
@@ -1,4 +1,5 @@
/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+ 2009-2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -382,7 +383,7 @@ static bool volatile select_thread_in_us
static bool volatile ready_to_exit;
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
static my_bool opt_short_log_format= 0;
-static my_bool opt_ignore_wrong_options= 0;
+static my_bool opt_ignore_wrong_options= 0, opt_expect_abort= 0;
static uint kill_cached_threads, wake_thread;
ulong thread_created;
static ulong max_used_connections;
@@ -2530,13 +2531,19 @@ extern "C" sig_handler handle_segfault(i
curr_time= my_time(0);
localtime_r(&curr_time, &tm);
- fprintf(stderr,"\
-%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\
+ fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d ",
+ tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ if (opt_expect_abort && sig == SIGABRT)
+ {
+ fprintf(stderr,"[Note] mysqld did an expected abort\n");
+ goto end;
+ }
+
+ fprintf(stderr,"[ERROR] mysqld got " SIGNAL_FMT " ;\n\
This could be because you hit a bug. It is also possible that this binary\n\
or one of the libraries it was linked against is corrupt, improperly built,\n\
or misconfigured. This error can also be caused by malfunctioning hardware.\n",
- tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec,
sig);
fprintf(stderr, "\
We will try our best to scrape up some info that will hopefully help diagnose\n\
@@ -2655,6 +2662,7 @@ bugs.\n");
}
#endif
+end:
#ifndef __WIN__
/* On Windows, do not terminate, but pass control to exception filter */
exit(1);
@@ -5888,7 +5896,7 @@ enum options_mysqld
OPT_MIN_EXAMINED_ROW_LIMIT,
OPT_LOG_SLOW_SLAVE_STATEMENTS,
OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_OLD_MODE,
- OPT_TEST_IGNORE_WRONG_OPTIONS,
+ OPT_TEST_IGNORE_WRONG_OPTIONS, OPT_TEST_RESTART,
#if defined(ENABLED_DEBUG_SYNC)
OPT_DEBUG_SYNC_TIMEOUT,
#endif /* defined(ENABLED_DEBUG_SYNC) */
@@ -6737,6 +6745,10 @@ log and this option does nothing anymore
"Ignore wrong enums values in command line arguments. Useful only for test scripts",
(uchar**) &opt_ignore_wrong_options, (uchar**) &opt_ignore_wrong_options,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"test-expect-abort", OPT_TEST_RESTART,
+ "Expect that server aborts with 'abort'; Don't write out server variables on 'abort'. Useful only for test scripts",
+ (uchar**) &opt_expect_abort, (uchar**) &opt_expect_abort,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"timed_mutexes", OPT_TIMED_MUTEXES,
"Specify whether to time mutexes (only InnoDB mutexes are currently supported)",
(uchar**) &timed_mutexes, (uchar**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2010-03-28 18:10:00 +0000
+++ b/sql/set_var.cc 2010-04-06 22:47:08 +0000
@@ -2590,7 +2590,7 @@ static int sys_check_log_path(THD *thd,
char path[FN_REFLEN], buff[FN_REFLEN];
MY_STAT f_stat;
String str(buff, sizeof(buff), system_charset_info), *res;
- const char *log_file_str;
+ const char *log_file_str= 0;
size_t path_length;
if (!(res= var->value->val_str(&str)))
@@ -2640,7 +2640,7 @@ static int sys_check_log_path(THD *thd,
err:
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name,
- res ? log_file_str : "NULL");
+ log_file_str ? log_file_str : "NULL");
return 1;
}
@@ -2649,7 +2649,7 @@ bool update_sys_var_str_path(THD *thd, s
set_var *var, const char *log_ext,
bool log_state, uint log_type)
{
- MYSQL_QUERY_LOG *file_log;
+ MYSQL_QUERY_LOG *file_log= 0;
char buff[FN_REFLEN];
char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
bool result= 0;
=== modified file 'sql/slave.cc'
--- a/sql/slave.cc 2010-03-04 08:03:07 +0000
+++ b/sql/slave.cc 2010-04-06 22:47:08 +0000
@@ -2255,6 +2255,7 @@ static int exec_relay_log_event(THD* thd
if (slave_trans_retries)
{
int temp_err;
+ LINT_INIT(temp_err);
if (exec_res && (temp_err= has_temporary_error(thd)))
{
const char *errmsg;
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-03-12 19:05:21 +0000
+++ b/sql/sql_plugin.cc 2010-04-06 22:47:08 +0000
@@ -1701,9 +1701,10 @@ bool mysql_install_plugin(THD *thd, cons
if (tmp->state == PLUGIN_IS_DISABLED)
{
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_CANT_INITIALIZE_UDF, ER(ER_CANT_INITIALIZE_UDF),
- name->str, "Plugin is disabled");
+ if (global_system_variables.log_warnings)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_CANT_INITIALIZE_UDF, ER(ER_CANT_INITIALIZE_UDF),
+ name->str, "Plugin is disabled");
}
else
{
=== modified file 'storage/xtradb/include/ut0lst.h'
--- a/storage/xtradb/include/ut0lst.h 2010-03-30 12:36:49 +0000
+++ b/storage/xtradb/include/ut0lst.h 2010-04-06 22:47:08 +0000
@@ -158,7 +158,7 @@ Inserts a NODE2 after NODE1 in a list.
/** Invalidate the pointers in a list node.
@param NAME list name
@param N pointer to the node that was removed */
-# define UT_LIST_REMOVE_CLEAR(NAME, N) {} while (0)
+# define UT_LIST_REMOVE_CLEAR(NAME, N) do {} while (0)
#endif
/*******************************************************************//**
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-04-01 09:40:11 +0000
+++ b/support-files/compiler_warnings.supp 2010-04-06 22:47:08 +0000
@@ -40,6 +40,7 @@ sync/sync0sync\.c: unused parameter
sync/sync0sync\.c: unused variable
ut/ut0ut\.c: ignoring return value of
srv/srv0srv\.c: value computed is not used
+buf/buf0buf\.c: warning: .*block_mutex.* might be used uninitialized
#
# bdb is not critical to keep up to date
1
0

[Maria-developers] Rev 2793: Always refer to materialized table as "SUBSELECT#%d" where %d is select number in file:///home/psergey/dev/maria-5.3-subqueries-r12/
by Sergey Petrunya 07 Apr '10
by Sergey Petrunya 07 Apr '10
07 Apr '10
At file:///home/psergey/dev/maria-5.3-subqueries-r12/
------------------------------------------------------------
revno: 2793
revision-id: psergey(a)askmonty.org-20100406212909-r07zximlfpwmyxhm
parent: psergey(a)askmonty.org-20100406103533-0upq6g7sse9sjstz
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.3-subqueries-r12
timestamp: Wed 2010-04-07 01:29:09 +0400
message:
Always refer to materialized table as "SUBSELECT#%d" where %d is select number
- for Item-based materialization, it was "materialized subselect"
- for SJ-Materialization it was "subquery%d"
=== modified file 'mysql-test/r/group_min_max.result'
--- a/mysql-test/r/group_min_max.result 2010-04-06 08:10:58 +0000
+++ b/mysql-test/r/group_min_max.result 2010-04-06 21:29:09 +0000
@@ -2256,7 +2256,7 @@
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 8
-1 PRIMARY t1_outer ref a a 5 materialized subselect.max(b) 2 Using index
+1 PRIMARY t1_outer ref a a 5 SUBQUERY#2.max(b) 2 Using index
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
=== modified file 'mysql-test/r/subselect.result'
--- a/mysql-test/r/subselect.result 2010-04-05 20:16:45 +0000
+++ b/mysql-test/r/subselect.result 2010-04-06 21:29:09 +0000
@@ -4328,14 +4328,14 @@
1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 4 const 1 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
Warnings:
-Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`materialized subselect`.`1` = 1)
+Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`SUBQUERY#2`.`1` = 1)
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 4 const 1 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`materialized subselect`.`1` = 1)
+Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`SUBQUERY#2`.`1` = 1)
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
=== modified file 'mysql-test/r/subselect3.result'
--- a/mysql-test/r/subselect3.result 2010-04-05 20:16:45 +0000
+++ b/mysql-test/r/subselect3.result 2010-04-06 21:29:09 +0000
@@ -1017,7 +1017,7 @@
explain select t21.* from t21,t22 where t21.a = t22.a and
t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer
1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer
2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
@@ -1035,7 +1035,7 @@
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY X ALL NULL NULL NULL NULL 2
2 DEPENDENT SUBQUERY Y ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY subselect3 eq_ref unique_key unique_key 5 func 1
+2 DEPENDENT SUBQUERY SUBQUERY#3 eq_ref unique_key unique_key 5 func 1
3 SUBQUERY Z ALL NULL NULL NULL NULL 2
select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
subq
@@ -1158,7 +1158,7 @@
insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B;
explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 2
1 PRIMARY t3 ref a a 5 test.t2.a 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
select * from t3 where a in (select a from t2);
@@ -1207,7 +1207,7 @@
explain select * from t1, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30) and t1.a =3;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 10
1 PRIMARY t3 ref a a 5 test.t2.a 10
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
@@ -1241,14 +1241,14 @@
explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 system NULL NULL NULL NULL 1
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 10
1 PRIMARY t3 ref a a 5 test.t2.a 10
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
create table t4 as select a as x, a as y from t1;
explain select * from t0, t3 where (t3.a, t3.b) in (select x,y from t4) and (t3.a < 10 or t3.a >30);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 system NULL NULL NULL NULL 1
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 10
1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where
2 SUBQUERY t4 ALL NULL NULL NULL NULL 10 Using where
drop table t0,t1,t2,t3,t4;
@@ -1274,14 +1274,14 @@
explain select * from t1 where (a,b) in (select a,b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 10
-1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 10 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
set @save_optimizer_search_depth=@@optimizer_search_depth;
set @@optimizer_search_depth=63;
explain select * from t1 where (a,b) in (select a,b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 10
-1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 10 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
set @@optimizer_search_depth=@save_optimizer_search_depth;
set @@optimizer_switch=default;
@@ -1320,7 +1320,7 @@
explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
-1 PRIMARY subselect2 eq_ref unique_key unique_key 15 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 15 func 1
2 SUBQUERY X ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer
2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer
@@ -1393,7 +1393,7 @@
WHERE cona.postalStripped='T2H3B2'
);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2 1.00
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 2 1.00
1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer
2 SUBQUERY cona ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00
=== modified file 'mysql-test/r/subselect3_jcl6.result'
--- a/mysql-test/r/subselect3_jcl6.result 2010-04-05 20:16:45 +0000
+++ b/mysql-test/r/subselect3_jcl6.result 2010-04-06 21:29:09 +0000
@@ -1021,7 +1021,7 @@
explain select t21.* from t21,t22 where t21.a = t22.a and
t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer
1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer
2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
@@ -1040,7 +1040,7 @@
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY X ALL NULL NULL NULL NULL 2
2 DEPENDENT SUBQUERY Y ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY subselect3 eq_ref unique_key unique_key 5 func 1
+2 DEPENDENT SUBQUERY SUBQUERY#3 eq_ref unique_key unique_key 5 func 1
3 SUBQUERY Z ALL NULL NULL NULL NULL 2
select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
subq
@@ -1163,7 +1163,7 @@
insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B;
explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 2
1 PRIMARY t3 ref a a 5 test.t2.a 1 Using join buffer
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
select * from t3 where a in (select a from t2);
@@ -1212,7 +1212,7 @@
explain select * from t1, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30) and t1.a =3;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 10
1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
@@ -1246,14 +1246,14 @@
explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 system NULL NULL NULL NULL 1
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 10
1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
create table t4 as select a as x, a as y from t1;
explain select * from t0, t3 where (t3.a, t3.b) in (select x,y from t4) and (t3.a < 10 or t3.a >30);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 system NULL NULL NULL NULL 1
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 10
1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where; Using join buffer
2 SUBQUERY t4 ALL NULL NULL NULL NULL 10 Using where
drop table t0,t1,t2,t3,t4;
@@ -1279,14 +1279,14 @@
explain select * from t1 where (a,b) in (select a,b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 10
-1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 10 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
set @save_optimizer_search_depth=@@optimizer_search_depth;
set @@optimizer_search_depth=63;
explain select * from t1 where (a,b) in (select a,b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 10
-1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 10 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
set @@optimizer_search_depth=@save_optimizer_search_depth;
set @@optimizer_switch=default;
@@ -1325,7 +1325,7 @@
explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
-1 PRIMARY subselect2 eq_ref unique_key unique_key 15 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 15 func 1
2 SUBQUERY X ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer
2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer
@@ -1398,7 +1398,7 @@
WHERE cona.postalStripped='T2H3B2'
);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2 1.00
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 2 1.00
1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer
2 SUBQUERY cona ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using join buffer
=== modified file 'mysql-test/r/subselect4.result'
--- a/mysql-test/r/subselect4.result 2010-03-29 14:04:35 +0000
+++ b/mysql-test/r/subselect4.result 2010-04-06 21:29:09 +0000
@@ -216,7 +216,7 @@
WHERE PTYPE = 'Design'));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
-1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
@@ -231,13 +231,13 @@
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
-1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
-1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
+1 SIMPLE SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
DEALLOCATE PREPARE stmt;
@@ -254,7 +254,7 @@
WHERE PTYPE = 'Design'));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
-1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
@@ -269,13 +269,13 @@
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
-1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
-1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
+1 SIMPLE SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
DEALLOCATE PREPARE stmt;
@@ -291,7 +291,7 @@
WHERE PTYPE = 'Design'));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
-1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
@@ -306,13 +306,13 @@
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
-1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
+1 SIMPLE SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer
DEALLOCATE PREPARE stmt;
=== modified file 'mysql-test/r/subselect_mat.result'
--- a/mysql-test/r/subselect_mat.result 2010-04-06 10:35:33 +0000
+++ b/mysql-test/r/subselect_mat.result 2010-04-06 21:29:09 +0000
@@ -42,7 +42,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 9 test.t1.a1 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0')) join `test`.`t1` where (`materialized subselect`.`b1` = `test`.`t1`.`a1`)
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0')) join `test`.`t1` where (`SUBQUERY#2`.`b1` = `test`.`t1`.`a1`)
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -54,7 +54,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 9 test.t1.a1 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where (`materialized subselect`.`b1` = `test`.`t1`.`a1`)
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where (`SUBQUERY#2`.`b1` = `test`.`t1`.`a1`)
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -66,7 +66,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`materialized subselect`.`b2` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`SUBQUERY#2`.`b2` = `test`.`t1`.`a2`) and (`SUBQUERY#2`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -78,7 +78,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1`,min(`test`.`t2`.`b2`) AS `min(b2)` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where ((`materialized subselect`.`min(b2)` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1`,min(`test`.`t2`.`b2`) AS `min(b2)` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where ((`SUBQUERY#2`.`min(b2)` = `test`.`t1`.`a2`) and (`SUBQUERY#2`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -90,7 +90,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 9 test.t1i.a1 1 100.00
2 SUBQUERY t2i index it2i1,it2i3 it2i1 9 NULL 5 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where (`materialized subselect`.`b1` = `test`.`t1i`.`a1`)
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where (`SUBQUERY#2`.`b1` = `test`.`t1i`.`a1`)
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -102,7 +102,7 @@
1 PRIMARY t1i ref it1i1,it1i3 # 9 # 1 100.00 #
2 SUBQUERY t2i range it2i1,it2i3 # 9 # 3 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where (`test`.`t1i`.`a1` = `materialized subselect`.`b1`)
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where (`test`.`t1i`.`a1` = `SUBQUERY#2`.`b1`)
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -114,7 +114,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1i.a1,test.t1i.a2 1 100.00
2 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where ((`materialized subselect`.`b2` = `test`.`t1i`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1i`.`a1`))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where ((`SUBQUERY#2`.`b2` = `test`.`t1i`.`a2`) and (`SUBQUERY#2`.`b1` = `test`.`t1i`.`a1`))
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -126,7 +126,7 @@
1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
2 SUBQUERY t2i range it2i1,it2i3 # # # 3 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`test`.`t1i`.`a2` = `materialized subselect`.`b2`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`test`.`t1i`.`a2` = `SUBQUERY#2`.`b2`) and (`test`.`t1i`.`a1` = `SUBQUERY#2`.`b1`))
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -138,7 +138,7 @@
1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
2 SUBQUERY t2i range it2i1,it2i3 # # # 3 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,min(`test`.`t2i`.`b2`) AS `min(b2)` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`test`.`t1i`.`a2` = `materialized subselect`.`min(b2)`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,min(`test`.`t2i`.`b2`) AS `min(b2)` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`test`.`t1i`.`a2` = `SUBQUERY#2`.`min(b2)`) and (`test`.`t1i`.`a1` = `SUBQUERY#2`.`b1`))
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -150,7 +150,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,max(`test`.`t2i`.`b2`) AS `max(b2)` from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`materialized subselect`.`max(b2)` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,max(`test`.`t2i`.`b2`) AS `max(b2)` from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`SUBQUERY#2`.`max(b2)` = `test`.`t1`.`a2`) and (`SUBQUERY#2`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
a1 a2
1 - 01 2 - 01
@@ -182,7 +182,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,min(`test`.`t2i`.`b2`) AS `min(b2)` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`materialized subselect`.`min(b2)` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,min(`test`.`t2i`.`b2`) AS `min(b2)` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`SUBQUERY#2`.`min(b2)` = `test`.`t1`.`a2`) and (`SUBQUERY#2`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -223,7 +223,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`materialized subselect`.`b2` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`SUBQUERY#2`.`b2` = `test`.`t1`.`a2`) and (`SUBQUERY#2`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -235,7 +235,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1i.a1,test.t1i.a2 1 100.00
2 SUBQUERY t2i index NULL it2i3 18 NULL 5 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`materialized subselect`.`b2` = `test`.`t1i`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1i`.`a1`))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`SUBQUERY#2`.`b2` = `test`.`t1i`.`a2`) and (`SUBQUERY#2`.`b1` = `test`.`t1i`.`a1`))
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -286,14 +286,14 @@
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 5 0.00
-1 PRIMARY SUBQUERY#3 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
+1 PRIMARY SUBQUERY#3 eq_ref distinct_key distinct_key 18 SUBQUERY#2.b1,SUBQUERY#2.b2 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00
3 SUBQUERY SUBQUERY#4 eq_ref distinct_key distinct_key 18 test.t3.c1,test.t3.c2 1 100.00
4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0')) join `test`.`t1` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a1` = `materialized subselect`.`b1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`SUBQUERY#4`.`b2` = `test`.`t3`.`c2`) and (`SUBQUERY#4`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0')) join `test`.`t1` where ((`SUBQUERY#3`.`c2` = `SUBQUERY#2`.`b2`) and (`test`.`t1`.`a2` = `SUBQUERY#2`.`b2`) and (`SUBQUERY#3`.`c1` = `SUBQUERY#2`.`b1`) and (`test`.`t1`.`a1` = `SUBQUERY#2`.`b1`))
select * from t1
where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
(a1, a2) in (select c1, c2 from t3
@@ -315,7 +315,7 @@
4 SUBQUERY t2i index it2i2 # # # 5 100.00 #
2 SUBQUERY t2i index it2i1,it2i3 # # # 5 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3i` where ((`materialized subselect`.`b2` = `test`.`t3i`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3i`.`c1`))) join <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3i` where ((`SUBQUERY#4`.`b2` = `test`.`t3i`.`c2`) and (`SUBQUERY#4`.`b1` = `test`.`t3i`.`c1`))) join <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where ((`SUBQUERY#3`.`c2` = `SUBQUERY#2`.`b2`) and (`test`.`t1i`.`a2` = `SUBQUERY#2`.`b2`) and (`SUBQUERY#3`.`c1` = `SUBQUERY#2`.`b1`) and (`test`.`t1i`.`a1` = `SUBQUERY#2`.`b1`))
select * from t1i
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
(a1, a2) in (select c1, c2 from t3i
@@ -332,7 +332,7 @@
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 5 0.00
-1 PRIMARY SUBQUERY#5 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
+1 PRIMARY SUBQUERY#5 eq_ref distinct_key distinct_key 18 SUBQUERY#2.b1,SUBQUERY#2.b2 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00
5 SUBQUERY SUBQUERY#6 eq_ref distinct_key distinct_key 18 test.t3.c1,test.t3.c2 1 100.00
@@ -341,7 +341,7 @@
4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(
`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))))) join `test`.`t1` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a1` = `materialized subselect`.`b1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`SUBQUERY#6`.`b2` = `test`.`t3`.`c2`) and (`SUBQUERY#6`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `SUBQUERY#3`.`c2`))))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table
> on distinct_key where ((`test`.`t2`.`b2` = `SUBQUERY#4`.`c2`))))))) join `test`.`t1` where ((`SUBQUERY#5`.`c2` = `SUBQUERY#2`.`b2`) and (`test`.`t1`.`a2` = `SUBQUERY#2`.`b2`) and (`SUBQUERY#5`.`c1` = `SUBQUERY#2`.`b1`) and (`test`.`t1`.`a1` = `SUBQUERY#2`.`b1`))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -368,7 +368,7 @@
3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3c`.`c1` AS `c1`,`test`.`t3c`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` `t3c` where ((`materialized subselect`.`b2` = `test`.`t3c`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3c`.`c1`))) join `test`.`t1` where ((`materialized subselect`.`c2` = `test`.`t1`.`a2`) and (`materialized subselect`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 AS `Not_used` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`)))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` AS `c2` fr
om `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3c`.`c1` AS `c1`,`test`.`t3c`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` `t3c` where ((`SUBQUERY#6`.`b2` = `test`.`t3c`.`c2`) and (`SUBQUERY#6`.`b1` = `test`.`t3c`.`c1`))) join `test`.`t1` where ((`SUBQUERY#5`.`c2` = `test`.`t1`.`a2`) and (`SUBQUERY#5`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 AS `Not_used` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`)))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` AS `c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` li
ke '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `SUBQUERY#4`.`c2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 t3a where c1 = a1) or
@@ -410,7 +410,7 @@
8 SUBQUERY t2i index it2i1,it2i3 # # # 5 100.00 #
NULL UNION RESULT <union1,7> ALL NULL # # # NULL NULL #
Warnings:
-Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>
(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a1` = `materialized subselect`.`b1`))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3i` where ((`materialized subselect`.`b2` = `test`.`t3i`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3i`.`c1`))) join <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i
` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`)))
+Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`SUBQUERY#6`.`b2` = `test`.`t3`.`c2`) and (`SUBQUERY#6`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `SUBQUERY#3`.`c2`))))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary tabl
e> on distinct_key where ((`test`.`t2`.`b2` = `SUBQUERY#4`.`c2`)))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`SUBQUERY#5`.`c2` = `SUBQUERY#2`.`b2`) and (`test`.`t1`.`a2` = `SUBQUERY#2`.`b2`) and (`SUBQUERY#5`.`c1` = `SUBQUERY#2`.`b1`) and (`test`.`t1`.`a1` = `SUBQUERY#2`.`b1`))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3i` where ((`SUBQUERY#10`.`b2` = `test`.`t3i`.`c2`) and (`SUBQUERY#10`.`b1` = `test`.`t3i`.`c1`))) join <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where ((`SUBQUERY#9`.`c2` = `SUBQUERY#8`.`b2`) and (`test`.`t1i`.`a2` = `SUBQUERY#8`.`b2`) and (`SUBQUERY#9`.`c1` = `SUBQUERY#8`.`b1`) and (
`test`.`t1i`.`a1` = `SUBQUERY#8`.`b1`)))
(select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -441,7 +441,7 @@
3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join `test`.`t1` where ((`materialized subselect`.`c2` = `test`.`t1`.`a2`) and (`materialized subselect`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`t
est`.`t1`.`a2`) = `test`.`t2`.`b2`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`SUBQUERY#5`.`b2` = `test`.`t3`.`c2`) and (`SUBQUERY#5`.`b1` = `test`.`t3`.`c1`))) join `test`.`t1` where ((`SUBQUERY#4`.`c2` = `test`.`t1`.`a2`) and (`SUBQUERY#4`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))))
select * from t1
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
(a1, a2) in (select c1, c2 from t3
@@ -466,7 +466,7 @@
3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`c2` = `materialized subselect`.`c2`) and (`materialized subselect`.`c1` = `test`.`t1`.`a1`) and (`test`.`t3`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `
test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`SUBQUERY#5`.`b2` = `test`.`t3`.`c2`) and (`SUBQUERY#5`.`b1` = `test`.`t3`.`c1`))) join `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`c2` = `SUBQUERY#4`.`c2`) and (`SUBQUERY#4`.`c1` = `test`.`t1`.`a1`) and (`test`.`t3`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (
<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))))
select * from t1, t3
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
(c1, c2) in (select c1, c2 from t3
@@ -512,7 +512,7 @@
Warnings:
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
Note 1276 Field or reference 'test.t1.a2' of SELECT #6 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 AS `Not_used` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`)))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` AS `c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t3c`.`c1` AS `c1`,`test`.`t3c`.`c2` AS `c2` from `test`.`t3` `t3c` where (<i
n_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),<exists>(<index_lookup>(<cache>(`test`.`t3c`.`c1`) in t2i on it2i3 where (((`test`.`t2i`.`b2` > '0') or (`test`.`t2i`.`b2` = `test`.`t1`.`a2`)) and (<cache>(`test`.`t3c`.`c1`) = `test`.`t2i`.`b1`) and (<cache>(`test`.`t3c`.`c2`) = `test`.`t2i`.`b2`))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t3c`.`c1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t3c`.`c2`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 AS `Not_used` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`)))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` AS `c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `SUBQUERY#4`.`c2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t3c`.`c1` AS `c1`,`test`.`t3c`.`c2` AS `c2` from `test`.`t3` `t3c` where (<in_optimizer>
((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),<exists>(<index_lookup>(<cache>(`test`.`t3c`.`c1`) in t2i on it2i3 where (((`test`.`t2i`.`b2` > '0') or (`test`.`t2i`.`b2` = `test`.`t1`.`a2`)) and (<cache>(`test`.`t3c`.`c1`) = `test`.`t2i`.`b1`) and (<cache>(`test`.`t3c`.`c2`) = `test`.`t2i`.`b2`))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t3c`.`c1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t3c`.`c2`)))))
explain extended
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
id select_type table type possible_keys key key_len ref rows filtered Extra
@@ -648,7 +648,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 20 test.t1_16.a1 1 100.00 Using where
2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from <materialize> (select substr(`test`.`t2_16`.`b1`,1,16) AS `substring(b1,1,16)` from `test`.`t2_16` where (`test`.`t2_16`.`b1` > '0')) join `test`.`t1_16` where (`test`.`t1_16`.`a1` = `materialized subselect`.`substring(b1,1,16)`)
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from <materialize> (select substr(`test`.`t2_16`.`b1`,1,16) AS `substring(b1,1,16)` from `test`.`t2_16` where (`test`.`t2_16`.`b1` > '0')) join `test`.`t1_16` where (`test`.`t1_16`.`a1` = `SUBQUERY#2`.`substring(b1,1,16)`)
select left(a1,7), left(a2,7)
from t1_16
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
@@ -678,7 +678,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_16.a1 1 100.00 Using where
2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_16`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_16` group by `test`.`t2_16`.`b2`) join `test`.`t1_16` where (`test`.`t1_16`.`a1` = `materialized subselect`.`group_concat(b1)`)
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_16`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_16` group by `test`.`t2_16`.`b2`) join `test`.`t1_16` where (`test`.`t1_16`.`a1` = `SUBQUERY#2`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_16
where a1 in (select group_concat(b1) from t2_16 group by b2);
@@ -701,7 +701,7 @@
3 DEPENDENT SUBQUERY SUBQUERY#4 eq_ref distinct_key distinct_key 9 test.t2.b1 1 100.00 Using where
4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select 1 AS `Not_used` from `test`.`t1_16` where (<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1` AS `b1`,`test`.`t2_16`.`b2` AS `b2` from <materialize> (select `test`.`t3`.`c1` AS `c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0')) join `test`.`t2_16` join `test`.`t2` where ((`materialized subselect`.`c1` = `test`.`t2`.`b1`) and (`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))) and (<cache>(concat(`test`.`t1`.`a1`,'x')) = left(`test`.`t1_16`.`a1`,8)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select 1 AS `Not_used` from `test`.`t1_16` where (<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1` AS `b1`,`test`.`t2_16`.`b2` AS `b2` from <materialize> (select `test`.`t3`.`c1` AS `c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0')) join `test`.`t2_16` join `test`.`t2` where ((`SUBQUERY#4`.`c1` = `test`.`t2`.`b1`) and (`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))) and (<cache>(concat(`test`.`t1`.`a1`,'x')) = left(`test`.`t1_16`.`a1`,8)))))
drop table t1_16, t2_16, t3_16;
set @blob_len = 512;
set @suffix_len = @blob_len - @prefix_len;
@@ -764,7 +764,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 517 test.t1_512.a1 1 100.00 Using where
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (select substr(`test`.`t2_512`.`b1`,1,512) AS `substring(b1,1,512)` from `test`.`t2_512` where (`test`.`t2_512`.`b1` > '0')) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `materialized subselect`.`substring(b1,1,512)`)
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (select substr(`test`.`t2_512`.`b1`,1,512) AS `substring(b1,1,512)` from `test`.`t2_512` where (`test`.`t2_512`.`b1` > '0')) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `SUBQUERY#2`.`substring(b1,1,512)`)
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
@@ -779,7 +779,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_512.a1 1 100.00 Using where
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `materialized subselect`.`group_concat(b1)`)
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `SUBQUERY#2`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
@@ -793,7 +793,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_512.a1 1 100.00 Using where
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `materialized subselect`.`group_concat(b1)`)
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `SUBQUERY#2`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
@@ -874,7 +874,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_1024.a1 1 100.00 Using where
2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = `materialized subselect`.`group_concat(b1)`)
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = `SUBQUERY#2`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
@@ -888,7 +888,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_1024.a1 1 100.00 Using where
2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = `materialized subselect`.`group_concat(b1)`)
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = `SUBQUERY#2`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
@@ -969,7 +969,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_1025.a1 1 100.00 Using where
2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = `materialized subselect`.`group_concat(b1)`)
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = `SUBQUERY#2`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
@@ -983,7 +983,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_1025.a1 1 100.00 Using where
2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = `materialized subselect`.`group_concat(b1)`)
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = `SUBQUERY#2`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
@@ -1006,7 +1006,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 10 test.t1bit.a1,test.t1bit.a2 1 100.00 Using where
2 SUBQUERY t2bit ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from <materialize> (select `test`.`t2bit`.`b1` AS `b1`,`test`.`t2bit`.`b2` AS `b2` from `test`.`t2bit`) join `test`.`t1bit` where ((`test`.`t1bit`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1bit`.`a2` = `materialized subselect`.`b2`))
+Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from <materialize> (select `test`.`t2bit`.`b1` AS `b1`,`test`.`t2bit`.`b2` AS `b2` from `test`.`t2bit`) join `test`.`t1bit` where ((`test`.`t1bit`.`a1` = `SUBQUERY#2`.`b1`) and (`test`.`t1bit`.`a2` = `SUBQUERY#2`.`b2`))
select bin(a1), bin(a2)
from t1bit
where (a1, a2) in (select b1, b2 from t2bit);
@@ -1078,7 +1078,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20)) join `test`.`t1` where (`materialized subselect`.`c` = `test`.`t1`.`a`)
+Note 1003 select `test`.`t1`.`a` AS `a` from <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20)) join `test`.`t1` where (`SUBQUERY#2`.`c` = `test`.`t1`.`a`)
select a from t1 where a in (select c from t2 where d >= 20);
a
2
@@ -1093,7 +1093,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20)) join `test`.`t1` where (`materialized subselect`.`c` = `test`.`t1`.`a`)
+Note 1003 select `test`.`t1`.`a` AS `a` from <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20)) join `test`.`t1` where (`SUBQUERY#2`.`c` = `test`.`t1`.`a`)
select a from t1 where a in (select c from t2 where d >= 20);
a
2
@@ -1108,7 +1108,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20)) join `test`.`t1` where (`materialized subselect`.`c` = `test`.`t1`.`a`)
+Note 1003 select `test`.`t1`.`a` AS `a` from <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20)) join `test`.`t1` where (`SUBQUERY#2`.`c` = `test`.`t1`.`a`)
select a from t1 where a in (select c from t2 where d >= 20);
a
2
@@ -1121,7 +1121,7 @@
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `SUBQUERY#2`.`c`)))))
select a from t1 group by a having a in (select c from t2 where d >= 20);
a
2
@@ -1133,7 +1133,7 @@
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `SUBQUERY#2`.`c`)))))
select a from t1 group by a having a in (select c from t2 where d >= 20);
a
2
@@ -1253,7 +1253,7 @@
SET @@optimizer_switch='default,semijoin=on,materialization=on';
EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 2
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
@@ -1275,7 +1275,7 @@
EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
-1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 5 func 1
2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using MRR
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
pk
=== modified file 'mysql-test/r/subselect_no_semijoin.result'
--- a/mysql-test/r/subselect_no_semijoin.result 2010-04-05 20:16:45 +0000
+++ b/mysql-test/r/subselect_no_semijoin.result 2010-04-06 21:29:09 +0000
@@ -1303,7 +1303,7 @@
1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer
2 SUBQUERY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1`) join `test`.`t2` where (`test`.`t2`.`a` = `materialized subselect`.`a`)
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1`) join `test`.`t2` where (`test`.`t2`.`a` = `SUBQUERY#2`.`a`)
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
2
@@ -1314,7 +1314,7 @@
1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30)) join `test`.`t2` where (`test`.`t2`.`a` = `materialized subselect`.`a`)
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30)) join `test`.`t2` where (`test`.`t2`.`a` = `SUBQUERY#2`.`a`)
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
@@ -1326,7 +1326,7 @@
2 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`)) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`)) join `test`.`t2` where (`SUBQUERY#2`.`a` = `test`.`t2`.`a`)
drop table t1, t2, t3;
create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a));
@@ -1349,7 +1349,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1 100.00
2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1`) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1`) join `test`.`t2` where (`SUBQUERY#2`.`a` = `test`.`t2`.`a`)
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
2
@@ -1360,7 +1360,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1 100.00
2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30)) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30)) join `test`.`t2` where (`SUBQUERY#2`.`a` = `test`.`t2`.`a`)
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
@@ -1372,7 +1372,7 @@
2 SUBQUERY t3 index a a 5 NULL 3 100.00 Using index
2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index; Using join buffer
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`)) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`)) join `test`.`t2` where (`SUBQUERY#2`.`a` = `test`.`t2`.`a`)
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -1389,7 +1389,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1 100.00
2 SUBQUERY t1 index NULL a 10 NULL 10005 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30)) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30)) join `test`.`t2` where (`SUBQUERY#2`.`a` = `test`.`t2`.`a`)
drop table t0, t1, t2, t3;
create table t1 (a int, b int);
create table t2 (a int, b int);
@@ -2844,7 +2844,7 @@
1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 10 test.t1.one,test.t1.two 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from <materialize> (select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where (`test`.`t2`.`flag` = 'N')) join `test`.`t1` where ((`materialized subselect`.`two` = `test`.`t1`.`two`) and (`materialized subselect`.`one` = `test`.`t1`.`one`))
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from <materialize> (select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where (`test`.`t2`.`flag` = 'N')) join `test`.`t1` where ((`SUBQUERY#2`.`two` = `test`.`t1`.`two`) and (`SUBQUERY#2`.`one` = `test`.`t1`.`one`))
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
@@ -4343,14 +4343,14 @@
1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 4 const 1 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
Warnings:
-Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`materialized subselect`.`1` = 1)
+Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`SUBQUERY#2`.`1` = 1)
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 4 const 1 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`materialized subselect`.`1` = 1)
+Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`SUBQUERY#2`.`1` = 1)
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
=== modified file 'mysql-test/r/subselect_sj.result'
--- a/mysql-test/r/subselect_sj.result 2010-03-29 14:04:35 +0000
+++ b/mysql-test/r/subselect_sj.result 2010-04-06 21:29:09 +0000
@@ -848,7 +848,7 @@
EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-1 PRIMARY subselect2 eq_ref unique_key unique_key 13 func 1 1.00
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 13 func 1 1.00
2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using MRR
Warnings:
Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0))
@@ -1017,7 +1017,7 @@
WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
-1 PRIMARY subselect2 eq_ref unique_key unique_key 8 func 1 1.00
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 8 func 1 1.00
2 SUBQUERY t1 ALL varchar_key NULL NULL NULL 15 100.00 Using where
Warnings:
Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_nokey` = `test`.`t1`.`varchar_key`) and ((`test`.`t1`.`varchar_nokey` < 'n') xor `test`.`t1`.`pk`))
=== modified file 'mysql-test/r/subselect_sj2.result'
--- a/mysql-test/r/subselect_sj2.result 2010-03-29 14:04:35 +0000
+++ b/mysql-test/r/subselect_sj2.result 2010-04-06 21:29:09 +0000
@@ -32,7 +32,7 @@
9 5
explain select * from t2 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 3
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 3
1 PRIMARY t2 ref b b 5 test.t1.a 2
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
select * from t2 where b in (select a from t1);
@@ -74,7 +74,7 @@
from t0 A, t0 B where B.a <5;
explain select * from t3 where b in (select a from t0);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 10
1 PRIMARY t3 ref b b 5 test.t0.a 1
2 SUBQUERY t0 ALL NULL NULL NULL NULL 10
set @save_ecp= @@engine_condition_pushdown;
@@ -101,7 +101,7 @@
explain select * from t1 where a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
-1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 5 func 1
2 SUBQUERY t2 index b b 5 NULL 10 Using index
select * from t1;
a b
@@ -129,7 +129,7 @@
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 22
1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer
2 SUBQUERY it ALL NULL NULL NULL NULL 22
select
@@ -163,7 +163,7 @@
from t2 ot where a in (select a from t1 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot ALL NULL NULL NULL NULL 22
-1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 5 func 1
2 SUBQUERY it ALL NULL NULL NULL NULL 32
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
@@ -197,7 +197,7 @@
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 22
1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer
2 SUBQUERY it ALL NULL NULL NULL NULL 22
select
@@ -231,7 +231,7 @@
from t2 ot where a in (select a from t1 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot ALL NULL NULL NULL NULL 22
-1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 5 func 1
2 SUBQUERY it ALL NULL NULL NULL NULL 52
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
@@ -348,7 +348,7 @@
SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 31
-1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
SELECT Name FROM t1
WHERE t1.Code IN (
@@ -692,7 +692,7 @@
explain select count(a) from t2 where a in ( SELECT a FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index a a 5 NULL 1000 Using index
-1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 5 func 1
2 SUBQUERY t3 index a a 5 NULL 30000 Using index
select count(a) from t2 where a in ( SELECT a FROM t3);
count(a)
=== modified file 'mysql-test/r/subselect_sj2_jcl6.result'
--- a/mysql-test/r/subselect_sj2_jcl6.result 2010-03-29 14:04:35 +0000
+++ b/mysql-test/r/subselect_sj2_jcl6.result 2010-04-06 21:29:09 +0000
@@ -36,7 +36,7 @@
9 5
explain select * from t2 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 3
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 3
1 PRIMARY t2 ref b b 5 test.t1.a 2 Using join buffer
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
select * from t2 where b in (select a from t1);
@@ -78,7 +78,7 @@
from t0 A, t0 B where B.a <5;
explain select * from t3 where b in (select a from t0);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 10
1 PRIMARY t3 ref b b 5 test.t0.a 1 Using join buffer
2 SUBQUERY t0 ALL NULL NULL NULL NULL 10
set @save_ecp= @@engine_condition_pushdown;
@@ -105,7 +105,7 @@
explain select * from t1 where a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
-1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 5 func 1
2 SUBQUERY t2 index b b 5 NULL 10 Using index
select * from t1;
a b
@@ -133,7 +133,7 @@
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 22
1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer
2 SUBQUERY it ALL NULL NULL NULL NULL 22
select
@@ -167,7 +167,7 @@
from t2 ot where a in (select a from t1 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot ALL NULL NULL NULL NULL 22
-1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 5 func 1
2 SUBQUERY it ALL NULL NULL NULL NULL 32
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
@@ -201,7 +201,7 @@
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
+1 PRIMARY SUBQUERY#2 ALL unique_key NULL NULL NULL 22
1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer
2 SUBQUERY it ALL NULL NULL NULL NULL 22
select
@@ -235,7 +235,7 @@
from t2 ot where a in (select a from t1 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot ALL NULL NULL NULL NULL 22
-1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 5 func 1
2 SUBQUERY it ALL NULL NULL NULL NULL 52
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
@@ -352,7 +352,7 @@
SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 31
-1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 3 func 1
2 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
SELECT Name FROM t1
WHERE t1.Code IN (
@@ -698,7 +698,7 @@
explain select count(a) from t2 where a in ( SELECT a FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index a a 5 NULL 1000 Using index
-1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 5 func 1
2 SUBQUERY t3 index a a 5 NULL 30000 Using index
select count(a) from t2 where a in ( SELECT a FROM t3);
count(a)
=== modified file 'mysql-test/r/subselect_sj_jcl6.result'
--- a/mysql-test/r/subselect_sj_jcl6.result 2010-03-29 14:04:35 +0000
+++ b/mysql-test/r/subselect_sj_jcl6.result 2010-04-06 21:29:09 +0000
@@ -852,7 +852,7 @@
EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-1 PRIMARY subselect2 eq_ref unique_key unique_key 13 func 1 1.00
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 13 func 1 1.00
2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using MRR
Warnings:
Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0))
@@ -1021,7 +1021,7 @@
WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
-1 PRIMARY subselect2 eq_ref unique_key unique_key 8 func 1 1.00
+1 PRIMARY SUBQUERY#2 eq_ref unique_key unique_key 8 func 1 1.00
2 SUBQUERY t1 ALL varchar_key NULL NULL NULL 15 100.00 Using where
Warnings:
Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_nokey` = `test`.`t1`.`varchar_key`) and ((`test`.`t1`.`varchar_nokey` < 'n') xor `test`.`t1`.`pk`))
=== modified file 'mysql-test/suite/pbxt/r/group_min_max.result'
--- a/mysql-test/suite/pbxt/r/group_min_max.result 2010-04-06 08:10:58 +0000
+++ b/mysql-test/suite/pbxt/r/group_min_max.result 2010-04-06 21:29:09 +0000
@@ -2257,7 +2257,7 @@
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 15
-1 PRIMARY t1_outer ref a a 5 materialized subselect.max(b) 1 Using index
+1 PRIMARY t1_outer ref a a 5 SUBQUERY#2.max(b) 1 Using index
2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
=== modified file 'mysql-test/suite/pbxt/r/subselect.result'
--- a/mysql-test/suite/pbxt/r/subselect.result 2010-04-06 08:10:58 +0000
+++ b/mysql-test/suite/pbxt/r/subselect.result 2010-04-06 21:29:09 +0000
@@ -3433,7 +3433,7 @@
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 9
-1 PRIMARY t1 ref a a 8 materialized subselect.a 1 Using where
+1 PRIMARY t1 ref a a 8 SUBQUERY#2.a 1 Using where
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
DROP TABLE t1;
create table t1( f1 int,f2 int);
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2010-04-05 20:16:45 +0000
+++ b/sql/item_subselect.cc 2010-04-06 21:29:09 +0000
@@ -2116,7 +2116,8 @@
if (!(new_engine= new subselect_hash_sj_engine(thd, this,
old_engine)) ||
- new_engine->init_permanent(unit->get_unit_column_types()))
+ new_engine->init_permanent(unit->get_unit_column_types(),
+ old_engine->get_identifier()))
{
Item_subselect::trans_res trans_res;
/*
@@ -3662,6 +3663,7 @@
reexecution.
@param tmp_columns the items that produce the data for the temp table
+ @param subquery_id subquery's identifier (for temptable name)
@details
- Create a temporary table to store the result of the IN subquery. The
@@ -3677,7 +3679,8 @@
@retval FALSE otherwise
*/
-bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns)
+bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns,
+ uint subquery_id)
{
/* Options to create_tmp_table. */
ulonglong tmp_create_options= thd->options | TMP_TABLE_ALL_COLUMNS;
@@ -3712,12 +3715,19 @@
DBUG_RETURN(TRUE);
}
*/
+ char buf[32];
+ uint len= my_snprintf(buf, sizeof(buf), "SUBQUERY#%d", subquery_id);
+ char *name;
+ if (!(name= (char*)thd->alloc(len + 1)))
+ DBUG_RETURN(TRUE);
+ memcpy(name, buf, len+1);
+
if (!(result= new select_materialize_with_stats))
DBUG_RETURN(TRUE);
if (((select_union*) result)->create_result_table(
thd, tmp_columns, TRUE, tmp_create_options,
- "materialized subselect", TRUE))
+ name, TRUE))
DBUG_RETURN(TRUE);
tmp_table= ((select_union*) result)->table;
@@ -3798,7 +3808,7 @@
if (!(tmp_table_ref= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST))))
DBUG_RETURN(TRUE);
- tmp_table_ref->init_one_table("", "materialized subselect", TL_READ);
+ tmp_table_ref->init_one_table("", tmp_table->alias, TL_READ);
tmp_table_ref->table= tmp_table;
context= new Name_resolution_context;
=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h 2010-04-05 20:16:45 +0000
+++ b/sql/item_subselect.h 2010-04-06 21:29:09 +0000
@@ -814,7 +814,7 @@
}
~subselect_hash_sj_engine();
- bool init_permanent(List<Item> *tmp_columns);
+ bool init_permanent(List<Item> *tmp_columns, uint subquery_id);
bool init_runtime();
void cleanup();
int prepare() { return 0; } /* Override virtual function in base class. */
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2010-04-05 20:16:45 +0000
+++ b/sql/sql_select.cc 2010-04-06 21:29:09 +0000
@@ -18004,7 +18004,7 @@
/* table */
int len= my_snprintf(table_name_buffer,
sizeof(table_name_buffer)-1,
- "subselect%d",
+ "SUBQUERY#%d",
tab->emb_sj_nest->sj_subq_pred->get_identifier());
item_list.push_back(new Item_string(table_name_buffer, len, cs));
/* partitions */
1
0

[Maria-developers] bzr commit into file:///home/tsk/mprog/src/5.3-subqueries/ branch (timour:2790)
by timour@askmonty.org 06 Apr '10
by timour@askmonty.org 06 Apr '10
06 Apr '10
#At file:///home/tsk/mprog/src/5.3-subqueries/ based on revid:timour@askmonty.org-20100405211515-istsgehaz7zafg0l
2790 timour(a)askmonty.org 2010-04-06
Fixed an error in the creation of REF access method for materialized
semi-join, where the the REF buffer format was mistaken to be in
record format instead of key format. The error was that the null
byte for all fields of the record was in the front of the buffer,
and not before each field data.
modified:
sql/opt_subselect.cc
=== modified file 'sql/opt_subselect.cc'
--- a/sql/opt_subselect.cc 2010-03-15 19:52:58 +0000
+++ b/sql/opt_subselect.cc 2010-04-06 19:56:20 +0000
@@ -2296,7 +2296,7 @@ bool setup_sj_materialization(JOIN_TAB *
use that information instead.
*/
cur_ref_buff + null_count,
- null_count ? tab_ref->key_buff : 0,
+ null_count ? cur_ref_buff : 0,
cur_key_part->length, tab_ref->items[i]);
cur_ref_buff+= cur_key_part->store_length;
}
1
0

[Maria-developers] Progress (by Knielsen): Merge OQGraph into MariaDB (112)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Merge OQGraph into MariaDB
CREATION DATE..: Mon, 29 Mar 2010, 18:00
SUPERVISOR.....: Knielsen
IMPLEMENTOR....: Knielsen
COPIES TO......:
CATEGORY.......: Server-Sprint
TASK ID........: 112 (http://askmonty.org/worklog/?tid=112)
VERSION........: Server-5.2
STATUS.........: Code-Review
PRIORITY.......: 60
WORKED HOURS...: 13
ESTIMATE.......: 2 (hours remain)
ORIG. ESTIMATE.: 15
PROGRESS NOTES:
-=-=(Knielsen - Tue, 06 Apr 2010, 15:28)=-=-
Fixed all issues from first code review.
Implement packaging for OQGraph in bakery.
Set up buildbot hosts for including OQGraph, including binary packaging.
Worked 13 hours and estimate 2 hours remain (original estimate unchanged).
-=-=(Knielsen - Wed, 31 Mar 2010, 13:38)=-=-
Status updated.
--- /tmp/wklog.112.old.12166 2010-03-31 13:38:25.000000000 +0000
+++ /tmp/wklog.112.new.12166 2010-03-31 13:38:25.000000000 +0000
@@ -1 +1 @@
-Assigned
+Code-Review
-=-=(Knielsen - Wed, 31 Mar 2010, 13:38)=-=-
High-Level Specification modified.
--- /tmp/wklog.112.old.12070 2010-03-31 13:38:08.000000000 +0000
+++ /tmp/wklog.112.new.12070 2010-03-31 13:38:08.000000000 +0000
@@ -15,3 +15,5 @@
Fix OQGraph plug.in to detect boost version >= 1.40.0, and only enable OQGraph
if such boost is found.
+Update the packaging in ourdelta/bakery to include the oqgraph_engine.so and
+link with g++ rather than gcc.
-=-=(Knielsen - Mon, 29 Mar 2010, 21:46)=-=-
High-Level Specification modified.
--- /tmp/wklog.112.old.31142 2010-03-29 21:46:11.000000000 +0000
+++ /tmp/wklog.112.new.31142 2010-03-29 21:46:11.000000000 +0000
@@ -1,28 +1,17 @@
Tasks:
-Find the latest version of OQGraph to base this on (there should be a
-Launchpad branch somewhere, match it up with what is in the OQGraph patch for
-MySQL 5.0 in the ourdelta stuff).
-
-Extract the correct version of Boost from the MySQL 5.0 ourdelta patch. This
-is a patched version of Boost fixing a bug that is supposedly fatal for
-OQGraph (details are not known at the time of writing).
+Base work on the Launchpad branch lp:~knielsen/maria/mariadb-5.1-oqgraph
-Document in OQGraph README the need for boost of a specific version, and point
-to where it can be obtained. Also include the patch for boost if the correct
-base version of boost to do this against can be determined.
+OQGraph requires Boost >= 1.40.0 (earlier versions have a bug that affects
+OQGraph).
-Install the patched boost in /usr/local/ on the build machines (release builds
-and selected Buildbot slaves).
+Document in OQGraph README the need for boost of a specific version, and point
+to where it can be obtained.
-Fix OQGraph plug.in to detect correct version of OQGraph that makes the build
-not break. Check which version in Ubuntu starts working (I think it was
-Jaunty), and require at least that version.
-
-Setup some repository or source tarball of the patched boost
-somewhere. Preferably a Launchpad branch or similar (if upstream project can
-be found).
+Install the patched boost in /usr/local/include/boost on the build machines
+(release builds and selected Buildbot slaves). G++ seems to by default look in
+/usr/local/include, so that is sufficient to find it.
-Setup in plug.in or /configure.in appropriate --with-boost=xxx. Or in a pinch,
-we can make do with CFLAGS=-Ixxx, or even default look in /usr/local/.
+Fix OQGraph plug.in to detect boost version >= 1.40.0, and only enable OQGraph
+if such boost is found.
-=-=(Knielsen - Mon, 29 Mar 2010, 18:09)=-=-
High-Level Specification modified.
--- /tmp/wklog.112.old.23061 2010-03-29 18:09:27.000000000 +0000
+++ /tmp/wklog.112.new.23061 2010-03-29 18:09:27.000000000 +0000
@@ -1 +1,28 @@
+Tasks:
+
+Find the latest version of OQGraph to base this on (there should be a
+Launchpad branch somewhere, match it up with what is in the OQGraph patch for
+MySQL 5.0 in the ourdelta stuff).
+
+Extract the correct version of Boost from the MySQL 5.0 ourdelta patch. This
+is a patched version of Boost fixing a bug that is supposedly fatal for
+OQGraph (details are not known at the time of writing).
+
+Document in OQGraph README the need for boost of a specific version, and point
+to where it can be obtained. Also include the patch for boost if the correct
+base version of boost to do this against can be determined.
+
+Install the patched boost in /usr/local/ on the build machines (release builds
+and selected Buildbot slaves).
+
+Fix OQGraph plug.in to detect correct version of OQGraph that makes the build
+not break. Check which version in Ubuntu starts working (I think it was
+Jaunty), and require at least that version.
+
+Setup some repository or source tarball of the patched boost
+somewhere. Preferably a Launchpad branch or similar (if upstream project can
+be found).
+
+Setup in plug.in or /configure.in appropriate --with-boost=xxx. Or in a pinch,
+we can make do with CFLAGS=-Ixxx, or even default look in /usr/local/.
DESCRIPTION:
Get the OQGraph storage engine merged into MariaDB, fixing the remaining
problems blocking the merge.
HIGH-LEVEL SPECIFICATION:
Tasks:
Base work on the Launchpad branch lp:~knielsen/maria/mariadb-5.1-oqgraph
OQGraph requires Boost >= 1.40.0 (earlier versions have a bug that affects
OQGraph).
Document in OQGraph README the need for boost of a specific version, and point
to where it can be obtained.
Install the patched boost in /usr/local/include/boost on the build machines
(release builds and selected Buildbot slaves). G++ seems to by default look in
/usr/local/include, so that is sufficient to find it.
Fix OQGraph plug.in to detect boost version >= 1.40.0, and only enable OQGraph
if such boost is found.
Update the packaging in ourdelta/bakery to include the oqgraph_engine.so and
link with g++ rather than gcc.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Progress (by Knielsen): Store in binlog text of statements that caused RBR events (47)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Store in binlog text of statements that caused RBR events
CREATION DATE..: Sat, 15 Aug 2009, 23:48
SUPERVISOR.....: Monty
IMPLEMENTOR....:
COPIES TO......: Knielsen, Serg
CATEGORY.......: Server-Sprint
TASK ID........: 47 (http://askmonty.org/worklog/?tid=47)
VERSION........: Server-9.x
STATUS.........: In-Progress
PRIORITY.......: 60
WORKED HOURS...: 47
ESTIMATE.......: 8 (hours remain)
ORIG. ESTIMATE.: 35
PROGRESS NOTES:
-=-=(Knielsen - Tue, 06 Apr 2010, 15:26)=-=-
Code review (mailed to maria-developers@).
Worked 7 hours and estimate 8 hours remain (original estimate unchanged).
-=-=(Knielsen - Tue, 06 Apr 2010, 15:25)=-=-
Status updated.
--- /tmp/wklog.47.old.12734 2010-04-06 15:25:54.000000000 +0000
+++ /tmp/wklog.47.new.12734 2010-04-06 15:25:54.000000000 +0000
@@ -1 +1 @@
-Code-Review
+In-Progress
-=-=(Knielsen - Mon, 29 Mar 2010, 10:59)=-=-
Status updated.
--- /tmp/wklog.47.old.27790 2010-03-29 10:59:53.000000000 +0000
+++ /tmp/wklog.47.new.27790 2010-03-29 10:59:53.000000000 +0000
@@ -1 +1 @@
-In-Progress
+Code-Review
-=-=(Alexi - Thu, 18 Feb 2010, 19:29)=-=-
Worked 20 hours (alexi)
Worked 20 hours and estimate 15 hours remain (original estimate unchanged).
-=-=(Serg - Fri, 05 Feb 2010, 14:04)=-=-
Observers changed: Knielsen,Serg
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Category updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Server-RawIdeaBin
+Server-Sprint
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Status updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Un-Assigned
+In-Progress
-=-=(Alexi - Thu, 04 Feb 2010, 09:54)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.16174 2010-02-04 09:54:13.000000000 +0200
+++ /tmp/wklog.47.new.16174 2010-02-04 09:54:13.000000000 +0200
@@ -171,35 +171,20 @@
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When requesting an event, the slave should inform the master whether
-it should send Annotate_rows events or not. To that end we add a new
-BINLOG_SEND_ANNOTATE_ROWS_EVENT flag used when requesting an event:
+If the replicate-annotate-rows-events option is not set on a slave, there
+is no need for master to send Annotate_rows events to this slave. The slave
+(or mysqlbinlog in remote case), before requesting binlog dump via the
+COM_BINLOG_DUMP command, informs the master whether it should send these
+events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
+command:
+
+ case COM_BINLOG_DUMP_OPTIONS_EXT:
+ thd->binlog_dump_flags_ext= packet[0];
+ my_ok(thd);
+ break;
- #define BINLOG_DUMP_NON_BLOCK 1
- #define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2
-
- pthread_handler_t handle_slave_io(void *arg)
- { ...
- request_dump(mysql, ...);
- ...
- }
-
- int request_dump(MYSQL* mysql, ...)
- { ...
- if (opt_log_slave_updates &&
- mi->io_thd->variables.binlog_annotate_rows_events)
- binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
- ...
- int2store(buf + 4, binlog_flags);
- ...
- simple_command(mysql, COM_BINLOG_DUMP, buf, ...);
- ...
- }
-
-NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
-simple_command() function, should also use this flag if it wants (in case
-of the --print-annotate-rows-events option set) to recieve Annotate_rows
-events.
+Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
+conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -338,10 +323,4 @@
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
-Also we should notice the introduction of the BINLOG_SEND_ANNOTATE_ROWS_EVENT
-flag taking into account that MySQL/Sun may also introduce a flag with the
-same value to be used in the request_dump-mysql_binlog_send interface.
-But this is mainly the question of merging: if a conflict concerning this
-flag occur, we may simply change the BINLOG_SEND_ANNOTATE_ROWS_EVENT value
-(this does not require additional changes in the code).
-=-=(Alexi - Sun, 20 Dec 2009, 16:00)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.19667 2009-12-20 14:00:56.000000000 +0000
+++ /tmp/wklog.47.new.19667 2009-12-20 14:00:56.000000000 +0000
@@ -196,6 +196,11 @@
...
}
+NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
+simple_command() function, should also use this flag if it wants (in case
+of the --print-annotate-rows-events option set) to recieve Annotate_rows
+events.
+
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,8 +217,7 @@
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
- flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT ||
- thd->server_id == 0 /* slave == mysqlbinlog */ )
+ flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
-=-=(Alexi - Sun, 20 Dec 2009, 13:14)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.11350 2009-12-20 13:14:04.000000000 +0200
+++ /tmp/wklog.47.new.11350 2009-12-20 13:14:04.000000000 +0200
@@ -282,23 +282,18 @@
Annotate_rows_log_event* m_annotate_event;
};
-When the saved Annotate_rows object may be deleted? When all corresponding
-Rows events will be processed, i.e. before processing the first non-Rows
-event (note that Annotate_rows object resides in the binary log *after*
-the (possible) 'BEGIN' Query event which accompanies the rows events; note
-also that this deletion is adjusted with the case when some or all
-corresponding Rows events are filtered out by replicate filter rules):
+The saved Annotate_rows object should be deleted when all corresponding
+Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
- if (rli->get_annotate_event() && !IS_RBR_EVENT_TYPE(ev->get_type_code()))
- rli->free_annotate_event();
-
apply_event_and_update_pos(ev, ...);
- if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
+ if (rli->get_annotate_event() && is_last_rows_event(ev))
+ rli->free_annotate_event();
+ else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
@@ -307,10 +302,21 @@
where
- #define IS_RBR_EVENT_TYPE(type) ( (type) == TABLE_MAP_EVENT || \
- (type) == WRITE_ROWS_EVENT || \
+ bool is_last_rows_event(Log_event* ev)
+ {
+ Log_event_type type= ev->get_type_code();
+ if (IS_ROWS_EVENT_TYPE(type))
+ {
+ Rows_log_event* rows= (Rows_log_event*)ev;
+ return rows->get_flags(Rows_log_event::STMT_END_F);
+ }
+
+ return 0;
+ }
+
+ #define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
- (type) == DELETE_ROWS_EVENT )
+ (type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
------------------------------------------------------------
-=-=(View All Progress Notes, 27 total)=-=-
http://askmonty.org/worklog/index.pl?tid=47&nolimit=1
DESCRIPTION:
Store in binlog (and show in mysqlbinlog output) texts of statements that
caused RBR events
This is needed for (list from Monty):
- Easier to understand why updates happened
- Would make it easier to find out where in application things went
wrong (as you can search for exact strings)
- Allow one to filter things based on comments in the statement.
The cost of this can be that the binlog will be approximately 2x in size
(especially insert of big blob's would be a bit painful), so this should
be an optional feature.
HIGH-LEVEL SPECIFICATION:
Content
~~~~~~~
1. Annotate_rows_log_event
2. Server option: --binlog-annotate-rows-events
3. Server option: --replicate-annotate-rows-events
4. mysqlbinlog option: --print-annotate-rows-events
5. mysqlbinlog output
1. Annotate_rows_log_event [ ANNOTATE_ROWS_EVENT ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Describes the query which caused the corresponding rows events. Has empty
post-header and contains the query text in its data part. Example:
************************
ANNOTATE_ROWS_EVENT
************************
00000220 | B6 A0 2C 4B | time_when = 1261215926
00000224 | 33 | event_type = 51
00000225 | 64 00 00 00 | server_id = 100
00000229 | 36 00 00 00 | event_len = 54
0000022D | 56 02 00 00 | log_pos = 00000256
00000231 | 00 00 | flags = <none>
------------------------
00000233 | 49 4E 53 45 | query = "INSERT INTO t1 VALUES (1), (2), (3)"
00000237 | 52 54 20 49 |
0000023B | 4E 54 4F 20 |
0000023F | 74 31 20 56 |
00000243 | 41 4C 55 45 |
00000247 | 53 20 28 31 |
0000024B | 29 2C 20 28 |
0000024F | 32 29 2C 20 |
00000253 | 28 33 29 |
************************
In binary log, Annotate_rows event follows the (possible) 'BEGIN' Query event
and precedes the first of Table map events which accompany the corresponding
rows events. (See example in the "mysqlbinlog output" section below.)
2. Server option: --binlog-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the master to write Annotate_rows events to the binary log.
* Variable Name: binlog_annotate_rows_events
* Scope: Global & Session
* Access Type: Dynamic
* Data Type: bool
* Default Value: OFF
NOTE. Session values allows to annotate only some selected statements:
...
SET SESSION binlog_annotate_rows_events=ON;
... statements to be annotated ...
SET SESSION binlog_annotate_rows_events=OFF;
... statements not to be annotated ...
3. Server option: --replicate-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the slave to reproduce Annotate_rows events recieved from the master
in its own binary log (sensible only in pair with log-slave-updates option).
* Variable Name: replicate_annotate_rows_events
* Scope: Global
* Access Type: Read only
* Data Type: bool
* Default Value: OFF
NOTE. Why do we additionally need this 'replicate' option? Why not to make
the slave to reproduce this events when its binlog-annotate-rows-events
global value is ON? Well, because, for example, we may want to configure
the slave which should reproduce Annotate_rows events but has global
binlog-annotate-rows-events = OFF meaning this to be the default value for
the client threads (see also "How slave treats replicate-annotate-rows-events
option" in LLD part).
4. mysqlbinlog option: --print-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With this option, mysqlbinlog prints the content of Annotate_rows events (if
the binary log does contain them). Without this option (i.e. by default),
mysqlbinlog skips Annotate_rows events.
5. mysqlbinlog output
~~~~~~~~~~~~~~~~~~~~~
With --print-annotate-rows-events, mysqlbinlog outputs Annotate_rows events
in a form like this:
...
# at 1646
#091219 12:45:26 server id 100 end_log_pos 1714 Query thread_id=1
exec_time=0 error_code=0
SET TIMESTAMP=1261215926/*!*/;
BEGIN
/*!*/;
# at 1714
# at 1812
# at 1853
# at 1894
# at 1938
#091219 12:45:26 server id 100 end_log_pos 1812 Query: `DELETE t1, t2 FROM
t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a`
#091219 12:45:26 server id 100 end_log_pos 1853 Table_map: `test`.`t1`
mapped to number 16
#091219 12:45:26 server id 100 end_log_pos 1894 Table_map: `test`.`t2`
mapped to number 17
#091219 12:45:26 server id 100 end_log_pos 1938 Delete_rows: table id 16
#091219 12:45:26 server id 100 end_log_pos 1982 Delete_rows: table id 17
flags: STMT_END_F
...
LOW-LEVEL DESIGN:
Content
~~~~~~~
1. Annotate_rows event number
2. Outline of Annotate_rows event behavior
3. How Master writes Annotate_rows events to the binary log
4. How slave treats replicate-annotate-rows-events option
5. How slave IO thread requests Annotate_rows events
6. How master executes the request
7. How slave SQL thread processes Annotate_rows events
8. General remarks
1. Annotate_rows event number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid possible event numbers conflict with MySQL/Sun, we leave a gap
between the last MySQL event number and the Annotate_rows event number:
enum Log_event_type
{ ...
INCIDENT_EVENT= 26,
// New MySQL event numbers are to be added here
MYSQL_EVENTS_END,
MARIA_EVENTS_BEGIN= 51,
// New Maria event numbers start from here
ANNOTATE_ROWS_EVENT= 51,
ENUM_END_EVENT
};
together with the corresponding extension of 'post_header_len' array in the
Format description event. (This extension does not affect the compatibility
of the binary log). Here is how Format description event looks like with
this extension:
************************
FORMAT_DESCRIPTION_EVENT
************************
00000004 | A1 A0 2C 4B | time_when = 1261215905
00000008 | 0F | event_type = 15
00000009 | 64 00 00 00 | server_id = 100
0000000D | 7F 00 00 00 | event_len = 127
00000011 | 83 00 00 00 | log_pos = 00000083
00000015 | 01 00 | flags = LOG_EVENT_BINLOG_IN_USE_F
------------------------
00000017 | 04 00 | binlog_ver = 4
00000019 | 35 2E 32 2E | server_ver = 5.2.0-MariaDB-alpha-debug-log
..... ...
0000004B | A1 A0 2C 4B | time_created = 1261215905
0000004F | 13 | common_header_len = 19
------------------------
post_header_len
------------------------
00000050 | 38 | 56 - START_EVENT_V3 [1]
..... ...
00000069 | 02 | 2 - INCIDENT_EVENT [26]
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each Annotate_rows_log_event object has two private members describing the
corresponding query:
char *m_query_txt;
uint m_query_len;
When the object is created for writing to a binary log, this query is taken
from 'thd' (for short, below we omit the 'Annotate_rows_log_event::' prefix
as well as other implementation details):
Annotate_rows_log_event(THD *thd)
{
m_query_txt = thd->query();
m_query_len = thd->query_length();
}
When the object is read from a binary log, the query is taken from the buffer
containing the binary log representation of the event (this buffer is allocated
in Log_event object from which all Log events are derived):
Annotate_rows_log_event(char *buf, uint event_len,
Format_description_log_event *desc)
{
m_query_len = event_len - desc->common_header_len;
m_query_txt = buf + desc->common_header_len;
}
The events are written to the binary log by the Log_event::write() member
which calls virtual write_data_header() and write_data_body() members
("data header" and "post header" are synonym in replication terminology).
In our case, data header is empty and data body is just the query:
bool write_data_body(IO_CACHE *file)
{
return my_b_safe_write(file, (uchar*) m_query_txt, m_query_len);
}
Printing the event is just printing the query:
void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
{
my_b_printf(&pinfo->head_cache, "\tQuery: `%s`\n", m_query_txt);
}
3. How Master writes Annotate_rows events to the binary log
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The event is written to the binary log just before the group of Table_map
events which precede corresponding Rows events (one query may generate
several Table map events in the binary log, but the corresponding
Annotate_rows event must be written only once before the first Table map
event; hence the boolean variable 'with_annotate' below):
int write_locked_table_maps(THD *thd)
{ ...
bool with_annotate= thd->variables.binlog_annotate_rows_events;
...
for (uint i= 0; i < ... <number of tables> ...; ++i)
{ ...
thd->binlog_write_table_map(table, ..., with_annotate);
with_annotate= 0; // write Annotate_event not more than once
...
}
...
}
int THD::binlog_write_table_map(TABLE *table, ..., bool with_annotate)
{ ...
Table_map_log_event the_event(...);
...
if (with_annotate)
{
Annotate_rows_log_event anno(this);
mysql_bin_log.write(&anno);
}
mysql_bin_log.write(&the_event);
...
}
4. How slave treats replicate-annotate-rows-events option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The replicate-annotate-rows-events option is treated just as the session
value of the binlog_annotate_rows_events variable for the slave IO and
SQL threads. This setting is done during initialization of these threads:
pthread_handler_t handle_slave_io(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_IO);
...
}
pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_SQL);
...
}
int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{ ...
thd->variables.binlog_annotate_rows_events=
opt_replicate_annotate_rows_events;
...
}
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the replicate-annotate-rows-events option is not set on a slave, there
is no need for master to send Annotate_rows events to this slave. The slave
(or mysqlbinlog in remote case), before requesting binlog dump via the
COM_BINLOG_DUMP command, informs the master whether it should send these
events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
command:
case COM_BINLOG_DUMP_OPTIONS_EXT:
thd->binlog_dump_flags_ext= packet[0];
my_ok(thd);
break;
Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
case COM_BINLOG_DUMP:
{ ...
flags= uint2korr(packet + 4);
...
mysql_binlog_send(thd, ..., flags);
...
}
void mysql_binlog_send(THD* thd, ..., ushort flags)
{ ...
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
...
}
7. How slave SQL thread processes Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slave processes each recieved event by "applying" it, i.e. by
calling the Log_event::apply_event() function which in turn calls
the virtual do_apply_event() member specific for each type of the
event.
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev = next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
int apply_event_and_update_pos(Log_event *ev, ...)
{ ...
ev->apply_event(...);
...
}
int Log_event::apply_event(...)
{
return do_apply_event(...);
}
What does it mean to "apply" an Annotate_rows event? It means to set current
thd query to that of the described by the event, i.e. to the query which
caused the subsequent Rows events (see "How Master writes Annotate_rows
events to the binary log" to follow what happens further when the subsequent
Rows events are applied):
int Annotate_rows_log_event::do_apply_event(...)
{
thd->set_query(m_query_txt, m_query_len);
}
NOTE. I am not sure, but possibly current values of thd->query and
thd->query_length should be saved before calling set_query() and to be
restored on the Annotate_rows_log_event object deletion.
Is it really needed ?
After calling this do_apply_event() function we may not delete the
Annotate_rows_log_event object immediatedly (see exec_relay_log_event()
above) because thd->query now points to the string inside this object.
We may keep the pointer to this object in the Relay_log_info:
class Relay_log_info
{
public:
...
void set_annotate_event(Annotate_rows_log_event*);
Annotate_rows_log_event* get_annotate_event();
void free_annotate_event();
...
private:
Annotate_rows_log_event* m_annotate_event;
};
The saved Annotate_rows object should be deleted when all corresponding
Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (rli->get_annotate_event() && is_last_rows_event(ev))
rli->free_annotate_event();
else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
where
bool is_last_rows_event(Log_event* ev)
{
Log_event_type type= ev->get_type_code();
if (IS_ROWS_EVENT_TYPE(type))
{
Rows_log_event* rows= (Rows_log_event*)ev;
return rows->get_flags(Rows_log_event::STMT_END_F);
}
return 0;
}
#define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
(type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
Kristian noticed that introducing new log event type should be coordinated
somehow with MySQL/Sun:
Kristian: The numeric code for this event must be assigned carefully.
It should be coordinated with MySQL/Sun, otherwise we can get into a
situation where MySQL uses the same numeric code for one event that
MariaDB uses for ANNOTATE_ROWS_EVENT, which would make merging the two
impossible.
Alex: I reserved about 20 numbers not to have possible conflicts
with MySQL.
Kristian: Still, I think it would be appropriate to send a polite email
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Progress (by Knielsen): Store in binlog text of statements that caused RBR events (47)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Store in binlog text of statements that caused RBR events
CREATION DATE..: Sat, 15 Aug 2009, 23:48
SUPERVISOR.....: Monty
IMPLEMENTOR....:
COPIES TO......: Knielsen, Serg
CATEGORY.......: Server-Sprint
TASK ID........: 47 (http://askmonty.org/worklog/?tid=47)
VERSION........: Server-9.x
STATUS.........: In-Progress
PRIORITY.......: 60
WORKED HOURS...: 47
ESTIMATE.......: 8 (hours remain)
ORIG. ESTIMATE.: 35
PROGRESS NOTES:
-=-=(Knielsen - Tue, 06 Apr 2010, 15:26)=-=-
Code review (mailed to maria-developers@).
Worked 7 hours and estimate 8 hours remain (original estimate unchanged).
-=-=(Knielsen - Tue, 06 Apr 2010, 15:25)=-=-
Status updated.
--- /tmp/wklog.47.old.12734 2010-04-06 15:25:54.000000000 +0000
+++ /tmp/wklog.47.new.12734 2010-04-06 15:25:54.000000000 +0000
@@ -1 +1 @@
-Code-Review
+In-Progress
-=-=(Knielsen - Mon, 29 Mar 2010, 10:59)=-=-
Status updated.
--- /tmp/wklog.47.old.27790 2010-03-29 10:59:53.000000000 +0000
+++ /tmp/wklog.47.new.27790 2010-03-29 10:59:53.000000000 +0000
@@ -1 +1 @@
-In-Progress
+Code-Review
-=-=(Alexi - Thu, 18 Feb 2010, 19:29)=-=-
Worked 20 hours (alexi)
Worked 20 hours and estimate 15 hours remain (original estimate unchanged).
-=-=(Serg - Fri, 05 Feb 2010, 14:04)=-=-
Observers changed: Knielsen,Serg
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Category updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Server-RawIdeaBin
+Server-Sprint
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Status updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Un-Assigned
+In-Progress
-=-=(Alexi - Thu, 04 Feb 2010, 09:54)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.16174 2010-02-04 09:54:13.000000000 +0200
+++ /tmp/wklog.47.new.16174 2010-02-04 09:54:13.000000000 +0200
@@ -171,35 +171,20 @@
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When requesting an event, the slave should inform the master whether
-it should send Annotate_rows events or not. To that end we add a new
-BINLOG_SEND_ANNOTATE_ROWS_EVENT flag used when requesting an event:
+If the replicate-annotate-rows-events option is not set on a slave, there
+is no need for master to send Annotate_rows events to this slave. The slave
+(or mysqlbinlog in remote case), before requesting binlog dump via the
+COM_BINLOG_DUMP command, informs the master whether it should send these
+events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
+command:
+
+ case COM_BINLOG_DUMP_OPTIONS_EXT:
+ thd->binlog_dump_flags_ext= packet[0];
+ my_ok(thd);
+ break;
- #define BINLOG_DUMP_NON_BLOCK 1
- #define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2
-
- pthread_handler_t handle_slave_io(void *arg)
- { ...
- request_dump(mysql, ...);
- ...
- }
-
- int request_dump(MYSQL* mysql, ...)
- { ...
- if (opt_log_slave_updates &&
- mi->io_thd->variables.binlog_annotate_rows_events)
- binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
- ...
- int2store(buf + 4, binlog_flags);
- ...
- simple_command(mysql, COM_BINLOG_DUMP, buf, ...);
- ...
- }
-
-NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
-simple_command() function, should also use this flag if it wants (in case
-of the --print-annotate-rows-events option set) to recieve Annotate_rows
-events.
+Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
+conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -338,10 +323,4 @@
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
-Also we should notice the introduction of the BINLOG_SEND_ANNOTATE_ROWS_EVENT
-flag taking into account that MySQL/Sun may also introduce a flag with the
-same value to be used in the request_dump-mysql_binlog_send interface.
-But this is mainly the question of merging: if a conflict concerning this
-flag occur, we may simply change the BINLOG_SEND_ANNOTATE_ROWS_EVENT value
-(this does not require additional changes in the code).
-=-=(Alexi - Sun, 20 Dec 2009, 16:00)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.19667 2009-12-20 14:00:56.000000000 +0000
+++ /tmp/wklog.47.new.19667 2009-12-20 14:00:56.000000000 +0000
@@ -196,6 +196,11 @@
...
}
+NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
+simple_command() function, should also use this flag if it wants (in case
+of the --print-annotate-rows-events option set) to recieve Annotate_rows
+events.
+
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,8 +217,7 @@
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
- flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT ||
- thd->server_id == 0 /* slave == mysqlbinlog */ )
+ flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
-=-=(Alexi - Sun, 20 Dec 2009, 13:14)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.11350 2009-12-20 13:14:04.000000000 +0200
+++ /tmp/wklog.47.new.11350 2009-12-20 13:14:04.000000000 +0200
@@ -282,23 +282,18 @@
Annotate_rows_log_event* m_annotate_event;
};
-When the saved Annotate_rows object may be deleted? When all corresponding
-Rows events will be processed, i.e. before processing the first non-Rows
-event (note that Annotate_rows object resides in the binary log *after*
-the (possible) 'BEGIN' Query event which accompanies the rows events; note
-also that this deletion is adjusted with the case when some or all
-corresponding Rows events are filtered out by replicate filter rules):
+The saved Annotate_rows object should be deleted when all corresponding
+Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
- if (rli->get_annotate_event() && !IS_RBR_EVENT_TYPE(ev->get_type_code()))
- rli->free_annotate_event();
-
apply_event_and_update_pos(ev, ...);
- if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
+ if (rli->get_annotate_event() && is_last_rows_event(ev))
+ rli->free_annotate_event();
+ else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
@@ -307,10 +302,21 @@
where
- #define IS_RBR_EVENT_TYPE(type) ( (type) == TABLE_MAP_EVENT || \
- (type) == WRITE_ROWS_EVENT || \
+ bool is_last_rows_event(Log_event* ev)
+ {
+ Log_event_type type= ev->get_type_code();
+ if (IS_ROWS_EVENT_TYPE(type))
+ {
+ Rows_log_event* rows= (Rows_log_event*)ev;
+ return rows->get_flags(Rows_log_event::STMT_END_F);
+ }
+
+ return 0;
+ }
+
+ #define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
- (type) == DELETE_ROWS_EVENT )
+ (type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
------------------------------------------------------------
-=-=(View All Progress Notes, 27 total)=-=-
http://askmonty.org/worklog/index.pl?tid=47&nolimit=1
DESCRIPTION:
Store in binlog (and show in mysqlbinlog output) texts of statements that
caused RBR events
This is needed for (list from Monty):
- Easier to understand why updates happened
- Would make it easier to find out where in application things went
wrong (as you can search for exact strings)
- Allow one to filter things based on comments in the statement.
The cost of this can be that the binlog will be approximately 2x in size
(especially insert of big blob's would be a bit painful), so this should
be an optional feature.
HIGH-LEVEL SPECIFICATION:
Content
~~~~~~~
1. Annotate_rows_log_event
2. Server option: --binlog-annotate-rows-events
3. Server option: --replicate-annotate-rows-events
4. mysqlbinlog option: --print-annotate-rows-events
5. mysqlbinlog output
1. Annotate_rows_log_event [ ANNOTATE_ROWS_EVENT ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Describes the query which caused the corresponding rows events. Has empty
post-header and contains the query text in its data part. Example:
************************
ANNOTATE_ROWS_EVENT
************************
00000220 | B6 A0 2C 4B | time_when = 1261215926
00000224 | 33 | event_type = 51
00000225 | 64 00 00 00 | server_id = 100
00000229 | 36 00 00 00 | event_len = 54
0000022D | 56 02 00 00 | log_pos = 00000256
00000231 | 00 00 | flags = <none>
------------------------
00000233 | 49 4E 53 45 | query = "INSERT INTO t1 VALUES (1), (2), (3)"
00000237 | 52 54 20 49 |
0000023B | 4E 54 4F 20 |
0000023F | 74 31 20 56 |
00000243 | 41 4C 55 45 |
00000247 | 53 20 28 31 |
0000024B | 29 2C 20 28 |
0000024F | 32 29 2C 20 |
00000253 | 28 33 29 |
************************
In binary log, Annotate_rows event follows the (possible) 'BEGIN' Query event
and precedes the first of Table map events which accompany the corresponding
rows events. (See example in the "mysqlbinlog output" section below.)
2. Server option: --binlog-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the master to write Annotate_rows events to the binary log.
* Variable Name: binlog_annotate_rows_events
* Scope: Global & Session
* Access Type: Dynamic
* Data Type: bool
* Default Value: OFF
NOTE. Session values allows to annotate only some selected statements:
...
SET SESSION binlog_annotate_rows_events=ON;
... statements to be annotated ...
SET SESSION binlog_annotate_rows_events=OFF;
... statements not to be annotated ...
3. Server option: --replicate-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the slave to reproduce Annotate_rows events recieved from the master
in its own binary log (sensible only in pair with log-slave-updates option).
* Variable Name: replicate_annotate_rows_events
* Scope: Global
* Access Type: Read only
* Data Type: bool
* Default Value: OFF
NOTE. Why do we additionally need this 'replicate' option? Why not to make
the slave to reproduce this events when its binlog-annotate-rows-events
global value is ON? Well, because, for example, we may want to configure
the slave which should reproduce Annotate_rows events but has global
binlog-annotate-rows-events = OFF meaning this to be the default value for
the client threads (see also "How slave treats replicate-annotate-rows-events
option" in LLD part).
4. mysqlbinlog option: --print-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With this option, mysqlbinlog prints the content of Annotate_rows events (if
the binary log does contain them). Without this option (i.e. by default),
mysqlbinlog skips Annotate_rows events.
5. mysqlbinlog output
~~~~~~~~~~~~~~~~~~~~~
With --print-annotate-rows-events, mysqlbinlog outputs Annotate_rows events
in a form like this:
...
# at 1646
#091219 12:45:26 server id 100 end_log_pos 1714 Query thread_id=1
exec_time=0 error_code=0
SET TIMESTAMP=1261215926/*!*/;
BEGIN
/*!*/;
# at 1714
# at 1812
# at 1853
# at 1894
# at 1938
#091219 12:45:26 server id 100 end_log_pos 1812 Query: `DELETE t1, t2 FROM
t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a`
#091219 12:45:26 server id 100 end_log_pos 1853 Table_map: `test`.`t1`
mapped to number 16
#091219 12:45:26 server id 100 end_log_pos 1894 Table_map: `test`.`t2`
mapped to number 17
#091219 12:45:26 server id 100 end_log_pos 1938 Delete_rows: table id 16
#091219 12:45:26 server id 100 end_log_pos 1982 Delete_rows: table id 17
flags: STMT_END_F
...
LOW-LEVEL DESIGN:
Content
~~~~~~~
1. Annotate_rows event number
2. Outline of Annotate_rows event behavior
3. How Master writes Annotate_rows events to the binary log
4. How slave treats replicate-annotate-rows-events option
5. How slave IO thread requests Annotate_rows events
6. How master executes the request
7. How slave SQL thread processes Annotate_rows events
8. General remarks
1. Annotate_rows event number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid possible event numbers conflict with MySQL/Sun, we leave a gap
between the last MySQL event number and the Annotate_rows event number:
enum Log_event_type
{ ...
INCIDENT_EVENT= 26,
// New MySQL event numbers are to be added here
MYSQL_EVENTS_END,
MARIA_EVENTS_BEGIN= 51,
// New Maria event numbers start from here
ANNOTATE_ROWS_EVENT= 51,
ENUM_END_EVENT
};
together with the corresponding extension of 'post_header_len' array in the
Format description event. (This extension does not affect the compatibility
of the binary log). Here is how Format description event looks like with
this extension:
************************
FORMAT_DESCRIPTION_EVENT
************************
00000004 | A1 A0 2C 4B | time_when = 1261215905
00000008 | 0F | event_type = 15
00000009 | 64 00 00 00 | server_id = 100
0000000D | 7F 00 00 00 | event_len = 127
00000011 | 83 00 00 00 | log_pos = 00000083
00000015 | 01 00 | flags = LOG_EVENT_BINLOG_IN_USE_F
------------------------
00000017 | 04 00 | binlog_ver = 4
00000019 | 35 2E 32 2E | server_ver = 5.2.0-MariaDB-alpha-debug-log
..... ...
0000004B | A1 A0 2C 4B | time_created = 1261215905
0000004F | 13 | common_header_len = 19
------------------------
post_header_len
------------------------
00000050 | 38 | 56 - START_EVENT_V3 [1]
..... ...
00000069 | 02 | 2 - INCIDENT_EVENT [26]
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each Annotate_rows_log_event object has two private members describing the
corresponding query:
char *m_query_txt;
uint m_query_len;
When the object is created for writing to a binary log, this query is taken
from 'thd' (for short, below we omit the 'Annotate_rows_log_event::' prefix
as well as other implementation details):
Annotate_rows_log_event(THD *thd)
{
m_query_txt = thd->query();
m_query_len = thd->query_length();
}
When the object is read from a binary log, the query is taken from the buffer
containing the binary log representation of the event (this buffer is allocated
in Log_event object from which all Log events are derived):
Annotate_rows_log_event(char *buf, uint event_len,
Format_description_log_event *desc)
{
m_query_len = event_len - desc->common_header_len;
m_query_txt = buf + desc->common_header_len;
}
The events are written to the binary log by the Log_event::write() member
which calls virtual write_data_header() and write_data_body() members
("data header" and "post header" are synonym in replication terminology).
In our case, data header is empty and data body is just the query:
bool write_data_body(IO_CACHE *file)
{
return my_b_safe_write(file, (uchar*) m_query_txt, m_query_len);
}
Printing the event is just printing the query:
void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
{
my_b_printf(&pinfo->head_cache, "\tQuery: `%s`\n", m_query_txt);
}
3. How Master writes Annotate_rows events to the binary log
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The event is written to the binary log just before the group of Table_map
events which precede corresponding Rows events (one query may generate
several Table map events in the binary log, but the corresponding
Annotate_rows event must be written only once before the first Table map
event; hence the boolean variable 'with_annotate' below):
int write_locked_table_maps(THD *thd)
{ ...
bool with_annotate= thd->variables.binlog_annotate_rows_events;
...
for (uint i= 0; i < ... <number of tables> ...; ++i)
{ ...
thd->binlog_write_table_map(table, ..., with_annotate);
with_annotate= 0; // write Annotate_event not more than once
...
}
...
}
int THD::binlog_write_table_map(TABLE *table, ..., bool with_annotate)
{ ...
Table_map_log_event the_event(...);
...
if (with_annotate)
{
Annotate_rows_log_event anno(this);
mysql_bin_log.write(&anno);
}
mysql_bin_log.write(&the_event);
...
}
4. How slave treats replicate-annotate-rows-events option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The replicate-annotate-rows-events option is treated just as the session
value of the binlog_annotate_rows_events variable for the slave IO and
SQL threads. This setting is done during initialization of these threads:
pthread_handler_t handle_slave_io(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_IO);
...
}
pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_SQL);
...
}
int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{ ...
thd->variables.binlog_annotate_rows_events=
opt_replicate_annotate_rows_events;
...
}
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the replicate-annotate-rows-events option is not set on a slave, there
is no need for master to send Annotate_rows events to this slave. The slave
(or mysqlbinlog in remote case), before requesting binlog dump via the
COM_BINLOG_DUMP command, informs the master whether it should send these
events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
command:
case COM_BINLOG_DUMP_OPTIONS_EXT:
thd->binlog_dump_flags_ext= packet[0];
my_ok(thd);
break;
Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
case COM_BINLOG_DUMP:
{ ...
flags= uint2korr(packet + 4);
...
mysql_binlog_send(thd, ..., flags);
...
}
void mysql_binlog_send(THD* thd, ..., ushort flags)
{ ...
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
...
}
7. How slave SQL thread processes Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slave processes each recieved event by "applying" it, i.e. by
calling the Log_event::apply_event() function which in turn calls
the virtual do_apply_event() member specific for each type of the
event.
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev = next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
int apply_event_and_update_pos(Log_event *ev, ...)
{ ...
ev->apply_event(...);
...
}
int Log_event::apply_event(...)
{
return do_apply_event(...);
}
What does it mean to "apply" an Annotate_rows event? It means to set current
thd query to that of the described by the event, i.e. to the query which
caused the subsequent Rows events (see "How Master writes Annotate_rows
events to the binary log" to follow what happens further when the subsequent
Rows events are applied):
int Annotate_rows_log_event::do_apply_event(...)
{
thd->set_query(m_query_txt, m_query_len);
}
NOTE. I am not sure, but possibly current values of thd->query and
thd->query_length should be saved before calling set_query() and to be
restored on the Annotate_rows_log_event object deletion.
Is it really needed ?
After calling this do_apply_event() function we may not delete the
Annotate_rows_log_event object immediatedly (see exec_relay_log_event()
above) because thd->query now points to the string inside this object.
We may keep the pointer to this object in the Relay_log_info:
class Relay_log_info
{
public:
...
void set_annotate_event(Annotate_rows_log_event*);
Annotate_rows_log_event* get_annotate_event();
void free_annotate_event();
...
private:
Annotate_rows_log_event* m_annotate_event;
};
The saved Annotate_rows object should be deleted when all corresponding
Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (rli->get_annotate_event() && is_last_rows_event(ev))
rli->free_annotate_event();
else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
where
bool is_last_rows_event(Log_event* ev)
{
Log_event_type type= ev->get_type_code();
if (IS_ROWS_EVENT_TYPE(type))
{
Rows_log_event* rows= (Rows_log_event*)ev;
return rows->get_flags(Rows_log_event::STMT_END_F);
}
return 0;
}
#define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
(type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
Kristian noticed that introducing new log event type should be coordinated
somehow with MySQL/Sun:
Kristian: The numeric code for this event must be assigned carefully.
It should be coordinated with MySQL/Sun, otherwise we can get into a
situation where MySQL uses the same numeric code for one event that
MariaDB uses for ANNOTATE_ROWS_EVENT, which would make merging the two
impossible.
Alex: I reserved about 20 numbers not to have possible conflicts
with MySQL.
Kristian: Still, I think it would be appropriate to send a polite email
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Progress (by Knielsen): Store in binlog text of statements that caused RBR events (47)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Store in binlog text of statements that caused RBR events
CREATION DATE..: Sat, 15 Aug 2009, 23:48
SUPERVISOR.....: Monty
IMPLEMENTOR....:
COPIES TO......: Knielsen, Serg
CATEGORY.......: Server-Sprint
TASK ID........: 47 (http://askmonty.org/worklog/?tid=47)
VERSION........: Server-9.x
STATUS.........: In-Progress
PRIORITY.......: 60
WORKED HOURS...: 47
ESTIMATE.......: 8 (hours remain)
ORIG. ESTIMATE.: 35
PROGRESS NOTES:
-=-=(Knielsen - Tue, 06 Apr 2010, 15:26)=-=-
Code review (mailed to maria-developers@).
Worked 7 hours and estimate 8 hours remain (original estimate unchanged).
-=-=(Knielsen - Tue, 06 Apr 2010, 15:25)=-=-
Status updated.
--- /tmp/wklog.47.old.12734 2010-04-06 15:25:54.000000000 +0000
+++ /tmp/wklog.47.new.12734 2010-04-06 15:25:54.000000000 +0000
@@ -1 +1 @@
-Code-Review
+In-Progress
-=-=(Knielsen - Mon, 29 Mar 2010, 10:59)=-=-
Status updated.
--- /tmp/wklog.47.old.27790 2010-03-29 10:59:53.000000000 +0000
+++ /tmp/wklog.47.new.27790 2010-03-29 10:59:53.000000000 +0000
@@ -1 +1 @@
-In-Progress
+Code-Review
-=-=(Alexi - Thu, 18 Feb 2010, 19:29)=-=-
Worked 20 hours (alexi)
Worked 20 hours and estimate 15 hours remain (original estimate unchanged).
-=-=(Serg - Fri, 05 Feb 2010, 14:04)=-=-
Observers changed: Knielsen,Serg
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Category updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Server-RawIdeaBin
+Server-Sprint
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Status updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Un-Assigned
+In-Progress
-=-=(Alexi - Thu, 04 Feb 2010, 09:54)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.16174 2010-02-04 09:54:13.000000000 +0200
+++ /tmp/wklog.47.new.16174 2010-02-04 09:54:13.000000000 +0200
@@ -171,35 +171,20 @@
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When requesting an event, the slave should inform the master whether
-it should send Annotate_rows events or not. To that end we add a new
-BINLOG_SEND_ANNOTATE_ROWS_EVENT flag used when requesting an event:
+If the replicate-annotate-rows-events option is not set on a slave, there
+is no need for master to send Annotate_rows events to this slave. The slave
+(or mysqlbinlog in remote case), before requesting binlog dump via the
+COM_BINLOG_DUMP command, informs the master whether it should send these
+events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
+command:
+
+ case COM_BINLOG_DUMP_OPTIONS_EXT:
+ thd->binlog_dump_flags_ext= packet[0];
+ my_ok(thd);
+ break;
- #define BINLOG_DUMP_NON_BLOCK 1
- #define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2
-
- pthread_handler_t handle_slave_io(void *arg)
- { ...
- request_dump(mysql, ...);
- ...
- }
-
- int request_dump(MYSQL* mysql, ...)
- { ...
- if (opt_log_slave_updates &&
- mi->io_thd->variables.binlog_annotate_rows_events)
- binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
- ...
- int2store(buf + 4, binlog_flags);
- ...
- simple_command(mysql, COM_BINLOG_DUMP, buf, ...);
- ...
- }
-
-NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
-simple_command() function, should also use this flag if it wants (in case
-of the --print-annotate-rows-events option set) to recieve Annotate_rows
-events.
+Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
+conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -338,10 +323,4 @@
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
-Also we should notice the introduction of the BINLOG_SEND_ANNOTATE_ROWS_EVENT
-flag taking into account that MySQL/Sun may also introduce a flag with the
-same value to be used in the request_dump-mysql_binlog_send interface.
-But this is mainly the question of merging: if a conflict concerning this
-flag occur, we may simply change the BINLOG_SEND_ANNOTATE_ROWS_EVENT value
-(this does not require additional changes in the code).
-=-=(Alexi - Sun, 20 Dec 2009, 16:00)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.19667 2009-12-20 14:00:56.000000000 +0000
+++ /tmp/wklog.47.new.19667 2009-12-20 14:00:56.000000000 +0000
@@ -196,6 +196,11 @@
...
}
+NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
+simple_command() function, should also use this flag if it wants (in case
+of the --print-annotate-rows-events option set) to recieve Annotate_rows
+events.
+
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,8 +217,7 @@
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
- flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT ||
- thd->server_id == 0 /* slave == mysqlbinlog */ )
+ flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
-=-=(Alexi - Sun, 20 Dec 2009, 13:14)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.11350 2009-12-20 13:14:04.000000000 +0200
+++ /tmp/wklog.47.new.11350 2009-12-20 13:14:04.000000000 +0200
@@ -282,23 +282,18 @@
Annotate_rows_log_event* m_annotate_event;
};
-When the saved Annotate_rows object may be deleted? When all corresponding
-Rows events will be processed, i.e. before processing the first non-Rows
-event (note that Annotate_rows object resides in the binary log *after*
-the (possible) 'BEGIN' Query event which accompanies the rows events; note
-also that this deletion is adjusted with the case when some or all
-corresponding Rows events are filtered out by replicate filter rules):
+The saved Annotate_rows object should be deleted when all corresponding
+Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
- if (rli->get_annotate_event() && !IS_RBR_EVENT_TYPE(ev->get_type_code()))
- rli->free_annotate_event();
-
apply_event_and_update_pos(ev, ...);
- if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
+ if (rli->get_annotate_event() && is_last_rows_event(ev))
+ rli->free_annotate_event();
+ else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
@@ -307,10 +302,21 @@
where
- #define IS_RBR_EVENT_TYPE(type) ( (type) == TABLE_MAP_EVENT || \
- (type) == WRITE_ROWS_EVENT || \
+ bool is_last_rows_event(Log_event* ev)
+ {
+ Log_event_type type= ev->get_type_code();
+ if (IS_ROWS_EVENT_TYPE(type))
+ {
+ Rows_log_event* rows= (Rows_log_event*)ev;
+ return rows->get_flags(Rows_log_event::STMT_END_F);
+ }
+
+ return 0;
+ }
+
+ #define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
- (type) == DELETE_ROWS_EVENT )
+ (type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
------------------------------------------------------------
-=-=(View All Progress Notes, 27 total)=-=-
http://askmonty.org/worklog/index.pl?tid=47&nolimit=1
DESCRIPTION:
Store in binlog (and show in mysqlbinlog output) texts of statements that
caused RBR events
This is needed for (list from Monty):
- Easier to understand why updates happened
- Would make it easier to find out where in application things went
wrong (as you can search for exact strings)
- Allow one to filter things based on comments in the statement.
The cost of this can be that the binlog will be approximately 2x in size
(especially insert of big blob's would be a bit painful), so this should
be an optional feature.
HIGH-LEVEL SPECIFICATION:
Content
~~~~~~~
1. Annotate_rows_log_event
2. Server option: --binlog-annotate-rows-events
3. Server option: --replicate-annotate-rows-events
4. mysqlbinlog option: --print-annotate-rows-events
5. mysqlbinlog output
1. Annotate_rows_log_event [ ANNOTATE_ROWS_EVENT ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Describes the query which caused the corresponding rows events. Has empty
post-header and contains the query text in its data part. Example:
************************
ANNOTATE_ROWS_EVENT
************************
00000220 | B6 A0 2C 4B | time_when = 1261215926
00000224 | 33 | event_type = 51
00000225 | 64 00 00 00 | server_id = 100
00000229 | 36 00 00 00 | event_len = 54
0000022D | 56 02 00 00 | log_pos = 00000256
00000231 | 00 00 | flags = <none>
------------------------
00000233 | 49 4E 53 45 | query = "INSERT INTO t1 VALUES (1), (2), (3)"
00000237 | 52 54 20 49 |
0000023B | 4E 54 4F 20 |
0000023F | 74 31 20 56 |
00000243 | 41 4C 55 45 |
00000247 | 53 20 28 31 |
0000024B | 29 2C 20 28 |
0000024F | 32 29 2C 20 |
00000253 | 28 33 29 |
************************
In binary log, Annotate_rows event follows the (possible) 'BEGIN' Query event
and precedes the first of Table map events which accompany the corresponding
rows events. (See example in the "mysqlbinlog output" section below.)
2. Server option: --binlog-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the master to write Annotate_rows events to the binary log.
* Variable Name: binlog_annotate_rows_events
* Scope: Global & Session
* Access Type: Dynamic
* Data Type: bool
* Default Value: OFF
NOTE. Session values allows to annotate only some selected statements:
...
SET SESSION binlog_annotate_rows_events=ON;
... statements to be annotated ...
SET SESSION binlog_annotate_rows_events=OFF;
... statements not to be annotated ...
3. Server option: --replicate-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the slave to reproduce Annotate_rows events recieved from the master
in its own binary log (sensible only in pair with log-slave-updates option).
* Variable Name: replicate_annotate_rows_events
* Scope: Global
* Access Type: Read only
* Data Type: bool
* Default Value: OFF
NOTE. Why do we additionally need this 'replicate' option? Why not to make
the slave to reproduce this events when its binlog-annotate-rows-events
global value is ON? Well, because, for example, we may want to configure
the slave which should reproduce Annotate_rows events but has global
binlog-annotate-rows-events = OFF meaning this to be the default value for
the client threads (see also "How slave treats replicate-annotate-rows-events
option" in LLD part).
4. mysqlbinlog option: --print-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With this option, mysqlbinlog prints the content of Annotate_rows events (if
the binary log does contain them). Without this option (i.e. by default),
mysqlbinlog skips Annotate_rows events.
5. mysqlbinlog output
~~~~~~~~~~~~~~~~~~~~~
With --print-annotate-rows-events, mysqlbinlog outputs Annotate_rows events
in a form like this:
...
# at 1646
#091219 12:45:26 server id 100 end_log_pos 1714 Query thread_id=1
exec_time=0 error_code=0
SET TIMESTAMP=1261215926/*!*/;
BEGIN
/*!*/;
# at 1714
# at 1812
# at 1853
# at 1894
# at 1938
#091219 12:45:26 server id 100 end_log_pos 1812 Query: `DELETE t1, t2 FROM
t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a`
#091219 12:45:26 server id 100 end_log_pos 1853 Table_map: `test`.`t1`
mapped to number 16
#091219 12:45:26 server id 100 end_log_pos 1894 Table_map: `test`.`t2`
mapped to number 17
#091219 12:45:26 server id 100 end_log_pos 1938 Delete_rows: table id 16
#091219 12:45:26 server id 100 end_log_pos 1982 Delete_rows: table id 17
flags: STMT_END_F
...
LOW-LEVEL DESIGN:
Content
~~~~~~~
1. Annotate_rows event number
2. Outline of Annotate_rows event behavior
3. How Master writes Annotate_rows events to the binary log
4. How slave treats replicate-annotate-rows-events option
5. How slave IO thread requests Annotate_rows events
6. How master executes the request
7. How slave SQL thread processes Annotate_rows events
8. General remarks
1. Annotate_rows event number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid possible event numbers conflict with MySQL/Sun, we leave a gap
between the last MySQL event number and the Annotate_rows event number:
enum Log_event_type
{ ...
INCIDENT_EVENT= 26,
// New MySQL event numbers are to be added here
MYSQL_EVENTS_END,
MARIA_EVENTS_BEGIN= 51,
// New Maria event numbers start from here
ANNOTATE_ROWS_EVENT= 51,
ENUM_END_EVENT
};
together with the corresponding extension of 'post_header_len' array in the
Format description event. (This extension does not affect the compatibility
of the binary log). Here is how Format description event looks like with
this extension:
************************
FORMAT_DESCRIPTION_EVENT
************************
00000004 | A1 A0 2C 4B | time_when = 1261215905
00000008 | 0F | event_type = 15
00000009 | 64 00 00 00 | server_id = 100
0000000D | 7F 00 00 00 | event_len = 127
00000011 | 83 00 00 00 | log_pos = 00000083
00000015 | 01 00 | flags = LOG_EVENT_BINLOG_IN_USE_F
------------------------
00000017 | 04 00 | binlog_ver = 4
00000019 | 35 2E 32 2E | server_ver = 5.2.0-MariaDB-alpha-debug-log
..... ...
0000004B | A1 A0 2C 4B | time_created = 1261215905
0000004F | 13 | common_header_len = 19
------------------------
post_header_len
------------------------
00000050 | 38 | 56 - START_EVENT_V3 [1]
..... ...
00000069 | 02 | 2 - INCIDENT_EVENT [26]
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each Annotate_rows_log_event object has two private members describing the
corresponding query:
char *m_query_txt;
uint m_query_len;
When the object is created for writing to a binary log, this query is taken
from 'thd' (for short, below we omit the 'Annotate_rows_log_event::' prefix
as well as other implementation details):
Annotate_rows_log_event(THD *thd)
{
m_query_txt = thd->query();
m_query_len = thd->query_length();
}
When the object is read from a binary log, the query is taken from the buffer
containing the binary log representation of the event (this buffer is allocated
in Log_event object from which all Log events are derived):
Annotate_rows_log_event(char *buf, uint event_len,
Format_description_log_event *desc)
{
m_query_len = event_len - desc->common_header_len;
m_query_txt = buf + desc->common_header_len;
}
The events are written to the binary log by the Log_event::write() member
which calls virtual write_data_header() and write_data_body() members
("data header" and "post header" are synonym in replication terminology).
In our case, data header is empty and data body is just the query:
bool write_data_body(IO_CACHE *file)
{
return my_b_safe_write(file, (uchar*) m_query_txt, m_query_len);
}
Printing the event is just printing the query:
void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
{
my_b_printf(&pinfo->head_cache, "\tQuery: `%s`\n", m_query_txt);
}
3. How Master writes Annotate_rows events to the binary log
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The event is written to the binary log just before the group of Table_map
events which precede corresponding Rows events (one query may generate
several Table map events in the binary log, but the corresponding
Annotate_rows event must be written only once before the first Table map
event; hence the boolean variable 'with_annotate' below):
int write_locked_table_maps(THD *thd)
{ ...
bool with_annotate= thd->variables.binlog_annotate_rows_events;
...
for (uint i= 0; i < ... <number of tables> ...; ++i)
{ ...
thd->binlog_write_table_map(table, ..., with_annotate);
with_annotate= 0; // write Annotate_event not more than once
...
}
...
}
int THD::binlog_write_table_map(TABLE *table, ..., bool with_annotate)
{ ...
Table_map_log_event the_event(...);
...
if (with_annotate)
{
Annotate_rows_log_event anno(this);
mysql_bin_log.write(&anno);
}
mysql_bin_log.write(&the_event);
...
}
4. How slave treats replicate-annotate-rows-events option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The replicate-annotate-rows-events option is treated just as the session
value of the binlog_annotate_rows_events variable for the slave IO and
SQL threads. This setting is done during initialization of these threads:
pthread_handler_t handle_slave_io(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_IO);
...
}
pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_SQL);
...
}
int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{ ...
thd->variables.binlog_annotate_rows_events=
opt_replicate_annotate_rows_events;
...
}
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the replicate-annotate-rows-events option is not set on a slave, there
is no need for master to send Annotate_rows events to this slave. The slave
(or mysqlbinlog in remote case), before requesting binlog dump via the
COM_BINLOG_DUMP command, informs the master whether it should send these
events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
command:
case COM_BINLOG_DUMP_OPTIONS_EXT:
thd->binlog_dump_flags_ext= packet[0];
my_ok(thd);
break;
Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
case COM_BINLOG_DUMP:
{ ...
flags= uint2korr(packet + 4);
...
mysql_binlog_send(thd, ..., flags);
...
}
void mysql_binlog_send(THD* thd, ..., ushort flags)
{ ...
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
...
}
7. How slave SQL thread processes Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slave processes each recieved event by "applying" it, i.e. by
calling the Log_event::apply_event() function which in turn calls
the virtual do_apply_event() member specific for each type of the
event.
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev = next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
int apply_event_and_update_pos(Log_event *ev, ...)
{ ...
ev->apply_event(...);
...
}
int Log_event::apply_event(...)
{
return do_apply_event(...);
}
What does it mean to "apply" an Annotate_rows event? It means to set current
thd query to that of the described by the event, i.e. to the query which
caused the subsequent Rows events (see "How Master writes Annotate_rows
events to the binary log" to follow what happens further when the subsequent
Rows events are applied):
int Annotate_rows_log_event::do_apply_event(...)
{
thd->set_query(m_query_txt, m_query_len);
}
NOTE. I am not sure, but possibly current values of thd->query and
thd->query_length should be saved before calling set_query() and to be
restored on the Annotate_rows_log_event object deletion.
Is it really needed ?
After calling this do_apply_event() function we may not delete the
Annotate_rows_log_event object immediatedly (see exec_relay_log_event()
above) because thd->query now points to the string inside this object.
We may keep the pointer to this object in the Relay_log_info:
class Relay_log_info
{
public:
...
void set_annotate_event(Annotate_rows_log_event*);
Annotate_rows_log_event* get_annotate_event();
void free_annotate_event();
...
private:
Annotate_rows_log_event* m_annotate_event;
};
The saved Annotate_rows object should be deleted when all corresponding
Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (rli->get_annotate_event() && is_last_rows_event(ev))
rli->free_annotate_event();
else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
where
bool is_last_rows_event(Log_event* ev)
{
Log_event_type type= ev->get_type_code();
if (IS_ROWS_EVENT_TYPE(type))
{
Rows_log_event* rows= (Rows_log_event*)ev;
return rows->get_flags(Rows_log_event::STMT_END_F);
}
return 0;
}
#define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
(type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
Kristian noticed that introducing new log event type should be coordinated
somehow with MySQL/Sun:
Kristian: The numeric code for this event must be assigned carefully.
It should be coordinated with MySQL/Sun, otherwise we can get into a
situation where MySQL uses the same numeric code for one event that
MariaDB uses for ANNOTATE_ROWS_EVENT, which would make merging the two
impossible.
Alex: I reserved about 20 numbers not to have possible conflicts
with MySQL.
Kristian: Still, I think it would be appropriate to send a polite email
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Progress (by Knielsen): Store in binlog text of statements that caused RBR events (47)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Store in binlog text of statements that caused RBR events
CREATION DATE..: Sat, 15 Aug 2009, 23:48
SUPERVISOR.....: Monty
IMPLEMENTOR....:
COPIES TO......: Knielsen, Serg
CATEGORY.......: Server-Sprint
TASK ID........: 47 (http://askmonty.org/worklog/?tid=47)
VERSION........: Server-9.x
STATUS.........: In-Progress
PRIORITY.......: 60
WORKED HOURS...: 47
ESTIMATE.......: 8 (hours remain)
ORIG. ESTIMATE.: 35
PROGRESS NOTES:
-=-=(Knielsen - Tue, 06 Apr 2010, 15:26)=-=-
Code review (mailed to maria-developers@).
Worked 7 hours and estimate 8 hours remain (original estimate unchanged).
-=-=(Knielsen - Tue, 06 Apr 2010, 15:25)=-=-
Status updated.
--- /tmp/wklog.47.old.12734 2010-04-06 15:25:54.000000000 +0000
+++ /tmp/wklog.47.new.12734 2010-04-06 15:25:54.000000000 +0000
@@ -1 +1 @@
-Code-Review
+In-Progress
-=-=(Knielsen - Mon, 29 Mar 2010, 10:59)=-=-
Status updated.
--- /tmp/wklog.47.old.27790 2010-03-29 10:59:53.000000000 +0000
+++ /tmp/wklog.47.new.27790 2010-03-29 10:59:53.000000000 +0000
@@ -1 +1 @@
-In-Progress
+Code-Review
-=-=(Alexi - Thu, 18 Feb 2010, 19:29)=-=-
Worked 20 hours (alexi)
Worked 20 hours and estimate 15 hours remain (original estimate unchanged).
-=-=(Serg - Fri, 05 Feb 2010, 14:04)=-=-
Observers changed: Knielsen,Serg
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Category updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Server-RawIdeaBin
+Server-Sprint
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Status updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Un-Assigned
+In-Progress
-=-=(Alexi - Thu, 04 Feb 2010, 09:54)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.16174 2010-02-04 09:54:13.000000000 +0200
+++ /tmp/wklog.47.new.16174 2010-02-04 09:54:13.000000000 +0200
@@ -171,35 +171,20 @@
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When requesting an event, the slave should inform the master whether
-it should send Annotate_rows events or not. To that end we add a new
-BINLOG_SEND_ANNOTATE_ROWS_EVENT flag used when requesting an event:
+If the replicate-annotate-rows-events option is not set on a slave, there
+is no need for master to send Annotate_rows events to this slave. The slave
+(or mysqlbinlog in remote case), before requesting binlog dump via the
+COM_BINLOG_DUMP command, informs the master whether it should send these
+events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
+command:
+
+ case COM_BINLOG_DUMP_OPTIONS_EXT:
+ thd->binlog_dump_flags_ext= packet[0];
+ my_ok(thd);
+ break;
- #define BINLOG_DUMP_NON_BLOCK 1
- #define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2
-
- pthread_handler_t handle_slave_io(void *arg)
- { ...
- request_dump(mysql, ...);
- ...
- }
-
- int request_dump(MYSQL* mysql, ...)
- { ...
- if (opt_log_slave_updates &&
- mi->io_thd->variables.binlog_annotate_rows_events)
- binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
- ...
- int2store(buf + 4, binlog_flags);
- ...
- simple_command(mysql, COM_BINLOG_DUMP, buf, ...);
- ...
- }
-
-NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
-simple_command() function, should also use this flag if it wants (in case
-of the --print-annotate-rows-events option set) to recieve Annotate_rows
-events.
+Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
+conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -338,10 +323,4 @@
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
-Also we should notice the introduction of the BINLOG_SEND_ANNOTATE_ROWS_EVENT
-flag taking into account that MySQL/Sun may also introduce a flag with the
-same value to be used in the request_dump-mysql_binlog_send interface.
-But this is mainly the question of merging: if a conflict concerning this
-flag occur, we may simply change the BINLOG_SEND_ANNOTATE_ROWS_EVENT value
-(this does not require additional changes in the code).
-=-=(Alexi - Sun, 20 Dec 2009, 16:00)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.19667 2009-12-20 14:00:56.000000000 +0000
+++ /tmp/wklog.47.new.19667 2009-12-20 14:00:56.000000000 +0000
@@ -196,6 +196,11 @@
...
}
+NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
+simple_command() function, should also use this flag if it wants (in case
+of the --print-annotate-rows-events option set) to recieve Annotate_rows
+events.
+
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,8 +217,7 @@
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
- flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT ||
- thd->server_id == 0 /* slave == mysqlbinlog */ )
+ flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
-=-=(Alexi - Sun, 20 Dec 2009, 13:14)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.11350 2009-12-20 13:14:04.000000000 +0200
+++ /tmp/wklog.47.new.11350 2009-12-20 13:14:04.000000000 +0200
@@ -282,23 +282,18 @@
Annotate_rows_log_event* m_annotate_event;
};
-When the saved Annotate_rows object may be deleted? When all corresponding
-Rows events will be processed, i.e. before processing the first non-Rows
-event (note that Annotate_rows object resides in the binary log *after*
-the (possible) 'BEGIN' Query event which accompanies the rows events; note
-also that this deletion is adjusted with the case when some or all
-corresponding Rows events are filtered out by replicate filter rules):
+The saved Annotate_rows object should be deleted when all corresponding
+Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
- if (rli->get_annotate_event() && !IS_RBR_EVENT_TYPE(ev->get_type_code()))
- rli->free_annotate_event();
-
apply_event_and_update_pos(ev, ...);
- if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
+ if (rli->get_annotate_event() && is_last_rows_event(ev))
+ rli->free_annotate_event();
+ else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
@@ -307,10 +302,21 @@
where
- #define IS_RBR_EVENT_TYPE(type) ( (type) == TABLE_MAP_EVENT || \
- (type) == WRITE_ROWS_EVENT || \
+ bool is_last_rows_event(Log_event* ev)
+ {
+ Log_event_type type= ev->get_type_code();
+ if (IS_ROWS_EVENT_TYPE(type))
+ {
+ Rows_log_event* rows= (Rows_log_event*)ev;
+ return rows->get_flags(Rows_log_event::STMT_END_F);
+ }
+
+ return 0;
+ }
+
+ #define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
- (type) == DELETE_ROWS_EVENT )
+ (type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
------------------------------------------------------------
-=-=(View All Progress Notes, 27 total)=-=-
http://askmonty.org/worklog/index.pl?tid=47&nolimit=1
DESCRIPTION:
Store in binlog (and show in mysqlbinlog output) texts of statements that
caused RBR events
This is needed for (list from Monty):
- Easier to understand why updates happened
- Would make it easier to find out where in application things went
wrong (as you can search for exact strings)
- Allow one to filter things based on comments in the statement.
The cost of this can be that the binlog will be approximately 2x in size
(especially insert of big blob's would be a bit painful), so this should
be an optional feature.
HIGH-LEVEL SPECIFICATION:
Content
~~~~~~~
1. Annotate_rows_log_event
2. Server option: --binlog-annotate-rows-events
3. Server option: --replicate-annotate-rows-events
4. mysqlbinlog option: --print-annotate-rows-events
5. mysqlbinlog output
1. Annotate_rows_log_event [ ANNOTATE_ROWS_EVENT ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Describes the query which caused the corresponding rows events. Has empty
post-header and contains the query text in its data part. Example:
************************
ANNOTATE_ROWS_EVENT
************************
00000220 | B6 A0 2C 4B | time_when = 1261215926
00000224 | 33 | event_type = 51
00000225 | 64 00 00 00 | server_id = 100
00000229 | 36 00 00 00 | event_len = 54
0000022D | 56 02 00 00 | log_pos = 00000256
00000231 | 00 00 | flags = <none>
------------------------
00000233 | 49 4E 53 45 | query = "INSERT INTO t1 VALUES (1), (2), (3)"
00000237 | 52 54 20 49 |
0000023B | 4E 54 4F 20 |
0000023F | 74 31 20 56 |
00000243 | 41 4C 55 45 |
00000247 | 53 20 28 31 |
0000024B | 29 2C 20 28 |
0000024F | 32 29 2C 20 |
00000253 | 28 33 29 |
************************
In binary log, Annotate_rows event follows the (possible) 'BEGIN' Query event
and precedes the first of Table map events which accompany the corresponding
rows events. (See example in the "mysqlbinlog output" section below.)
2. Server option: --binlog-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the master to write Annotate_rows events to the binary log.
* Variable Name: binlog_annotate_rows_events
* Scope: Global & Session
* Access Type: Dynamic
* Data Type: bool
* Default Value: OFF
NOTE. Session values allows to annotate only some selected statements:
...
SET SESSION binlog_annotate_rows_events=ON;
... statements to be annotated ...
SET SESSION binlog_annotate_rows_events=OFF;
... statements not to be annotated ...
3. Server option: --replicate-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the slave to reproduce Annotate_rows events recieved from the master
in its own binary log (sensible only in pair with log-slave-updates option).
* Variable Name: replicate_annotate_rows_events
* Scope: Global
* Access Type: Read only
* Data Type: bool
* Default Value: OFF
NOTE. Why do we additionally need this 'replicate' option? Why not to make
the slave to reproduce this events when its binlog-annotate-rows-events
global value is ON? Well, because, for example, we may want to configure
the slave which should reproduce Annotate_rows events but has global
binlog-annotate-rows-events = OFF meaning this to be the default value for
the client threads (see also "How slave treats replicate-annotate-rows-events
option" in LLD part).
4. mysqlbinlog option: --print-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With this option, mysqlbinlog prints the content of Annotate_rows events (if
the binary log does contain them). Without this option (i.e. by default),
mysqlbinlog skips Annotate_rows events.
5. mysqlbinlog output
~~~~~~~~~~~~~~~~~~~~~
With --print-annotate-rows-events, mysqlbinlog outputs Annotate_rows events
in a form like this:
...
# at 1646
#091219 12:45:26 server id 100 end_log_pos 1714 Query thread_id=1
exec_time=0 error_code=0
SET TIMESTAMP=1261215926/*!*/;
BEGIN
/*!*/;
# at 1714
# at 1812
# at 1853
# at 1894
# at 1938
#091219 12:45:26 server id 100 end_log_pos 1812 Query: `DELETE t1, t2 FROM
t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a`
#091219 12:45:26 server id 100 end_log_pos 1853 Table_map: `test`.`t1`
mapped to number 16
#091219 12:45:26 server id 100 end_log_pos 1894 Table_map: `test`.`t2`
mapped to number 17
#091219 12:45:26 server id 100 end_log_pos 1938 Delete_rows: table id 16
#091219 12:45:26 server id 100 end_log_pos 1982 Delete_rows: table id 17
flags: STMT_END_F
...
LOW-LEVEL DESIGN:
Content
~~~~~~~
1. Annotate_rows event number
2. Outline of Annotate_rows event behavior
3. How Master writes Annotate_rows events to the binary log
4. How slave treats replicate-annotate-rows-events option
5. How slave IO thread requests Annotate_rows events
6. How master executes the request
7. How slave SQL thread processes Annotate_rows events
8. General remarks
1. Annotate_rows event number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid possible event numbers conflict with MySQL/Sun, we leave a gap
between the last MySQL event number and the Annotate_rows event number:
enum Log_event_type
{ ...
INCIDENT_EVENT= 26,
// New MySQL event numbers are to be added here
MYSQL_EVENTS_END,
MARIA_EVENTS_BEGIN= 51,
// New Maria event numbers start from here
ANNOTATE_ROWS_EVENT= 51,
ENUM_END_EVENT
};
together with the corresponding extension of 'post_header_len' array in the
Format description event. (This extension does not affect the compatibility
of the binary log). Here is how Format description event looks like with
this extension:
************************
FORMAT_DESCRIPTION_EVENT
************************
00000004 | A1 A0 2C 4B | time_when = 1261215905
00000008 | 0F | event_type = 15
00000009 | 64 00 00 00 | server_id = 100
0000000D | 7F 00 00 00 | event_len = 127
00000011 | 83 00 00 00 | log_pos = 00000083
00000015 | 01 00 | flags = LOG_EVENT_BINLOG_IN_USE_F
------------------------
00000017 | 04 00 | binlog_ver = 4
00000019 | 35 2E 32 2E | server_ver = 5.2.0-MariaDB-alpha-debug-log
..... ...
0000004B | A1 A0 2C 4B | time_created = 1261215905
0000004F | 13 | common_header_len = 19
------------------------
post_header_len
------------------------
00000050 | 38 | 56 - START_EVENT_V3 [1]
..... ...
00000069 | 02 | 2 - INCIDENT_EVENT [26]
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each Annotate_rows_log_event object has two private members describing the
corresponding query:
char *m_query_txt;
uint m_query_len;
When the object is created for writing to a binary log, this query is taken
from 'thd' (for short, below we omit the 'Annotate_rows_log_event::' prefix
as well as other implementation details):
Annotate_rows_log_event(THD *thd)
{
m_query_txt = thd->query();
m_query_len = thd->query_length();
}
When the object is read from a binary log, the query is taken from the buffer
containing the binary log representation of the event (this buffer is allocated
in Log_event object from which all Log events are derived):
Annotate_rows_log_event(char *buf, uint event_len,
Format_description_log_event *desc)
{
m_query_len = event_len - desc->common_header_len;
m_query_txt = buf + desc->common_header_len;
}
The events are written to the binary log by the Log_event::write() member
which calls virtual write_data_header() and write_data_body() members
("data header" and "post header" are synonym in replication terminology).
In our case, data header is empty and data body is just the query:
bool write_data_body(IO_CACHE *file)
{
return my_b_safe_write(file, (uchar*) m_query_txt, m_query_len);
}
Printing the event is just printing the query:
void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
{
my_b_printf(&pinfo->head_cache, "\tQuery: `%s`\n", m_query_txt);
}
3. How Master writes Annotate_rows events to the binary log
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The event is written to the binary log just before the group of Table_map
events which precede corresponding Rows events (one query may generate
several Table map events in the binary log, but the corresponding
Annotate_rows event must be written only once before the first Table map
event; hence the boolean variable 'with_annotate' below):
int write_locked_table_maps(THD *thd)
{ ...
bool with_annotate= thd->variables.binlog_annotate_rows_events;
...
for (uint i= 0; i < ... <number of tables> ...; ++i)
{ ...
thd->binlog_write_table_map(table, ..., with_annotate);
with_annotate= 0; // write Annotate_event not more than once
...
}
...
}
int THD::binlog_write_table_map(TABLE *table, ..., bool with_annotate)
{ ...
Table_map_log_event the_event(...);
...
if (with_annotate)
{
Annotate_rows_log_event anno(this);
mysql_bin_log.write(&anno);
}
mysql_bin_log.write(&the_event);
...
}
4. How slave treats replicate-annotate-rows-events option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The replicate-annotate-rows-events option is treated just as the session
value of the binlog_annotate_rows_events variable for the slave IO and
SQL threads. This setting is done during initialization of these threads:
pthread_handler_t handle_slave_io(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_IO);
...
}
pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_SQL);
...
}
int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{ ...
thd->variables.binlog_annotate_rows_events=
opt_replicate_annotate_rows_events;
...
}
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the replicate-annotate-rows-events option is not set on a slave, there
is no need for master to send Annotate_rows events to this slave. The slave
(or mysqlbinlog in remote case), before requesting binlog dump via the
COM_BINLOG_DUMP command, informs the master whether it should send these
events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
command:
case COM_BINLOG_DUMP_OPTIONS_EXT:
thd->binlog_dump_flags_ext= packet[0];
my_ok(thd);
break;
Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
case COM_BINLOG_DUMP:
{ ...
flags= uint2korr(packet + 4);
...
mysql_binlog_send(thd, ..., flags);
...
}
void mysql_binlog_send(THD* thd, ..., ushort flags)
{ ...
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
...
}
7. How slave SQL thread processes Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slave processes each recieved event by "applying" it, i.e. by
calling the Log_event::apply_event() function which in turn calls
the virtual do_apply_event() member specific for each type of the
event.
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev = next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
int apply_event_and_update_pos(Log_event *ev, ...)
{ ...
ev->apply_event(...);
...
}
int Log_event::apply_event(...)
{
return do_apply_event(...);
}
What does it mean to "apply" an Annotate_rows event? It means to set current
thd query to that of the described by the event, i.e. to the query which
caused the subsequent Rows events (see "How Master writes Annotate_rows
events to the binary log" to follow what happens further when the subsequent
Rows events are applied):
int Annotate_rows_log_event::do_apply_event(...)
{
thd->set_query(m_query_txt, m_query_len);
}
NOTE. I am not sure, but possibly current values of thd->query and
thd->query_length should be saved before calling set_query() and to be
restored on the Annotate_rows_log_event object deletion.
Is it really needed ?
After calling this do_apply_event() function we may not delete the
Annotate_rows_log_event object immediatedly (see exec_relay_log_event()
above) because thd->query now points to the string inside this object.
We may keep the pointer to this object in the Relay_log_info:
class Relay_log_info
{
public:
...
void set_annotate_event(Annotate_rows_log_event*);
Annotate_rows_log_event* get_annotate_event();
void free_annotate_event();
...
private:
Annotate_rows_log_event* m_annotate_event;
};
The saved Annotate_rows object should be deleted when all corresponding
Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (rli->get_annotate_event() && is_last_rows_event(ev))
rli->free_annotate_event();
else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
where
bool is_last_rows_event(Log_event* ev)
{
Log_event_type type= ev->get_type_code();
if (IS_ROWS_EVENT_TYPE(type))
{
Rows_log_event* rows= (Rows_log_event*)ev;
return rows->get_flags(Rows_log_event::STMT_END_F);
}
return 0;
}
#define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
(type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
Kristian noticed that introducing new log event type should be coordinated
somehow with MySQL/Sun:
Kristian: The numeric code for this event must be assigned carefully.
It should be coordinated with MySQL/Sun, otherwise we can get into a
situation where MySQL uses the same numeric code for one event that
MariaDB uses for ANNOTATE_ROWS_EVENT, which would make merging the two
impossible.
Alex: I reserved about 20 numbers not to have possible conflicts
with MySQL.
Kristian: Still, I think it would be appropriate to send a polite email
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Updated (by Knielsen): Store in binlog text of statements that caused RBR events (47)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Store in binlog text of statements that caused RBR events
CREATION DATE..: Sat, 15 Aug 2009, 23:48
SUPERVISOR.....: Monty
IMPLEMENTOR....:
COPIES TO......: Knielsen, Serg
CATEGORY.......: Server-Sprint
TASK ID........: 47 (http://askmonty.org/worklog/?tid=47)
VERSION........: Server-9.x
STATUS.........: In-Progress
PRIORITY.......: 60
WORKED HOURS...: 40
ESTIMATE.......: 15 (hours remain)
ORIG. ESTIMATE.: 35
PROGRESS NOTES:
-=-=(Knielsen - Tue, 06 Apr 2010, 15:25)=-=-
Status updated.
--- /tmp/wklog.47.old.12734 2010-04-06 15:25:54.000000000 +0000
+++ /tmp/wklog.47.new.12734 2010-04-06 15:25:54.000000000 +0000
@@ -1 +1 @@
-Code-Review
+In-Progress
-=-=(Knielsen - Mon, 29 Mar 2010, 10:59)=-=-
Status updated.
--- /tmp/wklog.47.old.27790 2010-03-29 10:59:53.000000000 +0000
+++ /tmp/wklog.47.new.27790 2010-03-29 10:59:53.000000000 +0000
@@ -1 +1 @@
-In-Progress
+Code-Review
-=-=(Alexi - Thu, 18 Feb 2010, 19:29)=-=-
Worked 20 hours (alexi)
Worked 20 hours and estimate 15 hours remain (original estimate unchanged).
-=-=(Serg - Fri, 05 Feb 2010, 14:04)=-=-
Observers changed: Knielsen,Serg
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Category updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Server-RawIdeaBin
+Server-Sprint
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Status updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Un-Assigned
+In-Progress
-=-=(Alexi - Thu, 04 Feb 2010, 09:54)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.16174 2010-02-04 09:54:13.000000000 +0200
+++ /tmp/wklog.47.new.16174 2010-02-04 09:54:13.000000000 +0200
@@ -171,35 +171,20 @@
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When requesting an event, the slave should inform the master whether
-it should send Annotate_rows events or not. To that end we add a new
-BINLOG_SEND_ANNOTATE_ROWS_EVENT flag used when requesting an event:
+If the replicate-annotate-rows-events option is not set on a slave, there
+is no need for master to send Annotate_rows events to this slave. The slave
+(or mysqlbinlog in remote case), before requesting binlog dump via the
+COM_BINLOG_DUMP command, informs the master whether it should send these
+events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
+command:
+
+ case COM_BINLOG_DUMP_OPTIONS_EXT:
+ thd->binlog_dump_flags_ext= packet[0];
+ my_ok(thd);
+ break;
- #define BINLOG_DUMP_NON_BLOCK 1
- #define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2
-
- pthread_handler_t handle_slave_io(void *arg)
- { ...
- request_dump(mysql, ...);
- ...
- }
-
- int request_dump(MYSQL* mysql, ...)
- { ...
- if (opt_log_slave_updates &&
- mi->io_thd->variables.binlog_annotate_rows_events)
- binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
- ...
- int2store(buf + 4, binlog_flags);
- ...
- simple_command(mysql, COM_BINLOG_DUMP, buf, ...);
- ...
- }
-
-NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
-simple_command() function, should also use this flag if it wants (in case
-of the --print-annotate-rows-events option set) to recieve Annotate_rows
-events.
+Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
+conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -338,10 +323,4 @@
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
-Also we should notice the introduction of the BINLOG_SEND_ANNOTATE_ROWS_EVENT
-flag taking into account that MySQL/Sun may also introduce a flag with the
-same value to be used in the request_dump-mysql_binlog_send interface.
-But this is mainly the question of merging: if a conflict concerning this
-flag occur, we may simply change the BINLOG_SEND_ANNOTATE_ROWS_EVENT value
-(this does not require additional changes in the code).
-=-=(Alexi - Sun, 20 Dec 2009, 16:00)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.19667 2009-12-20 14:00:56.000000000 +0000
+++ /tmp/wklog.47.new.19667 2009-12-20 14:00:56.000000000 +0000
@@ -196,6 +196,11 @@
...
}
+NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
+simple_command() function, should also use this flag if it wants (in case
+of the --print-annotate-rows-events option set) to recieve Annotate_rows
+events.
+
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,8 +217,7 @@
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
- flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT ||
- thd->server_id == 0 /* slave == mysqlbinlog */ )
+ flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
-=-=(Alexi - Sun, 20 Dec 2009, 13:14)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.11350 2009-12-20 13:14:04.000000000 +0200
+++ /tmp/wklog.47.new.11350 2009-12-20 13:14:04.000000000 +0200
@@ -282,23 +282,18 @@
Annotate_rows_log_event* m_annotate_event;
};
-When the saved Annotate_rows object may be deleted? When all corresponding
-Rows events will be processed, i.e. before processing the first non-Rows
-event (note that Annotate_rows object resides in the binary log *after*
-the (possible) 'BEGIN' Query event which accompanies the rows events; note
-also that this deletion is adjusted with the case when some or all
-corresponding Rows events are filtered out by replicate filter rules):
+The saved Annotate_rows object should be deleted when all corresponding
+Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
- if (rli->get_annotate_event() && !IS_RBR_EVENT_TYPE(ev->get_type_code()))
- rli->free_annotate_event();
-
apply_event_and_update_pos(ev, ...);
- if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
+ if (rli->get_annotate_event() && is_last_rows_event(ev))
+ rli->free_annotate_event();
+ else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
@@ -307,10 +302,21 @@
where
- #define IS_RBR_EVENT_TYPE(type) ( (type) == TABLE_MAP_EVENT || \
- (type) == WRITE_ROWS_EVENT || \
+ bool is_last_rows_event(Log_event* ev)
+ {
+ Log_event_type type= ev->get_type_code();
+ if (IS_ROWS_EVENT_TYPE(type))
+ {
+ Rows_log_event* rows= (Rows_log_event*)ev;
+ return rows->get_flags(Rows_log_event::STMT_END_F);
+ }
+
+ return 0;
+ }
+
+ #define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
- (type) == DELETE_ROWS_EVENT )
+ (type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
-=-=(Alexi - Sun, 20 Dec 2009, 09:29)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.32726 2009-12-20 07:29:56.000000000 +0000
+++ /tmp/wklog.47.new.32726 2009-12-20 07:29:56.000000000 +0000
@@ -56,7 +56,7 @@
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
- 00000082 | 00 | 0 - ANNOTATE_RBR_EVENT [51]
+ 00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
------------------------------------------------------------
-=-=(View All Progress Notes, 26 total)=-=-
http://askmonty.org/worklog/index.pl?tid=47&nolimit=1
DESCRIPTION:
Store in binlog (and show in mysqlbinlog output) texts of statements that
caused RBR events
This is needed for (list from Monty):
- Easier to understand why updates happened
- Would make it easier to find out where in application things went
wrong (as you can search for exact strings)
- Allow one to filter things based on comments in the statement.
The cost of this can be that the binlog will be approximately 2x in size
(especially insert of big blob's would be a bit painful), so this should
be an optional feature.
HIGH-LEVEL SPECIFICATION:
Content
~~~~~~~
1. Annotate_rows_log_event
2. Server option: --binlog-annotate-rows-events
3. Server option: --replicate-annotate-rows-events
4. mysqlbinlog option: --print-annotate-rows-events
5. mysqlbinlog output
1. Annotate_rows_log_event [ ANNOTATE_ROWS_EVENT ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Describes the query which caused the corresponding rows events. Has empty
post-header and contains the query text in its data part. Example:
************************
ANNOTATE_ROWS_EVENT
************************
00000220 | B6 A0 2C 4B | time_when = 1261215926
00000224 | 33 | event_type = 51
00000225 | 64 00 00 00 | server_id = 100
00000229 | 36 00 00 00 | event_len = 54
0000022D | 56 02 00 00 | log_pos = 00000256
00000231 | 00 00 | flags = <none>
------------------------
00000233 | 49 4E 53 45 | query = "INSERT INTO t1 VALUES (1), (2), (3)"
00000237 | 52 54 20 49 |
0000023B | 4E 54 4F 20 |
0000023F | 74 31 20 56 |
00000243 | 41 4C 55 45 |
00000247 | 53 20 28 31 |
0000024B | 29 2C 20 28 |
0000024F | 32 29 2C 20 |
00000253 | 28 33 29 |
************************
In binary log, Annotate_rows event follows the (possible) 'BEGIN' Query event
and precedes the first of Table map events which accompany the corresponding
rows events. (See example in the "mysqlbinlog output" section below.)
2. Server option: --binlog-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the master to write Annotate_rows events to the binary log.
* Variable Name: binlog_annotate_rows_events
* Scope: Global & Session
* Access Type: Dynamic
* Data Type: bool
* Default Value: OFF
NOTE. Session values allows to annotate only some selected statements:
...
SET SESSION binlog_annotate_rows_events=ON;
... statements to be annotated ...
SET SESSION binlog_annotate_rows_events=OFF;
... statements not to be annotated ...
3. Server option: --replicate-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the slave to reproduce Annotate_rows events recieved from the master
in its own binary log (sensible only in pair with log-slave-updates option).
* Variable Name: replicate_annotate_rows_events
* Scope: Global
* Access Type: Read only
* Data Type: bool
* Default Value: OFF
NOTE. Why do we additionally need this 'replicate' option? Why not to make
the slave to reproduce this events when its binlog-annotate-rows-events
global value is ON? Well, because, for example, we may want to configure
the slave which should reproduce Annotate_rows events but has global
binlog-annotate-rows-events = OFF meaning this to be the default value for
the client threads (see also "How slave treats replicate-annotate-rows-events
option" in LLD part).
4. mysqlbinlog option: --print-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With this option, mysqlbinlog prints the content of Annotate_rows events (if
the binary log does contain them). Without this option (i.e. by default),
mysqlbinlog skips Annotate_rows events.
5. mysqlbinlog output
~~~~~~~~~~~~~~~~~~~~~
With --print-annotate-rows-events, mysqlbinlog outputs Annotate_rows events
in a form like this:
...
# at 1646
#091219 12:45:26 server id 100 end_log_pos 1714 Query thread_id=1
exec_time=0 error_code=0
SET TIMESTAMP=1261215926/*!*/;
BEGIN
/*!*/;
# at 1714
# at 1812
# at 1853
# at 1894
# at 1938
#091219 12:45:26 server id 100 end_log_pos 1812 Query: `DELETE t1, t2 FROM
t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a`
#091219 12:45:26 server id 100 end_log_pos 1853 Table_map: `test`.`t1`
mapped to number 16
#091219 12:45:26 server id 100 end_log_pos 1894 Table_map: `test`.`t2`
mapped to number 17
#091219 12:45:26 server id 100 end_log_pos 1938 Delete_rows: table id 16
#091219 12:45:26 server id 100 end_log_pos 1982 Delete_rows: table id 17
flags: STMT_END_F
...
LOW-LEVEL DESIGN:
Content
~~~~~~~
1. Annotate_rows event number
2. Outline of Annotate_rows event behavior
3. How Master writes Annotate_rows events to the binary log
4. How slave treats replicate-annotate-rows-events option
5. How slave IO thread requests Annotate_rows events
6. How master executes the request
7. How slave SQL thread processes Annotate_rows events
8. General remarks
1. Annotate_rows event number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid possible event numbers conflict with MySQL/Sun, we leave a gap
between the last MySQL event number and the Annotate_rows event number:
enum Log_event_type
{ ...
INCIDENT_EVENT= 26,
// New MySQL event numbers are to be added here
MYSQL_EVENTS_END,
MARIA_EVENTS_BEGIN= 51,
// New Maria event numbers start from here
ANNOTATE_ROWS_EVENT= 51,
ENUM_END_EVENT
};
together with the corresponding extension of 'post_header_len' array in the
Format description event. (This extension does not affect the compatibility
of the binary log). Here is how Format description event looks like with
this extension:
************************
FORMAT_DESCRIPTION_EVENT
************************
00000004 | A1 A0 2C 4B | time_when = 1261215905
00000008 | 0F | event_type = 15
00000009 | 64 00 00 00 | server_id = 100
0000000D | 7F 00 00 00 | event_len = 127
00000011 | 83 00 00 00 | log_pos = 00000083
00000015 | 01 00 | flags = LOG_EVENT_BINLOG_IN_USE_F
------------------------
00000017 | 04 00 | binlog_ver = 4
00000019 | 35 2E 32 2E | server_ver = 5.2.0-MariaDB-alpha-debug-log
..... ...
0000004B | A1 A0 2C 4B | time_created = 1261215905
0000004F | 13 | common_header_len = 19
------------------------
post_header_len
------------------------
00000050 | 38 | 56 - START_EVENT_V3 [1]
..... ...
00000069 | 02 | 2 - INCIDENT_EVENT [26]
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each Annotate_rows_log_event object has two private members describing the
corresponding query:
char *m_query_txt;
uint m_query_len;
When the object is created for writing to a binary log, this query is taken
from 'thd' (for short, below we omit the 'Annotate_rows_log_event::' prefix
as well as other implementation details):
Annotate_rows_log_event(THD *thd)
{
m_query_txt = thd->query();
m_query_len = thd->query_length();
}
When the object is read from a binary log, the query is taken from the buffer
containing the binary log representation of the event (this buffer is allocated
in Log_event object from which all Log events are derived):
Annotate_rows_log_event(char *buf, uint event_len,
Format_description_log_event *desc)
{
m_query_len = event_len - desc->common_header_len;
m_query_txt = buf + desc->common_header_len;
}
The events are written to the binary log by the Log_event::write() member
which calls virtual write_data_header() and write_data_body() members
("data header" and "post header" are synonym in replication terminology).
In our case, data header is empty and data body is just the query:
bool write_data_body(IO_CACHE *file)
{
return my_b_safe_write(file, (uchar*) m_query_txt, m_query_len);
}
Printing the event is just printing the query:
void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
{
my_b_printf(&pinfo->head_cache, "\tQuery: `%s`\n", m_query_txt);
}
3. How Master writes Annotate_rows events to the binary log
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The event is written to the binary log just before the group of Table_map
events which precede corresponding Rows events (one query may generate
several Table map events in the binary log, but the corresponding
Annotate_rows event must be written only once before the first Table map
event; hence the boolean variable 'with_annotate' below):
int write_locked_table_maps(THD *thd)
{ ...
bool with_annotate= thd->variables.binlog_annotate_rows_events;
...
for (uint i= 0; i < ... <number of tables> ...; ++i)
{ ...
thd->binlog_write_table_map(table, ..., with_annotate);
with_annotate= 0; // write Annotate_event not more than once
...
}
...
}
int THD::binlog_write_table_map(TABLE *table, ..., bool with_annotate)
{ ...
Table_map_log_event the_event(...);
...
if (with_annotate)
{
Annotate_rows_log_event anno(this);
mysql_bin_log.write(&anno);
}
mysql_bin_log.write(&the_event);
...
}
4. How slave treats replicate-annotate-rows-events option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The replicate-annotate-rows-events option is treated just as the session
value of the binlog_annotate_rows_events variable for the slave IO and
SQL threads. This setting is done during initialization of these threads:
pthread_handler_t handle_slave_io(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_IO);
...
}
pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_SQL);
...
}
int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{ ...
thd->variables.binlog_annotate_rows_events=
opt_replicate_annotate_rows_events;
...
}
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the replicate-annotate-rows-events option is not set on a slave, there
is no need for master to send Annotate_rows events to this slave. The slave
(or mysqlbinlog in remote case), before requesting binlog dump via the
COM_BINLOG_DUMP command, informs the master whether it should send these
events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
command:
case COM_BINLOG_DUMP_OPTIONS_EXT:
thd->binlog_dump_flags_ext= packet[0];
my_ok(thd);
break;
Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
case COM_BINLOG_DUMP:
{ ...
flags= uint2korr(packet + 4);
...
mysql_binlog_send(thd, ..., flags);
...
}
void mysql_binlog_send(THD* thd, ..., ushort flags)
{ ...
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
...
}
7. How slave SQL thread processes Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slave processes each recieved event by "applying" it, i.e. by
calling the Log_event::apply_event() function which in turn calls
the virtual do_apply_event() member specific for each type of the
event.
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev = next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
int apply_event_and_update_pos(Log_event *ev, ...)
{ ...
ev->apply_event(...);
...
}
int Log_event::apply_event(...)
{
return do_apply_event(...);
}
What does it mean to "apply" an Annotate_rows event? It means to set current
thd query to that of the described by the event, i.e. to the query which
caused the subsequent Rows events (see "How Master writes Annotate_rows
events to the binary log" to follow what happens further when the subsequent
Rows events are applied):
int Annotate_rows_log_event::do_apply_event(...)
{
thd->set_query(m_query_txt, m_query_len);
}
NOTE. I am not sure, but possibly current values of thd->query and
thd->query_length should be saved before calling set_query() and to be
restored on the Annotate_rows_log_event object deletion.
Is it really needed ?
After calling this do_apply_event() function we may not delete the
Annotate_rows_log_event object immediatedly (see exec_relay_log_event()
above) because thd->query now points to the string inside this object.
We may keep the pointer to this object in the Relay_log_info:
class Relay_log_info
{
public:
...
void set_annotate_event(Annotate_rows_log_event*);
Annotate_rows_log_event* get_annotate_event();
void free_annotate_event();
...
private:
Annotate_rows_log_event* m_annotate_event;
};
The saved Annotate_rows object should be deleted when all corresponding
Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (rli->get_annotate_event() && is_last_rows_event(ev))
rli->free_annotate_event();
else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
where
bool is_last_rows_event(Log_event* ev)
{
Log_event_type type= ev->get_type_code();
if (IS_ROWS_EVENT_TYPE(type))
{
Rows_log_event* rows= (Rows_log_event*)ev;
return rows->get_flags(Rows_log_event::STMT_END_F);
}
return 0;
}
#define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
(type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
Kristian noticed that introducing new log event type should be coordinated
somehow with MySQL/Sun:
Kristian: The numeric code for this event must be assigned carefully.
It should be coordinated with MySQL/Sun, otherwise we can get into a
situation where MySQL uses the same numeric code for one event that
MariaDB uses for ANNOTATE_ROWS_EVENT, which would make merging the two
impossible.
Alex: I reserved about 20 numbers not to have possible conflicts
with MySQL.
Kristian: Still, I think it would be appropriate to send a polite email
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Updated (by Knielsen): Store in binlog text of statements that caused RBR events (47)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Store in binlog text of statements that caused RBR events
CREATION DATE..: Sat, 15 Aug 2009, 23:48
SUPERVISOR.....: Monty
IMPLEMENTOR....:
COPIES TO......: Knielsen, Serg
CATEGORY.......: Server-Sprint
TASK ID........: 47 (http://askmonty.org/worklog/?tid=47)
VERSION........: Server-9.x
STATUS.........: In-Progress
PRIORITY.......: 60
WORKED HOURS...: 40
ESTIMATE.......: 15 (hours remain)
ORIG. ESTIMATE.: 35
PROGRESS NOTES:
-=-=(Knielsen - Tue, 06 Apr 2010, 15:25)=-=-
Status updated.
--- /tmp/wklog.47.old.12734 2010-04-06 15:25:54.000000000 +0000
+++ /tmp/wklog.47.new.12734 2010-04-06 15:25:54.000000000 +0000
@@ -1 +1 @@
-Code-Review
+In-Progress
-=-=(Knielsen - Mon, 29 Mar 2010, 10:59)=-=-
Status updated.
--- /tmp/wklog.47.old.27790 2010-03-29 10:59:53.000000000 +0000
+++ /tmp/wklog.47.new.27790 2010-03-29 10:59:53.000000000 +0000
@@ -1 +1 @@
-In-Progress
+Code-Review
-=-=(Alexi - Thu, 18 Feb 2010, 19:29)=-=-
Worked 20 hours (alexi)
Worked 20 hours and estimate 15 hours remain (original estimate unchanged).
-=-=(Serg - Fri, 05 Feb 2010, 14:04)=-=-
Observers changed: Knielsen,Serg
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Category updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Server-RawIdeaBin
+Server-Sprint
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Status updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Un-Assigned
+In-Progress
-=-=(Alexi - Thu, 04 Feb 2010, 09:54)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.16174 2010-02-04 09:54:13.000000000 +0200
+++ /tmp/wklog.47.new.16174 2010-02-04 09:54:13.000000000 +0200
@@ -171,35 +171,20 @@
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When requesting an event, the slave should inform the master whether
-it should send Annotate_rows events or not. To that end we add a new
-BINLOG_SEND_ANNOTATE_ROWS_EVENT flag used when requesting an event:
+If the replicate-annotate-rows-events option is not set on a slave, there
+is no need for master to send Annotate_rows events to this slave. The slave
+(or mysqlbinlog in remote case), before requesting binlog dump via the
+COM_BINLOG_DUMP command, informs the master whether it should send these
+events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
+command:
+
+ case COM_BINLOG_DUMP_OPTIONS_EXT:
+ thd->binlog_dump_flags_ext= packet[0];
+ my_ok(thd);
+ break;
- #define BINLOG_DUMP_NON_BLOCK 1
- #define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2
-
- pthread_handler_t handle_slave_io(void *arg)
- { ...
- request_dump(mysql, ...);
- ...
- }
-
- int request_dump(MYSQL* mysql, ...)
- { ...
- if (opt_log_slave_updates &&
- mi->io_thd->variables.binlog_annotate_rows_events)
- binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
- ...
- int2store(buf + 4, binlog_flags);
- ...
- simple_command(mysql, COM_BINLOG_DUMP, buf, ...);
- ...
- }
-
-NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
-simple_command() function, should also use this flag if it wants (in case
-of the --print-annotate-rows-events option set) to recieve Annotate_rows
-events.
+Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
+conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -338,10 +323,4 @@
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
-Also we should notice the introduction of the BINLOG_SEND_ANNOTATE_ROWS_EVENT
-flag taking into account that MySQL/Sun may also introduce a flag with the
-same value to be used in the request_dump-mysql_binlog_send interface.
-But this is mainly the question of merging: if a conflict concerning this
-flag occur, we may simply change the BINLOG_SEND_ANNOTATE_ROWS_EVENT value
-(this does not require additional changes in the code).
-=-=(Alexi - Sun, 20 Dec 2009, 16:00)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.19667 2009-12-20 14:00:56.000000000 +0000
+++ /tmp/wklog.47.new.19667 2009-12-20 14:00:56.000000000 +0000
@@ -196,6 +196,11 @@
...
}
+NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
+simple_command() function, should also use this flag if it wants (in case
+of the --print-annotate-rows-events option set) to recieve Annotate_rows
+events.
+
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,8 +217,7 @@
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
- flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT ||
- thd->server_id == 0 /* slave == mysqlbinlog */ )
+ flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
-=-=(Alexi - Sun, 20 Dec 2009, 13:14)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.11350 2009-12-20 13:14:04.000000000 +0200
+++ /tmp/wklog.47.new.11350 2009-12-20 13:14:04.000000000 +0200
@@ -282,23 +282,18 @@
Annotate_rows_log_event* m_annotate_event;
};
-When the saved Annotate_rows object may be deleted? When all corresponding
-Rows events will be processed, i.e. before processing the first non-Rows
-event (note that Annotate_rows object resides in the binary log *after*
-the (possible) 'BEGIN' Query event which accompanies the rows events; note
-also that this deletion is adjusted with the case when some or all
-corresponding Rows events are filtered out by replicate filter rules):
+The saved Annotate_rows object should be deleted when all corresponding
+Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
- if (rli->get_annotate_event() && !IS_RBR_EVENT_TYPE(ev->get_type_code()))
- rli->free_annotate_event();
-
apply_event_and_update_pos(ev, ...);
- if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
+ if (rli->get_annotate_event() && is_last_rows_event(ev))
+ rli->free_annotate_event();
+ else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
@@ -307,10 +302,21 @@
where
- #define IS_RBR_EVENT_TYPE(type) ( (type) == TABLE_MAP_EVENT || \
- (type) == WRITE_ROWS_EVENT || \
+ bool is_last_rows_event(Log_event* ev)
+ {
+ Log_event_type type= ev->get_type_code();
+ if (IS_ROWS_EVENT_TYPE(type))
+ {
+ Rows_log_event* rows= (Rows_log_event*)ev;
+ return rows->get_flags(Rows_log_event::STMT_END_F);
+ }
+
+ return 0;
+ }
+
+ #define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
- (type) == DELETE_ROWS_EVENT )
+ (type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
-=-=(Alexi - Sun, 20 Dec 2009, 09:29)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.32726 2009-12-20 07:29:56.000000000 +0000
+++ /tmp/wklog.47.new.32726 2009-12-20 07:29:56.000000000 +0000
@@ -56,7 +56,7 @@
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
- 00000082 | 00 | 0 - ANNOTATE_RBR_EVENT [51]
+ 00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
------------------------------------------------------------
-=-=(View All Progress Notes, 26 total)=-=-
http://askmonty.org/worklog/index.pl?tid=47&nolimit=1
DESCRIPTION:
Store in binlog (and show in mysqlbinlog output) texts of statements that
caused RBR events
This is needed for (list from Monty):
- Easier to understand why updates happened
- Would make it easier to find out where in application things went
wrong (as you can search for exact strings)
- Allow one to filter things based on comments in the statement.
The cost of this can be that the binlog will be approximately 2x in size
(especially insert of big blob's would be a bit painful), so this should
be an optional feature.
HIGH-LEVEL SPECIFICATION:
Content
~~~~~~~
1. Annotate_rows_log_event
2. Server option: --binlog-annotate-rows-events
3. Server option: --replicate-annotate-rows-events
4. mysqlbinlog option: --print-annotate-rows-events
5. mysqlbinlog output
1. Annotate_rows_log_event [ ANNOTATE_ROWS_EVENT ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Describes the query which caused the corresponding rows events. Has empty
post-header and contains the query text in its data part. Example:
************************
ANNOTATE_ROWS_EVENT
************************
00000220 | B6 A0 2C 4B | time_when = 1261215926
00000224 | 33 | event_type = 51
00000225 | 64 00 00 00 | server_id = 100
00000229 | 36 00 00 00 | event_len = 54
0000022D | 56 02 00 00 | log_pos = 00000256
00000231 | 00 00 | flags = <none>
------------------------
00000233 | 49 4E 53 45 | query = "INSERT INTO t1 VALUES (1), (2), (3)"
00000237 | 52 54 20 49 |
0000023B | 4E 54 4F 20 |
0000023F | 74 31 20 56 |
00000243 | 41 4C 55 45 |
00000247 | 53 20 28 31 |
0000024B | 29 2C 20 28 |
0000024F | 32 29 2C 20 |
00000253 | 28 33 29 |
************************
In binary log, Annotate_rows event follows the (possible) 'BEGIN' Query event
and precedes the first of Table map events which accompany the corresponding
rows events. (See example in the "mysqlbinlog output" section below.)
2. Server option: --binlog-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the master to write Annotate_rows events to the binary log.
* Variable Name: binlog_annotate_rows_events
* Scope: Global & Session
* Access Type: Dynamic
* Data Type: bool
* Default Value: OFF
NOTE. Session values allows to annotate only some selected statements:
...
SET SESSION binlog_annotate_rows_events=ON;
... statements to be annotated ...
SET SESSION binlog_annotate_rows_events=OFF;
... statements not to be annotated ...
3. Server option: --replicate-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the slave to reproduce Annotate_rows events recieved from the master
in its own binary log (sensible only in pair with log-slave-updates option).
* Variable Name: replicate_annotate_rows_events
* Scope: Global
* Access Type: Read only
* Data Type: bool
* Default Value: OFF
NOTE. Why do we additionally need this 'replicate' option? Why not to make
the slave to reproduce this events when its binlog-annotate-rows-events
global value is ON? Well, because, for example, we may want to configure
the slave which should reproduce Annotate_rows events but has global
binlog-annotate-rows-events = OFF meaning this to be the default value for
the client threads (see also "How slave treats replicate-annotate-rows-events
option" in LLD part).
4. mysqlbinlog option: --print-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With this option, mysqlbinlog prints the content of Annotate_rows events (if
the binary log does contain them). Without this option (i.e. by default),
mysqlbinlog skips Annotate_rows events.
5. mysqlbinlog output
~~~~~~~~~~~~~~~~~~~~~
With --print-annotate-rows-events, mysqlbinlog outputs Annotate_rows events
in a form like this:
...
# at 1646
#091219 12:45:26 server id 100 end_log_pos 1714 Query thread_id=1
exec_time=0 error_code=0
SET TIMESTAMP=1261215926/*!*/;
BEGIN
/*!*/;
# at 1714
# at 1812
# at 1853
# at 1894
# at 1938
#091219 12:45:26 server id 100 end_log_pos 1812 Query: `DELETE t1, t2 FROM
t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a`
#091219 12:45:26 server id 100 end_log_pos 1853 Table_map: `test`.`t1`
mapped to number 16
#091219 12:45:26 server id 100 end_log_pos 1894 Table_map: `test`.`t2`
mapped to number 17
#091219 12:45:26 server id 100 end_log_pos 1938 Delete_rows: table id 16
#091219 12:45:26 server id 100 end_log_pos 1982 Delete_rows: table id 17
flags: STMT_END_F
...
LOW-LEVEL DESIGN:
Content
~~~~~~~
1. Annotate_rows event number
2. Outline of Annotate_rows event behavior
3. How Master writes Annotate_rows events to the binary log
4. How slave treats replicate-annotate-rows-events option
5. How slave IO thread requests Annotate_rows events
6. How master executes the request
7. How slave SQL thread processes Annotate_rows events
8. General remarks
1. Annotate_rows event number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid possible event numbers conflict with MySQL/Sun, we leave a gap
between the last MySQL event number and the Annotate_rows event number:
enum Log_event_type
{ ...
INCIDENT_EVENT= 26,
// New MySQL event numbers are to be added here
MYSQL_EVENTS_END,
MARIA_EVENTS_BEGIN= 51,
// New Maria event numbers start from here
ANNOTATE_ROWS_EVENT= 51,
ENUM_END_EVENT
};
together with the corresponding extension of 'post_header_len' array in the
Format description event. (This extension does not affect the compatibility
of the binary log). Here is how Format description event looks like with
this extension:
************************
FORMAT_DESCRIPTION_EVENT
************************
00000004 | A1 A0 2C 4B | time_when = 1261215905
00000008 | 0F | event_type = 15
00000009 | 64 00 00 00 | server_id = 100
0000000D | 7F 00 00 00 | event_len = 127
00000011 | 83 00 00 00 | log_pos = 00000083
00000015 | 01 00 | flags = LOG_EVENT_BINLOG_IN_USE_F
------------------------
00000017 | 04 00 | binlog_ver = 4
00000019 | 35 2E 32 2E | server_ver = 5.2.0-MariaDB-alpha-debug-log
..... ...
0000004B | A1 A0 2C 4B | time_created = 1261215905
0000004F | 13 | common_header_len = 19
------------------------
post_header_len
------------------------
00000050 | 38 | 56 - START_EVENT_V3 [1]
..... ...
00000069 | 02 | 2 - INCIDENT_EVENT [26]
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each Annotate_rows_log_event object has two private members describing the
corresponding query:
char *m_query_txt;
uint m_query_len;
When the object is created for writing to a binary log, this query is taken
from 'thd' (for short, below we omit the 'Annotate_rows_log_event::' prefix
as well as other implementation details):
Annotate_rows_log_event(THD *thd)
{
m_query_txt = thd->query();
m_query_len = thd->query_length();
}
When the object is read from a binary log, the query is taken from the buffer
containing the binary log representation of the event (this buffer is allocated
in Log_event object from which all Log events are derived):
Annotate_rows_log_event(char *buf, uint event_len,
Format_description_log_event *desc)
{
m_query_len = event_len - desc->common_header_len;
m_query_txt = buf + desc->common_header_len;
}
The events are written to the binary log by the Log_event::write() member
which calls virtual write_data_header() and write_data_body() members
("data header" and "post header" are synonym in replication terminology).
In our case, data header is empty and data body is just the query:
bool write_data_body(IO_CACHE *file)
{
return my_b_safe_write(file, (uchar*) m_query_txt, m_query_len);
}
Printing the event is just printing the query:
void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
{
my_b_printf(&pinfo->head_cache, "\tQuery: `%s`\n", m_query_txt);
}
3. How Master writes Annotate_rows events to the binary log
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The event is written to the binary log just before the group of Table_map
events which precede corresponding Rows events (one query may generate
several Table map events in the binary log, but the corresponding
Annotate_rows event must be written only once before the first Table map
event; hence the boolean variable 'with_annotate' below):
int write_locked_table_maps(THD *thd)
{ ...
bool with_annotate= thd->variables.binlog_annotate_rows_events;
...
for (uint i= 0; i < ... <number of tables> ...; ++i)
{ ...
thd->binlog_write_table_map(table, ..., with_annotate);
with_annotate= 0; // write Annotate_event not more than once
...
}
...
}
int THD::binlog_write_table_map(TABLE *table, ..., bool with_annotate)
{ ...
Table_map_log_event the_event(...);
...
if (with_annotate)
{
Annotate_rows_log_event anno(this);
mysql_bin_log.write(&anno);
}
mysql_bin_log.write(&the_event);
...
}
4. How slave treats replicate-annotate-rows-events option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The replicate-annotate-rows-events option is treated just as the session
value of the binlog_annotate_rows_events variable for the slave IO and
SQL threads. This setting is done during initialization of these threads:
pthread_handler_t handle_slave_io(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_IO);
...
}
pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_SQL);
...
}
int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{ ...
thd->variables.binlog_annotate_rows_events=
opt_replicate_annotate_rows_events;
...
}
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the replicate-annotate-rows-events option is not set on a slave, there
is no need for master to send Annotate_rows events to this slave. The slave
(or mysqlbinlog in remote case), before requesting binlog dump via the
COM_BINLOG_DUMP command, informs the master whether it should send these
events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
command:
case COM_BINLOG_DUMP_OPTIONS_EXT:
thd->binlog_dump_flags_ext= packet[0];
my_ok(thd);
break;
Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
case COM_BINLOG_DUMP:
{ ...
flags= uint2korr(packet + 4);
...
mysql_binlog_send(thd, ..., flags);
...
}
void mysql_binlog_send(THD* thd, ..., ushort flags)
{ ...
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
...
}
7. How slave SQL thread processes Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slave processes each recieved event by "applying" it, i.e. by
calling the Log_event::apply_event() function which in turn calls
the virtual do_apply_event() member specific for each type of the
event.
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev = next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
int apply_event_and_update_pos(Log_event *ev, ...)
{ ...
ev->apply_event(...);
...
}
int Log_event::apply_event(...)
{
return do_apply_event(...);
}
What does it mean to "apply" an Annotate_rows event? It means to set current
thd query to that of the described by the event, i.e. to the query which
caused the subsequent Rows events (see "How Master writes Annotate_rows
events to the binary log" to follow what happens further when the subsequent
Rows events are applied):
int Annotate_rows_log_event::do_apply_event(...)
{
thd->set_query(m_query_txt, m_query_len);
}
NOTE. I am not sure, but possibly current values of thd->query and
thd->query_length should be saved before calling set_query() and to be
restored on the Annotate_rows_log_event object deletion.
Is it really needed ?
After calling this do_apply_event() function we may not delete the
Annotate_rows_log_event object immediatedly (see exec_relay_log_event()
above) because thd->query now points to the string inside this object.
We may keep the pointer to this object in the Relay_log_info:
class Relay_log_info
{
public:
...
void set_annotate_event(Annotate_rows_log_event*);
Annotate_rows_log_event* get_annotate_event();
void free_annotate_event();
...
private:
Annotate_rows_log_event* m_annotate_event;
};
The saved Annotate_rows object should be deleted when all corresponding
Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (rli->get_annotate_event() && is_last_rows_event(ev))
rli->free_annotate_event();
else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
where
bool is_last_rows_event(Log_event* ev)
{
Log_event_type type= ev->get_type_code();
if (IS_ROWS_EVENT_TYPE(type))
{
Rows_log_event* rows= (Rows_log_event*)ev;
return rows->get_flags(Rows_log_event::STMT_END_F);
}
return 0;
}
#define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
(type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
Kristian noticed that introducing new log event type should be coordinated
somehow with MySQL/Sun:
Kristian: The numeric code for this event must be assigned carefully.
It should be coordinated with MySQL/Sun, otherwise we can get into a
situation where MySQL uses the same numeric code for one event that
MariaDB uses for ANNOTATE_ROWS_EVENT, which would make merging the two
impossible.
Alex: I reserved about 20 numbers not to have possible conflicts
with MySQL.
Kristian: Still, I think it would be appropriate to send a polite email
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Updated (by Knielsen): Store in binlog text of statements that caused RBR events (47)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Store in binlog text of statements that caused RBR events
CREATION DATE..: Sat, 15 Aug 2009, 23:48
SUPERVISOR.....: Monty
IMPLEMENTOR....:
COPIES TO......: Knielsen, Serg
CATEGORY.......: Server-Sprint
TASK ID........: 47 (http://askmonty.org/worklog/?tid=47)
VERSION........: Server-9.x
STATUS.........: In-Progress
PRIORITY.......: 60
WORKED HOURS...: 40
ESTIMATE.......: 15 (hours remain)
ORIG. ESTIMATE.: 35
PROGRESS NOTES:
-=-=(Knielsen - Tue, 06 Apr 2010, 15:25)=-=-
Status updated.
--- /tmp/wklog.47.old.12734 2010-04-06 15:25:54.000000000 +0000
+++ /tmp/wklog.47.new.12734 2010-04-06 15:25:54.000000000 +0000
@@ -1 +1 @@
-Code-Review
+In-Progress
-=-=(Knielsen - Mon, 29 Mar 2010, 10:59)=-=-
Status updated.
--- /tmp/wklog.47.old.27790 2010-03-29 10:59:53.000000000 +0000
+++ /tmp/wklog.47.new.27790 2010-03-29 10:59:53.000000000 +0000
@@ -1 +1 @@
-In-Progress
+Code-Review
-=-=(Alexi - Thu, 18 Feb 2010, 19:29)=-=-
Worked 20 hours (alexi)
Worked 20 hours and estimate 15 hours remain (original estimate unchanged).
-=-=(Serg - Fri, 05 Feb 2010, 14:04)=-=-
Observers changed: Knielsen,Serg
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Category updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Server-RawIdeaBin
+Server-Sprint
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Status updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Un-Assigned
+In-Progress
-=-=(Alexi - Thu, 04 Feb 2010, 09:54)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.16174 2010-02-04 09:54:13.000000000 +0200
+++ /tmp/wklog.47.new.16174 2010-02-04 09:54:13.000000000 +0200
@@ -171,35 +171,20 @@
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When requesting an event, the slave should inform the master whether
-it should send Annotate_rows events or not. To that end we add a new
-BINLOG_SEND_ANNOTATE_ROWS_EVENT flag used when requesting an event:
+If the replicate-annotate-rows-events option is not set on a slave, there
+is no need for master to send Annotate_rows events to this slave. The slave
+(or mysqlbinlog in remote case), before requesting binlog dump via the
+COM_BINLOG_DUMP command, informs the master whether it should send these
+events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
+command:
+
+ case COM_BINLOG_DUMP_OPTIONS_EXT:
+ thd->binlog_dump_flags_ext= packet[0];
+ my_ok(thd);
+ break;
- #define BINLOG_DUMP_NON_BLOCK 1
- #define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2
-
- pthread_handler_t handle_slave_io(void *arg)
- { ...
- request_dump(mysql, ...);
- ...
- }
-
- int request_dump(MYSQL* mysql, ...)
- { ...
- if (opt_log_slave_updates &&
- mi->io_thd->variables.binlog_annotate_rows_events)
- binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
- ...
- int2store(buf + 4, binlog_flags);
- ...
- simple_command(mysql, COM_BINLOG_DUMP, buf, ...);
- ...
- }
-
-NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
-simple_command() function, should also use this flag if it wants (in case
-of the --print-annotate-rows-events option set) to recieve Annotate_rows
-events.
+Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
+conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -338,10 +323,4 @@
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
-Also we should notice the introduction of the BINLOG_SEND_ANNOTATE_ROWS_EVENT
-flag taking into account that MySQL/Sun may also introduce a flag with the
-same value to be used in the request_dump-mysql_binlog_send interface.
-But this is mainly the question of merging: if a conflict concerning this
-flag occur, we may simply change the BINLOG_SEND_ANNOTATE_ROWS_EVENT value
-(this does not require additional changes in the code).
-=-=(Alexi - Sun, 20 Dec 2009, 16:00)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.19667 2009-12-20 14:00:56.000000000 +0000
+++ /tmp/wklog.47.new.19667 2009-12-20 14:00:56.000000000 +0000
@@ -196,6 +196,11 @@
...
}
+NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
+simple_command() function, should also use this flag if it wants (in case
+of the --print-annotate-rows-events option set) to recieve Annotate_rows
+events.
+
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,8 +217,7 @@
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
- flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT ||
- thd->server_id == 0 /* slave == mysqlbinlog */ )
+ flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
-=-=(Alexi - Sun, 20 Dec 2009, 13:14)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.11350 2009-12-20 13:14:04.000000000 +0200
+++ /tmp/wklog.47.new.11350 2009-12-20 13:14:04.000000000 +0200
@@ -282,23 +282,18 @@
Annotate_rows_log_event* m_annotate_event;
};
-When the saved Annotate_rows object may be deleted? When all corresponding
-Rows events will be processed, i.e. before processing the first non-Rows
-event (note that Annotate_rows object resides in the binary log *after*
-the (possible) 'BEGIN' Query event which accompanies the rows events; note
-also that this deletion is adjusted with the case when some or all
-corresponding Rows events are filtered out by replicate filter rules):
+The saved Annotate_rows object should be deleted when all corresponding
+Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
- if (rli->get_annotate_event() && !IS_RBR_EVENT_TYPE(ev->get_type_code()))
- rli->free_annotate_event();
-
apply_event_and_update_pos(ev, ...);
- if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
+ if (rli->get_annotate_event() && is_last_rows_event(ev))
+ rli->free_annotate_event();
+ else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
@@ -307,10 +302,21 @@
where
- #define IS_RBR_EVENT_TYPE(type) ( (type) == TABLE_MAP_EVENT || \
- (type) == WRITE_ROWS_EVENT || \
+ bool is_last_rows_event(Log_event* ev)
+ {
+ Log_event_type type= ev->get_type_code();
+ if (IS_ROWS_EVENT_TYPE(type))
+ {
+ Rows_log_event* rows= (Rows_log_event*)ev;
+ return rows->get_flags(Rows_log_event::STMT_END_F);
+ }
+
+ return 0;
+ }
+
+ #define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
- (type) == DELETE_ROWS_EVENT )
+ (type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
-=-=(Alexi - Sun, 20 Dec 2009, 09:29)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.32726 2009-12-20 07:29:56.000000000 +0000
+++ /tmp/wklog.47.new.32726 2009-12-20 07:29:56.000000000 +0000
@@ -56,7 +56,7 @@
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
- 00000082 | 00 | 0 - ANNOTATE_RBR_EVENT [51]
+ 00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
------------------------------------------------------------
-=-=(View All Progress Notes, 26 total)=-=-
http://askmonty.org/worklog/index.pl?tid=47&nolimit=1
DESCRIPTION:
Store in binlog (and show in mysqlbinlog output) texts of statements that
caused RBR events
This is needed for (list from Monty):
- Easier to understand why updates happened
- Would make it easier to find out where in application things went
wrong (as you can search for exact strings)
- Allow one to filter things based on comments in the statement.
The cost of this can be that the binlog will be approximately 2x in size
(especially insert of big blob's would be a bit painful), so this should
be an optional feature.
HIGH-LEVEL SPECIFICATION:
Content
~~~~~~~
1. Annotate_rows_log_event
2. Server option: --binlog-annotate-rows-events
3. Server option: --replicate-annotate-rows-events
4. mysqlbinlog option: --print-annotate-rows-events
5. mysqlbinlog output
1. Annotate_rows_log_event [ ANNOTATE_ROWS_EVENT ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Describes the query which caused the corresponding rows events. Has empty
post-header and contains the query text in its data part. Example:
************************
ANNOTATE_ROWS_EVENT
************************
00000220 | B6 A0 2C 4B | time_when = 1261215926
00000224 | 33 | event_type = 51
00000225 | 64 00 00 00 | server_id = 100
00000229 | 36 00 00 00 | event_len = 54
0000022D | 56 02 00 00 | log_pos = 00000256
00000231 | 00 00 | flags = <none>
------------------------
00000233 | 49 4E 53 45 | query = "INSERT INTO t1 VALUES (1), (2), (3)"
00000237 | 52 54 20 49 |
0000023B | 4E 54 4F 20 |
0000023F | 74 31 20 56 |
00000243 | 41 4C 55 45 |
00000247 | 53 20 28 31 |
0000024B | 29 2C 20 28 |
0000024F | 32 29 2C 20 |
00000253 | 28 33 29 |
************************
In binary log, Annotate_rows event follows the (possible) 'BEGIN' Query event
and precedes the first of Table map events which accompany the corresponding
rows events. (See example in the "mysqlbinlog output" section below.)
2. Server option: --binlog-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the master to write Annotate_rows events to the binary log.
* Variable Name: binlog_annotate_rows_events
* Scope: Global & Session
* Access Type: Dynamic
* Data Type: bool
* Default Value: OFF
NOTE. Session values allows to annotate only some selected statements:
...
SET SESSION binlog_annotate_rows_events=ON;
... statements to be annotated ...
SET SESSION binlog_annotate_rows_events=OFF;
... statements not to be annotated ...
3. Server option: --replicate-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the slave to reproduce Annotate_rows events recieved from the master
in its own binary log (sensible only in pair with log-slave-updates option).
* Variable Name: replicate_annotate_rows_events
* Scope: Global
* Access Type: Read only
* Data Type: bool
* Default Value: OFF
NOTE. Why do we additionally need this 'replicate' option? Why not to make
the slave to reproduce this events when its binlog-annotate-rows-events
global value is ON? Well, because, for example, we may want to configure
the slave which should reproduce Annotate_rows events but has global
binlog-annotate-rows-events = OFF meaning this to be the default value for
the client threads (see also "How slave treats replicate-annotate-rows-events
option" in LLD part).
4. mysqlbinlog option: --print-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With this option, mysqlbinlog prints the content of Annotate_rows events (if
the binary log does contain them). Without this option (i.e. by default),
mysqlbinlog skips Annotate_rows events.
5. mysqlbinlog output
~~~~~~~~~~~~~~~~~~~~~
With --print-annotate-rows-events, mysqlbinlog outputs Annotate_rows events
in a form like this:
...
# at 1646
#091219 12:45:26 server id 100 end_log_pos 1714 Query thread_id=1
exec_time=0 error_code=0
SET TIMESTAMP=1261215926/*!*/;
BEGIN
/*!*/;
# at 1714
# at 1812
# at 1853
# at 1894
# at 1938
#091219 12:45:26 server id 100 end_log_pos 1812 Query: `DELETE t1, t2 FROM
t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a`
#091219 12:45:26 server id 100 end_log_pos 1853 Table_map: `test`.`t1`
mapped to number 16
#091219 12:45:26 server id 100 end_log_pos 1894 Table_map: `test`.`t2`
mapped to number 17
#091219 12:45:26 server id 100 end_log_pos 1938 Delete_rows: table id 16
#091219 12:45:26 server id 100 end_log_pos 1982 Delete_rows: table id 17
flags: STMT_END_F
...
LOW-LEVEL DESIGN:
Content
~~~~~~~
1. Annotate_rows event number
2. Outline of Annotate_rows event behavior
3. How Master writes Annotate_rows events to the binary log
4. How slave treats replicate-annotate-rows-events option
5. How slave IO thread requests Annotate_rows events
6. How master executes the request
7. How slave SQL thread processes Annotate_rows events
8. General remarks
1. Annotate_rows event number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid possible event numbers conflict with MySQL/Sun, we leave a gap
between the last MySQL event number and the Annotate_rows event number:
enum Log_event_type
{ ...
INCIDENT_EVENT= 26,
// New MySQL event numbers are to be added here
MYSQL_EVENTS_END,
MARIA_EVENTS_BEGIN= 51,
// New Maria event numbers start from here
ANNOTATE_ROWS_EVENT= 51,
ENUM_END_EVENT
};
together with the corresponding extension of 'post_header_len' array in the
Format description event. (This extension does not affect the compatibility
of the binary log). Here is how Format description event looks like with
this extension:
************************
FORMAT_DESCRIPTION_EVENT
************************
00000004 | A1 A0 2C 4B | time_when = 1261215905
00000008 | 0F | event_type = 15
00000009 | 64 00 00 00 | server_id = 100
0000000D | 7F 00 00 00 | event_len = 127
00000011 | 83 00 00 00 | log_pos = 00000083
00000015 | 01 00 | flags = LOG_EVENT_BINLOG_IN_USE_F
------------------------
00000017 | 04 00 | binlog_ver = 4
00000019 | 35 2E 32 2E | server_ver = 5.2.0-MariaDB-alpha-debug-log
..... ...
0000004B | A1 A0 2C 4B | time_created = 1261215905
0000004F | 13 | common_header_len = 19
------------------------
post_header_len
------------------------
00000050 | 38 | 56 - START_EVENT_V3 [1]
..... ...
00000069 | 02 | 2 - INCIDENT_EVENT [26]
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each Annotate_rows_log_event object has two private members describing the
corresponding query:
char *m_query_txt;
uint m_query_len;
When the object is created for writing to a binary log, this query is taken
from 'thd' (for short, below we omit the 'Annotate_rows_log_event::' prefix
as well as other implementation details):
Annotate_rows_log_event(THD *thd)
{
m_query_txt = thd->query();
m_query_len = thd->query_length();
}
When the object is read from a binary log, the query is taken from the buffer
containing the binary log representation of the event (this buffer is allocated
in Log_event object from which all Log events are derived):
Annotate_rows_log_event(char *buf, uint event_len,
Format_description_log_event *desc)
{
m_query_len = event_len - desc->common_header_len;
m_query_txt = buf + desc->common_header_len;
}
The events are written to the binary log by the Log_event::write() member
which calls virtual write_data_header() and write_data_body() members
("data header" and "post header" are synonym in replication terminology).
In our case, data header is empty and data body is just the query:
bool write_data_body(IO_CACHE *file)
{
return my_b_safe_write(file, (uchar*) m_query_txt, m_query_len);
}
Printing the event is just printing the query:
void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
{
my_b_printf(&pinfo->head_cache, "\tQuery: `%s`\n", m_query_txt);
}
3. How Master writes Annotate_rows events to the binary log
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The event is written to the binary log just before the group of Table_map
events which precede corresponding Rows events (one query may generate
several Table map events in the binary log, but the corresponding
Annotate_rows event must be written only once before the first Table map
event; hence the boolean variable 'with_annotate' below):
int write_locked_table_maps(THD *thd)
{ ...
bool with_annotate= thd->variables.binlog_annotate_rows_events;
...
for (uint i= 0; i < ... <number of tables> ...; ++i)
{ ...
thd->binlog_write_table_map(table, ..., with_annotate);
with_annotate= 0; // write Annotate_event not more than once
...
}
...
}
int THD::binlog_write_table_map(TABLE *table, ..., bool with_annotate)
{ ...
Table_map_log_event the_event(...);
...
if (with_annotate)
{
Annotate_rows_log_event anno(this);
mysql_bin_log.write(&anno);
}
mysql_bin_log.write(&the_event);
...
}
4. How slave treats replicate-annotate-rows-events option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The replicate-annotate-rows-events option is treated just as the session
value of the binlog_annotate_rows_events variable for the slave IO and
SQL threads. This setting is done during initialization of these threads:
pthread_handler_t handle_slave_io(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_IO);
...
}
pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_SQL);
...
}
int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{ ...
thd->variables.binlog_annotate_rows_events=
opt_replicate_annotate_rows_events;
...
}
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the replicate-annotate-rows-events option is not set on a slave, there
is no need for master to send Annotate_rows events to this slave. The slave
(or mysqlbinlog in remote case), before requesting binlog dump via the
COM_BINLOG_DUMP command, informs the master whether it should send these
events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
command:
case COM_BINLOG_DUMP_OPTIONS_EXT:
thd->binlog_dump_flags_ext= packet[0];
my_ok(thd);
break;
Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
case COM_BINLOG_DUMP:
{ ...
flags= uint2korr(packet + 4);
...
mysql_binlog_send(thd, ..., flags);
...
}
void mysql_binlog_send(THD* thd, ..., ushort flags)
{ ...
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
...
}
7. How slave SQL thread processes Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slave processes each recieved event by "applying" it, i.e. by
calling the Log_event::apply_event() function which in turn calls
the virtual do_apply_event() member specific for each type of the
event.
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev = next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
int apply_event_and_update_pos(Log_event *ev, ...)
{ ...
ev->apply_event(...);
...
}
int Log_event::apply_event(...)
{
return do_apply_event(...);
}
What does it mean to "apply" an Annotate_rows event? It means to set current
thd query to that of the described by the event, i.e. to the query which
caused the subsequent Rows events (see "How Master writes Annotate_rows
events to the binary log" to follow what happens further when the subsequent
Rows events are applied):
int Annotate_rows_log_event::do_apply_event(...)
{
thd->set_query(m_query_txt, m_query_len);
}
NOTE. I am not sure, but possibly current values of thd->query and
thd->query_length should be saved before calling set_query() and to be
restored on the Annotate_rows_log_event object deletion.
Is it really needed ?
After calling this do_apply_event() function we may not delete the
Annotate_rows_log_event object immediatedly (see exec_relay_log_event()
above) because thd->query now points to the string inside this object.
We may keep the pointer to this object in the Relay_log_info:
class Relay_log_info
{
public:
...
void set_annotate_event(Annotate_rows_log_event*);
Annotate_rows_log_event* get_annotate_event();
void free_annotate_event();
...
private:
Annotate_rows_log_event* m_annotate_event;
};
The saved Annotate_rows object should be deleted when all corresponding
Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (rli->get_annotate_event() && is_last_rows_event(ev))
rli->free_annotate_event();
else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
where
bool is_last_rows_event(Log_event* ev)
{
Log_event_type type= ev->get_type_code();
if (IS_ROWS_EVENT_TYPE(type))
{
Rows_log_event* rows= (Rows_log_event*)ev;
return rows->get_flags(Rows_log_event::STMT_END_F);
}
return 0;
}
#define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
(type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
Kristian noticed that introducing new log event type should be coordinated
somehow with MySQL/Sun:
Kristian: The numeric code for this event must be assigned carefully.
It should be coordinated with MySQL/Sun, otherwise we can get into a
situation where MySQL uses the same numeric code for one event that
MariaDB uses for ANNOTATE_ROWS_EVENT, which would make merging the two
impossible.
Alex: I reserved about 20 numbers not to have possible conflicts
with MySQL.
Kristian: Still, I think it would be appropriate to send a polite email
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Updated (by Knielsen): Store in binlog text of statements that caused RBR events (47)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Store in binlog text of statements that caused RBR events
CREATION DATE..: Sat, 15 Aug 2009, 23:48
SUPERVISOR.....: Monty
IMPLEMENTOR....:
COPIES TO......: Knielsen, Serg
CATEGORY.......: Server-Sprint
TASK ID........: 47 (http://askmonty.org/worklog/?tid=47)
VERSION........: Server-9.x
STATUS.........: In-Progress
PRIORITY.......: 60
WORKED HOURS...: 40
ESTIMATE.......: 15 (hours remain)
ORIG. ESTIMATE.: 35
PROGRESS NOTES:
-=-=(Knielsen - Tue, 06 Apr 2010, 15:25)=-=-
Status updated.
--- /tmp/wklog.47.old.12734 2010-04-06 15:25:54.000000000 +0000
+++ /tmp/wklog.47.new.12734 2010-04-06 15:25:54.000000000 +0000
@@ -1 +1 @@
-Code-Review
+In-Progress
-=-=(Knielsen - Mon, 29 Mar 2010, 10:59)=-=-
Status updated.
--- /tmp/wklog.47.old.27790 2010-03-29 10:59:53.000000000 +0000
+++ /tmp/wklog.47.new.27790 2010-03-29 10:59:53.000000000 +0000
@@ -1 +1 @@
-In-Progress
+Code-Review
-=-=(Alexi - Thu, 18 Feb 2010, 19:29)=-=-
Worked 20 hours (alexi)
Worked 20 hours and estimate 15 hours remain (original estimate unchanged).
-=-=(Serg - Fri, 05 Feb 2010, 14:04)=-=-
Observers changed: Knielsen,Serg
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Category updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Server-RawIdeaBin
+Server-Sprint
-=-=(Guest - Fri, 05 Feb 2010, 13:40)=-=-
Status updated.
--- /tmp/wklog.47.old.9197 2010-02-05 13:40:36.000000000 +0200
+++ /tmp/wklog.47.new.9197 2010-02-05 13:40:36.000000000 +0200
@@ -1 +1 @@
-Un-Assigned
+In-Progress
-=-=(Alexi - Thu, 04 Feb 2010, 09:54)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.16174 2010-02-04 09:54:13.000000000 +0200
+++ /tmp/wklog.47.new.16174 2010-02-04 09:54:13.000000000 +0200
@@ -171,35 +171,20 @@
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When requesting an event, the slave should inform the master whether
-it should send Annotate_rows events or not. To that end we add a new
-BINLOG_SEND_ANNOTATE_ROWS_EVENT flag used when requesting an event:
+If the replicate-annotate-rows-events option is not set on a slave, there
+is no need for master to send Annotate_rows events to this slave. The slave
+(or mysqlbinlog in remote case), before requesting binlog dump via the
+COM_BINLOG_DUMP command, informs the master whether it should send these
+events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
+command:
+
+ case COM_BINLOG_DUMP_OPTIONS_EXT:
+ thd->binlog_dump_flags_ext= packet[0];
+ my_ok(thd);
+ break;
- #define BINLOG_DUMP_NON_BLOCK 1
- #define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2
-
- pthread_handler_t handle_slave_io(void *arg)
- { ...
- request_dump(mysql, ...);
- ...
- }
-
- int request_dump(MYSQL* mysql, ...)
- { ...
- if (opt_log_slave_updates &&
- mi->io_thd->variables.binlog_annotate_rows_events)
- binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
- ...
- int2store(buf + 4, binlog_flags);
- ...
- simple_command(mysql, COM_BINLOG_DUMP, buf, ...);
- ...
- }
-
-NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
-simple_command() function, should also use this flag if it wants (in case
-of the --print-annotate-rows-events option set) to recieve Annotate_rows
-events.
+Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
+conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -338,10 +323,4 @@
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
-Also we should notice the introduction of the BINLOG_SEND_ANNOTATE_ROWS_EVENT
-flag taking into account that MySQL/Sun may also introduce a flag with the
-same value to be used in the request_dump-mysql_binlog_send interface.
-But this is mainly the question of merging: if a conflict concerning this
-flag occur, we may simply change the BINLOG_SEND_ANNOTATE_ROWS_EVENT value
-(this does not require additional changes in the code).
-=-=(Alexi - Sun, 20 Dec 2009, 16:00)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.19667 2009-12-20 14:00:56.000000000 +0000
+++ /tmp/wklog.47.new.19667 2009-12-20 14:00:56.000000000 +0000
@@ -196,6 +196,11 @@
...
}
+NOTE. mysqlbinlog, when remotely requesting BINLOG_DUMP by calling the
+simple_command() function, should also use this flag if it wants (in case
+of the --print-annotate-rows-events option set) to recieve Annotate_rows
+events.
+
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,8 +217,7 @@
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
- flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT ||
- thd->server_id == 0 /* slave == mysqlbinlog */ )
+ flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
-=-=(Alexi - Sun, 20 Dec 2009, 13:14)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.11350 2009-12-20 13:14:04.000000000 +0200
+++ /tmp/wklog.47.new.11350 2009-12-20 13:14:04.000000000 +0200
@@ -282,23 +282,18 @@
Annotate_rows_log_event* m_annotate_event;
};
-When the saved Annotate_rows object may be deleted? When all corresponding
-Rows events will be processed, i.e. before processing the first non-Rows
-event (note that Annotate_rows object resides in the binary log *after*
-the (possible) 'BEGIN' Query event which accompanies the rows events; note
-also that this deletion is adjusted with the case when some or all
-corresponding Rows events are filtered out by replicate filter rules):
+The saved Annotate_rows object should be deleted when all corresponding
+Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
- if (rli->get_annotate_event() && !IS_RBR_EVENT_TYPE(ev->get_type_code()))
- rli->free_annotate_event();
-
apply_event_and_update_pos(ev, ...);
- if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
+ if (rli->get_annotate_event() && is_last_rows_event(ev))
+ rli->free_annotate_event();
+ else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
@@ -307,10 +302,21 @@
where
- #define IS_RBR_EVENT_TYPE(type) ( (type) == TABLE_MAP_EVENT || \
- (type) == WRITE_ROWS_EVENT || \
+ bool is_last_rows_event(Log_event* ev)
+ {
+ Log_event_type type= ev->get_type_code();
+ if (IS_ROWS_EVENT_TYPE(type))
+ {
+ Rows_log_event* rows= (Rows_log_event*)ev;
+ return rows->get_flags(Rows_log_event::STMT_END_F);
+ }
+
+ return 0;
+ }
+
+ #define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
- (type) == DELETE_ROWS_EVENT )
+ (type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
-=-=(Alexi - Sun, 20 Dec 2009, 09:29)=-=-
Low Level Design modified.
--- /tmp/wklog.47.old.32726 2009-12-20 07:29:56.000000000 +0000
+++ /tmp/wklog.47.new.32726 2009-12-20 07:29:56.000000000 +0000
@@ -56,7 +56,7 @@
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
- 00000082 | 00 | 0 - ANNOTATE_RBR_EVENT [51]
+ 00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
------------------------------------------------------------
-=-=(View All Progress Notes, 26 total)=-=-
http://askmonty.org/worklog/index.pl?tid=47&nolimit=1
DESCRIPTION:
Store in binlog (and show in mysqlbinlog output) texts of statements that
caused RBR events
This is needed for (list from Monty):
- Easier to understand why updates happened
- Would make it easier to find out where in application things went
wrong (as you can search for exact strings)
- Allow one to filter things based on comments in the statement.
The cost of this can be that the binlog will be approximately 2x in size
(especially insert of big blob's would be a bit painful), so this should
be an optional feature.
HIGH-LEVEL SPECIFICATION:
Content
~~~~~~~
1. Annotate_rows_log_event
2. Server option: --binlog-annotate-rows-events
3. Server option: --replicate-annotate-rows-events
4. mysqlbinlog option: --print-annotate-rows-events
5. mysqlbinlog output
1. Annotate_rows_log_event [ ANNOTATE_ROWS_EVENT ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Describes the query which caused the corresponding rows events. Has empty
post-header and contains the query text in its data part. Example:
************************
ANNOTATE_ROWS_EVENT
************************
00000220 | B6 A0 2C 4B | time_when = 1261215926
00000224 | 33 | event_type = 51
00000225 | 64 00 00 00 | server_id = 100
00000229 | 36 00 00 00 | event_len = 54
0000022D | 56 02 00 00 | log_pos = 00000256
00000231 | 00 00 | flags = <none>
------------------------
00000233 | 49 4E 53 45 | query = "INSERT INTO t1 VALUES (1), (2), (3)"
00000237 | 52 54 20 49 |
0000023B | 4E 54 4F 20 |
0000023F | 74 31 20 56 |
00000243 | 41 4C 55 45 |
00000247 | 53 20 28 31 |
0000024B | 29 2C 20 28 |
0000024F | 32 29 2C 20 |
00000253 | 28 33 29 |
************************
In binary log, Annotate_rows event follows the (possible) 'BEGIN' Query event
and precedes the first of Table map events which accompany the corresponding
rows events. (See example in the "mysqlbinlog output" section below.)
2. Server option: --binlog-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the master to write Annotate_rows events to the binary log.
* Variable Name: binlog_annotate_rows_events
* Scope: Global & Session
* Access Type: Dynamic
* Data Type: bool
* Default Value: OFF
NOTE. Session values allows to annotate only some selected statements:
...
SET SESSION binlog_annotate_rows_events=ON;
... statements to be annotated ...
SET SESSION binlog_annotate_rows_events=OFF;
... statements not to be annotated ...
3. Server option: --replicate-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tells the slave to reproduce Annotate_rows events recieved from the master
in its own binary log (sensible only in pair with log-slave-updates option).
* Variable Name: replicate_annotate_rows_events
* Scope: Global
* Access Type: Read only
* Data Type: bool
* Default Value: OFF
NOTE. Why do we additionally need this 'replicate' option? Why not to make
the slave to reproduce this events when its binlog-annotate-rows-events
global value is ON? Well, because, for example, we may want to configure
the slave which should reproduce Annotate_rows events but has global
binlog-annotate-rows-events = OFF meaning this to be the default value for
the client threads (see also "How slave treats replicate-annotate-rows-events
option" in LLD part).
4. mysqlbinlog option: --print-annotate-rows-events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With this option, mysqlbinlog prints the content of Annotate_rows events (if
the binary log does contain them). Without this option (i.e. by default),
mysqlbinlog skips Annotate_rows events.
5. mysqlbinlog output
~~~~~~~~~~~~~~~~~~~~~
With --print-annotate-rows-events, mysqlbinlog outputs Annotate_rows events
in a form like this:
...
# at 1646
#091219 12:45:26 server id 100 end_log_pos 1714 Query thread_id=1
exec_time=0 error_code=0
SET TIMESTAMP=1261215926/*!*/;
BEGIN
/*!*/;
# at 1714
# at 1812
# at 1853
# at 1894
# at 1938
#091219 12:45:26 server id 100 end_log_pos 1812 Query: `DELETE t1, t2 FROM
t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a`
#091219 12:45:26 server id 100 end_log_pos 1853 Table_map: `test`.`t1`
mapped to number 16
#091219 12:45:26 server id 100 end_log_pos 1894 Table_map: `test`.`t2`
mapped to number 17
#091219 12:45:26 server id 100 end_log_pos 1938 Delete_rows: table id 16
#091219 12:45:26 server id 100 end_log_pos 1982 Delete_rows: table id 17
flags: STMT_END_F
...
LOW-LEVEL DESIGN:
Content
~~~~~~~
1. Annotate_rows event number
2. Outline of Annotate_rows event behavior
3. How Master writes Annotate_rows events to the binary log
4. How slave treats replicate-annotate-rows-events option
5. How slave IO thread requests Annotate_rows events
6. How master executes the request
7. How slave SQL thread processes Annotate_rows events
8. General remarks
1. Annotate_rows event number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid possible event numbers conflict with MySQL/Sun, we leave a gap
between the last MySQL event number and the Annotate_rows event number:
enum Log_event_type
{ ...
INCIDENT_EVENT= 26,
// New MySQL event numbers are to be added here
MYSQL_EVENTS_END,
MARIA_EVENTS_BEGIN= 51,
// New Maria event numbers start from here
ANNOTATE_ROWS_EVENT= 51,
ENUM_END_EVENT
};
together with the corresponding extension of 'post_header_len' array in the
Format description event. (This extension does not affect the compatibility
of the binary log). Here is how Format description event looks like with
this extension:
************************
FORMAT_DESCRIPTION_EVENT
************************
00000004 | A1 A0 2C 4B | time_when = 1261215905
00000008 | 0F | event_type = 15
00000009 | 64 00 00 00 | server_id = 100
0000000D | 7F 00 00 00 | event_len = 127
00000011 | 83 00 00 00 | log_pos = 00000083
00000015 | 01 00 | flags = LOG_EVENT_BINLOG_IN_USE_F
------------------------
00000017 | 04 00 | binlog_ver = 4
00000019 | 35 2E 32 2E | server_ver = 5.2.0-MariaDB-alpha-debug-log
..... ...
0000004B | A1 A0 2C 4B | time_created = 1261215905
0000004F | 13 | common_header_len = 19
------------------------
post_header_len
------------------------
00000050 | 38 | 56 - START_EVENT_V3 [1]
..... ...
00000069 | 02 | 2 - INCIDENT_EVENT [26]
0000006A | 00 | 0 - RESERVED [27]
..... ...
00000081 | 00 | 0 - RESERVED [50]
00000082 | 00 | 0 - ANNOTATE_ROWS_EVENT [51]
************************
2. Outline of Annotate_rows event behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each Annotate_rows_log_event object has two private members describing the
corresponding query:
char *m_query_txt;
uint m_query_len;
When the object is created for writing to a binary log, this query is taken
from 'thd' (for short, below we omit the 'Annotate_rows_log_event::' prefix
as well as other implementation details):
Annotate_rows_log_event(THD *thd)
{
m_query_txt = thd->query();
m_query_len = thd->query_length();
}
When the object is read from a binary log, the query is taken from the buffer
containing the binary log representation of the event (this buffer is allocated
in Log_event object from which all Log events are derived):
Annotate_rows_log_event(char *buf, uint event_len,
Format_description_log_event *desc)
{
m_query_len = event_len - desc->common_header_len;
m_query_txt = buf + desc->common_header_len;
}
The events are written to the binary log by the Log_event::write() member
which calls virtual write_data_header() and write_data_body() members
("data header" and "post header" are synonym in replication terminology).
In our case, data header is empty and data body is just the query:
bool write_data_body(IO_CACHE *file)
{
return my_b_safe_write(file, (uchar*) m_query_txt, m_query_len);
}
Printing the event is just printing the query:
void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
{
my_b_printf(&pinfo->head_cache, "\tQuery: `%s`\n", m_query_txt);
}
3. How Master writes Annotate_rows events to the binary log
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The event is written to the binary log just before the group of Table_map
events which precede corresponding Rows events (one query may generate
several Table map events in the binary log, but the corresponding
Annotate_rows event must be written only once before the first Table map
event; hence the boolean variable 'with_annotate' below):
int write_locked_table_maps(THD *thd)
{ ...
bool with_annotate= thd->variables.binlog_annotate_rows_events;
...
for (uint i= 0; i < ... <number of tables> ...; ++i)
{ ...
thd->binlog_write_table_map(table, ..., with_annotate);
with_annotate= 0; // write Annotate_event not more than once
...
}
...
}
int THD::binlog_write_table_map(TABLE *table, ..., bool with_annotate)
{ ...
Table_map_log_event the_event(...);
...
if (with_annotate)
{
Annotate_rows_log_event anno(this);
mysql_bin_log.write(&anno);
}
mysql_bin_log.write(&the_event);
...
}
4. How slave treats replicate-annotate-rows-events option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The replicate-annotate-rows-events option is treated just as the session
value of the binlog_annotate_rows_events variable for the slave IO and
SQL threads. This setting is done during initialization of these threads:
pthread_handler_t handle_slave_io(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_IO);
...
}
pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd= new THD;
...
init_slave_thread(thd, SLAVE_THD_SQL);
...
}
int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{ ...
thd->variables.binlog_annotate_rows_events=
opt_replicate_annotate_rows_events;
...
}
5. How slave IO thread requests Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the replicate-annotate-rows-events option is not set on a slave, there
is no need for master to send Annotate_rows events to this slave. The slave
(or mysqlbinlog in remote case), before requesting binlog dump via the
COM_BINLOG_DUMP command, informs the master whether it should send these
events by executing the newly added COM_BINLOG_DUMP_OPTIONS_EXT server
command:
case COM_BINLOG_DUMP_OPTIONS_EXT:
thd->binlog_dump_flags_ext= packet[0];
my_ok(thd);
break;
Note. We add this new command and don't use COM_BINLOG_DUMP to avoid possible
conflicts with MySQL/Sun.
6. How master executes the request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
case COM_BINLOG_DUMP:
{ ...
flags= uint2korr(packet + 4);
...
mysql_binlog_send(thd, ..., flags);
...
}
void mysql_binlog_send(THD* thd, ..., ushort flags)
{ ...
Log_event::read_log_event(&log, packet, ...);
...
if ((*packet)[EVENT_TYPE_OFFSET + 1] != ANNOTATE_ROWS_EVENT ||
flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT)
{
my_net_write(net, packet->ptr(), packet->length());
}
...
}
7. How slave SQL thread processes Annotate_rows events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slave processes each recieved event by "applying" it, i.e. by
calling the Log_event::apply_event() function which in turn calls
the virtual do_apply_event() member specific for each type of the
event.
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev = next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
int apply_event_and_update_pos(Log_event *ev, ...)
{ ...
ev->apply_event(...);
...
}
int Log_event::apply_event(...)
{
return do_apply_event(...);
}
What does it mean to "apply" an Annotate_rows event? It means to set current
thd query to that of the described by the event, i.e. to the query which
caused the subsequent Rows events (see "How Master writes Annotate_rows
events to the binary log" to follow what happens further when the subsequent
Rows events are applied):
int Annotate_rows_log_event::do_apply_event(...)
{
thd->set_query(m_query_txt, m_query_len);
}
NOTE. I am not sure, but possibly current values of thd->query and
thd->query_length should be saved before calling set_query() and to be
restored on the Annotate_rows_log_event object deletion.
Is it really needed ?
After calling this do_apply_event() function we may not delete the
Annotate_rows_log_event object immediatedly (see exec_relay_log_event()
above) because thd->query now points to the string inside this object.
We may keep the pointer to this object in the Relay_log_info:
class Relay_log_info
{
public:
...
void set_annotate_event(Annotate_rows_log_event*);
Annotate_rows_log_event* get_annotate_event();
void free_annotate_event();
...
private:
Annotate_rows_log_event* m_annotate_event;
};
The saved Annotate_rows object should be deleted when all corresponding
Rows events will be processed:
int exec_relay_log_event(THD* thd, Relay_log_info* rli)
{ ...
Log_event *ev= next_event(rli);
...
apply_event_and_update_pos(ev, ...);
if (rli->get_annotate_event() && is_last_rows_event(ev))
rli->free_annotate_event();
else if (ev->get_type_code() == ANNOTATE_ROWS_EVENT)
rli->set_annotate_event((Annotate_rows_log_event*) ev);
else if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
...
}
where
bool is_last_rows_event(Log_event* ev)
{
Log_event_type type= ev->get_type_code();
if (IS_ROWS_EVENT_TYPE(type))
{
Rows_log_event* rows= (Rows_log_event*)ev;
return rows->get_flags(Rows_log_event::STMT_END_F);
}
return 0;
}
#define IS_ROWS_EVENT_TYPE(type) ((type) == WRITE_ROWS_EVENT || \
(type) == UPDATE_ROWS_EVENT || \
(type) == DELETE_ROWS_EVENT)
8. General remarks
~~~~~~~~~~~~~~~~~~
Kristian noticed that introducing new log event type should be coordinated
somehow with MySQL/Sun:
Kristian: The numeric code for this event must be assigned carefully.
It should be coordinated with MySQL/Sun, otherwise we can get into a
situation where MySQL uses the same numeric code for one event that
MariaDB uses for ANNOTATE_ROWS_EVENT, which would make merging the two
impossible.
Alex: I reserved about 20 numbers not to have possible conflicts
with MySQL.
Kristian: Still, I think it would be appropriate to send a polite email
to internals(a)lists.mysql.com about this and suggesting to reserve the
event number.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0
Alexi1952 <Alexi1952(a)yandex.ru> writes:
> Hi Sergey,
>
> Send you for review:
>
> 1. WL#47 branch published on:
> https://code.launchpad.net/~alexi1952/maria/maria-5.2-wl47
>
> 2. Diff file attached.
>
> 3. Commit message attached.
Hi Alexi,
Thanks for sending the patch. I did the code review as Sergey is really busy
with preparations for the User's conference.
General comments, most of them with details inline in the patch below:
I started by reading the text in MWL#47. It was _very_ nice to have detailed
description of the approach here, thanks!
The patch also looks very well worked-through.
We should run this through our Buildbot in a MWL#47 feature branch before
pushing to main, as there may be more result file updates needed in special
parts of the test suite (eg --big). I'll help you set it up when you're ready.
It seems your Windows editor (?) has added Windows line ending (CTRL-M)
characters to some of the lines in the patch. You need to fix this and remove
those extra characters.
The new COM_BINLOG_DUMP_OPTIONS_EXT will cause problems the next time MySQL
adds a new command (which will have same numeric value but different
semantics). This needs to be coordinated, which I think means we might as well
use (and coordinate) a new flag for the normal COM_BINLOG_DUMP command.
If the server does not support COM_BINLOG_DUMP_OPTIONS_EXT, this should not be
a fatal error (as it will prevent working against older MariaDB, or
MySQL). This is for both mysqlbinlog and slave thread.
I think a newline in a query will cause mysqlbinlog to output a file that
cannot be correctly read by the mysql command-line client.
I suggest adding a couple more test cases, with multi-session INSERT DELAYED,
different character sets in query, and newline in query (see detailed comments
below).
I am wondering about the --print-annotate-rows-events option for
mysqlbinlog. Maybe we should have it on by default? My reasoning is that there
is little concern about backwards compatibility, as output will only change if
the corresponding option is enabled explicitly in the server (and the extra
output is just a comment anyway). And the user may want to see the annotations
by default. What do you think?
I found it a bit unnatural to have the annotate event be logged inside the
binlog_write_table_map() method, using the extra with_annotate
parameter. Check the suggestions for how to do this differently (below), and
see if it makes sense.
Things that need fixing:
- Windows line ending issue.
- The COM_BINLOG_DUMP_OPTIONS_EXT potential conflict issue
- Extra test cases
- Newline-in-query problem
- Not fail if server does not support annotate events.
- Minor coding style, comment spelling, etc. issues.
- Full Buildbot run before pushing (I'll set it up later).
Also try to see if the other suggestions can be implemented, or if not lets
discuss.
Detailed comments inline with the patch below.
- Kristian.
> === modified file 'client/mysqlbinlog.cc'
> --- client/mysqlbinlog.cc 2010-03-15 11:51:23 +0000
> +++ client/mysqlbinlog.cc 2010-03-24 06:25:13 +0000
> @@ -128,6 +129,69 @@
> OK_STOP
> };
>
> +/**
> + Pointer to the last read Annotate_rows_log_event. Having read an
> + Annotate_rows event, we should not print it immediatedly because all
> + subsequent rbr events can be filtered away, and have to keep it for a while.
> + Also because of that when reading a remote Annotate event we have to keep
> + its binary log representation in a separately allocated buffer.
> +*/
> +static Annotate_rows_log_event *annotate_event= NULL;
> +
> +inline void free_annotate_event()
Do not make this 'inline'.
> +inline void print_annotate_event(PRINT_EVENT_INFO *print_event_info)
> +{
> + if (annotate_event)
> + {
> + annotate_event->print(result_file, print_event_info);
> + delete annotate_event; // the event should be printed not more than once
s/should be printed not more than once/should not be printed more than once/
> @@ -1673,6 +1769,16 @@
> if ((retval= check_master_version()) != OK_CONTINUE)
> DBUG_RETURN(retval);
>
> + buf[0]= 0;
> + if (opt_print_annotate_rows_events)
> + buf[0]|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
> +
> + if (simple_command(mysql, COM_BINLOG_DUMP_OPTIONS_EXT, buf, 1, 0))
> + {
> + error("Got fatal error sending the log dump options command.");
> + DBUG_RETURN(ERROR_STOP);
> + }
What if the server we are trying to dump from does not support the
COM_BINLOG_DUMP_OPTIONS_EXT command? This should not be a fatal error.
At most, it should be an error only if the user actually requested printing of
annotate_rows_events. But I think it should not be an error at all - it seems
more useful to have an option that just prints any annotate events that are
available. Maybe print a warning if the user explicitly requests this option,
no more than that I think.
And I am wondering if the opt_print_annotate_rows_events should not be on by
default in mysqlbinlog. After all, the events will only be there if they were
explicitly enabled in the database, so most likely they will be wanted, or if
not most likely they will not do much harm as they are comments only.
> === modified file 'include/mysql_com.h'
> --- include/mysql_com.h 2010-03-15 11:51:23 +0000
> +++ include/mysql_com.h 2010-03-24 06:25:13 +0000
> @@ -62,6 +62,7 @@
> COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE,
> COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE,
> COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON,
> + COM_BINLOG_DUMP_OPTIONS_EXT,
In the MWL#47 text, you explain that
"Note. We add this new command and don't use COM_BINLOG_DUMP to avoid
possible conflicts with MySQL/Sun."
But this does not avoid such conflicts, on the contrary, we will for sure get
serious problems with this the next time upstream MySQL adds _any_ command
here.
One way or the other, when extending the communication between servers and
clients, we need to coordinate with MySQL/Sun/Oracle. And given this, it is
probably better to just use COM_BINLOG_DUMP, do you agree?
(Lars Thalman actually asked if we would be willing to contribute this work
upstream, which suggests that there should be no problem getting such
coordination working).
> === modified file 'mysql-test/extra/rpl_tests/rpl_deadlock.test'
> --- mysql-test/extra/rpl_tests/rpl_deadlock.test 2009-04-03 21:33:13 +0000
> +++ mysql-test/extra/rpl_tests/rpl_deadlock.test 2010-03-24 06:25:13 +0000
> @@ -72,7 +72,7 @@
> --source include/stop_slave.inc
> DELETE FROM t2;
> # Set slave position to the BEGIN log event
> ---replace_result $master_pos_begin MASTER_POS_BEGIN
> +--replace_result $master_pos_begin <master_pos_begin>
Why this change?
> === added file 'mysql-test/extra/rpl_tests/rpl_row_annotate.test'
> --- mysql-test/extra/rpl_tests/rpl_row_annotate.test 1970-01-01 00:00:00 +0000
> +++ mysql-test/extra/rpl_tests/rpl_row_annotate.test 2010-03-24 06:25:13 +0000
> +INSERT DELAYED INTO t2 VALUES (1,1), (2,2), (3,3);
Add to this test to do INSERT DELAYED from two extra connections, one of which
has binlog_annotate_rows_events set and one which does not.
> +INSERT INTO t3 VALUES (1,1), (2,2), (3,3);
> +DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a;
> +
> +INSERT INTO xt1 VALUES (1,1), (2,2), (3,3);
> +INSERT INTO t2 VALUES (1,1), (2,2), (3,3);
> +DELETE xt1, t2 FROM xt1 INNER JOIN t2 INNER JOIN t3 WHERE xt1.a=t2.a AND t2.a=t3.a;
> +
> +INSERT INTO xt1 VALUES (1,1), (2,2), (3,3);
> +INSERT INTO xt2 VALUES (1,1), (2,2), (3,3);
> +DELETE xt1, xt2 FROM xt1 INNER JOIN xt2 INNER JOIN t3 WHERE xt1.a=xt2.a AND xt2.a=t3.a;
Also add tests with a query containing linefeed and other special characters
(eg. insert of blob value and varchar with special character set), to test the
annotation of such queries.
> === added file 'mysql-test/include/binlog_start_pos.inc'
> --- mysql-test/include/binlog_start_pos.inc 1970-01-01 00:00:00 +0000
> +++ mysql-test/include/binlog_start_pos.inc 2010-03-24 06:25:13 +0000
> @@ -0,0 +1,5 @@
> +let $binlog_start_pos=240;
> +--disable_query_log
> +SET @binlog_start_pos=240;
> +--enable_query_log
> +
It would be nice with a short comment explaining what this include file does
and the magic value 240.
(I think what you've tried to do is to clean up this stuff a bit so that the
next change of format_description_event will be easier to integrate in the
test suite, which is good! So just requesting a short explanation here).
> === added file 'mysql-test/suite/binlog/r/binlog_row_annotate.result'
> --- mysql-test/suite/binlog/r/binlog_row_annotate.result 1970-01-01 00:00:00 +0000
> +++ mysql-test/suite/binlog/r/binlog_row_annotate.result 2010-03-24 06:25:13 +0000
> +/*!*/;
> +# at #
> +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
> +SET TIMESTAMP=1000000000/*!*/;
> +BEGIN
> +/*!*/;
> +# at #
> +# at #
> +# at #
> +# at #
> +# at #
> +#010909 4:46:40 server id # end_log_pos # Query: `DELETE test1.t1, test2.t2
> +FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3
> +WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a`
Right, here we see the problem ... this will cause an error if one tries to
apply this mysqlbinlog output to a server.
> === added file 'mysql-test/suite/binlog/t/binlog_row_annotate.test'
> --- mysql-test/suite/binlog/t/binlog_row_annotate.test 1970-01-01 00:00:00 +0000
> +++ mysql-test/suite/binlog/t/binlog_row_annotate.test 2010-03-24 06:25:14 +0000
> +--echo #
> +--echo #####################################################################################
> +--echo # mysqlbinlog --read-from-remote-server --print-annotate-rows-events
> +--echo # Only two Annotates should appear below:
> +--echo # The following Annotates should appear in this output:
These two lines of comment seem to contradict each other? Please fix/clarify.
> === modified file 'sql/handler.cc'
> --- sql/handler.cc 2010-03-15 11:51:23 +0000
> +++ sql/handler.cc 2010-03-24 06:25:16 +0000
> @@ -4594,7 +4594,8 @@
>
> /** @brief
> Write table maps for all (manually or automatically) locked tables
> - to the binary log.
> + to the binary log. Also, if binlog_annotate_rows_events is ON,
You have ^M (chr 13) Windows line endings in this line, and in others. Please
check the patch and remove all Windows line endings introduced.
> @@ -4648,7 +4652,8 @@
> check_table_binlog_row_based(thd, table))
> {
> int const has_trans= table->file->has_transactions();
> - int const error= thd->binlog_write_table_map(table, has_trans);
> + int const error= thd->binlog_write_table_map(table, has_trans,
> + &with_annotate);
I think we can avoid the extra complexity with passing the with_annotate
parameter.
Couldn't we write the annotate_rows_event _after_ the table maps? Then there
could just be a call to mysql_bin_log.write(Annotate_rows_log_event(thd))
after the loop that writes the table maps. (In fact if we moved the
"if (thd->get_binlog_table_maps() == 0)" from write_locked_table_maps() into
the caller binlog_log_row(), the writing of Annotate_rows_log_event could also
be moved there, which seems to me to be the natural place to put it).
Or is there some reason that the annotate event must come before the table
maps? If so, we can still avoid the with_annotate flag, but we need this
before the loop writing the table maps:
if (is_trans)
binlog_start_trans_and_stmt();
mysql_bin_log.write(Annotate_rows_log_event(thd))
> === modified file 'sql/log_event.cc'
> --- sql/log_event.cc 2010-03-15 11:51:23 +0000
> +++ sql/log_event.cc 2010-03-24 06:25:16 +0000
> +Annotate_rows_log_event::Annotate_rows_log_event(const char *buf,
> + uint event_len,
> + const Format_description_log_event *desc)
> + : Log_event(buf, desc),
> + m_save_thd_query_txt(0),
> + m_save_thd_query_len(0)
> +{
> + m_query_len= event_len - desc->common_header_len;
> + m_query_txt= (char*) buf + desc->common_header_len;
Instead of this cast, couldn't we make the m_query_txt member a const char * ?
(from a quick check of the patch, it seems we can).
> +}
> +
> +Annotate_rows_log_event::~Annotate_rows_log_event()
> +{
> +#ifndef MYSQL_CLIENT
> + if (m_save_thd_query_txt)
> + thd->set_query(m_save_thd_query_txt, m_save_thd_query_len);
> +#endif
> +}
I don't like this, it's much too magic that thd->query can change in the
destructor of a completely unrelated object.
I would suggest instead putting in explicit code to restore thd->query in the
places where it needs to be done (you can have a
Annotate_rows_log_event::restore_thd_query() method for that). This makes it
explicit in the code where the restoration happens.
But actually, I am wondering if it would be better not to change thd->query at
all? And instead just pick the query from a saved annotate_rows_log_event when
needed? But I haven't checked the code sufficient to see if this can be done
in a clean way, so think about it, and see if it makes sense.
> +#ifdef MYSQL_CLIENT
> +void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
> +{
> + if (!pinfo->short_form)
> + {
> + print_header(&pinfo->head_cache, pinfo, TRUE);
> + my_b_printf(&pinfo->head_cache, "\tQuery: `%s`\n", m_query_txt);
> + }
> +}
> +#endif
I think this will cause problems if the query contains linefeed characters,
right? The mysqlbinlog output will span multiple lines which will not be
marked as comment lines, so trying to apply the output (by piping through
`mysql`) will fail with a syntax error (or worse).
It seems to me we need some kind of quoting here.
Also, I see that mysqlbinlog is careful to make the query string zero
terminated (as required by my_b_printf("%s"), but that's a bit subtle. So
maybe that could also be avoided if some kind of quoting is enabled, or
alternatively add a comment about this zero-termination requirement for
Annotate_rows_log_event::print().
> === modified file 'sql/mysql_priv.h'
> --- sql/mysql_priv.h 2010-03-15 11:51:23 +0000
> +++ sql/mysql_priv.h 2010-03-24 06:25:17 +0000
> @@ -624,7 +624,12 @@
> /* BINLOG_DUMP options */
>
> #define BINLOG_DUMP_NON_BLOCK 1
> -
> +#endif //MYSQL_CLIENT
Make this #endif /* !MYSQL_CLIENT */
(as it is a negative test that this #endif ends)
> +
> +/* Extended BINLOG_DUMP options (passed to COM_BINLOG_DUMP_OPTIONS_EXT) */
> +#define BINLOG_SEND_ANNOTATE_ROWS_EVENT 1
> +
> +#ifndef MYSQL_CLIENT
> /* sql_show.cc:show_log_files() */
> #define SHOW_LOG_STATUS_FREE "FREE"
> #define SHOW_LOG_STATUS_INUSE "IN USE"
> === modified file 'sql/slave.cc'
> --- sql/slave.cc 2010-03-04 08:03:07 +0000
> +++ sql/slave.cc 2010-03-24 06:25:18 +0000
> @@ -1829,6 +1829,36 @@
> }
>
>
> +static int set_master_binlog_dump_options_ext(MYSQL *mysql,
> + bool *suppress_warnings)
> +{
> + uchar buf[1];
> + uchar flags= 0;
> + DBUG_ENTER("set_master_binlog_dump_options_ext");
> +
> + *suppress_warnings= FALSE;
> +
> + if (opt_log_slave_updates && opt_replicate_annotate_rows_events)
> + flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
> +
> + buf[0]= flags;
> +
> + if (simple_command(mysql, COM_BINLOG_DUMP_OPTIONS_EXT, buf, 1, 0))
> + {
> + if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
> + *suppress_warnings= TRUE;
> + else
> + sql_print_error("Error on COM_BINLOG_DUMP_OPTIONS_EXT: %d %s,"
> + " will retry in %d secs",
> + mysql_errno(mysql), mysql_error(mysql),
> + master_connect_retry);
> + DBUG_RETURN(1);
> + }
This will break replication from a master that does not know the
COM_BINLOG_DUMP_OPTIONS_EXT command. We could maybe log a warning in this
case (saying that query annotation is not available from master), but we
should not fail I think.
> +
> + DBUG_RETURN(0);
> +}
> @@ -2234,16 +2264,33 @@
> }
> exec_res= apply_event_and_update_pos(ev, thd, rli);
>
> - /*
> - Format_description_log_event should not be deleted because it will be
> - used to read info about the relay log's format; it will be deleted when
> - the SQL thread does not need it, i.e. when this thread terminates.
> - */
> - if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
> - {
> - DBUG_PRINT("info", ("Deleting the event after it has been executed"));
> - delete ev;
> - }
> + switch (ev->get_type_code()) {
> + case FORMAT_DESCRIPTION_EVENT:
> + // Format_description_log_event should not be deleted because it
> + // will be used to read info about the relay log's format;
> + // it will be deleted when the SQL thread does not need it,
> + // i.e. when this thread terminates.
> + break;
According to coding style, multi-line comments should use C-style /* ... */,
not C++-style //
http://forge.mysql.com/wiki/MySQL_Internals_Coding_Guidelines#Commenting_Co…
(Should be changed here and in several other places where it occurs).
> + case ANNOTATE_ROWS_EVENT:
> + // Annotate_rows event should not be deleted because after it has
> + // been applied, thd->query points to the string inside this event.
> + // The thd->query will be used to generate new Annotate_rows event
> + // during applying the subsequent Rows events.
> + rli->set_annotate_event((Annotate_rows_log_event*) ev);
> + break;
> + case DELETE_ROWS_EVENT:
> + case UPDATE_ROWS_EVENT:
> + case WRITE_ROWS_EVENT:
> + // After the last Rows event has been applied, the saved Annotate_rows
> + // event (if any) is not needed anymore and can be deleted.
> + if (((Rows_log_event*)ev)->get_flags(Rows_log_event::STMT_END_F))
> + rli->free_annotate_event();
This seems a natural place to explicitly restore thd->query rather than inside
the annotate event destructor (if such restoration is really needed).
> + /* fall through */
> + default:
> + DBUG_PRINT("info", ("Deleting the event after it has been executed"));
> + delete ev;
> + break;
> + }
1
0

[Maria-developers] Updated (by Serg): pluggable authentication (101)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: pluggable authentication
CREATION DATE..: Tue, 09 Mar 2010, 14:58
SUPERVISOR.....: Sergei
IMPLEMENTOR....: Sergei
COPIES TO......:
CATEGORY.......: Server-Sprint
TASK ID........: 101 (http://askmonty.org/worklog/?tid=101)
VERSION........: Server-5.2
STATUS.........: Complete
PRIORITY.......: 90
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
-=-=(Serg - Tue, 06 Apr 2010, 13:18)=-=-
Status updated.
--- /tmp/wklog.101.old.1262 2010-04-06 13:18:00.000000000 +0000
+++ /tmp/wklog.101.new.1262 2010-04-06 13:18:00.000000000 +0000
@@ -1 +1 @@
-Code-Review
+Complete
DESCRIPTION:
push the pluggable authentication feature
https://code.launchpad.net/~maria-captains/maria/5.2-pluggable-auth
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Updated (by Serg): pluggable authentication (101)
by worklog-noreply@askmonty.org 06 Apr '10
by worklog-noreply@askmonty.org 06 Apr '10
06 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: pluggable authentication
CREATION DATE..: Tue, 09 Mar 2010, 14:58
SUPERVISOR.....: Sergei
IMPLEMENTOR....: Sergei
COPIES TO......:
CATEGORY.......: Server-Sprint
TASK ID........: 101 (http://askmonty.org/worklog/?tid=101)
VERSION........: Server-5.2
STATUS.........: Complete
PRIORITY.......: 90
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
-=-=(Serg - Tue, 06 Apr 2010, 13:18)=-=-
Status updated.
--- /tmp/wklog.101.old.1262 2010-04-06 13:18:00.000000000 +0000
+++ /tmp/wklog.101.new.1262 2010-04-06 13:18:00.000000000 +0000
@@ -1 +1 @@
-Code-Review
+Complete
DESCRIPTION:
push the pluggable authentication feature
https://code.launchpad.net/~maria-captains/maria/5.2-pluggable-auth
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Rev 2775: keep acl_user->auth_string and acl_user->salt always in sync in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 06 Apr '10
by serg@askmonty.org 06 Apr '10
06 Apr '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2775
revision-id: sergii(a)pisem.net-20100406110456-zhkf13tvdcywb9tb
parent: sergii(a)pisem.net-20100406110224-0wtdkmquq8wmdfer
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: 5.2
timestamp: Tue 2010-04-06 13:04:56 +0200
message:
keep acl_user->auth_string and acl_user->salt always in sync
print authenticated via in show grants
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-04-05 09:50:31 +0000
+++ b/sql/sql_acl.cc 2010-04-06 11:04:56 +0000
@@ -287,9 +287,8 @@ static void init_check_host(void);
static void rebuild_check_host(void);
static ACL_USER *find_acl_user(const char *host, const char *user,
my_bool exact);
-static bool update_user_table(THD *thd, TABLE *table,
- const char *host, const char *user,
- const char *new_password, uint new_password_len);
+static bool update_user_table(THD *, TABLE *, const char *, const char *,
+ const char *, uint);
static void update_hostname(acl_host_and_ip *host, const char *hostname);
static bool compare_hostname(const acl_host_and_ip *host,const char *hostname,
const char *ip);
@@ -1161,7 +1160,12 @@ static void acl_update_user(const char *
acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length);
}
else
- set_user_salt(acl_user, password, password_len);
+ if (password)
+ {
+ acl_user->auth_string.str= strmake_root(&mem, password, password_len);
+ acl_user->auth_string.length= password_len;
+ set_user_salt(acl_user, password, password_len);
+ }
acl_user->access=privileges;
if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
acl_user->user_resource.questions=mqh->questions;
@@ -1611,7 +1615,13 @@ bool change_password(THD *thd, const cha
goto end;
}
/* update loaded acl entry: */
- set_user_salt(acl_user, new_password, new_password_len);
+ if (acl_user->plugin.str == native_password_plugin_name.str ||
+ acl_user->plugin.str == old_password_plugin_name.str)
+ {
+ acl_user->auth_string.str= strmake_root(&mem, new_password, new_password_len);
+ acl_user->auth_string.length= new_password_len;
+ set_user_salt(acl_user, new_password, new_password_len);
+ }
if (update_user_table(thd, table,
acl_user->host.hostname ? acl_user->host.hostname : "",
@@ -4642,16 +4652,27 @@ bool mysql_show_grants(THD *thd,LEX_USER
global.append(lex_user->host.str,lex_user->host.length,
system_charset_info);
global.append ('\'');
- if (acl_user->salt_len)
+ if (acl_user->plugin.str == native_password_plugin_name.str ||
+ acl_user->plugin.str == old_password_plugin_name.str)
{
- char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
- if (acl_user->salt_len == SCRAMBLE_LENGTH)
- make_password_from_salt(passwd_buff, acl_user->salt);
- else
- make_password_from_salt_323(passwd_buff, (ulong *) acl_user->salt);
- global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '"));
- global.append(passwd_buff);
- global.append('\'');
+ if (acl_user->auth_string.length)
+ {
+ DBUG_ASSERT(acl_user->salt_len);
+ global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '"));
+ global.append(acl_user->auth_string.str, acl_user->auth_string.length);
+ global.append('\'');
+ }
+ }
+ else
+ {
+ global.append(STRING_WITH_LEN(" IDENTIFIED VIA "));
+ global.append(acl_user->plugin.str, acl_user->plugin.length);
+ if (acl_user->auth_string.length)
+ {
+ global.append(STRING_WITH_LEN(" USING '"));
+ global.append(acl_user->auth_string.str, acl_user->auth_string.length);
+ global.append('\'');
+ }
}
/* "show grants" SSL related stuff */
if (acl_user->ssl_type == SSL_TYPE_ANY)
1
0

[Maria-developers] Rev 2774: fix a warning in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 06 Apr '10
by serg@askmonty.org 06 Apr '10
06 Apr '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2774
revision-id: sergii(a)pisem.net-20100406110224-0wtdkmquq8wmdfer
parent: igor(a)askmonty.org-20100406065639-w39nrood9amqc5zk
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: 5.2
timestamp: Tue 2010-04-06 13:02:24 +0200
message:
fix a warning
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2010-04-06 02:08:10 +0000
+++ b/mysys/mf_keycache.c 2010-04-06 11:02:24 +0000
@@ -5207,7 +5207,7 @@ int init_partitioned_key_cache(PARTITION
my_free(partition, MYF(0));
partition= 0;
}
- if (i == 0 && cnt < 0 || i > 0)
+ if ((i == 0 && cnt < 0) || i > 0)
{
/*
Here we have two cases:
1
0

[Maria-developers] Rev 2792: MWL#90: Subqueries: Inside-out execution for non-semijoin materialized in file:///home/psergey/dev/maria-5.3-subqueries-r12/
by Sergey Petrunya 06 Apr '10
by Sergey Petrunya 06 Apr '10
06 Apr '10
At file:///home/psergey/dev/maria-5.3-subqueries-r12/
------------------------------------------------------------
revno: 2792
revision-id: psergey(a)askmonty.org-20100406103533-0upq6g7sse9sjstz
parent: psergey(a)askmonty.org-20100406091710-xamea3aolh3rdspu
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.3-subqueries-r12
timestamp: Tue 2010-04-06 14:35:33 +0400
message:
MWL#90: Subqueries: Inside-out execution for non-semijoin materialized
subqueries that are AND-parts of the WHERE
- Make test results handle same-cost QEP races
=== modified file 'mysql-test/r/subselect_mat.result'
--- a/mysql-test/r/subselect_mat.result 2010-04-05 20:16:45 +0000
+++ b/mysql-test/r/subselect_mat.result 2010-04-06 10:35:33 +0000
@@ -98,9 +98,9 @@
explain extended
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 3 100.00
-1 PRIMARY t1i ref it1i1,it1i3 it1i3 9 materialized subselect.b1 1 100.00 Using index
-2 SUBQUERY t2i range it2i1,it2i3 it2i1 9 NULL 3 100.00 Using where; Using index for group-by
+1 PRIMARY SUBQUERY#2 ALL distinct_key # NULL # 3 100.00 #
+1 PRIMARY t1i ref it1i1,it1i3 # 9 # 1 100.00 #
+2 SUBQUERY t2i range it2i1,it2i3 # 9 # 3 100.00 #
Warnings:
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where (`test`.`t1i`.`a1` = `materialized subselect`.`b1`)
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
@@ -122,9 +122,9 @@
explain extended
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 3 100.00
-1 PRIMARY t1i ref it1i1,it1i2,it1i3 it1i3 18 materialized subselect.b1,materialized subselect.b2 1 100.00 Using index
-2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+1 PRIMARY SUBQUERY#2 ALL distinct_key # # # 3 100.00 #
+1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
+2 SUBQUERY t2i range it2i1,it2i3 # # # 3 100.00 #
Warnings:
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`test`.`t1i`.`a2` = `materialized subselect`.`b2`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`))
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
@@ -134,9 +134,9 @@
explain extended
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 3 100.00
-1 PRIMARY t1i ref it1i1,it1i2,it1i3 it1i3 18 materialized subselect.b1,materialized subselect.min(b2) 1 100.00 Using index
-2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+1 PRIMARY SUBQUERY#2 ALL distinct_key # # # 3 100.00 #
+1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
+2 SUBQUERY t2i range it2i1,it2i3 # # # 3 100.00 #
Warnings:
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,min(`test`.`t2i`.`b2`) AS `min(b2)` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`test`.`t1i`.`a2` = `materialized subselect`.`min(b2)`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`))
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
@@ -307,13 +307,13 @@
(a1, a2) in (select c1, c2 from t3i
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 5 0.00
-1 PRIMARY SUBQUERY#3 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
-1 PRIMARY t1i ref it1i1,it1i2,it1i3 it1i3 18 materialized subselect.b1,materialized subselect.c2 1 100.00 Using where; Using index
-3 SUBQUERY t3i index it3i1,it3i2,it3i3 it3i3 18 NULL 4 100.00 Using index
-3 SUBQUERY SUBQUERY#4 eq_ref distinct_key distinct_key 18 test.t3i.c1,test.t3i.c2 1 100.00
-4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
-2 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
+1 PRIMARY SUBQUERY#2 ALL distinct_key # # # 5 0.00 #
+1 PRIMARY SUBQUERY#3 eq_ref distinct_key # # # 1 100.00 #
+1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
+3 SUBQUERY t3i index it3i1,it3i2,it3i3 # # # 4 100.00 #
+3 SUBQUERY SUBQUERY#4 eq_ref distinct_key # # # 1 100.00 #
+4 SUBQUERY t2i index it2i2 # # # 5 100.00 #
+2 SUBQUERY t2i index it2i1,it2i3 # # # 5 100.00 #
Warnings:
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3i` where ((`materialized subselect`.`b2` = `test`.`t3i`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3i`.`c1`))) join <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`))
select * from t1i
@@ -392,23 +392,23 @@
(a1, a2) in (select c1, c2 from t3i
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 5 0.00
-1 PRIMARY SUBQUERY#5 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
-5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00
-5 SUBQUERY SUBQUERY#6 eq_ref distinct_key distinct_key 18 test.t3.c1,test.t3.c2 1 100.00
-6 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-7 UNION SUBQUERY#8 ALL distinct_key NULL NULL NULL 5 0.00
-7 UNION SUBQUERY#9 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
-7 UNION t1i ref it1i1,it1i2,it1i3 it1i3 18 materialized subselect.b1,materialized subselect.c2 1 100.00 Using where; Using index
-9 SUBQUERY t3i index it3i1,it3i2,it3i3 it3i3 18 NULL 4 100.00 Using index
-9 SUBQUERY SUBQUERY#10 eq_ref distinct_key distinct_key 18 test.t3i.c1,test.t3i.c2 1 100.00
-10 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
-8 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
-NULL UNION RESULT <union1,7> ALL NULL NULL NULL NULL NULL NULL
+1 PRIMARY SUBQUERY#2 ALL distinct_key # # # 5 0.00 #
+1 PRIMARY SUBQUERY#5 eq_ref distinct_key # # # 1 100.00 #
+1 PRIMARY t1 ALL NULL # # # 3 100.00 #
+5 SUBQUERY t3 ALL NULL # # # 4 100.00 #
+5 SUBQUERY SUBQUERY#6 eq_ref distinct_key # # # 1 100.00 #
+6 SUBQUERY t2i index it2i2 # # # 5 100.00 #
+2 SUBQUERY t2 ALL NULL # # # 5 100.00 #
+4 SUBQUERY t3 ALL NULL # # # 4 100.00 #
+3 SUBQUERY t3 ALL NULL # # # 4 100.00 #
+7 UNION SUBQUERY#8 ALL distinct_key # # # 5 0.00 #
+7 UNION SUBQUERY#9 eq_ref distinct_key # # # 1 100.00 #
+7 UNION t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
+9 SUBQUERY t3i index it3i1,it3i2,it3i3 # # # 4 100.00 #
+9 SUBQUERY SUBQUERY#10 eq_ref distinct_key # # # 1 100.00 #
+10 SUBQUERY t2i index it2i2 # # # 5 100.00 #
+8 SUBQUERY t2i index it2i1,it2i3 # # # 5 100.00 #
+NULL UNION RESULT <union1,7> ALL NULL # # # NULL NULL #
Warnings:
Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>
(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a1` = `materialized subselect`.`b1`))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3i` where ((`materialized subselect`.`b2` = `test`.`t3i`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3i`.`c1`))) join <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i
` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`)))
(select * from t1
=== modified file 'mysql-test/t/subselect_mat.test'
--- a/mysql-test/t/subselect_mat.test 2010-04-05 20:16:45 +0000
+++ b/mysql-test/t/subselect_mat.test 2010-04-06 10:35:33 +0000
@@ -75,18 +75,21 @@
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
-explain extended
-select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
-select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
-
-explain extended
-select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
-select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
-
-explain extended
-select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
-select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
-
+--replace_column 6 # 8 # 11 #
+explain extended
+select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+
+--replace_column 6 # 7 # 8 # 11 #
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+
+--replace_column 6 # 7 # 8 # 11 #
explain extended
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
@@ -174,6 +177,7 @@
(a1, a2) in (select c1, c2 from t3
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+--replace_column 6 # 7 # 8 # 11 #
explain extended
select * from t1i
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
@@ -215,6 +219,7 @@
# multiple levels of nesting subqueries, unions
+--replace_column 6 # 7 # 8 # 11 #
explain extended
(select * from t1
where (a1, a2) in (select b1, b2 from t2
1
0

[Maria-developers] Rev 2791: MWL#90: Subqueries: Inside-out execution for non-semijoin materialized in file:///home/psergey/dev/maria-5.3-subqueries-r12/
by Sergey Petrunya 06 Apr '10
by Sergey Petrunya 06 Apr '10
06 Apr '10
At file:///home/psergey/dev/maria-5.3-subqueries-r12/
------------------------------------------------------------
revno: 2791
revision-id: psergey(a)askmonty.org-20100406091710-xamea3aolh3rdspu
parent: psergey(a)askmonty.org-20100406083401-36tcbqvit0wtilcx
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.3-subqueries-r12
timestamp: Tue 2010-04-06 13:17:10 +0400
message:
MWL#90: Subqueries: Inside-out execution for non-semijoin materialized
subqueries that are AND-parts of the WHERE
- Update test results
=== modified file 'mysql-test/r/metadata.result'
--- a/mysql-test/r/metadata.result 2008-10-10 11:44:10 +0000
+++ b/mysql-test/r/metadata.result 2010-04-06 09:17:10 +0000
@@ -55,7 +55,7 @@
2 female no
select t1.id from t1 union select t2.id from t2;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def id id 1 4 1 Y 32768 0 63
+def id id 1 4 1 Y 49152 0 63
id
1
2
@@ -66,7 +66,7 @@
set @arg00=1 ;
select @arg00 FROM t1 where a=1 union distinct select 1 FROM t1 where a=1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def @arg00 @arg00 8 20 1 Y 32768 0 63
+def @arg00 @arg00 8 20 1 Y 49152 0 63
@arg00
1
select * from (select @arg00) aaa;
@@ -76,7 +76,7 @@
1
select 1 union select 1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def 1 1 8 20 1 N 32769 0 63
+def 1 1 8 20 1 N 49153 0 63
1
1
select * from (select 1 union select 1) aaa;
=== modified file 'mysql-test/suite/pbxt/r/metadata.result'
--- a/mysql-test/suite/pbxt/r/metadata.result 2009-04-02 10:03:14 +0000
+++ b/mysql-test/suite/pbxt/r/metadata.result 2010-04-06 09:17:10 +0000
@@ -55,7 +55,7 @@
2 female no
select t1.id from t1 union select t2.id from t2;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def id id 1 4 1 Y 32768 0 63
+def id id 1 4 1 Y 49152 0 63
id
1
2
@@ -66,7 +66,7 @@
set @arg00=1 ;
select @arg00 FROM t1 where a=1 union distinct select 1 FROM t1 where a=1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def @arg00 @arg00 8 20 1 Y 32768 0 63
+def @arg00 @arg00 8 20 1 Y 49152 0 63
@arg00
1
select * from (select @arg00) aaa;
@@ -76,7 +76,7 @@
1
select 1 union select 1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def 1 1 8 20 1 N 32769 0 63
+def 1 1 8 20 1 N 49153 0 63
1
1
select * from (select 1 union select 1) aaa;
1
0

[Maria-developers] Rev 2790: MWL#90: Subqueries: Inside-out execution for non-semijoin materialized in file:///home/psergey/dev/maria-5.3-subqueries-r12/
by Sergey Petrunya 06 Apr '10
by Sergey Petrunya 06 Apr '10
06 Apr '10
At file:///home/psergey/dev/maria-5.3-subqueries-r12/
------------------------------------------------------------
revno: 2790
revision-id: psergey(a)askmonty.org-20100406083401-36tcbqvit0wtilcx
parent: psergey(a)askmonty.org-20100406081058-ihhw7esolj0mzc9a
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.3-subqueries-r12
timestamp: Tue 2010-04-06 12:34:01 +0400
message:
MWL#90: Subqueries: Inside-out execution for non-semijoin materialized
subqueries that are AND-parts of the WHERE
- Update test results (checked, we get 0 because the subquery is actually
evaluated by the EXPLAIN).
=== modified file 'mysql-test/r/myisam_mrr.result'
--- a/mysql-test/r/myisam_mrr.result 2010-03-11 21:43:31 +0000
+++ b/mysql-test/r/myisam_mrr.result 2010-04-06 08:34:01 +0000
@@ -347,7 +347,7 @@
);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-2 SUBQUERY t2 ALL int_key int_key 5 3 33.33 Using index condition; Using filesort
+2 SUBQUERY t2 ALL int_key int_key 5 0 0.00 Using index condition; Using filesort
Warnings:
Note 1003 select min(`test`.`t1`.`pk`) AS `MIN(t1.pk)` from `test`.`t1` where 0
DROP TABLE t1, t2;
1
0

[Maria-developers] Rev 2789: MWL#90: Subqueries: Inside-out execution for in file:///home/psergey/dev/maria-5.3-subqueries-r12/
by Sergey Petrunya 06 Apr '10
by Sergey Petrunya 06 Apr '10
06 Apr '10
At file:///home/psergey/dev/maria-5.3-subqueries-r12/
------------------------------------------------------------
revno: 2789
revision-id: psergey(a)askmonty.org-20100406081058-ihhw7esolj0mzc9a
parent: psergey(a)askmonty.org-20100405201645-kuavh2rxc9whflc0
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.3-subqueries-r12
timestamp: Tue 2010-04-06 12:10:58 +0400
message:
MWL#90: Subqueries: Inside-out execution for
non-semijoin materialized subqueries that are AND-parts of the WHERE
- Update test results.
=== modified file 'mysql-test/r/group_min_max.result'
--- a/mysql-test/r/group_min_max.result 2010-04-05 20:16:45 +0000
+++ b/mysql-test/r/group_min_max.result 2010-04-06 08:10:58 +0000
@@ -2255,7 +2255,7 @@
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY SUBQUERY#2 ALL NULL NULL NULL NULL 8
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 8
1 PRIMARY t1_outer ref a a 5 materialized subselect.max(b) 2 Using index
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
=== modified file 'mysql-test/r/having.result'
--- a/mysql-test/r/having.result 2010-04-05 20:16:45 +0000
+++ b/mysql-test/r/having.result 2010-04-06 08:10:58 +0000
@@ -249,11 +249,11 @@
group by t2.col1, t2.col2 having t2.col1 <= 10);
col1
10
-10
-10
20
30
10
+10
+10
select t1.col1 from t1
where t1.col2 in
(select t2.col2 from t2
@@ -262,11 +262,11 @@
(select min(t3.col1) from t3));
col1
10
-10
-10
20
30
10
+10
+10
select t1.col1 from t1
where t1.col2 in
(select t2.col2 from t2
=== modified file 'mysql-test/r/view.result'
--- a/mysql-test/r/view.result 2010-03-20 12:01:47 +0000
+++ b/mysql-test/r/view.result 2010-04-06 08:10:58 +0000
@@ -303,7 +303,7 @@
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
-2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using filesort
drop view v1;
drop table t1;
create table t1 (a int);
=== modified file 'mysql-test/suite/pbxt/r/group_min_max.result'
--- a/mysql-test/suite/pbxt/r/group_min_max.result 2010-03-20 12:01:47 +0000
+++ b/mysql-test/suite/pbxt/r/group_min_max.result 2010-04-06 08:10:58 +0000
@@ -2256,7 +2256,8 @@
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_outer index NULL a 10 NULL 15 Using where; Using index
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 15
+1 PRIMARY t1_outer ref a a 5 materialized subselect.max(b) 1 Using index
2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
=== modified file 'mysql-test/suite/pbxt/r/partition_hash.result'
--- a/mysql-test/suite/pbxt/r/partition_hash.result 2009-04-02 10:03:14 +0000
+++ b/mysql-test/suite/pbxt/r/partition_hash.result 2010-04-06 08:10:58 +0000
@@ -57,25 +57,25 @@
1 SIMPLE t1 p0,p1,p2,p3 ALL NULL NULL NULL NULL 9 Using where
explain partitions select * from t1 where a is null or (a >= 5 and a <= 7);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p2,p3 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p0,p2,p3 ALL NULL NULL NULL NULL 7 Using where
explain partitions select * from t1 where a is null;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t1 where a is not null;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0,p1,p2,p3 ALL NULL NULL NULL NULL 9 Using where
explain partitions select * from t1 where a >= 1 and a < 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 5 Using where
explain partitions select * from t1 where a >= 3 and a <= 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t1 where a > 2 and a < 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a > 3 and a <= 6;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t1 where a > 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0,p1,p2,p3 ALL NULL NULL NULL NULL 9 Using where
=== modified file 'mysql-test/suite/pbxt/r/partition_pruning.result'
--- a/mysql-test/suite/pbxt/r/partition_pruning.result 2010-03-20 12:01:47 +0000
+++ b/mysql-test/suite/pbxt/r/partition_pruning.result 2010-04-06 08:10:58 +0000
@@ -14,7 +14,7 @@
1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a=2;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a=1 or a=2;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 3 Using where
@@ -31,7 +31,7 @@
1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t2 where a=1 and b=1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 2 Using where
create table t3 (
a int
)
@@ -42,16 +42,16 @@
insert into t3 values (5),(15);
explain partitions select * from t3 where a=11;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 p1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t3 p1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t3 where a=10;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 p1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t3 p1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t3 where a=20;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t3 where a=30;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where
create table t4 (a int not null, b int not null) partition by LIST (a+b) (
partition p0 values in (12),
partition p1 values in (14)
@@ -59,11 +59,11 @@
insert into t4 values (10,2), (10,4);
explain partitions select * from t4 where (a=10 and b=1) or (a=10 and b=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 p0 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t4 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t4
where (a=10 and b=1) or (a=10 and b=2) or (a=10 and b = 3);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 p0 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t4 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t4 where (a=10 and b=2) or (a=10 and b=3)
or (a=10 and b = 4);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -89,25 +89,25 @@
explain partitions select * from t5
where (a=10 and b=1) or (a=10 and b=2) or (a=10 and b = 3);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t5 where (a=10 and b=2) or (a=10 and b=3)
or (a=10 and b = 4);
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t5 where (c=1 and d=1);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp0,p1_p1sp0 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp0,p1_p1sp0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t5 where (c=2 and d=1);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t5 where (a=10 and b=2 and c=1 and d=1) or
(c=2 and d=1);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t5 where (a=10 and b=2 and c=1 and d=1) or
(b=2 and c=2 and d=1);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 3 Using where
create table t6 (a int not null) partition by LIST(a) (
partition p1 values in (1),
partition p3 values in (3),
@@ -121,34 +121,34 @@
1 SIMPLE t6 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t6 where a <= 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t6 p1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a > 9;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t6 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t6 where a >= 9;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p9 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t6 p9 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t6 where a > 0 and a < 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t6 p1,p3 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a > 5 and a < 12;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p7,p9 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t6 p7,p9 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t6 where a > 3 and a < 8 ;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p5,p7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 p5,p7 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a >= 0 and a <= 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t6 p1,p3,p5 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t6 where a >= 5 and a <= 12;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p5,p7,p9 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 p5,p7,p9 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a >= 3 and a <= 8;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a > 3 and a < 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 ALL NULL NULL NULL NULL 0 Using where
drop table t6;
create table t6 (a int unsigned not null) partition by LIST(a) (
partition p1 values in (1),
@@ -163,34 +163,34 @@
1 SIMPLE t6 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t6 where a <= 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t6 p1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a > 9;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t6 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t6 where a >= 9;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p9 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t6 p9 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t6 where a > 0 and a < 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t6 p1,p3 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a > 5 and a < 12;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p7,p9 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t6 p7,p9 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t6 where a > 3 and a < 8 ;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p5,p7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 p5,p7 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a >= 0 and a <= 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t6 p1,p3,p5 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t6 where a >= 5 and a <= 12;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p5,p7,p9 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 p5,p7,p9 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a >= 3 and a <= 8;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a > 3 and a < 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 ALL NULL NULL NULL NULL 0 Using where
create table t7 (a int not null) partition by RANGE(a) (
partition p10 values less than (10),
partition p30 values less than (30),
@@ -207,25 +207,25 @@
1 SIMPLE t7 p10 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t7 where a <= 10;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 p10,p30 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t7 p10,p30 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t7 where a = 10;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 p30 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t7 p30 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t7 where a < 90;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t7 p10,p30,p50,p70,p90 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t7 where a = 90;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t7 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t7 where a > 90;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t7 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t7 where a >= 90;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t7 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t7 where a > 11 and a < 29;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 p30 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t7 p30 ALL NULL NULL NULL NULL 2 Using where
drop table t7;
create table t7 (a int unsigned not null) partition by RANGE(a) (
partition p10 values less than (10),
@@ -243,25 +243,25 @@
1 SIMPLE t7 p10 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t7 where a <= 10;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 p10,p30 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t7 p10,p30 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t7 where a = 10;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 p30 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t7 p30 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t7 where a < 90;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t7 p10,p30,p50,p70,p90 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t7 where a = 90;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t7 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t7 where a > 90;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t7 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t7 where a >= 90;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t7 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t7 where a > 11 and a < 29;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t7 p30 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t7 p30 ALL NULL NULL NULL NULL 2 Using where
create table t8 (a date not null) partition by RANGE(YEAR(a)) (
partition p0 values less than (1980),
partition p1 values less than (1990),
@@ -270,7 +270,7 @@
insert into t8 values ('1985-05-05'),('1995-05-05');
explain partitions select * from t8 where a < '1980-02-02';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t8 p0,p1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t8 p0,p1 ALL NULL NULL NULL NULL 2 Using where
create table t9 (a date not null) partition by RANGE(TO_DAYS(a)) (
partition p0 values less than (732299), -- 2004-12-19
partition p1 values less than (732468), -- 2005-06-06
@@ -295,13 +295,13 @@
insert into t1 values (1),(2),(3);
explain partitions select * from t1 where a1 > 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a1 >= 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a1 < 3 and a1 > 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where
drop table t1;
create table t3 (a int, b int)
partition by list(a) subpartition by hash(b) subpartitions 4 (
@@ -325,7 +325,7 @@
insert into t1 values (1),(2);
explain partitions select * from t1 where a is null;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a is not null;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 2 Using where
@@ -342,20 +342,20 @@
explain partitions
select * from t1 X, t1 Y where X.a = Y.a and (X.a=1 or X.a=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE X p1,p2 ALL a NULL NULL NULL 4 Using where
+1 SIMPLE X p1,p2 ALL a NULL NULL NULL 2 Using where
1 SIMPLE Y p1,p2 ref a a 4 test.X.a 1
drop table t1;
create table t1 (a int) partition by hash(a) partitions 20;
insert into t1 values (1),(2),(3);
explain partitions select * from t1 where a > 1 and a < 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a >= 1 and a < 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a > 1 and a <= 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a >= 1 and a <= 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1,p2,p3 ALL NULL NULL NULL NULL 3 Using where
@@ -371,10 +371,10 @@
insert into t1 values (1,1),(2,2),(3,3);
explain partitions select * from t1 where b > 1 and b < 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0_p0sp2,p1_p1sp2,p2_p2sp2,p3_p3sp2 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 p0_p0sp2,p1_p1sp2,p2_p2sp2,p3_p3sp2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where b > 1 and b < 3 and (a =1 or a =2);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p1_p1sp2,p2_p2sp2 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 p1_p1sp2,p2_p2sp2 ALL NULL NULL NULL NULL 2 Using where
drop table t1;
create table t1 (a int) partition by list(a) (
partition p0 values in (1,2),
@@ -445,22 +445,22 @@
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 1010
explain partitions select * from t2 where a < 801 and a > 200;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p1,p2,p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p1,p2,p3,p4 ALL NULL NULL NULL NULL 800 Using where
explain partitions select * from t2 where a < 801 and a > 800;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 200 Using where
explain partitions select * from t2 where a > 600;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where
explain partitions select * from t2 where a > 600 and b = 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where
explain partitions select * from t2 where a > 600 and b = 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where
explain partitions select * from t2 where a > 600 and b = 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where
explain partitions select * from t2 where b = 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 1010 Using where
@@ -515,19 +515,19 @@
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 910
explain partitions select * from t2 where a = 101;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 110 Using where
explain partitions select * from t2 where a = 550;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 200 Using where
explain partitions select * from t2 where a = 833;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 200 Using where
explain partitions select * from t2 where (a = 100 OR a = 900);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 310 Using where
explain partitions select * from t2 where (a > 100 AND a < 600);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 510 Using where
analyze table t2;
Table Op Msg_type Msg_text
test.t2 analyze status OK
@@ -692,7 +692,7 @@
NULL
explain partitions select * from t1 where f_int1 is null;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part4_part4sp0 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 part4_part4sp0 ALL NULL NULL NULL NULL 2 Using where
drop table t1;
create table t1 (a int not null, b int not null)
partition by list(a)
@@ -721,10 +721,10 @@
(2,1),(2,2),(2,3),(2,4), (NULL,1);
explain partitions select * from t1 where a IS NULL AND (b=1 OR b=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where (a IS NULL or a < 1) AND (b=1 OR b=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where (a IS NULL or a < 2) AND (b=1 OR b=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0_p0sp0,p0_p0sp1,pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL 5 Using where
@@ -753,7 +753,7 @@
1
explain partitions select count(*) from t1 where s1 < 0 or s1 is null;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p3 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 p3 ALL NULL NULL NULL NULL 2 Using where
drop table t1;
create table t1 (a char(32) primary key)
partition by key()
@@ -812,24 +812,24 @@
insert into t1 values (18446744073709551614-1);
explain partitions select * from t1 where a < 10;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1
where a >= 18446744073709551000-1 and a <= 18446744073709551000+1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p3,p4 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p3,p4 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t1
where a between 18446744073709551001 and 18446744073709551002;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a = 18446744073709551000;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a = 18446744073709551613;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a = 18446744073709551614;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where
drop table t1;
create table t1 (a int)
partition by range(a) (
@@ -853,34 +853,34 @@
1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a=0xFE;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t2 where a=0xFE;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a > 0xFE AND a <= 0xFF;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t2 where a > 0xFE AND a <= 0xFF;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t1 where a >= 0xFE AND a <= 0xFF;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t2 where a >= 0xFE AND a <= 0xFF;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a < 64 AND a >= 63;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t2 where a < 64 AND a >= 63;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a <= 64 AND a >= 63;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t2 where a <= 64 AND a >= 63;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL 4 Using where
drop table t1;
drop table t2;
create table t1(a bigint unsigned not null) partition by range(a+0) (
@@ -898,7 +898,7 @@
explain partitions select * from t1 where
a > 0xFFFFFFFFFFFFFFEC and a < 0xFFFFFFFFFFFFFFEE;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where
explain partitions select * from t1 where a>=0 and a <= 0xFFFFFFFFFFFFFFFF;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1,p2,p3,p4 ALL NULL NULL NULL NULL 8 Using where
=== modified file 'mysql-test/suite/pbxt/r/partition_range.result'
--- a/mysql-test/suite/pbxt/r/partition_range.result 2009-10-16 12:45:42 +0000
+++ b/mysql-test/suite/pbxt/r/partition_range.result 2010-04-06 08:10:58 +0000
@@ -21,19 +21,19 @@
a
explain partitions select * from t1 where a is null;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 pnull ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a >= 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a < 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 pnull ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a <= 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull,p0 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 pnull,p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a > 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where
drop table t1;
create table t1 (a int unsigned, b int unsigned)
partition by range (a)
@@ -63,19 +63,19 @@
a b
explain partitions select * from t1 where a is null;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a >= 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t1 where a < 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a <= 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1,p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1,p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t1 where a > 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where
drop table t1;
CREATE TABLE t1 (
a int not null,
=== modified file 'mysql-test/suite/pbxt/r/subselect.result'
--- a/mysql-test/suite/pbxt/r/subselect.result 2010-03-20 12:08:44 +0000
+++ b/mysql-test/suite/pbxt/r/subselect.result 2010-04-06 08:10:58 +0000
@@ -3420,18 +3420,20 @@
EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
a b
+AAA 8
BBB 4
CCC 7
-AAA 8
EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 9
+1 PRIMARY t1 ref a a 8 materialized subselect.a 1 Using where
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
DROP TABLE t1;
create table t1( f1 int,f2 int);
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2773)
by Igor Babaev 06 Apr '10
by Igor Babaev 06 Apr '10
06 Apr '10
#At lp:maria/5.2 based on revid:sergii@pisem.net-20100405095031-bgjy005pcftkp6g1
2773 Igor Babaev 2010-04-05 [merge]
Merge of the code for partitioned key cache (mwl#85) into 5.2.
added:
mysql-test/r/select_pkeycache.result
mysql-test/t/select_pkeycache-master.opt
mysql-test/t/select_pkeycache.test
modified:
include/keycache.h
mysql-test/r/information_schema.result
mysql-test/r/information_schema_all_engines.result
mysql-test/r/key_cache.result
mysql-test/suite/funcs_1/r/is_columns_is.result
mysql-test/suite/funcs_1/r/is_tables_is.result
mysql-test/suite/pbxt/r/mysqlshow.result
mysql-test/t/key_cache.test
mysys/mf_keycache.c
sql/handler.cc
sql/handler.h
sql/mysqld.cc
sql/set_var.cc
sql/set_var.h
sql/sql_show.cc
sql/sql_test.cc
sql/table.h
storage/myisam/mi_check.c
storage/myisam/mi_close.c
storage/myisam/mi_delete_all.c
storage/myisam/mi_extra.c
storage/myisam/mi_keycache.c
storage/myisam/mi_locking.c
storage/myisam/mi_page.c
storage/myisam/mi_panic.c
storage/myisam/mi_preload.c
storage/myisam/mi_test1.c
storage/myisam/mi_test2.c
storage/myisam/mi_test3.c
storage/myisam/myisam_ftdump.c
storage/myisam/myisamchk.c
storage/myisam/myisamdef.h
storage/myisam/myisamlog.c
=== modified file 'include/keycache.h'
--- a/include/keycache.h 2009-12-03 11:19:05 +0000
+++ b/include/keycache.h 2010-04-06 02:08:10 +0000
@@ -19,96 +19,156 @@
#define _keycache_h
C_MODE_START
-/* declare structures that is used by st_key_cache */
-struct st_block_link;
-typedef struct st_block_link BLOCK_LINK;
-struct st_keycache_page;
-typedef struct st_keycache_page KEYCACHE_PAGE;
-struct st_hash_link;
-typedef struct st_hash_link HASH_LINK;
-/* info about requests in a waiting queue */
-typedef struct st_keycache_wqueue
+/*
+ Currently the default key cache is created as non-partitioned at
+ the start of the server unless the server is started with the parameter
+ --key-cache-partitions that is greater than 0
+*/
+
+#define DEFAULT_KEY_CACHE_PARTITIONS 0
+
+/*
+ MAX_KEY_CACHE_PARTITIONS cannot be greater than
+ sizeof(MYISAM_SHARE::dirty_part_map)
+ Currently sizeof(MYISAM_SHARE::dirty_part_map)=sizeof(ulonglong)
+*/
+
+#define MAX_KEY_CACHE_PARTITIONS 64
+
+/* The structure to get statistical data about a key cache */
+
+typedef struct st_key_cache_statistics
{
- struct st_my_thread_var *last_thread; /* circular list of waiting threads */
-} KEYCACHE_WQUEUE;
+ ulonglong mem_size; /* memory for cache buffers/auxiliary structures */
+ ulonglong block_size; /* size of the each buffers in the key cache */
+ ulonglong blocks_used; /* maximum number of used blocks/buffers */
+ ulonglong blocks_unused; /* number of currently unused blocks */
+ ulonglong blocks_changed; /* number of currently dirty blocks */
+ ulonglong read_requests; /* number of read requests (read hits) */
+ ulonglong reads; /* number of actual reads from files into buffers */
+ ulonglong write_requests; /* number of write requests (write hits) */
+ ulonglong writes; /* number of actual writes from buffers into files */
+} KEY_CACHE_STATISTICS;
+
+#define NUM_LONG_KEY_CACHE_STAT_VARIABLES 3
-#define CHANGED_BLOCKS_HASH 128 /* must be power of 2 */
+/* The type of a key cache object */
+typedef enum key_cache_type
+{
+ SIMPLE_KEY_CACHE,
+ PARTITIONED_KEY_CACHE
+} KEY_CACHE_TYPE;
+
+
+typedef
+ int (*INIT_KEY_CACHE)
+ (void *, uint key_cache_block_size,
+ size_t use_mem, uint division_limit, uint age_threshold);
+typedef
+ int (*RESIZE_KEY_CACHE)
+ (void *, uint key_cache_block_size,
+ size_t use_mem, uint division_limit, uint age_threshold);
+typedef
+ void (*CHANGE_KEY_CACHE_PARAM)
+ (void *keycache_cb,
+ uint division_limit, uint age_threshold);
+typedef
+ uchar* (*KEY_CACHE_READ)
+ (void *keycache_cb,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length, int return_buffer);
+typedef
+ int (*KEY_CACHE_INSERT)
+ (void *keycache_cb,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length);
+typedef
+ int (*KEY_CACHE_WRITE)
+ (void *keycache_cb,
+ File file, void *file_extra,
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length, int force_write);
+typedef
+ int (*FLUSH_KEY_BLOCKS)
+ (void *keycache_cb,
+ int file, void *file_extra,
+ enum flush_type type);
+typedef
+ int (*RESET_KEY_CACHE_COUNTERS)
+ (const char *name, void *keycache_cb);
+typedef
+ void (*END_KEY_CACHE)
+ (void *keycache_cb, my_bool cleanup);
+typedef
+ void (*GET_KEY_CACHE_STATISTICS)
+ (void *keycache_cb, uint partition_no,
+ KEY_CACHE_STATISTICS *key_cache_stats);
+typedef
+ ulonglong (*GET_KEY_CACHE_STAT_VALUE)
+ (void *keycache_cb, uint var_no);
/*
- The key cache structure
- It also contains read-only statistics parameters.
+ An object of the type KEY_CACHE_FUNCS contains pointers to all functions
+ from the key cache interface.
+ Currently a key cache can be of two types: simple and partitioned.
+ For each of them its own static structure of the type KEY_CACHE_FUNCS is
+ defined . The structures contain the pointers to the implementations of
+ the interface functions used by simple key caches and partitioned key
+ caches respectively. Pointers to these structures are assigned to key cache
+ objects at the time of their creation.
*/
+typedef struct st_key_cache_funcs
+{
+ INIT_KEY_CACHE init;
+ RESIZE_KEY_CACHE resize;
+ CHANGE_KEY_CACHE_PARAM change_param;
+ KEY_CACHE_READ read;
+ KEY_CACHE_INSERT insert;
+ KEY_CACHE_WRITE write;
+ FLUSH_KEY_BLOCKS flush;
+ RESET_KEY_CACHE_COUNTERS reset_counters;
+ END_KEY_CACHE end;
+ GET_KEY_CACHE_STATISTICS get_stats;
+ GET_KEY_CACHE_STAT_VALUE get_stat_val;
+} KEY_CACHE_FUNCS;
+
+
typedef struct st_key_cache
{
- my_bool key_cache_inited;
- my_bool in_resize; /* true during resize operation */
- my_bool resize_in_flush; /* true during flush of resize operation */
+ KEY_CACHE_TYPE key_cache_type; /* type of the key cache used for debugging */
+ void *keycache_cb; /* control block of the used key cache */
+ KEY_CACHE_FUNCS *interface_funcs; /* interface functions of the key cache */
+ ulonglong param_buff_size; /* size the memory allocated for the cache */
+ ulong param_block_size; /* size of the blocks in the key cache */
+ ulong param_division_limit; /* min. percentage of warm blocks */
+ ulong param_age_threshold; /* determines when hot block is downgraded */
+ ulong param_partitions; /* number of the key cache partitions */
+ my_bool key_cache_inited; /* <=> key cache has been created */
my_bool can_be_used; /* usage of cache for read/write is allowed */
- size_t key_cache_mem_size; /* specified size of the cache memory */
- uint key_cache_block_size; /* size of the page buffer of a cache block */
- ulong min_warm_blocks; /* min number of warm blocks; */
- ulong age_threshold; /* age threshold for hot blocks */
- ulonglong keycache_time; /* total number of block link operations */
- uint hash_entries; /* max number of entries in the hash table */
- int hash_links; /* max number of hash links */
- int hash_links_used; /* number of hash links currently used */
- int disk_blocks; /* max number of blocks in the cache */
- ulong blocks_used; /* maximum number of concurrently used blocks */
- ulong blocks_unused; /* number of currently unused blocks */
- ulong blocks_changed; /* number of currently dirty blocks */
- ulong warm_blocks; /* number of blocks in warm sub-chain */
- ulong cnt_for_resize_op; /* counter to block resize operation */
- long blocks_available; /* number of blocks available in the LRU chain */
- HASH_LINK **hash_root; /* arr. of entries into hash table buckets */
- HASH_LINK *hash_link_root; /* memory for hash table links */
- HASH_LINK *free_hash_list; /* list of free hash links */
- BLOCK_LINK *free_block_list; /* list of free blocks */
- BLOCK_LINK *block_root; /* memory for block links */
- uchar HUGE_PTR *block_mem; /* memory for block buffers */
- BLOCK_LINK *used_last; /* ptr to the last block of the LRU chain */
- BLOCK_LINK *used_ins; /* ptr to the insertion block in LRU chain */
- pthread_mutex_t cache_lock; /* to lock access to the cache structure */
- KEYCACHE_WQUEUE resize_queue; /* threads waiting during resize operation */
- /*
- Waiting for a zero resize count. Using a queue for symmetry though
- only one thread can wait here.
- */
- KEYCACHE_WQUEUE waiting_for_resize_cnt;
- KEYCACHE_WQUEUE waiting_for_hash_link; /* waiting for a free hash link */
- KEYCACHE_WQUEUE waiting_for_block; /* requests waiting for a free block */
- BLOCK_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; /* hash for dirty file bl.*/
- BLOCK_LINK *file_blocks[CHANGED_BLOCKS_HASH]; /* hash for other file bl.*/
-
- /*
- The following variables are and variables used to hold parameters for
- initializing the key cache.
- */
-
- ulonglong param_buff_size; /* size the memory allocated for the cache */
- ulong param_block_size; /* size of the blocks in the key cache */
- ulong param_division_limit; /* min. percentage of warm blocks */
- ulong param_age_threshold; /* determines when hot block is downgraded */
-
- /* Statistics variables. These are reset in reset_key_cache_counters(). */
- ulong global_blocks_changed; /* number of currently dirty blocks */
+ my_bool in_init; /* Set to 1 in MySQL during init/resize */
+ uint partitions; /* actual number of partitions */
+ size_t key_cache_mem_size; /* specified size of the cache memory */
+ ulong blocks_used; /* maximum number of concurrently used blocks */
+ ulong blocks_unused; /* number of currently unused blocks */
+ ulong global_blocks_changed; /* number of currently dirty blocks */
ulonglong global_cache_w_requests;/* number of write requests (write hits) */
ulonglong global_cache_write; /* number of writes from cache to files */
ulonglong global_cache_r_requests;/* number of read requests (read hits) */
ulonglong global_cache_read; /* number of reads from files to cache */
-
- int blocks; /* max number of blocks in the cache */
- my_bool in_init; /* Set to 1 in MySQL during init/resize */
} KEY_CACHE;
+
/* The default key cache */
extern KEY_CACHE dflt_key_cache_var, *dflt_key_cache;
extern int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold);
+ uint age_threshold, uint partitions);
extern int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
uint age_threshold);
@@ -122,12 +182,18 @@ extern int key_cache_insert(KEY_CACHE *k
File file, my_off_t filepos, int level,
uchar *buff, uint length);
extern int key_cache_write(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
+ File file, void *file_extra,
+ my_off_t filepos, int level,
uchar *buff, uint length,
- uint block_length,int force_write);
+ uint block_length, int force_write);
extern int flush_key_blocks(KEY_CACHE *keycache,
- int file, enum flush_type type);
+ int file, void *file_extra,
+ enum flush_type type);
extern void end_key_cache(KEY_CACHE *keycache, my_bool cleanup);
+extern void get_key_cache_statistics(KEY_CACHE *keycache,
+ uint partition_no,
+ KEY_CACHE_STATISTICS *key_cache_stats);
+extern ulonglong get_key_cache_stat_value(KEY_CACHE *keycache, uint var_no);
/* Functions to handle multiple key caches */
extern my_bool multi_keycache_init(void);
@@ -140,5 +206,11 @@ extern void multi_key_cache_change(KEY_C
KEY_CACHE *new_data);
extern int reset_key_cache_counters(const char *name,
KEY_CACHE *key_cache);
+extern int repartition_key_cache(KEY_CACHE *keycache,
+ uint key_cache_block_size,
+ size_t use_mem,
+ uint division_limit,
+ uint age_threshold,
+ uint partitions);
C_MODE_END
#endif /* _keycache_h */
=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result 2010-03-15 11:51:23 +0000
+++ b/mysql-test/r/information_schema.result 2010-03-29 21:16:12 +0000
@@ -69,6 +69,7 @@ INNODB_LOCK_WAITS
INNODB_RSEG
INNODB_TABLE_STATS
INNODB_TRX
+KEY_CACHES
KEY_COLUMN_USAGE
PARTITIONS
PLUGINS
=== modified file 'mysql-test/r/information_schema_all_engines.result'
--- a/mysql-test/r/information_schema_all_engines.result 2010-02-01 06:14:12 +0000
+++ b/mysql-test/r/information_schema_all_engines.result 2010-02-16 16:41:11 +0000
@@ -13,6 +13,7 @@ FILES
GLOBAL_STATUS
GLOBAL_VARIABLES
INDEX_STATISTICS
+KEY_CACHES
KEY_COLUMN_USAGE
PARTITIONS
PLUGINS
@@ -76,6 +77,7 @@ FILES TABLE_SCHEMA
GLOBAL_STATUS VARIABLE_NAME
GLOBAL_VARIABLES VARIABLE_NAME
INDEX_STATISTICS TABLE_SCHEMA
+KEY_CACHES KEY_CACHE_NAME
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
PARTITIONS TABLE_SCHEMA
PLUGINS PLUGIN_NAME
@@ -139,6 +141,7 @@ FILES TABLE_SCHEMA
GLOBAL_STATUS VARIABLE_NAME
GLOBAL_VARIABLES VARIABLE_NAME
INDEX_STATISTICS TABLE_SCHEMA
+KEY_CACHES KEY_CACHE_NAME
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
PARTITIONS TABLE_SCHEMA
PLUGINS PLUGIN_NAME
@@ -221,6 +224,7 @@ INNODB_LOCK_WAITS information_schema.INN
INNODB_RSEG information_schema.INNODB_RSEG 1
INNODB_TABLE_STATS information_schema.INNODB_TABLE_STATS 1
INNODB_TRX information_schema.INNODB_TRX 1
+KEY_CACHES information_schema.KEY_CACHES 1
KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1
PARTITIONS information_schema.PARTITIONS 1
PBXT_STATISTICS information_schema.PBXT_STATISTICS 1
@@ -259,6 +263,7 @@ Database: information_schema
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| INDEX_STATISTICS |
+| KEY_CACHES |
| KEY_COLUMN_USAGE |
| PARTITIONS |
| PLUGINS |
@@ -312,6 +317,7 @@ Database: INFORMATION_SCHEMA
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| INDEX_STATISTICS |
+| KEY_CACHES |
| KEY_COLUMN_USAGE |
| PARTITIONS |
| PLUGINS |
@@ -357,5 +363,5 @@ Wildcard: inf_rmation_schema
+--------------------+
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
table_schema count(*)
-information_schema 48
+information_schema 49
mysql 22
=== modified file 'mysql-test/r/key_cache.result'
--- a/mysql-test/r/key_cache.result 2009-03-16 19:54:50 +0000
+++ b/mysql-test/r/key_cache.result 2010-04-01 21:42:40 +0000
@@ -1,5 +1,7 @@
drop table if exists t1, t2, t3;
-SET @save_key_buffer=@@key_buffer_size;
+SET @save_key_buffer_size=@@key_buffer_size;
+SET @save_key_cache_block_size=@@key_cache_block_size;
+SET @save_key_cache_partitions=@@key_cache_partitions;
SELECT @@key_buffer_size, @@small.key_buffer_size;
@@key_buffer_size @@small.key_buffer_size
2097152 131072
@@ -37,7 +39,7 @@ SELECT @@small.key_buffer_size;
SELECT @@medium.key_buffer_size;
@@medium.key_buffer_size
0
-SET @@global.key_buffer_size=@save_key_buffer;
+SET @@global.key_buffer_size=@save_key_buffer_size;
SELECT @@default.key_buffer_size;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default.key_buffer_size' at line 1
SELECT @@skr.storage_engine="test";
@@ -366,3 +368,432 @@ Variable_name Value
key_cache_block_size 1536
SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size;
DROP TABLE t1;
+set global key_buffer_size=@save_key_buffer_size;
+set global key_cache_block_size=@save_key_cache_block_size;
+select @@key_buffer_size;
+@@key_buffer_size
+2097152
+select @@key_cache_block_size;
+@@key_cache_block_size
+1024
+select @@key_cache_partitions;
+@@key_cache_partitions
+0
+create table t1 (
+p int not null auto_increment primary key,
+a char(10));
+create table t2 (
+p int not null auto_increment primary key,
+i int, a char(10), key k1(i), key k2(a));
+select @@key_cache_partitions;
+@@key_cache_partitions
+0
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default NULL NULL 2097152 1024 0 # 0 0 0 0 0
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+insert into t1 values (1, 'qqqq'), (2, 'yyyy');
+insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
+(3, 1, 'yyyy'), (4, 3, 'zzzz');
+select * from t1;
+p a
+1 qqqq
+2 yyyy
+select * from t2;
+p i a
+1 1 qqqq
+2 1 pppp
+3 1 yyyy
+4 3 zzzz
+update t1 set p=3 where p=1;
+update t2 set i=2 where i=1;
+show status like 'key_%';
+Variable_name Value
+Key_blocks_not_flushed 0
+Key_blocks_unused KEY_BLOCKS_UNUSED
+Key_blocks_used 4
+Key_read_requests 22
+Key_reads 0
+Key_write_requests 26
+Key_writes 6
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default NULL NULL 2097152 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+delete from t2 where a='zzzz';
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default NULL NULL 2097152 1024 4 # 0 29 0 32 9
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+delete from t1;
+delete from t2;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default NULL NULL 2097152 1024 4 # 0 29 0 32 9
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+set global key_cache_partitions=2;
+select @@key_cache_partitions;
+@@key_cache_partitions
+2
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 2097152 1024 0 # 0 0 0 0 0
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+insert into t1 values (1, 'qqqq'), (2, 'yyyy');
+insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
+(3, 1, 'yyyy'), (4, 3, 'zzzz');
+select * from t1;
+p a
+1 qqqq
+2 yyyy
+select * from t2;
+p i a
+1 1 qqqq
+2 1 pppp
+3 1 yyyy
+4 3 zzzz
+update t1 set p=3 where p=1;
+update t2 set i=2 where i=1;
+show status like 'key_%';
+Variable_name Value
+Key_blocks_not_flushed 0
+Key_blocks_unused KEY_BLOCKS_UNUSED
+Key_blocks_used 4
+Key_read_requests 22
+Key_reads 0
+Key_write_requests 26
+Key_writes 6
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 2097152 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+delete from t1;
+delete from t2;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 2097152 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+set global key_cache_partitions=1;
+select @@key_cache_partitions;
+@@key_cache_partitions
+1
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 1 NULL 2097152 1024 0 # 0 0 0 0 0
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+insert into t1 values (1, 'qqqq'), (2, 'yyyy');
+insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
+(3, 1, 'yyyy'), (4, 3, 'zzzz');
+select * from t1;
+p a
+1 qqqq
+2 yyyy
+select * from t2;
+p i a
+1 1 qqqq
+2 1 pppp
+3 1 yyyy
+4 3 zzzz
+update t1 set p=3 where p=1;
+update t2 set i=2 where i=1;
+show status like 'key_%';
+Variable_name Value
+Key_blocks_not_flushed 0
+Key_blocks_unused KEY_BLOCKS_UNUSED
+Key_blocks_used 4
+Key_read_requests 22
+Key_reads 0
+Key_write_requests 26
+Key_writes 6
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 1 NULL 2097152 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+delete from t1;
+delete from t2;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 1 NULL 2097152 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+flush tables;
+flush status;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 1 NULL 2097152 1024 4 # 0 0 0 0 0
+small NULL NULL 1048576 1024 1 # 0 0 0 0 0
+set global key_buffer_size=32*1024;
+select @@key_buffer_size;
+@@key_buffer_size
+32768
+set global key_cache_partitions=2;
+select @@key_cache_partitions;
+@@key_cache_partitions
+2
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 0 # 0 0 0 0 0
+small NULL NULL 1048576 1024 1 # 0 0 0 0 0
+insert into t1 values (1, 'qqqq'), (2, 'yyyy');
+insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
+(3, 1, 'yyyy'), (4, 3, 'zzzz');
+select * from t1;
+p a
+1 qqqq
+2 yyyy
+select * from t2;
+p i a
+1 1 qqqq
+2 1 pppp
+3 1 yyyy
+4 3 zzzz
+update t1 set p=3 where p=1;
+update t2 set i=2 where i=1;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 0 0 0 0
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 6733 # 3684 103
+small NULL NULL 1048576 1024 # # 0 0 # 0 0
+select * from t1 where p between 1010 and 1020 ;
+p a
+select * from t2 where p between 1010 and 1020 ;
+p i a
+1010 2 pppp
+1011 2 yyyy
+1012 3 zzzz
+1013 2 qqqq
+1014 2 pppp
+1015 2 yyyy
+1016 3 zzzz
+1017 2 qqqq
+1018 2 pppp
+1019 2 yyyy
+1020 3 zzzz
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 6750 # 3684 103
+small NULL NULL 1048576 1024 # # 0 0 # 0 0
+flush tables;
+flush status;
+update t1 set a='zzzz' where a='qqqq';
+update t2 set i=1 where i=2;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3076 18 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+set global keycache1.key_buffer_size=256*1024;
+select @@keycache1.key_buffer_size;
+@@keycache1.key_buffer_size
+262144
+set global keycache1.key_cache_partitions=7;
+select @@keycache1.key_cache_partitions;
+@@keycache1.key_cache_partitions
+7
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3076 18 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 7 NULL 262143 2048 # # 0 0 0 0 0
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+keycache1 7 NULL 262143 2048 0 # 0 0 0 0 0
+cache index t1 key (`primary`) in keycache1;
+Table Op Msg_type Msg_text
+test.t1 assign_to_keycache status OK
+explain select p from t1 where p between 1010 and 1020;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using index
+select p from t1 where p between 1010 and 1020;
+p
+explain select i from t2 where p between 1010 and 1020;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 28 Using where
+select i from t2 where p between 1010 and 1020;
+i
+1
+1
+3
+1
+1
+1
+3
+1
+1
+1
+3
+explain select count(*) from t1, t2 where t1.p = t2.i;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index k1 k1 5 NULL 1024 Using index
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.i 1 Using index
+select count(*) from t1, t2 where t1.p = t2.i;
+count(*)
+256
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 7 NULL 262143 2048 # # 0 14 3 0 0
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+keycache1 7 NULL 262143 2048 3 # 0 14 3 0 0
+cache index t2 in keycache1;
+Table Op Msg_type Msg_text
+test.t2 assign_to_keycache status OK
+update t2 set p=p+3000, i=2 where a='qqqq';
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19
+set global keycache2.key_buffer_size=1024*1024;
+cache index t2 in keycache2;
+Table Op Msg_type Msg_text
+test.t2 assign_to_keycache status OK
+insert into t2 values (2000, 3, 'yyyy');
+select * from information_schema.key_caches where key_cache_name like "keycache2"
+ and partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3
+select * from information_schema.key_caches where key_cache_name like "key%"
+and partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19
+keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3
+cache index t2 in keycache1;
+Table Op Msg_type Msg_text
+test.t2 assign_to_keycache status OK
+update t2 set p=p+5000 where a='zzzz';
+select * from t2 where p between 1010 and 1020;
+p i a
+1010 1 pppp
+1011 1 yyyy
+1014 1 pppp
+1015 1 yyyy
+1018 1 pppp
+1019 1 yyyy
+explain select p from t2 where p between 1010 and 1020;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 7 Using where; Using index
+select p from t2 where p between 1010 and 1020;
+p
+1010
+1011
+1014
+1015
+1018
+1019
+explain select i from t2 where a='yyyy' and i=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref k1,k2 k1 5 const 188 Using where
+select i from t2 where a='yyyy' and i=3;
+i
+3
+explain select a from t2 where a='yyyy' and i=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref k1,k2 k1 5 const 188 Using where
+select a from t2 where a='yyyy' and i=3 ;
+a
+yyyy
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 7 NULL 262143 2048 # # 0 3201 43 1594 30
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_cache_block_size=2*1024;
+insert into t2 values (7000, 3, 'yyyy');
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 7 NULL 262143 2048 # # 0 6 6 3 3
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_cache_block_size=8*1024;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 3 NULL 262143 8192 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+insert into t2 values (8000, 3, 'yyyy');
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 3 NULL 262143 8192 # # 0 6 5 3 3
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_buffer_size=64*1024;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_cache_block_size=2*1024;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 3 NULL 65535 2048 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_cache_block_size=8*1024;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_buffer_size=0;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_cache_block_size=8*1024;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_buffer_size=0;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_buffer_size=128*1024;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 1 NULL 131072 8192 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+set global keycache1.key_cache_block_size=1024;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 7 NULL 131068 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
+drop table t1,t2;
+set global keycache1.key_buffer_size=0;
+set global keycache2.key_buffer_size=0;
+set global key_buffer_size=@save_key_buffer_size;
+set global key_cache_partitions=@save_key_cache_partitions;
=== added file 'mysql-test/r/select_pkeycache.result'
--- a/mysql-test/r/select_pkeycache.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/select_pkeycache.result 2010-03-29 21:16:12 +0000
@@ -0,0 +1,4784 @@
+drop table if exists t1,t2,t3,t4,t11;
+drop table if exists t1_1,t1_2,t9_1,t9_2,t1aa,t2aa;
+drop view if exists v1;
+CREATE TABLE t1 (
+Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
+Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
+);
+INSERT INTO t1 VALUES (9410,9412);
+select period from t1;
+period
+9410
+select * from t1;
+Period Varor_period
+9410 9412
+select t1.* from t1;
+Period Varor_period
+9410 9412
+CREATE TABLE t2 (
+auto int not null auto_increment,
+fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL,
+companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL,
+fld3 char(30) DEFAULT '' NOT NULL,
+fld4 char(35) DEFAULT '' NOT NULL,
+fld5 char(35) DEFAULT '' NOT NULL,
+fld6 char(4) DEFAULT '' NOT NULL,
+UNIQUE fld1 (fld1),
+KEY fld3 (fld3),
+PRIMARY KEY (auto)
+);
+select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%";
+fld3
+imaginable
+select fld3 from t2 where fld3 like "%cultivation" ;
+fld3
+cultivation
+select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3;
+fld3 companynr
+concoct 58
+druggists 58
+engrossing 58
+Eurydice 58
+exclaimers 58
+ferociousness 58
+hopelessness 58
+Huey 58
+imaginable 58
+judges 58
+merging 58
+ostrich 58
+peering 58
+Phelps 58
+presumes 58
+Ruth 58
+sentences 58
+Shylock 58
+straggled 58
+synergy 58
+thanking 58
+tying 58
+unlocks 58
+select fld3,companynr from t2 where companynr = 58 order by fld3;
+fld3 companynr
+concoct 58
+druggists 58
+engrossing 58
+Eurydice 58
+exclaimers 58
+ferociousness 58
+hopelessness 58
+Huey 58
+imaginable 58
+judges 58
+merging 58
+ostrich 58
+peering 58
+Phelps 58
+presumes 58
+Ruth 58
+sentences 58
+Shylock 58
+straggled 58
+synergy 58
+thanking 58
+tying 58
+unlocks 58
+select fld3 from t2 order by fld3 desc limit 10;
+fld3
+youthfulness
+yelped
+Wotan
+workers
+Witt
+witchcraft
+Winsett
+Willy
+willed
+wildcats
+select fld3 from t2 order by fld3 desc limit 5;
+fld3
+youthfulness
+yelped
+Wotan
+workers
+Witt
+select fld3 from t2 order by fld3 desc limit 5,5;
+fld3
+witchcraft
+Winsett
+Willy
+willed
+wildcats
+select t2.fld3 from t2 where fld3 = 'honeysuckle';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'h%le';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_';
+fld3
+select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%';
+fld3
+explain select t2.fld3 from t2 where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 ignore index (fld3) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select fld3 from t2 use index (fld1) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select fld3 from t2 use index (fld3) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 use index (fld1,fld3) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 ignore index (fld3,not_used);
+ERROR 42000: Key 'not_used' doesn't exist in table 't2'
+explain select fld3 from t2 use index (not_used);
+ERROR 42000: Key 'not_used' doesn't exist in table 't2'
+select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
+fld3
+honeysuckle
+honoring
+explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range fld3 fld3 30 NULL 2 Using where; Using index
+select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3;
+fld1 fld3
+148504 Colombo
+068305 Colombo
+000000 nondecreasing
+select fld1,fld3 from t2 where companynr = 37 and fld3 = 'appendixes';
+fld1 fld3
+232605 appendixes
+1232605 appendixes
+1232606 appendixes
+1232607 appendixes
+1232608 appendixes
+1232609 appendixes
+select fld1 from t2 where fld1=250501 or fld1="250502";
+fld1
+250501
+250502
+explain select fld1 from t2 where fld1=250501 or fld1="250502";
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range fld1 fld1 4 NULL 2 Using where; Using index
+select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
+fld1
+250501
+250502
+250505
+250601
+explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
+select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
+fld1 fld3
+218401 faithful
+018007 fanatic
+228311 fated
+018017 featherweight
+218022 feed
+088303 feminine
+058004 Fenton
+038017 fetched
+018054 fetters
+208101 fiftieth
+238007 filial
+013606 fingerings
+218008 finishers
+038205 firearm
+188505 fitting
+202301 Fitzpatrick
+238008 fixedly
+012001 flanking
+018103 flint
+018104 flopping
+188007 flurried
+013602 foldout
+226205 foothill
+232102 forgivably
+228306 forthcoming
+186002 freakish
+208113 freest
+231315 freezes
+036002 funereal
+226209 furnishings
+198006 furthermore
+select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
+fld3
+select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
+fld3
+Chantilly
+select fld1,fld3 from t2 where fld1 like "25050%";
+fld1 fld3
+250501 poisoning
+250502 Iraqis
+250503 heaving
+250504 population
+250505 bomb
+select fld1,fld3 from t2 where fld1 like "25050_";
+fld1 fld3
+250501 poisoning
+250502 Iraqis
+250503 heaving
+250504 population
+250505 bomb
+select distinct companynr from t2;
+companynr
+00
+37
+36
+50
+58
+29
+40
+53
+65
+41
+34
+68
+select distinct companynr from t2 order by companynr;
+companynr
+00
+29
+34
+36
+37
+40
+41
+50
+53
+58
+65
+68
+select distinct companynr from t2 order by companynr desc;
+companynr
+68
+65
+58
+53
+50
+41
+40
+37
+36
+34
+29
+00
+select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%";
+fld3 period
+obliterates 9410
+offload 9410
+opaquely 9410
+organizer 9410
+overestimating 9410
+overlay 9410
+select distinct fld3 from t2 where companynr = 34 order by fld3;
+fld3
+absentee
+accessed
+ahead
+alphabetic
+Asiaticizations
+attitude
+aye
+bankruptcies
+belays
+Blythe
+bomb
+boulevard
+bulldozes
+cannot
+caressing
+charcoal
+checksumming
+chess
+clubroom
+colorful
+cosy
+creator
+crying
+Darius
+diffusing
+duality
+Eiffel
+Epiphany
+Ernestine
+explorers
+exterminated
+famine
+forked
+Gershwins
+heaving
+Hodges
+Iraqis
+Italianization
+Lagos
+landslide
+libretto
+Majorca
+mastering
+narrowed
+occurred
+offerers
+Palestine
+Peruvianizes
+pharmaceutic
+poisoning
+population
+Pygmalion
+rats
+realest
+recording
+regimented
+retransmitting
+reviver
+rouses
+scars
+sicker
+sleepwalk
+stopped
+sugars
+translatable
+uncles
+unexpected
+uprisings
+versatility
+vest
+select distinct fld3 from t2 limit 10;
+fld3
+abates
+abiding
+Abraham
+abrogating
+absentee
+abut
+accessed
+accruing
+accumulating
+accuracies
+select distinct fld3 from t2 having fld3 like "A%" limit 10;
+fld3
+abates
+abiding
+Abraham
+abrogating
+absentee
+abut
+accessed
+accruing
+accumulating
+accuracies
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%";
+substring(fld3,1,3)
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+Adl
+adm
+Ado
+ads
+adv
+aer
+aff
+afi
+afl
+afo
+agi
+ahe
+aim
+air
+Ald
+alg
+ali
+all
+alp
+alr
+ama
+ame
+amm
+ana
+and
+ane
+Ang
+ani
+Ann
+Ant
+api
+app
+aqu
+Ara
+arc
+Arm
+arr
+Art
+Asi
+ask
+asp
+ass
+ast
+att
+aud
+Aug
+aut
+ave
+avo
+awe
+aye
+Azt
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" order by a limit 10;
+a
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%" limit 10;
+substring(fld3,1,3)
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" limit 10;
+a
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+create table t3 (
+period int not null,
+name char(32) not null,
+companynr int not null,
+price double(11,0),
+price2 double(11,0),
+key (period),
+key (name)
+);
+create temporary table tmp engine = myisam select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+alter table t3 add t2nr int not null auto_increment primary key first;
+drop table tmp;
+SET SQL_BIG_TABLES=1;
+select distinct concat(fld3," ",fld3) as namn from t2,t3 where t2.fld1=t3.t2nr order by namn limit 10;
+namn
+Abraham Abraham
+abrogating abrogating
+admonishing admonishing
+Adolph Adolph
+afield afield
+aging aging
+ammonium ammonium
+analyzable analyzable
+animals animals
+animized animized
+SET SQL_BIG_TABLES=0;
+select distinct concat(fld3," ",fld3) from t2,t3 where t2.fld1=t3.t2nr order by fld3 limit 10;
+concat(fld3," ",fld3)
+Abraham Abraham
+abrogating abrogating
+admonishing admonishing
+Adolph Adolph
+afield afield
+aging aging
+ammonium ammonium
+analyzable analyzable
+animals animals
+animized animized
+select distinct fld5 from t2 limit 10;
+fld5
+neat
+Steinberg
+jarring
+tinily
+balled
+persist
+attainments
+fanatic
+measures
+rightfulness
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
+fld3 count(*)
+affixed 1
+and 1
+annoyers 1
+Anthony 1
+assayed 1
+assurers 1
+attendants 1
+bedlam 1
+bedpost 1
+boasted 1
+SET SQL_BIG_TABLES=1;
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
+fld3 count(*)
+affixed 1
+and 1
+annoyers 1
+Anthony 1
+assayed 1
+assurers 1
+attendants 1
+bedlam 1
+bedpost 1
+boasted 1
+SET SQL_BIG_TABLES=0;
+select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10;
+fld3 repeat("a",length(fld3)) count(*)
+circus aaaaaa 1
+cited aaaaa 1
+Colombo aaaaaaa 1
+congresswoman aaaaaaaaaaaaa 1
+contrition aaaaaaaaaa 1
+corny aaaaa 1
+cultivation aaaaaaaaaaa 1
+definiteness aaaaaaaaaaaa 1
+demultiplex aaaaaaaaaaa 1
+disappointing aaaaaaaaaaaaa 1
+select distinct companynr,rtrim(space(512+companynr)) from t3 order by 1,2;
+companynr rtrim(space(512+companynr))
+37
+78
+101
+154
+311
+447
+512
+select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by fld3;
+fld3
+explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
+1 SIMPLE t3 ref period period 4 test.t1.period 4181
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 index period period 4 NULL 1
+1 SIMPLE t1 ref period period 4 test.t3.period 4181
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index period period 4 NULL 1
+1 SIMPLE t3 ref period period 4 test.t1.period 4181
+select period from t1;
+period
+9410
+select period from t1 where period=1900;
+period
+select fld3,period from t1,t2 where fld1 = 011401 order by period;
+fld3 period
+breaking 9410
+select fld3,period from t2,t3 where t2.fld1 = 011401 and t2.fld1=t3.t2nr and t3.period=1001;
+fld3 period
+breaking 1001
+explain select fld3,period from t2,t3 where t2.fld1 = 011401 and t3.t2nr=t2.fld1 and 1001 = t3.period;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 const fld1 fld1 4 const 1
+1 SIMPLE t3 const PRIMARY,period PRIMARY 4 const 1
+select fld3,period from t2,t1 where companynr*10 = 37*10;
+fld3 period
+breaking 9410
+Romans 9410
+intercepted 9410
+bewilderingly 9410
+astound 9410
+admonishing 9410
+sumac 9410
+flanking 9410
+combed 9410
+subjective 9410
+scatterbrain 9410
+Eulerian 9410
+Kane 9410
+overlay 9410
+perturb 9410
+goblins 9410
+annihilates 9410
+Wotan 9410
+snatching 9410
+concludes 9410
+laterally 9410
+yelped 9410
+grazing 9410
+Baird 9410
+celery 9410
+misunderstander 9410
+handgun 9410
+foldout 9410
+mystic 9410
+succumbed 9410
+Nabisco 9410
+fingerings 9410
+aging 9410
+afield 9410
+ammonium 9410
+boat 9410
+intelligibility 9410
+Augustine 9410
+teethe 9410
+dreaded 9410
+scholastics 9410
+audiology 9410
+wallet 9410
+parters 9410
+eschew 9410
+quitter 9410
+neat 9410
+Steinberg 9410
+jarring 9410
+tinily 9410
+balled 9410
+persist 9410
+attainments 9410
+fanatic 9410
+measures 9410
+rightfulness 9410
+capably 9410
+impulsive 9410
+starlet 9410
+terminators 9410
+untying 9410
+announces 9410
+featherweight 9410
+pessimist 9410
+daughter 9410
+decliner 9410
+lawgiver 9410
+stated 9410
+readable 9410
+attrition 9410
+cascade 9410
+motors 9410
+interrogate 9410
+pests 9410
+stairway 9410
+dopers 9410
+testicle 9410
+Parsifal 9410
+leavings 9410
+postulation 9410
+squeaking 9410
+contrasted 9410
+leftover 9410
+whiteners 9410
+erases 9410
+Punjab 9410
+Merritt 9410
+Quixotism 9410
+sweetish 9410
+dogging 9410
+scornfully 9410
+bellow 9410
+bills 9410
+cupboard 9410
+sureties 9410
+puddings 9410
+fetters 9410
+bivalves 9410
+incurring 9410
+Adolph 9410
+pithed 9410
+Miles 9410
+trimmings 9410
+tragedies 9410
+skulking 9410
+flint 9410
+flopping 9410
+relaxing 9410
+offload 9410
+suites 9410
+lists 9410
+animized 9410
+multilayer 9410
+standardizes 9410
+Judas 9410
+vacuuming 9410
+dentally 9410
+humanness 9410
+inch 9410
+Weissmuller 9410
+irresponsibly 9410
+luckily 9410
+culled 9410
+medical 9410
+bloodbath 9410
+subschema 9410
+animals 9410
+Micronesia 9410
+repetitions 9410
+Antares 9410
+ventilate 9410
+pityingly 9410
+interdependent 9410
+Graves 9410
+neonatal 9410
+chafe 9410
+honoring 9410
+realtor 9410
+elite 9410
+funereal 9410
+abrogating 9410
+sorters 9410
+Conley 9410
+lectured 9410
+Abraham 9410
+Hawaii 9410
+cage 9410
+hushes 9410
+Simla 9410
+reporters 9410
+Dutchman 9410
+descendants 9410
+groupings 9410
+dissociate 9410
+coexist 9410
+Beebe 9410
+Taoism 9410
+Connally 9410
+fetched 9410
+checkpoints 9410
+rusting 9410
+galling 9410
+obliterates 9410
+traitor 9410
+resumes 9410
+analyzable 9410
+terminator 9410
+gritty 9410
+firearm 9410
+minima 9410
+Selfridge 9410
+disable 9410
+witchcraft 9410
+betroth 9410
+Manhattanize 9410
+imprint 9410
+peeked 9410
+swelling 9410
+interrelationships 9410
+riser 9410
+Gandhian 9410
+peacock 9410
+bee 9410
+kanji 9410
+dental 9410
+scarf 9410
+chasm 9410
+insolence 9410
+syndicate 9410
+alike 9410
+imperial 9410
+convulsion 9410
+railway 9410
+validate 9410
+normalizes 9410
+comprehensive 9410
+chewing 9410
+denizen 9410
+schemer 9410
+chronicle 9410
+Kline 9410
+Anatole 9410
+partridges 9410
+brunch 9410
+recruited 9410
+dimensions 9410
+Chicana 9410
+announced 9410
+praised 9410
+employing 9410
+linear 9410
+quagmire 9410
+western 9410
+relishing 9410
+serving 9410
+scheduling 9410
+lore 9410
+eventful 9410
+arteriole 9410
+disentangle 9410
+cured 9410
+Fenton 9410
+avoidable 9410
+drains 9410
+detectably 9410
+husky 9410
+impelling 9410
+undoes 9410
+evened 9410
+squeezes 9410
+destroyer 9410
+rudeness 9410
+beaner 9410
+boorish 9410
+Everhart 9410
+encompass 9410
+mushrooms 9410
+Alison 9410
+externally 9410
+pellagra 9410
+cult 9410
+creek 9410
+Huffman 9410
+Majorca 9410
+governing 9410
+gadfly 9410
+reassigned 9410
+intentness 9410
+craziness 9410
+psychic 9410
+squabbled 9410
+burlesque 9410
+capped 9410
+extracted 9410
+DiMaggio 9410
+exclamation 9410
+subdirectory 9410
+Gothicism 9410
+feminine 9410
+metaphysically 9410
+sanding 9410
+Miltonism 9410
+freakish 9410
+index 9410
+straight 9410
+flurried 9410
+denotative 9410
+coming 9410
+commencements 9410
+gentleman 9410
+gifted 9410
+Shanghais 9410
+sportswriting 9410
+sloping 9410
+navies 9410
+leaflet 9410
+shooter 9410
+Joplin 9410
+babies 9410
+assails 9410
+admiring 9410
+swaying 9410
+Goldstine 9410
+fitting 9410
+Norwalk 9410
+analogy 9410
+deludes 9410
+cokes 9410
+Clayton 9410
+exhausts 9410
+causality 9410
+sating 9410
+icon 9410
+throttles 9410
+communicants 9410
+dehydrate 9410
+priceless 9410
+publicly 9410
+incidentals 9410
+commonplace 9410
+mumbles 9410
+furthermore 9410
+cautioned 9410
+parametrized 9410
+registration 9410
+sadly 9410
+positioning 9410
+babysitting 9410
+eternal 9410
+hoarder 9410
+congregates 9410
+rains 9410
+workers 9410
+sags 9410
+unplug 9410
+garage 9410
+boulder 9410
+specifics 9410
+Teresa 9410
+Winsett 9410
+convenient 9410
+buckboards 9410
+amenities 9410
+resplendent 9410
+sews 9410
+participated 9410
+Simon 9410
+certificates 9410
+Fitzpatrick 9410
+Evanston 9410
+misted 9410
+textures 9410
+save 9410
+count 9410
+rightful 9410
+chaperone 9410
+Lizzy 9410
+clenched 9410
+effortlessly 9410
+accessed 9410
+beaters 9410
+Hornblower 9410
+vests 9410
+indulgences 9410
+infallibly 9410
+unwilling 9410
+excrete 9410
+spools 9410
+crunches 9410
+overestimating 9410
+ineffective 9410
+humiliation 9410
+sophomore 9410
+star 9410
+rifles 9410
+dialysis 9410
+arriving 9410
+indulge 9410
+clockers 9410
+languages 9410
+Antarctica 9410
+percentage 9410
+ceiling 9410
+specification 9410
+regimented 9410
+ciphers 9410
+pictures 9410
+serpents 9410
+allot 9410
+realized 9410
+mayoral 9410
+opaquely 9410
+hostess 9410
+fiftieth 9410
+incorrectly 9410
+decomposition 9410
+stranglings 9410
+mixture 9410
+electroencephalography 9410
+similarities 9410
+charges 9410
+freest 9410
+Greenberg 9410
+tinting 9410
+expelled 9410
+warm 9410
+smoothed 9410
+deductions 9410
+Romano 9410
+bitterroot 9410
+corset 9410
+securing 9410
+environing 9410
+cute 9410
+Crays 9410
+heiress 9410
+inform 9410
+avenge 9410
+universals 9410
+Kinsey 9410
+ravines 9410
+bestseller 9410
+equilibrium 9410
+extents 9410
+relatively 9410
+pressure 9410
+critiques 9410
+befouled 9410
+rightfully 9410
+mechanizing 9410
+Latinizes 9410
+timesharing 9410
+Aden 9410
+embassies 9410
+males 9410
+shapelessly 9410
+mastering 9410
+Newtonian 9410
+finishers 9410
+abates 9410
+teem 9410
+kiting 9410
+stodgy 9410
+feed 9410
+guitars 9410
+airships 9410
+store 9410
+denounces 9410
+Pyle 9410
+Saxony 9410
+serializations 9410
+Peruvian 9410
+taxonomically 9410
+kingdom 9410
+stint 9410
+Sault 9410
+faithful 9410
+Ganymede 9410
+tidiness 9410
+gainful 9410
+contrary 9410
+Tipperary 9410
+tropics 9410
+theorizers 9410
+renew 9410
+already 9410
+terminal 9410
+Hegelian 9410
+hypothesizer 9410
+warningly 9410
+journalizing 9410
+nested 9410
+Lars 9410
+saplings 9410
+foothill 9410
+labeled 9410
+imperiously 9410
+reporters 9410
+furnishings 9410
+precipitable 9410
+discounts 9410
+excises 9410
+Stalin 9410
+despot 9410
+ripeness 9410
+Arabia 9410
+unruly 9410
+mournfulness 9410
+boom 9410
+slaughter 9410
+Sabine 9410
+handy 9410
+rural 9410
+organizer 9410
+shipyard 9410
+civics 9410
+inaccuracy 9410
+rules 9410
+juveniles 9410
+comprised 9410
+investigations 9410
+stabilizes 9410
+seminaries 9410
+Hunter 9410
+sporty 9410
+test 9410
+weasels 9410
+CERN 9410
+tempering 9410
+afore 9410
+Galatean 9410
+techniques 9410
+error 9410
+veranda 9410
+severely 9410
+Cassites 9410
+forthcoming 9410
+guides 9410
+vanish 9410
+lied 9410
+sawtooth 9410
+fated 9410
+gradually 9410
+widens 9410
+preclude 9410
+evenhandedly 9410
+percentage 9410
+disobedience 9410
+humility 9410
+gleaning 9410
+petted 9410
+bloater 9410
+minion 9410
+marginal 9410
+apiary 9410
+measures 9410
+precaution 9410
+repelled 9410
+primary 9410
+coverings 9410
+Artemia 9410
+navigate 9410
+spatial 9410
+Gurkha 9410
+meanwhile 9410
+Melinda 9410
+Butterfield 9410
+Aldrich 9410
+previewing 9410
+glut 9410
+unaffected 9410
+inmate 9410
+mineral 9410
+impending 9410
+meditation 9410
+ideas 9410
+miniaturizes 9410
+lewdly 9410
+title 9410
+youthfulness 9410
+creak 9410
+Chippewa 9410
+clamored 9410
+freezes 9410
+forgivably 9410
+reduce 9410
+McGovern 9410
+Nazis 9410
+epistle 9410
+socializes 9410
+conceptions 9410
+Kevin 9410
+uncovering 9410
+chews 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+raining 9410
+infest 9410
+compartment 9410
+minting 9410
+ducks 9410
+roped 9410
+waltz 9410
+Lillian 9410
+repressions 9410
+chillingly 9410
+noncritical 9410
+lithograph 9410
+spongers 9410
+parenthood 9410
+posed 9410
+instruments 9410
+filial 9410
+fixedly 9410
+relives 9410
+Pandora 9410
+watering 9410
+ungrateful 9410
+secures 9410
+poison 9410
+dusted 9410
+encompasses 9410
+presentation 9410
+Kantian 9410
+select fld3,period,price,price2 from t2,t3 where t2.fld1=t3.t2nr and period >= 1001 and period <= 1002 and t2.companynr = 37 order by fld3,period, price;
+fld3 period price price2
+admonishing 1002 28357832 8723648
+analyzable 1002 28357832 8723648
+annihilates 1001 5987435 234724
+Antares 1002 28357832 8723648
+astound 1001 5987435 234724
+audiology 1001 5987435 234724
+Augustine 1002 28357832 8723648
+Baird 1002 28357832 8723648
+bewilderingly 1001 5987435 234724
+breaking 1001 5987435 234724
+Conley 1001 5987435 234724
+dentally 1002 28357832 8723648
+dissociate 1002 28357832 8723648
+elite 1001 5987435 234724
+eschew 1001 5987435 234724
+Eulerian 1001 5987435 234724
+flanking 1001 5987435 234724
+foldout 1002 28357832 8723648
+funereal 1002 28357832 8723648
+galling 1002 28357832 8723648
+Graves 1001 5987435 234724
+grazing 1001 5987435 234724
+groupings 1001 5987435 234724
+handgun 1001 5987435 234724
+humility 1002 28357832 8723648
+impulsive 1002 28357832 8723648
+inch 1001 5987435 234724
+intelligibility 1001 5987435 234724
+jarring 1001 5987435 234724
+lawgiver 1001 5987435 234724
+lectured 1002 28357832 8723648
+Merritt 1002 28357832 8723648
+neonatal 1001 5987435 234724
+offload 1002 28357832 8723648
+parters 1002 28357832 8723648
+pityingly 1002 28357832 8723648
+puddings 1002 28357832 8723648
+Punjab 1001 5987435 234724
+quitter 1002 28357832 8723648
+realtor 1001 5987435 234724
+relaxing 1001 5987435 234724
+repetitions 1001 5987435 234724
+resumes 1001 5987435 234724
+Romans 1002 28357832 8723648
+rusting 1001 5987435 234724
+scholastics 1001 5987435 234724
+skulking 1002 28357832 8723648
+stated 1002 28357832 8723648
+suites 1002 28357832 8723648
+sureties 1001 5987435 234724
+testicle 1002 28357832 8723648
+tinily 1002 28357832 8723648
+tragedies 1001 5987435 234724
+trimmings 1001 5987435 234724
+vacuuming 1001 5987435 234724
+ventilate 1001 5987435 234724
+wallet 1001 5987435 234724
+Weissmuller 1002 28357832 8723648
+Wotan 1002 28357832 8723648
+select t2.fld1,fld3,period,price,price2 from t2,t3 where t2.fld1>= 18201 and t2.fld1 <= 18811 and t2.fld1=t3.t2nr and period = 1001 and t2.companynr = 37;
+fld1 fld3 period price price2
+018201 relaxing 1001 5987435 234724
+018601 vacuuming 1001 5987435 234724
+018801 inch 1001 5987435 234724
+018811 repetitions 1001 5987435 234724
+create table t4 (
+companynr tinyint(2) unsigned zerofill NOT NULL default '00',
+companyname char(30) NOT NULL default '',
+PRIMARY KEY (companynr),
+UNIQUE KEY companyname(companyname)
+) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames';
+select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
+companynr companyname
+00 Unknown
+29 company 1
+34 company 2
+36 company 3
+37 company 4
+40 company 5
+41 company 6
+50 company 11
+53 company 7
+58 company 8
+65 company 9
+68 company 10
+select SQL_SMALL_RESULT t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
+companynr companyname
+00 Unknown
+29 company 1
+34 company 2
+36 company 3
+37 company 4
+40 company 5
+41 company 6
+50 company 11
+53 company 7
+58 company 8
+65 company 9
+68 company 10
+select * from t1,t1 t12;
+Period Varor_period Period Varor_period
+9410 9412 9410 9412
+select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 250505 and t22.fld1 >= 250501 and t22.fld1 <= 250505;
+fld1 fld1
+250501 250501
+250502 250501
+250503 250501
+250504 250501
+250505 250501
+250501 250502
+250502 250502
+250503 250502
+250504 250502
+250505 250502
+250501 250503
+250502 250503
+250503 250503
+250504 250503
+250505 250503
+250501 250504
+250502 250504
+250503 250504
+250504 250504
+250505 250504
+250501 250505
+250502 250505
+250503 250505
+250504 250505
+250505 250505
+insert into t2 (fld1, companynr) values (999999,99);
+select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
+companynr companyname
+99 NULL
+select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null;
+count(*)
+1199
+explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1200
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists
+select companynr,companyname from t2 left join t4 using (companynr) where companynr is null;
+companynr companyname
+select count(*) from t2 left join t4 using (companynr) where companynr is not null;
+count(*)
+1200
+explain select companynr,companyname from t2 left join t4 using (companynr) where companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+delete from t2 where fld1=999999;
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
+companynr companynr
+37 36
+41 40
+explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
+fld1 companynr fld3 period
+038008 37 reporters 1008
+038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t2.fld1 = 38208 or t2.fld1 = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
+fld1 companynr fld3 period
+038008 37 reporters 1008
+038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t3.t2nr = 38208 or t3.t2nr = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
+fld1 companynr fld3 period
+038008 37 reporters 1008
+038208 37 Selfridge 1008
+select period from t1 where (((period > 0) or period < 10000 or (period = 1900)) and (period=1900 and period <= 1901) or (period=1903 and (period=1903)) and period>=1902) or ((period=1904 or period=1905) or (period=1906 or period>1907)) or (period=1908 and period = 1909);
+period
+9410
+select period from t1 where ((period > 0 and period < 1) or (((period > 0 and period < 100) and (period > 10)) or (period > 10)) or (period > 0 and (period > 5 or period > 6)));
+period
+9410
+select a.fld1 from t2 as a,t2 b where ((a.fld1 = 250501 and a.fld1=b.fld1) or a.fld1=250502 or a.fld1=250503 or (a.fld1=250505 and a.fld1<=b.fld1 and b.fld1>=a.fld1)) and a.fld1=b.fld1;
+fld1
+250501
+250502
+250503
+250505
+select fld1 from t2 where fld1 in (250502,98005,98006,250503,250605,250606) and fld1 >=250502 and fld1 not in (250605,250606);
+fld1
+250502
+250503
+select fld1 from t2 where fld1 between 250502 and 250504;
+fld1
+250502
+250503
+250504
+select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld3 like "L%" or fld3 like "G%")) and fld3 like "L%" ;
+fld3
+label
+labeled
+labeled
+landslide
+laterally
+leaflet
+lewdly
+Lillian
+luckily
+select count(*) from t1;
+count(*)
+1
+select companynr,count(*),sum(fld1) from t2 group by companynr;
+companynr count(*) sum(fld1)
+00 82 10355753
+29 95 14473298
+34 70 17788966
+36 215 22786296
+37 588 83602098
+40 37 6618386
+41 52 12816335
+50 11 1595438
+53 4 793210
+58 23 2254293
+65 10 2284055
+68 12 3097288
+select companynr,count(*) from t2 group by companynr order by companynr desc limit 5;
+companynr count(*)
+68 12
+65 10
+58 23
+53 4
+50 11
+select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";
+count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
+70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
+explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where
+Warnings:
+Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))
+select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
+companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
+00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
+29 95 abut wetness 14473298 152350.5053 8368.5480 70032594.9026
+34 70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
+select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
+companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
+37 1 1 5987435 5987435 5987435 5987435.0000
+37 2 1 28357832 28357832 28357832 28357832.0000
+37 3 1 39654943 39654943 39654943 39654943.0000
+37 11 1 5987435 5987435 5987435 5987435.0000
+37 12 1 28357832 28357832 28357832 28357832.0000
+37 13 1 39654943 39654943 39654943 39654943.0000
+37 21 1 5987435 5987435 5987435 5987435.0000
+37 22 1 28357832 28357832 28357832 28357832.0000
+37 23 1 39654943 39654943 39654943 39654943.0000
+37 31 1 5987435 5987435 5987435 5987435.0000
+select /*! SQL_SMALL_RESULT */ companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
+companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
+37 1 1 5987435 5987435 5987435 5987435.0000
+37 2 1 28357832 28357832 28357832 28357832.0000
+37 3 1 39654943 39654943 39654943 39654943.0000
+37 11 1 5987435 5987435 5987435 5987435.0000
+37 12 1 28357832 28357832 28357832 28357832.0000
+37 13 1 39654943 39654943 39654943 39654943.0000
+37 21 1 5987435 5987435 5987435 5987435.0000
+37 22 1 28357832 28357832 28357832 28357832.0000
+37 23 1 39654943 39654943 39654943 39654943.0000
+37 31 1 5987435 5987435 5987435 5987435.0000
+select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ;
+companynr count(price) sum(price) min(price) max(price) avg(price)
+37 12543 309394878010 5987435 39654943 24666736.6667
+78 8362 414611089292 726498 98439034 49582766.0000
+101 4181 3489454238 834598 834598 834598.0000
+154 4181 4112197254950 983543950 983543950 983543950.0000
+311 4181 979599938 234298 234298 234298.0000
+447 4181 9929180954 2374834 2374834 2374834.0000
+512 4181 3288532102 786542 786542 786542.0000
+select distinct mod(companynr,10) from t4 group by companynr;
+mod(companynr,10)
+0
+9
+4
+6
+7
+1
+3
+8
+5
+select distinct 1 from t4 group by companynr;
+1
+1
+select count(distinct fld1) from t2;
+count(distinct fld1)
+1199
+select companynr,count(distinct fld1) from t2 group by companynr;
+companynr count(distinct fld1)
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(*) from t2 group by companynr;
+companynr count(*)
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(distinct concat(fld1,repeat(65,1000))) from t2 group by companynr;
+companynr count(distinct concat(fld1,repeat(65,1000)))
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(distinct concat(fld1,repeat(65,200))) from t2 group by companynr;
+companynr count(distinct concat(fld1,repeat(65,200)))
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(distinct floor(fld1/100)) from t2 group by companynr;
+companynr count(distinct floor(fld1/100))
+00 47
+29 35
+34 14
+36 69
+37 108
+40 16
+41 11
+50 9
+53 1
+58 1
+65 1
+68 1
+select companynr,count(distinct concat(repeat(65,1000),floor(fld1/100))) from t2 group by companynr;
+companynr count(distinct concat(repeat(65,1000),floor(fld1/100)))
+00 47
+29 35
+34 14
+36 69
+37 108
+40 16
+41 11
+50 9
+53 1
+58 1
+65 1
+68 1
+select sum(fld1),fld3 from t2 where fld3="Romans" group by fld1 limit 10;
+sum(fld1) fld3
+11402 Romans
+select name,count(*) from t3 where name='cloakroom' group by name;
+name count(*)
+cloakroom 4181
+select name,count(*) from t3 where name='cloakroom' and price>10 group by name;
+name count(*)
+cloakroom 4181
+select count(*) from t3 where name='cloakroom' and price2=823742;
+count(*)
+4181
+select name,count(*) from t3 where name='cloakroom' and price2=823742 group by name;
+name count(*)
+cloakroom 4181
+select name,count(*) from t3 where name >= "extramarital" and price <= 39654943 group by name;
+name count(*)
+extramarital 4181
+gazer 4181
+gems 4181
+Iranizes 4181
+spates 4181
+tucked 4181
+violinist 4181
+select t2.fld3,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
+fld3 count(*)
+spates 4181
+select companynr|0,companyname from t4 group by 1;
+companynr|0 companyname
+0 Unknown
+29 company 1
+34 company 2
+36 company 3
+37 company 4
+40 company 5
+41 company 6
+50 company 11
+53 company 7
+58 company 8
+65 company 9
+68 company 10
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by t2.companynr order by companyname;
+companynr companyname count(*)
+29 company 1 95
+68 company 10 12
+50 company 11 11
+34 company 2 70
+36 company 3 215
+37 company 4 588
+40 company 5 37
+41 company 6 52
+53 company 7 4
+58 company 8 23
+65 company 9 10
+00 Unknown 82
+select t2.fld1,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
+fld1 count(*)
+158402 4181
+select sum(Period)/count(*) from t1;
+sum(Period)/count(*)
+9410.0000
+select companynr,count(price) as "count",sum(price) as "sum" ,abs(sum(price)/count(price)-avg(price)) as "diff",(0+count(price))*companynr as func from t3 group by companynr;
+companynr count sum diff func
+37 12543 309394878010 0.0000 464091
+78 8362 414611089292 0.0000 652236
+101 4181 3489454238 0.0000 422281
+154 4181 4112197254950 0.0000 643874
+311 4181 979599938 0.0000 1300291
+447 4181 9929180954 0.0000 1868907
+512 4181 3288532102 0.0000 2140672
+select companynr,sum(price)/count(price) as avg from t3 group by companynr having avg > 70000000 order by avg;
+companynr avg
+154 983543950.0000
+select companynr,count(*) from t2 group by companynr order by 2 desc;
+companynr count(*)
+37 588
+36 215
+29 95
+00 82
+34 70
+41 52
+40 37
+58 23
+68 12
+50 11
+65 10
+53 4
+select companynr,count(*) from t2 where companynr > 40 group by companynr order by 2 desc;
+companynr count(*)
+41 52
+58 23
+68 12
+50 11
+65 10
+53 4
+select t2.fld4,t2.fld1,count(price),sum(price),min(price),max(price),avg(price) from t3,t2 where t3.companynr = 37 and t2.fld1 = t3.t2nr group by fld1,t2.fld4;
+fld4 fld1 count(price) sum(price) min(price) max(price) avg(price)
+teethe 000001 1 5987435 5987435 5987435 5987435.0000
+dreaded 011401 1 5987435 5987435 5987435 5987435.0000
+scholastics 011402 1 28357832 28357832 28357832 28357832.0000
+audiology 011403 1 39654943 39654943 39654943 39654943.0000
+wallet 011501 1 5987435 5987435 5987435 5987435.0000
+parters 011701 1 5987435 5987435 5987435 5987435.0000
+eschew 011702 1 28357832 28357832 28357832 28357832.0000
+quitter 011703 1 39654943 39654943 39654943 39654943.0000
+neat 012001 1 5987435 5987435 5987435 5987435.0000
+Steinberg 012003 1 39654943 39654943 39654943 39654943.0000
+balled 012301 1 5987435 5987435 5987435 5987435.0000
+persist 012302 1 28357832 28357832 28357832 28357832.0000
+attainments 012303 1 39654943 39654943 39654943 39654943.0000
+capably 012501 1 5987435 5987435 5987435 5987435.0000
+impulsive 012602 1 28357832 28357832 28357832 28357832.0000
+starlet 012603 1 39654943 39654943 39654943 39654943.0000
+featherweight 012701 1 5987435 5987435 5987435 5987435.0000
+pessimist 012702 1 28357832 28357832 28357832 28357832.0000
+daughter 012703 1 39654943 39654943 39654943 39654943.0000
+lawgiver 013601 1 5987435 5987435 5987435 5987435.0000
+stated 013602 1 28357832 28357832 28357832 28357832.0000
+readable 013603 1 39654943 39654943 39654943 39654943.0000
+testicle 013801 1 5987435 5987435 5987435 5987435.0000
+Parsifal 013802 1 28357832 28357832 28357832 28357832.0000
+leavings 013803 1 39654943 39654943 39654943 39654943.0000
+squeaking 013901 1 5987435 5987435 5987435 5987435.0000
+contrasted 016001 1 5987435 5987435 5987435 5987435.0000
+leftover 016201 1 5987435 5987435 5987435 5987435.0000
+whiteners 016202 1 28357832 28357832 28357832 28357832.0000
+erases 016301 1 5987435 5987435 5987435 5987435.0000
+Punjab 016302 1 28357832 28357832 28357832 28357832.0000
+Merritt 016303 1 39654943 39654943 39654943 39654943.0000
+sweetish 018001 1 5987435 5987435 5987435 5987435.0000
+dogging 018002 1 28357832 28357832 28357832 28357832.0000
+scornfully 018003 1 39654943 39654943 39654943 39654943.0000
+fetters 018012 1 28357832 28357832 28357832 28357832.0000
+bivalves 018013 1 39654943 39654943 39654943 39654943.0000
+skulking 018021 1 5987435 5987435 5987435 5987435.0000
+flint 018022 1 28357832 28357832 28357832 28357832.0000
+flopping 018023 1 39654943 39654943 39654943 39654943.0000
+Judas 018032 1 28357832 28357832 28357832 28357832.0000
+vacuuming 018033 1 39654943 39654943 39654943 39654943.0000
+medical 018041 1 5987435 5987435 5987435 5987435.0000
+bloodbath 018042 1 28357832 28357832 28357832 28357832.0000
+subschema 018043 1 39654943 39654943 39654943 39654943.0000
+interdependent 018051 1 5987435 5987435 5987435 5987435.0000
+Graves 018052 1 28357832 28357832 28357832 28357832.0000
+neonatal 018053 1 39654943 39654943 39654943 39654943.0000
+sorters 018061 1 5987435 5987435 5987435 5987435.0000
+epistle 018062 1 28357832 28357832 28357832 28357832.0000
+Conley 018101 1 5987435 5987435 5987435 5987435.0000
+lectured 018102 1 28357832 28357832 28357832 28357832.0000
+Abraham 018103 1 39654943 39654943 39654943 39654943.0000
+cage 018201 1 5987435 5987435 5987435 5987435.0000
+hushes 018202 1 28357832 28357832 28357832 28357832.0000
+Simla 018402 1 28357832 28357832 28357832 28357832.0000
+reporters 018403 1 39654943 39654943 39654943 39654943.0000
+coexist 018601 1 5987435 5987435 5987435 5987435.0000
+Beebe 018602 1 28357832 28357832 28357832 28357832.0000
+Taoism 018603 1 39654943 39654943 39654943 39654943.0000
+Connally 018801 1 5987435 5987435 5987435 5987435.0000
+fetched 018802 1 28357832 28357832 28357832 28357832.0000
+checkpoints 018803 1 39654943 39654943 39654943 39654943.0000
+gritty 018811 1 5987435 5987435 5987435 5987435.0000
+firearm 018812 1 28357832 28357832 28357832 28357832.0000
+minima 019101 1 5987435 5987435 5987435 5987435.0000
+Selfridge 019102 1 28357832 28357832 28357832 28357832.0000
+disable 019103 1 39654943 39654943 39654943 39654943.0000
+witchcraft 019201 1 5987435 5987435 5987435 5987435.0000
+betroth 030501 1 5987435 5987435 5987435 5987435.0000
+Manhattanize 030502 1 28357832 28357832 28357832 28357832.0000
+imprint 030503 1 39654943 39654943 39654943 39654943.0000
+swelling 031901 1 5987435 5987435 5987435 5987435.0000
+interrelationships 036001 1 5987435 5987435 5987435 5987435.0000
+riser 036002 1 28357832 28357832 28357832 28357832.0000
+bee 038001 1 5987435 5987435 5987435 5987435.0000
+kanji 038002 1 28357832 28357832 28357832 28357832.0000
+dental 038003 1 39654943 39654943 39654943 39654943.0000
+railway 038011 1 5987435 5987435 5987435 5987435.0000
+validate 038012 1 28357832 28357832 28357832 28357832.0000
+normalizes 038013 1 39654943 39654943 39654943 39654943.0000
+Kline 038101 1 5987435 5987435 5987435 5987435.0000
+Anatole 038102 1 28357832 28357832 28357832 28357832.0000
+partridges 038103 1 39654943 39654943 39654943 39654943.0000
+recruited 038201 1 5987435 5987435 5987435 5987435.0000
+dimensions 038202 1 28357832 28357832 28357832 28357832.0000
+Chicana 038203 1 39654943 39654943 39654943 39654943.0000
+select t3.companynr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 group by companynr,fld3;
+companynr fld3 sum(price)
+512 boat 786542
+512 capably 786542
+512 cupboard 786542
+512 decliner 786542
+512 descendants 786542
+512 dopers 786542
+512 erases 786542
+512 Micronesia 786542
+512 Miles 786542
+512 skies 786542
+select t2.companynr,count(*),min(fld3),max(fld3),sum(price),avg(price) from t2,t3 where t3.companynr >= 30 and t3.companynr <= 58 and t3.t2nr = t2.fld1 and 1+1=2 group by t2.companynr;
+companynr count(*) min(fld3) max(fld3) sum(price) avg(price)
+00 1 Omaha Omaha 5987435 5987435.0000
+36 1 dubbed dubbed 28357832 28357832.0000
+37 83 Abraham Wotan 1908978016 22999735.1325
+50 2 scribbled tapestry 68012775 34006387.5000
+select t3.companynr+0,t3.t2nr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 37 group by 1,t3.t2nr,fld3,fld3,fld3,fld3,fld3 order by fld1;
+t3.companynr+0 t2nr fld3 sum(price)
+37 1 Omaha 5987435
+37 11401 breaking 5987435
+37 11402 Romans 28357832
+37 11403 intercepted 39654943
+37 11501 bewilderingly 5987435
+37 11701 astound 5987435
+37 11702 admonishing 28357832
+37 11703 sumac 39654943
+37 12001 flanking 5987435
+37 12003 combed 39654943
+37 12301 Eulerian 5987435
+37 12302 dubbed 28357832
+37 12303 Kane 39654943
+37 12501 annihilates 5987435
+37 12602 Wotan 28357832
+37 12603 snatching 39654943
+37 12701 grazing 5987435
+37 12702 Baird 28357832
+37 12703 celery 39654943
+37 13601 handgun 5987435
+37 13602 foldout 28357832
+37 13603 mystic 39654943
+37 13801 intelligibility 5987435
+37 13802 Augustine 28357832
+37 13803 teethe 39654943
+37 13901 scholastics 5987435
+37 16001 audiology 5987435
+37 16201 wallet 5987435
+37 16202 parters 28357832
+37 16301 eschew 5987435
+37 16302 quitter 28357832
+37 16303 neat 39654943
+37 18001 jarring 5987435
+37 18002 tinily 28357832
+37 18003 balled 39654943
+37 18012 impulsive 28357832
+37 18013 starlet 39654943
+37 18021 lawgiver 5987435
+37 18022 stated 28357832
+37 18023 readable 39654943
+37 18032 testicle 28357832
+37 18033 Parsifal 39654943
+37 18041 Punjab 5987435
+37 18042 Merritt 28357832
+37 18043 Quixotism 39654943
+37 18051 sureties 5987435
+37 18052 puddings 28357832
+37 18053 tapestry 39654943
+37 18061 trimmings 5987435
+37 18062 humility 28357832
+37 18101 tragedies 5987435
+37 18102 skulking 28357832
+37 18103 flint 39654943
+37 18201 relaxing 5987435
+37 18202 offload 28357832
+37 18402 suites 28357832
+37 18403 lists 39654943
+37 18601 vacuuming 5987435
+37 18602 dentally 28357832
+37 18603 humanness 39654943
+37 18801 inch 5987435
+37 18802 Weissmuller 28357832
+37 18803 irresponsibly 39654943
+37 18811 repetitions 5987435
+37 18812 Antares 28357832
+37 19101 ventilate 5987435
+37 19102 pityingly 28357832
+37 19103 interdependent 39654943
+37 19201 Graves 5987435
+37 30501 neonatal 5987435
+37 30502 scribbled 28357832
+37 30503 chafe 39654943
+37 31901 realtor 5987435
+37 36001 elite 5987435
+37 36002 funereal 28357832
+37 38001 Conley 5987435
+37 38002 lectured 28357832
+37 38003 Abraham 39654943
+37 38011 groupings 5987435
+37 38012 dissociate 28357832
+37 38013 coexist 39654943
+37 38101 rusting 5987435
+37 38102 galling 28357832
+37 38103 obliterates 39654943
+37 38201 resumes 5987435
+37 38202 analyzable 28357832
+37 38203 terminator 39654943
+select sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1= t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008;
+sum(price)
+234298
+select t2.fld1,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1 = t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008 or t3.t2nr = t2.fld1 and t2.fld1 = 38008 group by t2.fld1;
+fld1 sum(price)
+038008 234298
+explain select fld3 from t2 where 1>2 or 2>3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+explain select fld3 from t2 where fld1=fld1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502;
+companynr fld1
+34 250501
+34 250502
+select companynr,fld1 from t2 WHERE fld1>=250501 HAVING fld1<=250502;
+companynr fld1
+34 250501
+34 250502
+select companynr,count(*) as count,sum(fld1) as sum from t2 group by companynr having count > 40 and sum/count >= 120000;
+companynr count sum
+00 82 10355753
+29 95 14473298
+34 70 17788966
+37 588 83602098
+41 52 12816335
+select companynr from t2 group by companynr having count(*) > 40 and sum(fld1)/count(*) >= 120000 ;
+companynr
+00
+29
+34
+37
+41
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by companyname having t2.companynr >= 40;
+companynr companyname count(*)
+68 company 10 12
+50 company 11 11
+40 company 5 37
+41 company 6 52
+53 company 7 4
+58 company 8 23
+65 company 9 10
+select count(*) from t2;
+count(*)
+1199
+select count(*) from t2 where fld1 < 098024;
+count(*)
+387
+select min(fld1) from t2 where fld1>= 098024;
+min(fld1)
+98024
+select max(fld1) from t2 where fld1>= 098024;
+max(fld1)
+1232609
+select count(*) from t3 where price2=76234234;
+count(*)
+4181
+select count(*) from t3 where companynr=512 and price2=76234234;
+count(*)
+4181
+explain select min(fld1),max(fld1),count(*) from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+select min(fld1),max(fld1),count(*) from t2;
+min(fld1) max(fld1) count(*)
+0 1232609 1199
+select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742;
+min(t2nr) max(t2nr)
+2115 2115
+select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78;
+count(*) min(t2nr) max(t2nr)
+4181 4 41804
+select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20;
+t2nr count(*)
+9 1
+19 1
+29 1
+39 1
+49 1
+59 1
+69 1
+79 1
+89 1
+99 1
+109 1
+119 1
+129 1
+139 1
+149 1
+159 1
+169 1
+179 1
+189 1
+199 1
+select max(t2nr) from t3 where price=983543950;
+max(t2nr)
+41807
+select t1.period from t3 = t1 limit 1;
+period
+1001
+select t1.period from t1 as t1 limit 1;
+period
+9410
+select t1.period as "Nuvarande period" from t1 as t1 limit 1;
+Nuvarande period
+9410
+select period as ok_period from t1 limit 1;
+ok_period
+9410
+select period as ok_period from t1 group by ok_period limit 1;
+ok_period
+9410
+select 1+1 as summa from t1 group by summa limit 1;
+summa
+2
+select period as "Nuvarande period" from t1 group by "Nuvarande period" limit 1;
+Nuvarande period
+9410
+show tables;
+Tables_in_test
+t1
+t2
+t3
+t4
+show tables from test like "s%";
+Tables_in_test (s%)
+show tables from test like "t?";
+Tables_in_test (t?)
+show full columns from t2;
+Field Type Collation Null Key Default Extra Privileges Comment
+auto int(11) NULL NO PRI NULL auto_increment #
+fld1 int(6) unsigned zerofill NULL NO UNI 000000 #
+companynr tinyint(2) unsigned zerofill NULL NO 00 #
+fld3 char(30) latin1_swedish_ci NO MUL #
+fld4 char(35) latin1_swedish_ci NO #
+fld5 char(35) latin1_swedish_ci NO #
+fld6 char(4) latin1_swedish_ci NO #
+show full columns from t2 from test like 'f%';
+Field Type Collation Null Key Default Extra Privileges Comment
+fld1 int(6) unsigned zerofill NULL NO UNI 000000 #
+fld3 char(30) latin1_swedish_ci NO MUL #
+fld4 char(35) latin1_swedish_ci NO #
+fld5 char(35) latin1_swedish_ci NO #
+fld6 char(4) latin1_swedish_ci NO #
+show full columns from t2 from test like 's%';
+Field Type Collation Null Key Default Extra Privileges Comment
+show keys from t2;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE
+t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE
+t2 1 fld3 1 fld3 A NULL NULL NULL BTREE
+drop table t4, t3, t2, t1;
+DO 1;
+DO benchmark(100,1+1),1,1;
+do default;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+do foobar;
+ERROR 42S22: Unknown column 'foobar' in 'field list'
+CREATE TABLE t1 (
+id mediumint(8) unsigned NOT NULL auto_increment,
+pseudo varchar(35) NOT NULL default '',
+PRIMARY KEY (id),
+UNIQUE KEY pseudo (pseudo)
+);
+INSERT INTO t1 (pseudo) VALUES ('test');
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 1 as rnd1 from t1 where rand() > 2;
+rnd1
+DROP TABLE t1;
+CREATE TABLE t1 (gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL);
+CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35);
+SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'wrong-date-value' AND b.sampletime < 'wrong-date-value' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
+gvid the_success the_fail the_size the_time
+Warnings:
+Warning 1292 Incorrect datetime value: 'wrong-date-value' for column 'sampletime' at row 1
+Warning 1292 Incorrect datetime value: 'wrong-date-value' for column 'sampletime' at row 1
+SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= NULL AND b.sampletime < NULL AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
+gvid the_success the_fail the_size the_time
+DROP TABLE t1,t2;
+create table t1 ( A_Id bigint(20) NOT NULL default '0', A_UpdateBy char(10) NOT NULL default '', A_UpdateDate bigint(20) NOT NULL default '0', A_UpdateSerial int(11) NOT NULL default '0', other_types bigint(20) NOT NULL default '0', wss_type bigint(20) NOT NULL default '0');
+INSERT INTO t1 VALUES (102935998719055004,'brade',1029359987,2,102935229116544068,102935229216544093);
+select wss_type from t1 where wss_type ='102935229216544106';
+wss_type
+select wss_type from t1 where wss_type ='102935229216544105';
+wss_type
+select wss_type from t1 where wss_type ='102935229216544104';
+wss_type
+select wss_type from t1 where wss_type ='102935229216544093';
+wss_type
+102935229216544093
+select wss_type from t1 where wss_type =102935229216544093;
+wss_type
+102935229216544093
+drop table t1;
+select 1+2,"aaaa",3.13*2.0 into @a,@b,@c;
+select @a;
+@a
+3
+select @b;
+@b
+aaaa
+select @c;
+@c
+6.260
+create table t1 (a int not null auto_increment primary key);
+insert into t1 values ();
+insert into t1 values ();
+insert into t1 values ();
+select * from (t1 as t2 left join t1 as t3 using (a)), t1;
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from t1, (t1 as t2 left join t1 as t3 using (a));
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) straight_join t1;
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from t1 straight_join (t1 as t2 left join t1 as t3 using (a));
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1;
+a a
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+2 1
+3 1
+2 2
+3 2
+2 3
+3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 using ( a );
+a
+1
+2
+3
+select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) left outer join t1 on t1.a>1;
+a a
+1 2
+1 3
+2 2
+2 3
+3 2
+3 3
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+1 NULL
+2 1
+2 2
+2 3
+3 1
+3 2
+3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) left join t1 using ( a );
+a
+1
+2
+3
+select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+a
+1
+2
+3
+select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a));
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1;
+a a
+NULL 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+2 1
+3 1
+2 2
+3 2
+2 3
+3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a );
+a
+1
+2
+3
+select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) natural right join t1;
+a
+1
+2
+3
+select * from t1 natural right join (t1 as t2 left join t1 as t3 using (a));
+a
+1
+2
+3
+select * from t1 natural join (t1 as t2 left join t1 as t3 using (a));
+a
+1
+2
+3
+select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1;
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 ( aa char(2), id int(11) NOT NULL auto_increment, t2_id int(11) NOT NULL default '0', PRIMARY KEY (id), KEY replace_id (t2_id)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ("1",8264,2506),("2",8299,2517),("3",8301,2518),("4",8302,2519),("5",8303,2520),("6",8304,2521),("7",8305,2522);
+CREATE TABLE t2 ( id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (2517), (2518), (2519), (2520), (2521), (2522);
+select * from t1, t2 WHERE t1.t2_id = t2.id and t1.t2_id > 0 order by t1.id LIMIT 0, 5;
+aa id t2_id id
+2 8299 2517 2517
+3 8301 2518 2518
+4 8302 2519 2519
+5 8303 2520 2520
+6 8304 2521 2521
+drop table t1,t2;
+create table t1 (id1 int NOT NULL);
+create table t2 (id2 int NOT NULL);
+create table t3 (id3 int NOT NULL);
+create table t4 (id4 int NOT NULL, id44 int NOT NULL, KEY (id4));
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t2 values (1);
+insert into t4 values (1,1);
+explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
+left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t4 const id4 NULL NULL NULL 1
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where
+select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
+left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
+id1 id2 id3 id4 id44
+1 1 NULL NULL NULL
+drop table t1,t2,t3,t4;
+create table t1(s varchar(10) not null);
+create table t2(s varchar(10) not null primary key);
+create table t3(s varchar(10) not null primary key);
+insert into t1 values ('one\t'), ('two\t');
+insert into t2 values ('one\r'), ('two\t');
+insert into t3 values ('one '), ('two\t');
+select * from t1 where s = 'one';
+s
+select * from t2 where s = 'one';
+s
+select * from t3 where s = 'one';
+s
+one
+select * from t1,t2 where t1.s = t2.s;
+s s
+two two
+select * from t2,t3 where t2.s = t3.s;
+s s
+two two
+drop table t1, t2, t3;
+create table t1 (a integer, b integer, index(a), index(b));
+create table t2 (c integer, d integer, index(c), index(d));
+insert into t1 values (1,2), (2,2), (3,2), (4,2);
+insert into t2 values (1,3), (2,3), (3,4), (4,4);
+explain select * from t1 left join t2 on a=c where d in (4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref c,d d 5 const 2 Using where
+1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
+select * from t1 left join t2 on a=c where d in (4);
+a b c d
+3 2 3 4
+4 2 4 4
+explain select * from t1 left join t2 on a=c where d = 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref c,d d 5 const 2 Using where
+1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer
+select * from t1 left join t2 on a=c where d = 4;
+a b c d
+3 2 3 4
+4 2 4 4
+drop table t1, t2;
+CREATE TABLE t1 (
+i int(11) NOT NULL default '0',
+c char(10) NOT NULL default '',
+PRIMARY KEY (i),
+UNIQUE KEY c (c)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,'a');
+INSERT INTO t1 VALUES (2,'b');
+INSERT INTO t1 VALUES (3,'c');
+EXPLAIN SELECT i FROM t1 WHERE i=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+DROP TABLE t1;
+CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
+CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
+INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
+INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ref a a 23 test.t1.a 2
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ref a a 23 test.t1.a 2
+DROP TABLE t1, t2;
+CREATE TABLE t1 ( city char(30) );
+INSERT INTO t1 VALUES ('London');
+INSERT INTO t1 VALUES ('Paris');
+SELECT * FROM t1 WHERE city='London';
+city
+London
+SELECT * FROM t1 WHERE city='london';
+city
+London
+EXPLAIN SELECT * FROM t1 WHERE city='London' AND city='london';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE city='London' AND city='london';
+city
+London
+EXPLAIN SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London';
+city
+London
+DROP TABLE t1;
+create table t1 (a int(11) unsigned, b int(11) unsigned);
+insert into t1 values (1,0), (1,1), (1,2);
+select a-b from t1 order by 1;
+a-b
+0
+1
+18446744073709551615
+select a-b , (a-b < 0) from t1 order by 1;
+a-b (a-b < 0)
+0 0
+1 0
+18446744073709551615 0
+select a-b as d, (a-b >= 0), b from t1 group by b having d >= 0;
+d (a-b >= 0) b
+1 1 0
+0 1 1
+18446744073709551615 1 2
+select cast((a - b) as unsigned) from t1 order by 1;
+cast((a - b) as unsigned)
+0
+1
+18446744073709551615
+drop table t1;
+create table t1 (a int(11));
+select all all * from t1;
+a
+select distinct distinct * from t1;
+a
+select all distinct * from t1;
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+select distinct all * from t1;
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+drop table t1;
+CREATE TABLE t1 (
+kunde_intern_id int(10) unsigned NOT NULL default '0',
+kunde_id int(10) unsigned NOT NULL default '0',
+FK_firma_id int(10) unsigned NOT NULL default '0',
+aktuell enum('Ja','Nein') NOT NULL default 'Ja',
+vorname varchar(128) NOT NULL default '',
+nachname varchar(128) NOT NULL default '',
+geloescht enum('Ja','Nein') NOT NULL default 'Nein',
+firma varchar(128) NOT NULL default ''
+);
+INSERT INTO t1 VALUES
+(3964,3051,1,'Ja','Vorname1','1Nachname','Nein','Print Schau XXXX'),
+(3965,3051111,1,'Ja','Vorname1111','1111Nachname','Nein','Print Schau XXXX');
+SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname, geloescht FROM t1
+WHERE
+(
+(
+( '' != '' AND firma LIKE CONCAT('%', '', '%'))
+OR
+(vorname LIKE CONCAT('%', 'Vorname1', '%') AND
+nachname LIKE CONCAT('%', '1Nachname', '%') AND
+'Vorname1' != '' AND 'xxxx' != '')
+)
+AND
+(
+aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2
+)
+)
+;
+kunde_id FK_firma_id aktuell vorname nachname geloescht
+SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname,
+geloescht FROM t1
+WHERE
+(
+(
+aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2
+)
+AND
+(
+( '' != '' AND firma LIKE CONCAT('%', '', '%') )
+OR
+( vorname LIKE CONCAT('%', 'Vorname1', '%') AND
+nachname LIKE CONCAT('%', '1Nachname', '%') AND 'Vorname1' != '' AND
+'xxxx' != '')
+)
+)
+;
+kunde_id FK_firma_id aktuell vorname nachname geloescht
+SELECT COUNT(*) FROM t1 WHERE
+( 0 OR (vorname LIKE '%Vorname1%' AND nachname LIKE '%1Nachname%' AND 1))
+AND FK_firma_id = 2;
+COUNT(*)
+0
+drop table t1;
+CREATE TABLE t1 (b BIGINT(20) UNSIGNED NOT NULL, PRIMARY KEY (b));
+INSERT INTO t1 VALUES (0x8000000000000000);
+SELECT b FROM t1 WHERE b=0x8000000000000000;
+b
+9223372036854775808
+DROP TABLE t1;
+CREATE TABLE `t1` ( `gid` int(11) default NULL, `uid` int(11) default NULL);
+CREATE TABLE `t2` ( `ident` int(11) default NULL, `level` char(16) default NULL);
+INSERT INTO `t2` VALUES (0,'READ');
+CREATE TABLE `t3` ( `id` int(11) default NULL, `name` char(16) default NULL);
+INSERT INTO `t3` VALUES (1,'fs');
+select * from t3 left join t1 on t3.id = t1.uid, t2 where t2.ident in (0, t1.gid, t3.id, 0);
+id name gid uid ident level
+1 fs NULL NULL 0 READ
+drop table t1,t2,t3;
+CREATE TABLE t1 (
+acct_id int(11) NOT NULL default '0',
+profile_id smallint(6) default NULL,
+UNIQUE KEY t1$acct_id (acct_id),
+KEY t1$profile_id (profile_id)
+);
+INSERT INTO t1 VALUES (132,17),(133,18);
+CREATE TABLE t2 (
+profile_id smallint(6) default NULL,
+queue_id int(11) default NULL,
+seq int(11) default NULL,
+KEY t2$queue_id (queue_id)
+);
+INSERT INTO t2 VALUES (17,31,4),(17,30,3),(17,36,2),(17,37,1);
+CREATE TABLE t3 (
+id int(11) NOT NULL default '0',
+qtype int(11) default NULL,
+seq int(11) default NULL,
+warn_lvl int(11) default NULL,
+crit_lvl int(11) default NULL,
+rr1 tinyint(4) NOT NULL default '0',
+rr2 int(11) default NULL,
+default_queue tinyint(4) NOT NULL default '0',
+KEY t3$qtype (qtype),
+KEY t3$id (id)
+);
+INSERT INTO t3 VALUES (30,1,29,NULL,NULL,0,NULL,0),(31,1,28,NULL,NULL,0,NULL,0),
+(36,1,34,NULL,NULL,0,NULL,0),(37,1,35,NULL,NULL,0,121,0);
+SELECT COUNT(*) FROM t1 a STRAIGHT_JOIN t2 pq STRAIGHT_JOIN t3 q
+WHERE
+(pq.profile_id = a.profile_id) AND (a.acct_id = 132) AND
+(pq.queue_id = q.id) AND (q.rr1 <> 1);
+COUNT(*)
+4
+drop table t1,t2,t3;
+create table t1 (f1 int);
+insert into t1 values (1),(NULL);
+create table t2 (f2 int, f3 int, f4 int);
+create index idx1 on t2 (f4);
+insert into t2 values (1,2,3),(2,4,6);
+select A.f2 from t1 left join t2 A on A.f2 = f1 where A.f3=(select min(f3)
+from t2 C where A.f4 = C.f4) or A.f3 IS NULL;
+f2
+1
+NULL
+drop table t1,t2;
+create table t2 (a tinyint unsigned);
+create index t2i on t2(a);
+insert into t2 values (0), (254), (255);
+explain select * from t2 where a > -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index t2i t2i 2 NULL 3 Using where; Using index
+select * from t2 where a > -1;
+a
+0
+254
+255
+drop table t2;
+CREATE TABLE t1 (a int, b int, c int);
+INSERT INTO t1
+SELECT 50, 3, 3 FROM DUAL
+WHERE NOT EXISTS
+(SELECT * FROM t1 WHERE a = 50 AND b = 3);
+SELECT * FROM t1;
+a b c
+50 3 3
+INSERT INTO t1
+SELECT 50, 3, 3 FROM DUAL
+WHERE NOT EXISTS
+(SELECT * FROM t1 WHERE a = 50 AND b = 3);
+select found_rows();
+found_rows()
+0
+SELECT * FROM t1;
+a b c
+50 3 3
+select count(*) from t1;
+count(*)
+1
+select found_rows();
+found_rows()
+1
+select count(*) from t1 limit 2,3;
+count(*)
+select found_rows();
+found_rows()
+0
+select SQL_CALC_FOUND_ROWS count(*) from t1 limit 2,3;
+count(*)
+select found_rows();
+found_rows()
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+(SELECT a, b AS c FROM t1) ORDER BY c+1;
+a c
+(SELECT a, b AS c FROM t1) ORDER BY b+1;
+a c
+SELECT a, b AS c FROM t1 ORDER BY c+1;
+a c
+SELECT a, b AS c FROM t1 ORDER BY b+1;
+a c
+drop table t1;
+create table t1(f1 int, f2 int);
+create table t2(f3 int);
+select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,1));
+f1
+select f1 from t1,t2 where f1=f2 and (f1,NULL) = ((1,1));
+f1
+select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,NULL));
+f1
+insert into t1 values(1,1),(2,null);
+insert into t2 values(2);
+select * from t1,t2 where f1=f3 and (f1,f2) = (2,null);
+f1 f2 f3
+select * from t1,t2 where f1=f3 and (f1,f2) <=> (2,null);
+f1 f2 f3
+2 NULL 2
+drop table t1,t2;
+create table t1 (f1 int not null auto_increment primary key, f2 varchar(10));
+create table t11 like t1;
+insert into t1 values(1,""),(2,"");
+show table status like 't1%';
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+t1 MyISAM 10 Dynamic 2 20 X X X X X X X X latin1_swedish_ci NULL
+t11 MyISAM 10 Dynamic 0 0 X X X X X X X X latin1_swedish_ci NULL
+select 123 as a from t1 where f1 is null;
+a
+drop table t1,t11;
+CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL, UNIQUE idx (a,b) );
+INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4);
+CREATE TABLE t2 ( a INT NOT NULL, b INT NOT NULL, e INT );
+INSERT INTO t2 VALUES ( 1,10,1), (1,10,2), (1,11,1), (1,11,2), (1,2,1), (1,2,2),(1,2,3);
+SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2 LEFT JOIN
+t1 ON t2.a = t1.a AND t2.b = t1.b GROUP BY a, b, c;
+a b c d
+1 2 1 1
+1 2 2 1
+1 2 3 1
+1 10 2
+1 11 2
+SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2 LEFT JOIN
+t1 ON t2.a = t1.a AND t2.b = t1.b GROUP BY t1.a, t1.b, c;
+a b c d
+1 10 4
+1 2 1 1
+1 2 2 1
+1 2 3 1
+SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2 LEFT JOIN
+t1 ON t2.a = t1.a AND t2.b = t1.b GROUP BY t2.a, t2.b, c;
+a b c d
+1 2 1 1
+1 2 2 1
+1 2 3 1
+1 10 2
+1 11 2
+SELECT t2.a, t2.b, IF(t1.b IS NULL,'',e) AS c, COUNT(*) AS d FROM t2,t1
+WHERE t2.a = t1.a AND t2.b = t1.b GROUP BY a, b, c;
+a b c d
+1 2 1 1
+1 2 2 1
+1 2 3 1
+DROP TABLE IF EXISTS t1, t2;
+create table t1 (f1 int primary key, f2 int);
+create table t2 (f3 int, f4 int, primary key(f3,f4));
+insert into t1 values (1,1);
+insert into t2 values (1,1),(1,2);
+select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1;
+count(f2) >0
+1
+drop table t1,t2;
+create table t1 (f1 int,f2 int);
+insert into t1 values(1,1);
+create table t2 (f3 int, f4 int, primary key(f3,f4));
+insert into t2 values(1,1);
+select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2));
+f1 f2
+1 1
+drop table t1,t2;
+CREATE TABLE t1(a int, b int, c int, KEY b(b), KEY c(c));
+insert into t1 values (1,0,0),(2,0,0);
+CREATE TABLE t2 (a int, b varchar(2), c varchar(2), PRIMARY KEY(a));
+insert into t2 values (1,'',''), (2,'','');
+CREATE TABLE t3 (a int, b int, PRIMARY KEY (a,b), KEY a (a), KEY b (b));
+insert into t3 values (1,1),(1,2);
+explain select straight_join DISTINCT t2.a,t2.b, t1.c from t1, t3, t2
+where (t1.c=t2.a or (t1.c=t3.a and t2.a=t3.b)) and t1.b=556476786 and
+t2.b like '%%' order by t2.b limit 0,1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref b,c b 5 const 1 Using where; Using temporary; Using filesort
+1 SIMPLE t3 index PRIMARY,a,b PRIMARY 8 NULL 2 Using index; Using join buffer
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int, INDEX idx(a));
+INSERT INTO t1 VALUES (2), (3), (1);
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (idx);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (a);
+ERROR 42000: Key 'a' doesn't exist in table 't1'
+EXPLAIN SELECT * FROM t1 FORCE INDEX (a);
+ERROR 42000: Key 'a' doesn't exist in table 't1'
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1,1), (2,1), (4,10);
+CREATE TABLE t2 (a int PRIMARY KEY, b int, KEY b (b));
+INSERT INTO t2 VALUES (1,NULL), (2,10);
+ALTER TABLE t1 ENABLE KEYS;
+EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index b b 5 NULL 2 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
+a b a b
+1 NULL 1 1
+1 NULL 2 1
+1 NULL 4 10
+2 10 4 10
+EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index b b 5 NULL 2 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL;
+a b a b
+1 NULL 1 1
+1 NULL 2 1
+1 NULL 4 10
+2 10 4 10
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (key1 float default NULL, UNIQUE KEY key1 (key1));
+CREATE TABLE t2 (key2 float default NULL, UNIQUE KEY key2 (key2));
+INSERT INTO t1 VALUES (0.3762),(0.3845),(0.6158),(0.7941);
+INSERT INTO t2 VALUES (1.3762),(1.3845),(1.6158),(1.7941);
+explain select max(key1) from t1 where key1 <= 0.6158;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select max(key2) from t2 where key2 <= 1.6158;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select min(key1) from t1 where key1 >= 0.3762;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select min(key2) from t2 where key2 >= 1.3762;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select max(key1), min(key2) from t1, t2
+where key1 <= 0.6158 and key2 >= 1.3762;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+select max(key1) from t1 where key1 <= 0.6158;
+max(key1)
+0.615800023078918
+select max(key2) from t2 where key2 <= 1.6158;
+max(key2)
+1.61580002307892
+select min(key1) from t1 where key1 >= 0.3762;
+min(key1)
+0.376199990510941
+select min(key2) from t2 where key2 >= 1.3762;
+min(key2)
+1.37619996070862
+select max(key1), min(key2) from t1, t2
+where key1 <= 0.6158 and key2 >= 1.3762;
+max(key1) min(key2)
+0.615800023078918 1.37619996070862
+select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+max(key1)
+0.615800023078918
+select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+min(key1)
+0.376199990510941
+DROP TABLE t1,t2;
+CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
+INSERT INTO t1 VALUES (10);
+SELECT i='1e+01',i=1e+01, i in (1e+01,1e+01), i in ('1e+01','1e+01') FROM t1;
+i='1e+01' i=1e+01 i in (1e+01,1e+01) i in ('1e+01','1e+01')
+1 1 1 1
+DROP TABLE t1;
+create table t1(a bigint unsigned, b bigint);
+insert into t1 values (0xfffffffffffffffff, 0xfffffffffffffffff),
+(0x10000000000000000, 0x10000000000000000),
+(0x8fffffffffffffff, 0x8fffffffffffffff);
+Warnings:
+Warning 1264 Out of range value for column 'a' at row 1
+Warning 1264 Out of range value for column 'b' at row 1
+Warning 1264 Out of range value for column 'a' at row 2
+Warning 1264 Out of range value for column 'b' at row 2
+Warning 1264 Out of range value for column 'b' at row 3
+select hex(a), hex(b) from t1;
+hex(a) hex(b)
+FFFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF
+8FFFFFFFFFFFFFFF 7FFFFFFFFFFFFFFF
+drop table t1;
+CREATE TABLE t1 (c0 int);
+CREATE TABLE t2 (c0 int);
+INSERT INTO t1 VALUES(@@connect_timeout);
+INSERT INTO t2 VALUES(@@connect_timeout);
+SELECT * FROM t1 JOIN t2 ON t1.c0 = t2.c0 WHERE (t1.c0 <=> @@connect_timeout);
+c0 c0
+X X
+DROP TABLE t1, t2;
+End of 4.1 tests
+CREATE TABLE t1 (
+K2C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '',
+K4N4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '0000',
+F2I4 int(11) NOT NULL default '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES
+('W%RT', '0100', 1),
+('W-RT', '0100', 1),
+('WART', '0100', 1),
+('WART', '0200', 1),
+('WERT', '0100', 2),
+('WORT','0200', 2),
+('WT', '0100', 2),
+('W_RT', '0100', 2),
+('WaRT', '0100', 3),
+('WART', '0300', 3),
+('WRT' , '0400', 3),
+('WURM', '0500', 3),
+('W%T', '0600', 4),
+('WA%T', '0700', 4),
+('WA_T', '0800', 4);
+SELECT K2C4, K4N4, F2I4 FROM t1
+WHERE K2C4 = 'WART' AND
+(F2I4 = 2 AND K2C4 = 'WART' OR (F2I4 = 2 OR K4N4 = '0200'));
+K2C4 K4N4 F2I4
+WART 0200 1
+SELECT K2C4, K4N4, F2I4 FROM t1
+WHERE K2C4 = 'WART' AND (K2C4 = 'WART' OR K4N4 = '0200');
+K2C4 K4N4 F2I4
+WART 0100 1
+WART 0200 1
+WART 0300 3
+DROP TABLE t1;
+create table t1 (a int, b int);
+create table t2 like t1;
+select t1.a from (t1 inner join t2 on t1.a=t2.a) where t2.a=1;
+a
+select t1.a from ((t1 inner join t2 on t1.a=t2.a)) where t2.a=1;
+a
+select x.a, y.a, z.a from ( (t1 x inner join t2 y on x.a=y.a) inner join t2 z on y.a=z.a) WHERE x.a=1;
+a a a
+drop table t1,t2;
+create table t1 (s1 varchar(5));
+insert into t1 values ('Wall');
+select min(s1) from t1 group by s1 with rollup;
+min(s1)
+Wall
+Wall
+drop table t1;
+create table t1 (s1 int) engine=myisam;
+insert into t1 values (0);
+select avg(distinct s1) from t1 group by s1 with rollup;
+avg(distinct s1)
+0.0000
+0.0000
+drop table t1;
+create table t1 (s1 int);
+insert into t1 values (null),(1);
+select distinct avg(s1) as x from t1 group by s1 with rollup;
+x
+NULL
+1.0000
+drop table t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+INSERT INTO t2 VALUES (2), (4), (6);
+SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a;
+a
+2
+4
+EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer
+EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON t1.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer
+DROP TABLE t1,t2;
+select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
+x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
+16 16 2 2
+create table t1 (f1 varchar(6) default NULL, f2 int(6) primary key not null);
+create table t2 (f3 varchar(5) not null, f4 varchar(5) not null, UNIQUE KEY UKEY (f3,f4));
+insert into t1 values (" 2", 2);
+insert into t2 values (" 2", " one "),(" 2", " two ");
+select * from t1 left join t2 on f1 = f3;
+f1 f2 f3 f4
+ 2 2 2 one
+ 2 2 2 two
+drop table t1,t2;
+create table t1 (empnum smallint, grp int);
+create table t2 (empnum int, name char(5));
+insert into t1 values(1,1);
+insert into t2 values(1,'bob');
+create view v1 as select * from t2 inner join t1 using (empnum);
+select * from v1;
+empnum name grp
+1 bob 1
+drop table t1,t2;
+drop view v1;
+create table t1 (pk int primary key, b int);
+create table t2 (pk int primary key, c int);
+select pk from t1 inner join t2 using (pk);
+pk
+drop table t1,t2;
+create table t1 (s1 int, s2 char(5), s3 decimal(10));
+create view v1 as select s1, s2, 'x' as s3 from t1;
+select * from t1 natural join v1;
+s1 s2 s3
+insert into t1 values (1,'x',5);
+select * from t1 natural join v1;
+s1 s2 s3
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'x'
+drop table t1;
+drop view v1;
+create table t1(a1 int);
+create table t2(a2 int);
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+create view v2 (c) as select a1 from t1;
+select * from t1 natural left join t2;
+a1 a2
+1 1
+1 2
+2 1
+2 2
+select * from t1 natural right join t2;
+a2 a1
+1 1
+1 2
+2 1
+2 2
+select * from v2 natural left join t2;
+c a2
+1 1
+1 2
+2 1
+2 2
+select * from v2 natural right join t2;
+a2 c
+1 1
+1 2
+2 1
+2 2
+drop table t1, t2;
+drop view v2;
+create table t1 (a int(10), t1_val int(10));
+create table t2 (b int(10), t2_val int(10));
+create table t3 (a int(10), b int(10));
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(2,2),(3,3);
+insert into t3 values (1,1),(2,1),(3,1),(4,1);
+select * from t1 natural join t2 natural join t3;
+a b t1_val t2_val
+1 1 1 1
+2 1 2 1
+select * from t1 natural join t3 natural join t2;
+b a t1_val t2_val
+1 1 1 1
+1 2 2 1
+drop table t1, t2, t3;
+DO IFNULL(NULL, NULL);
+SELECT CAST(IFNULL(NULL, NULL) AS DECIMAL);
+CAST(IFNULL(NULL, NULL) AS DECIMAL)
+NULL
+SELECT ABS(IFNULL(NULL, NULL));
+ABS(IFNULL(NULL, NULL))
+NULL
+SELECT IFNULL(NULL, NULL);
+IFNULL(NULL, NULL)
+NULL
+SET @OLD_SQL_MODE12595=@@SQL_MODE, @@SQL_MODE='';
+SHOW LOCAL VARIABLES LIKE 'SQL_MODE';
+Variable_name Value
+sql_mode
+CREATE TABLE BUG_12595(a varchar(100));
+INSERT INTO BUG_12595 VALUES ('hakan%'), ('hakank'), ("ha%an");
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%';
+a
+hakan%
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan*%' ESCAPE '*';
+a
+hakan%
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan**%' ESCAPE '**';
+ERROR HY000: Incorrect arguments to ESCAPE
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan%' ESCAPE '';
+a
+hakan%
+hakank
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%' ESCAPE '';
+a
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha\%an' ESCAPE 0x5c;
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha%%an' ESCAPE '%';
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha\%an' ESCAPE '\\';
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha|%an' ESCAPE '|';
+a
+ha%an
+SET @@SQL_MODE='NO_BACKSLASH_ESCAPES';
+SHOW LOCAL VARIABLES LIKE 'SQL_MODE';
+Variable_name Value
+sql_mode NO_BACKSLASH_ESCAPES
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%';
+a
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan*%' ESCAPE '*';
+a
+hakan%
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan**%' ESCAPE '**';
+ERROR HY000: Incorrect arguments to ESCAPE
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\%' ESCAPE '\\';
+ERROR HY000: Incorrect arguments to ESCAPE
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan%' ESCAPE '';
+ERROR HY000: Incorrect arguments to ESCAPE
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha\%an' ESCAPE 0x5c;
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'ha|%an' ESCAPE '|';
+a
+ha%an
+SELECT * FROM BUG_12595 WHERE a LIKE 'hakan\n%' ESCAPE '\n';
+ERROR HY000: Incorrect arguments to ESCAPE
+SET @@SQL_MODE=@OLD_SQL_MODE12595;
+DROP TABLE BUG_12595;
+create table t1 (a char(1));
+create table t2 (a char(1));
+insert into t1 values ('a'),('b'),('c');
+insert into t2 values ('b'),('c'),('d');
+select a from t1 natural join t2;
+a
+b
+c
+select * from t1 natural join t2 where a = 'b';
+a
+b
+drop table t1, t2;
+CREATE TABLE t1 (`id` TINYINT);
+CREATE TABLE t2 (`id` TINYINT);
+CREATE TABLE t3 (`id` TINYINT);
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+SELECT t1.id,t3.id FROM t1 JOIN t2 ON (t2.id=t1.id) LEFT JOIN t3 USING (id);
+ERROR 23000: Column 'id' in from clause is ambiguous
+SELECT t1.id,t3.id FROM t1 JOIN t2 ON (t2.notacolumn=t1.id) LEFT JOIN t3 USING (id);
+ERROR 23000: Column 'id' in from clause is ambiguous
+SELECT id,t3.id FROM t1 JOIN t2 ON (t2.id=t1.id) LEFT JOIN t3 USING (id);
+ERROR 23000: Column 'id' in from clause is ambiguous
+SELECT id,t3.id FROM (t1 JOIN t2 ON (t2.id=t1.id)) LEFT JOIN t3 USING (id);
+ERROR 23000: Column 'id' in from clause is ambiguous
+drop table t1, t2, t3;
+create table t1 (a int(10),b int(10));
+create table t2 (a int(10),b int(10));
+insert into t1 values (1,10),(2,20),(3,30);
+insert into t2 values (1,10);
+select * from t1 inner join t2 using (A);
+a b b
+1 10 10
+select * from t1 inner join t2 using (a);
+a b b
+1 10 10
+drop table t1, t2;
+create table t1 (a int, c int);
+create table t2 (b int);
+create table t3 (b int, a int);
+create table t4 (c int);
+insert into t1 values (1,1);
+insert into t2 values (1);
+insert into t3 values (1,1);
+insert into t4 values (1);
+select * from t1 join t2 join t3 on (t2.b = t3.b and t1.a = t3.a);
+a c b b a
+1 1 1 1 1
+select * from t1, t2 join t3 on (t2.b = t3.b and t1.a = t3.a);
+ERROR 42S22: Unknown column 't1.a' in 'on clause'
+select * from t1 join t2 join t3 join t4 on (t1.a = t4.c and t2.b = t4.c);
+a c b b a c
+1 1 1 1 1 1
+select * from t1 join t2 join t4 using (c);
+c a b
+1 1 1
+drop table t1, t2, t3, t4;
+create table t1(x int, y int);
+create table t2(x int, y int);
+create table t3(x int, primary key(x));
+insert into t1 values (1, 1), (2, 1), (3, 1), (4, 3), (5, 6), (6, 6);
+insert into t2 values (1, 1), (2, 1), (3, 3), (4, 6), (5, 6);
+insert into t3 values (1), (2), (3), (4), (5);
+select t1.x, t3.x from t1, t2, t3 where t1.x = t2.x and t3.x >= t1.y and t3.x <= t2.y;
+x x
+1 1
+2 1
+3 1
+3 2
+3 3
+4 3
+4 4
+4 5
+drop table t1,t2,t3;
+create table t1 (id char(16) not null default '', primary key (id));
+insert into t1 values ('100'),('101'),('102');
+create table t2 (id char(16) default null);
+insert into t2 values (1);
+create view v1 as select t1.id from t1;
+create view v2 as select t2.id from t2;
+create view v3 as select (t1.id+2) as id from t1 natural left join t2;
+select t1.id from t1 left join v2 using (id);
+id
+100
+101
+102
+select t1.id from v2 right join t1 using (id);
+id
+100
+101
+102
+select t1.id from t1 left join v3 using (id);
+id
+100
+101
+102
+select * from t1 left join v2 using (id);
+id
+100
+101
+102
+select * from v2 right join t1 using (id);
+id
+100
+101
+102
+select * from t1 left join v3 using (id);
+id
+100
+101
+102
+select v1.id from v1 left join v2 using (id);
+id
+100
+101
+102
+select v1.id from v2 right join v1 using (id);
+id
+100
+101
+102
+select v1.id from v1 left join v3 using (id);
+id
+100
+101
+102
+select * from v1 left join v2 using (id);
+id
+100
+101
+102
+select * from v2 right join v1 using (id);
+id
+100
+101
+102
+select * from v1 left join v3 using (id);
+id
+100
+101
+102
+drop table t1, t2;
+drop view v1, v2, v3;
+create table t1 (id int(11) not null default '0');
+insert into t1 values (123),(191),(192);
+create table t2 (id char(16) character set utf8 not null);
+insert into t2 values ('58013'),('58014'),('58015'),('58016');
+create table t3 (a_id int(11) not null, b_id char(16) character set utf8);
+insert into t3 values (123,null),(123,null),(123,null),(123,null),(123,null),(123,'58013');
+select count(*)
+from t1 inner join (t3 left join t2 on t2.id = t3.b_id) on t1.id = t3.a_id;
+count(*)
+6
+select count(*)
+from t1 inner join (t2 right join t3 on t2.id = t3.b_id) on t1.id = t3.a_id;
+count(*)
+6
+drop table t1,t2,t3;
+create table t1 (a int);
+create table t2 (b int);
+create table t3 (c int);
+select * from t1 join t2 join t3 on (t1.a=t3.c);
+a b c
+select * from t1 join t2 left join t3 on (t1.a=t3.c);
+a b c
+select * from t1 join t2 right join t3 on (t1.a=t3.c);
+a b c
+select * from t1 join t2 straight_join t3 on (t1.a=t3.c);
+a b c
+drop table t1, t2 ,t3;
+create table t1(f1 int, f2 date);
+insert into t1 values(1,'2005-01-01'),(2,'2005-09-01'),(3,'2005-09-30'),
+(4,'2005-10-01'),(5,'2005-12-30');
+select * from t1 where f2 >= 0 order by f2;
+f1 f2
+1 2005-01-01
+2 2005-09-01
+3 2005-09-30
+4 2005-10-01
+5 2005-12-30
+select * from t1 where f2 >= '0000-00-00' order by f2;
+f1 f2
+1 2005-01-01
+2 2005-09-01
+3 2005-09-30
+4 2005-10-01
+5 2005-12-30
+select * from t1 where f2 >= '2005-09-31' order by f2;
+f1 f2
+4 2005-10-01
+5 2005-12-30
+select * from t1 where f2 >= '2005-09-3a' order by f2;
+f1 f2
+3 2005-09-30
+4 2005-10-01
+5 2005-12-30
+Warnings:
+Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
+select * from t1 where f2 <= '2005-09-31' order by f2;
+f1 f2
+1 2005-01-01
+2 2005-09-01
+3 2005-09-30
+select * from t1 where f2 <= '2005-09-3a' order by f2;
+f1 f2
+1 2005-01-01
+2 2005-09-01
+Warnings:
+Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
+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;
+CREATE TABLE t1(key_a int4 NOT NULL, optimus varchar(32), PRIMARY KEY(key_a));
+CREATE TABLE t2(key_a int4 NOT NULL, prime varchar(32), PRIMARY KEY(key_a));
+CREATE table t3(key_a int4 NOT NULL, key_b int4 NOT NULL, foo varchar(32),
+PRIMARY KEY(key_a,key_b));
+INSERT INTO t1 VALUES (0,'');
+INSERT INTO t1 VALUES (1,'i');
+INSERT INTO t1 VALUES (2,'j');
+INSERT INTO t1 VALUES (3,'k');
+INSERT INTO t2 VALUES (1,'r');
+INSERT INTO t2 VALUES (2,'s');
+INSERT INTO t2 VALUES (3,'t');
+INSERT INTO t3 VALUES (1,5,'x');
+INSERT INTO t3 VALUES (1,6,'y');
+INSERT INTO t3 VALUES (2,5,'xx');
+INSERT INTO t3 VALUES (2,6,'yy');
+INSERT INTO t3 VALUES (2,7,'zz');
+INSERT INTO t3 VALUES (3,5,'xxx');
+SELECT t2.key_a,foo
+FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a
+INNER JOIN t3 ON t1.key_a = t3.key_a
+WHERE t2.key_a=2 and key_b=5;
+key_a foo
+2 xx
+EXPLAIN SELECT t2.key_a,foo
+FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a
+INNER JOIN t3 ON t1.key_a = t3.key_a
+WHERE t2.key_a=2 and key_b=5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1
+SELECT t2.key_a,foo
+FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a
+INNER JOIN t3 ON t1.key_a = t3.key_a
+WHERE t2.key_a=2 and key_b=5;
+key_a foo
+2 xx
+EXPLAIN SELECT t2.key_a,foo
+FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a
+INNER JOIN t3 ON t1.key_a = t3.key_a
+WHERE t2.key_a=2 and key_b=5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1
+DROP TABLE t1,t2,t3;
+create table t1 (f1 int);
+insert into t1 values(1),(2);
+create table t2 (f2 int, f3 int, key(f2));
+insert into t2 values(1,1),(2,2);
+create table t3 (f4 int not null);
+insert into t3 values (2),(2),(2);
+select f1,(select count(*) from t2,t3 where f2=f1 and f3=f4) as count from t1;
+f1 count
+1 0
+2 3
+drop table t1,t2,t3;
+create table t1 (f1 int unique);
+create table t2 (f2 int unique);
+create table t3 (f3 int unique);
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+insert into t3 values(1),(NULL);
+select * from t3 where f3 is null;
+f3
+NULL
+select t2.f2 from t1 left join t2 on f1=f2 join t3 on f1=f3 where f1=1;
+f2
+1
+drop table t1,t2,t3;
+create table t1(f1 char, f2 char not null);
+insert into t1 values(null,'a');
+create table t2 (f2 char not null);
+insert into t2 values('b');
+select * from t1 left join t2 on f1=t2.f2 where t1.f2='a';
+f1 f2 f2
+NULL a NULL
+drop table t1,t2;
+select * from (select * left join t on f1=f2) tt;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'on f1=f2) tt' at line 1
+CREATE TABLE t1 (sku int PRIMARY KEY, pr int);
+CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255));
+INSERT INTO t1 VALUES
+(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
+INSERT INTO t2 VALUES
+(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
+(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
+SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
+FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
+sku sppr name sku pr
+20 10 bbb 10 10
+20 10 bbb 20 10
+EXPLAIN
+SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
+FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
+DROP TABLE t1,t2;
+CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
+INSERT t1 SET i = 0;
+UPDATE t1 SET i = -1;
+Warnings:
+Warning 1264 Out of range value for column 'i' at row 1
+SELECT * FROM t1;
+i
+0
+UPDATE t1 SET i = CAST(i - 1 AS SIGNED);
+Warnings:
+Warning 1264 Out of range value for column 'i' at row 1
+SELECT * FROM t1;
+i
+0
+UPDATE t1 SET i = i - 1;
+Warnings:
+Warning 1264 Out of range value for column 'i' at row 1
+SELECT * FROM t1;
+i
+255
+DROP TABLE t1;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, b int, c int, e int, primary key(a,b,c));
+insert into t2 select A.a, B.a, C.a, C.a from t1 A, t1 B, t1 C;
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+select 'In next EXPLAIN, B.rows must be exactly 10:' Z;
+Z
+In next EXPLAIN, B.rows must be exactly 10:
+explain select * from t2 A, t2 B where A.a=5 and A.b=5 and A.C<5
+and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using where
+1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10
+drop table t1, t2;
+CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b));
+INSERT INTO t1 VALUES (1, 3), (9,4), (7,5), (4,5), (6,2),
+(3,1), (5,1), (8,9), (2,2), (0,9);
+CREATE TABLE t2 (c int, d int, f int, INDEX(c,f));
+INSERT INTO t2 VALUES
+(1,0,0), (1,0,1), (2,0,0), (2,0,1), (3,0,0), (4,0,1),
+(5,0,0), (5,0,1), (6,0,0), (0,0,1), (7,0,0), (7,0,1),
+(0,0,0), (0,0,1), (8,0,0), (8,0,1), (9,0,0), (9,0,1);
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where
+DROP TABLE t1, t2;
+create table t1 (
+a int unsigned not null auto_increment primary key,
+b bit not null,
+c bit not null
+);
+create table t2 (
+a int unsigned not null auto_increment primary key,
+b bit not null,
+c int unsigned not null,
+d varchar(50)
+);
+insert into t1 (b,c) values (0,1), (0,1);
+insert into t2 (b,c) values (0,1);
+select t1.a, t1.b + 0, t1.c + 0, t2.a, t2.b + 0, t2.c, t2.d
+from t1 left outer join t2 on t1.a = t2.c and t2.b <> 1
+where t1.b <> 1 order by t1.a;
+a t1.b + 0 t1.c + 0 a t2.b + 0 c d
+1 0 1 1 0 1 NULL
+2 0 1 NULL NULL NULL NULL
+drop table t1,t2;
+SELECT 0.9888889889 * 1.011111411911;
+0.9888889889 * 1.011111411911
+0.9998769417899202067879
+prepare stmt from 'select 1 as " a "';
+Warnings:
+Warning 1466 Leading spaces are removed from name ' a '
+execute stmt;
+a
+1
+CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int NOT NULL);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
+CREATE TABLE t2 (c int NOT NULL, INDEX idx(c));
+INSERT INTO t2 VALUES
+(1), (1), (1), (1), (1), (1), (1), (1),
+(2), (2), (2), (2),
+(3), (3),
+(4);
+EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 ref idx idx 4 const 7 Using index
+EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 ref idx idx 4 const 1 Using index
+DROP TABLE t1, t2;
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int);
+INSERT INTO t1 VALUES (1,2), (2,NULL), (3,2);
+CREATE TABLE t2 (b int, c INT, INDEX idx1(b));
+INSERT INTO t2 VALUES (2,1), (3,2);
+CREATE TABLE t3 (d int, e int, INDEX idx1(d));
+INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50);
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
+WHERE t1.id=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 const idx1 NULL NULL NULL 1
+1 SIMPLE t3 ref idx1 idx1 5 const 3 Using where
+SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
+WHERE t1.id=2;
+id a b c d e
+2 NULL NULL NULL 2 10
+2 NULL NULL NULL 2 20
+2 NULL NULL NULL 2 40
+2 NULL NULL NULL 2 50
+DROP TABLE t1,t2,t3;
+create table t1 (c1 varchar(1), c2 int, c3 int, c4 int, c5 int, c6 int,
+c7 int, c8 int, c9 int, fulltext key (`c1`));
+select distinct match (`c1`) against ('z') , c2, c3, c4,c5, c6,c7, c8
+from t1 where c9=1 order by c2, c2;
+match (`c1`) against ('z') c2 c3 c4 c5 c6 c7 c8
+drop table t1;
+CREATE TABLE t1 (pk varchar(10) PRIMARY KEY, fk varchar(16));
+CREATE TABLE t2 (pk varchar(16) PRIMARY KEY, fk varchar(10));
+INSERT INTO t1 VALUES
+('d','dddd'), ('i','iii'), ('a','aa'), ('b','bb'), ('g','gg'),
+('e','eee'), ('c','cccc'), ('h','hhh'), ('j','jjj'), ('f','fff');
+INSERT INTO t2 VALUES
+('jjj', 'j'), ('cc','c'), ('ccc','c'), ('aaa', 'a'), ('jjjj','j'),
+('hhh','h'), ('gg','g'), ('fff','f'), ('ee','e'), ('ffff','f'),
+('bbb','b'), ('ff','f'), ('cccc','c'), ('dddd','d'), ('jj','j'),
+('aaaa','a'), ('bb','b'), ('eeee','e'), ('aa','a'), ('hh','h');
+EXPLAIN SELECT t2.*
+FROM t1 JOIN t2 ON t2.fk=t1.pk
+WHERE t2.fk < 'c' AND t2.pk=t1.fk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
+EXPLAIN SELECT t2.*
+FROM t1 JOIN t2 ON t2.fk=t1.pk
+WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
+EXPLAIN SELECT t2.*
+FROM t1 JOIN t2 ON t2.fk=t1.pk
+WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a));
+CREATE TABLE t2 (a int, b varchar(20) NOT NULL,
+PRIMARY KEY (a), UNIQUE KEY (b));
+INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
+INSERT INTO t2 VALUES (1,'a'),(2,'b'),(3,'c');
+EXPLAIN SELECT t1.a FROM t1 LEFT JOIN t2 ON t2.b=t1.b WHERE t1.a=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+DROP TABLE t1,t2;
+CREATE TABLE t1(id int PRIMARY KEY, b int, e int);
+CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a));
+CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c));
+INSERT INTO t1 VALUES
+(1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79),
+(6,63,67), (5,55,58), (3,38,39), (8,81,89);
+INSERT INTO t2 VALUES
+(21,210), (41,410), (82,820), (83,830), (84,840),
+(65,650), (51,510), (37,370), (94,940), (76,760),
+(22,220), (33,330), (40,400), (95,950), (38,380),
+(67,670), (88,880), (57,570), (96,960), (97,970);
+INSERT INTO t3 VALUES
+(210,'bb'), (950,'ii'), (400,'ab'), (500,'ee'), (220,'gg'),
+(440,'gg'), (310,'eg'), (380,'ee'), (840,'bb'), (830,'ff'),
+(230,'aa'), (960,'ii'), (410,'aa'), (510,'ee'), (290,'bb'),
+(450,'gg'), (320,'dd'), (390,'hh'), (850,'jj'), (860,'ff');
+EXPLAIN
+SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
+WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
+t3.a=t2.a AND t3.c IN ('bb','ee');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 range si si 5 NULL 4 Using where
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
+EXPLAIN
+SELECT t3.a FROM t1,t2,t3
+WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
+t3.a=t2.a AND t3.c IN ('bb','ee') ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 range si,ai si 5 NULL 4 Using where
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
+EXPLAIN
+SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
+WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
+t3.c IN ('bb','ee');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 range si si 5 NULL 2 Using where
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
+EXPLAIN
+SELECT t3.a FROM t1,t2,t3
+WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
+t3.c IN ('bb','ee');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 range si,ai si 5 NULL 2 Using where
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
+CREATE TABLE t2 ( f11 int PRIMARY KEY );
+INSERT INTO t1 VALUES (1,1,1,0,0,0,0),(2,1,1,3,8,1,0),(3,1,1,4,12,1,0);
+INSERT INTO t2 VALUES (62);
+SELECT * FROM t1 LEFT JOIN t2 ON f11 = t1.checked_out GROUP BY f1 ORDER BY f2, f3, f4, f5 LIMIT 0, 1;
+f1 f2 f3 f4 f5 f6 checked_out f11
+1 1 1 0 0 0 0 NULL
+DROP TABLE t1, t2;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(a int);
+INSERT into t1 values (1), (2), (3);
+SELECT * FROM t1 LIMIT 2, -1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1' at line 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+ID_with_null int NULL,
+ID_better int NOT NULL,
+INDEX idx1 (ID_with_null),
+INDEX idx2 (ID_better)
+);
+INSERT INTO t1 VALUES (1,1), (2,1), (null,3), (null,3), (null,3), (null,3);
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
+SELECT COUNT(*) FROM t1 WHERE ID_with_null IS NULL;
+COUNT(*)
+128
+SELECT COUNT(*) FROM t1 WHERE ID_better=1;
+COUNT(*)
+2
+EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+DROP INDEX idx1 ON t1;
+CREATE UNIQUE INDEX idx1 ON t1(ID_with_null);
+EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+DROP TABLE t1;
+CREATE TABLE t1 (
+ID1_with_null int NULL,
+ID2_with_null int NULL,
+ID_better int NOT NULL,
+INDEX idx1 (ID1_with_null, ID2_with_null),
+INDEX idx2 (ID_better)
+);
+INSERT INTO t1 VALUES (1,1,1), (2,2,1), (3,null,3), (null,3,3), (null,null,3),
+(3,null,3), (null,3,3), (null,null,3), (3,null,3), (null,3,3), (null,null,3);
+INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
+INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
+SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3;
+COUNT(*)
+24
+SELECT COUNT(*) FROM t1 WHERE ID1_with_null=3 AND ID2_with_null IS NULL;
+COUNT(*)
+24
+SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null IS NULL;
+COUNT(*)
+192
+SELECT COUNT(*) FROM t1 WHERE ID_better=1;
+COUNT(*)
+2
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+DROP INDEX idx1 ON t1;
+CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null);
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+EXPLAIN SELECT * FROM t1
+WHERE ID_better=1 AND ID1_with_null IS NULL AND
+(ID2_with_null=1 OR ID2_with_null=2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, ts TIMESTAMP, KEY ts(ts));
+INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00");
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+CREATE TABLE t2 (a INT, dt1 DATETIME, dt2 DATETIME, PRIMARY KEY (a));
+INSERT INTO t2 VALUES (30, "2006-01-01 00:00:00", "2999-12-31 00:00:00");
+INSERT INTO t2 SELECT a+1,dt1,dt2 FROM t2;
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
+AND t1.ts BETWEEN t2.dt1 AND t2.dt2
+AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t1 range ts ts 4 NULL 1 Using where
+Warnings:
+Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1
+SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
+AND t1.ts BETWEEN t2.dt1 AND t2.dt2
+AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
+a ts a dt1 dt2
+30 2006-01-03 23:00:00 30 2006-01-01 00:00:00 2999-12-31 00:00:00
+Warnings:
+Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1
+DROP TABLE t1,t2;
+create table t1 (a bigint unsigned);
+insert into t1 values
+(if(1, 9223372036854775808, 1)),
+(case when 1 then 9223372036854775808 else 1 end),
+(coalesce(9223372036854775808, 1));
+select * from t1;
+a
+9223372036854775808
+9223372036854775808
+9223372036854775808
+drop table t1;
+create table t1 select
+if(1, 9223372036854775808, 1) i,
+case when 1 then 9223372036854775808 else 1 end c,
+coalesce(9223372036854775808, 1) co;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` decimal(19,0) NOT NULL DEFAULT '0',
+ `c` decimal(19,0) NOT NULL DEFAULT '0',
+ `co` decimal(19,0) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+select
+if(1, cast(1111111111111111111 as unsigned), 1) i,
+case when 1 then cast(1111111111111111111 as unsigned) else 1 end c,
+coalesce(cast(1111111111111111111 as unsigned), 1) co;
+i c co
+1111111111111111111 1111111111111111111 1111111111111111111
+CREATE TABLE t1 (name varchar(255));
+CREATE TABLE t2 (name varchar(255), n int, KEY (name(3)));
+INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa');
+INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3);
+INSERT INTO t2 VALUES (concat('cc ', 0x06), 4);
+INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7);
+SELECT * FROM t2;
+name n
+bb 1
+aa 2
+cc 3
+cc 4
+cc 5
+bb 6
+cc 7
+SELECT * FROM t2 ORDER BY name;
+name n
+aa 2
+bb 1
+bb 6
+cc 4
+cc 3
+cc 5
+cc 7
+SELECT name, LENGTH(name), n FROM t2 ORDER BY name;
+name LENGTH(name) n
+aa 2 2
+bb 2 1
+bb 3 6
+cc 4 4
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref name name 6 const 3 Using where
+SELECT name, LENGTH(name), n FROM t2 WHERE name='cc ';
+name LENGTH(name) n
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range name name 6 NULL 3 Using where
+SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%';
+name LENGTH(name) n
+cc 5 3
+cc 4 4
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort
+SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name;
+name LENGTH(name) n
+cc 4 4
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ref name name 6 test.t1.name 2
+SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
+name name n
+ccc NULL NULL
+bb bb 1
+bb bb 6
+cc cc 3
+cc cc 5
+cc cc 7
+aa aa 2
+aa aa 2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (name text);
+CREATE TABLE t2 (name text, n int, KEY (name(3)));
+INSERT INTO t1 VALUES ('ccc'), ('bb'), ('cc '), ('aa '), ('aa');
+INSERT INTO t2 VALUES ('bb',1), ('aa',2), ('cc ',3);
+INSERT INTO t2 VALUES (concat('cc ', 0x06), 4);
+INSERT INTO t2 VALUES ('cc',5), ('bb ',6), ('cc ',7);
+SELECT * FROM t2;
+name n
+bb 1
+aa 2
+cc 3
+cc 4
+cc 5
+bb 6
+cc 7
+SELECT * FROM t2 ORDER BY name;
+name n
+aa 2
+bb 1
+bb 6
+cc 4
+cc 3
+cc 5
+cc 7
+SELECT name, LENGTH(name), n FROM t2 ORDER BY name;
+name LENGTH(name) n
+aa 2 2
+bb 2 1
+bb 3 6
+cc 4 4
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name, LENGTH(name), n FROM t2 WHERE name='cc ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref name name 6 const 3 Using where
+SELECT name, LENGTH(name), n FROM t2 WHERE name='cc ';
+name LENGTH(name) n
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range name name 6 NULL 3 Using where
+SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%';
+name LENGTH(name) n
+cc 5 3
+cc 4 4
+cc 2 5
+cc 3 7
+EXPLAIN SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range name name 6 NULL 3 Using where; Using filesort
+SELECT name , LENGTH(name), n FROM t2 WHERE name LIKE 'cc%' ORDER BY name;
+name LENGTH(name) n
+cc 4 4
+cc 5 3
+cc 2 5
+cc 3 7
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 SIMPLE t2 ref name name 6 test.t1.name 2
+SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name;
+name name n
+ccc NULL NULL
+bb bb 1
+bb bb 6
+cc cc 3
+cc cc 5
+cc cc 7
+aa aa 2
+aa aa 2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+access_id int NOT NULL default '0',
+name varchar(20) default NULL,
+rank int NOT NULL default '0',
+KEY idx (access_id)
+);
+CREATE TABLE t2 (
+faq_group_id int NOT NULL default '0',
+faq_id int NOT NULL default '0',
+access_id int default NULL,
+UNIQUE KEY idx1 (faq_id),
+KEY idx2 (faq_group_id,faq_id)
+);
+INSERT INTO t1 VALUES
+(1,'Everyone',2),(2,'Help',3),(3,'Technical Support',1),(4,'Chat User',4);
+INSERT INTO t2 VALUES
+(261,265,1),(490,494,1);
+SELECT t2.faq_id
+FROM t1 INNER JOIN t2 IGNORE INDEX (idx1)
+ON (t1.access_id = t2.access_id)
+LEFT JOIN t2 t
+ON (t.faq_group_id = t2.faq_group_id AND
+find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4'))
+WHERE
+t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265);
+faq_id
+265
+SELECT t2.faq_id
+FROM t1 INNER JOIN t2
+ON (t1.access_id = t2.access_id)
+LEFT JOIN t2 t
+ON (t.faq_group_id = t2.faq_group_id AND
+find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4'))
+WHERE
+t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265);
+faq_id
+265
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, KEY inx (b,a));
+INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1, 6), (1,7);
+EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2
+ON ( f1.b=f2.b AND f1.a<f2.a )
+WHERE 1 AND f1.b NOT IN (100,2232,3343,51111);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE f1 index inx inx 10 NULL 7 Using where; Using index
+1 SIMPLE f2 ref inx inx 5 test.f1.b 1 Using where; Using index
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT, c2 INT);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2)))))))))))))))))))))))))))))))) > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+31 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+32 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) > 0;
+ERROR HY000: Too high level of nesting for select
+DROP TABLE t1;
+CREATE TABLE t1 (
+c1 int(11) NOT NULL AUTO_INCREMENT,
+c2 varchar(1000) DEFAULT NULL,
+c3 bigint(20) DEFAULT NULL,
+c4 bigint(20) DEFAULT NULL,
+PRIMARY KEY (c1)
+);
+EXPLAIN EXTENDED
+SELECT join_2.c1
+FROM
+t1 AS join_0,
+t1 AS join_1,
+t1 AS join_2,
+t1 AS join_3,
+t1 AS join_4,
+t1 AS join_5,
+t1 AS join_6,
+t1 AS join_7
+WHERE
+join_0.c1=join_1.c1 AND
+join_1.c1=join_2.c1 AND
+join_2.c1=join_3.c1 AND
+join_3.c1=join_4.c1 AND
+join_4.c1=join_5.c1 AND
+join_5.c1=join_6.c1 AND
+join_6.c1=join_7.c1
+OR
+join_0.c2 < '?' AND
+join_1.c2 < '?' AND
+join_2.c2 > '?' AND
+join_2.c2 < '!' AND
+join_3.c2 > '?' AND
+join_4.c2 = '?' AND
+join_5.c2 <> '?' AND
+join_6.c2 <> '?' AND
+join_7.c2 >= '?' AND
+join_0.c1=join_1.c1 AND
+join_1.c1=join_2.c1 AND
+join_2.c1=join_3.c1 AND
+join_3.c1=join_4.c1 AND
+join_4.c1=join_5.c1 AND
+join_5.c1=join_6.c1 AND
+join_6.c1=join_7.c1
+GROUP BY
+join_3.c1,
+join_2.c1,
+join_7.c1,
+join_1.c1,
+join_0.c1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
+SHOW WARNINGS;
+Level Code Message
+Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
+DROP TABLE t1;
+SELECT 1 AS ` `;
+
+1
+Warnings:
+Warning 1474 Name ' ' has become ''
+SELECT 1 AS ` `;
+
+1
+Warnings:
+Warning 1474 Name ' ' has become ''
+SELECT 1 AS ` x`;
+x
+1
+Warnings:
+Warning 1466 Leading spaces are removed from name ' x'
+CREATE VIEW v1 AS SELECT 1 AS ``;
+ERROR 42000: Incorrect column name ''
+CREATE VIEW v1 AS SELECT 1 AS ` `;
+ERROR 42000: Incorrect column name ' '
+CREATE VIEW v1 AS SELECT 1 AS ` `;
+ERROR 42000: Incorrect column name ' '
+CREATE VIEW v1 AS SELECT (SELECT 1 AS ` `);
+ERROR 42000: Incorrect column name ' '
+CREATE VIEW v1 AS SELECT 1 AS ` x`;
+Warnings:
+Warning 1466 Leading spaces are removed from name ' x'
+SELECT `x` FROM v1;
+x
+1
+ALTER VIEW v1 AS SELECT 1 AS ` `;
+ERROR 42000: Incorrect column name ' '
+DROP VIEW v1;
+select str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT'
+ and '2007/10/20 00:00:00 GMT';
+str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT'
+ and '2007/10/20 00:00:00 GMT'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT'
+Warning 1292 Truncated incorrect datetime value: '2007/10/20 00:00:00 GMT'
+select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6';
+str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: '2007/10/01 00:00:00 GMT-6'
+select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6';
+str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: '2007/10/2000:00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-1 00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: '2007-10-1 00:00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 x00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: '2007-10-01 x00:00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 00:x00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 00:x00:00 GMT-6'
+select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6';
+str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 x12:34:56 GMT-6'
+select str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6';
+str_to_date('2007-10-01 12:34:00','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6'
+select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6';
+str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34x:56 GMT-6'
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34x:56 GMT-6'
+select str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56';
+str_to_date('2007-10-01 12:34:56','%Y-%m-%d %H:%i:%s') = '2007-10-01 12:34:56'
+1
+select str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00';
+str_to_date('2007-10-01','%Y-%m-%d') = '2007-10-01 12:00:00'
+0
+select str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00';
+str_to_date('2007-10-01 12','%Y-%m-%d %H') = '2007-10-01 12:00:00'
+1
+select str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00';
+str_to_date('2007-10-01 12:34','%Y-%m-%d %H') = '2007-10-01 12:00:00'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-01 12:34'
+select str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34';
+str_to_date('2007-02-30 12:34','%Y-%m-%d %H:%i') = '2007-02-30 12:34'
+1
+select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34';
+str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'
+1
+select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00'
+ and '2007/10/20 00:00:00';
+str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00'
+ and '2007/10/20 00:00:00'
+1
+set SQL_MODE=TRADITIONAL;
+select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34';
+str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34'
+select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34';
+str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34'
+select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34';
+str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34'
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34:00'
+select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01'
+ and '2007/10/20';
+str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01'
+ and '2007/10/20'
+0
+Warnings:
+Warning 1292 Incorrect datetime value: '2007-10-00' for column '2007/09/01' at row 1
+Warning 1292 Incorrect datetime value: '2007-10-00' for column '2007/10/20' at row 1
+set SQL_MODE=DEFAULT;
+select str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20';
+str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: ''
+select str_to_date('','%Y-%m-%d') between '2007/10/01' and '2007/10/20';
+str_to_date('','%Y-%m-%d') between '2007/10/01' and '2007/10/20'
+0
+select str_to_date('','%Y-%m-%d %H:%i') = '2007-10-01 12:34';
+str_to_date('','%Y-%m-%d %H:%i') = '2007-10-01 12:34'
+0
+select str_to_date(NULL,'%Y-%m-%d %H:%i') = '2007-10-01 12:34';
+str_to_date(NULL,'%Y-%m-%d %H:%i') = '2007-10-01 12:34'
+NULL
+select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '';
+str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = ''
+0
+Warnings:
+Warning 1292 Truncated incorrect datetime value: ''
+select str_to_date('1','%Y-%m-%d') = '1';
+str_to_date('1','%Y-%m-%d') = '1'
+0
+Warnings:
+Warning 1292 Truncated incorrect date value: '1'
+select str_to_date('1','%Y-%m-%d') = '1';
+str_to_date('1','%Y-%m-%d') = '1'
+0
+Warnings:
+Warning 1292 Truncated incorrect date value: '1'
+select str_to_date('','%Y-%m-%d') = '';
+str_to_date('','%Y-%m-%d') = ''
+0
+Warnings:
+Warning 1292 Truncated incorrect date value: ''
+select str_to_date('1000-01-01','%Y-%m-%d') between '0000-00-00' and NULL;
+str_to_date('1000-01-01','%Y-%m-%d') between '0000-00-00' and NULL
+0
+select str_to_date('1000-01-01','%Y-%m-%d') between NULL and '2000-00-00';
+str_to_date('1000-01-01','%Y-%m-%d') between NULL and '2000-00-00'
+0
+select str_to_date('1000-01-01','%Y-%m-%d') between NULL and NULL;
+str_to_date('1000-01-01','%Y-%m-%d') between NULL and NULL
+0
+CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL,
+c22 INT DEFAULT NULL,
+KEY(c21, c22));
+CREATE TABLE t3 (c31 INT UNSIGNED NOT NULL DEFAULT 0,
+c32 INT DEFAULT NULL,
+c33 INT NOT NULL,
+c34 INT UNSIGNED DEFAULT 0,
+KEY (c33, c34, c32));
+INSERT INTO t1 values (),(),(),(),();
+INSERT INTO t2 SELECT a.c11, b.c11 FROM t1 a, t1 b;
+INSERT INTO t3 VALUES (1, 1, 1, 0),
+(2, 2, 0, 0),
+(3, 3, 1, 0),
+(4, 4, 0, 0),
+(5, 5, 1, 0);
+SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND
+t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND
+t3.c33 = 1 AND t2.c22 in (1, 3)
+ORDER BY c32;
+c32
+1
+1
+3
+3
+5
+5
+SELECT c32 FROM t1, t2, t3 WHERE t1.c11 IN (1, 3, 5) AND
+t3.c31 = t1.c11 AND t2.c21 = t1.c11 AND
+t3.c33 = 1 AND t2.c22 in (1, 3)
+ORDER BY c32 DESC;
+c32
+5
+5
+3
+3
+1
+1
+DROP TABLE t1, t2, t3;
+
+#
+# Bug#30736: Row Size Too Large Error Creating a Table and
+# Inserting Data.
+#
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+
+CREATE TABLE t1(
+c1 DECIMAL(10, 2),
+c2 FLOAT);
+
+INSERT INTO t1 VALUES (0, 1), (2, 3), (4, 5);
+
+CREATE TABLE t2(
+c3 DECIMAL(10, 2))
+SELECT
+c1 * c2 AS c3
+FROM t1;
+
+SELECT * FROM t1;
+c1 c2
+0.00 1
+2.00 3
+4.00 5
+
+SELECT * FROM t2;
+c3
+0.00
+6.00
+20.00
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+CREATE TABLE t1 (c1 BIGINT NOT NULL);
+INSERT INTO t1 (c1) VALUES (1);
+SELECT * FROM t1 WHERE c1 > NULL + 1;
+c1
+DROP TABLE t1;
+
+CREATE TABLE t1 (a VARCHAR(10) NOT NULL PRIMARY KEY);
+INSERT INTO t1 (a) VALUES ('foo0'), ('bar0'), ('baz0');
+SELECT * FROM t1 WHERE a IN (CONCAT('foo', 0), 'bar');
+a
+foo0
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT, c INT, KEY(a));
+INSERT INTO t1 VALUES (1, 1), (2, 2);
+INSERT INTO t2 VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
+(2, 1), (2, 2), (2, 3), (2, 4), (2, 5),
+(3, 1), (3, 2), (3, 3), (3, 4), (3, 5),
+(4, 1), (4, 2), (4, 3), (4, 4), (4, 5);
+FLUSH STATUS;
+SELECT DISTINCT b FROM t1 LEFT JOIN t2 USING(a) WHERE c <= 3;
+b
+1
+2
+SHOW STATUS LIKE 'Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 2
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 6
+DROP TABLE t1, t2;
+CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0',
+f2 int(11) NOT NULL default '0',
+f3 bigint(20) NOT NULL default '0',
+f4 varchar(255) NOT NULL default '',
+PRIMARY KEY (f1),
+KEY key1 (f4),
+KEY key2 (f2));
+CREATE TABLE t2 (f1 int(11) NOT NULL default '0',
+f2 enum('A1','A2','A3') NOT NULL default 'A1',
+f3 int(11) NOT NULL default '0',
+PRIMARY KEY (f1),
+KEY key1 (f3));
+CREATE TABLE t3 (f1 bigint(20) NOT NULL default '0',
+f2 datetime NOT NULL default '1980-01-01 00:00:00',
+PRIMARY KEY (f1));
+insert into t1 values (1, 1, 1, 'abc');
+insert into t1 values (2, 1, 2, 'def');
+insert into t1 values (3, 1, 2, 'def');
+insert into t2 values (1, 'A1', 1);
+insert into t3 values (1, '1980-01-01');
+SELECT a.f3, cr.f4, count(*) count
+FROM t2 a
+STRAIGHT_JOIN t1 cr ON cr.f2 = a.f1
+LEFT JOIN
+(t1 cr2
+JOIN t3 ae2 ON cr2.f3 = ae2.f1
+) ON a.f1 = cr2.f2 AND ae2.f2 < now() - INTERVAL 7 DAY AND
+cr.f4 = cr2.f4
+GROUP BY a.f3, cr.f4;
+f3 f4 count
+1 abc 1
+1 def 2
+drop table t1, t2, t3;
+CREATE TABLE t1 (a INT KEY, b INT);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
+EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
+EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2
+DROP TABLE t1;
+#
+# Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when
+# forcing a spatial index
+#
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+1
+1
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+1
+1
+1
+1
+1
+DROP TABLE t1;
+#
+# Bug #48291 : crash with row() operator,select into @var, and
+# subquery returning multiple rows
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (2),(3);
+# Should not crash
+SELECT 1 FROM t1 WHERE a <> 1 AND NOT
+ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1))
+INTO @var0;
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1;
+#
+# Bug #48458: simple query tries to allocate enormous amount of
+# memory
+#
+CREATE TABLE t1(a INT NOT NULL, b YEAR);
+INSERT INTO t1 VALUES ();
+Warnings:
+Warning 1364 Field 'a' doesn't have a default value
+CREATE TABLE t2(c INT);
+# Should not err out because of out-of-memory
+SELECT 1 FROM t2 JOIN t1 ON 1=1
+WHERE a != '1' AND NOT a >= b OR NOT ROW(b,a )<> ROW(a,a);
+1
+DROP TABLE t1,t2;
+#
+# Bug #49199: Optimizer handles incorrectly:
+# field='const1' AND field='const2' in some cases
+
+CREATE TABLE t1(a DATETIME NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+a
+2001-01-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+a
+2001-01-01
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01' AS `a` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a TIMESTAMP NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+a
+2001-01-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+a b
+2001-01-01 00:00:00 2001-01-01
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATETIME NOT NULL, b VARCHAR(20) NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+a b
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 0
+SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
+a b
+2001-01-01 00:00:00 2001-01-01
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT x.a, y.a, z.a FROM t1 x
+JOIN t1 y ON x.a=y.a
+JOIN t1 z ON y.a=z.a
+WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
+a a a
+2001-01-01 00:00:00 2001-01-01 00:00:00 2001-01-01 00:00:00
+EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x
+JOIN t1 y ON x.a=y.a
+JOIN t1 z ON y.a=z.a
+WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE x system NULL NULL NULL NULL 1 100.00
+1 SIMPLE y system NULL NULL NULL NULL 1 100.00
+1 SIMPLE z system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a` from `test`.`t1` `x` join `test`.`t1` `y` join `test`.`t1` `z` where 1
+DROP TABLE t1;
+#
+# Bug #49897: crash in ptr_compare when char(0) NOT NULL
+# column is used for ORDER BY
+#
+SET @old_sort_buffer_size= @@session.sort_buffer_size;
+SET @@sort_buffer_size= 40000;
+CREATE TABLE t1(a CHAR(0) NOT NULL);
+INSERT INTO t1 VALUES (0), (0), (0);
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+EXPLAIN SELECT a FROM t1 ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
+SELECT a FROM t1 ORDER BY a;
+DROP TABLE t1;
+CREATE TABLE t1(a CHAR(0) NOT NULL, b CHAR(0) NOT NULL, c int);
+INSERT INTO t1 VALUES (0, 0, 0), (0, 0, 2), (0, 0, 1);
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+EXPLAIN SELECT a FROM t1 ORDER BY a LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
+SELECT a FROM t1 ORDER BY a LIMIT 5;
+a
+
+
+
+
+
+EXPLAIN SELECT * FROM t1 ORDER BY a, b LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
+SELECT * FROM t1 ORDER BY a, b LIMIT 5;
+a b c
+ 0
+ 2
+ 1
+ 0
+ 2
+EXPLAIN SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort
+SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
+a b c
+ 0
+ 0
+ 0
+ 0
+ 0
+EXPLAIN SELECT * FROM t1 ORDER BY c, a LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort
+SELECT * FROM t1 ORDER BY c, a LIMIT 5;
+a b c
+ 0
+ 0
+ 0
+ 0
+ 0
+SET @@sort_buffer_size= @old_sort_buffer_size;
+DROP TABLE t1;
+End of 5.0 tests
+create table t1(a INT, KEY (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
+SELECT a FROM t1 ORDER BY a LIMIT 2;
+a
+1
+2
+SELECT a FROM t1 ORDER BY a LIMIT 2,4294967296;
+a
+3
+4
+5
+SELECT a FROM t1 ORDER BY a LIMIT 2,4294967297;
+a
+3
+4
+5
+DROP TABLE t1;
+CREATE TABLE A (date_key date);
+CREATE TABLE C (
+pk int,
+int_nokey int,
+int_key int,
+date_key date NOT NULL,
+date_nokey date,
+varchar_key varchar(1)
+);
+INSERT INTO C VALUES
+(1,1,1,'0000-00-00',NULL,NULL),
+(1,1,1,'0000-00-00',NULL,NULL);
+SELECT 1 FROM C WHERE pk > ANY (SELECT 1 FROM C);
+1
+SELECT COUNT(DISTINCT 1) FROM C
+WHERE date_key = (SELECT 1 FROM A WHERE C.date_key IS NULL) GROUP BY pk;
+COUNT(DISTINCT 1)
+SELECT date_nokey FROM C
+WHERE int_key IN (SELECT 1 FROM A)
+HAVING date_nokey = '10:41:7'
+ORDER BY date_key;
+date_nokey
+Warnings:
+Warning 1292 Incorrect date value: '10:41:7' for column 'date_nokey' at row 1
+DROP TABLE A,C;
+CREATE TABLE t1 (a INT NOT NULL, b INT);
+INSERT INTO t1 VALUES (1, 1);
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a) OR b > 2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '1' AS `a`,'1' AS `b` from `test`.`t1` where 1
+SELECT * FROM t1 WHERE (a=a AND a=a) OR b > 2;
+a b
+1 1
+DROP TABLE t1;
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL);
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND c=c) OR b > 20;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select '0' AS `a`,'0' AS `b`,'0' AS `c` from `test`.`t1` where 1
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a AND b=b) OR b > 20;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select '0' AS `a`,'0' AS `b`,'0' AS `c` from `test`.`t1` where 1
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND a=a) OR b > 20;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select '0' AS `a`,'0' AS `b`,'0' AS `c` from `test`.`t1` where 1
+DROP TABLE t1;
+#
+# Bug#45266: Uninitialized variable lead to an empty result.
+#
+drop table if exists A,AA,B,BB;
+CREATE TABLE `A` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`date_key` date NOT NULL,
+`date_nokey` date NOT NULL,
+`datetime_key` datetime NOT NULL,
+`int_nokey` int(11) NOT NULL,
+`time_key` time NOT NULL,
+`time_nokey` time NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `date_key` (`date_key`),
+KEY `time_key` (`time_key`),
+KEY `datetime_key` (`datetime_key`)
+);
+CREATE TABLE `AA` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`time_key` time NOT NULL,
+KEY `time_key` (`time_key`),
+PRIMARY KEY (`pk`)
+);
+CREATE TABLE `B` (
+`date_nokey` date NOT NULL,
+`date_key` date NOT NULL,
+`time_key` time NOT NULL,
+`datetime_nokey` datetime NOT NULL,
+`varchar_key` varchar(1) NOT NULL,
+KEY `date_key` (`date_key`),
+KEY `time_key` (`time_key`),
+KEY `varchar_key` (`varchar_key`)
+);
+INSERT INTO `B` VALUES ('2003-07-28','2003-07-28','15:13:38','0000-00-00 00:00:00','f'),('0000-00-00','0000-00-00','00:05:48','2004-07-02 14:34:13','x');
+CREATE TABLE `BB` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`int_nokey` int(11) NOT NULL,
+`date_key` date NOT NULL,
+`varchar_nokey` varchar(1) NOT NULL,
+`date_nokey` date NOT NULL,
+PRIMARY KEY (`pk`),
+KEY `date_key` (`date_key`)
+);
+INSERT INTO `BB` VALUES (10,8,'0000-00-00','i','0000-00-00'),(11,0,'2005-08-18','','2005-08-18');
+SELECT table1 . `pk` AS field1
+FROM
+(BB AS table1 INNER JOIN
+(AA AS table2 STRAIGHT_JOIN A AS table3
+ON ( table3 . `date_key` = table2 . `pk` ))
+ON ( table3 . `datetime_key` = table2 . `int_nokey` ))
+WHERE ( table3 . `date_key` <= 4 AND table2 . `pk` = table1 . `varchar_nokey`)
+GROUP BY field1 ;
+field1
+SELECT table3 .`date_key` field1
+FROM
+B table1 LEFT JOIN B table3 JOIN
+(BB table6 JOIN A table7 ON table6 .`varchar_nokey`)
+ON table6 .`int_nokey` ON table6 .`date_key`
+ WHERE NOT ( table1 .`varchar_key` AND table7 .`pk`) GROUP BY field1;
+field1
+NULL
+SELECT table4 . `time_nokey` AS field1 FROM
+(AA AS table1 CROSS JOIN
+(AA AS table2 STRAIGHT_JOIN
+(B AS table3 STRAIGHT_JOIN A AS table4
+ON ( table4 . `date_key` = table3 . `time_key` ))
+ON ( table4 . `pk` = table3 . `date_nokey` ))
+ON ( table4 . `time_key` = table3 . `datetime_nokey` ))
+WHERE ( table4 . `time_key` < table1 . `time_key` AND
+table1 . `int_nokey` != 'f')
+GROUP BY field1 ORDER BY field1 , field1;
+field1
+SELECT table1 .`time_key` field2 FROM B table1 LEFT JOIN BB JOIN A table5 ON table5 .`date_nokey` ON table5 .`int_nokey` GROUP BY field2;
+field2
+00:05:48
+15:13:38
+drop table A,AA,B,BB;
+#end of test for bug#45266
+#
+# BUG#48052: Valgrind warning - uninitialized value in init_read_record()
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL,
+i int(11) DEFAULT NULL,
+v varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (2,7,'m');
+INSERT INTO t1 VALUES (3,9,'m');
+SELECT v
+FROM t1
+WHERE NOT pk > 0
+HAVING v <= 't'
+ORDER BY pk;
+v
+DROP TABLE t1;
+#
+# Bug#49489 Uninitialized cache led to a wrong result.
+#
+CREATE TABLE t1(c1 DOUBLE(5,4));
+INSERT INTO t1 VALUES (9.1234);
+SELECT * FROM t1 WHERE c1 < 9.12345;
+c1
+9.1234
+DROP TABLE t1;
+# End of test for bug#49489.
+#
+# Bug #49517: Inconsistent behavior while using
+# NULLable BIGINT and INT columns in comparison
+#
+CREATE TABLE t1(a BIGINT UNSIGNED NOT NULL, b BIGINT NULL, c INT NULL);
+INSERT INTO t1 VALUES(105, NULL, NULL);
+SELECT * FROM t1 WHERE b < 102;
+a b c
+SELECT * FROM t1 WHERE c < 102;
+a b c
+SELECT * FROM t1 WHERE 102 < b;
+a b c
+SELECT * FROM t1 WHERE 102 < c;
+a b c
+DROP TABLE t1;
+End of 5.1 tests
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_is.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result 2010-04-02 10:03:39 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result 2010-04-06 02:08:10 +0000
@@ -230,6 +230,18 @@ NULL information_schema INNODB_TRX trx_s
NULL information_schema INNODB_TRX trx_state 2 NO varchar 13 39 NULL NULL utf8 utf8_general_ci varchar(13) select
NULL information_schema INNODB_TRX trx_wait_started 5 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema INNODB_TRX trx_weight 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES BLOCK_SIZE 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES DIRTY_BLOCKS 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES FULL_SIZE 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES KEY_CACHE_NAME 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema KEY_CACHES PARTITIONS 2 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned select
+NULL information_schema KEY_CACHES PARTITION_NUMBER 3 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned select
+NULL information_schema KEY_CACHES READS 10 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES READ_REQUESTS 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES UNUSED_BLOCKS 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES USED_BLOCKS 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES WRITES 12 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES WRITE_REQUESTS 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
NULL information_schema KEY_COLUMN_USAGE COLUMN_NAME 7 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
@@ -743,6 +755,18 @@ NULL information_schema INNODB_TRX trx_w
NULL information_schema INNODB_TRX trx_weight bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_TRX trx_mysql_thread_id bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema INNODB_TRX trx_query varchar 1024 3072 utf8 utf8_general_ci varchar(1024)
+3.0000 information_schema KEY_CACHES KEY_CACHE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
+NULL information_schema KEY_CACHES PARTITIONS int NULL NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES PARTITION_NUMBER int NULL NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES FULL_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES BLOCK_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES USED_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES UNUSED_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES DIRTY_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES READ_REQUESTS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES READS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITE_REQUESTS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITES bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
=== modified file 'mysql-test/suite/funcs_1/r/is_tables_is.result'
--- a/mysql-test/suite/funcs_1/r/is_tables_is.result 2010-02-01 06:14:12 +0000
+++ b/mysql-test/suite/funcs_1/r/is_tables_is.result 2010-04-06 02:08:10 +0000
@@ -590,6 +590,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME KEY_CACHES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME KEY_COLUMN_USAGE
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1688,6 +1711,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME KEY_CACHES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME KEY_COLUMN_USAGE
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
=== modified file 'mysql-test/suite/pbxt/r/mysqlshow.result'
--- a/mysql-test/suite/pbxt/r/mysqlshow.result 2010-02-01 06:14:12 +0000
+++ b/mysql-test/suite/pbxt/r/mysqlshow.result 2010-03-31 18:45:41 +0000
@@ -91,6 +91,7 @@ Database: information_schema
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| INDEX_STATISTICS |
+| KEY_CACHES |
| KEY_COLUMN_USAGE |
| PARTITIONS |
| PLUGINS |
@@ -144,6 +145,7 @@ Database: INFORMATION_SCHEMA
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| INDEX_STATISTICS |
+| KEY_CACHES |
| KEY_COLUMN_USAGE |
| PARTITIONS |
| PLUGINS |
=== modified file 'mysql-test/t/key_cache.test'
--- a/mysql-test/t/key_cache.test 2008-03-27 16:43:17 +0000
+++ b/mysql-test/t/key_cache.test 2010-04-01 21:42:40 +0000
@@ -1,11 +1,13 @@
#
-# Test of multiple key caches
+# Test of multiple key caches, simple an partitioned
#
--disable_warnings
drop table if exists t1, t2, t3;
--enable_warnings
-SET @save_key_buffer=@@key_buffer_size;
+SET @save_key_buffer_size=@@key_buffer_size;
+SET @save_key_cache_block_size=@@key_cache_block_size;
+SET @save_key_cache_partitions=@@key_cache_partitions;
SELECT @@key_buffer_size, @@small.key_buffer_size;
@@ -33,7 +35,7 @@ SELECT @@`default`.key_buffer_size;
SELECT @@small.key_buffer_size;
SELECT @@medium.key_buffer_size;
-SET @@global.key_buffer_size=@save_key_buffer;
+SET @@global.key_buffer_size=@save_key_buffer_size;
#
# Errors
@@ -247,3 +249,270 @@ SET GLOBAL key_cache_block_size= @bug284
DROP TABLE t1;
# End of 4.1 tests
+
+#
+# Test cases for partitioned key caches
+#
+
+# Test usage of the KEY_CACHE table from information schema
+# for a simple key cache
+
+set global key_buffer_size=@save_key_buffer_size;
+set global key_cache_block_size=@save_key_cache_block_size;
+select @@key_buffer_size;
+select @@key_cache_block_size;
+select @@key_cache_partitions;
+
+create table t1 (
+ p int not null auto_increment primary key,
+ a char(10));
+create table t2 (
+ p int not null auto_increment primary key,
+ i int, a char(10), key k1(i), key k2(a));
+
+select @@key_cache_partitions;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+insert into t1 values (1, 'qqqq'), (2, 'yyyy');
+insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
+ (3, 1, 'yyyy'), (4, 3, 'zzzz');
+select * from t1;
+select * from t2;
+update t1 set p=3 where p=1;
+update t2 set i=2 where i=1;
+
+--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
+show status like 'key_%';
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+delete from t2 where a='zzzz';
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+delete from t1;
+delete from t2;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+# For the key cache with 2 partitions execute the same sequence of
+# statements as for the simple cache above.
+# The statistical information on the number of i/o requests and
+# the number of is expected to be the same.
+
+set global key_cache_partitions=2;
+select @@key_cache_partitions;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+insert into t1 values (1, 'qqqq'), (2, 'yyyy');
+insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
+ (3, 1, 'yyyy'), (4, 3, 'zzzz');
+select * from t1;
+select * from t2;
+update t1 set p=3 where p=1;
+update t2 set i=2 where i=1;
+
+--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
+show status like 'key_%';
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+delete from t1;
+delete from t2;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+# Check that we can work with one partition with the same results
+
+set global key_cache_partitions=1;
+select @@key_cache_partitions;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+insert into t1 values (1, 'qqqq'), (2, 'yyyy');
+insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
+ (3, 1, 'yyyy'), (4, 3, 'zzzz');
+select * from t1;
+select * from t2;
+update t1 set p=3 where p=1;
+update t2 set i=2 where i=1;
+
+--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
+show status like 'key_%';
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+delete from t1;
+delete from t2;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+flush tables; flush status;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+# Switch back to 2 partitions
+
+set global key_buffer_size=32*1024;
+select @@key_buffer_size;
+set global key_cache_partitions=2;
+select @@key_cache_partitions;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+insert into t1 values (1, 'qqqq'), (2, 'yyyy');
+insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
+ (3, 1, 'yyyy'), (4, 3, 'zzzz');
+select * from t1;
+select * from t2;
+update t1 set p=3 where p=1;
+update t2 set i=2 where i=1;
+
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+# Add more rows to tables t1 and t2
+
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+insert into t1(a) select a from t1;
+
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+insert into t2(i,a) select i,a from t2;
+
+--replace_column 6 # 7 # 10 #
+select * from information_schema.key_caches where partition_number is null;
+
+select * from t1 where p between 1010 and 1020 ;
+select * from t2 where p between 1010 and 1020 ;
+--replace_column 6 # 7 # 10 #
+select * from information_schema.key_caches where partition_number is null;
+
+flush tables; flush status;
+update t1 set a='zzzz' where a='qqqq';
+update t2 set i=1 where i=2;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+# Now test how we can work with 7 partitions
+
+set global keycache1.key_buffer_size=256*1024;
+select @@keycache1.key_buffer_size;
+set global keycache1.key_cache_partitions=7;
+select @@keycache1.key_cache_partitions;
+
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+--replace_column 7 #
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
+
+cache index t1 key (`primary`) in keycache1;
+
+explain select p from t1 where p between 1010 and 1020;
+select p from t1 where p between 1010 and 1020;
+explain select i from t2 where p between 1010 and 1020;
+select i from t2 where p between 1010 and 1020;
+explain select count(*) from t1, t2 where t1.p = t2.i;
+select count(*) from t1, t2 where t1.p = t2.i;
+
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+--replace_column 7 #
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
+
+cache index t2 in keycache1;
+update t2 set p=p+3000, i=2 where a='qqqq';
+--replace_column 7 #
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
+
+set global keycache2.key_buffer_size=1024*1024;
+cache index t2 in keycache2;
+insert into t2 values (2000, 3, 'yyyy');
+--replace_column 7 #
+select * from information_schema.key_caches where key_cache_name like "keycache2"
+ and partition_number is null;
+--replace_column 7 #
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
+
+cache index t2 in keycache1;
+update t2 set p=p+5000 where a='zzzz';
+select * from t2 where p between 1010 and 1020;
+explain select p from t2 where p between 1010 and 1020;
+select p from t2 where p between 1010 and 1020;
+explain select i from t2 where a='yyyy' and i=3;
+select i from t2 where a='yyyy' and i=3;
+explain select a from t2 where a='yyyy' and i=3;
+select a from t2 where a='yyyy' and i=3 ;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_cache_block_size=2*1024;
+insert into t2 values (7000, 3, 'yyyy');
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_cache_block_size=8*1024;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+insert into t2 values (8000, 3, 'yyyy');
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_buffer_size=64*1024;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_cache_block_size=2*1024;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_cache_block_size=8*1024;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_buffer_size=0;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_cache_block_size=8*1024;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_buffer_size=0;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_buffer_size=128*1024;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+set global keycache1.key_cache_block_size=1024;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
+
+drop table t1,t2;
+
+set global keycache1.key_buffer_size=0;
+set global keycache2.key_buffer_size=0;
+
+set global key_buffer_size=@save_key_buffer_size;
+set global key_cache_partitions=@save_key_cache_partitions;
+
+#End of 5.1 tests
=== added file 'mysql-test/t/select_pkeycache-master.opt'
--- a/mysql-test/t/select_pkeycache-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/select_pkeycache-master.opt 2010-02-16 16:41:11 +0000
@@ -0,0 +1 @@
+--key_cache_partitions=7
=== added file 'mysql-test/t/select_pkeycache.test'
--- a/mysql-test/t/select_pkeycache.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/select_pkeycache.test 2010-02-16 16:41:11 +0000
@@ -0,0 +1,8 @@
+
+#
+# Run select.test partitioned default key cache (with 7 partitions)
+# (see setting the number of partitions in select_pkecache-master.opt)
+# The result is expected the same as for select.test
+#
+
+--source t/select.test
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2010-03-30 12:36:49 +0000
+++ b/mysys/mf_keycache.c 2010-04-06 02:08:10 +0000
@@ -13,12 +13,43 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
/**
- @file
+ @file
+ The file contains the following modules:
+
+ Simple Key Cache Module
+
+ Partitioned Key Cache Module
+
+ Key Cache Interface Module
+
+*/
+
+#include "mysys_priv.h"
+#include "mysys_err.h"
+#include <keycache.h>
+#include "my_static.h"
+#include <m_string.h>
+#include <my_bit.h>
+#include <errno.h>
+#include <stdarg.h>
+
+/******************************************************************************
+ Simple Key Cache Module
+
+ The module contains implementations of all key cache interface functions
+ employed by partitioned key caches.
+
+******************************************************************************/
+
+/*
These functions handle keyblock cacheing for ISAM and MyISAM tables.
One cache can handle many files.
It must contain buffers of the same blocksize.
+
init_key_cache() should be used to init cache handler.
The free list (free_block_list) is a stack like structure.
@@ -37,9 +68,7 @@
blocks_unused is the sum of never used blocks in the pool and of currently
free blocks. blocks_used is the number of blocks fetched from the pool and
as such gives the maximum number of in-use blocks at any time.
-*/
-/*
Key Cache Locking
=================
@@ -104,14 +133,77 @@
I/O finished.
*/
-#include "mysys_priv.h"
-#include "mysys_err.h"
-#include <keycache.h>
-#include "my_static.h"
-#include <m_string.h>
-#include <my_bit.h>
-#include <errno.h>
-#include <stdarg.h>
+/* declare structures that is used by st_key_cache */
+
+struct st_block_link;
+typedef struct st_block_link BLOCK_LINK;
+struct st_keycache_page;
+typedef struct st_keycache_page KEYCACHE_PAGE;
+struct st_hash_link;
+typedef struct st_hash_link HASH_LINK;
+
+/* info about requests in a waiting queue */
+typedef struct st_keycache_wqueue
+{
+ struct st_my_thread_var *last_thread; /* circular list of waiting threads */
+} KEYCACHE_WQUEUE;
+
+#define CHANGED_BLOCKS_HASH 128 /* must be power of 2 */
+
+/* Control block for a simple (non-partitioned) key cache */
+
+typedef struct st_simple_key_cache_cb
+{
+ my_bool key_cache_inited; /* <=> control block is allocated */
+ my_bool in_resize; /* true during resize operation */
+ my_bool resize_in_flush; /* true during flush of resize operation */
+ my_bool can_be_used; /* usage of cache for read/write is allowed */
+ size_t key_cache_mem_size; /* specified size of the cache memory */
+ uint key_cache_block_size; /* size of the page buffer of a cache block */
+ ulong min_warm_blocks; /* min number of warm blocks; */
+ ulong age_threshold; /* age threshold for hot blocks */
+ ulonglong keycache_time; /* total number of block link operations */
+ uint hash_entries; /* max number of entries in the hash table */
+ int hash_links; /* max number of hash links */
+ int hash_links_used; /* number of hash links currently used */
+ int disk_blocks; /* max number of blocks in the cache */
+ ulong blocks_used; /* maximum number of concurrently used blocks */
+ ulong blocks_unused; /* number of currently unused blocks */
+ ulong blocks_changed; /* number of currently dirty blocks */
+ ulong warm_blocks; /* number of blocks in warm sub-chain */
+ ulong cnt_for_resize_op; /* counter to block resize operation */
+ long blocks_available; /* number of blocks available in the LRU chain */
+ HASH_LINK **hash_root; /* arr. of entries into hash table buckets */
+ HASH_LINK *hash_link_root; /* memory for hash table links */
+ HASH_LINK *free_hash_list; /* list of free hash links */
+ BLOCK_LINK *free_block_list; /* list of free blocks */
+ BLOCK_LINK *block_root; /* memory for block links */
+ uchar HUGE_PTR *block_mem; /* memory for block buffers */
+ BLOCK_LINK *used_last; /* ptr to the last block of the LRU chain */
+ BLOCK_LINK *used_ins; /* ptr to the insertion block in LRU chain */
+ pthread_mutex_t cache_lock; /* to lock access to the cache structure */
+ KEYCACHE_WQUEUE resize_queue; /* threads waiting during resize operation */
+ /*
+ Waiting for a zero resize count. Using a queue for symmetry though
+ only one thread can wait here.
+ */
+ KEYCACHE_WQUEUE waiting_for_resize_cnt;
+ KEYCACHE_WQUEUE waiting_for_hash_link; /* waiting for a free hash link */
+ KEYCACHE_WQUEUE waiting_for_block; /* requests waiting for a free block */
+ BLOCK_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; /* hash for dirty file bl.*/
+ BLOCK_LINK *file_blocks[CHANGED_BLOCKS_HASH]; /* hash for other file bl.*/
+
+ /* Statistics variables. These are reset in reset_key_cache_counters(). */
+ ulong global_blocks_changed; /* number of currently dirty blocks */
+ ulonglong global_cache_w_requests;/* number of write requests (write hits) */
+ ulonglong global_cache_write; /* number of writes from cache to files */
+ ulonglong global_cache_r_requests;/* number of read requests (read hits) */
+ ulonglong global_cache_read; /* number of reads from files to cache */
+
+ int blocks; /* max number of blocks in the cache */
+ uint hash_factor; /* factor used to calculate hash function */
+ my_bool in_init; /* Set to 1 in MySQL during init/resize */
+} SIMPLE_KEY_CACHE_CB;
/*
Some compilation flags have been added specifically for this module
@@ -223,7 +315,8 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cac
#define FLUSH_CACHE 2000 /* sort this many blocks at once */
-static int flush_all_key_blocks(KEY_CACHE *keycache);
+static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache);
+static void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup);
#ifdef THREAD
static void wait_on_queue(KEYCACHE_WQUEUE *wqueue,
pthread_mutex_t *mutex);
@@ -232,15 +325,16 @@ static void release_whole_queue(KEYCACHE
#define wait_on_queue(wqueue, mutex) do {} while (0)
#define release_whole_queue(wqueue) do {} while (0)
#endif
-static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block);
+static void free_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block);
#if !defined(DBUG_OFF)
-static void test_key_cache(KEY_CACHE *keycache,
+static void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
const char *where, my_bool lock);
#endif
-
+#define KEYCACHE_BASE_EXPR(f, pos) \
+ ((ulong) ((pos) / keycache->key_cache_block_size) + (ulong) (f))
#define KEYCACHE_HASH(f, pos) \
-(((ulong) ((pos) / keycache->key_cache_block_size) + \
- (ulong) (f)) & (keycache->hash_entries-1))
+ ((KEYCACHE_BASE_EXPR(f, pos) / keycache->hash_factor) & \
+ (keycache->hash_entries-1))
#define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1))
#define DEFAULT_KEYCACHE_DEBUG_LOG "keycache_debug.log"
@@ -336,9 +430,10 @@ static int keycache_pthread_cond_signal(
#define inline /* disabled inline for easier debugging */
static int fail_block(BLOCK_LINK *block);
static int fail_hlink(HASH_LINK *hlink);
-static int cache_empty(KEY_CACHE *keycache);
+static int cache_empty(SIMPLE_KEY_CACHE_CB *keycache);
#endif
+
static inline uint next_power(uint value)
{
return (uint) my_round_up_to_next_power((uint32) value) << 1;
@@ -346,19 +441,32 @@ static inline uint next_power(uint value
/*
- Initialize a key cache
+ Initialize a simple key cache
SYNOPSIS
- init_key_cache()
- keycache pointer to a key cache data structure
- key_cache_block_size size of blocks to keep cached data
- use_mem total memory to use for the key cache
- division_limit division limit (may be zero)
- age_threshold age threshold (may be zero)
+ init_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
+ key_cache_block_size size of blocks to keep cached data
+ use_mem memory to use for the key cache buferrs/structures
+ division_limit division limit (may be zero)
+ age_threshold age threshold (may be zero)
+
+ DESCRIPTION
+ This function is the implementation of the init_key_cache interface
+ function that is employed by simple (non-partitioned) key caches.
+ The function builds a simple key cache and initializes the control block
+ structure of the type SIMPLE_KEY_CACHE_CB that is used for this key cache.
+ The parameter keycache is supposed to point to this structure.
+ The parameter key_cache_block_size specifies the size of the blocks in
+ the key cache to be built. The parameters division_limit and age_threshhold
+ determine the initial values of those characteristics of the key cache
+ that are used for midpoint insertion strategy. The parameter use_mem
+ specifies the total amount of memory to be allocated for key cache blocks
+ and auxiliary structures.
RETURN VALUE
number of blocks in the key cache, if successful,
- 0 - otherwise.
+ <= 0 - otherwise.
NOTES.
if keycache->key_cache_inited != 0 we assume that the key cache
@@ -367,17 +475,17 @@ static inline uint next_power(uint value
It's assumed that no two threads call this function simultaneously
referring to the same key cache handle.
-
*/
-int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+static
+int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
ulong blocks, hash_links;
size_t length;
int error;
- DBUG_ENTER("init_key_cache");
+ DBUG_ENTER("init_simple_key_cache");
DBUG_ASSERT(key_cache_block_size >= 512);
KEYCACHE_DEBUG_OPEN;
@@ -387,12 +495,15 @@ int init_key_cache(KEY_CACHE *keycache,
DBUG_RETURN(0);
}
+ keycache->blocks_used= keycache->blocks_unused= 0;
+ keycache->global_blocks_changed= 0;
keycache->global_cache_w_requests= keycache->global_cache_r_requests= 0;
keycache->global_cache_read= keycache->global_cache_write= 0;
keycache->disk_blocks= -1;
if (! keycache->key_cache_inited)
{
keycache->key_cache_inited= 1;
+ keycache->hash_factor= 1;
/*
Initialize these variables once only.
Their value must survive re-initialization during resizing.
@@ -534,51 +645,42 @@ err:
/*
- Resize a key cache
+ Prepare for resizing a simple key cache
SYNOPSIS
- resize_key_cache()
- keycache pointer to a key cache data structure
- key_cache_block_size size of blocks to keep cached data
- use_mem total memory to use for the new key cache
- division_limit new division limit (if not zero)
- age_threshold new age threshold (if not zero)
-
- RETURN VALUE
- number of blocks in the key cache, if successful,
- 0 - otherwise.
+ prepare_resize_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
+ with_resize_queue <=> resize queue is used
+ release_lock <=> release the key cache lock before return
- NOTES.
- The function first compares the memory size and the block size parameters
- with the key cache values.
+ DESCRIPTION
+ This function flushes all dirty pages from a simple key cache and after
+ this it destroys the key cache calling end_simple_key_cache. The function
+ takes the parameter keycache as a pointer to the control block
+ structure of the type SIMPLE_KEY_CACHE_CB for this key cache.
+ The parameter with_resize_queue determines weather the resize queue is
+ involved (MySQL server never uses this queue). The parameter release_lock
+ says weather the key cache lock must be released before return from
+ the function.
- If they differ the function free the the memory allocated for the
- old key cache blocks by calling the end_key_cache function and
- then rebuilds the key cache with new blocks by calling
- init_key_cache.
+ RETURN VALUE
+ 0 - on success,
+ 1 - otherwise.
- The function starts the operation only when all other threads
- performing operations with the key cache let her to proceed
- (when cnt_for_resize=0).
+ NOTES
+ This function is the called by resize_simple_key_cache and
+ resize_partitioned_key_cache that resize simple and partitioned key caches
+ respectively.
*/
-int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+static
+int prepare_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
+ my_bool with_resize_queue,
+ my_bool release_lock)
{
- int blocks;
- DBUG_ENTER("resize_key_cache");
-
- if (!keycache->key_cache_inited)
- DBUG_RETURN(keycache->disk_blocks);
-
- if(key_cache_block_size == keycache->key_cache_block_size &&
- use_mem == keycache->key_cache_mem_size)
- {
- change_key_cache_param(keycache, division_limit, age_threshold);
- DBUG_RETURN(keycache->disk_blocks);
- }
-
+ int res= 0;
+ DBUG_ENTER("prepare_resize_simple_key_cache");
+
keycache_pthread_mutex_lock(&keycache->cache_lock);
#ifdef THREAD
@@ -588,7 +690,7 @@ int resize_key_cache(KEY_CACHE *keycache
one resizer only. In set_var.cc keycache->in_init is used to block
multiple attempts.
*/
- while (keycache->in_resize)
+ while (with_resize_queue && keycache->in_resize)
{
/* purecov: begin inspected */
wait_on_queue(&keycache->resize_queue, &keycache->cache_lock);
@@ -613,8 +715,8 @@ int resize_key_cache(KEY_CACHE *keycache
{
/* TODO: if this happens, we should write a warning in the log file ! */
keycache->resize_in_flush= 0;
- blocks= 0;
keycache->can_be_used= 0;
+ res= 1;
goto finish;
}
DBUG_ASSERT(cache_empty(keycache));
@@ -640,29 +742,144 @@ int resize_key_cache(KEY_CACHE *keycache
#else
KEYCACHE_DBUG_ASSERT(keycache->cnt_for_resize_op == 0);
#endif
-
- /*
- Free old cache structures, allocate new structures, and initialize
- them. Note that the cache_lock mutex and the resize_queue are left
- untouched. We do not lose the cache_lock and will release it only at
- the end of this function.
- */
- end_key_cache(keycache, 0); /* Don't free mutex */
- /* The following will work even if use_mem is 0 */
- blocks= init_key_cache(keycache, key_cache_block_size, use_mem,
- division_limit, age_threshold);
+
+ end_simple_key_cache(keycache, 0);
finish:
+ if (release_lock)
+ keycache_pthread_mutex_unlock(&keycache->cache_lock);
+ DBUG_RETURN(res);
+}
+
+
+/*
+ Finalize resizing a simple key cache
+
+ SYNOPSIS
+ finish_resize_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
+ with_resize_queue <=> resize queue is used
+ acquire_lock <=> acquire the key cache lock at start
+
+ DESCRIPTION
+ This function performs finalizing actions for the operation of
+ resizing a simple key cache. The function takes the parameter
+ keycache as a pointer to the control block structure of the type
+ SIMPLE_KEY_CACHE_CB for this key cache. The function sets the flag
+ in_resize in this structure to FALSE.
+ The parameter with_resize_queue determines weather the resize queue
+ is involved (MySQL server never uses this queue).
+ The parameter acquire_lock says weather the key cache lock must be
+ acquired at the start of the function.
+
+ RETURN VALUE
+ none
+
+ NOTES
+ This function is the called by resize_simple_key_cache and
+ resize_partitioned_key_cache that resize simple and partitioned key caches
+ respectively.
+*/
+
+static
+void finish_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
+ my_bool with_resize_queue,
+ my_bool acquire_lock)
+{
+ DBUG_ENTER("finish_resize_simple_key_cache");
+
+ if (acquire_lock)
+ keycache_pthread_mutex_lock(&keycache->cache_lock);
+
+ safe_mutex_assert_owner(&keycache->cache_lock);
+
/*
Mark the resize finished. This allows other threads to start a
resize or to request new cache blocks.
*/
keycache->in_resize= 0;
-
- /* Signal waiting threads. */
- release_whole_queue(&keycache->resize_queue);
+
+ if (with_resize_queue)
+ {
+ /* Signal waiting threads. */
+ release_whole_queue(&keycache->resize_queue);
+ }
keycache_pthread_mutex_unlock(&keycache->cache_lock);
+
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Resize a simple key cache
+
+ SYNOPSIS
+ resize_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
+ key_cache_block_size size of blocks to keep cached data
+ use_mem memory to use for the key cache buffers/structures
+ division_limit new division limit (if not zero)
+ age_threshold new age threshold (if not zero)
+
+ DESCRIPTION
+ This function is the implementation of the resize_key_cache interface
+ function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key
+ cache to be resized.
+ The parameter key_cache_block_size specifies the new size of the blocks in
+ the key cache. The parameters division_limit and age_threshold
+ determine the new initial values of those characteristics of the key cache
+ that are used for midpoint insertion strategy. The parameter use_mem
+ specifies the total amount of memory to be allocated for key cache blocks
+ and auxiliary structures in the new key cache.
+
+ RETURN VALUE
+ number of blocks in the key cache, if successful,
+ 0 - otherwise.
+
+ NOTES.
+ The function first calls the function prepare_resize_simple_key_cache
+ to flush all dirty blocks from key cache, to free memory used
+ for key cache blocks and auxiliary structures. After this the
+ function builds a new key cache with new parameters.
+
+ This implementation doesn't block the calls and executions of other
+ functions from the key cache interface. However it assumes that the
+ calls of resize_simple_key_cache itself are serialized.
+
+ The function starts the operation only when all other threads
+ performing operations with the key cache let her to proceed
+ (when cnt_for_resize=0).
+*/
+
+static
+int resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
+{
+ int blocks= 0;
+ DBUG_ENTER("resize_simple_key_cache");
+
+ if (!keycache->key_cache_inited)
+ DBUG_RETURN(blocks);
+
+ /*
+ Note that the cache_lock mutex and the resize_queue are left untouched.
+ We do not lose the cache_lock and will release it only at the end of
+ this function.
+ */
+ if (prepare_resize_simple_key_cache(keycache, 1, 0))
+ goto finish;
+
+ /* The following will work even if use_mem is 0 */
+ blocks= init_simple_key_cache(keycache, key_cache_block_size, use_mem,
+ division_limit, age_threshold);
+
+finish:
+ finish_resize_simple_key_cache(keycache, 1, 0);
+
DBUG_RETURN(blocks);
}
@@ -670,7 +887,7 @@ finish:
/*
Increment counter blocking resize key cache operation
*/
-static inline void inc_counter_for_resize_op(KEY_CACHE *keycache)
+static inline void inc_counter_for_resize_op(SIMPLE_KEY_CACHE_CB *keycache)
{
keycache->cnt_for_resize_op++;
}
@@ -680,35 +897,47 @@ static inline void inc_counter_for_resiz
Decrement counter blocking resize key cache operation;
Signal the operation to proceed when counter becomes equal zero
*/
-static inline void dec_counter_for_resize_op(KEY_CACHE *keycache)
+static inline void dec_counter_for_resize_op(SIMPLE_KEY_CACHE_CB *keycache)
{
if (!--keycache->cnt_for_resize_op)
release_whole_queue(&keycache->waiting_for_resize_cnt);
}
+
/*
- Change the key cache parameters
+ Change key cache parameters of a simple key cache
SYNOPSIS
- change_key_cache_param()
- keycache pointer to a key cache data structure
- division_limit new division limit (if not zero)
- age_threshold new age threshold (if not zero)
+ change_simple_key_cache_param()
+ keycache pointer to the control block of a simple key cache
+ division_limit new division limit (if not zero)
+ age_threshold new age threshold (if not zero)
+
+ DESCRIPTION
+ This function is the implementation of the change_key_cache_param interface
+ function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key
+ cache where new values of the division limit and the age threshold used
+ for midpoint insertion strategy are to be set. The parameters
+ division_limit and age_threshold provide these new values.
RETURN VALUE
none
NOTES.
- Presently the function resets the key cache parameters
- concerning midpoint insertion strategy - division_limit and
- age_threshold.
+ Presently the function resets the key cache parameters concerning
+ midpoint insertion strategy - division_limit and age_threshold.
+ This function changes some parameters of a given key cache without
+ reformatting it. The function does not touch the contents the key
+ cache blocks.
*/
-void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
- uint age_threshold)
+static
+void change_simple_key_cache_param(SIMPLE_KEY_CACHE_CB *keycache, uint division_limit,
+ uint age_threshold)
{
- DBUG_ENTER("change_key_cache_param");
-
+ DBUG_ENTER("change_simple_key_cache_param");
keycache_pthread_mutex_lock(&keycache->cache_lock);
if (division_limit)
keycache->min_warm_blocks= (keycache->disk_blocks *
@@ -722,20 +951,31 @@ void change_key_cache_param(KEY_CACHE *k
/*
- Remove key_cache from memory
+ Destroy a simple key cache
SYNOPSIS
- end_key_cache()
- keycache key cache handle
- cleanup Complete free (Free also mutex for key cache)
+ end_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
+ cleanup <=> complete free (free also mutex for key cache)
+
+ DESCRIPTION
+ This function is the implementation of the end_key_cache interface
+ function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key
+ cache to be destroyed.
+ The function frees the memory allocated for the key cache blocks and
+ auxiliary structures. If the value of the parameter cleanup is TRUE
+ then even the key cache mutex is freed.
RETURN VALUE
none
*/
-void end_key_cache(KEY_CACHE *keycache, my_bool cleanup)
+static
+void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup)
{
- DBUG_ENTER("end_key_cache");
+ DBUG_ENTER("end_simple_key_cache");
DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache));
if (!keycache->key_cache_inited)
@@ -1026,7 +1266,7 @@ static inline void link_changed(BLOCK_LI
void
*/
-static void link_to_file_list(KEY_CACHE *keycache,
+static void link_to_file_list(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block, int file,
my_bool unlink_block)
{
@@ -1067,7 +1307,7 @@ static void link_to_file_list(KEY_CACHE
void
*/
-static void link_to_changed_list(KEY_CACHE *keycache,
+static void link_to_changed_list(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block)
{
DBUG_ASSERT(block->status & BLOCK_IN_USE);
@@ -1122,8 +1362,8 @@ static void link_to_changed_list(KEY_CAC
not linked in the LRU ring.
*/
-static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
- my_bool at_end)
+static void link_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block,
+ my_bool hot, my_bool at_end)
{
BLOCK_LINK *ins;
BLOCK_LINK **pins;
@@ -1243,7 +1483,7 @@ static void link_block(KEY_CACHE *keycac
See NOTES for link_block
*/
-static void unlink_block(KEY_CACHE *keycache, BLOCK_LINK *block)
+static void unlink_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
{
DBUG_ASSERT((block->status & ~BLOCK_CHANGED) == (BLOCK_READ | BLOCK_IN_USE));
DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/
@@ -1301,7 +1541,8 @@ static void unlink_block(KEY_CACHE *keyc
RETURN
void
*/
-static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count)
+static void reg_requests(SIMPLE_KEY_CACHE_CB *keycache,
+ BLOCK_LINK *block, int count)
{
DBUG_ASSERT(block->status & BLOCK_IN_USE);
DBUG_ASSERT(block->hash_link);
@@ -1344,7 +1585,7 @@ static void reg_requests(KEY_CACHE *keyc
not linked in the LRU ring.
*/
-static void unreg_request(KEY_CACHE *keycache,
+static void unreg_request(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block, int at_end)
{
DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
@@ -1433,7 +1674,7 @@ static void remove_reader(BLOCK_LINK *bl
signals on its termination
*/
-static void wait_for_readers(KEY_CACHE *keycache,
+static void wait_for_readers(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block)
{
#ifdef THREAD
@@ -1482,7 +1723,7 @@ static inline void link_hash(HASH_LINK *
Remove a hash link from the hash table
*/
-static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link)
+static void unlink_hash(SIMPLE_KEY_CACHE_CB *keycache, HASH_LINK *hash_link)
{
KEYCACHE_DBUG_PRINT("unlink_hash", ("fd: %u pos_ %lu #requests=%u",
(uint) hash_link->file,(ulong) hash_link->diskpos, hash_link->requests));
@@ -1538,7 +1779,7 @@ static void unlink_hash(KEY_CACHE *keyca
Get the hash link for a page
*/
-static HASH_LINK *get_hash_link(KEY_CACHE *keycache,
+static HASH_LINK *get_hash_link(SIMPLE_KEY_CACHE_CB *keycache,
int file, my_off_t filepos)
{
reg1 HASH_LINK *hash_link, **start;
@@ -1659,7 +1900,7 @@ restart:
waits until first of this operations links any block back.
*/
-static BLOCK_LINK *find_key_block(KEY_CACHE *keycache,
+static BLOCK_LINK *find_key_block(SIMPLE_KEY_CACHE_CB *keycache,
File file, my_off_t filepos,
int init_hits_left,
int wrmode, int *page_st)
@@ -2419,7 +2660,7 @@ restart:
portion is less than read_length, but not less than min_length.
*/
-static void read_block(KEY_CACHE *keycache,
+static void read_block(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block, uint read_length,
uint min_length, my_bool primary)
{
@@ -2507,43 +2748,60 @@ static void read_block(KEY_CACHE *keycac
/*
- Read a block of data from a cached file into a buffer;
+ Read a block of data from a simple key cache into a buffer
SYNOPSIS
- key_cache_read()
- keycache pointer to a key cache data structure
- file handler for the file for the block of data to be read
- filepos position of the block of data in the file
- level determines the weight of the data
- buff buffer to where the data must be placed
- length length of the buffer
- block_length length of the block in the key cache buffer
- return_buffer return pointer to the key cache buffer with the data
+ simple_key_cache_read()
+ keycache pointer to the control block of a simple key cache
+ file handler for the file for the block of data to be read
+ filepos position of the block of data in the file
+ level determines the weight of the data
+ buff buffer to where the data must be placed
+ length length of the buffer
+ block_length length of the read data from a key cache block
+ return_buffer return pointer to the key cache buffer with the data
+ DESCRIPTION
+ This function is the implementation of the key_cache_read interface
+ function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
+ cache.
+ In a general case the function reads a block of data from the key cache
+ into the buffer buff of the size specified by the parameter length. The
+ beginning of the block of data to be read is specified by the parameters
+ file and filepos. The length of the read data is the same as the length
+ of the buffer. The data is read into the buffer in key_cache_block_size
+ increments. If the next portion of the data is not found in any key cache
+ block, first it is read from file into the key cache.
+ If the parameter return_buffer is not ignored and its value is TRUE, and
+ the data to be read of the specified size block_length can be read from one
+ key cache buffer, then the function returns a pointer to the data in the
+ key cache buffer.
+ The function takse into account parameters block_length and return buffer
+ only in a single-threaded environment.
+ The parameter 'level' is used only by the midpoint insertion strategy
+ when the data or its portion cannot be found in the key cache.
+
RETURN VALUE
- Returns address from where the data is placed if sucessful, 0 - otherwise.
+ Returns address from where the data is placed if successful, 0 - otherwise.
- NOTES.
- The function ensures that a block of data of size length from file
- positioned at filepos is in the buffers for some key cache blocks.
- Then the function either copies the data into the buffer buff, or,
- if return_buffer is TRUE, it just returns the pointer to the key cache
- buffer with the data.
+ NOTES
Filepos must be a multiple of 'block_length', but it doesn't
have to be a multiple of key_cache_block_size;
*/
-uchar *key_cache_read(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int return_buffer __attribute__((unused)))
+uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int return_buffer __attribute__((unused)))
{
my_bool locked_and_incremented= FALSE;
int error=0;
uchar *start= buff;
- DBUG_ENTER("key_cache_read");
+ DBUG_ENTER("simple_key_cache_read");
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
(uint) file, (ulong) filepos, length));
@@ -2738,28 +2996,47 @@ end:
/*
- Insert a block of file data from a buffer into key cache
+ Insert a block of file data from a buffer into a simple key cache
SYNOPSIS
- key_cache_insert()
- keycache pointer to a key cache data structure
+ simple_key_cache_insert()
+ keycache pointer to the control block of a simple key cache
file handler for the file to insert data from
filepos position of the block of data in the file to insert
level determines the weight of the data
buff buffer to read data from
length length of the data in the buffer
- NOTES
- This is used by MyISAM to move all blocks from a index file to the key
- cache
-
+ DESCRIPTION
+ This function is the implementation of the key_cache_insert interface
+ function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
+ cache.
+ The function writes a block of file data from a buffer into the key cache.
+ The buffer is specified with the parameters buff and length - the pointer
+ to the beginning of the buffer and its size respectively. It's assumed
+ the buffer contains the data from 'file' allocated from the position
+ filepos. The data is copied from the buffer in key_cache_block_size
+ increments.
+ The parameter level is used to set one characteristic for the key buffers
+ loaded with the data from buff. The characteristic is used only by the
+ midpoint insertion strategy.
+
RETURN VALUE
0 if a success, 1 - otherwise.
+
+ NOTES
+ The function is used by MyISAM to move all blocks from a index file to
+ the key cache. It can be performed in parallel with reading the file data
+ from the key buffers by other threads.
+
*/
-int key_cache_insert(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length)
+static
+int simple_key_cache_insert(SIMPLE_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length)
{
int error= 0;
DBUG_ENTER("key_cache_insert");
@@ -2979,43 +3256,64 @@ int key_cache_insert(KEY_CACHE *keycache
/*
- Write a buffer into a cached file.
+ Write a buffer into a simple key cache
SYNOPSIS
- key_cache_write()
- keycache pointer to a key cache data structure
- file handler for the file to write data to
- filepos position in the file to write data to
- level determines the weight of the data
- buff buffer with the data
- length length of the buffer
- dont_write if is 0 then all dirty pages involved in writing
- should have been flushed from key cache
+ simple_key_cache_write()
+ keycache pointer to the control block of a simple key cache
+ file handler for the file to write data to
+ file_extra maps of key cache partitions containing
+ dirty pages from file
+ filepos position in the file to write data to
+ level determines the weight of the data
+ buff buffer with the data
+ length length of the buffer
+ dont_write if is 0 then all dirty pages involved in writing
+ should have been flushed from key cache
+ DESCRIPTION
+ This function is the implementation of the key_cache_write interface
+ function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
+ cache.
+ In a general case the function copies data from a buffer into the key
+ cache. The buffer is specified with the parameters buff and length -
+ the pointer to the beginning of the buffer and its size respectively.
+ It's assumed the buffer contains the data to be written into 'file'
+ starting from the position filepos. The data is copied from the buffer
+ in key_cache_block_size increments.
+ If the value of the parameter dont_write is FALSE then the function
+ also writes the data into file.
+ The parameter level is used to set one characteristic for the key buffers
+ filled with the data from buff. The characteristic is employed only by
+ the midpoint insertion strategy.
+ The parameter file_extra currently makes sense only for simple key caches
+ that are elements of a partitioned key cache. It provides a pointer to the
+ shared bitmap of the partitions that may contains dirty pages for the file.
+ This bitmap is used to optimize the function
+ flush_partitioned_key_cache_blocks.
+
RETURN VALUE
0 if a success, 1 - otherwise.
- NOTES.
- The function copies the data of size length from buff into buffers
- for key cache blocks that are assigned to contain the portion of
- the file starting with position filepos.
- It ensures that this data is flushed to the file if dont_write is FALSE.
- Filepos must be a multiple of 'block_length', but it doesn't
- have to be a multiple of key_cache_block_size;
-
- dont_write is always TRUE in the server (info->lock_type is never F_UNLCK).
+ NOTES
+ This implementation exploits the fact that the function is called only
+ when a thread has got an exclusive lock for the key file.
*/
-int key_cache_write(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int dont_write)
+static
+int simple_key_cache_write(SIMPLE_KEY_CACHE_CB *keycache,
+ File file, void *file_extra __attribute__((unused)),
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int dont_write)
{
my_bool locked_and_incremented= FALSE;
int error=0;
- DBUG_ENTER("key_cache_write");
+ DBUG_ENTER("simple_key_cache_write");
DBUG_PRINT("enter",
("fd: %u pos: %lu length: %u block_length: %u"
" key_block_length: %u",
@@ -3330,7 +3628,7 @@ end:
Block must have a request registered on it.
*/
-static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
+static void free_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
{
KEYCACHE_THREAD_TRACE("free block");
KEYCACHE_DBUG_PRINT("free_block",
@@ -3470,7 +3768,7 @@ static int cmp_sec_link(BLOCK_LINK **a,
free used blocks if requested
*/
-static int flush_cached_blocks(KEY_CACHE *keycache,
+static int flush_cached_blocks(SIMPLE_KEY_CACHE_CB *keycache,
File file, BLOCK_LINK **cache,
BLOCK_LINK **end,
enum flush_type type)
@@ -3514,9 +3812,9 @@ static int flush_cached_blocks(KEY_CACHE
(BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE));
block->status|= BLOCK_IN_FLUSHWRITE;
keycache_pthread_mutex_unlock(&keycache->cache_lock);
- error= my_pwrite(file, block->buffer+block->offset,
+ error= my_pwrite(file, block->buffer + block->offset,
block->length - block->offset,
- block->hash_link->diskpos+ block->offset,
+ block->hash_link->diskpos + block->offset,
MYF(MY_NABP | MY_WAIT_IF_FULL));
keycache_pthread_mutex_lock(&keycache->cache_lock);
keycache->global_cache_write++;
@@ -3576,7 +3874,7 @@ static int flush_cached_blocks(KEY_CACHE
/*
- Flush all key blocks for a file to disk, but don't do any mutex locks.
+ Flush all key blocks for a file to disk, but don't do any mutex locks
SYNOPSIS
flush_key_blocks_int()
@@ -3598,7 +3896,7 @@ static int flush_cached_blocks(KEY_CACHE
1 error
*/
-static int flush_key_blocks_int(KEY_CACHE *keycache,
+static int flush_key_blocks_int(SIMPLE_KEY_CACHE_CB *keycache,
File file, enum flush_type type)
{
BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache;
@@ -4040,22 +4338,46 @@ err:
/*
- Flush all blocks for a file to disk
+ Flush all blocks for a file from key buffers of a simple key cache
SYNOPSIS
- flush_key_blocks()
- keycache pointer to a key cache data structure
- file handler for the file to flush to
- flush_type type of the flush
+ flush_simple_key_blocks()
+ keycache pointer to the control block of a simple key cache
+ file handler for the file to flush to
+ file_extra maps of key cache partitions containing
+ dirty pages from file (not used)
+ flush_type type of the flush operation
+ DESCRIPTION
+ This function is the implementation of the flush_key_blocks interface
+ function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type S_KEY_CACHE_CB for a simple key
+ cache.
+ In a general case the function flushes the data from all dirty key
+ buffers related to the file 'file' into this file. The function does
+ exactly this if the value of the parameter type is FLUSH_KEEP. If the
+ value of this parameter is FLUSH_RELEASE, the function additionally
+ releases the key buffers containing data from 'file' for new usage.
+ If the value of the parameter type is FLUSH_IGNORE_CHANGED the function
+ just releases the key buffers containing data from 'file'.
+ The parameter file_extra currently is not used by this function.
+
RETURN
0 ok
1 error
+
+ NOTES
+ This implementation exploits the fact that the function is called only
+ when a thread has got an exclusive lock for the key file.
*/
-int flush_key_blocks(KEY_CACHE *keycache,
- File file, enum flush_type type)
+static
+int flush_simple_key_cache_blocks(SIMPLE_KEY_CACHE_CB *keycache,
+ File file,
+ void *file_extra __attribute__((unused)),
+ enum flush_type type)
{
int res= 0;
DBUG_ENTER("flush_key_blocks");
@@ -4109,7 +4431,7 @@ int flush_key_blocks(KEY_CACHE *keycache
!= 0 Error
*/
-static int flush_all_key_blocks(KEY_CACHE *keycache)
+static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
{
BLOCK_LINK *block;
uint total_found;
@@ -4212,37 +4534,43 @@ static int flush_all_key_blocks(KEY_CACH
/*
- Reset the counters of a key cache.
+ Reset the counters of a simple key cache
SYNOPSIS
- reset_key_cache_counters()
- name the name of a key cache
- key_cache pointer to the key kache to be reset
+ reset_simple_key_cache_counters()
+ name the name of a key cache
+ keycache pointer to the control block of a simple key cache
DESCRIPTION
- This procedure is used by process_key_caches() to reset the counters of all
- currently used key caches, both the default one and the named ones.
+ This function is the implementation of the reset_key_cache_counters
+ interface function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type S_KEY_CACHE_CB for a simple key cache.
+ This function resets the values of all statistical counters for the key
+ cache to 0.
+ The parameter name is currently not used.
RETURN
0 on success (always because it can't fail)
*/
-int reset_key_cache_counters(const char *name __attribute__((unused)),
- KEY_CACHE *key_cache)
+static
+int reset_simple_key_cache_counters(const char *name __attribute__((unused)),
+ SIMPLE_KEY_CACHE_CB *keycache)
{
- DBUG_ENTER("reset_key_cache_counters");
- if (!key_cache->key_cache_inited)
+ DBUG_ENTER("reset_simple_key_cache_counters");
+ if (!keycache->key_cache_inited)
{
DBUG_PRINT("info", ("Key cache %s not initialized.", name));
DBUG_RETURN(0);
}
DBUG_PRINT("info", ("Resetting counters for key cache %s.", name));
- key_cache->global_blocks_changed= 0; /* Key_blocks_not_flushed */
- key_cache->global_cache_r_requests= 0; /* Key_read_requests */
- key_cache->global_cache_read= 0; /* Key_reads */
- key_cache->global_cache_w_requests= 0; /* Key_write_requests */
- key_cache->global_cache_write= 0; /* Key_writes */
+ keycache->global_blocks_changed= 0; /* Key_blocks_not_flushed */
+ keycache->global_cache_r_requests= 0; /* Key_read_requests */
+ keycache->global_cache_read= 0; /* Key_reads */
+ keycache->global_cache_w_requests= 0; /* Key_write_requests */
+ keycache->global_cache_write= 0; /* Key_writes */
DBUG_RETURN(0);
}
@@ -4251,9 +4579,10 @@ int reset_key_cache_counters(const char
/*
Test if disk-cache is ok
*/
-static void test_key_cache(KEY_CACHE *keycache __attribute__((unused)),
- const char *where __attribute__((unused)),
- my_bool lock __attribute__((unused)))
+static
+void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache __attribute__((unused)),
+ const char *where __attribute__((unused)),
+ my_bool lock __attribute__((unused)))
{
/* TODO */
}
@@ -4265,7 +4594,7 @@ static void test_key_cache(KEY_CACHE *ke
#define MAX_QUEUE_LEN 100
-static void keycache_dump(KEY_CACHE *keycache)
+static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache)
{
FILE *keycache_dump_file=fopen(KEYCACHE_DUMP_FILE, "w");
struct st_my_thread_var *last;
@@ -4505,7 +4834,7 @@ static int fail_hlink(HASH_LINK *hlink)
return 0; /* Let the assert fail. */
}
-static int cache_empty(KEY_CACHE *keycache)
+static int cache_empty(SIMPLE_KEY_CACHE_CB *keycache)
{
int errcnt= 0;
int idx;
@@ -4543,3 +4872,1702 @@ static int cache_empty(KEY_CACHE *keycac
}
#endif
+
+/*
+ Get statistics for a simple key cache
+
+ SYNOPSIS
+ get_simple_key_cache_statistics()
+ keycache pointer to the control block of a simple key cache
+ partition_no partition number (not used)
+ key_cache_stats OUT pointer to the structure for the returned statistics
+
+ DESCRIPTION
+ This function is the implementation of the get_key_cache_statistics
+ interface function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
+ cache. This function returns the statistical data for the key cache.
+ The parameter partition_no is not used by this function.
+
+ RETURN
+ none
+*/
+
+static
+void get_simple_key_cache_statistics(SIMPLE_KEY_CACHE_CB *keycache,
+ uint partition_no __attribute__((unused)),
+ KEY_CACHE_STATISTICS *keycache_stats)
+{
+ DBUG_ENTER("simple_get_key_cache_statistics");
+
+ keycache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
+ keycache_stats->block_size= (longlong) keycache->key_cache_block_size;
+ keycache_stats->blocks_used= keycache->blocks_used;
+ keycache_stats->blocks_unused= keycache->blocks_unused;
+ keycache_stats->blocks_changed= keycache->global_blocks_changed;
+ keycache_stats->read_requests= keycache->global_cache_r_requests;
+ keycache_stats->reads= keycache->global_cache_read;
+ keycache_stats->write_requests= keycache->global_cache_w_requests;
+ keycache_stats->writes= keycache->global_cache_write;
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Offsets of the statistical values in the control block for a simple key cache
+ The first NO_LONG_KEY_CACHE_STAT_VARIABLES=3 are of the ulong type while the
+ remaining are of the ulonglong type.
+ */
+static size_t simple_key_cache_stat_var_offsets[]=
+{
+ offsetof(SIMPLE_KEY_CACHE_CB, blocks_used),
+ offsetof(SIMPLE_KEY_CACHE_CB, blocks_unused),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_blocks_changed),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_w_requests),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_write),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_r_requests),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_read)
+};
+
+
+/*
+ Get the value of a statistical variable for a simple key cache
+
+ SYNOPSIS
+ get_simple_key_cache_stat_value()
+ keycache pointer to the control block of a simple key cache
+ var_no the ordered number of a statistical variable
+
+ DESCRIPTION
+ This function is the implementation of the get_simple_key_cache_stat_value
+ interface function that is employed by simple (non-partitioned) key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
+ cache. This function returns the value of the statistical variable var_no
+ for this key cache. The variables are numbered starting from 0 to 6.
+
+ RETURN
+ The value of the specified statistical variable
+
+*/
+
+static
+ulonglong get_simple_key_cache_stat_value(SIMPLE_KEY_CACHE_CB *keycache,
+ uint var_no)
+{
+ size_t var_ofs= simple_key_cache_stat_var_offsets[var_no];
+ ulonglong res= 0;
+ DBUG_ENTER("get_simple_key_cache_stat_value");
+
+ if (var_no < 3)
+ res= (ulonglong) (*(long *) ((char *) keycache + var_ofs));
+ else
+ res= *(ulonglong *) ((char *) keycache + var_ofs);
+
+ DBUG_RETURN(res);
+}
+
+
+/*
+ The array of pointer to the key cache interface functions used for simple
+ key caches. Any simple key cache objects including those incorporated into
+ partitioned keys caches exploit this array.
+
+ The current implementation of these functions allows to call them from
+ the MySQL server code directly. We don't do it though.
+*/
+
+static KEY_CACHE_FUNCS simple_key_cache_funcs =
+{
+ (INIT_KEY_CACHE) init_simple_key_cache,
+ (RESIZE_KEY_CACHE) resize_simple_key_cache,
+ (CHANGE_KEY_CACHE_PARAM) change_simple_key_cache_param,
+ (KEY_CACHE_READ) simple_key_cache_read,
+ (KEY_CACHE_INSERT) simple_key_cache_insert,
+ (KEY_CACHE_WRITE) simple_key_cache_write,
+ (FLUSH_KEY_BLOCKS) flush_simple_key_cache_blocks,
+ (RESET_KEY_CACHE_COUNTERS) reset_simple_key_cache_counters,
+ (END_KEY_CACHE) end_simple_key_cache,
+ (GET_KEY_CACHE_STATISTICS) get_simple_key_cache_statistics,
+ (GET_KEY_CACHE_STAT_VALUE) get_simple_key_cache_stat_value
+};
+
+
+/******************************************************************************
+ Partitioned Key Cache Module
+
+ The module contains implementations of all key cache interface functions
+ employed by partitioned key caches.
+
+ A partitioned key cache is a collection of structures for simple key caches
+ called key cache partitions. Any page from a file can be placed into a buffer
+ of only one partition. The number of the partition is calculated from
+ the file number and the position of the page in the file, and it's always the
+ same for the page. The function that maps pages into partitions takes care
+ of even distribution of pages among partitions.
+
+ Partition key cache mitigate one of the major problem of simple key cache:
+ thread contention for key cache lock (mutex). Every call of a key cache
+ interface function must acquire this lock. So threads compete for this lock
+ even in the case when they have acquired shared locks for the file and
+ pages they want read from are in the key cache buffers.
+ When working with a partitioned key cache any key cache interface function
+ that needs only one page has to acquire the key cache lock only for the
+ partition the page is ascribed to. This makes the chances for threads not
+ compete for the same key cache lock better. Unfortunately if we use a
+ partitioned key cache with N partitions for B-tree indexes we can't say
+ that the chances becomes N times less. The fact is that any index lookup
+ operation requires reading from the root page that, for any index, is always
+ ascribed to the same partition. To resolve this problem we should have
+ employed more sophisticated mechanisms of working with root pages.
+
+ Currently the number of partitions in a partitioned key cache is limited
+ by 64. We could increase this limit. Simultaneously we would have to increase
+ accordingly the size of the bitmap dirty_part_map from the MYISAM_SHARE
+ structure.
+
+******************************************************************************/
+
+/* Control block for a partitioned key cache */
+
+typedef struct st_partitioned_key_cache_cb
+{
+ my_bool key_cache_inited; /*<=> control block is allocated */
+ SIMPLE_KEY_CACHE_CB **partition_array; /* the key cache partitions */
+ size_t key_cache_mem_size; /* specified size of the cache memory */
+ uint key_cache_block_size; /* size of the page buffer of a cache block */
+ uint partitions; /* number of partitions in the key cache */
+} PARTITIONED_KEY_CACHE_CB;
+
+static
+void end_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ my_bool cleanup);
+
+static int
+reset_partitioned_key_cache_counters(const char *name,
+ PARTITIONED_KEY_CACHE_CB *keycache);
+
+/*
+ Determine the partition to which the index block to read is ascribed
+
+ SYNOPSIS
+ get_key_cache_partition()
+ keycache pointer to the control block of a partitioned key cache
+ file handler for the file for the block of data to be read
+ filepos position of the block of data in the file
+
+ DESCRIPTION
+ The function determines the number of the partition in whose buffer the
+ block from 'file' at the position filepos has to be placed for reading.
+ The function returns the control block of the simple key cache for this
+ partition to the caller.
+
+ RETURN VALUE
+ The pointer to the control block of the partition to which the specified
+ file block is ascribed.
+*/
+
+static
+SIMPLE_KEY_CACHE_CB *
+get_key_cache_partition(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos)
+{
+ uint i= KEYCACHE_BASE_EXPR(file, filepos) % keycache->partitions;
+ return keycache->partition_array[i];
+}
+
+
+/*
+ Determine the partition to which the index block to write is ascribed
+
+ SYNOPSIS
+ get_key_cache_partition()
+ keycache pointer to the control block of a partitioned key cache
+ file handler for the file for the block of data to be read
+ filepos position of the block of data in the file
+ dirty_part_map pointer to the bitmap of dirty partitions for the file
+
+ DESCRIPTION
+ The function determines the number of the partition in whose buffer the
+ block from 'file' at the position filepos has to be placed for writing and
+ marks the partition as dirty in the dirty_part_map bitmap.
+ The function returns the control block of the simple key cache for this
+ partition to the caller.
+
+ RETURN VALUE
+ The pointer to the control block of the partition to which the specified
+ file block is ascribed.
+*/
+
+static SIMPLE_KEY_CACHE_CB
+*get_key_cache_partition_for_write(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos,
+ ulonglong* dirty_part_map)
+{
+ uint i= KEYCACHE_BASE_EXPR( file, filepos) % keycache->partitions;
+ *dirty_part_map|= 1<<i;
+ return keycache->partition_array[i];
+}
+
+
+/*
+ Initialize a partitioned key cache
+
+ SYNOPSIS
+ init_partitioned_key_cache()
+ keycache pointer to the control block of a partitioned key cache
+ key_cache_block_size size of blocks to keep cached data
+ use_mem total memory to use for all key cache partitions
+ division_limit division limit (may be zero)
+ age_threshold age threshold (may be zero)
+
+ DESCRIPTION
+ This function is the implementation of the init_key_cache interface function
+ that is employed by partitioned key caches.
+ The function builds and initializes an array of simple key caches, and then
+ initializes the control block structure of the type PARTITIONED_KEY_CACHE_CB
+ that is used for a partitioned key cache. The parameter keycache is
+ supposed to point to this structure. The number of partitions in the
+ partitioned key cache to be built must be passed through the field
+ 'partitions' of this structure. The parameter key_cache_block_size specifies
+ the size of the blocks in the the simple key caches to be built.
+ The parameters division_limit and age_threshold determine the initial
+ values of those characteristics of the simple key caches that are used for
+ midpoint insertion strategy. The parameter use_mem specifies the total
+ amount of memory to be allocated for the key cache blocks in all simple key
+ caches and for all auxiliary structures.
+
+ RETURN VALUE
+ total number of blocks in key cache partitions, if successful,
+ <= 0 - otherwise.
+
+ NOTES
+ If keycache->key_cache_inited != 0 then we assume that the memory for
+ the array of partitions has been already allocated.
+
+ It's assumed that no two threads call this function simultaneously
+ referring to the same key cache handle.
+*/
+
+static
+int init_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
+{
+ int i;
+ size_t mem_per_cache;
+ size_t mem_decr;
+ int cnt;
+ SIMPLE_KEY_CACHE_CB *partition;
+ SIMPLE_KEY_CACHE_CB **partition_ptr;
+ uint partitions= keycache->partitions;
+ int blocks= 0;
+ DBUG_ENTER("partitioned_init_key_cache");
+
+ keycache->key_cache_block_size = key_cache_block_size;
+
+ if (keycache->key_cache_inited)
+ partition_ptr= keycache->partition_array;
+ else
+ {
+ if(!(partition_ptr=
+ (SIMPLE_KEY_CACHE_CB **) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB *) *
+ partitions, MYF(MY_WME))))
+ DBUG_RETURN(-1);
+ bzero(partition_ptr, sizeof(SIMPLE_KEY_CACHE_CB *) * partitions);
+ keycache->partition_array= partition_ptr;
+ }
+
+ mem_decr= mem_per_cache / 5;
+ mem_per_cache = use_mem / partitions;
+
+ for (i= 0; i < (int) partitions; i++)
+ {
+ my_bool key_cache_inited= keycache->key_cache_inited;
+ if (key_cache_inited)
+ partition= *partition_ptr;
+ else
+ {
+ if (!(partition=
+ (SIMPLE_KEY_CACHE_CB *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB),
+ MYF(MY_WME))))
+ continue;
+ partition->key_cache_inited= 0;
+ }
+
+ cnt= init_simple_key_cache(partition, key_cache_block_size, mem_per_cache,
+ division_limit, age_threshold);
+ if (cnt <= 0)
+ {
+ end_simple_key_cache(partition, 1);
+ if (!key_cache_inited)
+ {
+ my_free(partition, MYF(0));
+ partition= 0;
+ }
+ if (i == 0 && cnt < 0 || i > 0)
+ {
+ /*
+ Here we have two cases:
+ 1. i == 0 and cnt < 0
+ cnt < 0 => mem_per_cache is not big enough to allocate minimal
+ number of key blocks in the key cache of the partition.
+ Decrease the the number of the partitions by 1 and start again.
+ 2. i > 0
+ There is not enough memory for one of the succeeding partitions.
+ Just skip this partition decreasing the number of partitions in
+ the key cache by one.
+ Do not change the value of mem_per_cache in both cases.
+ */
+ if (key_cache_inited)
+ {
+ my_free(partition, MYF(0));
+ partition= 0;
+ if(key_cache_inited)
+ memmove(partition_ptr, partition_ptr+1,
+ sizeof(partition_ptr)*(partitions-i-1));
+ }
+ if (!--partitions)
+ break;
+ }
+ else
+ {
+ /*
+ We come here when i == 0 && cnt == 0.
+ cnt == 0 => the memory allocator fails to allocate a block of
+ memory of the size mem_per_cache. Decrease the value of
+ mem_per_cache without changing the current number of partitions
+ and start again. Make sure that such a decrease may happen not
+ more than 5 times in total.
+ */
+ if (use_mem <= mem_decr)
+ break;
+ use_mem-= mem_decr;
+ }
+ i--;
+ mem_per_cache= use_mem/partitions;
+ continue;
+ }
+ else
+ {
+ blocks+= cnt;
+ *partition_ptr++= partition;
+ }
+ }
+
+ keycache->partitions= partitions= partition_ptr-keycache->partition_array;
+ keycache->key_cache_mem_size= mem_per_cache * partitions;
+ for (i= 0; i < (int) partitions; i++)
+ keycache->partition_array[i]->hash_factor= partitions;
+
+ keycache->key_cache_inited= 1;
+
+ if (!partitions)
+ blocks= -1;
+
+ DBUG_RETURN(blocks);
+}
+
+
+/*
+ Resize a partitioned key cache
+
+ SYNOPSIS
+ resize_partitioned_key_cache()
+ keycache pointer to the control block of a partitioned key cache
+ key_cache_block_size size of blocks to keep cached data
+ use_mem total memory to use for the new key cache
+ division_limit new division limit (if not zero)
+ age_threshold new age threshold (if not zero)
+
+ DESCRIPTION
+ This function is the implementation of the resize_key_cache interface
+ function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for the
+ partitioned key cache to be resized.
+ The parameter key_cache_block_size specifies the new size of the blocks in
+ the simple key caches that comprise the partitioned key cache.
+ The parameters division_limit and age_threshold determine the new initial
+ values of those characteristics of the simple key cache that are used for
+ midpoint insertion strategy. The parameter use-mem specifies the total
+ amount of memory to be allocated for the key cache blocks in all new
+ simple key caches and for all auxiliary structures.
+
+ RETURN VALUE
+ number of blocks in the key cache, if successful,
+ 0 - otherwise.
+
+ NOTES.
+ The function first calls prepare_resize_simple_key_cache for each simple
+ key cache effectively flushing all dirty pages from it and destroying
+ the key cache. Then init_partitioned_key_cache is called. This call builds
+ a new array of simple key caches containing the same number of elements
+ as the old one. After this the function calls the function
+ finish_resize_simple_key_cache for each simple key cache from this array.
+
+ This implementation doesn't block the calls and executions of other
+ functions from the key cache interface. However it assumes that the
+ calls of resize_partitioned_key_cache itself are serialized.
+*/
+
+static
+int resize_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
+{
+ uint i;
+ uint partitions= keycache->partitions;
+ my_bool cleanup= use_mem == 0;
+ int blocks= -1;
+ int err= 0;
+ DBUG_ENTER("partitioned_resize_key_cache");
+ if (cleanup)
+ {
+ end_partitioned_key_cache(keycache, 0);
+ DBUG_RETURN(-1);
+ }
+ for (i= 0; i < partitions; i++)
+ {
+ err|= prepare_resize_simple_key_cache(keycache->partition_array[i], 0, 1);
+ }
+ if (!err)
+ blocks= init_partitioned_key_cache(keycache, key_cache_block_size,
+ use_mem, division_limit, age_threshold);
+ if (blocks > 0)
+ {
+ for (i= 0; i < partitions; i++)
+ {
+ finish_resize_simple_key_cache(keycache->partition_array[i], 0, 1);
+ }
+ }
+ DBUG_RETURN(blocks);
+}
+
+
+/*
+ Change key cache parameters of a partitioned key cache
+
+ SYNOPSIS
+ partitioned_change_key_cache_param()
+ keycache pointer to the control block of a partitioned key cache
+ division_limit new division limit (if not zero)
+ age_threshold new age threshold (if not zero)
+
+ DESCRIPTION
+ This function is the implementation of the change_key_cache_param interface
+ function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for the simple
+ key cache where new values of the division limit and the age threshold used
+ for midpoint insertion strategy are to be set. The parameters
+ division_limit and age_threshold provide these new values.
+
+ RETURN VALUE
+ none
+
+ NOTES
+ The function just calls change_simple_key_cache_param for each element from
+ the array of simple caches that comprise the partitioned key cache.
+*/
+
+static
+void change_partitioned_key_cache_param(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint division_limit,
+ uint age_threshold)
+{
+ uint i;
+ uint partitions= keycache->partitions;
+ DBUG_ENTER("partitioned_change_key_cache_param");
+ for (i= 0; i < partitions; i++)
+ {
+ change_simple_key_cache_param(keycache->partition_array[i], division_limit,
+ age_threshold);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Destroy a partitioned key cache
+
+ SYNOPSIS
+ end_partitioned_key_cache()
+ keycache pointer to the control block of a partitioned key cache
+ cleanup <=> complete free (free also control block structures
+ for all simple key caches)
+
+ DESCRIPTION
+ This function is the implementation of the end_key_cache interface
+ function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for the
+ partitioned key cache to be destroyed.
+ The function frees the memory allocated for the cache blocks and
+ auxiliary structures used by simple key caches that comprise the
+ partitioned key cache. If the value of the parameter cleanup is TRUE
+ then even the memory used for control blocks of the simple key caches
+ and the array of pointers to them are freed.
+
+ RETURN VALUE
+ none
+*/
+
+static
+void end_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ my_bool cleanup)
+{
+ uint i;
+ uint partitions= keycache->partitions;
+ DBUG_ENTER("partitioned_end_key_cache");
+ DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache));
+
+ for (i= 0; i < partitions; i++)
+ {
+ end_simple_key_cache(keycache->partition_array[i], cleanup);
+ }
+ if (cleanup)
+ {
+ for (i= 0; i < partitions; i++)
+ my_free((uchar*) keycache->partition_array[i], MYF(0));
+ my_free((uchar*) keycache->partition_array, MYF(0));
+ keycache->key_cache_inited= 0;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Read a block of data from a partitioned key cache into a buffer
+
+ SYNOPSIS
+
+ partitioned_key_cache_read()
+ keycache pointer to the control block of a partitioned key cache
+ file handler for the file for the block of data to be read
+ filepos position of the block of data in the file
+ level determines the weight of the data
+ buff buffer to where the data must be placed
+ length length of the buffer
+ block_length length of the read data from a key cache block
+ return_buffer return pointer to the key cache buffer with the data
+
+ DESCRIPTION
+ This function is the implementation of the key_cache_read interface
+ function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
+ In a general case the function reads a block of data from the key cache
+ into the buffer buff of the size specified by the parameter length. The
+ beginning of the block of data to be read is specified by the parameters
+ file and filepos. The length of the read data is the same as the length
+ of the buffer. The data is read into the buffer in key_cache_block_size
+ increments. To read each portion the function first finds out in what
+ partition of the key cache this portion(page) is to be saved, and calls
+ simple_key_cache_read with the pointer to the corresponding simple key as
+ its first parameter.
+ If the parameter return_buffer is not ignored and its value is TRUE, and
+ the data to be read of the specified size block_length can be read from one
+ key cache buffer, then the function returns a pointer to the data in the
+ key cache buffer.
+ The function takes into account parameters block_length and return buffer
+ only in a single-threaded environment.
+ The parameter 'level' is used only by the midpoint insertion strategy
+ when the data or its portion cannot be found in the key cache.
+
+ RETURN VALUE
+ Returns address from where the data is placed if successful, 0 - otherwise.
+*/
+
+static
+uchar *partitioned_key_cache_read(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int return_buffer __attribute__((unused)))
+{
+ uint r_length;
+ uint offset= (uint) (filepos % keycache->key_cache_block_size);
+ uchar *start= buff;
+ DBUG_ENTER("partitioned_key_cache_read");
+ DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
+ (uint) file, (ulong) filepos, length));
+
+#ifndef THREAD
+ if (block_length > keycache->key_cache_block_size || offset)
+ return_buffer=0;
+#endif
+
+ /* Read data in key_cache_block_size increments */
+ do
+ {
+ SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
+ file, filepos);
+ uchar *ret_buff= 0;
+ r_length= length;
+ set_if_smaller(r_length, keycache->key_cache_block_size - offset);
+ ret_buff= simple_key_cache_read((void *) partition,
+ file, filepos, level,
+ buff, r_length,
+ block_length, return_buffer);
+ if (ret_buff == 0)
+ DBUG_RETURN(0);
+#ifndef THREAD
+ /* This is only true if we were able to read everything in one block */
+ if (return_buffer)
+ DBUG_RETURN(ret_buff);
+#endif
+ filepos+= r_length;
+ buff+= r_length;
+ offset= 0;
+ } while ((length-= r_length));
+
+ DBUG_RETURN(start);
+}
+
+
+/*
+ Insert a block of file data from a buffer into a partitioned key cache
+
+ SYNOPSIS
+ partitioned_key_cache_insert()
+ keycache pointer to the control block of a partitioned key cache
+ file handler for the file to insert data from
+ filepos position of the block of data in the file to insert
+ level determines the weight of the data
+ buff buffer to read data from
+ length length of the data in the buffer
+
+ DESCRIPTION
+ This function is the implementation of the key_cache_insert interface
+ function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
+ The function writes a block of file data from a buffer into the key cache.
+ The buffer is specified with the parameters buff and length - the pointer
+ to the beginning of the buffer and its size respectively. It's assumed
+ that the buffer contains the data from 'file' allocated from the position
+ filepos. The data is copied from the buffer in key_cache_block_size
+ increments. For every portion of data the function finds out in what simple
+ key cache from the array of partitions the data must be stored, and after
+ this calls simple_key_cache_insert to copy the data into a key buffer of
+ this simple key cache.
+ The parameter level is used to set one characteristic for the key buffers
+ loaded with the data from buff. The characteristic is used only by the
+ midpoint insertion strategy.
+
+ RETURN VALUE
+ 0 if a success, 1 - otherwise.
+
+ NOTES
+ The function is used by MyISAM to move all blocks from a index file to
+ the key cache. It can be performed in parallel with reading the file data
+ from the key buffers by other threads.
+*/
+
+static
+int partitioned_key_cache_insert(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length)
+{
+ uint w_length;
+ uint offset= (uint) (filepos % keycache->key_cache_block_size);
+ DBUG_ENTER("partitioned_key_cache_insert");
+ DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
+ (uint) file,(ulong) filepos, length));
+
+
+ /* Write data in key_cache_block_size increments */
+ do
+ {
+ SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
+ file, filepos);
+ w_length= length;
+ set_if_smaller(w_length, keycache->key_cache_block_size - offset);
+ if (simple_key_cache_insert((void *) partition,
+ file, filepos, level,
+ buff, w_length))
+ DBUG_RETURN(1);
+
+ filepos+= w_length;
+ buff+= w_length;
+ offset = 0;
+ } while ((length-= w_length));
+
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Write data from a buffer into a partitioned key cache
+
+ SYNOPSIS
+
+ partitioned_key_cache_write()
+ keycache pointer to the control block of a partitioned key cache
+ file handler for the file to write data to
+ filepos position in the file to write data to
+ level determines the weight of the data
+ buff buffer with the data
+ length length of the buffer
+ dont_write if is 0 then all dirty pages involved in writing
+ should have been flushed from key cache
+ file_extra maps of key cache partitions containing
+ dirty pages from file
+
+ DESCRIPTION
+ This function is the implementation of the key_cache_write interface
+ function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
+ In a general case the function copies data from a buffer into the key
+ cache. The buffer is specified with the parameters buff and length -
+ the pointer to the beginning of the buffer and its size respectively.
+ It's assumed the buffer contains the data to be written into 'file'
+ starting from the position filepos. The data is copied from the buffer
+ in key_cache_block_size increments. For every portion of data the
+ function finds out in what simple key cache from the array of partitions
+ the data must be stored, and after this calls simple_key_cache_write to
+ copy the data into a key buffer of this simple key cache.
+ If the value of the parameter dont_write is FALSE then the function
+ also writes the data into file.
+ The parameter level is used to set one characteristic for the key buffers
+ filled with the data from buff. The characteristic is employed only by
+ the midpoint insertion strategy.
+ The parameter file_expra provides a pointer to the shared bitmap of
+ the partitions that may contains dirty pages for the file. This bitmap
+ is used to optimize the function flush_partitioned_key_cache_blocks.
+
+ RETURN VALUE
+ 0 if a success, 1 - otherwise.
+
+ NOTES
+ This implementation exploits the fact that the function is called only
+ when a thread has got an exclusive lock for the key file.
+*/
+
+static
+int partitioned_key_cache_write(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, void *file_extra,
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int dont_write)
+{
+ uint w_length;
+ ulonglong *part_map= (ulonglong *) file_extra;
+ uint offset= (uint) (filepos % keycache->key_cache_block_size);
+ DBUG_ENTER("partitioned_key_cache_write");
+ DBUG_PRINT("enter",
+ ("fd: %u pos: %lu length: %u block_length: %u"
+ " key_block_length: %u",
+ (uint) file, (ulong) filepos, length, block_length,
+ keycache ? keycache->key_cache_block_size : 0));
+
+
+ /* Write data in key_cache_block_size increments */
+ do
+ {
+ SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition_for_write(keycache,
+ file,
+ filepos,
+ part_map);
+ w_length = length;
+ set_if_smaller(w_length, keycache->key_cache_block_size - offset );
+ if (simple_key_cache_write(partition,
+ file, 0, filepos, level,
+ buff, w_length, block_length,
+ dont_write))
+ DBUG_RETURN(1);
+
+ filepos+= w_length;
+ buff+= w_length;
+ offset= 0;
+ } while ((length-= w_length));
+
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Flush all blocks for a file from key buffers of a partitioned key cache
+
+ SYNOPSIS
+
+ flush_partitioned_key_cache_blocks()
+ keycache pointer to the control block of a partitioned key cache
+ file handler for the file to flush to
+ file_extra maps of key cache partitions containing
+ dirty pages from file (not used)
+ flush_type type of the flush operation
+
+ DESCRIPTION
+ This function is the implementation of the flush_key_blocks interface
+ function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
+ In a general case the function flushes the data from all dirty key
+ buffers related to the file 'file' into this file. The function does
+ exactly this if the value of the parameter type is FLUSH_KEEP. If the
+ value of this parameter is FLUSH_RELEASE, the function additionally
+ releases the key buffers containing data from 'file' for new usage.
+ If the value of the parameter type is FLUSH_IGNORE_CHANGED the function
+ just releases the key buffers containing data from 'file'.
+ The function performs the operation by calling the function
+ flush_simple_key_cache_blocks for the elements of the array of the
+ simple key caches that comprise the partitioned key_cache. If the value
+ of the parameter type is FLUSH_KEEP s_flush_key_blocks is called only
+ for the partitions with possibly dirty pages marked in the bitmap
+ pointed to by the parameter file_extra.
+
+ RETURN
+ 0 ok
+ 1 error
+
+ NOTES
+ This implementation exploits the fact that the function is called only
+ when a thread has got an exclusive lock for the key file.
+*/
+
+static
+int flush_partitioned_key_cache_blocks(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, void *file_extra,
+ enum flush_type type)
+{
+ uint i;
+ uint partitions= keycache->partitions;
+ int err= 0;
+ ulonglong *dirty_part_map= (ulonglong *) file_extra;
+ DBUG_ENTER("partitioned_flush_key_blocks");
+ DBUG_PRINT("enter", ("keycache: 0x%lx", (long) keycache));
+
+ for (i= 0; i < partitions; i++)
+ {
+ SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i];
+ if ((type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE) &&
+ !((*dirty_part_map) & ((ulonglong) 1 << i)))
+ continue;
+ err|= test(flush_simple_key_cache_blocks(partition, file, 0, type));
+ }
+ *dirty_part_map= 0;
+
+ DBUG_RETURN(err);
+}
+
+
+/*
+ Reset the counters of a partitioned key cache
+
+ SYNOPSIS
+ reset_partitioned_key_cache_counters()
+ name the name of a key cache
+ keycache pointer to the control block of a partitioned key cache
+
+ DESCRIPTION
+ This function is the implementation of the reset_key_cache_counters
+ interface function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a partitioned
+ key cache.
+ This function resets the values of the statistical counters of the simple
+ key caches comprising partitioned key cache to 0. It does it by calling
+ reset_simple_key_cache_counters for each key cache partition.
+ The parameter name is currently not used.
+
+ RETURN
+ 0 on success (always because it can't fail)
+*/
+
+static int
+reset_partitioned_key_cache_counters(const char *name __attribute__((unused)),
+ PARTITIONED_KEY_CACHE_CB *keycache)
+{
+ uint i;
+ uint partitions= keycache->partitions;
+ DBUG_ENTER("partitioned_reset_key_cache_counters");
+
+ for (i = 0; i < partitions; i++)
+ {
+ reset_simple_key_cache_counters(name, keycache->partition_array[i]);
+ }
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Get statistics for a partition key cache
+
+ SYNOPSIS
+ get_partitioned_key_cache_statistics()
+ keycache pointer to the control block of a partitioned key cache
+ partition_no partition number to get statistics for
+ key_cache_stats OUT pointer to the structure for the returned statistics
+
+ DESCRIPTION
+ This function is the implementation of the get_key_cache_statistics
+ interface function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for
+ a partitioned key cache.
+ If the value of the parameter partition_no is equal to 0 then aggregated
+ statistics for all partitions is returned in the fields of the
+ structure key_cache_stat of the type KEY_CACHE_STATISTICS . Otherwise
+ the function returns data for the partition number partition_no of the
+ key cache in the structure key_cache_stat. (Here partitions are numbered
+ starting from 1.)
+
+ RETURN
+ none
+*/
+
+static
+void
+get_partitioned_key_cache_statistics(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint partition_no,
+ KEY_CACHE_STATISTICS *keycache_stats)
+{
+ uint i;
+ SIMPLE_KEY_CACHE_CB *partition;
+ uint partitions= keycache->partitions;
+ DBUG_ENTER("get_partitioned_key_cache_statistics");
+
+ if (partition_no != 0)
+ {
+ partition= keycache->partition_array[partition_no-1];
+ get_simple_key_cache_statistics((void *) partition, 0, keycache_stats);
+ DBUG_VOID_RETURN;
+ }
+ bzero(keycache_stats, sizeof(KEY_CACHE_STATISTICS));
+ keycache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
+ keycache_stats->block_size= (longlong) keycache->key_cache_block_size;
+ for (i = 0; i < partitions; i++)
+ {
+ partition= keycache->partition_array[i];
+ keycache_stats->blocks_used+= partition->blocks_used;
+ keycache_stats->blocks_unused+= partition->blocks_unused;
+ keycache_stats->blocks_changed+= partition->global_blocks_changed;
+ keycache_stats->read_requests+= partition->global_cache_r_requests;
+ keycache_stats->reads+= partition->global_cache_read;
+ keycache_stats->write_requests+= partition->global_cache_w_requests;
+ keycache_stats->writes+= partition->global_cache_write;
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Get the value of a statistical variable for a partitioned key cache
+
+ SYNOPSIS
+ get_partitioned_key_cache_stat_value()
+ keycache pointer to the control block of a partitioned key cache
+ var_no the ordered number of a statistical variable
+
+ DESCRIPTION
+ This function is the implementation of the get_key_cache_stat_value
+ interface function that is employed by partitioned key caches.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
+ This function returns the value of the statistical variable var_no
+ for this key cache. The variables are numbered starting from 0 to 6.
+ The returned value is calculated as the sum of the values of the
+ statistical variable with number var_no for all simple key caches that
+ comprise the partitioned key cache.
+
+ RETURN
+ The value of the specified statistical variable
+*/
+
+static
+ulonglong
+get_partitioned_key_cache_stat_value(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint var_no)
+{
+ uint i;
+ uint partitions= keycache->partitions;
+ size_t var_ofs= simple_key_cache_stat_var_offsets[var_no];
+ ulonglong res= 0;
+ DBUG_ENTER("get_partitioned_key_cache_stat_value");
+
+ if (var_no < NUM_LONG_KEY_CACHE_STAT_VARIABLES)
+ {
+ for (i = 0; i < partitions; i++)
+ {
+ SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i];
+ res+= (ulonglong) (*(long *) ((char *) partition + var_ofs));
+ }
+ }
+ else
+ {
+ for (i = 0; i < partitions; i++)
+ {
+ SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i];
+ res+= *(ulonglong *) ((char *) partition + var_ofs);
+ }
+ }
+ DBUG_RETURN(res);
+}
+
+
+/*
+ The array of pointers to the key cache interface functions used by
+ partitioned key caches. Any partitioned key cache object caches exploits
+ this array.
+
+ The current implementation of these functions does not allow to call
+ them from the MySQL server code directly. The key cache interface
+ wrappers must be used for this purpose.
+*/
+
+static KEY_CACHE_FUNCS partitioned_key_cache_funcs =
+{
+ (INIT_KEY_CACHE) init_partitioned_key_cache,
+ (RESIZE_KEY_CACHE) resize_partitioned_key_cache,
+ (CHANGE_KEY_CACHE_PARAM) change_partitioned_key_cache_param,
+ (KEY_CACHE_READ) partitioned_key_cache_read,
+ (KEY_CACHE_INSERT) partitioned_key_cache_insert,
+ (KEY_CACHE_WRITE) partitioned_key_cache_write,
+ (FLUSH_KEY_BLOCKS) flush_partitioned_key_cache_blocks,
+ (RESET_KEY_CACHE_COUNTERS) reset_partitioned_key_cache_counters,
+ (END_KEY_CACHE) end_partitioned_key_cache,
+ (GET_KEY_CACHE_STATISTICS) get_partitioned_key_cache_statistics,
+ (GET_KEY_CACHE_STAT_VALUE) get_partitioned_key_cache_stat_value
+};
+
+
+/******************************************************************************
+ Key Cache Interface Module
+
+ The module contains wrappers for all key cache interface functions.
+
+ Currently there are key caches of two types: simple key caches and
+ partitioned key caches. Each type (class) has its own implementation of the
+ basic key cache operations used the MyISAM storage engine. The pointers
+ to the implementation functions are stored in two static structures of the
+ type KEY_CACHE_FUNC: simple_key_cache_funcs - for simple key caches, and
+ partitioned_key_cache_funcs - for partitioned key caches. When a key cache
+ object is created the constructor procedure init_key_cache places a pointer
+ to the corresponding table into one of its fields. The procedure also
+ initializes a control block for the key cache oject and saves the pointer
+ to this block in another field of the key cache object.
+ When a key cache wrapper function is invoked for a key cache object to
+ perform a basic key cache operation it looks into the interface table
+ associated with the key cache oject and calls the corresponding
+ implementation of the operation. It passes the saved key cache control
+ block to this implementation. If, for some reasons, the control block
+ has not been fully initialized yet, the wrapper function either does not
+ do anything or, in the case when it perform a read/write operation, the
+ function do it directly through the system i/o functions.
+
+ As we can see the model with which the key cache interface is supported
+ as quite conventional for interfaces in general.
+
+******************************************************************************/
+
+
+/*
+ Initialize a key cache
+
+ SYNOPSIS
+ init_key_cache()
+ keycache pointer to the key cache to be initialized
+ key_cache_block_size size of blocks to keep cached data
+ use_mem total memory to use for cache buffers/structures
+ division_limit division limit (may be zero)
+ age_threshold age threshold (may be zero)
+ partitions number of partitions in the key cache
+
+ DESCRIPTION
+ The function creates a control block structure for a key cache and
+ places the pointer to this block in the structure keycache.
+ If the value of the parameter 'partitions' is 0 then a simple key cache
+ is created. Otherwise a partitioned key cache with the specified number
+ of partitions is created.
+ The parameter key_cache_block_size specifies the size of the blocks in
+ the key cache to be created. The parameters division_limit and
+ age_threshold determine the initial values of those characteristics of
+ the key cache that are used for midpoint insertion strategy. The parameter
+ use_mem specifies the total amount of memory to be allocated for the
+ key cache buffers and for all auxiliary structures.
+
+ RETURN VALUE
+ total number of blocks in key cache partitions, if successful,
+ <= 0 - otherwise.
+
+ NOTES
+ if keycache->key_cache_inited != 0 we assume that the memory
+ for the control block of the key cache has been already allocated.
+
+ It's assumed that no two threads call this function simultaneously
+ referring to the same key cache handle.
+*/
+
+int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold, uint partitions)
+{
+ void *keycache_cb;
+ int blocks;
+ if (keycache->key_cache_inited)
+ keycache_cb= keycache->keycache_cb;
+ else
+ {
+ if (partitions == 0)
+ {
+ if (!(keycache_cb= (void *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB),
+ MYF(0))))
+ return 0;
+ ((SIMPLE_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
+ keycache->key_cache_type= SIMPLE_KEY_CACHE;
+ keycache->interface_funcs= &simple_key_cache_funcs;
+ }
+ else
+ {
+ if (!(keycache_cb= (void *) my_malloc(sizeof(PARTITIONED_KEY_CACHE_CB),
+ MYF(0))))
+ return 0;
+ ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
+ keycache->key_cache_type= PARTITIONED_KEY_CACHE;
+ keycache->interface_funcs= &partitioned_key_cache_funcs;
+ }
+ keycache->keycache_cb= keycache_cb;
+ keycache->key_cache_inited= 1;
+ }
+
+ if (partitions != 0)
+ {
+ ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions= partitions;
+ }
+ keycache->can_be_used= 0;
+ blocks= keycache->interface_funcs->init(keycache_cb, key_cache_block_size,
+ use_mem, division_limit,
+ age_threshold);
+ keycache->partitions= partitions ?
+ ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions :
+ 0;
+ DBUG_ASSERT(partitions <= MAX_KEY_CACHE_PARTITIONS);
+ if (blocks > 0)
+ keycache->can_be_used= 1;
+ return blocks;
+}
+
+
+/*
+ Resize a key cache
+
+ SYNOPSIS
+ resize_key_cache()
+ keycache pointer to the key cache to be resized
+ key_cache_block_size size of blocks to keep cached data
+ use_mem total memory to use for the new key cache
+ division_limit new division limit (if not zero)
+ age_threshold new age threshold (if not zero)
+
+ DESCRIPTION
+ The function operates over the key cache key cache.
+ The parameter key_cache_block_size specifies the new size of the block
+ buffers in the key cache. The parameters division_limit and age_threshold
+ determine the new initial values of those characteristics of the key cache
+ that are used for midpoint insertion strategy. The parameter use_mem
+ specifies the total amount of memory to be allocated for the key cache
+ buffers and for all auxiliary structures.
+
+ RETURN VALUE
+ number of blocks in the key cache, if successful,
+ 0 - otherwise.
+
+ NOTES
+ The function does not block the calls and executions of other functions
+ from the key cache interface. However it assumes that the calls of
+ resize_key_cache itself are serialized.
+
+ Currently the function is called when the values of the variables
+ key_buffer_size and/or key_cache_block_size are being reset for
+ the key cache keycache.
+*/
+
+int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
+ size_t use_mem, uint division_limit, uint age_threshold)
+{
+ int blocks= -1;
+ if (keycache->key_cache_inited)
+ {
+ if ((uint) keycache->param_partitions != keycache->partitions && use_mem)
+ blocks= repartition_key_cache(keycache,
+ key_cache_block_size, use_mem,
+ division_limit, age_threshold,
+ (uint) keycache->param_partitions);
+ else
+ {
+ blocks= keycache->interface_funcs->resize(keycache->keycache_cb,
+ key_cache_block_size,
+ use_mem, division_limit,
+ age_threshold);
+
+ if (keycache->partitions)
+ keycache->partitions=
+ ((PARTITIONED_KEY_CACHE_CB *)(keycache->keycache_cb))->partitions;
+ }
+
+ keycache->can_be_used= (blocks >= 0);
+ }
+ return blocks;
+}
+
+
+/*
+ Change key cache parameters of a key cache
+
+ SYNOPSIS
+ change_key_cache_param()
+ keycache pointer to the key cache to change parameters for
+ division_limit new division limit (if not zero)
+ age_threshold new age threshold (if not zero)
+
+ DESCRIPTION
+ The function sets new values of the division limit and the age threshold
+ used when the key cache keycach employs midpoint insertion strategy.
+ The parameters division_limit and age_threshold provide these new values.
+
+ RETURN VALUE
+ none
+
+ NOTES
+ Currently the function is called when the values of the variables
+ key_cache_division_limit and/or key_cache_age_threshold are being reset
+ for the key cache keycache.
+*/
+
+void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
+ uint age_threshold)
+{
+ if (keycache->key_cache_inited)
+ {
+
+ keycache->interface_funcs->change_param(keycache->keycache_cb,
+ division_limit,
+ age_threshold);
+ }
+}
+
+
+/*
+ Destroy a key cache
+
+ SYNOPSIS
+ end_key_cache()
+ keycache pointer to the key cache to be destroyed
+ cleanup <=> complete free
+
+ DESCRIPTION
+ The function frees the memory allocated for the cache blocks and
+ auxiliary structures used by the key cache keycache. If the value
+ of the parameter cleanup is TRUE then all resources used by the key
+ cache are to be freed.
+
+ RETURN VALUE
+ none
+*/
+
+void end_key_cache(KEY_CACHE *keycache, my_bool cleanup)
+{
+ if (keycache->key_cache_inited)
+ {
+ keycache->interface_funcs->end(keycache->keycache_cb, cleanup);
+ if (cleanup)
+ {
+ if (keycache->keycache_cb)
+ {
+ my_free((uchar *) keycache->keycache_cb, MYF(0));
+ keycache->keycache_cb= 0;
+ }
+ keycache->key_cache_inited= 0;
+ }
+ keycache->can_be_used= 0;
+ }
+}
+
+
+/*
+ Read a block of data from a key cache into a buffer
+
+ SYNOPSIS
+
+ key_cache_read()
+ keycache pointer to the key cache to read data from
+ file handler for the file for the block of data to be read
+ filepos position of the block of data in the file
+ level determines the weight of the data
+ buff buffer to where the data must be placed
+ length length of the buffer
+ block_length length of the data read from a key cache block
+ return_buffer return pointer to the key cache buffer with the data
+
+ DESCRIPTION
+ The function operates over buffers of the key cache keycache.
+ In a general case the function reads a block of data from the key cache
+ into the buffer buff of the size specified by the parameter length. The
+ beginning of the block of data to be read is specified by the parameters
+ file and filepos. The length of the read data is the same as the length
+ of the buffer.
+ If the parameter return_buffer is not ignored and its value is TRUE, and
+ the data to be read of the specified size block_length can be read from one
+ key cache buffer, then the function returns a pointer to the data in the
+ key cache buffer.
+ The parameter 'level' is used only by the midpoint insertion strategy
+ when the data or its portion cannot be found in the key cache.
+ The function reads data into the buffer directly from file if the control
+ block of the key cache has not been initialized yet.
+
+ RETURN VALUE
+ Returns address from where the data is placed if successful, 0 - otherwise.
+
+ NOTES.
+ Filepos must be a multiple of 'block_length', but it doesn't
+ have to be a multiple of key_cache_block_size;
+*/
+
+uchar *key_cache_read(KEY_CACHE *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length, int return_buffer)
+{
+ if (keycache->key_cache_inited && keycache->can_be_used)
+ return keycache->interface_funcs->read(keycache->keycache_cb,
+ file, filepos, level,
+ buff, length,
+ block_length, return_buffer);
+
+ /* We can't use mutex here as the key cache may not be initialized */
+ keycache->global_cache_r_requests++;
+ keycache->global_cache_read++;
+
+ if (my_pread(file, (uchar*) buff, length, filepos, MYF(MY_NABP)))
+ return (uchar *) 0;
+
+ return buff;
+}
+
+
+/*
+ Insert a block of file data from a buffer into a key cache
+
+ SYNOPSIS
+ key_cache_insert()
+ keycache pointer to the key cache to insert data into
+ file handler for the file to insert data from
+ filepos position of the block of data in the file to insert
+ level determines the weight of the data
+ buff buffer to read data from
+ length length of the data in the buffer
+
+ DESCRIPTION
+ The function operates over buffers of the key cache keycache.
+ The function writes a block of file data from a buffer into the key cache.
+ The buffer is specified with the parameters buff and length - the pointer
+ to the beginning of the buffer and its size respectively. It's assumed
+ that the buffer contains the data from 'file' allocated from the position
+ filepos.
+ The parameter level is used to set one characteristic for the key buffers
+ loaded with the data from buff. The characteristic is used only by the
+ midpoint insertion strategy.
+
+ RETURN VALUE
+ 0 if a success, 1 - otherwise.
+
+ NOTES
+ The function is used by MyISAM to move all blocks from a index file to
+ the key cache.
+ It is assumed that it may be performed in parallel with reading the file
+ data from the key buffers by other threads.
+*/
+
+int key_cache_insert(KEY_CACHE *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length)
+{
+ if (keycache->key_cache_inited && keycache->can_be_used)
+ return keycache->interface_funcs->insert(keycache->keycache_cb,
+ file, filepos, level,
+ buff, length);
+ return 0;
+}
+
+
+/*
+ Write data from a buffer into a key cache
+
+ SYNOPSIS
+
+ key_cache_write()
+ keycache pointer to the key cache to write data to
+ file handler for the file to write data to
+ filepos position in the file to write data to
+ level determines the weight of the data
+ buff buffer with the data
+ length length of the buffer
+ dont_write if is 0 then all dirty pages involved in writing
+ should have been flushed from key cache
+ file_extra pointer to optional file attributes
+
+ DESCRIPTION
+ The function operates over buffers of the key cache keycache.
+ In a general case the function writes data from a buffer into the key
+ cache. The buffer is specified with the parameters buff and length -
+ the pointer to the beginning of the buffer and its size respectively.
+ It's assumed the buffer contains the data to be written into 'file'
+ starting from the position filepos.
+ If the value of the parameter dont_write is FALSE then the function
+ also writes the data into file.
+ The parameter level is used to set one characteristic for the key buffers
+ filled with the data from buff. The characteristic is employed only by
+ the midpoint insertion strategy.
+ The parameter file_expra may point to additional file attributes used
+ for optimization or other purposes.
+ The function writes data from the buffer directly into file if the control
+ block of the key cache has not been initialized yet.
+
+ RETURN VALUE
+ 0 if a success, 1 - otherwise.
+
+ NOTES
+ This implementation may exploit the fact that the function is called only
+ when a thread has got an exclusive lock for the key file.
+*/
+
+int key_cache_write(KEY_CACHE *keycache,
+ File file, void *file_extra,
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length, int force_write)
+{
+ if (keycache->key_cache_inited && keycache->can_be_used)
+ return keycache->interface_funcs->write(keycache->keycache_cb,
+ file, file_extra,
+ filepos, level,
+ buff, length,
+ block_length, force_write);
+
+ /* We can't use mutex here as the key cache may not be initialized */
+ keycache->global_cache_w_requests++;
+ keycache->global_cache_write++;
+ if (my_pwrite(file, buff, length, filepos, MYF(MY_NABP | MY_WAIT_IF_FULL)))
+ return 1;
+
+ return 0;
+}
+
+
+/*
+ Flush all blocks for a file from key buffers of a key cache
+
+ SYNOPSIS
+
+ flush_key_blocks()
+ keycache pointer to the key cache whose blocks are to be flushed
+ file handler for the file to flush to
+ file_extra maps of key cache (used for partitioned key caches)
+ flush_type type of the flush operation
+
+ DESCRIPTION
+ The function operates over buffers of the key cache keycache.
+ In a general case the function flushes the data from all dirty key
+ buffers related to the file 'file' into this file. The function does
+ exactly this if the value of the parameter type is FLUSH_KEEP. If the
+ value of this parameter is FLUSH_RELEASE, the function additionally
+ releases the key buffers containing data from 'file' for new usage.
+ If the value of the parameter type is FLUSH_IGNORE_CHANGED the function
+ just releases the key buffers containing data from 'file'.
+ If the value of the parameter type is FLUSH_KEEP the function may use
+ the value of the parameter file_extra pointing to possibly dirty
+ partitions to optimize the operation for partitioned key caches.
+
+ RETURN
+ 0 ok
+ 1 error
+
+ NOTES
+ Any implementation of the function may exploit the fact that the function
+ is called only when a thread has got an exclusive lock for the key file.
+*/
+
+int flush_key_blocks(KEY_CACHE *keycache,
+ int file, void *file_extra,
+ enum flush_type type)
+{
+ if (keycache->key_cache_inited)
+ return keycache->interface_funcs->flush(keycache->keycache_cb,
+ file, file_extra, type);
+ return 0;
+}
+
+
+/*
+ Reset the counters of a key cache
+
+ SYNOPSIS
+ reset_key_cache_counters()
+ name the name of a key cache (unused)
+ keycache pointer to the key cache for which to reset counters
+
+ DESCRIPTION
+ This function resets the values of the statistical counters for the key
+ cache keycache.
+ The parameter name is currently not used.
+
+ RETURN
+ 0 on success (always because it can't fail)
+
+ NOTES
+ This procedure is used by process_key_caches() to reset the counters of all
+ currently used key caches, both the default one and the named ones.
+*/
+
+int reset_key_cache_counters(const char *name __attribute__((unused)),
+ KEY_CACHE *keycache)
+{
+ if (keycache->key_cache_inited)
+ {
+
+ return keycache->interface_funcs->reset_counters(name,
+ keycache->keycache_cb);
+ }
+ return 0;
+}
+
+
+/*
+ Get statistics for a key cache
+
+ SYNOPSIS
+ get_key_cache_statistics()
+ keycache pointer to the key cache to get statistics for
+ partition_no partition number to get statistics for
+ key_cache_stats OUT pointer to the structure for the returned statistics
+
+ DESCRIPTION
+ If the value of the parameter partition_no is equal to 0 then statistics
+ for the whole key cache keycache (aggregated statistics) is returned in the
+ fields of the structure key_cache_stat of the type KEY_CACHE_STATISTICS.
+ Otherwise the value of the parameter partition_no makes sense only for
+ a partitioned key cache. In this case the function returns statistics
+ for the partition with the specified number partition_no.
+
+ RETURN
+ none
+*/
+
+void get_key_cache_statistics(KEY_CACHE *keycache, uint partition_no,
+ KEY_CACHE_STATISTICS *key_cache_stats)
+{
+ if (keycache->key_cache_inited)
+ {
+ keycache->interface_funcs->get_stats(keycache->keycache_cb,
+ partition_no, key_cache_stats);
+ }
+}
+
+
+/*
+ Get the value of a statistical variable for a key cache
+
+ SYNOPSIS
+ get_key_cache_stat_value()
+ keycache pointer to the key cache to get statistics for
+ var_no the ordered number of a statistical variable
+
+ DESCRIPTION
+ This function returns the value of the statistical variable var_no for
+ the key cache keycache. The variables are numbered starting from 0 to 6.
+
+ RETURN
+ The value of the specified statistical variable.
+
+ NOTES
+ Currently for any key cache the function can return values for the
+ following 7 statistical variables:
+
+ Name Number
+
+ blocks_used 0
+ blocks_unused 1
+ blocks_changed 2
+ read_requests 3
+ reads 4
+ write_requests 5
+ writes 6
+*/
+
+ulonglong get_key_cache_stat_value(KEY_CACHE *keycache, uint var_no)
+{
+ if (keycache->key_cache_inited)
+ {
+ return keycache->interface_funcs->get_stat_val(keycache->keycache_cb,
+ var_no);
+ }
+ else
+ return 0;
+}
+
+
+/*
+ Repartition a key cache
+
+ SYNOPSIS
+ repartition_key_cache()
+ keycache pointer to the key cache to be repartitioned
+ key_cache_block_size size of blocks to keep cached data
+ use_mem total memory to use for the new key cache
+ division_limit new division limit (if not zero)
+ age_threshold new age threshold (if not zero)
+ partitions new number of partitions in the key cache
+
+ DESCRIPTION
+ The function operates over the key cache keycache.
+ The parameter partitions specifies the number of partitions in the key
+ cache after repartitioning. If the value of this parameter is 0 then
+ a simple key cache must be created instead of the old one.
+ The parameter key_cache_block_size specifies the new size of the block
+ buffers in the key cache. The parameters division_limit and age_threshold
+ determine the new initial values of those characteristics of the key cache
+ that are used for midpoint insertion strategy. The parameter use_mem
+ specifies the total amount of memory to be allocated for the new key
+ cache buffers and for all auxiliary structures.
+
+ RETURN VALUE
+ number of blocks in the key cache, if successful,
+ 0 - otherwise.
+
+ NOTES
+ The function does not block the calls and executions of other functions
+ from the key cache interface. However it assumes that the calls of
+ resize_key_cache itself are serialized.
+
+ Currently the function is called when the value of the variable
+ key_cache_partitions is being reset for the key cache keycache.
+*/
+
+int repartition_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold, uint partitions)
+{
+ uint blocks= -1;
+ if (keycache->key_cache_inited)
+ {
+ keycache->interface_funcs->resize(keycache->keycache_cb,
+ key_cache_block_size, 0,
+ division_limit, age_threshold);
+ end_key_cache(keycache, 1);
+ blocks= init_key_cache(keycache, key_cache_block_size, use_mem,
+ division_limit, age_threshold, partitions);
+ }
+ return blocks;
+}
+
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-04-01 09:04:26 +0000
+++ b/sql/handler.cc 2010-04-03 20:19:35 +0000
@@ -3826,11 +3826,13 @@ int ha_init_key_cache(const char *name,
uint tmp_block_size= (uint) key_cache->param_block_size;
uint division_limit= key_cache->param_division_limit;
uint age_threshold= key_cache->param_age_threshold;
+ uint partitions= key_cache->param_partitions;
pthread_mutex_unlock(&LOCK_global_system_variables);
DBUG_RETURN(!init_key_cache(key_cache,
tmp_block_size,
tmp_buff_size,
- division_limit, age_threshold));
+ division_limit, age_threshold,
+ partitions));
}
DBUG_RETURN(0);
}
@@ -3860,10 +3862,12 @@ int ha_resize_key_cache(KEY_CACHE *key_c
/**
- Change parameters for key cache (like size)
+ Change parameters for key cache (like division_limit)
*/
int ha_change_key_cache_param(KEY_CACHE *key_cache)
{
+ DBUG_ENTER("ha_change_key_cache_param");
+
if (key_cache->key_cache_inited)
{
pthread_mutex_lock(&LOCK_global_system_variables);
@@ -3872,9 +3876,35 @@ int ha_change_key_cache_param(KEY_CACHE
pthread_mutex_unlock(&LOCK_global_system_variables);
change_key_cache_param(key_cache, division_limit, age_threshold);
}
- return 0;
+ DBUG_RETURN(0);
}
+
+/**
+ Repartition key cache
+*/
+int ha_repartition_key_cache(KEY_CACHE *key_cache)
+{
+ DBUG_ENTER("ha_repartition_key_cache");
+
+ if (key_cache->key_cache_inited)
+ {
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ size_t tmp_buff_size= (size_t) key_cache->param_buff_size;
+ long tmp_block_size= (long) key_cache->param_block_size;
+ uint division_limit= key_cache->param_division_limit;
+ uint age_threshold= key_cache->param_age_threshold;
+ uint partitions= key_cache->param_partitions;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ DBUG_RETURN(!repartition_key_cache(key_cache, tmp_block_size,
+ tmp_buff_size,
+ division_limit, age_threshold,
+ partitions));
+ }
+ DBUG_RETURN(0);
+}
+
+
/**
Free memory allocated by a key cache.
*/
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2010-03-25 13:33:39 +0000
+++ b/sql/handler.h 2010-03-29 21:16:12 +0000
@@ -2201,6 +2201,7 @@ int ha_table_exists_in_engine(THD* thd,
extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
int ha_resize_key_cache(KEY_CACHE *key_cache);
int ha_change_key_cache_param(KEY_CACHE *key_cache);
+int ha_repartition_key_cache(KEY_CACHE *key_cache);
int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
int ha_end_key_cache(KEY_CACHE *key_cache);
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-04-02 09:20:09 +0000
+++ b/sql/mysqld.cc 2010-04-03 20:19:35 +0000
@@ -5831,6 +5831,7 @@ enum options_mysqld
OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
+ OPT_KEY_CACHE_PARTITIONS,
OPT_LONG_QUERY_TIME,
OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
@@ -6928,6 +6929,12 @@ log and this option does nothing anymore
(uchar**) 0,
0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
1, 100, 0, 1, 0},
+ {"key_cache_partitions", OPT_KEY_CACHE_PARTITIONS,
+ "The number of partitions in key cache",
+ (uchar**) &dflt_key_cache_var.param_partitions,
+ (uchar**) 0,
+ 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, DEFAULT_KEY_CACHE_PARTITIONS,
+ 0, MAX_KEY_CACHE_PARTITIONS, 0, 1, 0},
{"log-slow-filter", OPT_LOG_SLOW_FILTER,
"Log only the queries that followed certain execution plan. Multiple flags allowed in a comma-separated string. [admin, filesort, filesort_on_disk, full_join, full_scan, query_cache, query_cache_miss, tmp_table, tmp_table_on_disk]. Sets log-slow-admin-command to ON",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, QPLAN_ALWAYS_SET, 0, 0},
@@ -8910,6 +8917,7 @@ mysql_getopt_value(const char *keyname,
case OPT_KEY_CACHE_BLOCK_SIZE:
case OPT_KEY_CACHE_DIVISION_LIMIT:
case OPT_KEY_CACHE_AGE_THRESHOLD:
+ case OPT_KEY_CACHE_PARTITIONS:
{
KEY_CACHE *key_cache;
if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
@@ -8927,6 +8935,8 @@ mysql_getopt_value(const char *keyname,
return (uchar**) &key_cache->param_division_limit;
case OPT_KEY_CACHE_AGE_THRESHOLD:
return (uchar**) &key_cache->param_age_threshold;
+ case OPT_KEY_CACHE_PARTITIONS:
+ return (uchar**) &key_cache->param_partitions;
}
}
}
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2010-04-01 09:04:26 +0000
+++ b/sql/set_var.cc 2010-04-03 20:19:35 +0000
@@ -320,15 +320,18 @@ static sys_var_thd_ulong sys_interactive
static sys_var_thd_ulong sys_join_buffer_size(&vars, "join_buffer_size",
&SV::join_buff_size);
static sys_var_key_buffer_size sys_key_buffer_size(&vars, "key_buffer_size");
-static sys_var_key_cache_long sys_key_cache_block_size(&vars, "key_cache_block_size",
- offsetof(KEY_CACHE,
- param_block_size));
-static sys_var_key_cache_long sys_key_cache_division_limit(&vars, "key_cache_division_limit",
- offsetof(KEY_CACHE,
- param_division_limit));
-static sys_var_key_cache_long sys_key_cache_age_threshold(&vars, "key_cache_age_threshold",
- offsetof(KEY_CACHE,
- param_age_threshold));
+static sys_var_key_cache_long sys_key_cache_block_size(&vars,
+ "key_cache_block_size",
+ offsetof(KEY_CACHE,param_block_size));
+static sys_var_key_cache_long sys_key_cache_division_limit(&vars,
+ "key_cache_division_limit",
+ offsetof(KEY_CACHE, param_division_limit));
+static sys_var_key_cache_long sys_key_cache_age_threshold(&vars,
+ "key_cache_age_threshold",
+ offsetof(KEY_CACHE, param_age_threshold));
+static sys_var_key_cache_long sys_key_cache_partitions(&vars,
+ "key_cache_partitions",
+ offsetof(KEY_CACHE, param_partitions));
static sys_var_const sys_language(&vars, "language",
OPT_GLOBAL, SHOW_CHAR,
(uchar*) language);
@@ -2548,7 +2551,21 @@ bool sys_var_key_cache_long::update(THD
pthread_mutex_unlock(&LOCK_global_system_variables);
- error= (bool) (ha_resize_key_cache(key_cache));
+ switch (offset) {
+
+ case offsetof(KEY_CACHE, param_block_size):
+ error= (bool) (ha_resize_key_cache(key_cache));
+ break;
+
+ case offsetof(KEY_CACHE, param_division_limit):
+ case offsetof(KEY_CACHE, param_age_threshold):
+ error= (bool) (ha_change_key_cache_param(key_cache));
+ break;
+
+ case offsetof(KEY_CACHE, param_partitions):
+ error= (bool) (ha_repartition_key_cache(key_cache));
+ break;
+ }
pthread_mutex_lock(&LOCK_global_system_variables);
key_cache->in_init= 0;
@@ -4156,6 +4173,7 @@ static KEY_CACHE *create_key_cache(const
key_cache->param_block_size= dflt_key_cache_var.param_block_size;
key_cache->param_division_limit= dflt_key_cache_var.param_division_limit;
key_cache->param_age_threshold= dflt_key_cache_var.param_age_threshold;
+ key_cache->param_partitions= dflt_key_cache_var.param_partitions;
}
}
DBUG_RETURN(key_cache);
=== modified file 'sql/set_var.h'
--- a/sql/set_var.h 2009-12-03 11:19:05 +0000
+++ b/sql/set_var.h 2010-02-16 16:41:11 +0000
@@ -1427,6 +1427,7 @@ public:
my_free((uchar*) name, MYF(0));
}
friend bool process_key_caches(process_key_cache_t func);
+ friend int fill_key_cache_tables(THD *thd, TABLE_LIST *tables, COND *cond);
friend void delete_elements(I_List<NAMED_LIST> *list,
void (*free_element)(const char*, uchar*));
};
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-04-02 09:20:09 +0000
+++ b/sql/sql_show.cc 2010-04-06 02:08:10 +0000
@@ -2249,6 +2249,32 @@ void remove_status_vars(SHOW_VAR *list)
}
+
+static void update_key_cache_stat_var(KEY_CACHE *key_cache, size_t ofs)
+{
+ uint var_no;
+ switch (ofs) {
+ case offsetof(KEY_CACHE, blocks_used):
+ case offsetof(KEY_CACHE, blocks_unused):
+ case offsetof(KEY_CACHE, global_blocks_changed):
+ var_no= (ofs-offsetof(KEY_CACHE, blocks_used))/sizeof(ulong);
+ *(ulong *)((char *) key_cache + ofs)=
+ (ulong) get_key_cache_stat_value(key_cache, var_no);
+ break;
+ case offsetof(KEY_CACHE, global_cache_r_requests):
+ case offsetof(KEY_CACHE, global_cache_read):
+ case offsetof(KEY_CACHE, global_cache_w_requests):
+ case offsetof(KEY_CACHE, global_cache_write):
+ var_no= NUM_LONG_KEY_CACHE_STAT_VARIABLES +
+ (ofs-offsetof(KEY_CACHE, global_cache_w_requests))/
+ sizeof(ulonglong);
+ *(ulonglong *)((char *) key_cache + ofs)=
+ get_key_cache_stat_value(key_cache, var_no);
+ break;
+ }
+}
+
+
static bool show_status_array(THD *thd, const char *wild,
SHOW_VAR *variables,
enum enum_var_type value_type,
@@ -2381,10 +2407,12 @@ static bool show_status_array(THD *thd,
break;
}
case SHOW_KEY_CACHE_LONG:
+ update_key_cache_stat_var(dflt_key_cache, (size_t) value);
value= (char*) dflt_key_cache + (ulong)value;
end= int10_to_str(*(long*) value, buff, 10);
break;
case SHOW_KEY_CACHE_LONGLONG:
+ update_key_cache_stat_var(dflt_key_cache, (size_t) value);
value= (char*) dflt_key_cache + (ulong)value;
end= longlong10_to_str(*(longlong*) value, buff, 10);
break;
@@ -6640,6 +6668,90 @@ int fill_schema_files(THD *thd, TABLE_LI
}
+static
+int store_key_cache_table_record(THD *thd, TABLE *table,
+ const char *name, uint name_length,
+ KEY_CACHE *key_cache,
+ uint partitions, uint partition_no)
+{
+ KEY_CACHE_STATISTICS keycache_stats;
+ uint err;
+ DBUG_ENTER("store_key_cache_table_record");
+
+ get_key_cache_statistics(key_cache, partition_no, &keycache_stats);
+
+ if (!key_cache->key_cache_inited || keycache_stats.mem_size == 0)
+ DBUG_RETURN(0);
+
+ restore_record(table, s->default_values);
+ table->field[0]->store(name, name_length, system_charset_info);
+ if (partitions == 0)
+ table->field[1]->set_null();
+ else
+ {
+ table->field[1]->set_notnull();
+ table->field[1]->store((long) partitions, TRUE);
+ }
+
+ if (partition_no == 0)
+ table->field[2]->set_null();
+ else
+ {
+ table->field[2]->set_notnull();
+ table->field[2]->store((long) partition_no, TRUE);
+ }
+ table->field[3]->store(keycache_stats.mem_size, TRUE);
+ table->field[4]->store(keycache_stats.block_size, TRUE);
+ table->field[5]->store(keycache_stats.blocks_used, TRUE);
+ table->field[6]->store(keycache_stats.blocks_unused, TRUE);
+ table->field[7]->store(keycache_stats.blocks_changed, TRUE);
+ table->field[8]->store(keycache_stats.read_requests, TRUE);
+ table->field[9]->store(keycache_stats.reads, TRUE);
+ table->field[10]->store(keycache_stats.write_requests, TRUE);
+ table->field[11]->store(keycache_stats.writes, TRUE);
+
+ err= schema_table_store_record(thd, table);
+ DBUG_RETURN(err);
+}
+
+
+int fill_key_cache_tables(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+ TABLE *table= tables->table;
+ I_List_iterator<NAMED_LIST> it(key_caches);
+ NAMED_LIST *element;
+ DBUG_ENTER("fill_key_cache_tables");
+
+ while ((element= it++))
+ {
+ KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
+
+ if (!key_cache->key_cache_inited)
+ continue;
+
+ uint partitions= key_cache->partitions;
+ DBUG_ASSERT(partitions <= MAX_KEY_CACHE_PARTITIONS);
+
+ if (partitions)
+ {
+ for (uint i= 0; i < partitions; i++)
+ {
+ if (store_key_cache_table_record(thd, table,
+ element->name, element->name_length,
+ key_cache, partitions, i+1))
+ DBUG_RETURN(1);
+ }
+ }
+
+ if (store_key_cache_table_record(thd, table,
+ element->name, element->name_length,
+ key_cache, partitions, 0))
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+
+
ST_FIELD_INFO schema_fields_info[]=
{
{"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
@@ -7219,6 +7331,35 @@ ST_FIELD_INFO referential_constraints_fi
};
+ST_FIELD_INFO keycache_fields_info[]=
+{
+ {"KEY_CACHE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+ {"PARTITIONS", 3, MYSQL_TYPE_LONG, 0,
+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED) , 0, SKIP_OPEN_TABLE},
+ {"PARTITION_NUMBER", 3, MYSQL_TYPE_LONG, 0,
+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
+ {"FULL_SIZE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
+ {"BLOCK_SIZE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE },
+ {"USED_BLOCKS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_UNSIGNED), "Key_blocks_used", SKIP_OPEN_TABLE},
+ {"UNUSED_BLOCKS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_UNSIGNED), "Key_blocks_unused", SKIP_OPEN_TABLE},
+ {"DIRTY_BLOCKS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_UNSIGNED), "Key_blocks_not_flushed", SKIP_OPEN_TABLE},
+ {"READ_REQUESTS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_UNSIGNED), "Key_read_requests", SKIP_OPEN_TABLE},
+ {"READS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_UNSIGNED), "Key_reads", SKIP_OPEN_TABLE},
+ {"WRITE_REQUESTS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_UNSIGNED), "Key_write_requests", SKIP_OPEN_TABLE},
+ {"WRITES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ (MY_I_S_UNSIGNED), "Key_writes", SKIP_OPEN_TABLE},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
+};
+
+
/*
Description of ST_FIELD_INFO in table.h
@@ -7258,6 +7399,8 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_variables, make_old_format, 0, 0, -1, 0, 0},
{"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
fill_schema_index_stats, make_old_format, 0, -1, -1, 0, 0},
+ {"KEY_CACHES", keycache_fields_info, create_schema_table,
+ fill_key_cache_tables, make_old_format, 0, -1,-1, 0, 0},
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
OPEN_TABLE_ONLY},
=== modified file 'sql/sql_test.cc'
--- a/sql/sql_test.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_test.cc 2010-03-29 21:16:12 +0000
@@ -445,7 +445,8 @@ static int print_key_cache_status(const
Buffer_size: %10lu\n\
Block_size: %10lu\n\
Division_limit: %10lu\n\
-Age_limit: %10lu\n\
+Age_threshold: %10lu\n\
+Partitions: %10lu\n\
blocks used: %10lu\n\
not flushed: %10lu\n\
w_requests: %10s\n\
@@ -455,6 +456,7 @@ reads: %10s\n\n",
name,
(ulong) key_cache->param_buff_size, key_cache->param_block_size,
key_cache->param_division_limit, key_cache->param_age_threshold,
+ key_cache->param_partitions,
key_cache->blocks_used,key_cache->global_blocks_changed,
llstr(key_cache->global_cache_w_requests,llbuff1),
llstr(key_cache->global_cache_write,llbuff2),
=== modified file 'sql/table.h'
--- a/sql/table.h 2010-02-12 08:47:31 +0000
+++ b/sql/table.h 2010-02-16 16:41:11 +0000
@@ -953,6 +953,7 @@ enum enum_schema_tables
SCH_GLOBAL_STATUS,
SCH_GLOBAL_VARIABLES,
SCH_INDEX_STATS,
+ SCH_KEY_CACHES,
SCH_KEY_COLUMN_USAGE,
SCH_OPEN_TABLES,
SCH_PARTITIONS,
=== modified file 'storage/myisam/mi_check.c'
--- a/storage/myisam/mi_check.c 2010-01-14 16:51:00 +0000
+++ b/storage/myisam/mi_check.c 2010-02-16 16:41:11 +0000
@@ -332,7 +332,8 @@ int chk_size(HA_CHECK *param, register M
/* The following is needed if called externally (not from myisamchk) */
flush_key_blocks(info->s->key_cache,
- info->s->kfile, FLUSH_FORCE_WRITE);
+ info->s->kfile, &info->s->dirty_part_map,
+ FLUSH_FORCE_WRITE);
size= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
if ((skr=(my_off_t) info->state->key_file_length) != size)
@@ -1474,6 +1475,7 @@ static int mi_drop_all_indexes(HA_CHECK
*/
DBUG_PRINT("repair", ("all disabled are empty: create missing"));
error= flush_key_blocks(share->key_cache, share->kfile,
+ &share->dirty_part_map,
FLUSH_FORCE_WRITE);
goto end;
}
@@ -1488,6 +1490,7 @@ static int mi_drop_all_indexes(HA_CHECK
/* Remove all key blocks of this index file from key cache. */
if ((error= flush_key_blocks(share->key_cache, share->kfile,
+ &share->dirty_part_map,
FLUSH_IGNORE_CHANGED)))
goto end; /* purecov: inspected */
@@ -1549,7 +1552,7 @@ int mi_repair(HA_CHECK *param, register
if (!param->using_global_keycache)
VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size,
- (size_t) param->use_buffers, 0, 0));
+ (size_t) param->use_buffers, 0, 0, 0));
if (init_io_cache(¶m->read_cache,info->dfile,
(uint) param->read_buffer_length,
@@ -1762,7 +1765,8 @@ err:
VOID(end_io_cache(¶m->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
VOID(end_io_cache(&info->rec_cache));
- got_error|=flush_blocks(param, share->key_cache, share->kfile);
+ got_error|=flush_blocks(param, share->key_cache, share->kfile,
+ &share->dirty_part_map);
if (!got_error && param->testflag & T_UNPACK)
{
share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
@@ -1908,9 +1912,10 @@ void lock_memory(HA_CHECK *param __attri
/* Flush all changed blocks to disk */
-int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file)
+int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file,
+ ulonglong *dirty_part_map)
{
- if (flush_key_blocks(key_cache, file, FLUSH_RELEASE))
+ if (flush_key_blocks(key_cache, file, dirty_part_map, FLUSH_RELEASE))
{
mi_check_print_error(param,"%d when trying to write bufferts",my_errno);
return(1);
@@ -1977,7 +1982,8 @@ int mi_sort_index(HA_CHECK *param, regis
}
/* Flush key cache for this file if we are calling this outside myisamchk */
- flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED);
+ flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map,
+ FLUSH_IGNORE_CHANGED);
share->state.version=(ulong) time((time_t*) 0);
old_state= share->state; /* save state if not stored */
@@ -2535,7 +2541,8 @@ int mi_repair_by_sort(HA_CHECK *param, r
memcpy( &share->state.state, info->state, sizeof(*info->state));
err:
- got_error|= flush_blocks(param, share->key_cache, share->kfile);
+ got_error|= flush_blocks(param, share->key_cache, share->kfile,
+ &share->dirty_part_map);
VOID(end_io_cache(&info->rec_cache));
if (!got_error)
{
@@ -3059,7 +3066,8 @@ int mi_repair_parallel(HA_CHECK *param,
memcpy(&share->state.state, info->state, sizeof(*info->state));
err:
- got_error|= flush_blocks(param, share->key_cache, share->kfile);
+ got_error|= flush_blocks(param, share->key_cache, share->kfile,
+ &share->dirty_part_map);
/*
Destroy the write cache. The master thread did already detach from
the share by remove_io_thread() or it was not yet started (if the
=== modified file 'storage/myisam/mi_close.c'
--- a/storage/myisam/mi_close.c 2010-02-10 19:06:24 +0000
+++ b/storage/myisam/mi_close.c 2010-02-16 16:41:11 +0000
@@ -64,6 +64,7 @@ int mi_close(register MI_INFO *info)
if (share->kfile >= 0) abort(););
if (share->kfile >= 0 &&
flush_key_blocks(share->key_cache, share->kfile,
+ &share->dirty_part_map,
((share->temporary || share->deleting) ?
FLUSH_IGNORE_CHANGED :
FLUSH_RELEASE)))
=== modified file 'storage/myisam/mi_delete_all.c'
--- a/storage/myisam/mi_delete_all.c 2008-04-28 16:24:05 +0000
+++ b/storage/myisam/mi_delete_all.c 2010-02-16 16:41:11 +0000
@@ -52,7 +52,8 @@ int mi_delete_all_rows(MI_INFO *info)
If we are using delayed keys or if the user has done changes to the tables
since it was locked then there may be key blocks in the key cache
*/
- flush_key_blocks(share->key_cache, share->kfile, FLUSH_IGNORE_CHANGED);
+ flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map,
+ FLUSH_IGNORE_CHANGED);
#ifdef HAVE_MMAP
if (share->file_map)
_mi_unmap_file(info);
=== modified file 'storage/myisam/mi_extra.c'
--- a/storage/myisam/mi_extra.c 2010-02-10 19:06:24 +0000
+++ b/storage/myisam/mi_extra.c 2010-02-16 16:41:11 +0000
@@ -268,6 +268,7 @@ int mi_extra(MI_INFO *info, enum ha_extr
pthread_mutex_lock(&share->intern_lock);
/* Flush pages that we don't need anymore */
if (flush_key_blocks(share->key_cache, share->kfile,
+ &share->dirty_part_map,
(function == HA_EXTRA_PREPARE_FOR_DROP ?
FLUSH_IGNORE_CHANGED : FLUSH_RELEASE)))
{
@@ -326,7 +327,8 @@ int mi_extra(MI_INFO *info, enum ha_extr
break;
case HA_EXTRA_FLUSH:
if (!share->temporary)
- flush_key_blocks(share->key_cache, share->kfile, FLUSH_KEEP);
+ flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map,
+ FLUSH_KEEP);
#ifdef HAVE_PWRITE
_mi_decrement_open_count(info);
#endif
=== modified file 'storage/myisam/mi_keycache.c'
--- a/storage/myisam/mi_keycache.c 2008-03-29 15:56:33 +0000
+++ b/storage/myisam/mi_keycache.c 2010-02-16 16:41:11 +0000
@@ -75,7 +75,8 @@ int mi_assign_to_key_cache(MI_INFO *info
in the old key cache.
*/
- if (flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE))
+ if (flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map,
+ FLUSH_RELEASE))
{
error= my_errno;
mi_print_error(info->s, HA_ERR_CRASHED);
@@ -90,7 +91,8 @@ int mi_assign_to_key_cache(MI_INFO *info
(This can never fail as there is never any not written data in the
new key cache)
*/
- (void) flush_key_blocks(key_cache, share->kfile, FLUSH_RELEASE);
+ (void) flush_key_blocks(key_cache, share->kfile, &share->dirty_part_map,
+ FLUSH_RELEASE);
/*
ensure that setting the key cache and changing the multi_key_cache
@@ -102,6 +104,7 @@ int mi_assign_to_key_cache(MI_INFO *info
This should be seen at the lastes for the next call to an myisam function.
*/
share->key_cache= key_cache;
+ share->dirty_part_map= 0;
/* store the key cache in the global hash structure for future opens */
if (multi_key_cache_set((uchar*) share->unique_file_name,
=== modified file 'storage/myisam/mi_locking.c'
--- a/storage/myisam/mi_locking.c 2009-10-06 06:57:22 +0000
+++ b/storage/myisam/mi_locking.c 2010-02-16 16:41:11 +0000
@@ -68,7 +68,9 @@ int mi_lock_database(MI_INFO *info, int
--share->tot_locks;
if (info->lock_type == F_WRLCK && !share->w_locks &&
!share->delay_key_write && flush_key_blocks(share->key_cache,
- share->kfile,FLUSH_KEEP))
+ share->kfile,
+ &share->dirty_part_map,
+ FLUSH_KEEP))
{
error=my_errno;
mi_print_error(info->s, HA_ERR_CRASHED);
@@ -513,7 +515,8 @@ int _mi_test_if_changed(register MI_INFO
{ /* Keyfile has changed */
DBUG_PRINT("info",("index file changed"));
if (share->state.process != share->this_process)
- VOID(flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE));
+ VOID(flush_key_blocks(share->key_cache, share->kfile,
+ &share->dirty_part_map, FLUSH_RELEASE));
share->last_process=share->state.process;
info->last_unique= share->state.unique;
info->last_loop= share->state.update_count;
=== modified file 'storage/myisam/mi_page.c'
--- a/storage/myisam/mi_page.c 2009-05-06 12:03:24 +0000
+++ b/storage/myisam/mi_page.c 2010-02-16 16:41:11 +0000
@@ -94,10 +94,11 @@ int _mi_write_keypage(register MI_INFO *
}
#endif
DBUG_RETURN((key_cache_write(info->s->key_cache,
- info->s->kfile,page, level, (uchar*) buff,length,
- (uint) keyinfo->block_length,
- (int) ((info->lock_type != F_UNLCK) ||
- info->s->delay_key_write))));
+ info->s->kfile, &info->s->dirty_part_map,
+ page, level, (uchar*) buff, length,
+ (uint) keyinfo->block_length,
+ (int) ((info->lock_type != F_UNLCK) ||
+ info->s->delay_key_write))));
} /* mi_write_keypage */
@@ -116,7 +117,8 @@ int _mi_dispose(register MI_INFO *info,
mi_sizestore(buff,old_link);
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
DBUG_RETURN(key_cache_write(info->s->key_cache,
- info->s->kfile, pos , level, buff,
+ info->s->kfile, &info->s->dirty_part_map,
+ pos , level, buff,
sizeof(buff),
(uint) keyinfo->block_length,
(int) (info->lock_type != F_UNLCK)));
=== modified file 'storage/myisam/mi_panic.c'
--- a/storage/myisam/mi_panic.c 2006-12-31 00:32:21 +0000
+++ b/storage/myisam/mi_panic.c 2010-02-16 16:41:11 +0000
@@ -47,7 +47,8 @@ int mi_panic(enum ha_panic_function flag
if (info->s->options & HA_OPTION_READ_ONLY_DATA)
break;
#endif
- if (flush_key_blocks(info->s->key_cache, info->s->kfile, FLUSH_RELEASE))
+ if (flush_key_blocks(info->s->key_cache, info->s->kfile,
+ &info->s->dirty_part_map, FLUSH_RELEASE))
error=my_errno;
if (info->opt_flag & WRITE_CACHE_USED)
if (flush_io_cache(&info->rec_cache))
=== modified file 'storage/myisam/mi_preload.c'
--- a/storage/myisam/mi_preload.c 2009-09-09 15:13:13 +0000
+++ b/storage/myisam/mi_preload.c 2010-02-16 16:41:11 +0000
@@ -65,7 +65,7 @@ int mi_preload(MI_INFO *info, ulonglong
}
}
else
- block_length= share->key_cache->key_cache_block_size;
+ block_length= share->key_cache->param_block_size;
length= info->preload_buff_size/block_length * block_length;
set_if_bigger(length, block_length);
@@ -73,7 +73,8 @@ int mi_preload(MI_INFO *info, ulonglong
if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME))))
DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM);
- if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_RELEASE))
+ if (flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map,
+ FLUSH_RELEASE))
goto err;
do
=== modified file 'storage/myisam/mi_test1.c'
--- a/storage/myisam/mi_test1.c 2008-04-28 16:24:05 +0000
+++ b/storage/myisam/mi_test1.c 2010-02-16 16:41:11 +0000
@@ -49,7 +49,8 @@ int main(int argc,char *argv[])
MY_INIT(argv[0]);
my_init();
if (key_cacheing)
- init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,IO_SIZE*16,0,0);
+ init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,IO_SIZE*16,0,0,
+ DEFAULT_KEY_CACHE_PARTITIONS);
get_options(argc,argv);
exit(run_test("test1"));
=== modified file 'storage/myisam/mi_test2.c'
--- a/storage/myisam/mi_test2.c 2008-04-28 16:24:05 +0000
+++ b/storage/myisam/mi_test2.c 2010-02-16 16:41:11 +0000
@@ -215,7 +215,8 @@ int main(int argc, char *argv[])
if (!silent)
printf("- Writing key:s\n");
if (key_cacheing)
- init_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size,0,0);
+ init_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size,0,0,
+ DEFAULT_KEY_CACHE_PARTITIONS);
if (do_locking)
mi_lock_database(file,F_WRLCK);
if (write_cacheing)
=== modified file 'storage/myisam/mi_test3.c'
--- a/storage/myisam/mi_test3.c 2010-01-06 21:27:53 +0000
+++ b/storage/myisam/mi_test3.c 2010-02-16 16:41:11 +0000
@@ -177,7 +177,8 @@ void start_test(int id)
exit(1);
}
if (key_cacheing && rnd(2) == 0)
- init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0);
+ init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0,
+ DEFAULT_KEY_CACHE_PARTITIONS);
printf("Process %d, pid: %ld\n", id, (long) getpid());
fflush(stdout);
=== modified file 'storage/myisam/myisam_ftdump.c'
--- a/storage/myisam/myisam_ftdump.c 2009-11-30 13:36:06 +0000
+++ b/storage/myisam/myisam_ftdump.c 2010-02-16 16:41:11 +0000
@@ -83,7 +83,7 @@ int main(int argc,char *argv[])
usage();
}
- init_key_cache(dflt_key_cache,MI_KEY_BLOCK_LENGTH,USE_BUFFER_INIT, 0, 0);
+ init_key_cache(dflt_key_cache,MI_KEY_BLOCK_LENGTH,USE_BUFFER_INIT, 0, 0, 0);
if (!(info=mi_open(argv[0], O_RDONLY,
HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER)))
=== modified file 'storage/myisam/myisamchk.c'
--- a/storage/myisam/myisamchk.c 2009-12-03 11:34:11 +0000
+++ b/storage/myisam/myisamchk.c 2010-02-16 16:41:11 +0000
@@ -1102,7 +1102,7 @@ static int myisamchk(HA_CHECK *param, ch
{
if (param->testflag & (T_EXTEND | T_MEDIUM))
VOID(init_key_cache(dflt_key_cache,opt_key_cache_block_size,
- (size_t) param->use_buffers, 0, 0));
+ (size_t) param->use_buffers, 0, 0, 0));
VOID(init_io_cache(¶m->read_cache,datafile,
(uint) param->read_buffer_length,
READ_CACHE,
@@ -1116,7 +1116,8 @@ static int myisamchk(HA_CHECK *param, ch
HA_OPTION_COMPRESS_RECORD)) ||
(param->testflag & (T_EXTEND | T_MEDIUM)))
error|=chk_data_link(param, info, test(param->testflag & T_EXTEND));
- error|=flush_blocks(param, share->key_cache, share->kfile);
+ error|=flush_blocks(param, share->key_cache, share->kfile,
+ &share->dirty_part_map);
VOID(end_io_cache(¶m->read_cache));
}
if (!error)
@@ -1526,7 +1527,7 @@ static int mi_sort_records(HA_CHECK *par
DBUG_RETURN(0); /* Nothing to do */
init_key_cache(dflt_key_cache, opt_key_cache_block_size,
- (size_t) param->use_buffers, 0, 0);
+ (size_t) param->use_buffers, 0, 0, 0);
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
@@ -1641,8 +1642,8 @@ err:
my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
sort_info.buff=0;
share->state.sortkey=sort_key;
- DBUG_RETURN(flush_blocks(param, share->key_cache, share->kfile) |
- got_error);
+ DBUG_RETURN(flush_blocks(param, share->key_cache, share->kfile,
+ &share->dirty_part_map) | got_error);
} /* sort_records */
=== modified file 'storage/myisam/myisamdef.h'
--- a/storage/myisam/myisamdef.h 2010-03-04 08:03:07 +0000
+++ b/storage/myisam/myisamdef.h 2010-03-29 21:16:12 +0000
@@ -174,6 +174,8 @@ typedef struct st_mi_isam_share
*index_file_name;
uchar *file_map; /* mem-map of file if possible */
KEY_CACHE *key_cache; /* ref to the current key cache */
+ /* To mark the key cache partitions containing dirty pages for this file */
+ ulonglong dirty_part_map;
MI_DECODE_TREE *decode_trees;
uint16 *decode_tables;
/* Function to use for a row checksum. */
@@ -732,7 +734,8 @@ void mi_check_print_info _VARARGS((HA_CH
#ifdef THREAD
pthread_handler_t thr_find_all_keys(void *arg);
#endif
-int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file);
+int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file,
+ ulonglong *dirty_part_map);
#ifdef __cplusplus
}
#endif
=== modified file 'storage/myisam/myisamlog.c'
--- a/storage/myisam/myisamlog.c 2009-11-29 23:08:56 +0000
+++ b/storage/myisam/myisamlog.c 2010-02-16 16:41:11 +0000
@@ -333,7 +333,7 @@ static int examine_log(char * file_name,
init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
(tree_element_free) file_info_free, NULL);
VOID(init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE,
- 0, 0));
+ 0, 0, 0));
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2750)
by Igor Babaev 06 Apr '10
by Igor Babaev 06 Apr '10
06 Apr '10
#At lp:maria/5.2 based on revid:igor@askmonty.org-20100405202809-beg2cwhelygpbl6i
2750 Igor Babaev 2010-04-05
Post review fixes.
modified:
include/keycache.h
mysql-test/suite/funcs_1/r/is_columns_is.result
mysql-test/suite/funcs_1/r/is_tables_is.result
mysys/mf_keycache.c
sql/sql_show.cc
=== modified file 'include/keycache.h'
--- a/include/keycache.h 2010-04-01 21:42:40 +0000
+++ b/include/keycache.h 2010-04-06 02:08:10 +0000
@@ -52,7 +52,7 @@ typedef struct st_key_cache_statistics
ulonglong writes; /* number of actual writes from buffers into files */
} KEY_CACHE_STATISTICS;
-#define NO_LONG_KEY_CACHE_STAT_VARIABLES 3
+#define NUM_LONG_KEY_CACHE_STAT_VARIABLES 3
/* The type of a key cache object */
typedef enum key_cache_type
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_is.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result 2010-04-02 10:03:39 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result 2010-04-06 02:08:10 +0000
@@ -230,6 +230,18 @@ NULL information_schema INNODB_TRX trx_s
NULL information_schema INNODB_TRX trx_state 2 NO varchar 13 39 NULL NULL utf8 utf8_general_ci varchar(13) select
NULL information_schema INNODB_TRX trx_wait_started 5 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema INNODB_TRX trx_weight 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES BLOCK_SIZE 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES DIRTY_BLOCKS 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES FULL_SIZE 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES KEY_CACHE_NAME 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema KEY_CACHES PARTITIONS 2 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned select
+NULL information_schema KEY_CACHES PARTITION_NUMBER 3 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned select
+NULL information_schema KEY_CACHES READS 10 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES READ_REQUESTS 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES UNUSED_BLOCKS 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES USED_BLOCKS 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES WRITES 12 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES WRITE_REQUESTS 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
NULL information_schema KEY_COLUMN_USAGE COLUMN_NAME 7 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
@@ -743,6 +755,18 @@ NULL information_schema INNODB_TRX trx_w
NULL information_schema INNODB_TRX trx_weight bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_TRX trx_mysql_thread_id bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema INNODB_TRX trx_query varchar 1024 3072 utf8 utf8_general_ci varchar(1024)
+3.0000 information_schema KEY_CACHES KEY_CACHE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
+NULL information_schema KEY_CACHES PARTITIONS int NULL NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES PARTITION_NUMBER int NULL NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES FULL_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES BLOCK_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES USED_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES UNUSED_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES DIRTY_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES READ_REQUESTS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES READS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITE_REQUESTS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITES bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
=== modified file 'mysql-test/suite/funcs_1/r/is_tables_is.result'
--- a/mysql-test/suite/funcs_1/r/is_tables_is.result 2010-02-01 06:14:12 +0000
+++ b/mysql-test/suite/funcs_1/r/is_tables_is.result 2010-04-06 02:08:10 +0000
@@ -590,6 +590,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME KEY_CACHES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME KEY_COLUMN_USAGE
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1688,6 +1711,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME KEY_CACHES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME KEY_COLUMN_USAGE
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2010-04-03 20:19:35 +0000
+++ b/mysys/mf_keycache.c 2010-04-06 02:08:10 +0000
@@ -5158,6 +5158,7 @@ int init_partitioned_key_cache(PARTITION
{
int i;
size_t mem_per_cache;
+ size_t mem_decr;
int cnt;
SIMPLE_KEY_CACHE_CB *partition;
SIMPLE_KEY_CACHE_CB **partition_ptr;
@@ -5175,9 +5176,11 @@ int init_partitioned_key_cache(PARTITION
(SIMPLE_KEY_CACHE_CB **) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB *) *
partitions, MYF(MY_WME))))
DBUG_RETURN(-1);
+ bzero(partition_ptr, sizeof(SIMPLE_KEY_CACHE_CB *) * partitions);
keycache->partition_array= partition_ptr;
}
+ mem_decr= mem_per_cache / 5;
mem_per_cache = use_mem / partitions;
for (i= 0; i < (int) partitions; i++)
@@ -5194,30 +5197,64 @@ int init_partitioned_key_cache(PARTITION
partition->key_cache_inited= 0;
}
- if ((cnt= init_simple_key_cache(partition,
- key_cache_block_size, mem_per_cache,
- division_limit, age_threshold)) <= 0)
+ cnt= init_simple_key_cache(partition, key_cache_block_size, mem_per_cache,
+ division_limit, age_threshold);
+ if (cnt <= 0)
{
end_simple_key_cache(partition, 1);
- my_free(partition, MYF(0));
- partition= 0;
- if (key_cache_inited)
+ if (!key_cache_inited)
{
- memmove(partition_ptr, partition_ptr+1,
- sizeof(partition_ptr)*(partitions-i-1));
+ my_free(partition, MYF(0));
+ partition= 0;
}
- if (!--partitions)
- break;
- if (i == 0)
+ if (i == 0 && cnt < 0 || i > 0)
{
- i--;
- mem_per_cache = use_mem / partitions;
- continue;
+ /*
+ Here we have two cases:
+ 1. i == 0 and cnt < 0
+ cnt < 0 => mem_per_cache is not big enough to allocate minimal
+ number of key blocks in the key cache of the partition.
+ Decrease the the number of the partitions by 1 and start again.
+ 2. i > 0
+ There is not enough memory for one of the succeeding partitions.
+ Just skip this partition decreasing the number of partitions in
+ the key cache by one.
+ Do not change the value of mem_per_cache in both cases.
+ */
+ if (key_cache_inited)
+ {
+ my_free(partition, MYF(0));
+ partition= 0;
+ if(key_cache_inited)
+ memmove(partition_ptr, partition_ptr+1,
+ sizeof(partition_ptr)*(partitions-i-1));
+ }
+ if (!--partitions)
+ break;
+ }
+ else
+ {
+ /*
+ We come here when i == 0 && cnt == 0.
+ cnt == 0 => the memory allocator fails to allocate a block of
+ memory of the size mem_per_cache. Decrease the value of
+ mem_per_cache without changing the current number of partitions
+ and start again. Make sure that such a decrease may happen not
+ more than 5 times in total.
+ */
+ if (use_mem <= mem_decr)
+ break;
+ use_mem-= mem_decr;
}
+ i--;
+ mem_per_cache= use_mem/partitions;
+ continue;
+ }
+ else
+ {
+ blocks+= cnt;
+ *partition_ptr++= partition;
}
-
- blocks+= cnt;
- *partition_ptr++= partition;
}
keycache->partitions= partitions= partition_ptr-keycache->partition_array;
@@ -5859,7 +5896,7 @@ get_partitioned_key_cache_stat_value(PAR
ulonglong res= 0;
DBUG_ENTER("get_partitioned_key_cache_stat_value");
- if (var_no < NO_LONG_KEY_CACHE_STAT_VARIABLES)
+ if (var_no < NUM_LONG_KEY_CACHE_STAT_VARIABLES)
{
for (i = 0; i < partitions; i++)
{
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-04-03 20:19:35 +0000
+++ b/sql/sql_show.cc 2010-04-06 02:08:10 +0000
@@ -2265,7 +2265,7 @@ static void update_key_cache_stat_var(KE
case offsetof(KEY_CACHE, global_cache_read):
case offsetof(KEY_CACHE, global_cache_w_requests):
case offsetof(KEY_CACHE, global_cache_write):
- var_no= NO_LONG_KEY_CACHE_STAT_VARIABLES +
+ var_no= NUM_LONG_KEY_CACHE_STAT_VARIABLES +
(ofs-offsetof(KEY_CACHE, global_cache_w_requests))/
sizeof(ulonglong);
*(ulonglong *)((char *) key_cache + ofs)=
1
0

[Maria-developers] Rev 2773: MWL#43 CREATE TABLE options in file:///home/bell/maria/bzr/work-maria-5.2-createoptions5/
by sanja@askmonty.org 06 Apr '10
by sanja@askmonty.org 06 Apr '10
06 Apr '10
At file:///home/bell/maria/bzr/work-maria-5.2-createoptions5/
------------------------------------------------------------
revno: 2773
revision-id: sanja(a)askmonty.org-20100406000609-jl8415st523eq5jj
parent: sergii(a)pisem.net-20100405095031-bgjy005pcftkp6g1
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-createoptions5
timestamp: Tue 2010-04-06 03:06:09 +0300
message:
MWL#43 CREATE TABLE options
=== modified file 'Docs/sp-imp-spec.txt'
--- a/Docs/sp-imp-spec.txt 2004-03-23 11:04:40 +0000
+++ b/Docs/sp-imp-spec.txt 2010-04-06 00:06:09 +0000
@@ -1075,7 +1075,7 @@
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
- 'NOT_USED',
+ 'CREATE_OPTIONS_NOERR',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
@@ -1097,4 +1097,4 @@
) comment='Stored Procedures';
--
-
\ No newline at end of file
+
=== modified file 'include/my_base.h'
--- a/include/my_base.h 2010-02-10 19:06:24 +0000
+++ b/include/my_base.h 2010-04-06 00:06:09 +0000
@@ -314,6 +314,8 @@
#define HA_OPTION_RELIES_ON_SQL_LAYER 512
#define HA_OPTION_NULL_FIELDS 1024
#define HA_OPTION_PAGE_CHECKSUM 2048
+/* .frm has extra create options in linked-list format */
+#define HA_OPTION_TEXT_CREATE_OPTIONS (1L << 14)
#define HA_OPTION_TEMP_COMPRESS_RECORD (1L << 15) /* set by isamchk */
#define HA_OPTION_READ_ONLY_DATA (1L << 16) /* Set by isamchk */
#define HA_OPTION_NO_CHECKSUM (1L << 17)
=== modified file 'libmysqld/CMakeLists.txt'
--- a/libmysqld/CMakeLists.txt 2010-04-02 18:51:02 +0000
+++ b/libmysqld/CMakeLists.txt 2010-04-06 00:06:09 +0000
@@ -139,7 +139,8 @@
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
../sql/partition_info.cc ../sql/sql_connect.cc
- ../sql/scheduler.cc ../sql/event_parse_data.cc
+ ../sql/scheduler.cc ../sql/event_parse_data.cc
+ ../sql/create_options.cc
${GEN_SOURCES}
${LIB_SOURCES})
=== modified file 'libmysqld/Makefile.am'
--- a/libmysqld/Makefile.am 2010-03-29 15:13:53 +0000
+++ b/libmysqld/Makefile.am 2010-04-06 00:06:09 +0000
@@ -75,7 +75,7 @@
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
debug_sync.cc \
- sql_tablespace.cc \
+ sql_tablespace.cc create_options.cc \
rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc event_parse_data.cc opt_table_elimination.cc
=== added file 'mysql-test/r/create_options.result'
--- a/mysql-test/r/create_options.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/create_options.result 2010-04-06 00:06:09 +0000
@@ -0,0 +1,182 @@
+drop table if exists t1;
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='CREATE_OPTIONS_NOERR';
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+Warnings:
+Warning 1650 Unknown option 'fkey'
+Warning 1650 Unknown option 'dff'
+Warning 1650 Unknown option 'tkey1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey`='vvv',
+ KEY `akey` (`a`) `dff`='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v1'
+drop table t1;
+#reassiginig options in the same line
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1;
+Warnings:
+Warning 1650 Unknown option 'fkey'
+Warning 1650 Unknown option 'dff'
+Warning 1650 Unknown option 'tkey1'
+Warning 1650 Unknown option 'tkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey`='vvv',
+ KEY `akey` (`a`) `dff`='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v2' `tkey2`='2v1'
+#add option
+alter table t1 tkey4=4v1;
+Warnings:
+Warning 1650 Unknown option 'tkey4'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey`='vvv',
+ KEY `akey` (`a`) `dff`='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v2' `tkey2`='2v1' `tkey4`='4v1'
+#remove options
+alter table t1 tkey3=DEFAULT tkey4=DEFAULT;
+Warnings:
+Warning 1650 Unknown option 'tkey3'
+Warning 1650 Unknown option 'tkey4'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey`='vvv',
+ KEY `akey` (`a`) `dff`='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v2' `tkey2`='2v1' `tkey4`='4v1'
+drop table t1;
+create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1;
+Warnings:
+Warning 1650 Unknown option 'fkey1'
+Warning 1650 Unknown option 'kkey1'
+Warning 1650 Unknown option 'TKEY1'
+Warning 1650 Unknown option 'tkey2'
+Warning 1650 Unknown option 'tkey3'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v1',
+ KEY `akey` (`a`) `kkey1`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#change field with option with the same option
+alter table t1 change a a int `FKEY1`='v1';
+Warnings:
+Warning 1650 Unknown option 'FKEY1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `FKEY1`='v1',
+ KEY `akey` (`a`) `kkey1`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#change field with option with a different option
+alter table t1 change a a int fkey1=v2;
+Warnings:
+Warning 1650 Unknown option 'fkey1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ KEY `akey` (`a`) `kkey1`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#new column no options
+alter table t1 add column b int;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `b` int(11) DEFAULT NULL,
+ KEY `akey` (`a`) `kkey1`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#new key with options
+alter table t1 add key bkey (b) kkey2=v1;
+Warnings:
+Warning 1650 Unknown option 'kkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `b` int(11) DEFAULT NULL,
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `bkey` (`b`) `kkey2`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#new column with options
+alter table t1 add column c int fkey1=v1 fkey2=v2;
+Warnings:
+Warning 1650 Unknown option 'fkey1'
+Warning 1650 Unknown option 'fkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `bkey` (`b`) `kkey2`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#new key no options
+alter table t1 add key ckey (c);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `bkey` (`b`) `kkey2`='v1',
+ KEY `ckey` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#drop column
+alter table t1 drop b;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `ckey` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#add column with options after delete
+alter table t1 add column b int fkey2=v1;
+Warnings:
+Warning 1650 Unknown option 'fkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ `b` int(11) DEFAULT NULL `fkey2`='v1',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `ckey` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#add key
+alter table t1 add key bkey (b) kkey2=v2;
+Warnings:
+Warning 1650 Unknown option 'kkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ `b` int(11) DEFAULT NULL `fkey2`='v1',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `ckey` (`c`),
+ KEY `bkey` (`b`) `kkey2`='v2'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+drop table t1;
+create table t1 (a int) tkey1=100;
+Warnings:
+Warning 1650 Unknown option 'tkey1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=100
+drop table t1;
+#error on unknown option
+SET SQL_MODE='';
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+ERROR HY000: Unknown option 'fkey'
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/r/events_bugs.result'
--- a/mysql-test/r/events_bugs.result 2009-03-11 20:30:56 +0000
+++ b/mysql-test/r/events_bugs.result 2010-04-06 00:06:09 +0000
@@ -729,9 +729,8 @@
create event e1 on schedule every 1 day do select 1;
select @@sql_mode;
@@sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,CREATE_OPTIONS_NOERR,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
set @@sql_mode= @old_mode;
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.event where name = 'p' and sql_mode = @full_mode;
name
=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result 2010-03-15 11:51:23 +0000
+++ b/mysql-test/r/information_schema.result 2010-04-06 00:06:09 +0000
@@ -615,7 +615,7 @@
proc definer char(77)
proc created timestamp
proc modified timestamp
-proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
proc comment char(64)
proc character_set_client char(32)
proc collation_connection char(32)
=== modified file 'mysql-test/r/plugin_load.result'
--- a/mysql-test/r/plugin_load.result 2008-01-26 00:05:15 +0000
+++ b/mysql-test/r/plugin_load.result 2010-04-06 00:06:09 +0000
@@ -1,3 +1,57 @@
SELECT @@global.example_enum_var = 'e2';
@@global.example_enum_var = 'e2'
1
+#legal values
+CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example ULL=10000 STR='dskj' one_or_two='one' YESNO=0;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `complex`='c,f,f,f'
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0
+drop table t1;
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='CREATE_OPTIONS_NOERR';
+#illegal value fixed
+CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+Warnings:
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`='SSS'
+#alter table
+alter table t1 ULL=10000000;
+Warnings:
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`='SSS' `ULL`='10000000'
+alter table t1 change a a int complex='c,c,c';
+Warnings:
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `complex`='c,c,c'
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`='SSS' `ULL`='10000000'
+drop table t1;
+#illegal value error
+SET SQL_MODE='';
+CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+ERROR HY000: Incorrect value '10000000000000000000' for option 'ULL'
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/r/sp.result'
--- a/mysql-test/r/sp.result 2009-12-23 13:44:03 +0000
+++ b/mysql-test/r/sp.result 2010-04-06 00:06:09 +0000
@@ -6940,9 +6940,8 @@
call p();
select @@sql_mode;
@@sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,CREATE_OPTIONS_NOERR,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
set @@sql_mode= @old_mode;
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.proc where name = 'p' and sql_mode = @full_mode;
name
=== modified file 'mysql-test/r/system_mysql_db.result'
--- a/mysql-test/r/system_mysql_db.result 2010-03-29 15:13:53 +0000
+++ b/mysql-test/r/system_mysql_db.result 2010-04-06 00:06:09 +0000
@@ -202,7 +202,7 @@
`definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
@@ -227,7 +227,7 @@
`ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`originator` int(10) unsigned NOT NULL,
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2010-03-29 15:13:53 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2010-04-06 00:06:09 +0000
@@ -49,7 +49,7 @@
NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references
NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
+NULL mysql event sql_mode 15 NO set 488 1464 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references
NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references
@@ -124,7 +124,7 @@
NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references
NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references
-NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
+NULL mysql proc sql_mode 15 NO set 488 1464 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
@@ -330,7 +330,7 @@
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql event sql_mode set 488 1464 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -405,7 +405,7 @@
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql proc sql_mode set 488 1464 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result 2009-05-19 16:43:50 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result 2010-04-06 00:06:09 +0000
@@ -49,7 +49,7 @@
NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI
NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE')
NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64)
@@ -124,7 +124,7 @@
NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER')
NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')
-NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI
NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL
@@ -327,7 +327,7 @@
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -402,7 +402,7 @@
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
=== added file 'mysql-test/t/create_options.test'
--- a/mysql-test/t/create_options.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/create_options.test 2010-04-06 00:06:09 +0000
@@ -0,0 +1,68 @@
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='CREATE_OPTIONS_NOERR';
+
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+show create table t1;
+drop table t1;
+
+--echo #reassiginig options in the same line
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1;
+show create table t1;
+
+-- echo #add option
+alter table t1 tkey4=4v1;
+show create table t1;
+
+--echo #remove options
+alter table t1 tkey3=DEFAULT tkey4=DEFAULT;
+show create table t1;
+
+drop table t1;
+
+create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1;
+show create table t1;
+
+--echo #change field with option with the same option
+alter table t1 change a a int `FKEY1`='v1';
+show create table t1;
+--echo #change field with option with a different option
+alter table t1 change a a int fkey1=v2;
+show create table t1;
+--echo #new column no options
+alter table t1 add column b int;
+show create table t1;
+--echo #new key with options
+alter table t1 add key bkey (b) kkey2=v1;
+show create table t1;
+--echo #new column with options
+alter table t1 add column c int fkey1=v1 fkey2=v2;
+show create table t1;
+--echo #new key no options
+alter table t1 add key ckey (c);
+show create table t1;
+--echo #drop column
+alter table t1 drop b;
+show create table t1;
+--echo #add column with options after delete
+alter table t1 add column b int fkey2=v1;
+show create table t1;
+--echo #add key
+alter table t1 add key bkey (b) kkey2=v2;
+show create table t1;
+drop table t1;
+
+#numeric (unquoted) value
+create table t1 (a int) tkey1=100;
+show create table t1;
+drop table t1;
+
+--echo #error on unknown option
+SET SQL_MODE='';
+--error ER_UNKNOWN_OPTION
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/t/events_bugs.test'
--- a/mysql-test/t/events_bugs.test 2009-03-11 20:30:56 +0000
+++ b/mysql-test/t/events_bugs.test 2010-04-06 00:06:09 +0000
@@ -1204,7 +1204,6 @@
select @@sql_mode;
set @@sql_mode= @old_mode;
# Rename SQL modes that differ in name between the server and the table definition.
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.event where name = 'p' and sql_mode = @full_mode;
drop event e1;
=== modified file 'mysql-test/t/plugin_load.test'
--- a/mysql-test/t/plugin_load.test 2009-10-08 08:39:15 +0000
+++ b/mysql-test/t/plugin_load.test 2010-04-06 00:06:09 +0000
@@ -2,3 +2,30 @@
--source include/have_example_plugin.inc
SELECT @@global.example_enum_var = 'e2';
+
+--echo #legal values
+CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example ULL=10000 STR='dskj' one_or_two='one' YESNO=0;
+show create table t1;
+drop table t1;
+
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='CREATE_OPTIONS_NOERR';
+
+--echo #illegal value fixed
+CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+show create table t1;
+
+--echo #alter table
+alter table t1 ULL=10000000;
+show create table t1;
+alter table t1 change a a int complex='c,c,c';
+show create table t1;
+drop table t1;
+
+
+--echo #illegal value error
+SET SQL_MODE='';
+--error ER_BAD_OPTION_VALUE
+CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/t/sp.test'
--- a/mysql-test/t/sp.test 2009-12-23 13:44:03 +0000
+++ b/mysql-test/t/sp.test 2010-04-06 00:06:09 +0000
@@ -8210,7 +8210,6 @@
select @@sql_mode;
set @@sql_mode= @old_mode;
# Rename SQL modes that differ in name between the server and the table definition.
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.proc where name = 'p' and sql_mode = @full_mode;
drop procedure p;
=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql 2010-03-29 15:13:53 +0000
+++ b/scripts/mysql_system_tables.sql 2010-04-06 00:06:09 +0000
@@ -60,7 +60,7 @@
CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones';
-CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
+CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'CREATE_OPTIONS_NOERR', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
@@ -80,7 +80,7 @@
EXECUTE stmt;
DROP PREPARE stmt;
-CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
+CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;
=== modified file 'scripts/mysql_system_tables_fix.sql'
--- a/scripts/mysql_system_tables_fix.sql 2010-03-29 15:13:53 +0000
+++ b/scripts/mysql_system_tables_fix.sql 2010-04-06 00:06:09 +0000
@@ -368,7 +368,7 @@
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
- 'NOT_USED',
+ 'CREATE_OPTIONS_NOERR',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
@@ -482,14 +482,14 @@
ALTER TABLE event DROP PRIMARY KEY;
ALTER TABLE event ADD PRIMARY KEY(db, name);
# Add sql_mode column just in case.
-ALTER TABLE event ADD sql_mode set ('NOT_USED') AFTER on_completion;
+ALTER TABLE event ADD sql_mode set ('CREATE_OPTIONS_NOERR') AFTER on_completion;
# Update list of sql_mode values.
ALTER TABLE event MODIFY sql_mode
set('REAL_AS_FLOAT',
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
- 'NOT_USED',
+ 'CREATE_OPTIONS_NOERR',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2010-03-29 15:13:53 +0000
+++ b/sql/CMakeLists.txt 2010-04-06 00:06:09 +0000
@@ -77,6 +77,7 @@
rpl_rli.cc rpl_mi.cc sql_servers.cc
sql_connect.cc scheduler.cc
sql_profile.cc event_parse_data.cc opt_table_elimination.cc
+ create_options.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
${PROJECT_SOURCE_DIR}/include/mysqld_error.h
=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am 2010-03-29 15:13:53 +0000
+++ b/sql/Makefile.am 2010-04-06 00:06:09 +0000
@@ -78,7 +78,8 @@
sql_plugin.h authors.h event_parse_data.h \
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
- contributors.h sql_servers.h
+ contributors.h sql_servers.h \
+ create_options.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
@@ -124,7 +125,7 @@
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_servers.cc event_parse_data.cc \
- opt_table_elimination.cc
+ opt_table_elimination.cc create_options.cc
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c client_plugin.c
=== added file 'sql/create_options.cc'
--- a/sql/create_options.cc 1970-01-01 00:00:00 +0000
+++ b/sql/create_options.cc 2010-04-06 00:06:09 +0000
@@ -0,0 +1,679 @@
+/* Copyright (C) 2010 Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ Engine defined options of tables/fields/keys in CREATE/ALTER TABLE.
+*/
+
+#include "mysql_priv.h"
+#include <my_getopt.h>
+
+/* bits of first byte (type byte of frm imege) */
+#define FRM_TYPE_MASK 0x03
+#define FRM_QUATED_VALUE 0x80
+
+/**
+ Links this item to the given list end
+
+ @param start The list beginning or NULL
+ @param end The list last element or does not matter
+*/
+
+void engine_option_value::link(engine_option_value **start,
+ engine_option_value **end)
+{
+ DBUG_ENTER("engine_option_value::link");
+ DBUG_PRINT("enter", ("name: '%s' (%u) value: '%s' (%u)",
+ name.str, (uint) name.length,
+ value.str, (uint) value.length));
+ engine_option_value *opt;
+ /* check duplicates to avoid writing them to frm*/
+ for(opt= *start;
+ opt && (opt->deleted ||
+ my_strnncoll(system_charset_info,
+ (uchar *)name.str, name.length,
+ (uchar*)opt->name.str, opt->name.length));
+ opt= opt->next) {};
+ if (opt)
+ {
+ /* remove previous value */
+ opt->value.str= NULL;
+ opt->parsed= TRUE;
+ opt->deleted= TRUE;
+ }
+ /*
+ Add this option to the end of the list
+
+ @note: We add even if it is opt->value.str == NULL because it can be
+ ALTER TABLE to remove the option.
+ */
+ if (*start)
+ {
+ (*end)->next= this;
+ *end= this;
+ }
+ else
+ {
+ *start= *end= this;
+ }
+ DBUG_VOID_RETURN;
+}
+
+static bool report_wrong_value(THD *thd, const char *name, const char *val,
+ my_bool suppress_warning)
+{
+ if (!(thd->variables.sql_mode & MODE_CREATE_OPTIONS_NOERR))
+ {
+ my_error(ER_BAD_OPTION_VALUE, MYF(0), val, name);
+ return 1;
+ }
+
+ /*
+ We suppress errors to avoid double messages about the same value. It has
+ no sense to supress errors as they lead to execution abortion.
+ */
+ if (!suppress_warning)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_BAD_OPTION_VALUE,
+ ER(ER_BAD_OPTION_VALUE), val, name);
+ return 0;
+}
+
+static bool report_unknown_option(THD *thd, engine_option_value *val,
+ my_bool suppress_warning)
+{
+ DBUG_ENTER("report_unknown_option");
+ if (val->parsed)
+ {
+ DBUG_PRINT("info", ("parsed => exiting"));
+ DBUG_RETURN(FALSE);
+ }
+
+ if (!(thd->variables.sql_mode & MODE_CREATE_OPTIONS_NOERR))
+ {
+ my_error(ER_UNKNOWN_OPTION, MYF(0), val->name.str);
+ DBUG_RETURN(TRUE);
+ }
+
+ /*
+ We suppress errors to avoid double messages about the same value. It has
+ no sense to supress errors as they lead to execution abortion.
+ */
+ if (!suppress_warning)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_OPTION,
+ ER(ER_UNKNOWN_OPTION),
+ val->name.str);
+ DBUG_RETURN(FALSE);
+}
+
+static bool set_one_value(ha_create_table_option *opt,
+ THD *thd, LEX_STRING *value, void *base,
+ my_bool suppress_warning,
+ MEM_ROOT *root)
+{
+ DBUG_ENTER("set_one_value");
+ DBUG_PRINT("enter", ("opt: 0x%lx type: %u name '%s' value: '%s'",
+ (ulong) opt,
+ opt->type, opt->name,
+ (value->str ? value->str : "<DEFAULT>")));
+ switch (opt->type)
+ {
+ case HA_OPTION_TYPE_ULL:
+ {
+ ulonglong *val= (ulonglong*)((char*)base + opt->offset);
+ *val= opt->def_value;
+ if (!value->str)
+ {
+ DBUG_RETURN(0);
+ }
+
+ my_option optp= { opt->name, 1, 0, (uchar **)val, 0, 0, GET_ULL,
+ REQUIRED_ARG, opt->def_value, opt->min_value, opt->max_value,
+ 0, opt->block_size, 0};
+
+ ulonglong orig_val= strtoull(value->str, NULL, 10);
+ my_bool unused;
+ *val= orig_val;
+ *val= getopt_ull_limit_value(*val, &optp, &unused);
+ if (*val == orig_val)
+ DBUG_RETURN(0);
+
+ DBUG_RETURN(report_wrong_value(thd, opt->name, value->str,
+ suppress_warning));
+ }
+ case HA_OPTION_TYPE_STRING:
+ {
+ char **val= (char **)((char *)base + opt->offset);
+ *val= 0;
+ if (!value->str)
+ {
+ DBUG_RETURN(0);
+ }
+
+ if (!(*val= strmake_root(root, value->str, value->length)))
+ DBUG_RETURN(1);
+ DBUG_RETURN(0);
+ }
+ case HA_OPTION_TYPE_ENUM:
+ {
+ uint *val= (uint *)((char *)base + opt->offset), num;
+ *val= opt->def_value;
+
+ if (!value->str)
+ {
+ DBUG_RETURN(0);
+ }
+
+ const char *start= opt->values, *end;
+
+ num= 0;
+ while (*start)
+ {
+ for (end=start;
+ *end && *end != ',';
+ end+= my_mbcharlen(system_charset_info, *end)) /* no-op */;
+ if (!my_strnncoll(system_charset_info,
+ (uchar*)start, end-start,
+ (uchar*)value->str, value->length))
+ {
+ *val= num;
+ DBUG_RETURN(0);
+ }
+ if (*end) *end++;
+ start= end;
+ num++;
+ }
+
+ DBUG_RETURN(report_wrong_value(thd, opt->name, value->str,
+ suppress_warning));
+ }
+ case HA_OPTION_TYPE_BOOL:
+ {
+ bool *val= (bool *)((char *)base + opt->offset);
+ *val= opt->def_value;
+
+ if (!value->str)
+ {
+ DBUG_RETURN(0);
+ }
+
+ if (!my_strnncoll(system_charset_info,
+ (const uchar*)"NO", 2,
+ (uchar *)value->str, value->length) ||
+ !my_strnncoll(system_charset_info,
+ (const uchar*)"OFF", 3,
+ (uchar *)value->str, value->length) ||
+ !my_strnncoll(system_charset_info,
+ (const uchar*)"N", 1,
+ (uchar *)value->str, value->length))
+ {
+ *val= FALSE;
+ DBUG_RETURN(FALSE);
+ }
+
+ if (!my_strnncoll(system_charset_info,
+ (const uchar*)"YES", 3,
+ (uchar *)value->str, value->length) ||
+ !my_strnncoll(system_charset_info,
+ (const uchar*)"ON", 2,
+ (uchar *)value->str, value->length) ||
+ !my_strnncoll(system_charset_info,
+ (const uchar*)"N", 1,
+ (uchar *)value->str, value->length))
+ {
+ *val= TRUE;
+ DBUG_RETURN(FALSE);
+ }
+
+ /* numeric value */
+ if (value->str[0] < '0' || value->str[0] > '9')
+ DBUG_RETURN(report_wrong_value(thd, opt->name, value->str,
+ suppress_warning));
+
+ if (strtoull(value->str, NULL, 10))
+ *val= 1;
+ else
+ *val= 0;
+
+ DBUG_RETURN(FALSE);
+ }
+ }
+ DBUG_ASSERT(0);
+ my_error(ER_UNKNOWN_ERROR, MYF(0));
+ DBUG_RETURN(1);
+}
+
+static const size_t ha_option_type_sizeof[]=
+{ sizeof(ulonglong), sizeof(char *), sizeof(uint), sizeof(bool)};
+
+/**
+ Creates option structure and parses list of options in it
+
+ @param thd thread handler
+ @param option_struct where to store pointer on the option struct
+ @param option_list list of options given by user
+ @param rules list of option description by engine
+ @param suppress_warning second parse so we do not need warnings
+ @param root MEM_ROOT where allocate memory
+
+ @retval TRUE Error
+ @retval FALSE OK
+*/
+
+my_bool parse_option_list(THD* thd, void **option_struct,
+ engine_option_value *option_list,
+ ha_create_table_option *rules,
+ my_bool suppress_warning,
+ MEM_ROOT *root)
+{
+ ha_create_table_option *opt;
+ size_t option_struct_size= 0;
+ engine_option_value *val= option_list;
+ DBUG_ENTER("parse_option_list");
+ DBUG_PRINT("enter",
+ ("struct: 0x%lx list: 0x%lx rules: 0x%lx suppres %u root 0x%lx",
+ (ulong) *option_struct, (ulong)option_list, (ulong)rules,
+ (uint) suppress_warning, (ulong) root));
+
+ if (rules)
+ {
+ LEX_STRING default_val= {NULL, 0};
+ for (opt= rules; opt->name; opt++)
+ set_if_bigger(option_struct_size, opt->offset +
+ ha_option_type_sizeof[opt->type]);
+
+ *option_struct= alloc_root(root, option_struct_size);
+
+ /* set all values to default */
+ for (opt= rules; opt->name; opt++)
+ set_one_value(opt, thd, &default_val, *option_struct,
+ suppress_warning, root);
+ }
+
+ for (; val; val= val->next)
+ {
+ //if (!val->value.str) continue; // skip deleted
+ for (opt= rules; opt && opt->name; opt++)
+ {
+ if (my_strnncoll(system_charset_info,
+ (uchar*)opt->name, opt->name_length,
+ (uchar*)val->name.str, val->name.length))
+ continue;
+
+ if (set_one_value(opt, thd, &val->value,
+ *option_struct, suppress_warning, root))
+ DBUG_RETURN(TRUE);
+ val->parsed= true;
+ break;
+ }
+ if (report_unknown_option(thd, val, suppress_warning))
+ DBUG_RETURN(TRUE);
+ val->parsed= true;
+ }
+
+ DBUG_RETURN(FALSE);;
+}
+
+
+/**
+ Parses all table/fields/keys options
+
+ @param thd thread handler
+ @param file handler of the table
+ @parem share descriptor of the table
+
+ @retval TRUE Error
+ @retval FALSE OK
+*/
+
+my_bool parse_engine_table_options(THD *thd, handlerton *ht,
+ TABLE_SHARE *share)
+{
+ MEM_ROOT *root= &share->mem_root;
+ DBUG_ENTER("parse_engine_table_options");
+
+ if (parse_option_list(thd, &share->option_struct, share->option_list,
+ ht->table_opt_rules, TRUE, root))
+ DBUG_RETURN(TRUE);
+
+ for (Field **field= share->field; *field; field++)
+ {
+ if (parse_option_list(thd, &(*field)->option_struct, (*field)->option_list,
+ ht->field_opt_rules, TRUE, root))
+ DBUG_RETURN(TRUE);
+ }
+
+ for (uint index= 0; index < share->keys; index ++)
+ {
+ if (parse_option_list(thd, &share->key_info[index].option_struct,
+ share->key_info[index].option_list,
+ ht->key_opt_rules, TRUE, root))
+ DBUG_RETURN(TRUE);
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Returns representation length of key and value in the frm file
+*/
+
+uint engine_option_value::frm_length()
+{
+ /*
+ 2 bytes - value length
+ 1 byte - key length
+ */
+ return 2 + 1 + name.length + value.length;
+}
+
+
+/**
+ Returns length of representation of option list in the frm file
+
+ @param opt list of options;
+ @param overhead length of additional information per option
+
+ @returns length of image in frm
+*/
+
+static uint option_list_frm_length(engine_option_value *opt, uint overhead)
+{
+ uint res= 0;
+
+ for (; opt; opt= opt->next)
+ if (opt->value.str)
+ res+= opt->frm_length() + overhead;
+
+ return res;
+}
+
+
+/**
+ Calculates length of options image in the .frm
+
+ @param table_option_list list of table options
+ @param create_fields field descriptors list
+ @param keys number of keys
+ @param key_info array of key descriptors
+
+ @returns length of image in frm
+*/
+
+uint engine_table_options_frm_length(engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info)
+{
+ List_iterator<Create_field> it(create_fields);
+ Create_field *field;
+ uint res, index;
+ DBUG_ENTER("engine_table_options_frm_length");
+
+ /* 1 byte - record type */
+ res= option_list_frm_length(table_option_list, 1);
+
+ while ((field= it++))
+ {
+ /*
+ 1 byte - record type
+ 2 bytes - field number
+ */
+ res+= option_list_frm_length(field->option_list, 1 + 2);
+ }
+
+ for (index= 0; index < keys; index++, key_info++)
+ {
+
+ /*
+ 1 byte - record type
+ 2 bytes - key number
+ */
+ res+= option_list_frm_length(key_info->option_list, 1 + 2);
+ }
+ DBUG_RETURN(res);
+}
+
+
+/**
+ Writes image of the key and value to the frm image buffer
+
+ @param buff pointer to the buffer free space beginning
+
+ @returns pointer to byte after last recorded in the buffer
+*/
+
+uchar *engine_option_value::frm_image(uchar *buff)
+{
+ buff[0]= name.length;
+ buff++;
+ memcpy(buff, name.str, name.length);
+ buff+= name.length;
+ int2store(buff, value.length);
+ buff+= 2;
+ memcpy(buff, (const uchar *) value.str, value.length);
+ buff+= value.length;
+ return buff;
+}
+
+/**
+ Writes image of the key and value to the frm image buffer
+
+ @param buff pointer to the buffer free space beginning
+ @param opt list of options;
+ @param type option type (CREATE_OPTION_*)
+ @param index for keys and fields index of them
+
+ @returns pointer to byte after last recorded in the buffer
+*/
+static uchar *option_list_frm_image(uchar *buff,
+ engine_option_value *opt,
+ CREATE_OPTION_TYPES type,
+ uint index)
+{
+ for (; opt; opt= opt->next)
+ {
+ /* skip deleted options */
+ if (opt->value.str)
+ {
+ *(buff++)= (type | (opt->quoted_value ? FRM_QUATED_VALUE : 0));
+ if (type != CREATE_OPTION_TABLE)
+ {
+ int2store(buff, index);
+ buff+= 2;
+ }
+ buff= opt->frm_image(buff);
+ }
+ }
+
+ return buff;
+}
+
+
+/**
+ Writes options image in the .frm buffer
+
+ @param buff pointer to the buffer
+ @param table_option_list list of table options
+ @param create_fields field descriptors list
+ @param keys number of keys
+ @param key_info array of key descriptors
+
+ @returns pointer to byte after last recorded in the buffer
+*/
+
+uchar *engine_table_options_frm_image(uchar *buff,
+ engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info)
+{
+ List_iterator<Create_field> it(create_fields);
+ Create_field *field;
+ uint index;
+ DBUG_ENTER("engine_table_options_frm_image");
+
+ buff= option_list_frm_image(buff, table_option_list, CREATE_OPTION_TABLE, 0);
+
+ for (index= 0; (field= it++); index++)
+ buff= option_list_frm_image(buff, field->option_list,
+ CREATE_OPTION_FIELD, index);
+
+ for (index= 0; index < keys; index++, key_info++)
+ buff= option_list_frm_image(buff, key_info->option_list,
+ CREATE_OPTION_KEY, index);
+ DBUG_RETURN(buff);
+}
+
+/**
+ Reads name and value from buffer, then link it in the list
+
+ @param buff the buffer to read from
+ @param start The list beginning or NULL
+ @param end The list last element or does not matter
+ @param root MEM_ROOT for allocating
+
+ @returns pointer to byte after last recorded in the buffer
+*/
+uchar *engine_option_value::frm_read(const uchar *buff,
+ engine_option_value **start,
+ engine_option_value **end,
+ MEM_ROOT *root)
+{
+ name.length= buff[0];
+ buff++;
+ if (!(name.str= strmake_root(root, (const char*)buff,
+ name.length)))
+ return NULL;
+ buff+= name.length;
+ value.length= uint2korr(buff);
+ buff+= 2;
+ if (!(value.str= strmake_root(root, (const char*)buff,
+ value.length)))
+ return NULL;
+ buff+= value.length;
+ link(start, end);
+ return (uchar *)buff;
+}
+
+
+/**
+ Reads options from this buffer
+
+ @param buff the buffer to read from
+ @param length buffer length
+ @param share table descriptor
+ @param root MEM_ROOT for allocating
+
+ @retval TRUE Error
+ @retval FALSE OK
+*/
+
+my_bool engine_table_options_frm_read(const uchar *buff,
+ uint length,
+ TABLE_SHARE *share)
+{
+ const uchar *buff_end= buff + length;
+ engine_option_value *tbl_end, **fld_end, **key_end;
+ MEM_ROOT *root= &share->mem_root;
+ DBUG_ENTER("engine_table_options_frm_read");
+
+ /* temporary list end pointers to construct lists */
+ tbl_end= NULL;
+ if (!(fld_end= (engine_option_value **)
+ alloc_root(root, sizeof(engine_option_value *) * share->fields)) ||
+ !(key_end= (engine_option_value **)
+ alloc_root(root, sizeof(engine_option_value *) * share->keys)))
+ {
+ DBUG_RETURN(TRUE);
+ }
+
+ while (buff < buff_end)
+ {
+ engine_option_value *option;
+ CREATE_OPTION_TYPES type;
+ uint index= 0;
+
+ if (!(option= new (root) engine_option_value()))
+ DBUG_RETURN(TRUE);
+
+ DBUG_ASSERT(buff + 4 <= buff_end);
+
+ type= (CREATE_OPTION_TYPES)(FRM_TYPE_MASK & buff[0]);
+ option->set_quoted_value(FRM_QUATED_VALUE & buff[0]);
+ buff++;
+ switch (type) {
+ case CREATE_OPTION_FIELD:
+ index= uint2korr(buff);
+ buff+= 2;
+ DBUG_ASSERT(index < share->fields);
+ if (!(buff= option->frm_read(buff,
+ &share->field[index]->option_list,
+ fld_end + index,
+ root)))
+ DBUG_RETURN(TRUE);
+ break;
+ case CREATE_OPTION_KEY:
+ index= uint2korr(buff);
+ buff+= 2;
+ DBUG_ASSERT(index < share->keys);
+ if (!(buff= option->frm_read(buff,
+ &share->key_info[index].option_list,
+ key_end + index,
+ root)))
+ DBUG_RETURN(TRUE);
+ break;
+ case CREATE_OPTION_TABLE:
+ if (!(buff= option->frm_read(buff,
+ &share->option_list,
+ &tbl_end,
+ root)))
+ DBUG_RETURN(TRUE);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+ DBUG_PRINT("info", ("type: %u index: %u key: '%s' value: '%s'",
+ (uint) type, (uint) index,
+ option->name.str, option->value.str));
+ }
+ DBUG_RETURN(FALSE);
+}
+
+/**
+ Adds (merges) chages to source
+*/
+
+engine_option_value *merge_engine_table_options(engine_option_value *source,
+ engine_option_value *changes,
+ MEM_ROOT *root)
+{
+ engine_option_value *end, *opt;
+ DBUG_ENTER("merge_engine_table_options");
+
+ /* find last element */
+ if (source)
+ for (end= source; end->next; end= end->next){};
+
+ for (opt= changes; opt; opt= opt->next)
+ {
+ new (root) engine_option_value(opt->name,
+ opt->value.str, opt->value.length,
+ &source, &end);
+ }
+ DBUG_RETURN(source);
+}
=== added file 'sql/create_options.h'
--- a/sql/create_options.h 1970-01-01 00:00:00 +0000
+++ b/sql/create_options.h 2010-04-06 00:06:09 +0000
@@ -0,0 +1,139 @@
+/* Copyright (C) 2010 Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ Engine defined options of tables/fields/keys in CREATE/ALTER TABLE.
+*/
+
+#ifndef SQL_CREATE_OPTIONS_INCLUDED
+#define SQL_CREATE_OPTIONS_INCLUDED
+
+class Item;
+#include "handler.h"
+
+/* types of cretate options records on disk, also it is length of extra data */
+typedef enum enum_create_options_type {
+ CREATE_OPTION_TABLE= 0,
+ CREATE_OPTION_KEY= 1,
+ CREATE_OPTION_FIELD= 2
+} CREATE_OPTION_TYPES;
+
+class engine_option_value: public Sql_alloc
+{
+ public:
+ LEX_STRING name;
+ LEX_STRING value;
+ engine_option_value *next;
+ bool parsed;
+ bool deleted;
+ bool quoted_value;
+ engine_option_value() :
+ next(NULL), parsed(false)
+ {}
+ engine_option_value(const char *name_arg, size_t name_len_arg,
+ const char *value_arg, size_t value_len_arg,
+ engine_option_value **start, engine_option_value **end) :
+ next(NULL), parsed(false), deleted(false), quoted_value(true)
+ {
+ name.str= const_cast<char*>(name_arg);
+ name.length= name_len_arg;
+ value.str= const_cast<char*>(value_arg);
+ value.length= value_len_arg;
+ link(start, end);
+ }
+ engine_option_value(LEX_STRING &name_arg,
+ const char *value_arg, size_t value_len_arg,
+ engine_option_value **start, engine_option_value **end) :
+ name(name_arg), next(NULL), parsed(false), deleted(false),
+ quoted_value(true)
+ {
+ value.str= const_cast<char*>(value_arg);
+ value.length= value_len_arg;
+ link(start, end);
+ }
+ engine_option_value(const char *name_arg, size_t name_len_arg,
+ ulonglong value_arg,
+ engine_option_value **start, engine_option_value **end,
+ MEM_ROOT *root) :
+ next(NULL), parsed(false), deleted(false), quoted_value(false)
+ {
+ name.str= const_cast<char*>(name_arg);
+ name.length= name_len_arg;
+ if ((value.str= (char *)alloc_root(root, 22)))
+ {
+ value.length= longlong2str(value_arg, value.str, 10) - value.str;
+ link(start, end);
+ }
+ }
+ engine_option_value(LEX_STRING &name_arg,
+ ulonglong value_arg,
+ engine_option_value **start, engine_option_value **end,
+ MEM_ROOT *root) :
+ name(name_arg), next(NULL), parsed(false), deleted(false),
+ quoted_value(false)
+ {
+ if ((value.str= (char *)alloc_root(root, 22)))
+ {
+ value.length= longlong2str(value_arg, value.str, 10) - value.str;
+ link(start, end);
+ }
+ }
+ engine_option_value(LEX_STRING &name_arg,
+ ha_choice value_arg,
+ engine_option_value **start, engine_option_value **end) :
+ name(name_arg), next(NULL), parsed(false), deleted(false),
+ quoted_value(false)
+ {
+ value.length= 1;
+ switch (value_arg) {
+ case HA_CHOICE_UNDEF:
+ value.str= NULL;
+ value.length= 0;
+ break;
+ case HA_CHOICE_NO:
+ value.str= (char*)"0";
+ break;
+ case HA_CHOICE_YES:
+ value.str= (char*)"1";
+ break;
+ }
+ }
+ void set_quoted_value(bool quoted) {quoted_value= quoted;}
+ void link(engine_option_value **start, engine_option_value **end);
+ uint frm_length();
+ uchar *frm_image(uchar *buff);
+ uchar *frm_read(const uchar *buff,
+ engine_option_value **start, engine_option_value **end,
+ MEM_ROOT *root);
+};
+
+class handler;
+class THD;
+my_bool parse_engine_table_options(THD *thd, handlerton *ht,
+ TABLE_SHARE *share);
+my_bool parse_option_list(THD* thd, void **option_struct,
+ engine_option_value *option_list,
+ ha_create_table_option *rules,
+ my_bool suppress_warning,
+ MEM_ROOT *root);
+my_bool engine_table_options_frm_read(const uchar *buff,
+ uint length,
+ TABLE_SHARE *share);
+engine_option_value *merge_engine_table_options(engine_option_value *source,
+ engine_option_value *changes,
+ MEM_ROOT *root);
+#endif
=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc 2010-03-15 11:51:23 +0000
+++ b/sql/event_db_repository.cc 2010-04-06 00:06:09 +0000
@@ -105,7 +105,8 @@
{
{ C_STRING_WITH_LEN("sql_mode") },
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
- "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
+ "'IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY',"
+ "'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2010-03-17 02:32:31 +0000
+++ b/sql/field.cc 2010-04-06 00:06:09 +0000
@@ -1306,14 +1306,13 @@
Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg)
- :ptr(ptr_arg), null_ptr(null_ptr_arg),
- table(0), orig_table(0), table_name(0),
- field_name(field_name_arg),
- key_start(0), part_of_key(0), part_of_key_not_clustered(0),
- part_of_sortkey(0), unireg_check(unireg_check_arg),
- field_length(length_arg), null_bit(null_bit_arg),
- is_created_from_null_item(FALSE),
- vcol_info(0), stored_in_db(TRUE)
+ :ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0),
+ table_name(0), field_name(field_name_arg), option_list(0),
+ option_struct(0), key_start(0), part_of_key(0),
+ part_of_key_not_clustered(0), part_of_sortkey(0),
+ unireg_check(unireg_check_arg), field_length(length_arg),
+ null_bit(null_bit_arg), is_created_from_null_item(FALSE), vcol_info(0),
+ stored_in_db(TRUE)
{
flags=null_ptr ? 0: NOT_NULL_FLAG;
comment.str= (char*) "";
@@ -9567,7 +9566,8 @@
Item *fld_on_update_value, LEX_STRING *fld_comment,
char *fld_change, List<String> *fld_interval_list,
CHARSET_INFO *fld_charset, uint fld_geom_type,
- Virtual_column_info *fld_vcol_info)
+ Virtual_column_info *fld_vcol_info,
+ engine_option_value *create_opt)
{
uint sign_len, allowed_type_modifier= 0;
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
@@ -9578,6 +9578,7 @@
field_name= fld_name;
def= fld_default_value;
flags= fld_type_modifier;
+ option_list= create_opt;
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
Field::NEXT_NUMBER : Field::NONE);
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
@@ -10217,6 +10218,8 @@
decimals= old_field->decimals();
vcol_info= old_field->vcol_info;
stored_in_db= old_field->stored_in_db;
+ option_list= old_field->option_list;
+ option_struct= old_field->option_struct;
/* Fix if the original table had 4 byte pointer blobs */
if (flags & BLOB_FLAG)
@@ -10291,6 +10294,19 @@
/**
+ Makes a clone of this object for ALTER/CREATE TABLE
+
+ @param mem_root MEM_ROOT where to clone the field
+*/
+
+Create_field *Create_field::clone(MEM_ROOT *mem_root) const
+{
+ Create_field *res= new (mem_root) Create_field(*this);
+ return res;
+}
+
+
+/**
maximum possible display length for blob.
@return
=== modified file 'sql/field.h'
--- a/sql/field.h 2010-03-15 11:51:23 +0000
+++ b/sql/field.h 2010-04-06 00:06:09 +0000
@@ -137,6 +137,9 @@
struct st_table *table; // Pointer for table
struct st_table *orig_table; // Pointer to original table
const char **table_name, *field_name;
+ /** reference to the list of options or NULL */
+ engine_option_value *option_list;
+ void *option_struct; /* structure with parsed options */
LEX_STRING comment;
/* Field is part of the following keys */
key_map key_start, part_of_key, part_of_key_not_clustered;
@@ -2145,6 +2148,9 @@
CHARSET_INFO *charset;
Field::geometry_type geom_type;
Field *field; // For alter table
+ engine_option_value *option_list;
+ /** structure with parsed options (for comparing fields in ALTER TABLE) */
+ void *option_struct;
uint8 row,col,sc_length,interval_id; // For rea_create_table
uint offset,pack_flag;
@@ -2162,11 +2168,11 @@
*/
bool stored_in_db;
- Create_field() :after(0) {}
+ Create_field() :after(0), option_list(NULL), option_struct(NULL)
+ {}
Create_field(Field *field, Field *orig_field);
/* Used to make a clone of this object for ALTER/CREATE TABLE */
- Create_field *clone(MEM_ROOT *mem_root) const
- { return new (mem_root) Create_field(*this); }
+ Create_field *clone(MEM_ROOT *mem_root) const;
void create_length_to_internal_length(void);
/* Init for a tmp table field. To be extended if need be. */
@@ -2178,8 +2184,8 @@
char *decimals, uint type_modifier, Item *default_value,
Item *on_update_value, LEX_STRING *comment, char *change,
List<String> *interval_list, CHARSET_INFO *cs,
- uint uint_geom_type,
- Virtual_column_info *vcol_info);
+ uint uint_geom_type, Virtual_column_info *vcol_info,
+ engine_option_value *option_list);
bool field_flags_are_binary()
{
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2010-04-01 14:34:51 +0000
+++ b/sql/ha_partition.cc 2010-04-06 00:06:09 +0000
@@ -1218,7 +1218,9 @@
DBUG_ENTER("prepare_new_partition");
if ((error= set_up_table_before_create(tbl, part_name, create_info,
- 0, p_elem)))
+ 0, p_elem)) ||
+ parse_engine_table_options(ha_thd(), file->ht,
+ file->table_share))
goto error_create;
if ((error= file->ha_create(part_name, tbl, create_info)))
{
@@ -1869,6 +1871,8 @@
{
if ((error= set_up_table_before_create(table_arg, from_buff,
create_info, i, NULL)) ||
+ parse_engine_table_options(ha_thd(), (*file)->ht,
+ (*file)->table_share) ||
((error= (*file)->ha_create(from_buff, table_arg, create_info))))
goto create_error;
}
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-04-01 09:04:26 +0000
+++ b/sql/handler.cc 2010-04-06 00:06:09 +0000
@@ -3719,7 +3719,12 @@
name= get_canonical_filename(table.file, share.path.str, name_buff);
+ if (parse_engine_table_options(thd, table.file->ht, &share))
+ goto err;
+
error= table.file->ha_create(name, &table, create_info);
+
+
VOID(closefrm(&table, 0));
if (error)
{
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2010-03-25 13:33:39 +0000
+++ b/sql/handler.h 2010-04-06 00:06:09 +0000
@@ -16,6 +16,9 @@
/* Definitions for parameters to do with handler-routines */
+#ifndef SQL_HANDLER_INCLUDED
+#define SQL_HANDLER_INCLUDED
+
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
@@ -23,6 +26,7 @@
#include <my_handler.h>
#include <ft_global.h>
#include <keycache.h>
+#include "create_options.h"
#ifndef NO_HASH
#define NO_HASH /* Not yet implemented */
@@ -516,6 +520,7 @@
struct st_table;
typedef struct st_table TABLE;
typedef struct st_table_share TABLE_SHARE;
+class engine_option;
struct st_foreign_key_info;
typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len,
@@ -549,6 +554,65 @@
enum log_status status;
};
+enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */
+ HA_OPTION_TYPE_STRING, /* char * */
+ HA_OPTION_TYPE_ENUM, /* uint */
+ HA_OPTION_TYPE_BOOL}; /* bool */
+
+#define HA_xOPTION_ULL(name, struc, field, def, min, max, blk_siz) \
+ { HA_OPTION_TYPE_ULL, name, sizeof(name)-1, \
+ offsetof(struc, field), def, min, max, blk_siz, 0 }
+#define HA_xOPTION_STRING(name, struc, field) \
+ { HA_OPTION_TYPE_STRING, name, sizeof(name)-1, \
+ offsetof(struc, field), 0, 0, 0, 0, 0 }
+#define HA_xOPTION_ENUM(name, struc, field, values, def) \
+ { HA_OPTION_TYPE_ENUM, name, sizeof(name)-1, \
+ offsetof(struc, field), def, 0, \
+ sizeof(values)-1, 0, values }
+#define HA_xOPTION_BOOL(name, struc, field, def) \
+ { HA_OPTION_TYPE_BOOL, name, sizeof(name)-1, \
+ offsetof(struc, field), def, 0, 1, 0, 0 }
+#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0 }
+
+#define HA_TOPTION_ULL(name, field, def, min, max, blk_siz) \
+ HA_xOPTION_ULL(name, ha_table_option_struct, field, def, min, max, blk_siz)
+#define HA_TOPTION_STRING(name, field) \
+ HA_xOPTION_STRING(name, ha_table_option_struct, field)
+#define HA_TOPTION_ENUM(name, field, values, def) \
+ HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def)
+#define HA_TOPTION_BOOL(name, field, def) \
+ HA_xOPTION_BOOL(name, ha_table_option_struct, field, def)
+#define HA_TOPTION_END HA_xOPTION_END
+
+#define HA_FOPTION_ULL(name, field, def, min, max, blk_siz) \
+ HA_xOPTION_ULL(name, ha_field_option_struct, field, def, min, max, blk_siz)
+#define HA_FOPTION_STRING(name, field) \
+ HA_xOPTION_STRING(name, ha_field_option_struct, field)
+#define HA_FOPTION_ENUM(name, field, values, def) \
+ HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def)
+#define HA_FOPTION_BOOL(name, field, def) \
+ HA_xOPTION_BOOL(name, ha_field_option_struct, field, def)
+#define HA_FOPTION_END HA_xOPTION_END
+
+#define HA_KOPTION_ULL(name, field, def, min, max, blk_siz) \
+ HA_xOPTION_ULL(name, ha_key_option_struct, field, def, min, max, blk_siz)
+#define HA_KOPTION_STRING(name, field) \
+ HA_xOPTION_STRING(name, ha_key_option_struct, field)
+#define HA_KOPTION_ENUM(name, field, values, def) \
+ HA_xOPTION_ENUM(name, ha_key_option_struct, field, values, def)
+#define HA_KOPTION_BOOL(name, field, values, def) \
+ HA_xOPTION_BOOL(name, ha_key_option_struct, field, values, def)
+#define HA_KOPTION_END HA_xOPTION_END
+
+typedef struct st_ha_create_table_option {
+ enum ha_option_type type;
+ const char *name;
+ size_t name_length;
+ ptrdiff_t offset;
+ ulonglong def_value;
+ ulonglong min_value, max_value, block_size;
+ const char *values;
+} ha_create_table_option;
enum handler_iterator_type
{
@@ -721,7 +785,11 @@
int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
const char *name);
uint32 license; /* Flag for Engine License */
- void *data; /* Location for engines to keep personal structures */
+ /* CREATE OPTIONS rules for parameter parsing */
+ ha_create_table_option *table_opt_rules,
+ *field_opt_rules,
+ *key_opt_rules;
+
};
@@ -950,6 +1018,14 @@
bool varchar; /* 1 if table has a VARCHAR */
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
enum ha_choice page_checksum; /* If we have page_checksums */
+ engine_option_value *option_list; /* list of table create options */
+ /** structure with parsed options (for comparing fields in ALTER TABLE) */
+ void *option_struct;
+ /* following 4 fields assigned only for check_if_incompatible_data() */
+ void *old_option_struct;
+ void **old_new_fileds_option_struct[2];
+ void **old_new_keys_option_struct[2];
+ uint fields, keys;
} HA_CREATE_INFO;
@@ -2254,3 +2330,5 @@
#define ha_binlog_wait(a) do {} while (0)
#define ha_binlog_end(a) do {} while (0)
#endif
+
+#endif
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2010-03-15 11:51:23 +0000
+++ b/sql/log_event.h 2010-04-06 00:06:09 +0000
@@ -1371,7 +1371,7 @@
MODE_PIPES_AS_CONCAT==0x2
MODE_ANSI_QUOTES==0x4
MODE_IGNORE_SPACE==0x8
- MODE_NOT_USED==0x10
+ MODE_CREATE_OPTIONS_NOERR==0x10
MODE_ONLY_FULL_GROUP_BY==0x20
MODE_NO_UNSIGNED_SUBTRACTION==0x40
MODE_NO_DIR_IN_CREATE==0x80
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2010-03-29 15:13:53 +0000
+++ b/sql/mysql_priv.h 2010-04-06 00:06:09 +0000
@@ -54,7 +54,6 @@
#include "sql_plugin.h"
#include "scheduler.h"
#include "log_slow.h"
-
class Parser_state;
/**
@@ -520,7 +519,7 @@
#define MODE_PIPES_AS_CONCAT 2
#define MODE_ANSI_QUOTES 4
#define MODE_IGNORE_SPACE 8
-#define MODE_NOT_USED 16
+#define MODE_CREATE_OPTIONS_NOERR 16
#define MODE_ONLY_FULL_GROUP_BY 32
#define MODE_NO_UNSIGNED_SUBTRACTION 64
#define MODE_NO_DIR_IN_CREATE 128
@@ -783,6 +782,7 @@
ulonglong *engine_data);
#include "sql_string.h"
#include "sql_list.h"
+#include "create_options.h"
#include "sql_map.h"
#include "my_decimal.h"
#include "handler.h"
@@ -1508,7 +1508,8 @@
char *change, List<String> *interval_list,
CHARSET_INFO *cs,
uint uint_geom_type,
- Virtual_column_info *vcol_info);
+ Virtual_column_info *vcol_info,
+ engine_option_value *create_options);
Create_field * new_create_field(THD *thd, char *field_name, enum_field_types type,
char *length, char *decimals,
uint type_modifier,
@@ -2625,4 +2626,14 @@
#endif /* MYSQL_CLIENT */
+/* Define to force use of my_malloc() if the allocated memory block is big */
+
+#ifndef HAVE_ALLOCA
+#define my_safe_alloca(size, min_length) my_alloca(size)
+#define my_safe_afree(ptr, size, min_length) my_afree(ptr)
+#else
+#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(0)))
+#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0))
+#endif
+
#endif /* MYSQL_PRIV_H */
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-04-02 09:20:09 +0000
+++ b/sql/mysqld.cc 2010-04-06 00:06:09 +0000
@@ -244,7 +244,7 @@
static const char *sql_mode_names[]=
{
"REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
- "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
+ "CREATE_OPTIONS_NOERR", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
"NO_DIR_IN_CREATE",
"POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
"NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
@@ -264,7 +264,7 @@
/*PIPES_AS_CONCAT*/ 15,
/*ANSI_QUOTES*/ 11,
/*IGNORE_SPACE*/ 12,
- /*?*/ 1,
+ /*CREATE_OPTIONS_NOERR*/ 20,
/*ONLY_FULL_GROUP_BY*/ 18,
/*NO_UNSIGNED_SUBTRACTION*/ 23,
/*NO_DIR_IN_CREATE*/ 16,
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2010-03-15 11:51:23 +0000
+++ b/sql/share/errmsg.txt 2010-04-06 00:06:09 +0000
@@ -6240,3 +6240,8 @@
ER_DEBUG_SYNC_HIT_LIMIT
eng "debug sync point hit limit reached"
ger "Debug Sync Point Hit Limit erreicht"
+
+ER_UNKNOWN_OPTION
+ eng "Unknown option '%-.64s'"
+ER_BAD_OPTION_VALUE
+ eng "Incorrect value '%-.64s' for option '%-.64s'"
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sp.cc 2010-04-06 00:06:09 +0000
@@ -147,7 +147,8 @@
{
{ C_STRING_WITH_LEN("sql_mode") },
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
- "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
+ "'IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY',"
+ "'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-04-01 09:04:26 +0000
+++ b/sql/sp_head.cc 2010-04-06 00:06:09 +0000
@@ -2218,7 +2218,7 @@
lex->charset ? lex->charset :
thd->variables.collation_database,
lex->uint_geom_type,
- lex->vcol_info))
+ lex->vcol_info, NULL))
return TRUE;
if (field_def->interval_list.elements)
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-04-02 18:51:02 +0000
+++ b/sql/sql_class.cc 2010-04-06 00:06:09 +0000
@@ -106,6 +106,7 @@
key_create_info(rhs.key_create_info),
columns(rhs.columns, mem_root),
name(rhs.name),
+ option_list(rhs.option_list),
generated(rhs.generated)
{
list_copy_and_replace_each_value(columns, mem_root);
@@ -775,6 +776,7 @@
void THD::push_internal_handler(Internal_error_handler *handler)
{
+ DBUG_ENTER("THD::push_internal_handler");
if (m_internal_handler)
{
handler->m_prev_internal_handler= m_internal_handler;
@@ -784,6 +786,7 @@
{
m_internal_handler= handler;
}
+ DBUG_VOID_RETURN;
}
@@ -803,8 +806,10 @@
void THD::pop_internal_handler()
{
+ DBUG_ENTER("THD::pop_internal_handler");
DBUG_ASSERT(m_internal_handler != NULL);
m_internal_handler= m_internal_handler->m_prev_internal_handler;
+ DBUG_VOID_RETURN;
}
extern "C"
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-04-01 09:04:26 +0000
+++ b/sql/sql_class.h 2010-04-06 00:06:09 +0000
@@ -205,13 +205,15 @@
KEY_CREATE_INFO key_create_info;
List<Key_part_spec> columns;
const char *name;
+ engine_option_value *option_list;
bool generated;
Key(enum Keytype type_par, const char *name_arg,
KEY_CREATE_INFO *key_info_arg,
- bool generated_arg, List<Key_part_spec> &cols)
+ bool generated_arg, List<Key_part_spec> &cols,
+ engine_option_value *create_opt)
:type(type_par), key_create_info(*key_info_arg), columns(cols),
- name(name_arg), generated(generated_arg)
+ name(name_arg), option_list(create_opt), generated(generated_arg)
{}
Key(const Key &rhs, MEM_ROOT *mem_root);
virtual ~Key() {}
@@ -240,7 +242,7 @@
Foreign_key(const char *name_arg, List<Key_part_spec> &cols,
Table_ident *table, List<Key_part_spec> &ref_cols,
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
- :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols),
+ :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL),
ref_table(table), ref_columns(ref_cols),
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
match_opt(match_opt_arg)
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_insert.cc 2010-04-06 00:06:09 +0000
@@ -72,15 +72,6 @@
#endif
static bool check_view_insertability(THD *thd, TABLE_LIST *view);
-/* Define to force use of my_malloc() if the allocated memory block is big */
-
-#ifndef HAVE_ALLOCA
-#define my_safe_alloca(size, min_length) my_alloca(size)
-#define my_safe_afree(ptr, size, min_length) my_afree(ptr)
-#else
-#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(0)))
-#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0))
-#endif
/*
Check that insert/update fields are from the same single table of a view.
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2010-03-29 15:13:53 +0000
+++ b/sql/sql_lex.h 2010-04-06 00:06:09 +0000
@@ -1749,6 +1749,11 @@
const char *stmt_definition_end;
/**
+ Collects create options for Field and KEY
+ */
+ engine_option_value *option_list, *option_list_last;
+
+ /**
During name resolution search only in the table list given by
Name_resolution_context::first_name_resolution_table and
Name_resolution_context::last_name_resolution_table
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_parse.cc 2010-04-06 00:06:09 +0000
@@ -6086,7 +6086,8 @@
char *change,
List<String> *interval_list, CHARSET_INFO *cs,
uint uint_geom_type,
- Virtual_column_info *vcol_info)
+ Virtual_column_info *vcol_info,
+ engine_option_value *create_options)
{
register Create_field *new_field;
LEX *lex= thd->lex;
@@ -6104,7 +6105,7 @@
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
key= new Key(Key::PRIMARY, NullS,
&default_key_create_info,
- 0, lex->col_list);
+ 0, lex->col_list, NULL);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty();
}
@@ -6114,7 +6115,7 @@
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
key= new Key(Key::UNIQUE, NullS,
&default_key_create_info, 0,
- lex->col_list);
+ lex->col_list, NULL);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty();
}
@@ -6172,7 +6173,8 @@
if (!(new_field= new Create_field()) ||
new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
default_value, on_update_value, comment, change,
- interval_list, cs, uint_geom_type, vcol_info))
+ interval_list, cs, uint_geom_type, vcol_info,
+ create_options))
DBUG_RETURN(1);
lex->alter_info.create_list.push_back(new_field);
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-04-02 09:20:09 +0000
+++ b/sql/sql_show.cc 2010-04-06 00:06:09 +0000
@@ -981,6 +981,30 @@
DBUG_RETURN(0);
}
+
+/**
+ Goes through all character combinations and ensure that it is number.
+
+ @param name attribute name
+ @param name_length length of name
+
+ @retval # Pointer to conflicting character
+ @retval 0 No conflicting character
+*/
+
+static const char *is_unsigned_number(const char *name, uint name_length)
+{
+ const char *end= name + name_length;
+
+ for (; name < end ; name++)
+ {
+ uchar chr= (uchar) *name;
+ if (chr < '0' || chr > '9')
+ return name;
+ }
+ return 0;
+}
+
/*
Go through all character combinations and ensure that sql_lex.cc can
parse it as an identifier.
@@ -1043,7 +1067,7 @@
/*
The identifier must be quoted as it includes a quote character or
- it's a keyword
+ it's a keyword
*/
VOID(packet->reserve(length*2 + 2));
@@ -1106,7 +1130,6 @@
return '`';
}
-
/* Append directory name (if exists) to CREATE INFO */
static void append_directory(THD *thd, String *packet, const char *dir_type,
@@ -1203,6 +1226,32 @@
return has_default;
}
+
+/**
+ Appends list of options to string
+
+ @param thd thread handler
+ @param packet string to append
+ @param opt list of options
+*/
+
+static void append_create_options(THD *thd, String *packet,
+ engine_option_value *opt)
+{
+ for(; opt; opt= opt->next)
+ {
+ DBUG_ASSERT(opt->value.str);
+ packet->append(' ');
+ append_identifier(thd, packet, opt->name.str, opt->name.length);
+ packet->append('=');
+ if (!opt->quoted_value && opt->value.length < 21 &&
+ is_unsigned_number(opt->value.str, opt->value.length) == NULL)
+ packet->append(opt->value.str, opt->value.length);
+ else
+ append_unescaped(packet, opt->value.str, opt->value.length);
+ }
+}
+
/*
Build a CREATE TABLE statement for a table.
@@ -1385,6 +1434,8 @@
packet->append(STRING_WITH_LEN(" COMMENT "));
append_unescaped(packet, field->comment.str, field->comment.length);
}
+ if (field->option_list)
+ append_create_options(thd, packet, field->option_list);
}
key_info= table->key_info;
@@ -1456,6 +1507,8 @@
append_identifier(thd, packet, parser_name->str, parser_name->length);
packet->append(STRING_WITH_LEN(" */ "));
}
+ if (key_info->option_list)
+ append_create_options(thd, packet, key_info->option_list);
}
/*
@@ -1615,6 +1668,10 @@
packet->append(STRING_WITH_LEN(" CONNECTION="));
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
}
+ /* create_table_options can be NULL for temporary tables */
+ if (share->option_list)
+ append_create_options(thd, packet,
+ share->option_list);
append_directory(thd, packet, "DATA", create_info.data_file_name);
append_directory(thd, packet, "INDEX", create_info.index_file_name);
}
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-04-01 09:04:26 +0000
+++ b/sql/sql_table.cc 2010-04-06 00:06:09 +0000
@@ -2863,6 +2863,11 @@
sql_field->offset= record_offset;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
auto_increment++;
+ if (parse_option_list(thd, &sql_field->option_struct,
+ sql_field->option_list,
+ create_info->db_type->field_opt_rules, FALSE,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
/*
For now skip fields that are not physically stored in the database
(virtual fields) and update their offset later
@@ -3061,6 +3066,12 @@
key_info->key_part=key_part_info;
key_info->usable_key_parts= key_number;
key_info->algorithm= key->key_create_info.algorithm;
+ key_info->option_list= key->option_list;
+ if (parse_option_list(thd, &key_info->option_struct,
+ key_info->option_list,
+ create_info->db_type->key_opt_rules, FALSE,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
if (key->type == Key::FULLTEXT)
{
@@ -3438,6 +3449,12 @@
}
}
+ if (parse_option_list(thd, &create_info->option_struct,
+ create_info->option_list,
+ create_info->db_type->table_opt_rules, FALSE,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
+
DBUG_RETURN(FALSE);
}
@@ -5679,6 +5696,7 @@
KEY_PART_INFO *key_part;
KEY_PART_INFO *end;
THD *thd= table->in_use;
+ uint i;
/*
Remember if the new definition has new VARCHAR column;
create_info->varchar will be reset in mysql_prepare_create_table.
@@ -5769,6 +5787,43 @@
DBUG_RETURN(0);
}
+ create_info->fields= table->s->fields;
+ create_info->keys= table->s->keys;
+ /*if (!(create_info->old_new_fileds_option_struct[0]=
+ (void**)thd->alloc(sizeof(void*) * 2 * (create_info->fields) +
+ sizeof(void*) * 2 * (create_info->keys))))
+ DBUG_RETURN(1);
+ bzero(create_info->old_new_fileds_option_struct[0],
+ sizeof(void*) * 2 * (create_info->fields) +
+ sizeof(void*) * 2 * (create_info->keys));
+ create_info->old_new_fileds_option_struct[1]=
+ create_info->old_new_fileds_option_struct[0] +
+ sizeof(void*) * (create_info->fields);
+ create_info->old_new_keys_option_struct[0]=
+ create_info->old_new_fileds_option_struct[1] +
+ sizeof(void*) * (create_info->fields);
+ create_info->old_new_keys_option_struct[1]=
+ create_info->old_new_keys_option_struct[0] +
+ sizeof(void*) * (create_info->keys);
+ */
+ if ((create_info->old_new_fileds_option_struct[0]=
+ (void**)thd->alloc(sizeof(void*) * create_info->fields)) == NULL ||
+ (create_info->old_new_fileds_option_struct[1]=
+ (void**)thd->alloc(sizeof(void*) * create_info->fields)) == NULL ||
+ (create_info->old_new_keys_option_struct[0]=
+ (void**)thd->alloc(sizeof(void*) * create_info->keys)) == NULL ||
+ (create_info->old_new_keys_option_struct[1]=
+ (void**)thd->alloc(sizeof(void*) * create_info->keys)) == NULL)
+ DBUG_RETURN(1);
+ bzero(create_info->old_new_fileds_option_struct[0],
+ sizeof(void*) * create_info->fields);
+ bzero(create_info->old_new_fileds_option_struct[1],
+ sizeof(void*) * create_info->fields);
+ bzero(create_info->old_new_keys_option_struct[0],
+ sizeof(void*) * create_info->keys);
+ bzero(create_info->old_new_keys_option_struct[1],
+ sizeof(void*) * create_info->keys);
+
/*
Use transformed info to evaluate possibility of fast ALTER TABLE
but use the preserved field to persist modifications.
@@ -5779,12 +5834,16 @@
/* Go through fields and check if the original ones are compatible
with new table.
*/
- for (f_ptr= table->field, new_field= new_field_it++,
+ for (i= 0, f_ptr= table->field, new_field= new_field_it++,
tmp_new_field= tmp_new_field_it++;
(field= *f_ptr);
+ i++,
f_ptr++, new_field= new_field_it++,
tmp_new_field= tmp_new_field_it++)
{
+ DBUG_ASSERT(i < create_info->fields);
+ create_info->old_new_fileds_option_struct[0][i]= field->option_struct;
+
/* Make sure we have at least the default charset in use. */
if (!new_field->charset)
new_field->charset= create_info->default_table_charset;
@@ -5811,6 +5870,10 @@
DBUG_RETURN(0);
}
+ /* to allow check_if_incompatible_data compare */
+ create_info->old_new_fileds_option_struct[1][i]=
+ tmp_new_field->option_struct;
+
/* Don't pack rows in old tables if the user has requested this. */
if (create_info->row_type == ROW_TYPE_DYNAMIC ||
(tmp_new_field->flags & BLOB_FLAG) ||
@@ -5854,11 +5917,15 @@
*index_drop_count= 0;
*index_add_count= 0;
*candidate_key_count= 0;
- for (table_key= table->key_info; table_key < table_key_end; table_key++)
+ for (i= 0,table_key= table->key_info;
+ table_key < table_key_end;
+ i++, table_key++)
{
KEY_PART_INFO *table_part;
KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
KEY_PART_INFO *new_part;
+ DBUG_ASSERT(i < create_info->keys);
+ create_info->old_new_keys_option_struct[0][i]= table_key->option_struct;
/*
Check if key is a candidate key, i.e. a unique index with no index
@@ -5938,7 +6005,9 @@
for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
{
/* Search an old key with the same name. */
- for (table_key= table->key_info; table_key < table_key_end; table_key++)
+ for (i= 0, table_key= table->key_info;
+ table_key < table_key_end;
+ i++, table_key++)
{
if (! strcmp(table_key->name, new_key->name))
break;
@@ -5957,9 +6026,16 @@
}
DBUG_PRINT("info", ("index added: '%s'", new_key->name));
}
+ else
+ {
+ DBUG_ASSERT(i < create_info->keys);
+ create_info->old_new_keys_option_struct[1][i]=
+ new_key->option_struct;
+ }
}
/* Check if changes are compatible with current handler without a copy */
+ create_info->old_option_struct= table->s->option_struct;
if (table->file->check_if_incompatible_data(create_info, changes))
{
DBUG_PRINT("info", ("check_if_incompatible_data() -> "
@@ -6132,6 +6208,16 @@
}
restore_record(table, s->default_values); // Empty record for DEFAULT
+ if (create_info->option_list)
+ {
+ create_info->option_list=
+ merge_engine_table_options(table->s->option_list,
+ create_info->option_list,
+ thd->mem_root);
+ }
+ else
+ create_info->option_list= table->s->option_list;
+
/*
First collect all fields from table which isn't in drop_list
*/
@@ -6384,7 +6470,7 @@
key= new Key(key_type, key_name,
&key_create_info,
test(key_info->flags & HA_GENERATED_KEY),
- key_parts);
+ key_parts, key_info->option_list);
new_key_list.push_back(key);
}
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-03-30 12:36:49 +0000
+++ b/sql/sql_view.cc 2010-04-06 00:06:09 +0000
@@ -1185,7 +1185,7 @@
+ MODE_PIPES_AS_CONCAT affect expression parsing
+ MODE_ANSI_QUOTES affect expression parsing
+ MODE_IGNORE_SPACE affect expression parsing
- - MODE_NOT_USED not used :)
+ - MODE_CREATE_OPTIONS_NOERR affect only CREATE/ALTER TABLE parsing
* MODE_ONLY_FULL_GROUP_BY affect execution
* MODE_NO_UNSIGNED_SUBTRACTION affect execution
- MODE_NO_DIR_IN_CREATE affect table creation only
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-04-01 09:04:26 +0000
+++ b/sql/sql_yacc.yy 2010-04-06 00:06:09 +0000
@@ -608,6 +608,7 @@
lex->alter_info.flags= ALTER_ADD_INDEX;
lex->col_list.empty();
lex->change= NullS;
+ lex->option_list= lex->option_list_last= NULL;
return FALSE;
}
@@ -617,7 +618,7 @@
{
Key *key;
key= new Key(type, name, info ? info : &lex->key_create_info, generated,
- lex->col_list);
+ lex->col_list, lex->option_list);
if (key == NULL)
return TRUE;
@@ -3898,7 +3899,11 @@
;
create2a:
- field_list ')' opt_create_table_options
+ field_list ')'
+ {
+ Lex->create_info.option_list= Lex->option_list_last= NULL;
+ }
+ opt_create_table_options
opt_partitioning
create3 {}
| opt_partitioning
@@ -4751,6 +4756,39 @@
Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
Lex->create_info.transactional= $3;
}
+ | IDENT_sys equal TEXT_STRING_sys
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->create_info.option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ident
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->create_info.option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ulonglong_num
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3,
+ &Lex->create_info.option_list,
+ &Lex->option_list_last,
+ YYTHD->mem_root);
+ }
+ | IDENT_sys equal DEFAULT
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ NULL, 0,
+ &Lex->create_info.option_list,
+ &Lex->option_list_last);
+ }
;
default_charset:
@@ -4872,25 +4910,33 @@
;
key_def:
- normal_key_type opt_ident key_alg '(' key_list ')' normal_key_options
+ normal_key_type opt_ident key_alg '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ normal_key_options
{
if (add_create_index (Lex, $1, $2))
MYSQL_YYABORT;
}
| fulltext opt_key_or_index opt_ident init_key_options
- '(' key_list ')' fulltext_key_options
+ '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ fulltext_key_options
{
if (add_create_index (Lex, $1, $3))
MYSQL_YYABORT;
}
| spatial opt_key_or_index opt_ident init_key_options
- '(' key_list ')' spatial_key_options
+ '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ spatial_key_options
{
if (add_create_index (Lex, $1, $3))
MYSQL_YYABORT;
}
| opt_constraint constraint_key_type opt_ident key_alg
- '(' key_list ')' normal_key_options
+ '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ normal_key_options
{
if (add_create_index (Lex, $2, $3 ? $3 : $1))
MYSQL_YYABORT;
@@ -4953,6 +4999,7 @@
lex->comment=null_lex_str;
lex->charset=NULL;
lex->vcol_info= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
field_def
{
@@ -4963,7 +5010,7 @@
&lex->comment,
lex->change,&lex->interval_list,lex->charset,
lex->uint_geom_type,
- lex->vcol_info))
+ lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
}
;
@@ -5383,6 +5430,39 @@
Lex->charset=$2;
}
}
+ | IDENT_sys equal TEXT_STRING_sys
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ident
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ulonglong_num
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3,
+ &Lex->option_list,
+ &Lex->option_list_last,
+ YYTHD->mem_root);
+ }
+ | IDENT_sys equal DEFAULT
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ NULL, 0,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
;
now_or_signed_literal:
@@ -5672,6 +5752,39 @@
all_key_opt:
KEY_BLOCK_SIZE opt_equal ulong_num
{ Lex->key_create_info.block_size= $3; }
+ | IDENT_sys equal TEXT_STRING_sys
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ident
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ulonglong_num
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3,
+ &Lex->option_list,
+ &Lex->option_list_last,
+ YYTHD->mem_root);
+ }
+ | IDENT_sys equal DEFAULT
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ NULL, 0,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
;
normal_key_opt:
@@ -6161,6 +6274,7 @@
LEX *lex=Lex;
lex->change= $3.str;
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
+ lex->option_list= lex->option_list_last= NULL;
}
field_spec opt_place
| MODIFY_SYM opt_column field_ident
@@ -6172,6 +6286,7 @@
lex->charset= NULL;
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
lex->vcol_info= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
field_def
{
@@ -6183,7 +6298,7 @@
&lex->comment,
$3.str, &lex->interval_list, lex->charset,
lex->uint_geom_type,
- lex->vcol_info))
+ lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
}
opt_place
@@ -6290,8 +6405,7 @@
}
| create_table_options_space_separated
{
- LEX *lex=Lex;
- lex->alter_info.flags|= ALTER_OPTIONS;
+ Lex->alter_info.flags|= ALTER_OPTIONS;
}
| FORCE_SYM
{
@@ -13651,6 +13765,7 @@
lex->interval_list.empty();
lex->type= 0;
lex->vcol_info= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
type /* $11 */
{ /* $12 */
@@ -13901,6 +14016,7 @@
}
;
+
/**
@} (end of group Parser)
*/
=== modified file 'sql/structs.h'
--- a/sql/structs.h 2010-03-29 15:13:53 +0000
+++ b/sql/structs.h 2010-04-06 00:06:09 +0000
@@ -68,6 +68,7 @@
uint8 null_bit; /* Position to null_bit */
} KEY_PART_INFO ;
+class engine_option_value;
typedef struct st_key {
uint key_length; /* Tot length of key */
@@ -101,6 +102,9 @@
int bdb_return_if_eq;
} handler;
struct st_table *table;
+ /** reference to the list of options or NULL */
+ engine_option_value *option_list;
+ void *option_struct; /* structure with parsed options */
} KEY;
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2010-03-29 15:13:53 +0000
+++ b/sql/table.cc 2010-04-06 00:06:09 +0000
@@ -667,12 +667,13 @@
uint db_create_options, keys, key_parts, n_length;
uint key_info_length, com_length, null_bit_pos;
uint vcol_screen_length;
- uint extra_rec_buf_length;
+ uint extra_rec_buf_length, options_len;
uint i,j;
bool use_hash;
char *keynames, *names, *comment_pos, *vcol_screen_pos;
uchar *record;
- uchar *disk_buff, *strpos, *null_flags, *null_pos;
+ uchar *disk_buff, *strpos, *null_flags, *null_pos, *options;
+ uchar *buff= 0;
ulong pos, record_offset, *rec_per_key, rec_buff_length;
handler *handler_file= 0;
KEY *keyinfo;
@@ -788,7 +789,6 @@
for (i=0 ; i < keys ; i++, keyinfo++)
{
- keyinfo->table= 0; // Updated in open_frm
if (new_frm_ver >= 3)
{
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
@@ -858,15 +858,14 @@
if ((n_length= uint4korr(head+55)))
{
/* Read extra data segment */
- uchar *buff, *next_chunk, *buff_end;
+ uchar *next_chunk, *buff_end;
DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
goto err;
if (my_pread(file, buff, n_length, record_offset + share->reclength,
MYF(MY_NABP)))
{
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
share->connect_string.length= uint2korr(buff);
if (!(share->connect_string.str= strmake_root(&share->mem_root,
@@ -874,8 +873,7 @@
share->connect_string.
length)))
{
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
next_chunk+= share->connect_string.length + 2;
buff_end= buff + n_length;
@@ -895,8 +893,7 @@
plugin_data(tmp_plugin, handlerton *)))
{
/* bad file, legacy_db_type did not match the name */
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
/*
tmp_plugin is locked with a local lock.
@@ -925,8 +922,7 @@
error= 8;
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"--skip-partition");
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
plugin_unlock(NULL, share->db_plugin);
share->db_plugin= ha_lock_engine(NULL, partition_hton);
@@ -940,8 +936,7 @@
/* purecov: begin inspected */
error= 8;
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
/* purecov: end */
}
next_chunk+= str_db_type_length + 2;
@@ -957,16 +952,14 @@
memdup_root(&share->mem_root, next_chunk + 4,
partition_info_len + 1)))
{
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
}
#else
if (partition_info_len)
{
DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined"));
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
#endif
next_chunk+= 5 + partition_info_len;
@@ -992,6 +985,16 @@
#endif
next_chunk++;
}
+ if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
+ {
+ /*
+ store options position, but skip till the time we will
+ know number of fields
+ */
+ options_len= uint4korr(next_chunk);
+ options= next_chunk + 4;
+ next_chunk+= options_len + 4;
+ }
keyinfo= share->key_info;
for (i= 0; i < keys; i++, keyinfo++)
{
@@ -1002,8 +1005,7 @@
{
DBUG_PRINT("error",
("fulltext key uses parser that is not defined in .frm"));
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
parser_name.str= (char*) next_chunk;
parser_name.length= strlen((char*) next_chunk);
@@ -1013,12 +1015,10 @@
if (! keyinfo->parser)
{
my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str);
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
}
}
- my_free(buff, MYF(0));
}
share->key_block_size= uint2korr(head+62);
@@ -1028,21 +1028,21 @@
share->rec_buff_length= rec_buff_length;
if (!(record= (uchar *) alloc_root(&share->mem_root,
rec_buff_length)))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
share->default_values= record;
if (my_pread(file, record, (size_t) share->reclength,
record_offset, MYF(MY_NABP)))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
if (my_read(file, head,288,MYF(MY_NABP)))
- goto err;
+ goto free_and_err;
#ifdef HAVE_CRYPTED_FRM
if (crypted)
{
crypted->decode((char*) head+256,288-256);
if (sint2korr(head+284) != 0) // Should be 0
- goto err; // Wrong password
+ goto free_and_err; // Wrong password
}
#endif
@@ -1062,6 +1062,8 @@
share->comment.length);
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length, vcol_screen_length));
+
+
if (!(field_ptr = (Field **)
alloc_root(&share->mem_root,
(uint) ((share->fields+1)*sizeof(Field*)+
@@ -1070,14 +1072,14 @@
keys+3)*sizeof(char *)+
(n_length+int_length+com_length+
vcol_screen_length)))))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
share->field= field_ptr;
read_length=(uint) (share->fields * field_pack_length +
pos+ (uint) (n_length+int_length+com_length+
vcol_screen_length));
if (read_string(file,(uchar**) &disk_buff,read_length))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
#ifdef HAVE_CRYPTED_FRM
if (crypted)
{
@@ -1104,7 +1106,7 @@
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
if (share->fieldnames.count != share->fields)
- goto err;
+ goto free_and_err;
fix_type_pointers(&interval_array, share->intervals, interval_count,
&names);
@@ -1118,7 +1120,7 @@
uint count= (uint) (interval->count + 1) * sizeof(uint);
if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
count)))
- goto err;
+ goto free_and_err;
for (count= 0; count < interval->count; count++)
{
char *val= (char*) interval->type_names[count];
@@ -1134,7 +1136,7 @@
/* Allocate handler */
if (!(handler_file= get_new_handler(share, thd->mem_root,
share->db_type())))
- goto err;
+ goto free_and_err;
record= share->default_values-1; /* Fieldstart = 1 */
if (share->null_field_first)
@@ -1196,7 +1198,7 @@
charset= &my_charset_bin;
#else
error= 4; // unsupported field type
- goto err;
+ goto free_and_err;
#endif
}
else
@@ -1207,7 +1209,7 @@
{
error= 5; // Unknown or unavailable charset
errarg= (int) strpos[14];
- goto err;
+ goto free_and_err;
}
}
@@ -1247,7 +1249,7 @@
if ((uint)vcol_screen_pos[0] != 1)
{
error= 4;
- goto err;
+ goto free_and_err;
}
field_type= (enum_field_types) (uchar) vcol_screen_pos[1];
fld_stored_in_db= (bool) (uint) vcol_screen_pos[2];
@@ -1256,7 +1258,7 @@
(char *)memdup_root(&share->mem_root,
vcol_screen_pos+(uint)FRM_VCOL_HEADER_SIZE,
vcol_expr_length)))
- goto err;
+ goto free_and_err;
vcol_info->expr_str.length= vcol_expr_length;
vcol_screen_pos+= vcol_info_length;
share->vfields++;
@@ -1346,7 +1348,7 @@
if (!reg_field) // Not supported field type
{
error= 4;
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
}
reg_field->field_index= i;
@@ -1385,7 +1387,7 @@
sent (OOM).
*/
error= 8;
- goto err;
+ goto free_and_err;
}
}
if (!reg_field->stored_in_db)
@@ -1462,7 +1464,7 @@
if (!key_part->fieldnr)
{
error= 4; // Wrong file
- goto err;
+ goto free_and_err;
}
field= key_part->field= share->field[key_part->fieldnr-1];
key_part->type= field->key_type();
@@ -1627,6 +1629,15 @@
null_length, 255);
}
+ if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
+ {
+ DBUG_ASSERT(options_len);
+ if (engine_table_options_frm_read(options, options_len, share) ||
+ parse_engine_table_options(thd, handler_file->ht, share))
+ goto free_and_err;
+ }
+ my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
+
if (share->found_next_number_field)
{
reg_field= *share->found_next_number_field;
@@ -1685,6 +1696,8 @@
#endif
DBUG_RETURN (0);
+ free_and_err:
+ my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
err:
share->error= error;
share->open_errno= my_errno;
@@ -2883,6 +2896,7 @@
ulong length;
uchar fill[IO_SIZE];
int create_flags= O_RDWR | O_TRUNC;
+ DBUG_ENTER("create_frm");
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
create_flags|= O_EXCL | O_NOFOLLOW;
@@ -2964,7 +2978,7 @@
{
VOID(my_close(file,MYF(0)));
VOID(my_delete(name,MYF(0)));
- return(-1);
+ DBUG_RETURN(-1);
}
}
}
@@ -2975,7 +2989,7 @@
else
my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
}
- return (file);
+ DBUG_RETURN(file);
} /* create_frm */
@@ -2994,6 +3008,7 @@
create_info->comment= share->comment;
create_info->transactional= share->transactional;
create_info->page_checksum= share->page_checksum;
+ create_info->option_list= share->option_list;
DBUG_VOID_RETURN;
}
=== modified file 'sql/table.h'
--- a/sql/table.h 2010-02-12 08:47:31 +0000
+++ b/sql/table.h 2010-04-06 00:06:09 +0000
@@ -340,6 +340,8 @@
#ifdef NOT_YET
struct st_table *open_tables; /* link to open tables */
#endif
+ engine_option_value *option_list; /* text options for table */
+ void *option_struct; /* structure with parsed options */
/* The following is copied to each TABLE on OPEN */
Field **field;
=== modified file 'sql/unireg.cc'
--- a/sql/unireg.cc 2010-01-04 17:54:42 +0000
+++ b/sql/unireg.cc 2010-04-06 00:06:09 +0000
@@ -29,6 +29,9 @@
#define FCOMP 17 /* Bytes for a packed field */
+/* max length of options in frm which be allocated on stack */
+#define OPTIONS_ON_STACK 256
+
static uchar * pack_screens(List<Create_field> &create_fields,
uint *info_length, uint *screens, bool small_file);
static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info,
@@ -46,6 +49,18 @@
uint reclength, ulong data_offset,
handler *handler);
+/*
+ We declare engine_table_options_frm_length end
+ engine_table_options_frm_image here because
+ List, Create_field, KEY are not declared in create_options.h
+*/
+uint engine_table_options_frm_length(engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info);
+uchar *engine_table_options_frm_image(uchar *buff,
+ engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info);
/**
An interceptor to hijack ER_TOO_MANY_FIELDS error from
pack_screens and retry again without UNIREG screens.
@@ -75,6 +90,7 @@
return is_handled;
}
+
/*
Create a frm (table definition) file
@@ -107,6 +123,7 @@
ulong key_buff_length;
File file;
ulong filepos, data_offset;
+ uint options_len;
uchar fileinfo[64],forminfo[288],*keybuff;
TYPELIB formnames;
uchar *screen_buff;
@@ -183,6 +200,16 @@
create_info->extra_size+= key_info[i].parser_name->length + 1;
}
+ options_len= engine_table_options_frm_length(create_info->option_list,
+ create_fields,
+ keys, key_info);
+ DBUG_PRINT("info", ("Options length: %u", options_len));
+ if (options_len)
+ {
+ create_info->table_options|= HA_OPTION_TEXT_CREATE_OPTIONS;
+ create_info->extra_size+= (options_len + 4);
+ }
+
if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo,
create_info, keys)) < 0)
{
@@ -294,6 +321,25 @@
if (my_write(file, (uchar*) buff, 6, MYF_RW))
goto err;
}
+
+ if (options_len)
+ {
+ uchar *optbuff= (uchar *)my_safe_alloca(options_len + 4, OPTIONS_ON_STACK);
+ my_bool error;
+ DBUG_PRINT("info", ("Create options length: %u", options_len));
+ if (!optbuff)
+ goto err;
+ int4store(optbuff, options_len);
+ engine_table_options_frm_image(optbuff + 4,
+ create_info->option_list,
+ create_fields,
+ keys, key_info);
+ error= my_write(file, optbuff, options_len + 4, MYF_RW);
+ my_safe_afree(optbuff, options_len + 4, OPTIONS_ON_STACK);
+ if (error)
+ goto err;
+ }
+
for (i= 0; i < keys; i++)
{
if (key_info[i].parser_name)
=== modified file 'storage/example/ha_example.cc'
--- a/storage/example/ha_example.cc 2010-04-01 14:34:51 +0000
+++ b/storage/example/ha_example.cc 2010-04-06 00:06:09 +0000
@@ -113,6 +113,47 @@
/* The mutex used to init the hash; variable for example share methods */
pthread_mutex_t example_mutex;
+
+/**
+ structure for CREATE TABLE options (table options)
+*/
+
+struct example_table_options_struct
+{
+ const char *strparam;
+ ulonglong ullparam;
+ uint enumparam;
+ bool boolparam;
+};
+
+
+/**
+ structure for CREATE TABLE options (table options)
+*/
+
+struct example_field_options_struct
+{
+ const char *compex_param_to_parse_it_in_engine;
+};
+
+#define ha_table_option_struct example_table_options_struct
+ha_create_table_option example_table_option_list[]=
+{
+ HA_TOPTION_ULL("ULL", ullparam, UINT_MAX32, 0, UINT_MAX32, 1),
+ HA_TOPTION_STRING("STR", strparam),
+ HA_TOPTION_ENUM("one_or_two", enumparam, "one,two", 0),
+ HA_TOPTION_BOOL("YESNO", boolparam, 1),
+ HA_TOPTION_END
+};
+
+#define ha_field_option_struct example_field_options_struct
+ha_create_table_option example_field_option_list[]=
+{
+ HA_FOPTION_STRING("COMPLEX", compex_param_to_parse_it_in_engine),
+ HA_FOPTION_END
+};
+
+
/**
@brief
Function we use in the creation of our hash to get key.
@@ -138,6 +179,9 @@
example_hton->state= SHOW_OPTION_YES;
example_hton->create= example_create_handler;
example_hton->flags= HTON_CAN_RECREATE;
+ example_hton->table_opt_rules= example_table_option_list;
+ example_hton->field_opt_rules= example_field_option_list;
+ example_hton->key_opt_rules= NULL;
DBUG_RETURN(0);
}
@@ -774,27 +818,6 @@
/**
@brief
- Renames a table from one name to another via an alter table call.
-
- @details
- If you do not implement this, the default rename_table() is called from
- handler.cc and it will delete all files with the file extensions returned
- by bas_ext().
-
- Called from sql_table.cc by mysql_rename_table().
-
- @see
- mysql_rename_table() in sql_table.cc
-*/
-int ha_example::rename_table(const char * from, const char * to)
-{
- DBUG_ENTER("ha_example::rename_table ");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
-}
-
-
-/**
- @brief
Given a starting key and an ending key, estimate the number of rows that
will exist between the two keys.
@@ -836,15 +859,110 @@
int ha_example::create(const char *name, TABLE *table_arg,
HA_CREATE_INFO *create_info)
{
+ example_table_options_struct *prm=
+ (example_table_options_struct *)table_arg->s->option_struct;
DBUG_ENTER("ha_example::create");
/*
- This is not implemented but we want someone to be able to see that it
- works.
+ This example shows how to support custom engine specific table and field
+ options.
*/
+ DBUG_ASSERT(prm);
+ DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\
+ "boolparam: %u",
+ (prm->strparam ? prm->strparam : "<NULL>"),
+ prm->ullparam, prm->enumparam, prm->boolparam));
+ for (Field **field= table_arg->s->field; *field; field++)
+ {
+ example_field_options_struct *fprm=
+ (example_field_options_struct *)(*field)->option_struct;
+ DBUG_ASSERT(fprm);
+ DBUG_PRINT("info", ("field: %s complex: '%-.64s'",
+ (*field)->field_name,
+ (fprm->compex_param_to_parse_it_in_engine ?
+ fprm->compex_param_to_parse_it_in_engine :
+ "<NULL>")));
+
+ }
+
DBUG_RETURN(0);
}
+/**
+ check_if_incompatible_data() called if ALTER TABLE can't detect otherwise
+ if new and old definition are compatible
+
+ @details If there are no other explicit signs like changed number of
+ fields this function will be called by compare_tables()
+ (sql/sql_tables.cc) to decide should we rewrite whole table or only .frm
+ file.
+
+*/
+
+bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes)
+{
+ example_table_options_struct *prmo, *prmn;
+ uint i;
+ DBUG_ENTER("ha_example::check_if_incompatible_data");
+ DBUG_ASSERT(info->option_struct);
+ DBUG_ASSERT(info->old_option_struct);
+ /*
+ This example shows how custom engine specific table and field
+ options can be accessed from this function to be compared.
+ */
+
+ prmn= (example_table_options_struct *)info->option_struct;
+ DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u "\
+ "boolparam: %u",
+ (prmn->strparam ? prmn->strparam : "<NULL>"),
+ prmn->ullparam, prmn->enumparam, prmn->boolparam));
+
+ prmo= (example_table_options_struct *)info->old_option_struct;
+ DBUG_PRINT("info", ("old strparam: '%-.64s' ullparam: %llu enumparam: %u "\
+ "boolparam: %u",
+ (prmo->strparam ? prmo->strparam : "<NULL>"),
+ prmo->ullparam, prmo->enumparam, prmo->boolparam));
+
+ /* check important parameters */
+ if (prmn->ullparam != prmo->ullparam || prmn->boolparam != prmo->boolparam)
+ DBUG_RETURN(COMPATIBLE_DATA_NO);
+
+ for (i= 0; i < info->fields; i++)
+ {
+ example_field_options_struct *fprmo, *fprmn;
+ if (info->old_new_fileds_option_struct[1][i])
+ {
+ fprmn=
+ (example_field_options_struct *)
+ info->old_new_fileds_option_struct[1][i];
+ DBUG_PRINT("info", ("old field: %u new complex: '%-.64s'", i,
+ (fprmn->compex_param_to_parse_it_in_engine ?
+ fprmn->compex_param_to_parse_it_in_engine :
+ "<NULL>")));
+ /*
+ if (!structure_is_the_same(fprmn->compex_param_to_parse_it_in_engine,
+ fprmo->compex_param_to_parse_it_in_engine)
+ DBUG_RETURN(COMPATIBLE_DATA_NO);
+ */
+ }
+ else
+ DBUG_PRINT("info", ("old field %i did not changed", i));
+
+ fprmo=
+ (example_field_options_struct *)info->old_new_fileds_option_struct[0][i];
+ DBUG_ASSERT(fprmo);
+ DBUG_PRINT("info", ("old field: %u old complex: '%-.64s'", i,
+ (fprmo->compex_param_to_parse_it_in_engine ?
+ fprmo->compex_param_to_parse_it_in_engine :
+ "<NULL>")));
+ }
+
+ DBUG_RETURN(COMPATIBLE_DATA_YES);
+}
+
+
+
struct st_mysql_storage_engine example_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
=== modified file 'storage/example/ha_example.h'
--- a/storage/example/ha_example.h 2010-03-28 18:10:00 +0000
+++ b/storage/example/ha_example.h 2010-04-06 00:06:09 +0000
@@ -243,9 +243,10 @@
ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key);
int delete_table(const char *from);
- int rename_table(const char * from, const char * to);
int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); ///< required
+ bool check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); ///< required
=== modified file 'storage/pbxt/src/discover_xt.cc'
--- a/storage/pbxt/src/discover_xt.cc 2010-02-01 06:14:12 +0000
+++ b/storage/pbxt/src/discover_xt.cc 2010-04-06 00:06:09 +0000
@@ -1623,7 +1623,7 @@
#endif
NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/,
NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/,
- NULL /*vcol_info*/))
+ NULL /*vcol_info*/, NULL /* create options */))
#endif
goto error;
1
0

[Maria-developers] bzr commit into file:///home/tsk/mprog/src/5.3-subqueries/ branch (timour:2789)
by timour@askmonty.org 06 Apr '10
by timour@askmonty.org 06 Apr '10
06 Apr '10
#At file:///home/tsk/mprog/src/5.3-subqueries/ based on revid:timour@askmonty.org-20100402142706-klcgi39tjzhvy22z
2789 timour(a)askmonty.org 2010-04-06
Fixed a problem where the temp table of a materialized subquery
was not cleaned up between PS re-executions. The reason was two-fold:
- a merge with mysql-6.0 missed select_union::cleanup() that should
have cleaned up the temp table, and
- the subclass of select_union used by materialization didn't call
the base class cleanup() method.
modified:
mysql-test/r/subselect_mat.result
mysql-test/t/subselect_mat.test
sql/sql_class.cc
sql/sql_class.h
sql/sql_union.cc
=== modified file 'mysql-test/r/subselect_mat.result'
--- a/mysql-test/r/subselect_mat.result 2010-03-29 14:04:35 +0000
+++ b/mysql-test/r/subselect_mat.result 2010-04-05 21:15:15 +0000
@@ -1246,3 +1246,29 @@ i
4
set session optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
+create table t0 (a int);
+insert into t0 values (0),(1),(2);
+create table t1 (a int);
+insert into t1 values (0),(1),(2);
+explain select a, a in (select a from t1) from t0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 3
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+select a, a in (select a from t1) from t0;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+prepare s from 'select a, a in (select a from t1) from t0';
+execute s;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+update t1 set a=123;
+execute s;
+a a in (select a from t1)
+0 0
+1 0
+2 0
+drop table t0, t1;
=== modified file 'mysql-test/t/subselect_mat.test'
--- a/mysql-test/t/subselect_mat.test 2010-03-13 20:04:52 +0000
+++ b/mysql-test/t/subselect_mat.test 2010-04-05 21:15:15 +0000
@@ -905,3 +905,19 @@ select * from t1 where t1.i in (select t
set session optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
+#
+# Test that the contentes of the temp table of a materialized subquery is
+# cleanup up between PS reexecutions.
+#
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2);
+create table t1 (a int);
+insert into t1 values (0),(1),(2);
+explain select a, a in (select a from t1) from t0;
+select a, a in (select a from t1) from t0;
+prepare s from 'select a, a in (select a from t1) from t0';
+execute s;
+update t1 set a=123;
+execute s;
+drop table t0, t1;
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-03-20 12:01:47 +0000
+++ b/sql/sql_class.cc 2010-04-05 21:15:15 +0000
@@ -2942,8 +2942,7 @@ bool select_dumpvar::send_eof()
}
-bool
-select_materialize_with_stats::
+bool select_materialize_with_stats::
create_result_table(THD *thd_arg, List<Item> *column_types,
bool is_union_distinct, ulonglong options,
const char *table_alias, bool bit_fields_as_long)
@@ -2962,14 +2961,29 @@ create_result_table(THD *thd_arg, List<I
if (!stat)
return TRUE;
- cleanup();
-
+ reset();
table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
return FALSE;
}
+void select_materialize_with_stats::reset()
+{
+ memset(col_stat, 0, table->s->fields * sizeof(Column_statistics));
+ max_nulls_in_row= 0;
+ count_rows= 0;
+}
+
+
+void select_materialize_with_stats::cleanup()
+{
+ reset();
+ select_union::cleanup();
+}
+
+
+
/**
Override select_union::send_data to analyze each row for NULLs and to
update null_statistics before sending data to the client.
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-20 12:01:47 +0000
+++ b/sql/sql_class.h 2010-04-05 21:15:15 +0000
@@ -2820,7 +2820,7 @@ public:
bool send_data(List<Item> &items);
bool send_eof();
bool flush();
-
+ void cleanup();
virtual bool create_result_table(THD *thd, List<Item> *column_types,
bool is_distinct, ulonglong options,
const char *alias, bool bit_fields_as_long);
@@ -2883,6 +2883,9 @@ protected:
*/
ha_rows count_rows;
+protected:
+ void reset();
+
public:
select_materialize_with_stats() {}
virtual bool create_result_table(THD *thd, List<Item> *column_types,
@@ -2890,12 +2893,7 @@ public:
const char *alias, bool bit_fields_as_long);
bool init_result_table(ulonglong select_options);
bool send_data(List<Item> &items);
- void cleanup()
- {
- memset(col_stat, 0, table->s->fields * sizeof(Column_statistics));
- max_nulls_in_row= 0;
- count_rows= 0;
- }
+ void cleanup();
ha_rows get_null_count_of_col(uint idx)
{
DBUG_ASSERT(idx < table->s->fields);
=== modified file 'sql/sql_union.cc'
--- a/sql/sql_union.cc 2010-03-20 12:01:47 +0000
+++ b/sql/sql_union.cc 2010-04-05 21:15:15 +0000
@@ -136,6 +136,22 @@ select_union::create_result_table(THD *t
}
+/**
+ Reset and empty the temporary table that stores the materialized query result.
+
+ @note The cleanup performed here is exactly the same as for the two temp
+ tables of JOIN - exec_tmp_table_[1 | 2].
+*/
+
+void select_union::cleanup()
+{
+ table->file->extra(HA_EXTRA_RESET_STATE);
+ table->file->ha_delete_all_rows();
+ free_io_cache(table);
+ filesort_free_buffers(table,0);
+}
+
+
/*
initialization procedures before fake_select_lex preparation()
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2749)
by Igor Babaev 05 Apr '10
by Igor Babaev 05 Apr '10
05 Apr '10
#At lp:maria/5.2 based on revid:igor@askmonty.org-20100403201935-gg9tnu4bxe73i7yk
2749 Igor Babaev 2010-04-05 [merge]
Merge with the latest changes of 5.2.
modified:
mysql-test/r/connect.result
mysql-test/t/connect.test
sql/sql_acl.cc
=== modified file 'mysql-test/r/connect.result'
--- a/mysql-test/r/connect.result 2009-04-25 09:04:38 +0000
+++ b/mysql-test/r/connect.result 2010-04-05 09:50:31 +0000
@@ -225,3 +225,17 @@ Connection on extra port 2 ok
# ------------------------------------------------------------------
# -- End of 5.1 tests
# ------------------------------------------------------------------
+CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB';
+CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389';
+connect(localhost,mysqltest_up1,foo,test,13001,MASTER_SOCKET);
+ERROR 28000: Access denied for user 'mysqltest_up1'@'localhost' (using password: YES)
+select user(), current_user();
+user() current_user()
+mysqltest_up1@localhost mysqltest_up1@%
+connect(localhost,mysqltest_up2,newpw,test,13001,MASTER_SOCKET);
+ERROR 28000: Access denied for user 'mysqltest_up2'@'localhost' (using password: YES)
+select user(), current_user();
+user() current_user()
+mysqltest_up2@localhost mysqltest_up2@%
+DROP USER mysqltest_up1@'%';
+DROP USER mysqltest_up2@'%';
=== modified file 'mysql-test/t/connect.test'
--- a/mysql-test/t/connect.test 2009-09-07 20:50:10 +0000
+++ b/mysql-test/t/connect.test 2010-04-05 09:50:31 +0000
@@ -328,6 +328,34 @@ if ($error)
--disconnect extracon2
--connection default
+#
+# A couple of plugin tests - for builtin plugins only
+#
+CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB';
+CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389';
+
+--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+--error ER_ACCESS_DENIED_ERROR
+connect(pcon1,localhost,mysqltest_up1,foo,,$MASTER_EXTRA_PORT,);
+
+connect(pcon2,localhost,mysqltest_up1,bar,,$MASTER_EXTRA_PORT,);
+connection pcon2;
+select user(), current_user();
+disconnect pcon2;
+
+--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+--error ER_ACCESS_DENIED_ERROR
+connect(pcon3,localhost,mysqltest_up2,newpw,,$MASTER_EXTRA_PORT,);
+
+connect(pcon4,localhost,mysqltest_up2,oldpw,,$MASTER_EXTRA_PORT,);
+connection pcon4;
+select user(), current_user();
+disconnect pcon4;
+
+connection default;
+DROP USER mysqltest_up1@'%';
+DROP USER mysqltest_up2@'%';
+
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-04-02 20:08:40 +0000
+++ b/sql/sql_acl.cc 2010-04-05 09:50:31 +0000
@@ -319,6 +319,35 @@ set_user_salt(ACL_USER *acl_user, const
acl_user->salt_len= 0;
}
+/**
+ Fix ACL::plugin pointer to point to a hard-coded string, if appropriate
+
+ Make sure that if ACL_USER's plugin is a built-in, then it points
+ to a hard coded string, not to an allocated copy. Run-time, for
+ authentication, we want to be able to detect built-ins by comparing
+ pointers, not strings.
+
+ Additionally - update the salt if the plugin is built-in.
+
+ @retval 0 the pointers were fixed
+ @retval 1 this ACL_USER uses a not built-in plugin
+*/
+static bool fix_user_plugin_ptr(ACL_USER *user)
+{
+ if (my_strcasecmp(system_charset_info, user->plugin.str,
+ native_password_plugin_name.str) == 0)
+ user->plugin= native_password_plugin_name;
+ else
+ if (my_strcasecmp(system_charset_info, user->plugin.str,
+ old_password_plugin_name.str) == 0)
+ user->plugin= old_password_plugin_name;
+ else
+ return true;
+
+ set_user_salt(user, user->auth_string.str, user->auth_string.length);
+ return false;
+}
+
/*
This after_update function is used when user.password is less than
SCRAMBLE_LENGTH bytes.
@@ -662,6 +691,8 @@ static my_bool acl_load(THD *thd, TABLE_
char *tmpstr= get_field(&mem, table->field[next_field++]);
if (tmpstr)
{
+ user.plugin.str= tmpstr;
+ user.plugin.length= strlen(user.plugin.str);
if (user.auth_string.length)
{
sql_print_warning("'user' entry '%s@%s' has both a password "
@@ -670,22 +701,12 @@ static my_bool acl_load(THD *thd, TABLE_
user.user ? user.user : "",
user.host.hostname ? user.host.hostname : "");
}
- if (my_strcasecmp(system_charset_info, tmpstr,
- native_password_plugin_name.str) == 0)
- user.plugin= native_password_plugin_name;
- else
- if (my_strcasecmp(system_charset_info, tmpstr,
- old_password_plugin_name.str) == 0)
- user.plugin= old_password_plugin_name;
- else
- {
- user.plugin.str= tmpstr;
- user.plugin.length= strlen(tmpstr);
- }
user.auth_string.str= get_field(&mem, table->field[next_field++]);
if (!user.auth_string.str)
user.auth_string.str= const_cast<char*>("");
user.auth_string.length= strlen(user.auth_string.str);
+
+ fix_user_plugin_ptr(&user);
}
}
}
@@ -1132,12 +1153,15 @@ static void acl_update_user(const char *
{
if (plugin->str[0])
{
- acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length);
- acl_user->plugin.length= plugin->length;
+ acl_user->plugin= *plugin;
acl_user->auth_string.str= auth->str ?
strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
acl_user->auth_string.length= auth->length;
+ if (fix_user_plugin_ptr(acl_user))
+ acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length);
}
+ else
+ set_user_salt(acl_user, password, password_len);
acl_user->access=privileges;
if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
acl_user->user_resource.questions=mqh->questions;
@@ -1157,8 +1181,6 @@ static void acl_update_user(const char *
acl_user->x509_subject= (x509_subject ?
strdup_root(&mem,x509_subject) : 0);
}
- if (password)
- set_user_salt(acl_user, password, password_len);
/* search complete: */
break;
}
@@ -1186,11 +1208,12 @@ static void acl_insert_user(const char *
update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0);
if (plugin->str[0])
{
- acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length);
- acl_user.plugin.length= plugin->length;
+ acl_user.plugin= *plugin;
acl_user.auth_string.str= auth->str ?
strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
acl_user.auth_string.length= auth->length;
+ if (fix_user_plugin_ptr(&acl_user))
+ acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length);
}
else
{
@@ -1198,6 +1221,7 @@ static void acl_insert_user(const char *
old_password_plugin_name : native_password_plugin_name;
acl_user.auth_string.str= strmake_root(&mem, password, password_len);
acl_user.auth_string.length= password_len;
+ set_user_salt(&acl_user, password, password_len);
}
acl_user.access=privileges;
@@ -1210,8 +1234,6 @@ static void acl_insert_user(const char *
acl_user.x509_issuer= x509_issuer ? strdup_root(&mem,x509_issuer) : 0;
acl_user.x509_subject=x509_subject ? strdup_root(&mem,x509_subject) : 0;
- set_user_salt(&acl_user, password, password_len);
-
VOID(push_dynamic(&acl_users,(uchar*) &acl_user));
if (!acl_user.host.hostname ||
(acl_user.host.hostname[0] == wild_many && !acl_user.host.hostname[1]))
1
0

[Maria-developers] Rev 2788: MWL#90: Subqueries: Inside-out execution for non-semijoin materialized in file:///home/psergey/dev/maria-5.3-subqueries-r12/
by Sergey Petrunya 05 Apr '10
by Sergey Petrunya 05 Apr '10
05 Apr '10
At file:///home/psergey/dev/maria-5.3-subqueries-r12/
------------------------------------------------------------
revno: 2788
revision-id: psergey(a)askmonty.org-20100405201645-kuavh2rxc9whflc0
parent: psergey(a)askmonty.org-20100329200940-9ikx6gpww0gtsx00
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.3-subqueries-r12
timestamp: Tue 2010-04-06 00:16:45 +0400
message:
MWL#90: Subqueries: Inside-out execution for non-semijoin materialized
subqueries that are AND-parts of the WHERE
- First code (needs cleanup).
=== modified file 'mysql-test/include/mix1.inc'
--- a/mysql-test/include/mix1.inc 2010-03-20 12:01:47 +0000
+++ b/mysql-test/include/mix1.inc 2010-04-05 20:16:45 +0000
@@ -1522,6 +1522,12 @@
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
+--echo # MariaDB note:
+--echo # This will show 2 for table which has 5 rows.
+--echo # This is because the access method employed is actually range access
+--echo # which scans 2 records (yes, EXPLAIN displays it incorrectly).
+--echo # our correct printing is an artifact of changing in select_describe()
+--echo # from printing table->starts.records() to tab->records.
EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
@@ -1535,6 +1541,7 @@
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
+--echo # See above "MariaDB note"
EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
@@ -1549,6 +1556,7 @@
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
+--echo # See above "MariaDB note"
EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
=== modified file 'mysql-test/r/group_min_max.result'
--- a/mysql-test/r/group_min_max.result 2010-03-20 12:01:47 +0000
+++ b/mysql-test/r/group_min_max.result 2010-04-05 20:16:45 +0000
@@ -2255,7 +2255,8 @@
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_outer index NULL a 10 NULL 15 Using where; Using index
+1 PRIMARY SUBQUERY#2 ALL NULL NULL NULL NULL 8
+1 PRIMARY t1_outer ref a a 5 materialized subselect.max(b) 2 Using index
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
=== modified file 'mysql-test/r/having.result'
--- a/mysql-test/r/having.result 2009-01-16 15:38:38 +0000
+++ b/mysql-test/r/having.result 2010-04-05 20:16:45 +0000
@@ -249,11 +249,11 @@
group by t2.col1, t2.col2 having t2.col1 <= 10);
col1
10
+10
+10
20
30
10
-10
-10
select t1.col1 from t1
where t1.col2 in
(select t2.col2 from t2
@@ -262,11 +262,11 @@
(select min(t3.col1) from t3));
col1
10
+10
+10
20
30
10
-10
-10
select t1.col1 from t1
where t1.col2 in
(select t2.col2 from t2
=== modified file 'mysql-test/r/innodb_mysql.result'
--- a/mysql-test/r/innodb_mysql.result 2010-03-20 12:01:47 +0000
+++ b/mysql-test/r/innodb_mysql.result 2010-04-05 20:16:45 +0000
@@ -1727,12 +1727,18 @@
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
1
1
+# MariaDB note:
+# This will show 2 for table which has 5 rows.
+# This is because the access method employed is actually range access
+# which scans 2 records (yes, EXPLAIN displays it incorrectly).
+# our correct printing is an artifact of changing in select_describe()
+# from printing table->starts.records() to tab->records.
EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 index c3,c2 c2 10 NULL 5
+2 DERIVED t1 index c3,c2 c2 10 NULL 2
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
ENGINE=InnoDB;
@@ -1741,12 +1747,13 @@
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
1
1
+# See above "MariaDB note"
EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 index c3,c2 c2 18 NULL 5
+2 DERIVED t1 index c3,c2 c2 18 NULL 2
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
KEY (c3), KEY (c2, c3))
@@ -1756,12 +1763,13 @@
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
1
1
+# See above "MariaDB note"
EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 index c3,c2 c2 14 NULL 5
+2 DERIVED t1 index c3,c2 c2 14 NULL 2
DROP TABLE t1;
End of 5.1 tests
drop table if exists t1, t2, t3;
=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result 2010-03-04 08:03:07 +0000
+++ b/mysql-test/r/partition.result 2010-04-05 20:16:45 +0000
@@ -1382,7 +1382,7 @@
2
explain partitions select * from t1 where a is null or a < 0 or a > 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pn,p2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 pn,p2 ALL NULL NULL NULL NULL 2 Using where
drop table t1;
CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, name VARCHAR(20))
ENGINE=MyISAM DEFAULT CHARSET=latin1
=== modified file 'mysql-test/r/partition_hash.result'
--- a/mysql-test/r/partition_hash.result 2008-07-07 20:42:19 +0000
+++ b/mysql-test/r/partition_hash.result 2010-04-05 20:16:45 +0000
@@ -69,25 +69,25 @@
1 SIMPLE t1 p0,p1,p2,p3 ALL NULL NULL NULL NULL 9 Using where
explain partitions select * from t1 where a is null or (a >= 5 and a <= 7);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p2,p3 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p0,p2,p3 ALL NULL NULL NULL NULL 7 Using where
explain partitions select * from t1 where a is null;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t1 where a is not null;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0,p1,p2,p3 ALL NULL NULL NULL NULL 9 Using where
explain partitions select * from t1 where a >= 1 and a < 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 5 Using where
explain partitions select * from t1 where a >= 3 and a <= 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t1 where a > 2 and a < 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a > 3 and a <= 6;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 9 Using where
+1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t1 where a > 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0,p1,p2,p3 ALL NULL NULL NULL NULL 9 Using where
=== modified file 'mysql-test/r/partition_pruning.result'
--- a/mysql-test/r/partition_pruning.result 2010-03-20 12:01:47 +0000
+++ b/mysql-test/r/partition_pruning.result 2010-04-05 20:16:45 +0000
@@ -89,7 +89,7 @@
1
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index
SELECT * FROM t1 WHERE a <= 2;
a
-1
@@ -98,7 +98,7 @@
2
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index
SELECT * FROM t1 WHERE a <= 3;
a
-1
@@ -108,7 +108,7 @@
3
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 5 Using where; Using index
SELECT * FROM t1 WHERE a <= 4;
a
-1
@@ -119,7 +119,7 @@
4
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 6 Using where; Using index
SELECT * FROM t1 WHERE a <= 5;
a
-1
@@ -131,7 +131,7 @@
5
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 7 Using where; Using index
SELECT * FROM t1 WHERE a <= 6;
a
-1
@@ -213,7 +213,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 8 Using where; Using index
SELECT * FROM t1 WHERE a >= 2;
a
2
@@ -225,7 +225,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 7 Using where; Using index
SELECT * FROM t1 WHERE a >= 3;
a
3
@@ -236,7 +236,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 6 Using where; Using index
SELECT * FROM t1 WHERE a >= 4;
a
4
@@ -246,7 +246,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 5 Using where; Using index
SELECT * FROM t1 WHERE a >= 5;
a
5
@@ -255,7 +255,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 4 Using where; Using index
SELECT * FROM t1 WHERE a >= 6;
a
6
@@ -263,7 +263,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index
SELECT * FROM t1 WHERE a >= 7;
a
7
@@ -282,7 +282,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 7 Using where; Using index
SELECT * FROM t1 WHERE a > 2;
a
3
@@ -293,7 +293,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 6 Using where; Using index
SELECT * FROM t1 WHERE a > 3;
a
4
@@ -303,7 +303,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 5 Using where; Using index
SELECT * FROM t1 WHERE a > 4;
a
5
@@ -312,7 +312,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 4 Using where; Using index
SELECT * FROM t1 WHERE a > 5;
a
6
@@ -320,7 +320,7 @@
8
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index
SELECT * FROM t1 WHERE a > 6;
a
7
@@ -408,7 +408,7 @@
1
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index
SELECT * FROM t1 WHERE a <= 2;
a
-1
@@ -417,7 +417,7 @@
2
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index
SELECT * FROM t1 WHERE a <= 3;
a
-1
@@ -427,7 +427,7 @@
3
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 5 Using where; Using index
SELECT * FROM t1 WHERE a <= 4;
a
-1
@@ -438,7 +438,7 @@
4
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 6 Using where; Using index
SELECT * FROM t1 WHERE a <= 5;
a
-1
@@ -511,7 +511,7 @@
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 7 Using where; Using index
SELECT * FROM t1 WHERE a >= 2;
a
2
@@ -522,7 +522,7 @@
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 6 Using where; Using index
SELECT * FROM t1 WHERE a >= 3;
a
3
@@ -532,7 +532,7 @@
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 5 Using where; Using index
SELECT * FROM t1 WHERE a >= 4;
a
4
@@ -541,7 +541,7 @@
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 4 Using where; Using index
SELECT * FROM t1 WHERE a >= 5;
a
5
@@ -549,7 +549,7 @@
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index
SELECT * FROM t1 WHERE a >= 6;
a
6
@@ -567,7 +567,7 @@
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 6 Using where; Using index
SELECT * FROM t1 WHERE a > 2;
a
3
@@ -577,7 +577,7 @@
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 5 Using where; Using index
SELECT * FROM t1 WHERE a > 3;
a
4
@@ -586,7 +586,7 @@
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 4 Using where; Using index
SELECT * FROM t1 WHERE a > 4;
a
5
@@ -594,7 +594,7 @@
7
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index
SELECT * FROM t1 WHERE a > 5;
a
6
@@ -880,34 +880,34 @@
1001-01-01
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 4 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1001-01-01 system NULL NULL NULL NULL 1
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 3 Using where
# Disabling warnings for the invalid date
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -917,25 +917,25 @@
1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 4 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 4 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 3 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
DROP TABLE t1;
# test of LIST and index
CREATE TABLE t1 (a DATE, KEY(a))
@@ -1209,62 +1209,62 @@
1001-01-01
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 4 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1001-01-01 system NULL NULL NULL NULL 1
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 3 Using where
# Disabling warnings for the invalid date
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 4 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 4 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 3 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 pNULL,p1001-01-01 ALL NULL NULL NULL NULL 4 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 5 Using where
DROP TABLE t1;
# Test with DATETIME column NOT NULL
CREATE TABLE t1 (
@@ -1289,25 +1289,25 @@
1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index
+1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1315,99 +1315,99 @@
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p20090401,p20090402,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index
+1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 3 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1440,21 +1440,21 @@
1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index
+1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 2 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1462,79 +1462,79 @@
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 2 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 2 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 2 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1542,19 +1542,19 @@
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1562,11 +1562,11 @@
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index
DROP TABLE t1;
# Test with DATETIME column NULL
CREATE TABLE t1 (
@@ -1590,25 +1590,25 @@
1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 8 Using where
+1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 3 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1616,99 +1616,99 @@
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 3 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p20090401,p20090402,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 3 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1740,21 +1740,21 @@
1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1762,79 +1762,79 @@
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1842,19 +1842,19 @@
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -1862,11 +1862,11 @@
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where
DROP TABLE t1;
# For better code coverage of the patch
CREATE TABLE t1 (
@@ -1930,7 +1930,7 @@
1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t2 where a=1 and b=1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 2 Using where
create table t3 (
a int
)
@@ -1988,25 +1988,25 @@
explain partitions select * from t5
where (a=10 and b=1) or (a=10 and b=2) or (a=10 and b = 3);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t5 where (a=10 and b=2) or (a=10 and b=3)
or (a=10 and b = 4);
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t5 where (c=1 and d=1);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp0,p1_p1sp0 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp0,p1_p1sp0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t5 where (c=2 and d=1);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t5 where (a=10 and b=2 and c=1 and d=1) or
(c=2 and d=1);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t5 where (a=10 and b=2 and c=1 and d=1) or
(b=2 and c=2 and d=1);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 3 Using where
create table t6 (a int not null) partition by LIST(a) (
partition p1 values in (1),
partition p3 values in (3),
@@ -2044,7 +2044,7 @@
1 SIMPLE t6 p5,p7,p9 system NULL NULL NULL NULL 1
explain partitions select * from t6 where a >= 3 and a <= 8;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a > 3 and a < 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -2086,7 +2086,7 @@
1 SIMPLE t6 p5,p7,p9 system NULL NULL NULL NULL 1
explain partitions select * from t6 where a >= 3 and a <= 8;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t6 where a > 3 and a < 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -2241,7 +2241,7 @@
explain partitions
select * from t1 X, t1 Y where X.a = Y.a and (X.a=1 or X.a=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE X p1,p2 ALL a NULL NULL NULL 4 Using where
+1 SIMPLE X p1,p2 ALL a NULL NULL NULL 2 Using where
1 SIMPLE Y p1,p2 ref a a 4 test.X.a 2
drop table t1;
create table t1 (a int) partition by hash(a) partitions 20;
@@ -2254,7 +2254,7 @@
1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a > 1 and a <= 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a >= 1 and a <= 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1,p2,p3 ALL NULL NULL NULL NULL 3 Using where
@@ -2344,22 +2344,22 @@
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 1010
explain partitions select * from t2 where a < 801 and a > 200;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p1,p2,p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p1,p2,p3,p4 ALL NULL NULL NULL NULL 800 Using where
explain partitions select * from t2 where a < 801 and a > 800;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 200 Using where
explain partitions select * from t2 where a > 600;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where
explain partitions select * from t2 where a > 600 and b = 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where
explain partitions select * from t2 where a > 600 and b = 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where
explain partitions select * from t2 where a > 600 and b = 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where
+1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where
explain partitions select * from t2 where b = 5;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 1010 Using where
@@ -2414,19 +2414,19 @@
1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 910
explain partitions select * from t2 where a = 101;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 110 Using where
explain partitions select * from t2 where a = 550;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 200 Using where
explain partitions select * from t2 where a = 833;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 200 Using where
explain partitions select * from t2 where (a = 100 OR a = 900);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 310 Using where
explain partitions select * from t2 where (a > 100 AND a < 600);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 510 Using where
explain partitions select * from t2 where b = 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76
@@ -2712,17 +2712,17 @@
explain partitions select * from t1
where a >= 18446744073709551000-1 and a <= 18446744073709551000+1;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p3,p4 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p3,p4 ALL NULL NULL NULL NULL 3 Using where
explain partitions select * from t1
where a between 18446744073709551001 and 18446744073709551002;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a = 18446744073709551000;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a = 18446744073709551613;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a = 18446744073709551614;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -2749,10 +2749,10 @@
1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a=0xFE;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t2 where a=0xFE;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a > 0xFE AND a <= 0xFF;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -2761,22 +2761,22 @@
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
explain partitions select * from t1 where a >= 0xFE AND a <= 0xFF;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t2 where a >= 0xFE AND a <= 0xFF;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a < 64 AND a >= 63;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t2 where a < 64 AND a >= 63;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a <= 64 AND a >= 63;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t2 where a <= 64 AND a >= 63;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL 4 Using where
drop table t1;
drop table t2;
create table t1(a bigint unsigned not null) partition by range(a+0) (
=== modified file 'mysql-test/r/partition_range.result'
--- a/mysql-test/r/partition_range.result 2009-08-26 10:59:49 +0000
+++ b/mysql-test/r/partition_range.result 2010-04-05 20:16:45 +0000
@@ -59,13 +59,13 @@
1 SIMPLE t1 pnull system NULL NULL NULL NULL 1
explain partitions select * from t1 where a >= 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a < 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
explain partitions select * from t1 where a <= 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull,p0 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t1 pnull,p0 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a > 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -98,16 +98,16 @@
a b
explain partitions select * from t1 where a is null;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a >= 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t1 where a < 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 2 Using where
explain partitions select * from t1 where a <= 0;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1,p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 6 Using where
+1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1,p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 4 Using where
explain partitions select * from t1 where a > 1;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
=== modified file 'mysql-test/r/subselect.result'
--- a/mysql-test/r/subselect.result 2010-03-20 12:01:47 +0000
+++ b/mysql-test/r/subselect.result 2010-04-05 20:16:45 +0000
@@ -3417,7 +3417,8 @@
EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
@@ -3428,7 +3429,8 @@
EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY t1 ALL a NULL NULL NULL 9
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
DROP TABLE t1;
create table t1( f1 int,f2 int);
@@ -4322,16 +4324,18 @@
INSERT INTO t1 VALUES (1),(2);
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 4 const 1 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,1 in ( <materialize> (select 1 AS `1` from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`)))))
+Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`materialized subselect`.`1` = 1)
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 4 const 1 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,1 in ( <materialize> (select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`)))))
+Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`materialized subselect`.`1` = 1)
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
=== modified file 'mysql-test/r/subselect3.result'
--- a/mysql-test/r/subselect3.result 2010-03-29 14:04:35 +0000
+++ b/mysql-test/r/subselect3.result 2010-04-05 20:16:45 +0000
@@ -1212,24 +1212,28 @@
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY A ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY A ALL NULL NULL NULL NULL 10
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.A.a 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1
2 SUBQUERY A ALL NULL NULL NULL NULL 10
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1
2 SUBQUERY A ALL NULL NULL NULL NULL 10
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
explain select straight_join * from t2 X, t2 Y
where X.a in (select straight_join A.a from t1 A, t1 B);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY X ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY X ALL NULL NULL NULL NULL 10
1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.X.a 1
2 SUBQUERY A ALL NULL NULL NULL NULL 10
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
create table t0 (a int, b int);
=== modified file 'mysql-test/r/subselect3_jcl6.result'
--- a/mysql-test/r/subselect3_jcl6.result 2010-03-29 14:04:35 +0000
+++ b/mysql-test/r/subselect3_jcl6.result 2010-04-05 20:16:45 +0000
@@ -1217,24 +1217,28 @@
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY A ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY A ALL NULL NULL NULL NULL 10
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.A.a 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1
2 SUBQUERY A ALL NULL NULL NULL NULL 10
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 10
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1
2 SUBQUERY A ALL NULL NULL NULL NULL 10
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
explain select straight_join * from t2 X, t2 Y
where X.a in (select straight_join A.a from t1 A, t1 B);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY X ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY X ALL NULL NULL NULL NULL 10
1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.X.a 1
2 SUBQUERY A ALL NULL NULL NULL NULL 10
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer
create table t0 (a int, b int);
=== modified file 'mysql-test/r/subselect_mat.result'
--- a/mysql-test/r/subselect_mat.result 2010-03-29 14:04:35 +0000
+++ b/mysql-test/r/subselect_mat.result 2010-04-05 20:16:45 +0000
@@ -38,10 +38,11 @@
explain extended
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 9 test.t1.a1 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` AS `b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0')) join `test`.`t1` where (`materialized subselect`.`b1` = `test`.`t1`.`a1`)
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -49,10 +50,11 @@
explain extended
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 9 test.t1.a1 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` AS `b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where (`materialized subselect`.`b1` = `test`.`t1`.`a1`)
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -60,10 +62,11 @@
explain extended
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`materialized subselect`.`b2` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -71,10 +74,11 @@
explain extended
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1` AS `b1`,min(`test`.`t2`.`b2`) AS `min(b2)` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`min(b2)`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1`,min(`test`.`t2`.`b2`) AS `min(b2)` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where ((`materialized subselect`.`min(b2)` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -82,10 +86,11 @@
explain extended
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
+1 PRIMARY t1i index it1i1,it1i3 it1i3 18 NULL 3 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 9 test.t1i.a1 1 100.00
2 SUBQUERY t2i index it2i1,it2i3 it2i1 9 NULL 5 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` AS `b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`)))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where (`materialized subselect`.`b1` = `test`.`t1i`.`a1`)
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -93,10 +98,11 @@
explain extended
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 3 100.00
+1 PRIMARY t1i ref it1i1,it1i3 it1i3 9 materialized subselect.b1 1 100.00 Using index
2 SUBQUERY t2i range it2i1,it2i3 it2i1 9 NULL 3 100.00 Using where; Using index for group-by
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` AS `b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`)))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where (`test`.`t1i`.`a1` = `materialized subselect`.`b1`)
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -104,10 +110,11 @@
explain extended
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
+1 PRIMARY t1i index it1i1,it1i2,it1i3 it1i3 18 NULL 3 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1i.a1,test.t1i.a2 1 100.00
2 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`)))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where ((`materialized subselect`.`b2` = `test`.`t1i`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1i`.`a1`))
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -115,10 +122,11 @@
explain extended
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 3 100.00
+1 PRIMARY t1i ref it1i1,it1i2,it1i3 it1i3 18 materialized subselect.b1,materialized subselect.b2 1 100.00 Using index
2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`)))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`test`.`t1i`.`a2` = `materialized subselect`.`b2`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`))
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -126,10 +134,11 @@
explain extended
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 3 100.00
+1 PRIMARY t1i ref it1i1,it1i2,it1i3 it1i3 18 materialized subselect.b1,materialized subselect.min(b2) 1 100.00 Using index
2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,min(`test`.`t2i`.`b2`) AS `min(b2)` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`min(b2)`)))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,min(`test`.`t2i`.`b2`) AS `min(b2)` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`test`.`t1i`.`a2` = `materialized subselect`.`min(b2)`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`))
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -137,10 +146,11 @@
explain extended
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,max(`test`.`t2i`.`b2`) AS `max(b2)` from `test`.`t2i` group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`max(b2)`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,max(`test`.`t2i`.`b2`) AS `max(b2)` from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`materialized subselect`.`max(b2)` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
a1 a2
1 - 01 2 - 01
@@ -148,11 +158,13 @@
prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
execute st1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1
2 SUBQUERY t2i range NULL it2i3 9 NULL 3 Using index for group-by
execute st1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1
2 SUBQUERY t2i range NULL it2i3 9 NULL 3 Using index for group-by
prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
execute st2;
@@ -166,10 +178,11 @@
explain extended
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,min(`test`.`t2i`.`b2`) AS `min(b2)` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`min(b2)`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,min(`test`.`t2i`.`b2`) AS `min(b2)` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`materialized subselect`.`min(b2)` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -206,10 +219,11 @@
explain extended
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`materialized subselect`.`b2` = `test`.`t1`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -217,10 +231,11 @@
explain extended
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
+1 PRIMARY t1i index it1i1,it1i2,it1i3 it1i3 18 NULL 3 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 18 test.t1i.a1,test.t1i.a2 1 100.00
2 SUBQUERY t2i index NULL it2i3 18 NULL 5 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`)))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`materialized subselect`.`b2` = `test`.`t1i`.`a2`) and (`materialized subselect`.`b1` = `test`.`t1i`.`a1`))
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -270,12 +285,15 @@
(a1, a2) in (select c1, c2 from t3
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 5 0.00
+1 PRIMARY SUBQUERY#3 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00
+3 SUBQUERY SUBQUERY#4 eq_ref distinct_key distinct_key 18 test.t3.c1,test.t3.c2 1 100.00
4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`))))) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key wh
ere ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0')) join `test`.`t1` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a1` = `materialized subselect`.`b1`))
select * from t1
where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
(a1, a2) in (select c1, c2 from t3
@@ -289,12 +307,15 @@
(a1, a2) in (select c1, c2 from t3i
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
-3 SUBQUERY t3i index NULL it3i3 18 NULL 4 100.00 Using where; Using index
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 5 0.00
+1 PRIMARY SUBQUERY#3 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
+1 PRIMARY t1i ref it1i1,it1i2,it1i3 it1i3 18 materialized subselect.b1,materialized subselect.c2 1 100.00 Using where; Using index
+3 SUBQUERY t3i index it3i1,it3i2,it3i3 it3i3 18 NULL 4 100.00 Using index
+3 SUBQUERY SUBQUERY#4 eq_ref distinct_key distinct_key 18 test.t3i.c1,test.t3i.c2 1 100.00
4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
2 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`))))) and <in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from `test`.`t3i` where <in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary
table> on distinct_key where ((`test`.`t3i`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3i`.`c2` = `materialized subselect`.`b2`))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`c2`))))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3i` where ((`materialized subselect`.`b2` = `test`.`t3i`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3i`.`c1`))) join <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`))
select * from t1i
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
(a1, a2) in (select c1, c2 from t3i
@@ -310,14 +331,17 @@
(a1, a2) in (select c1, c2 from t3
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 5 0.00
+1 PRIMARY SUBQUERY#5 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
+5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00
+5 SUBQUERY SUBQUERY#6 eq_ref distinct_key distinct_key 18 test.t3.c1,test.t3.c2 1 100.00
6 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materi
alized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`))))) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(
`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))))) join `test`.`t1` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a1` = `materialized subselect`.`b1`))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -335,14 +359,16 @@
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-5 SUBQUERY t3c ALL NULL NULL NULL NULL 4 100.00 Using where
+1 PRIMARY SUBQUERY#5 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
+5 SUBQUERY t3c ALL NULL NULL NULL NULL 4 100.00
+5 SUBQUERY SUBQUERY#6 eq_ref distinct_key distinct_key 18 test.t3c.c1,test.t3c.c2 1 100.00
6 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
4 SUBQUERY t3b ALL NULL NULL NULL NULL 4 100.00 Using where
3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 AS `Not_used` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`)))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` AS `c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3c`.`c1` AS `c1`,`test`.`t3c
`.`c2` AS `c2` from `test`.`t3` `t3c` where <in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),(`test`.`t3c`.`c1`,`test`.`t3c`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3c`.`c1` in <temporary table> on distinct_key where ((`test`.`t3c`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3c`.`c2` = `materialized subselect`.`b2`))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3c`.`c1` AS `c1`,`test`.`t3c`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` `t3c` where ((`materialized subselect`.`b2` = `test`.`t3c`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3c`.`c1`))) join `test`.`t1` where ((`materialized subselect`.`c2` = `test`.`t1`.`a2`) and (`materialized subselect`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 AS `Not_used` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`)))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` AS `c2` fr
om `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 t3a where c1 = a1) or
@@ -366,19 +392,25 @@
(a1, a2) in (select c1, c2 from t3i
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 5 0.00
+1 PRIMARY SUBQUERY#5 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
+5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00
+5 SUBQUERY SUBQUERY#6 eq_ref distinct_key distinct_key 18 test.t3.c1,test.t3.c2 1 100.00
6 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-7 UNION t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
-9 SUBQUERY t3i index NULL it3i3 18 NULL 4 100.00 Using where; Using index
+7 UNION SUBQUERY#8 ALL distinct_key NULL NULL NULL 5 0.00
+7 UNION SUBQUERY#9 eq_ref distinct_key distinct_key 18 materialized subselect.b1,materialized subselect.b2 1 100.00
+7 UNION t1i ref it1i1,it1i2,it1i3 it1i3 18 materialized subselect.b1,materialized subselect.c2 1 100.00 Using where; Using index
+9 SUBQUERY t3i index it3i1,it3i2,it3i3 it3i3 18 NULL 4 100.00 Using index
+9 SUBQUERY SUBQUERY#10 eq_ref distinct_key distinct_key 18 test.t3i.c1,test.t3i.c2 1 100.00
10 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
8 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
NULL UNION RESULT <union1,7> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on dis
tinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`))))) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`))))))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` A
S `a2` from `test`.`t1i` where (<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`))))) and <in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from `test`.`t3i` where <in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `materiali
zed subselect`.`b1`) and (`test`.`t3i`.`c2` = `materialized subselect`.`b2`))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`c2`)))))))
+Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join <materialize> (select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where (<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))) or <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` AS `c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>
(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a1` = `materialized subselect`.`b1`))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t3i`.`c1` AS `c1`,`test`.`t3i`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3i` where ((`materialized subselect`.`b2` = `test`.`t3i`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3i`.`c1`))) join <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0')) join `test`.`t1i
` where ((`materialized subselect`.`c2` = `materialized subselect`.`b2`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`) and (`materialized subselect`.`c1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a1` = `materialized subselect`.`b1`)))
(select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -401,13 +433,15 @@
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+1 PRIMARY SUBQUERY#4 eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
+4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00
+4 SUBQUERY SUBQUERY#5 eq_ref distinct_key distinct_key 18 test.t3.c1,test.t3.c2 1 100.00
5 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <p
rimary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join `test`.`t1` where ((`materialized subselect`.`c2` = `test`.`t1`.`a2`) and (`materialized subselect`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`t
est`.`t1`.`a2`) = `test`.`t2`.`b2`)))))
select * from t1
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
(a1, a2) in (select c1, c2 from t3
@@ -423,14 +457,16 @@
a1 = c1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY SUBQUERY#4 ALL distinct_key NULL NULL NULL 4 75.00 Using where; Using join buffer
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00
+4 SUBQUERY SUBQUERY#5 eq_ref distinct_key distinct_key 18 test.t3.c1,test.t3.c2 1 100.00
5 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))) and <in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (selec
t `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`))))) ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`c1`) and (`test`.`t3`.`c2` = `materialized subselect`.`c2`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from <materialize> (select `test`.`t2i`.`b1` AS `b1`,`test`.`t2i`.`b2` AS `b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0')) join `test`.`t3` where ((`materialized subselect`.`b2` = `test`.`t3`.`c2`) and (`materialized subselect`.`b1` = `test`.`t3`.`c1`))) join `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`c2` = `materialized subselect`.`c2`) and (`materialized subselect`.`c1` = `test`.`t1`.`a1`) and (`test`.`t3`.`c1` = `test`.`t1`.`a1`) and <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1` AS `b1`,`test`.`t2`.`b2` AS `b2` from `
test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`)))))
select * from t1, t3
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
(c1, c2) in (select c1, c2 from t3
@@ -608,10 +644,11 @@
from t1_16
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 20 test.t1_16.a1 1 100.00 Using where
2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select substr(`test`.`t2_16`.`b1`,1,16) AS `substring(b1,1,16)` from `test`.`t2_16` where (`test`.`t2_16`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `materialized subselect`.`substring(b1,1,16)`)))))
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from <materialize> (select substr(`test`.`t2_16`.`b1`,1,16) AS `substring(b1,1,16)` from `test`.`t2_16` where (`test`.`t2_16`.`b1` > '0')) join `test`.`t1_16` where (`test`.`t1_16`.`a1` = `materialized subselect`.`substring(b1,1,16)`)
select left(a1,7), left(a2,7)
from t1_16
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
@@ -637,10 +674,11 @@
from t1_16
where a1 in (select group_concat(b1) from t2_16 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_16.a1 1 100.00 Using where
2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select group_concat(`test`.`t2_16`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_16` group by `test`.`t2_16`.`b2` ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `materialized subselect`.`group_concat(b1)`)))))
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_16`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_16` group by `test`.`t2_16`.`b2`) join `test`.`t1_16` where (`test`.`t1_16`.`a1` = `materialized subselect`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_16
where a1 in (select group_concat(b1) from t2_16 group by b2);
@@ -660,9 +698,10 @@
2 DEPENDENT SUBQUERY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
3 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer
+3 DEPENDENT SUBQUERY SUBQUERY#4 eq_ref distinct_key distinct_key 9 test.t2.b1 1 100.00 Using where
4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select 1 AS `Not_used` from `test`.`t1_16` where (<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1` AS `b1`,`test`.`t2_16`.`b2` AS `b2` from `test`.`t2_16` join `test`.`t2` where ((`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and <in_optimizer>(`test`.`t2`.`b1`,`test`.`t2`.`b1` in ( <materialize> (select `test`.`t3`.`c1` AS `c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0') ), <primary_index_lookup>(`test`.`t2`.`b1` in <temporary table> on distinct_key where ((`test`.`t2`.`b1` = `materialized subselect`.`c1`))))) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))) and (<cache>(concat(`test`.`t1`.`a1`,'x')) = left(`test`.`t1_16`.`a1`,8)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select 1 AS `Not_used` from `test`.`t1_16` where (<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1` AS `b1`,`test`.`t2_16`.`b2` AS `b2` from <materialize> (select `test`.`t3`.`c1` AS `c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0')) join `test`.`t2_16` join `test`.`t2` where ((`materialized subselect`.`c1` = `test`.`t2`.`b1`) and (`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))) and (<cache>(concat(`test`.`t1`.`a1`,'x')) = left(`test`.`t1_16`.`a1`,8)))))
drop table t1_16, t2_16, t3_16;
set @blob_len = 512;
set @suffix_len = @blob_len - @prefix_len;
@@ -721,10 +760,11 @@
from t1_512
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 517 test.t1_512.a1 1 100.00 Using where
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select substr(`test`.`t2_512`.`b1`,1,512) AS `substring(b1,1,512)` from `test`.`t2_512` where (`test`.`t2_512`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `materialized subselect`.`substring(b1,1,512)`)))))
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (select substr(`test`.`t2_512`.`b1`,1,512) AS `substring(b1,1,512)` from `test`.`t2_512` where (`test`.`t2_512`.`b1` > '0')) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `materialized subselect`.`substring(b1,1,512)`)
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
@@ -735,10 +775,11 @@
from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_512.a1 1 100.00 Using where
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `materialized subselect`.`group_concat(b1)`)))))
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `materialized subselect`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
@@ -748,10 +789,11 @@
from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_512.a1 1 100.00 Using where
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `materialized subselect`.`group_concat(b1)`)))))
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `materialized subselect`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
@@ -817,7 +859,7 @@
1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in (select 1 AS `Not_used` from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = substr(`test`.`t2_1024`.`b1`,1,1024)))))
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <in_optimizer>(`test`.`t1_1024`.`a1`,<exists>(select 1 AS `Not_used` from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = substr(`test`.`t2_1024`.`b1`,1,1024)) and (<cache>(`test`.`t1_1024`.`a1`) = 1))))
select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
@@ -828,10 +870,11 @@
from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_1024.a1 1 100.00 Using where
2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `materialized subselect`.`group_concat(b1)`)))))
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = `materialized subselect`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
@@ -841,10 +884,11 @@
from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_1024.a1 1 100.00 Using where
2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `materialized subselect`.`group_concat(b1)`)))))
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = `materialized subselect`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
@@ -910,7 +954,7 @@
1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in (select 1 AS `Not_used` from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = substr(`test`.`t2_1025`.`b1`,1,1025)))))
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <in_optimizer>(`test`.`t1_1025`.`a1`,<exists>(select 1 AS `Not_used` from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = substr(`test`.`t2_1025`.`b1`,1,1025)) and (<cache>(`test`.`t1_1025`.`a1`) = 1))))
select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
@@ -921,10 +965,11 @@
from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_1025.a1 1 100.00 Using where
2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `materialized subselect`.`group_concat(b1)`)))))
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = `materialized subselect`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
@@ -934,10 +979,11 @@
from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 261 test.t1_1025.a1 1 100.00 Using where
2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
-Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `materialized subselect`.`group_concat(b1)`)))))
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') AS `group_concat(b1)` from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = `materialized subselect`.`group_concat(b1)`)
select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
@@ -956,10 +1002,11 @@
from t1bit
where (a1, a2) in (select b1, b2 from t2bit);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1bit ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1bit ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 10 test.t1bit.a1,test.t1bit.a2 1 100.00 Using where
2 SUBQUERY t2bit ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from `test`.`t1bit` where <in_optimizer>((`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`),(`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`) in ( <materialize> (select `test`.`t2bit`.`b1` AS `b1`,`test`.`t2bit`.`b2` AS `b2` from `test`.`t2bit` ), <primary_index_lookup>(`test`.`t1bit`.`a1` in <temporary table> on distinct_key where ((`test`.`t1bit`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1bit`.`a2` = `materialized subselect`.`b2`)))))
+Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from <materialize> (select `test`.`t2bit`.`b1` AS `b1`,`test`.`t2bit`.`b2` AS `b2` from `test`.`t2bit`) join `test`.`t1bit` where ((`test`.`t1bit`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1bit`.`a2` = `materialized subselect`.`b2`))
select bin(a1), bin(a2)
from t1bit
where (a1, a2) in (select b1, b2 from t2bit);
@@ -1027,10 +1074,11 @@
explain extended
select a from t1 where a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20)) join `test`.`t1` where (`materialized subselect`.`c` = `test`.`t1`.`a`)
select a from t1 where a in (select c from t2 where d >= 20);
a
2
@@ -1041,10 +1089,11 @@
explain extended
select a from t1 where a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
+1 PRIMARY t1 index it1a it1a 4 NULL 7 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20)) join `test`.`t1` where (`materialized subselect`.`c` = `test`.`t1`.`a`)
select a from t1 where a in (select c from t2 where d >= 20);
a
2
@@ -1055,10 +1104,11 @@
explain extended
select a from t1 where a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
+1 PRIMARY t1 index it1a it1a 4 NULL 7 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from <materialize> (select `test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`d` >= 20)) join `test`.`t1` where (`materialized subselect`.`c` = `test`.`t1`.`a`)
select a from t1 where a in (select c from t2 where d >= 20);
a
2
@@ -1138,10 +1188,12 @@
insert into t1 values (5);
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 5 const 1
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
min(a1)
+NULL
set @@optimizer_switch='default,materialization=off';
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
id select_type table type possible_keys key key_len ref rows Extra
@@ -1152,17 +1204,27 @@
set @@optimizer_switch='default,semijoin=off';
explain select min(a1) from t1 where 7 in (select b1 from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 5 const 1
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
select min(a1) from t1 where 7 in (select b1 from t2);
min(a1)
+NULL
set @@optimizer_switch='default,materialization=off';
+# with MariaDB and MWL#90, this particular case is solved:
explain select min(a1) from t1 where 7 in (select b1 from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
select min(a1) from t1 where 7 in (select b1 from t2);
min(a1)
NULL
+# but when we go around MWL#90 code, the problem still shows up:
+explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+min(a1)
drop table t1,t2;
create table t1 (a char(2), b varchar(10));
insert into t1 values ('a', 'aaa');
@@ -1170,7 +1232,8 @@
set @@optimizer_switch='default,semijoin=off';
explain select a,b from t1 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 3 test.t1.b 1 Using where
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
select a,b from t1 where b in (select a from t1);
a b
=== modified file 'mysql-test/r/subselect_no_semijoin.result'
--- a/mysql-test/r/subselect_no_semijoin.result 2010-03-20 12:01:47 +0000
+++ b/mysql-test/r/subselect_no_semijoin.result 2010-04-05 20:16:45 +0000
@@ -1299,31 +1299,34 @@
4
explain extended select * from t2 where t2.a in (select a from t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 4 100.00
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer
2 SUBQUERY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1`) join `test`.`t2` where (`test`.`t2`.`a` = `materialized subselect`.`a`)
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
2
4
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
+1 PRIMARY SUBQUERY#2 ALL distinct_key NULL NULL NULL 4 100.00
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30)) join `test`.`t2` where (`test`.`t2`.`a` = `materialized subselect`.`a`)
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
3
explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 4 test.t2.a 1 100.00
2 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`)) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
drop table t1, t2, t3;
create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a));
@@ -1342,31 +1345,34 @@
4
explain extended select * from t2 where t2.a in (select a from t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1 100.00
2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1`) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
2
4
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1 100.00
2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30)) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
3
explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1 100.00
2 SUBQUERY t3 index a a 5 NULL 3 100.00 Using index
2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index; Using join buffer
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`)) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -1379,10 +1385,11 @@
4
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using index
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.a 1 100.00
2 SUBQUERY t1 index NULL a 10 NULL 10005 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from <materialize> (select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`b` <> 30)) join `test`.`t2` where (`materialized subselect`.`a` = `test`.`t2`.`a`)
drop table t0, t1, t2, t3;
create table t1 (a int, b int);
create table t2 (a int, b int);
@@ -2833,10 +2840,11 @@
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 10 test.t1.one,test.t1.two 1 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),(`test`.`t1`.`one`,`test`.`t1`.`two`) in ( <materialize> (select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where (`test`.`t2`.`flag` = 'N') ), <primary_index_lookup>(`test`.`t1`.`one` in <temporary table> on distinct_key where ((`test`.`t1`.`one` = `materialized subselect`.`one`) and (`test`.`t1`.`two` = `materialized subselect`.`two`)))))
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from <materialize> (select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where (`test`.`t2`.`flag` = 'N')) join `test`.`t1` where ((`materialized subselect`.`two` = `test`.`t1`.`two`) and (`materialized subselect`.`one` = `test`.`t1`.`one`))
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
@@ -3421,7 +3429,8 @@
EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
@@ -3432,7 +3441,8 @@
EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY t1 ALL a NULL NULL NULL 9
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
DROP TABLE t1;
create table t1( f1 int,f2 int);
@@ -4206,7 +4216,8 @@
CREATE INDEX I2 ON t1 (b);
EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 2 test.t1.b 1 Using where
2 SUBQUERY t1 index NULL I1 2 NULL 2 Using index
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
a b
@@ -4216,14 +4227,16 @@
CREATE INDEX I2 ON t2 (b);
EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL I2 NULL NULL NULL 2
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 5 test.t2.b 1 Using where
2 SUBQUERY t2 index NULL I1 4 NULL 2 Using index
SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
a b
EXPLAIN
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2
+1 PRIMARY SUBQUERY#2 eq_ref distinct_key distinct_key 2 test.t1.b 1 Using where
2 SUBQUERY t1 index NULL I1 2 NULL 2 Using where; Using index
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
a b
@@ -4326,16 +4339,18 @@
INSERT INTO t1 VALUES (1),(2);
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 4 const 1 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,1 in ( <materialize> (select 1 AS `1` from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`)))))
+Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`materialized subselect`.`1` = 1)
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY SUBQUERY#2 const distinct_key distinct_key 4 const 1 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,1 in ( <materialize> (select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`)))))
+Note 1003 select 1 AS `1` from <materialize> (select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`materialized subselect`.`1` = 1)
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
=== modified file 'mysql-test/suite/parts/r/partition_alter3_innodb.result'
--- a/mysql-test/suite/parts/r/partition_alter3_innodb.result 2008-11-12 17:51:47 +0000
+++ b/mysql-test/suite/parts/r/partition_alter3_innodb.result 2010-04-05 20:16:45 +0000
@@ -141,7 +141,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 7 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -165,7 +165,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -190,7 +190,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 3 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -226,7 +226,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 3 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -248,7 +248,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -269,7 +269,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -289,7 +289,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -308,7 +308,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 7 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -326,7 +326,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 10 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -452,7 +452,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 7 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -476,7 +476,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 5 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -504,7 +504,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 3 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -538,7 +538,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -563,7 +563,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 3 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -587,7 +587,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 23 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 10 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -610,7 +610,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 5 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -632,7 +632,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 7 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -653,7 +653,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 10 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
=== modified file 'mysql-test/suite/parts/r/partition_alter3_myisam.result'
--- a/mysql-test/suite/parts/r/partition_alter3_myisam.result 2008-11-12 17:51:47 +0000
+++ b/mysql-test/suite/parts/r/partition_alter3_myisam.result 2010-04-05 20:16:45 +0000
@@ -155,7 +155,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 7 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -187,7 +187,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -228,7 +228,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 3 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -278,7 +278,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 3 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -312,7 +312,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -343,7 +343,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -371,7 +371,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -396,7 +396,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 7 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -418,7 +418,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10';
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 10 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -552,7 +552,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 7 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -584,7 +584,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 5 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -628,7 +628,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 3 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -676,7 +676,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -713,7 +713,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 3 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -747,7 +747,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 10 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -778,7 +778,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 5 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -806,7 +806,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 7 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
@@ -831,7 +831,7 @@
t1.par
EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where
+1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 10 Using where
# check read single success: 1
# check read all success: 1
# check read row by row success: 1
=== modified file 'mysql-test/t/subselect_mat.test'
--- a/mysql-test/t/subselect_mat.test 2010-03-13 20:04:52 +0000
+++ b/mysql-test/t/subselect_mat.test 2010-04-05 20:16:45 +0000
@@ -829,8 +829,12 @@
# This is the only correct result of all four queries. This difference is
# filed as BUG#40037.
set @@optimizer_switch='default,materialization=off';
+-- echo # with MariaDB and MWL#90, this particular case is solved:
explain select min(a1) from t1 where 7 in (select b1 from t2);
select min(a1) from t1 where 7 in (select b1 from t2);
+-- echo # but when we go around MWL#90 code, the problem still shows up:
+explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
drop table t1,t2;
#
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2010-03-29 14:04:35 +0000
+++ b/sql/item_subselect.cc 2010-04-05 20:16:45 +0000
@@ -468,6 +468,12 @@
return (res);
}
+int Item_subselect::optimize()
+{
+ int res;
+ res= engine->optimize();
+ return res;
+}
/*
Compute the IN predicate if the left operand's cache changed.
@@ -2088,7 +2094,7 @@
@retval FALSE an execution method was chosen successfully
*/
-bool Item_in_subselect::setup_engine()
+bool Item_in_subselect::setup_engine(bool dont_switch_arena)
{
subselect_hash_sj_engine *new_engine= NULL;
bool res= FALSE;
@@ -2103,7 +2109,7 @@
old_engine= (subselect_single_select_engine*) engine;
- if (arena->is_conventional())
+ if (arena->is_conventional() || dont_switch_arena)
arena= 0;
else
thd->set_n_backup_active_arena(arena, &backup);
@@ -3457,7 +3463,7 @@
bitmap_set_bit(&partial_match_key_parts, i);
++count_partial_match_columns;
}
- }
+ };
}
/* If no column contains NULLs use regular hash index lookups. */
@@ -3970,6 +3976,17 @@
}
+int subselect_hash_sj_engine::optimize()
+{
+ int res= 0;
+ SELECT_LEX *save_select= thd->lex->current_select;
+ thd->lex->current_select= materialize_join->select_lex;
+ res= materialize_join->optimize();
+ thd->lex->current_select= save_select;
+
+ return res;
+}
+
/**
Execute a subquery IN predicate via materialization.
=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h 2010-03-29 14:04:35 +0000
+++ b/sql/item_subselect.h 2010-04-05 20:16:45 +0000
@@ -52,9 +52,9 @@
public:
/* unit of subquery */
st_select_lex_unit *unit;
-protected:
/* engine that perform execution of subselect (single select or union) */
subselect_engine *engine;
+protected:
/* old engine if engine was changed */
subselect_engine *old_engine;
/* cache of used external tables */
@@ -139,6 +139,7 @@
bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item);
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
void recalc_used_tables(st_select_lex *new_parent, bool after_pullout);
+ virtual int optimize();
virtual bool exec();
virtual void fix_length_and_dec();
table_map used_tables() const;
@@ -333,7 +334,9 @@
all JOIN in UNION
*/
Item *expr;
+public:
Item_in_optimizer *optimizer;
+protected:
bool was_null;
bool abort_on_null;
public:
@@ -379,6 +382,10 @@
};
enum_exec_method exec_method;
+ /* JTBM: temporary measure to tell JTBM predicates from SJ predicates */
+ bool convert_to_semi_join;
+ double startup_cost;
+
bool *get_cond_guard(int i)
{
return pushed_cond_guards ? pushed_cond_guards + i : NULL;
@@ -428,7 +435,7 @@
bool fix_fields(THD *thd, Item **ref);
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
void update_used_tables();
- bool setup_engine();
+ bool setup_engine(bool dont_switch_arena);
bool init_left_expr_cache();
/* Inform 'this' that it was computed, and contains a valid result. */
void set_first_execution() { if (first_execution) first_execution= FALSE; }
@@ -502,6 +509,7 @@
THD * get_thd() { return thd; }
virtual int prepare()= 0;
virtual void fix_length_and_dec(Item_cache** row)= 0;
+ virtual int optimize() { DBUG_ASSERT(0); return 0; }
/*
Execute the engine
@@ -734,7 +742,7 @@
class subselect_hash_sj_engine : public subselect_engine
{
-protected:
+public:
/* The table into which the subquery is materialized. */
TABLE *tmp_table;
/* TRUE if the subquery was materialized into a temp table. */
@@ -746,14 +754,16 @@
of subselect_single_select_engine::[prepare | cols].
*/
subselect_single_select_engine *materialize_engine;
+protected:
/* The engine used to compute the IN predicate. */
subselect_engine *lookup_engine;
/*
QEP to execute the subquery and materialize its result into a
temporary table. Created during the first call to exec().
*/
+public:
JOIN *materialize_join;
-
+protected:
/* Keyparts of the only non-NULL composite index in a rowid merge. */
MY_BITMAP non_null_key_parts;
/* Keyparts of the single column indexes with NULL, one keypart per index. */
@@ -766,7 +776,9 @@
IN results because index lookups sometimes match values that are actually
not equal to the search key in SQL terms.
*/
+public:
Item_cond_and *semi_join_conds;
+protected:
/* Possible execution strategies that can be used to compute hash semi-join.*/
enum exec_strategy {
UNDEFINED,
@@ -806,6 +818,7 @@
bool init_runtime();
void cleanup();
int prepare() { return 0; } /* Override virtual function in base class. */
+ int optimize();
int exec();
virtual void print(String *str, enum_query_type query_type);
uint cols()
=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc 2010-03-20 12:01:47 +0000
+++ b/sql/opt_range.cc 2010-04-05 20:16:45 +0000
@@ -2285,7 +2285,7 @@
quick=0;
needed_reg.clear_all();
quick_keys.clear_all();
- if (keys_to_use.is_clear_all())
+ if (keys_to_use.is_clear_all() || head->pos_in_table_list->jtbm_subselect)
DBUG_RETURN(0);
records= head->file->stats.records;
if (!records)
=== modified file 'sql/opt_subselect.cc'
--- a/sql/opt_subselect.cc 2010-03-15 19:52:58 +0000
+++ b/sql/opt_subselect.cc 2010-04-05 20:16:45 +0000
@@ -25,6 +25,8 @@
static int subq_sj_candidate_cmp(Item_in_subselect* const *el1,
Item_in_subselect* const *el2);
static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred);
+static bool convert_subq_to_jtbm(JOIN *parent_join,
+ Item_in_subselect *subq_pred, bool *remove);
static TABLE_LIST *alloc_join_nest(THD *thd);
static
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist);
@@ -166,6 +168,7 @@
(void)subquery_types_allow_materialization(in_subs);
in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
+ in_subs->convert_to_semi_join= TRUE; //JTBM
/* Register the subquery for further processing in flatten_subqueries() */
select_lex->
@@ -220,10 +223,21 @@
(in_subs->is_top_level_item() ||
optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) ||
optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) &&//4
- !in_subs->is_correlated && // 5
- in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED) // 6
+ !in_subs->is_correlated) // 5
{
+ if (in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED)
in_subs->exec_method= Item_in_subselect::MATERIALIZATION;
+
+ // psergey-jtbm: "if we're top-level, register for
+ // conversion-to-join-tab".
+ if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION &&
+ thd->thd_marker.emb_on_expr_nest == (TABLE_LIST*)0x1)
+ {
+ in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
+ in_subs->convert_to_semi_join= FALSE; //JTBM
+ select_lex->outer_select()->
+ join->sj_subselects.append(thd->mem_root, in_subs);//JTBM
+ }
}
Item_subselect::trans_res trans_res;
@@ -338,6 +352,60 @@
}
+static bool make_in_exists_conversion(THD *thd, JOIN *join, Item_in_subselect *item)
+{
+ DBUG_ENTER("make_in_exists_conversion");
+ JOIN *child_join= item->unit->first_select()->join;
+ Item_subselect::trans_res res;
+ item->changed= 0;
+ item->fixed= 0;
+
+ SELECT_LEX *save_select_lex= thd->lex->current_select;
+ thd->lex->current_select= item->unit->first_select();
+
+ res= item->select_transformer(child_join);
+
+ thd->lex->current_select= save_select_lex;
+
+ if (res == Item_subselect::RES_ERROR)
+ DBUG_RETURN(TRUE);
+
+ item->changed= 1;
+ item->fixed= 1;
+
+ Item *substitute= item->substitution;
+ bool do_fix_fields= !item->substitution->fixed;
+ Item **tree= (item->emb_on_expr_nest == (TABLE_LIST*)1)?
+ &join->conds : &(item->emb_on_expr_nest->on_expr);
+
+ Item *replace_me= item;
+ /*
+ JTBM: the subquery was already mapped with Item_in_optimizer, so we
+ should search for that, not for original Item_in_subselect.
+ TODO: what about delaying that rewrite until here?
+ */
+ if (!item->convert_to_semi_join)
+ {
+ replace_me= item->optimizer;
+ }
+
+ if (replace_where_subcondition(join, tree, replace_me, substitute,
+ do_fix_fields))
+ DBUG_RETURN(TRUE);
+ item->substitution= NULL;
+
+ if (!thd->stmt_arena->is_conventional())
+ {
+ tree= (item->emb_on_expr_nest == (TABLE_LIST*)1)?
+ &join->select_lex->prep_where :
+ &(item->emb_on_expr_nest->prep_on_expr);
+
+ if (replace_where_subcondition(join, tree, replace_me, substitute,
+ FALSE))
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_RETURN(FALSE);
+}
/*
Convert semi-join subquery predicates into semi-join join nests
@@ -445,6 +513,7 @@
// #tables-in-parent-query + #tables-in-subquery < MAX_TABLES
/* Replace all subqueries to be flattened with Item_int(1) */
arena= thd->activate_stmt_arena_if_needed(&backup);
+#if 0
for (in_subq= join->sj_subselects.front();
in_subq != in_subq_end &&
join->tables + (*in_subq)->unit->first_select()->join->tables < MAX_TABLES;
@@ -452,18 +521,58 @@
{
Item **tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
&join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
- if (replace_where_subcondition(join, tree, *in_subq, new Item_int(1),
+ Item *replace_me= *in_subq;
+ /*
+ JTBM: the subquery was already mapped with Item_in_optimizer, so we
+ should search for that, not for original Item_in_subselect.
+ TODO: what about delaying that rewrite until here?
+ */
+ if (!(*in_subq)->convert_to_semi_join)
+ {
+ replace_me= (*in_subq)->optimizer;
+ }
+ if (replace_where_subcondition(join, tree, replace_me, new Item_int(1),
FALSE))
DBUG_RETURN(TRUE); /* purecov: inspected */
}
+#endif
for (in_subq= join->sj_subselects.front();
in_subq != in_subq_end &&
join->tables + (*in_subq)->unit->first_select()->join->tables < MAX_TABLES;
in_subq++)
{
- if (convert_subq_to_sj(join, *in_subq))
- DBUG_RETURN(TRUE);
+ bool remove_item= TRUE;
+ //psergey-jtbm: todo: here: check if we should convert to semi-join or
+ // to JTBM nest.
+ if ((*in_subq)->convert_to_semi_join)
+ {
+ if (convert_subq_to_sj(join, *in_subq))
+ DBUG_RETURN(TRUE);
+ }
+ else
+ {
+ if (convert_subq_to_jtbm(join, *in_subq, &remove_item))
+ DBUG_RETURN(TRUE);
+ }
+ if (remove_item)
+ {
+ Item **tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
+ &join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
+ Item *replace_me= *in_subq;
+ /*
+ JTBM: the subquery was already mapped with Item_in_optimizer, so we
+ should search for that, not for original Item_in_subselect.
+ TODO: what about delaying that rewrite until here?
+ */
+ if (!(*in_subq)->convert_to_semi_join)
+ {
+ replace_me= (*in_subq)->optimizer;
+ }
+ if (replace_where_subcondition(join, tree, replace_me, new Item_int(1),
+ FALSE))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ }
}
skip_conversion:
/*
@@ -494,7 +603,19 @@
bool do_fix_fields= !(*in_subq)->substitution->fixed;
Item **tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
&join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
- if (replace_where_subcondition(join, tree, *in_subq, substitute,
+
+ Item *replace_me= *in_subq;
+ /*
+ JTBM: the subquery was already mapped with Item_in_optimizer, so we
+ should search for that, not for original Item_in_subselect.
+ TODO: what about delaying that rewrite until here?
+ */
+ if (!(*in_subq)->convert_to_semi_join)
+ {
+ replace_me= (*in_subq)->optimizer;
+ }
+
+ if (replace_where_subcondition(join, tree, replace_me, substitute,
do_fix_fields))
DBUG_RETURN(TRUE);
(*in_subq)->substitution= NULL;
@@ -505,7 +626,7 @@
&join->select_lex->prep_where :
&((*in_subq)->emb_on_expr_nest->prep_on_expr);
- if (replace_where_subcondition(join, tree, *in_subq, substitute,
+ if (replace_where_subcondition(join, tree, replace_me, substitute,
FALSE))
DBUG_RETURN(TRUE);
}
@@ -517,6 +638,36 @@
DBUG_RETURN(FALSE);
}
+
+void get_temptable_params(Item_in_subselect *item, ha_rows *out_rows,
+ ha_rows *scan_time)
+{
+ item->optimize();
+
+ DBUG_ASSERT(item->engine->engine_type() ==
+ subselect_engine::HASH_SJ_ENGINE);
+
+ subselect_hash_sj_engine *hash_sj_engine=
+ ((subselect_hash_sj_engine*)item->engine);
+ JOIN *join= hash_sj_engine->materialize_join;
+
+ double rows= 1;
+ double read_time= 0.0;
+
+ /* Calculate #rows and cost of join execution */
+ for (uint i= join->const_tables; i < join->tables; i++)
+ {
+ rows *= join->best_positions[i].records_read;
+ read_time += join->best_positions[i].read_time;
+ }
+ *out_rows= rows;
+ item->startup_cost= read_time;
+ /* Calculate cost of scanning the temptable */
+ double data_size= rows * hash_sj_engine->tmp_table->s->reclength;
+ /* Do like in handler::read_time */
+ *scan_time= data_size/IO_SIZE + 2;
+}
+
/**
@brief Replaces an expression destructively inside the expression tree of
the WHERE clase.
@@ -887,6 +1038,114 @@
DBUG_RETURN(FALSE);
}
+
+static bool convert_subq_to_jtbm(JOIN *parent_join,
+ Item_in_subselect *subq_pred,
+ bool *remove_item)
+{
+ SELECT_LEX *parent_lex= parent_join->select_lex;
+ List<TABLE_LIST> *emb_join_list= &parent_lex->top_join_list;
+ TABLE_LIST *emb_tbl_nest= NULL; // will change when we learn to handle outer joins
+ TABLE_LIST *tl;//, *last_leaf;
+ DBUG_ENTER("convert_subq_to_jtbm");
+
+ if (subq_pred->setup_engine(TRUE))
+ DBUG_RETURN(TRUE);
+
+ if (subq_pred->engine->engine_type() != subselect_engine::HASH_SJ_ENGINE)
+ {
+ *remove_item= FALSE;
+ make_in_exists_conversion(parent_join->thd, parent_join, subq_pred);
+ DBUG_RETURN(FALSE);
+ }
+ *remove_item= TRUE;
+
+ TABLE_LIST *jtbm;
+ char *tbl_alias;
+ const char alias_mask[]="SUBQUERY#%d";
+ if (!(tbl_alias= (char*)parent_join->thd->calloc(sizeof(alias_mask)+5)) ||
+ !(jtbm= alloc_join_nest(parent_join->thd))) //todo: this is not a join nest!
+ {
+ DBUG_RETURN(TRUE);
+ }
+
+ jtbm->join_list= emb_join_list;
+ jtbm->embedding= emb_tbl_nest;
+ jtbm->alias= (char*)"(jtbm)";
+ jtbm->jtbm_subselect= subq_pred;
+ jtbm->nested_join= NULL;
+
+ /* Nests do not participate in those 'chains', so: */
+ /* jtbm->next_leaf= jtbm->next_local= jtbm->next_global == NULL*/
+ emb_join_list->push_back(jtbm);
+
+ /* Inject ourselves into next-leaf list */
+ /*
+ JTBM: Inject us into next_leaf and lext_local chains..
+ so that make_join_statistics et al find us.
+ */
+
+ /*
+ Reconnect the next_leaf chain.
+ TODO: Do we have to put subquery's tables at the end of the chain?
+ Inserting them at the beginning would be a bit faster.
+ NOTE: We actually insert them at the front! That's because the order is
+ reversed in this list.
+ */
+ for (tl= parent_lex->leaf_tables; tl->next_leaf; tl= tl->next_leaf) ;
+ tl->next_leaf= jtbm;
+
+ /*
+ Same as above for next_local chain
+ (a theory: a next_local chain always starts with ::leaf_tables
+ because view's tables are inserted after the view)
+ */
+ for (tl= parent_lex->leaf_tables; tl->next_local; tl= tl->next_local) ;
+ tl->next_local= jtbm;
+
+ /* A theory: no need to re-connect the next_global chain */
+
+ subselect_hash_sj_engine *hash_sj_engine=
+ ((subselect_hash_sj_engine*)subq_pred->engine);
+ jtbm->table= hash_sj_engine->tmp_table;
+
+ jtbm->table->tablenr= parent_join->tables;
+ jtbm->table->map= table_map(1) << (parent_join->tables);
+
+ parent_join->tables++;
+
+ Item *conds= hash_sj_engine->semi_join_conds;
+ conds->fix_after_pullout(parent_lex, &conds);
+
+ DBUG_EXECUTE("where", print_where(conds,"SJ-EXPR", QT_ORDINARY););
+
+ my_snprintf(tbl_alias, sizeof(alias_mask)+5, alias_mask,
+ hash_sj_engine->materialize_join->select_lex->select_number);
+ jtbm->alias= tbl_alias;
+
+ /* Inject sj_on_expr into the parent's WHERE or ON */
+ if (emb_tbl_nest)
+ {
+ DBUG_ASSERT(0);
+ /*emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr,
+ sj_nest->sj_on_expr);
+ emb_tbl_nest->on_expr->fix_fields(parent_join->thd, &emb_tbl_nest->on_expr);
+ */
+ }
+ else
+ {
+ /* Inject into the WHERE */
+ parent_join->conds= and_items(parent_join->conds, conds);
+ parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
+ parent_join->select_lex->where= parent_join->conds;
+ }
+
+ /* Don't unlink the child, the subquery is still there and used */
+
+ DBUG_RETURN(FALSE);
+}
+
+
static TABLE_LIST *alloc_join_nest(THD *thd)
{
TABLE_LIST *tbl;
@@ -3503,4 +3762,26 @@
}
}
+int do_jtbm_materialization_if_needed(JOIN_TAB *tab)
+{
+ Item_in_subselect *in_subs;
+ if (tab->table->pos_in_table_list &&
+ (in_subs= tab->table->pos_in_table_list->jtbm_subselect))
+ {
+ DBUG_ASSERT(in_subs->engine->engine_type() ==
+ subselect_engine::HASH_SJ_ENGINE);
+
+ subselect_hash_sj_engine *hash_sj_engine=
+ ((subselect_hash_sj_engine*)in_subs->engine);
+ if (!hash_sj_engine->is_materialized)
+ {
+ hash_sj_engine->materialize_join->exec();
+ hash_sj_engine->is_materialized= TRUE;
+
+ if (hash_sj_engine->materialize_join->error || tab->join->thd->is_fatal_error)
+ return 1;
+ }
+ }
+ return 0;
+}
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2010-03-20 12:01:47 +0000
+++ b/sql/sql_base.cc 2010-04-05 20:16:45 +0000
@@ -7661,6 +7661,17 @@
if (res)
DBUG_RETURN(1);
}
+ if (table_list->jtbm_subselect)
+ {
+ Item *item= table_list->jtbm_subselect;
+ if (item->fix_fields(thd, &item))
+ {
+ my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
+ DBUG_RETURN(1);
+ }
+ DBUG_ASSERT(item == table_list->jtbm_subselect);
+ table_list->jtbm_subselect->setup_engine(FALSE);
+ }
}
/* Precompute and store the row types of NATURAL/USING joins. */
=== modified file 'sql/sql_join_cache.cc'
--- a/sql/sql_join_cache.cc 2010-03-07 15:41:45 +0000
+++ b/sql/sql_join_cache.cc 2010-04-05 20:16:45 +0000
@@ -33,6 +33,7 @@
#define NO_MORE_RECORDS_IN_BUFFER (uint)(-1)
+int do_jtbm_materialization_if_needed(JOIN_TAB *tab);
/*****************************************************************************
* Join cache module
@@ -1778,6 +1779,10 @@
}
/* Start retrieving all records of the joined table */
+
+ //jtbm-todo: error handling!
+ do_jtbm_materialization_if_needed(join_tab);
+
if ((error= join_init_read_record(join_tab)))
{
rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2010-03-29 20:09:40 +0000
+++ b/sql/sql_select.cc 2010-04-05 20:16:45 +0000
@@ -243,6 +243,10 @@
Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
bool *inherited_fl);
+void get_temptable_params(Item_in_subselect *item, ha_rows *out_rows,
+ ha_rows *scan_time);
+int do_jtbm_materialization_if_needed(JOIN_TAB *tab);
+
/**
This handles SELECT with and without UNION.
*/
@@ -2445,7 +2449,7 @@
{
Item_in_subselect *in_subs= (Item_in_subselect*) subquery_predicate;
if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION &&
- in_subs->setup_engine())
+ in_subs->setup_engine(FALSE))
return TRUE;
}
}
@@ -2531,9 +2535,10 @@
DBUG_ENTER("make_join_statistics");
table_count=join->tables;
- stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*table_count);
+
+ stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*(table_count));
stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
- table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
+ table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*((table_count)*2));
if (!stat || !stat_ref || !table_vector)
DBUG_RETURN(1); // Eom /* purecov: inspected */
@@ -2542,7 +2547,7 @@
stat_end=stat+table_count;
found_const_table_map= all_table_map=0;
const_count=0;
-
+
for (s= stat, i= 0;
tables;
s++, tables= tables->next_leaf, i++)
@@ -2565,7 +2570,7 @@
table->reginfo.join_tab=s;
table->reginfo.not_exists_optimize=0;
bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->s->keys);
- all_table_map|= table->map;
+ all_table_map|= s->table->map;
s->join=join;
s->info=0; // For describe
@@ -2574,15 +2579,17 @@
if (tables->schema_table)
table->file->stats.records= 2;
table->quick_condition_rows= table->file->stats.records;
-
+
s->on_expr_ref= &tables->on_expr;
if (*s->on_expr_ref)
{
/* s is the only inner table of an outer join */
#ifdef WITH_PARTITION_STORAGE_ENGINE
- if ((!table->file->stats.records || table->no_partitions_used) && !embedding)
+ if (!table->pos_in_table_list->jtbm_subselect &&
+ (!table->file->stats.records || table->no_partitions_used) && !embedding)
#else
- if (!table->file->stats.records && !embedding)
+ if (!table->pos_in_table_list->jtbm_subselect &&
+ !table->file->stats.records && !embedding)
#endif
{ // Empty table
s->dependent= 0; // Ignore LEFT JOIN depend.
@@ -2616,7 +2623,8 @@
#else
const bool no_partitions_used= FALSE;
#endif
- if ((table->s->system || table->file->stats.records <= 1 ||
+ if (!table->pos_in_table_list->jtbm_subselect &&
+ (table->s->system || table->file->stats.records <= 1 ||
no_partitions_used) &&
!s->dependent &&
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
@@ -2626,6 +2634,8 @@
no_rows_const_tables |= table->map;
}
}
+ //psergey-todo: inject jtbm JOIN_TABS here.
+
stat_vector[i]=0;
join->outer_join=outer_join;
@@ -2714,6 +2724,9 @@
{
table=s->table;
+ if (table->pos_in_table_list->jtbm_subselect)
+ continue;
+
/*
If equi-join condition by a key is null rejecting and after a
substitution of a const table the key value happens to be null
@@ -2873,8 +2886,21 @@
continue;
}
/* Approximate found rows and time to read them */
- s->found_records=s->records=s->table->file->stats.records;
- s->read_time=(ha_rows) s->table->file->scan_time();
+
+ if (s->table->pos_in_table_list->jtbm_subselect)
+ {
+ get_temptable_params(s->table->pos_in_table_list->jtbm_subselect,
+ &s->records,
+ &s->read_time);
+ s->found_records= s->records;
+ table->quick_condition_rows=s->records;
+ }
+ else
+ {
+ s->found_records=s->records=s->table->file->stats.records;
+ s->read_time=(ha_rows) s->table->file->scan_time();
+ }
+
/*
Set a max range of how many seeks we can expect when using keys
@@ -2897,10 +2923,11 @@
Don't do range analysis if we're on the inner side of an outer join (2).
Do range analysis if we're on the inner side of a semi-join (3).
*/
- if (!s->const_keys.is_clear_all() && // (1)
- (!s->table->pos_in_table_list->embedding || // (2)
- (s->table->pos_in_table_list->embedding && // (3)
- s->table->pos_in_table_list->embedding->sj_on_expr))) // (3)
+ if (!s->const_keys.is_clear_all() && // (1)
+ (!s->table->pos_in_table_list->embedding || // (2)
+ (s->table->pos_in_table_list->embedding && // (3)
+ s->table->pos_in_table_list->embedding->sj_on_expr)) && // (3)
+ !s->table->pos_in_table_list->jtbm_subselect)
{
ha_rows records;
SQL_SELECT *select;
@@ -4265,6 +4292,8 @@
double tmp;
ha_rows rec;
bool best_uses_jbuf= FALSE;
+ Item_in_subselect* jtbm_subselect= s->table->pos_in_table_list->jtbm_subselect;
+ bool jtbm_ref_used= FALSE;
Loose_scan_opt loose_scan_opt;
DBUG_ENTER("best_access_path");
@@ -4617,8 +4646,9 @@
else
tmp= best_time; // Do nothing
}
+ if (jtbm_subselect)
+ tmp += jtbm_subselect->startup_cost;
loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp);
-
} /* not ft_key */
if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
{
@@ -4628,6 +4658,8 @@
best_key= start_key;
best_max_key_part= max_key_part;
best_ref_depends_map= found_ref;
+ if (jtbm_subselect)
+ jtbm_ref_used= TRUE;
}
} /* for each key */
records= best_records;
@@ -4666,7 +4698,8 @@
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
!((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3)
! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3)
- !(s->table->force_index && best_key && !s->quick)) // (4)
+ !(s->table->force_index && best_key && !s->quick) && // (4)
+ !jtbm_ref_used)
{ // Check full join
ha_rows rnd_records= s->found_records;
/*
@@ -4714,7 +4747,11 @@
else
{
/* Estimate cost of reading table. */
- tmp= s->table->file->scan_time();
+ if (jtbm_subselect)
+ tmp= s->read_time;
+ else
+ tmp= s->table->file->scan_time();
+
if ((s->table->map & join->outer_join) || disable_jbuf) // Can't use join cache
{
/*
@@ -4743,6 +4780,8 @@
}
}
+ if (jtbm_subselect)
+ tmp += jtbm_subselect->startup_cost;
/*
We estimate the cost of evaluating WHERE clause for found records
as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
@@ -7684,6 +7723,12 @@
table->file->extra(HA_EXTRA_NO_KEYREAD);
}
table->file->ha_index_or_rnd_end();
+ //psergey-jtbm2:
+ if (table->pos_in_table_list &&
+ table->pos_in_table_list->jtbm_subselect)
+ {
+ table->pos_in_table_list->jtbm_subselect->cleanup();
+ }
/*
We need to reset this for next select
(Tested in part_of_refkey)
@@ -11396,6 +11441,8 @@
share->keys=1;
share->uniques= test(using_unique_constraint);
table->key_info= table->s->key_info= keyinfo;
+ table->keys_in_use_for_query.set_bit(0);
+ share->keys_in_use.set_bit(0);
keyinfo->key_part=key_part_info;
keyinfo->flags=HA_NOSAME;
keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
@@ -11411,6 +11458,8 @@
bool maybe_null=(*cur_group->item)->maybe_null;
key_part_info->null_bit=0;
key_part_info->field= field;
+ if (cur_group == group)
+ field->key_start.set_bit(0);
key_part_info->offset= field->offset(table->record[0]);
key_part_info->length= (uint16) field->key_length();
key_part_info->type= (uint8) field->key_type();
@@ -11481,6 +11530,8 @@
keyinfo->key_parts * sizeof(KEY_PART_INFO))))
goto err;
bzero((void*) key_part_info, keyinfo->key_parts * sizeof(KEY_PART_INFO));
+ table->keys_in_use_for_query.set_bit(0);
+ share->keys_in_use.set_bit(0);
table->key_info= table->s->key_info= keyinfo;
keyinfo->key_part=key_part_info;
keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
@@ -11519,6 +11570,14 @@
{
key_part_info->null_bit=0;
key_part_info->field= *reg_field;
+ //psergey-jtbm:
+ (*reg_field)->flags |= PART_KEY_FLAG;
+ if (key_part_info == keyinfo->key_part)
+ (*reg_field)->key_start.set_bit(0);
+ key_part_info->null_bit= (*reg_field)->null_bit;
+ key_part_info->null_offset= (uint) ((*reg_field)->null_ptr -
+ (uchar*) table->record[0]);
+
key_part_info->offset= (*reg_field)->offset(table->record[0]);
key_part_info->length= (uint16) (*reg_field)->pack_length();
/* TODO:
@@ -12804,7 +12863,9 @@
join_tab->last_inner->first_unmatched= join_tab;
}
join->thd->row_count= 0;
-
+
+ //jtbm-todo: error handling!
+ do_jtbm_materialization_if_needed(join_tab);
error= (*join_tab->read_first_record)(join_tab);
if (join_tab->keep_current_rowid)
@@ -18169,7 +18230,7 @@
if (tab->select && tab->select->quick)
examined_rows= tab->select->quick->records;
else if (tab->type == JT_NEXT || tab->type == JT_ALL)
- examined_rows= tab->limit ? tab->limit : tab->table->file->records();
+ examined_rows= tab->limit ? tab->limit : tab->records;
else
examined_rows=(ha_rows)join->best_positions[i].records_read;
@@ -18658,6 +18719,14 @@
print_join(thd, eliminated_tables, str, &nested_join->join_list, query_type);
str->append(')');
}
+ else if (jtbm_subselect)
+ {
+ str->append(STRING_WITH_LEN(" <materialize> ("));
+ subselect_hash_sj_engine *hash_engine;
+ hash_engine= (subselect_hash_sj_engine*)jtbm_subselect->engine;
+ hash_engine->materialize_engine->print(str, query_type);
+ str->append(')');
+ }
else
{
const char *cmp_name; // Name to compare with alias
=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h 2010-03-20 12:01:47 +0000
+++ b/sql/sql_select.h 2010-04-05 20:16:45 +0000
@@ -1551,7 +1551,18 @@
bool union_part; ///< this subselect is part of union
bool optimized; ///< flag to avoid double optimization in EXPLAIN
+ /*
+ Subqueries that will need to be converted to semi-join nests (the list
+ is emptied when conversion is done
+ */
Array<Item_in_subselect> sj_subselects;
+
+ /*
+ Subqueries that will need to be converted to JOIN_TABs
+ (Note this is different from the above in the respect that it's part
+ of WHERE clause or something like that?)
+ */
+ //Array<Item_in_subselect> jtbm_subselects;
/* Temporary tables used to weed-out semi-join duplicates */
List<TABLE> sj_tmp_tables;
@@ -1575,6 +1586,7 @@
JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
select_result *result_arg)
:fields_list(fields_arg), sj_subselects(thd_arg->mem_root, 4)
+ //jtbm_subselects(thd_arg->mem_root, 4)
{
init(thd_arg, fields_arg, select_options_arg, result_arg);
}
=== modified file 'sql/table.h'
--- a/sql/table.h 2010-03-20 12:01:47 +0000
+++ b/sql/table.h 2010-04-05 20:16:45 +0000
@@ -1194,6 +1194,7 @@
/* Number of IN-compared expressions */
uint sj_in_exprs;
Item_in_subselect *sj_subq_pred;
+ Item_in_subselect *jtbm_subselect;
SJ_MATERIALIZATION_INFO *sj_mat_info;
/*
1
0

[Maria-developers] Rev 2772: fixed a bug in handling mysql_native_password specified explicitly: in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 05 Apr '10
by serg@askmonty.org 05 Apr '10
05 Apr '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2772
revision-id: sergii(a)pisem.net-20100405095031-bgjy005pcftkp6g1
parent: sergii(a)pisem.net-20100402200840-0nctbdvalpetkkzp
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: 5.2
timestamp: Mon 2010-04-05 11:50:31 +0200
message:
fixed a bug in handling mysql_native_password specified explicitly:
CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password
pointers were not always fixed, salt wasn't updated
=== modified file 'mysql-test/r/connect.result'
--- a/mysql-test/r/connect.result 2009-04-25 09:04:38 +0000
+++ b/mysql-test/r/connect.result 2010-04-05 09:50:31 +0000
@@ -225,3 +225,17 @@ Connection on extra port 2 ok
# ------------------------------------------------------------------
# -- End of 5.1 tests
# ------------------------------------------------------------------
+CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB';
+CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389';
+connect(localhost,mysqltest_up1,foo,test,13001,MASTER_SOCKET);
+ERROR 28000: Access denied for user 'mysqltest_up1'@'localhost' (using password: YES)
+select user(), current_user();
+user() current_user()
+mysqltest_up1@localhost mysqltest_up1@%
+connect(localhost,mysqltest_up2,newpw,test,13001,MASTER_SOCKET);
+ERROR 28000: Access denied for user 'mysqltest_up2'@'localhost' (using password: YES)
+select user(), current_user();
+user() current_user()
+mysqltest_up2@localhost mysqltest_up2@%
+DROP USER mysqltest_up1@'%';
+DROP USER mysqltest_up2@'%';
=== modified file 'mysql-test/t/connect.test'
--- a/mysql-test/t/connect.test 2009-09-07 20:50:10 +0000
+++ b/mysql-test/t/connect.test 2010-04-05 09:50:31 +0000
@@ -328,6 +328,34 @@ if ($error)
--disconnect extracon2
--connection default
+#
+# A couple of plugin tests - for builtin plugins only
+#
+CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB';
+CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389';
+
+--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+--error ER_ACCESS_DENIED_ERROR
+connect(pcon1,localhost,mysqltest_up1,foo,,$MASTER_EXTRA_PORT,);
+
+connect(pcon2,localhost,mysqltest_up1,bar,,$MASTER_EXTRA_PORT,);
+connection pcon2;
+select user(), current_user();
+disconnect pcon2;
+
+--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+--error ER_ACCESS_DENIED_ERROR
+connect(pcon3,localhost,mysqltest_up2,newpw,,$MASTER_EXTRA_PORT,);
+
+connect(pcon4,localhost,mysqltest_up2,oldpw,,$MASTER_EXTRA_PORT,);
+connection pcon4;
+select user(), current_user();
+disconnect pcon4;
+
+connection default;
+DROP USER mysqltest_up1@'%';
+DROP USER mysqltest_up2@'%';
+
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-04-02 20:08:40 +0000
+++ b/sql/sql_acl.cc 2010-04-05 09:50:31 +0000
@@ -319,6 +319,35 @@ set_user_salt(ACL_USER *acl_user, const
acl_user->salt_len= 0;
}
+/**
+ Fix ACL::plugin pointer to point to a hard-coded string, if appropriate
+
+ Make sure that if ACL_USER's plugin is a built-in, then it points
+ to a hard coded string, not to an allocated copy. Run-time, for
+ authentication, we want to be able to detect built-ins by comparing
+ pointers, not strings.
+
+ Additionally - update the salt if the plugin is built-in.
+
+ @retval 0 the pointers were fixed
+ @retval 1 this ACL_USER uses a not built-in plugin
+*/
+static bool fix_user_plugin_ptr(ACL_USER *user)
+{
+ if (my_strcasecmp(system_charset_info, user->plugin.str,
+ native_password_plugin_name.str) == 0)
+ user->plugin= native_password_plugin_name;
+ else
+ if (my_strcasecmp(system_charset_info, user->plugin.str,
+ old_password_plugin_name.str) == 0)
+ user->plugin= old_password_plugin_name;
+ else
+ return true;
+
+ set_user_salt(user, user->auth_string.str, user->auth_string.length);
+ return false;
+}
+
/*
This after_update function is used when user.password is less than
SCRAMBLE_LENGTH bytes.
@@ -662,6 +691,8 @@ static my_bool acl_load(THD *thd, TABLE_
char *tmpstr= get_field(&mem, table->field[next_field++]);
if (tmpstr)
{
+ user.plugin.str= tmpstr;
+ user.plugin.length= strlen(user.plugin.str);
if (user.auth_string.length)
{
sql_print_warning("'user' entry '%s@%s' has both a password "
@@ -670,22 +701,12 @@ static my_bool acl_load(THD *thd, TABLE_
user.user ? user.user : "",
user.host.hostname ? user.host.hostname : "");
}
- if (my_strcasecmp(system_charset_info, tmpstr,
- native_password_plugin_name.str) == 0)
- user.plugin= native_password_plugin_name;
- else
- if (my_strcasecmp(system_charset_info, tmpstr,
- old_password_plugin_name.str) == 0)
- user.plugin= old_password_plugin_name;
- else
- {
- user.plugin.str= tmpstr;
- user.plugin.length= strlen(tmpstr);
- }
user.auth_string.str= get_field(&mem, table->field[next_field++]);
if (!user.auth_string.str)
user.auth_string.str= const_cast<char*>("");
user.auth_string.length= strlen(user.auth_string.str);
+
+ fix_user_plugin_ptr(&user);
}
}
}
@@ -1132,12 +1153,15 @@ static void acl_update_user(const char *
{
if (plugin->str[0])
{
- acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length);
- acl_user->plugin.length= plugin->length;
+ acl_user->plugin= *plugin;
acl_user->auth_string.str= auth->str ?
strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
acl_user->auth_string.length= auth->length;
+ if (fix_user_plugin_ptr(acl_user))
+ acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length);
}
+ else
+ set_user_salt(acl_user, password, password_len);
acl_user->access=privileges;
if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
acl_user->user_resource.questions=mqh->questions;
@@ -1157,8 +1181,6 @@ static void acl_update_user(const char *
acl_user->x509_subject= (x509_subject ?
strdup_root(&mem,x509_subject) : 0);
}
- if (password)
- set_user_salt(acl_user, password, password_len);
/* search complete: */
break;
}
@@ -1186,11 +1208,12 @@ static void acl_insert_user(const char *
update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0);
if (plugin->str[0])
{
- acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length);
- acl_user.plugin.length= plugin->length;
+ acl_user.plugin= *plugin;
acl_user.auth_string.str= auth->str ?
strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
acl_user.auth_string.length= auth->length;
+ if (fix_user_plugin_ptr(&acl_user))
+ acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length);
}
else
{
@@ -1198,6 +1221,7 @@ static void acl_insert_user(const char *
old_password_plugin_name : native_password_plugin_name;
acl_user.auth_string.str= strmake_root(&mem, password, password_len);
acl_user.auth_string.length= password_len;
+ set_user_salt(&acl_user, password, password_len);
}
acl_user.access=privileges;
@@ -1210,8 +1234,6 @@ static void acl_insert_user(const char *
acl_user.x509_issuer= x509_issuer ? strdup_root(&mem,x509_issuer) : 0;
acl_user.x509_subject=x509_subject ? strdup_root(&mem,x509_subject) : 0;
- set_user_salt(&acl_user, password, password_len);
-
VOID(push_dynamic(&acl_users,(uchar*) &acl_user));
if (!acl_user.host.hostname ||
(acl_user.host.hostname[0] == wild_many && !acl_user.host.hostname[1]))
1
0

[Maria-developers] Rev 2751: options for CREATE TABLE (MWL#43) in file:///home/bell/maria/bzr/work-maria-5.2-createoptions2/
by sanja@askmonty.org 05 Apr '10
by sanja@askmonty.org 05 Apr '10
05 Apr '10
At file:///home/bell/maria/bzr/work-maria-5.2-createoptions2/
------------------------------------------------------------
revno: 2751
revision-id: sanja(a)askmonty.org-20100405084956-cesl6d5fm56m644z
parent: sergii(a)pisem.net-20100323092233-t2gwaclx94hd6exa
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-createoptions2
timestamp: Mon 2010-04-05 11:49:56 +0300
message:
options for CREATE TABLE (MWL#43)
=== modified file 'Docs/sp-imp-spec.txt'
--- a/Docs/sp-imp-spec.txt 2004-03-23 11:04:40 +0000
+++ b/Docs/sp-imp-spec.txt 2010-04-05 08:49:56 +0000
@@ -1075,7 +1075,7 @@
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
- 'NOT_USED',
+ 'CREATE_OPTIONS_NOERR',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
@@ -1097,4 +1097,4 @@
) comment='Stored Procedures';
--
-
\ No newline at end of file
+
=== modified file 'include/my_base.h'
--- a/include/my_base.h 2010-02-10 19:06:24 +0000
+++ b/include/my_base.h 2010-04-05 08:49:56 +0000
@@ -314,6 +314,8 @@
#define HA_OPTION_RELIES_ON_SQL_LAYER 512
#define HA_OPTION_NULL_FIELDS 1024
#define HA_OPTION_PAGE_CHECKSUM 2048
+/* .frm has extra create options in linked-list format */
+#define HA_OPTION_TEXT_CREATE_OPTIONS (1L << 14)
#define HA_OPTION_TEMP_COMPRESS_RECORD (1L << 15) /* set by isamchk */
#define HA_OPTION_READ_ONLY_DATA (1L << 16) /* Set by isamchk */
#define HA_OPTION_NO_CHECKSUM (1L << 17)
=== modified file 'libmysqld/CMakeLists.txt'
--- a/libmysqld/CMakeLists.txt 2010-01-31 09:13:21 +0000
+++ b/libmysqld/CMakeLists.txt 2010-04-05 08:49:56 +0000
@@ -139,7 +139,8 @@
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
../sql/partition_info.cc ../sql/sql_connect.cc
- ../sql/scheduler.cc ../sql/event_parse_data.cc
+ ../sql/scheduler.cc ../sql/event_parse_data.cc
+ ../sql/create_options.cc
${GEN_SOURCES}
${LIB_SOURCES})
=== modified file 'libmysqld/Makefile.am'
--- a/libmysqld/Makefile.am 2009-12-03 11:19:05 +0000
+++ b/libmysqld/Makefile.am 2010-04-05 08:49:56 +0000
@@ -75,7 +75,7 @@
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
debug_sync.cc \
- sql_tablespace.cc \
+ sql_tablespace.cc create_options.cc \
rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc event_parse_data.cc opt_table_elimination.cc
=== added file 'mysql-test/r/create_options.result'
--- a/mysql-test/r/create_options.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/create_options.result 2010-04-05 08:49:56 +0000
@@ -0,0 +1,182 @@
+drop table if exists t1;
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='CREATE_OPTIONS_NOERR';
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+Warnings:
+Warning 1650 Unknown option 'fkey'
+Warning 1650 Unknown option 'dff'
+Warning 1650 Unknown option 'tkey1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey`='vvv',
+ KEY `akey` (`a`) `dff`='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v1'
+drop table t1;
+#reassiginig options in the same line
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1;
+Warnings:
+Warning 1650 Unknown option 'fkey'
+Warning 1650 Unknown option 'dff'
+Warning 1650 Unknown option 'tkey1'
+Warning 1650 Unknown option 'tkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey`='vvv',
+ KEY `akey` (`a`) `dff`='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v2' `tkey2`='2v1'
+#add option
+alter table t1 tkey4=4v1;
+Warnings:
+Warning 1650 Unknown option 'tkey4'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey`='vvv',
+ KEY `akey` (`a`) `dff`='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v2' `tkey2`='2v1' `tkey4`='4v1'
+#remove options
+alter table t1 tkey3=DEFAULT tkey4=DEFAULT;
+Warnings:
+Warning 1650 Unknown option 'tkey3'
+Warning 1650 Unknown option 'tkey4'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey`='vvv',
+ KEY `akey` (`a`) `dff`='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v2' `tkey2`='2v1' `tkey4`='4v1'
+drop table t1;
+create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1;
+Warnings:
+Warning 1650 Unknown option 'fkey1'
+Warning 1650 Unknown option 'kkey1'
+Warning 1650 Unknown option 'TKEY1'
+Warning 1650 Unknown option 'tkey2'
+Warning 1650 Unknown option 'tkey3'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v1',
+ KEY `akey` (`a`) `kkey1`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#change field with option with the same option
+alter table t1 change a a int `FKEY1`='v1';
+Warnings:
+Warning 1650 Unknown option 'FKEY1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `FKEY1`='v1',
+ KEY `akey` (`a`) `kkey1`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#change field with option with a different option
+alter table t1 change a a int fkey1=v2;
+Warnings:
+Warning 1650 Unknown option 'fkey1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ KEY `akey` (`a`) `kkey1`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#new column no options
+alter table t1 add column b int;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `b` int(11) DEFAULT NULL,
+ KEY `akey` (`a`) `kkey1`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#new key with options
+alter table t1 add key bkey (b) kkey2=v1;
+Warnings:
+Warning 1650 Unknown option 'kkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `b` int(11) DEFAULT NULL,
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `bkey` (`b`) `kkey2`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#new column with options
+alter table t1 add column c int fkey1=v1 fkey2=v2;
+Warnings:
+Warning 1650 Unknown option 'fkey1'
+Warning 1650 Unknown option 'fkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `bkey` (`b`) `kkey2`='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#new key no options
+alter table t1 add key ckey (c);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `bkey` (`b`) `kkey2`='v1',
+ KEY `ckey` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#drop column
+alter table t1 drop b;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `ckey` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#add column with options after delete
+alter table t1 add column b int fkey2=v1;
+Warnings:
+Warning 1650 Unknown option 'fkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ `b` int(11) DEFAULT NULL `fkey2`='v1',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `ckey` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+#add key
+alter table t1 add key bkey (b) kkey2=v2;
+Warnings:
+Warning 1650 Unknown option 'kkey2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `fkey1`='v2',
+ `c` int(11) DEFAULT NULL `fkey1`='v1' `fkey2`='v2',
+ `b` int(11) DEFAULT NULL `fkey2`='v1',
+ KEY `akey` (`a`) `kkey1`='v1',
+ KEY `ckey` (`c`),
+ KEY `bkey` (`b`) `kkey2`='v2'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`='2v1' `tkey3`='3v1'
+drop table t1;
+create table t1 (a int) tkey1=100;
+Warnings:
+Warning 1650 Unknown option 'tkey1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=100
+drop table t1;
+#error on unknown option
+SET SQL_MODE='';
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+ERROR HY000: Unknown option 'fkey'
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/r/events_bugs.result'
--- a/mysql-test/r/events_bugs.result 2009-03-11 20:30:56 +0000
+++ b/mysql-test/r/events_bugs.result 2010-04-05 08:49:56 +0000
@@ -729,9 +729,8 @@
create event e1 on schedule every 1 day do select 1;
select @@sql_mode;
@@sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,CREATE_OPTIONS_ERR,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
set @@sql_mode= @old_mode;
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.event where name = 'p' and sql_mode = @full_mode;
name
=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result 2010-03-15 11:51:23 +0000
+++ b/mysql-test/r/information_schema.result 2010-04-05 08:49:56 +0000
@@ -615,7 +615,7 @@
proc definer char(77)
proc created timestamp
proc modified timestamp
-proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
proc comment char(64)
proc character_set_client char(32)
proc collation_connection char(32)
=== modified file 'mysql-test/r/plugin_load.result'
--- a/mysql-test/r/plugin_load.result 2008-01-26 00:05:15 +0000
+++ b/mysql-test/r/plugin_load.result 2010-04-05 08:49:56 +0000
@@ -1,3 +1,57 @@
SELECT @@global.example_enum_var = 'e2';
@@global.example_enum_var = 'e2'
1
+#legal values
+CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example ULL=10000 STR='dskj' one_or_two='one' YESNO=0;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `complex`='c,f,f,f'
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0
+drop table t1;
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='CREATE_OPTIONS_NOERR';
+#illegal value fixed
+CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+Warnings:
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`='SSS'
+#alter table
+alter table t1 ULL=10000000;
+Warnings:
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`='SSS' `ULL`='10000000'
+alter table t1 change a a int complex='c,c,c';
+Warnings:
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1651 Incorrect value 'SSS' for option 'YESNO'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL `complex`='c,c,c'
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`='SSS' `ULL`='10000000'
+drop table t1;
+#illegal value error
+SET SQL_MODE='';
+CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+ERROR HY000: Incorrect value '10000000000000000000' for option 'ULL'
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/r/sp.result'
--- a/mysql-test/r/sp.result 2009-12-23 13:44:03 +0000
+++ b/mysql-test/r/sp.result 2010-04-05 08:49:56 +0000
@@ -6940,9 +6940,8 @@
call p();
select @@sql_mode;
@@sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,CREATE_OPTIONS_NOERR,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
set @@sql_mode= @old_mode;
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.proc where name = 'p' and sql_mode = @full_mode;
name
=== modified file 'mysql-test/r/system_mysql_db.result'
--- a/mysql-test/r/system_mysql_db.result 2009-10-27 10:09:36 +0000
+++ b/mysql-test/r/system_mysql_db.result 2010-04-05 08:49:56 +0000
@@ -200,7 +200,7 @@
`definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
@@ -225,7 +225,7 @@
`ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`originator` int(10) unsigned NOT NULL,
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2009-10-28 09:23:02 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2010-04-05 08:49:56 +0000
@@ -49,7 +49,7 @@
NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references
NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
+NULL mysql event sql_mode 15 NO set 488 1464 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references
NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references
@@ -124,7 +124,7 @@
NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references
NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references
-NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
+NULL mysql proc sql_mode 15 NO set 488 1464 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
@@ -327,7 +327,7 @@
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql event sql_mode set 488 1464 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -402,7 +402,7 @@
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql proc sql_mode set 488 1464 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result 2009-05-19 16:43:50 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result 2010-04-05 08:49:56 +0000
@@ -49,7 +49,7 @@
NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI
NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE')
NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64)
@@ -124,7 +124,7 @@
NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER')
NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')
-NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI
NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL
@@ -327,7 +327,7 @@
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -402,7 +402,7 @@
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
=== added file 'mysql-test/t/create_options.test'
--- a/mysql-test/t/create_options.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/create_options.test 2010-04-05 08:49:56 +0000
@@ -0,0 +1,68 @@
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='CREATE_OPTIONS_NOERR';
+
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+show create table t1;
+drop table t1;
+
+--echo #reassiginig options in the same line
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1;
+show create table t1;
+
+-- echo #add option
+alter table t1 tkey4=4v1;
+show create table t1;
+
+--echo #remove options
+alter table t1 tkey3=DEFAULT tkey4=DEFAULT;
+show create table t1;
+
+drop table t1;
+
+create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1;
+show create table t1;
+
+--echo #change field with option with the same option
+alter table t1 change a a int `FKEY1`='v1';
+show create table t1;
+--echo #change field with option with a different option
+alter table t1 change a a int fkey1=v2;
+show create table t1;
+--echo #new column no options
+alter table t1 add column b int;
+show create table t1;
+--echo #new key with options
+alter table t1 add key bkey (b) kkey2=v1;
+show create table t1;
+--echo #new column with options
+alter table t1 add column c int fkey1=v1 fkey2=v2;
+show create table t1;
+--echo #new key no options
+alter table t1 add key ckey (c);
+show create table t1;
+--echo #drop column
+alter table t1 drop b;
+show create table t1;
+--echo #add column with options after delete
+alter table t1 add column b int fkey2=v1;
+show create table t1;
+--echo #add key
+alter table t1 add key bkey (b) kkey2=v2;
+show create table t1;
+drop table t1;
+
+#numeric (unquoted) value
+create table t1 (a int) tkey1=100;
+show create table t1;
+drop table t1;
+
+--echo #error on unknown option
+SET SQL_MODE='';
+--error ER_UNKNOWN_OPTION
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/t/events_bugs.test'
--- a/mysql-test/t/events_bugs.test 2009-03-11 20:30:56 +0000
+++ b/mysql-test/t/events_bugs.test 2010-04-05 08:49:56 +0000
@@ -1204,7 +1204,6 @@
select @@sql_mode;
set @@sql_mode= @old_mode;
# Rename SQL modes that differ in name between the server and the table definition.
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.event where name = 'p' and sql_mode = @full_mode;
drop event e1;
=== modified file 'mysql-test/t/exampledb.test'
--- a/mysql-test/t/exampledb.test 2006-05-05 17:08:40 +0000
+++ b/mysql-test/t/exampledb.test 2010-04-05 08:49:56 +0000
@@ -20,3 +20,4 @@
drop table t1;
# End of 4.1 tests
+
=== modified file 'mysql-test/t/plugin_load.test'
--- a/mysql-test/t/plugin_load.test 2009-10-08 08:39:15 +0000
+++ b/mysql-test/t/plugin_load.test 2010-04-05 08:49:56 +0000
@@ -2,3 +2,30 @@
--source include/have_example_plugin.inc
SELECT @@global.example_enum_var = 'e2';
+
+--echo #legal values
+CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example ULL=10000 STR='dskj' one_or_two='one' YESNO=0;
+show create table t1;
+drop table t1;
+
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='CREATE_OPTIONS_NOERR';
+
+--echo #illegal value fixed
+CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+show create table t1;
+
+--echo #alter table
+alter table t1 ULL=10000000;
+show create table t1;
+alter table t1 change a a int complex='c,c,c';
+show create table t1;
+drop table t1;
+
+
+--echo #illegal value error
+SET SQL_MODE='';
+--error ER_BAD_OPTION_VALUE
+CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/t/sp.test'
--- a/mysql-test/t/sp.test 2009-12-23 13:44:03 +0000
+++ b/mysql-test/t/sp.test 2010-04-05 08:49:56 +0000
@@ -8210,7 +8210,6 @@
select @@sql_mode;
set @@sql_mode= @old_mode;
# Rename SQL modes that differ in name between the server and the table definition.
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.proc where name = 'p' and sql_mode = @full_mode;
drop procedure p;
=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql 2009-10-27 10:09:36 +0000
+++ b/scripts/mysql_system_tables.sql 2010-04-05 08:49:56 +0000
@@ -60,7 +60,7 @@
CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones';
-CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
+CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'CREATE_OPTIONS_NOERR', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
@@ -80,7 +80,7 @@
EXECUTE stmt;
DROP PREPARE stmt;
-CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
+CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;
=== modified file 'scripts/mysql_system_tables_fix.sql'
--- a/scripts/mysql_system_tables_fix.sql 2009-12-03 16:15:47 +0000
+++ b/scripts/mysql_system_tables_fix.sql 2010-04-05 08:49:56 +0000
@@ -368,7 +368,7 @@
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
- 'NOT_USED',
+ 'CREATE_OPTIONS_ERR',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
@@ -482,14 +482,14 @@
ALTER TABLE event DROP PRIMARY KEY;
ALTER TABLE event ADD PRIMARY KEY(db, name);
# Add sql_mode column just in case.
-ALTER TABLE event ADD sql_mode set ('NOT_USED') AFTER on_completion;
+ALTER TABLE event ADD sql_mode set ('CREATE_OPTIONS_ERR') AFTER on_completion;
# Update list of sql_mode values.
ALTER TABLE event MODIFY sql_mode
set('REAL_AS_FLOAT',
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
- 'NOT_USED',
+ 'CREATE_OPTIONS_ERR',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2010-03-03 14:44:14 +0000
+++ b/sql/CMakeLists.txt 2010-04-05 08:49:56 +0000
@@ -77,6 +77,7 @@
rpl_rli.cc rpl_mi.cc sql_servers.cc
sql_connect.cc scheduler.cc
sql_profile.cc event_parse_data.cc opt_table_elimination.cc
+ create_options.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
${PROJECT_SOURCE_DIR}/include/mysqld_error.h
=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am 2010-03-03 14:44:14 +0000
+++ b/sql/Makefile.am 2010-04-05 08:49:56 +0000
@@ -78,7 +78,8 @@
sql_plugin.h authors.h event_parse_data.h \
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
- contributors.h sql_servers.h
+ contributors.h sql_servers.h \
+ create_options.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
@@ -124,7 +125,7 @@
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_servers.cc event_parse_data.cc \
- opt_table_elimination.cc
+ opt_table_elimination.cc create_options.cc
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
=== added file 'sql/create_options.cc'
--- a/sql/create_options.cc 1970-01-01 00:00:00 +0000
+++ b/sql/create_options.cc 2010-04-05 08:49:56 +0000
@@ -0,0 +1,651 @@
+#include "mysql_priv.h"
+#include <my_getopt.h>
+
+/* bits of first byte (type byte of frm imege) */
+#define FRM_TYPE_MASK 0x03
+#define FRM_QUATED_VALUE 0x80
+
+/**
+ Links this item to the given list end
+
+ @param start The list beginning or NULL
+ @param end The list last element or does not matter
+*/
+
+void engine_option_value::link(engine_option_value **start,
+ engine_option_value **end)
+{
+ engine_option_value *opt;
+ /* check duplicates to avoid writing them to frm*/
+ for(opt= *start;
+ opt && (opt->deleted ||
+ my_strnncoll(system_charset_info,
+ (uchar *)name.str, name.length,
+ (uchar*)opt->name.str, opt->name.length));
+ opt= opt->next) {};
+ if (opt)
+ {
+ /* remove previous value */
+ opt->value.str= NULL;
+ opt->parsed= TRUE;
+ opt->deleted= TRUE;
+ }
+ /*
+ Add this option to the end of the list
+
+ @note: We add even if it is opt->value.str == NULL because it can be
+ ALTER TABLE to remove the option.
+ */
+ if (*start)
+ {
+ (*end)->next= this;
+ *end= this;
+ }
+ else
+ {
+ *start= *end= this;
+ }
+}
+
+static bool report_wrong_value(THD *thd, const char *name, const char *val,
+ my_bool suppress_warning)
+{
+ if (!(thd->variables.sql_mode & MODE_CREATE_OPTIONS_NOERR))
+ {
+ my_error(ER_BAD_OPTION_VALUE, MYF(0), val, name);
+ return 1;
+ }
+
+ /*
+ We suppress errors to avoid double messages about the same value. It has
+ no sense to supress errors as they lead to execution abortion.
+ */
+ if (!suppress_warning)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_BAD_OPTION_VALUE,
+ ER(ER_BAD_OPTION_VALUE), val, name);
+ return 0;
+}
+
+static bool report_unknown_option(THD *thd, engine_option_value *val,
+ my_bool suppress_warning)
+{
+ DBUG_ENTER("report_unknown_option");
+ if (val->parsed)
+ {
+ DBUG_PRINT("info", ("parsed => exiting"));
+ DBUG_RETURN(FALSE);
+ }
+
+ if (!(thd->variables.sql_mode & MODE_CREATE_OPTIONS_NOERR))
+ {
+ my_error(ER_UNKNOWN_OPTION, MYF(0), val->name.str);
+ DBUG_RETURN(TRUE);
+ }
+
+ /*
+ We suppress errors to avoid double messages about the same value. It has
+ no sense to supress errors as they lead to execution abortion.
+ */
+ if (!suppress_warning)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_OPTION,
+ ER(ER_UNKNOWN_OPTION),
+ val->name.str);
+ DBUG_RETURN(FALSE);
+}
+
+static bool set_one_value(ha_create_table_option *opt,
+ THD *thd, LEX_STRING *value, void *base,
+ my_bool suppress_warning,
+ MEM_ROOT *root)
+{
+ DBUG_ENTER("set_one_value");
+ DBUG_PRINT("enter", ("opt: 0x%lx type: %u name '%s' value: '%s'",
+ (ulong) opt,
+ opt->type, opt->name,
+ (value->str ? value->str : "<DEFAULT>")));
+ switch (opt->type)
+ {
+ case HA_OPTION_TYPE_ULL:
+ {
+ ulonglong *val= (ulonglong*)((char*)base + opt->offset);
+ *val= opt->def_value;
+ if (!value->str)
+ {
+ DBUG_RETURN(0);
+ }
+
+ my_option optp= { opt->name, 1, 0, (uchar **)val, 0, 0, GET_ULL,
+ REQUIRED_ARG, opt->def_value, opt->min_value, opt->max_value,
+ 0, opt->block_size, 0};
+
+ ulonglong orig_val= strtoull(value->str, NULL, 10);
+ my_bool unused;
+ *val= orig_val;
+ *val= getopt_ull_limit_value(*val, &optp, &unused);
+ if (*val == orig_val)
+ DBUG_RETURN(0);
+
+ DBUG_RETURN(report_wrong_value(thd, opt->name, value->str,
+ suppress_warning));
+ }
+ case HA_OPTION_TYPE_STRING:
+ {
+ char **val= (char **)((char *)base + opt->offset);
+ *val= 0;
+ if (!value->str)
+ {
+ DBUG_RETURN(0);
+ }
+
+ if (!(*val= strmake_root(root, value->str, value->length)))
+ DBUG_RETURN(1);
+ DBUG_RETURN(0);
+ }
+ case HA_OPTION_TYPE_ENUM:
+ {
+ uint *val= (uint *)((char *)base + opt->offset), num;
+ *val= opt->def_value;
+
+ if (!value->str)
+ {
+ DBUG_RETURN(0);
+ }
+
+ const char *start= opt->values, *end;
+
+ num= 0;
+ while (*start)
+ {
+ for (end=start;
+ *end && *end != ',';
+ end+= my_mbcharlen(system_charset_info, *end)) /* no-op */;
+ if (!my_strnncoll(system_charset_info,
+ (uchar*)start, end-start,
+ (uchar*)value->str, value->length))
+ {
+ *val= num;
+ DBUG_RETURN(0);
+ }
+ if (*end) *end++;
+ start= end;
+ num++;
+ }
+
+ DBUG_RETURN(report_wrong_value(thd, opt->name, value->str,
+ suppress_warning));
+ }
+ case HA_OPTION_TYPE_BOOL:
+ {
+ bool *val= (bool *)((char *)base + opt->offset);
+ *val= opt->def_value;
+
+ if (!value->str)
+ {
+ DBUG_RETURN(0);
+ }
+
+ if (!my_strnncoll(system_charset_info,
+ (const uchar*)"NO", 2,
+ (uchar *)value->str, value->length) ||
+ !my_strnncoll(system_charset_info,
+ (const uchar*)"OFF", 3,
+ (uchar *)value->str, value->length) ||
+ !my_strnncoll(system_charset_info,
+ (const uchar*)"N", 1,
+ (uchar *)value->str, value->length))
+ {
+ *val= FALSE;
+ DBUG_RETURN(FALSE);
+ }
+
+ if (!my_strnncoll(system_charset_info,
+ (const uchar*)"YES", 3,
+ (uchar *)value->str, value->length) ||
+ !my_strnncoll(system_charset_info,
+ (const uchar*)"ON", 2,
+ (uchar *)value->str, value->length) ||
+ !my_strnncoll(system_charset_info,
+ (const uchar*)"N", 1,
+ (uchar *)value->str, value->length))
+ {
+ *val= TRUE;
+ DBUG_RETURN(FALSE);
+ }
+
+ /* numeric value */
+ if (value->str[0] < '0' || value->str[0] > '9')
+ DBUG_RETURN(report_wrong_value(thd, opt->name, value->str,
+ suppress_warning));
+
+ if (strtoull(value->str, NULL, 10))
+ *val= 1;
+ else
+ *val= 0;
+
+ DBUG_RETURN(FALSE);
+ }
+ }
+ DBUG_ASSERT(0);
+ my_error(ER_UNKNOWN_ERROR, MYF(0));
+ DBUG_RETURN(1);
+}
+
+static const size_t ha_option_type_sizeof[]=
+{ sizeof(ulonglong), sizeof(char *), sizeof(uint), sizeof(uint)};
+
+/**
+ Creates option structure and parses list of options in it
+
+ @param thd thread handler
+ @param option_struct where to store pointer on the option struct
+ @param option_list list of options given by user
+ @param rules list of option description by engine
+ @param suppress_warning second parse so we do not need warnings
+ @param root MEM_ROOT where allocate memory
+
+ @retval TRUE Error
+ @retval FALSE OK
+*/
+
+my_bool parse_option_list(THD* thd, void **option_struct,
+ engine_option_value *option_list,
+ ha_create_table_option *rules,
+ my_bool suppress_warning,
+ MEM_ROOT *root)
+{
+ ha_create_table_option *opt;
+ size_t option_struct_size= 0;
+ engine_option_value *val= option_list;
+ DBUG_ENTER("parse_option_list");
+ DBUG_PRINT("enter",
+ ("struct: 0x%lx list: 0x%lx rules: 0x%lx suppres %u root 0x%lx",
+ (ulong) *option_struct, (ulong)option_list, (ulong)rules,
+ (uint) suppress_warning, (ulong) root));
+
+ if (rules)
+ {
+ LEX_STRING default_val= {NULL, 0};
+ for (opt= rules; opt->name; opt++)
+ set_if_bigger(option_struct_size, opt->offset +
+ ha_option_type_sizeof[opt->type]);
+
+ *option_struct= alloc_root(root, option_struct_size);
+
+ /* set all values to default */
+ for (opt= rules; opt->name; opt++)
+ set_one_value(opt, thd, &default_val, *option_struct,
+ suppress_warning, root);
+ }
+
+ for (; val; val= val->next)
+ {
+ //if (!val->value.str) continue; // skip deleted
+ for (opt= rules; opt && opt->name; opt++)
+ {
+ if (my_strnncoll(system_charset_info,
+ (uchar*)opt->name, opt->name_length,
+ (uchar*)val->name.str, val->name.length))
+ continue;
+
+ if (set_one_value(opt, thd, &val->value,
+ *option_struct, suppress_warning, root))
+ DBUG_RETURN(TRUE);
+ val->parsed= true;
+ break;
+ }
+ if (report_unknown_option(thd, val, suppress_warning))
+ DBUG_RETURN(TRUE);
+ val->parsed= true;
+ }
+
+ DBUG_RETURN(FALSE);;
+}
+
+
+/**
+ Parses all table/fields/keys options
+
+ @param thd thread handler
+ @param file handler of the table
+ @parem share descriptor of the table
+
+ @retval TRUE Error
+ @retval FALSE OK
+*/
+
+my_bool parse_engine_table_options(THD *thd, handlerton *ht,
+ TABLE_SHARE *share)
+{
+ MEM_ROOT *root= &share->mem_root;
+ DBUG_ENTER("parse_engine_table_options");
+
+ if (parse_option_list(thd, &share->option_struct, share->option_list,
+ ht->table_opt_rules, TRUE, root))
+ DBUG_RETURN(TRUE);
+
+ for (Field **field= share->field; *field; field++)
+ {
+ if (parse_option_list(thd, &(*field)->option_struct, (*field)->option_list,
+ ht->field_opt_rules, TRUE, root))
+ DBUG_RETURN(TRUE);
+ }
+
+ for (uint index= 0; index < share->keys; index ++)
+ {
+ if (parse_option_list(thd, &share->key_info[index].option_struct,
+ share->key_info[index].option_list,
+ ht->key_opt_rules, TRUE, root))
+ DBUG_RETURN(TRUE);
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Returns representation length of key and value in the frm file
+*/
+
+uint engine_option_value::frm_length()
+{
+ /*
+ 2 bytes - value length
+ 1 byte - key length
+ */
+ return 2 + 1 + name.length + value.length;
+}
+
+
+/**
+ Returns length of representation of option list in the frm file
+
+ @param opt list of options;
+ @param overhead length of additional information per option
+
+ @returns length of image in frm
+*/
+
+static uint option_list_frm_length(engine_option_value *opt, uint overhead)
+{
+ uint res= 0;
+
+ for (; opt; opt= opt->next)
+ if (opt->value.str)
+ res+= opt->frm_length() + overhead;
+
+ return res;
+}
+
+
+/**
+ Calculates length of options image in the .frm
+
+ @param table_option_list list of table options
+ @param create_fields field descriptors list
+ @param keys number of keys
+ @param key_info array of key descriptors
+
+ @returns length of image in frm
+*/
+
+uint engine_table_options_frm_length(engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info)
+{
+ List_iterator<Create_field> it(create_fields);
+ Create_field *field;
+ uint res, index;
+ DBUG_ENTER("engine_table_options_frm_length");
+
+ /* 1 byte - record type */
+ res= option_list_frm_length(table_option_list, 1);
+
+ while ((field= it++))
+ {
+ /*
+ 1 byte - record type
+ 2 bytes - field number
+ */
+ res+= option_list_frm_length(field->option_list, 1 + 2);
+ }
+
+ for (index= 0; index < keys; index++, key_info++)
+ {
+
+ /*
+ 1 byte - record type
+ 2 bytes - key number
+ */
+ res+= option_list_frm_length(key_info->option_list, 1 + 2);
+ }
+ DBUG_RETURN(res);
+}
+
+
+/**
+ Writes image of the key and value to the frm image buffer
+
+ @param buff pointer to the buffer free space beginning
+
+ @returns pointer to byte after last recorded in the buffer
+*/
+
+uchar *engine_option_value::frm_image(uchar *buff)
+{
+ buff[0]= name.length;
+ buff++;
+ memcpy(buff, name.str, name.length);
+ buff+= name.length;
+ int2store(buff, value.length);
+ buff+= 2;
+ memcpy(buff, (const uchar *) value.str, value.length);
+ buff+= value.length;
+ return buff;
+}
+
+/**
+ Writes image of the key and value to the frm image buffer
+
+ @param buff pointer to the buffer free space beginning
+ @param opt list of options;
+ @param type option type (CREATE_OPTION_*)
+ @param index for keys and fields index of them
+
+ @returns pointer to byte after last recorded in the buffer
+*/
+static uchar *option_list_frm_image(uchar *buff,
+ engine_option_value *opt,
+ CREATE_OPTION_TYPES type,
+ uint index)
+{
+ for (; opt; opt= opt->next)
+ {
+ /* skip deleted options */
+ if (opt->value.str)
+ {
+ *(buff++)= (type | (opt->quoted_value ? FRM_QUATED_VALUE : 0));
+ if (type != CREATE_OPTION_TABLE)
+ {
+ int2store(buff, index);
+ buff+= 2;
+ }
+ buff= opt->frm_image(buff);
+ }
+ }
+
+ return buff;
+}
+
+
+/**
+ Writes options image in the .frm buffer
+
+ @param buff pointer to the buffer
+ @param table_option_list list of table options
+ @param create_fields field descriptors list
+ @param keys number of keys
+ @param key_info array of key descriptors
+
+ @returns pointer to byte after last recorded in the buffer
+*/
+
+uchar *engine_table_options_frm_image(uchar *buff,
+ engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info)
+{
+ List_iterator<Create_field> it(create_fields);
+ Create_field *field;
+ uint index;
+ DBUG_ENTER("engine_table_options_frm_image");
+
+ buff= option_list_frm_image(buff, table_option_list, CREATE_OPTION_TABLE, 0);
+
+ for (index= 0; (field= it++); index++)
+ buff= option_list_frm_image(buff, field->option_list,
+ CREATE_OPTION_FIELD, index);
+
+ for (index= 0; index < keys; index++, key_info++)
+ buff= option_list_frm_image(buff, key_info->option_list,
+ CREATE_OPTION_KEY, index);
+ DBUG_RETURN(buff);
+}
+
+/**
+ Reads name and value from buffer, then link it in the list
+
+ @param buff the buffer to read from
+ @param start The list beginning or NULL
+ @param end The list last element or does not matter
+ @param root MEM_ROOT for allocating
+
+ @returns pointer to byte after last recorded in the buffer
+*/
+uchar *engine_option_value::frm_read(const uchar *buff,
+ engine_option_value **start,
+ engine_option_value **end,
+ MEM_ROOT *root)
+{
+ name.length= buff[0];
+ buff++;
+ if (!(name.str= strmake_root(root, (const char*)buff,
+ name.length)))
+ return NULL;
+ buff+= name.length;
+ value.length= uint2korr(buff);
+ buff+= 2;
+ if (!(value.str= strmake_root(root, (const char*)buff,
+ value.length)))
+ return NULL;
+ buff+= value.length;
+ link(start, end);
+ return (uchar *)buff;
+}
+
+
+/**
+ Reads options from this buffer
+
+ @param buff the buffer to read from
+ @param length buffer length
+ @param share table descriptor
+ @param root MEM_ROOT for allocating
+
+ @retval TRUE Error
+ @retval FALSE OK
+*/
+
+my_bool engine_table_options_frm_read(const uchar *buff,
+ uint length,
+ TABLE_SHARE *share)
+{
+ const uchar *buff_end= buff + length;
+ engine_option_value *tbl_end, **fld_end, **key_end;
+ MEM_ROOT *root= &share->mem_root;
+ DBUG_ENTER("engine_table_options_frm_read");
+
+ /* temporary list end pointers to construct lists */
+ tbl_end= NULL;
+ if (!(fld_end= (engine_option_value **)
+ alloc_root(root, sizeof(engine_option_value *) * share->fields)) ||
+ !(key_end= (engine_option_value **)
+ alloc_root(root, sizeof(engine_option_value *) * share->keys)))
+ {
+ DBUG_RETURN(TRUE);
+ }
+
+ while (buff < buff_end)
+ {
+ engine_option_value *option;
+ CREATE_OPTION_TYPES type;
+ uint index= 0;
+
+ if (!(option= new (root) engine_option_value()))
+ DBUG_RETURN(TRUE);
+
+ DBUG_ASSERT(buff + 4 <= buff_end);
+
+ type= (CREATE_OPTION_TYPES)(FRM_TYPE_MASK & buff[0]);
+ option->set_quoted_value(FRM_QUATED_VALUE & buff[0]);
+ buff++;
+ switch (type) {
+ case CREATE_OPTION_FIELD:
+ index= uint2korr(buff);
+ buff+= 2;
+ if (!(buff= option->frm_read(buff,
+ &share->field[index]->option_list,
+ fld_end + index,
+ root)))
+ DBUG_RETURN(TRUE);
+ break;
+ case CREATE_OPTION_KEY:
+ index= uint2korr(buff);
+ buff+= 2;
+ if (!(buff= option->frm_read(buff,
+ &share->key_info[index].option_list,
+ key_end + index,
+ root)))
+ DBUG_RETURN(TRUE);
+ break;
+ case CREATE_OPTION_TABLE:
+ if (!(buff= option->frm_read(buff,
+ &share->option_list,
+ &tbl_end,
+ root)))
+ DBUG_RETURN(TRUE);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+ DBUG_PRINT("info", ("type: %u index: %u key: '%s' value: '%s'",
+ (uint) type, (uint) index,
+ option->name.str, option->value.str));
+ }
+ DBUG_RETURN(FALSE);
+}
+
+/**
+ Adds (merges) chages to source
+*/
+
+engine_option_value *merge_engine_table_options(engine_option_value *source,
+ engine_option_value *changes,
+ MEM_ROOT *root)
+{
+ engine_option_value *end, *opt;
+ DBUG_ENTER("merge_engine_table_options");
+
+ /* find last element */
+ if (source)
+ for (end= source; end->next; end= end->next){};
+
+ for (opt= changes; opt; opt= opt->next)
+ {
+ new (root) engine_option_value(opt->name,
+ opt->value.str, opt->value.length,
+ &source, &end);
+ }
+ DBUG_RETURN(source);
+}
=== added file 'sql/create_options.h'
--- a/sql/create_options.h 1970-01-01 00:00:00 +0000
+++ b/sql/create_options.h 2010-04-05 08:49:56 +0000
@@ -0,0 +1,139 @@
+/* Copyright (C) 2010 Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ Engine defined options of tables/fields/keys in CREATE/ALTER TABLE.
+*/
+
+#ifndef SQL_CREATE_OPTIONS_INCLUDED
+#define SQL_CREATE_OPTIONS_INCLUDED
+
+class Item;
+#include "handler.h"
+
+/* types of cretate options records on disk, also it is length of extra data */
+typedef enum enum_create_options_type {
+ CREATE_OPTION_TABLE= 0,
+ CREATE_OPTION_KEY= 1,
+ CREATE_OPTION_FIELD= 2
+} CREATE_OPTION_TYPES;
+
+class engine_option_value: public Sql_alloc
+{
+ public:
+ LEX_STRING name;
+ LEX_STRING value;
+ engine_option_value *next;
+ bool parsed;
+ bool deleted;
+ bool quoted_value;
+ engine_option_value() :
+ next(NULL), parsed(false)
+ {}
+ engine_option_value(const char *name_arg, size_t name_len_arg,
+ const char *value_arg, size_t value_len_arg,
+ engine_option_value **start, engine_option_value **end) :
+ next(NULL), parsed(false), deleted(false), quoted_value(true)
+ {
+ name.str= const_cast<char*>(name_arg);
+ name.length= name_len_arg;
+ value.str= const_cast<char*>(value_arg);
+ value.length= value_len_arg;
+ link(start, end);
+ }
+ engine_option_value(LEX_STRING &name_arg,
+ const char *value_arg, size_t value_len_arg,
+ engine_option_value **start, engine_option_value **end) :
+ name(name_arg), next(NULL), parsed(false), deleted(false),
+ quoted_value(true)
+ {
+ value.str= const_cast<char*>(value_arg);
+ value.length= value_len_arg;
+ link(start, end);
+ }
+ engine_option_value(const char *name_arg, size_t name_len_arg,
+ ulonglong value_arg,
+ engine_option_value **start, engine_option_value **end,
+ MEM_ROOT *root) :
+ next(NULL), parsed(false), deleted(false), quoted_value(false)
+ {
+ name.str= const_cast<char*>(name_arg);
+ name.length= name_len_arg;
+ if ((value.str= (char *)alloc_root(root, 22)))
+ {
+ value.length= my_snprintf(value.str, 22, "%llu", value_arg);
+ link(start, end);
+ }
+ }
+ engine_option_value(LEX_STRING &name_arg,
+ ulonglong value_arg,
+ engine_option_value **start, engine_option_value **end,
+ MEM_ROOT *root) :
+ name(name_arg), next(NULL), parsed(false), deleted(false),
+ quoted_value(false)
+ {
+ if ((value.str= (char *)alloc_root(root, 22)))
+ {
+ value.length= my_snprintf(value.str, 22, "%llu", value_arg);
+ link(start, end);
+ }
+ }
+ engine_option_value(LEX_STRING &name_arg,
+ ha_choice value_arg,
+ engine_option_value **start, engine_option_value **end) :
+ name(name_arg), next(NULL), parsed(false), deleted(false),
+ quoted_value(false)
+ {
+ value.length= 1;
+ switch (value_arg) {
+ case HA_CHOICE_UNDEF:
+ value.str= NULL;
+ value.length= 0;
+ break;
+ case HA_CHOICE_NO:
+ value.str= (char*)"0";
+ break;
+ case HA_CHOICE_YES:
+ value.str= (char*)"1";
+ break;
+ }
+ }
+ void set_quoted_value(bool quoted) {quoted_value= quoted;}
+ void link(engine_option_value **start, engine_option_value **end);
+ uint frm_length();
+ uchar *frm_image(uchar *buff);
+ uchar *frm_read(const uchar *buff,
+ engine_option_value **start, engine_option_value **end,
+ MEM_ROOT *root);
+};
+
+class handler;
+class THD;
+my_bool parse_engine_table_options(THD *thd, handlerton *ht,
+ TABLE_SHARE *share);
+my_bool parse_option_list(THD* thd, void **option_struct,
+ engine_option_value *option_list,
+ ha_create_table_option *rules,
+ my_bool suppress_warning,
+ MEM_ROOT *root);
+my_bool engine_table_options_frm_read(const uchar *buff,
+ uint length,
+ TABLE_SHARE *share);
+engine_option_value *merge_engine_table_options(engine_option_value *source,
+ engine_option_value *changes,
+ MEM_ROOT *root);
+#endif
=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc 2010-03-15 11:51:23 +0000
+++ b/sql/event_db_repository.cc 2010-04-05 08:49:56 +0000
@@ -105,7 +105,8 @@
{
{ C_STRING_WITH_LEN("sql_mode") },
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
- "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
+ "'IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY',"
+ "'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2010-03-17 02:32:31 +0000
+++ b/sql/field.cc 2010-04-05 08:49:56 +0000
@@ -1306,14 +1306,13 @@
Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg)
- :ptr(ptr_arg), null_ptr(null_ptr_arg),
- table(0), orig_table(0), table_name(0),
- field_name(field_name_arg),
- key_start(0), part_of_key(0), part_of_key_not_clustered(0),
- part_of_sortkey(0), unireg_check(unireg_check_arg),
- field_length(length_arg), null_bit(null_bit_arg),
- is_created_from_null_item(FALSE),
- vcol_info(0), stored_in_db(TRUE)
+ :ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0),
+ table_name(0), field_name(field_name_arg), option_list(0),
+ option_struct(0), key_start(0), part_of_key(0),
+ part_of_key_not_clustered(0), part_of_sortkey(0),
+ unireg_check(unireg_check_arg), field_length(length_arg),
+ null_bit(null_bit_arg), is_created_from_null_item(FALSE), vcol_info(0),
+ stored_in_db(TRUE)
{
flags=null_ptr ? 0: NOT_NULL_FLAG;
comment.str= (char*) "";
@@ -9567,7 +9566,8 @@
Item *fld_on_update_value, LEX_STRING *fld_comment,
char *fld_change, List<String> *fld_interval_list,
CHARSET_INFO *fld_charset, uint fld_geom_type,
- Virtual_column_info *fld_vcol_info)
+ Virtual_column_info *fld_vcol_info,
+ engine_option_value *create_opt)
{
uint sign_len, allowed_type_modifier= 0;
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
@@ -9578,6 +9578,7 @@
field_name= fld_name;
def= fld_default_value;
flags= fld_type_modifier;
+ option_list= create_opt;
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
Field::NEXT_NUMBER : Field::NONE);
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
@@ -10217,6 +10218,8 @@
decimals= old_field->decimals();
vcol_info= old_field->vcol_info;
stored_in_db= old_field->stored_in_db;
+ option_list= old_field->option_list;
+ option_struct= old_field->option_struct;
/* Fix if the original table had 4 byte pointer blobs */
if (flags & BLOB_FLAG)
@@ -10291,6 +10294,19 @@
/**
+ Makes a clone of this object for ALTER/CREATE TABLE
+
+ @param mem_root MEM_ROOT where to clone the field
+*/
+
+Create_field *Create_field::clone(MEM_ROOT *mem_root) const
+{
+ Create_field *res= new (mem_root) Create_field(*this);
+ return res;
+}
+
+
+/**
maximum possible display length for blob.
@return
=== modified file 'sql/field.h'
--- a/sql/field.h 2010-03-15 11:51:23 +0000
+++ b/sql/field.h 2010-04-05 08:49:56 +0000
@@ -137,6 +137,9 @@
struct st_table *table; // Pointer for table
struct st_table *orig_table; // Pointer to original table
const char **table_name, *field_name;
+ /** reference to the list of options or NULL */
+ engine_option_value *option_list;
+ void *option_struct; /* structure with parsed options */
LEX_STRING comment;
/* Field is part of the following keys */
key_map key_start, part_of_key, part_of_key_not_clustered;
@@ -2145,6 +2148,9 @@
CHARSET_INFO *charset;
Field::geometry_type geom_type;
Field *field; // For alter table
+ engine_option_value *option_list;
+ /** structure with parsed options (for comparing fields in ALTER TABLE) */
+ void *option_struct;
uint8 row,col,sc_length,interval_id; // For rea_create_table
uint offset,pack_flag;
@@ -2162,11 +2168,11 @@
*/
bool stored_in_db;
- Create_field() :after(0) {}
+ Create_field() :after(0), option_list(NULL), option_struct(NULL)
+ {}
Create_field(Field *field, Field *orig_field);
/* Used to make a clone of this object for ALTER/CREATE TABLE */
- Create_field *clone(MEM_ROOT *mem_root) const
- { return new (mem_root) Create_field(*this); }
+ Create_field *clone(MEM_ROOT *mem_root) const;
void create_length_to_internal_length(void);
/* Init for a tmp table field. To be extended if need be. */
@@ -2178,8 +2184,8 @@
char *decimals, uint type_modifier, Item *default_value,
Item *on_update_value, LEX_STRING *comment, char *change,
List<String> *interval_list, CHARSET_INFO *cs,
- uint uint_geom_type,
- Virtual_column_info *vcol_info);
+ uint uint_geom_type, Virtual_column_info *vcol_info,
+ engine_option_value *option_list);
bool field_flags_are_binary()
{
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2010-03-15 11:51:23 +0000
+++ b/sql/ha_partition.cc 2010-04-05 08:49:56 +0000
@@ -1218,7 +1218,9 @@
DBUG_ENTER("prepare_new_partition");
if ((error= set_up_table_before_create(tbl, part_name, create_info,
- 0, p_elem)))
+ 0, p_elem)) ||
+ parse_engine_table_options(ha_thd(), file->ht,
+ file->table_share))
goto error_create;
if ((error= file->ha_create(part_name, tbl, create_info)))
{
@@ -1869,6 +1871,8 @@
{
if ((error= set_up_table_before_create(table_arg, from_buff,
create_info, i, NULL)) ||
+ parse_engine_table_options(ha_thd(), (*file)->ht,
+ (*file)->table_share) ||
((error= (*file)->ha_create(from_buff, table_arg, create_info))))
goto create_error;
}
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-03-15 11:51:23 +0000
+++ b/sql/handler.cc 2010-04-05 08:49:56 +0000
@@ -3716,7 +3716,12 @@
name= get_canonical_filename(table.file, share.path.str, name_buff);
+ if (parse_engine_table_options(thd, table.file->ht, &share))
+ goto err;
+
error= table.file->ha_create(name, &table, create_info);
+
+
VOID(closefrm(&table, 0));
if (error)
{
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2010-02-01 06:14:12 +0000
+++ b/sql/handler.h 2010-04-05 08:49:56 +0000
@@ -16,6 +16,9 @@
/* Definitions for parameters to do with handler-routines */
+#ifndef SQL_HANDLER_INCLUDED
+#define SQL_HANDLER_INCLUDED
+
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
@@ -23,6 +26,7 @@
#include <my_handler.h>
#include <ft_global.h>
#include <keycache.h>
+#include "create_options.h"
#ifndef NO_HASH
#define NO_HASH /* Not yet implemented */
@@ -516,6 +520,7 @@
struct st_table;
typedef struct st_table TABLE;
typedef struct st_table_share TABLE_SHARE;
+class engine_option;
struct st_foreign_key_info;
typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len,
@@ -549,6 +554,65 @@
enum log_status status;
};
+enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */
+ HA_OPTION_TYPE_STRING, /* char * */
+ HA_OPTION_TYPE_ENUM, /* uint */
+ HA_OPTION_TYPE_BOOL}; /* bool */
+
+#define HA_xOPTION_ULL(name, struc, field, def, min, max, blk_siz) \
+ { HA_OPTION_TYPE_ULL, name, sizeof(name)-1, \
+ offsetof(struc, field), def, min, max, blk_siz, 0 }
+#define HA_xOPTION_STRING(name, struc, field) \
+ { HA_OPTION_TYPE_STRING, name, sizeof(name)-1, \
+ offsetof(struc, field), 0, 0, 0, 0, 0 }
+#define HA_xOPTION_ENUM(name, struc, field, values, def) \
+ { HA_OPTION_TYPE_ENUM, name, sizeof(name)-1, \
+ offsetof(struc, field), def, 0, \
+ sizeof(values)-1, 0, values }
+#define HA_xOPTION_BOOL(name, struc, field, def) \
+ { HA_OPTION_TYPE_BOOL, name, sizeof(name)-1, \
+ offsetof(struc, field), def, 0, 1, 0, 0 }
+#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0 }
+
+#define HA_TOPTION_ULL(name, field, def, min, max, blk_siz) \
+ HA_xOPTION_ULL(name, ha_table_option_struct, field, def, min, max, blk_siz)
+#define HA_TOPTION_STRING(name, field) \
+ HA_xOPTION_STRING(name, ha_table_option_struct, field)
+#define HA_TOPTION_ENUM(name, field, values, def) \
+ HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def)
+#define HA_TOPTION_BOOL(name, field, def) \
+ HA_xOPTION_BOOL(name, ha_table_option_struct, field, def)
+#define HA_TOPTION_END HA_xOPTION_END
+
+#define HA_FOPTION_ULL(name, field, def, min, max, blk_siz) \
+ HA_xOPTION_ULL(name, ha_field_option_struct, field, def, min, max, blk_siz)
+#define HA_FOPTION_STRING(name, field) \
+ HA_xOPTION_STRING(name, ha_field_option_struct, field)
+#define HA_FOPTION_ENUM(name, field, values, def) \
+ HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def)
+#define HA_FOPTION_BOOL(name, field, def) \
+ HA_xOPTION_BOOL(name, ha_field_option_struct, field, def)
+#define HA_FOPTION_END HA_xOPTION_END
+
+#define HA_KOPTION_ULL(name, field, def, min, max, blk_siz) \
+ HA_xOPTION_ULL(name, ha_key_option_struct, field, def, min, max, blk_siz)
+#define HA_KOPTION_STRING(name, field) \
+ HA_xOPTION_STRING(name, ha_key_option_struct, field)
+#define HA_KOPTION_ENUM(name, field, values, def) \
+ HA_xOPTION_ENUM(name, ha_key_option_struct, field, values, def)
+#define HA_KOPTION_BOOL(name, field, values, def) \
+ HA_xOPTION_BOOL(name, ha_key_option_struct, field, values, def)
+#define HA_KOPTION_END HA_xOPTION_END
+
+typedef struct st_ha_create_table_option {
+ enum ha_option_type type;
+ const char *name;
+ size_t name_length;
+ ptrdiff_t offset;
+ ulonglong def_value;
+ ulonglong min_value, max_value, block_size;
+ const char *values;
+} ha_create_table_option;
enum handler_iterator_type
{
@@ -721,7 +785,11 @@
int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
const char *name);
uint32 license; /* Flag for Engine License */
- void *data; /* Location for engines to keep personal structures */
+ /* CREATE OPTIONS rules for parameter parsing */
+ ha_create_table_option *table_opt_rules,
+ *field_opt_rules,
+ *key_opt_rules;
+
};
@@ -950,6 +1018,14 @@
bool varchar; /* 1 if table has a VARCHAR */
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
enum ha_choice page_checksum; /* If we have page_checksums */
+ engine_option_value *option_list; /* list of table create options */
+ /** structure with parsed options (for comparing fields in ALTER TABLE) */
+ void *option_struct;
+ /* following 4 fields assigned only for check_if_incompatible_data() */
+ void *old_option_struct;
+ void **old_new_fileds_option_struct[2];
+ void **old_new_keys_option_struct[2];
+ uint fields, keys;
} HA_CREATE_INFO;
@@ -2241,3 +2317,5 @@
#define ha_binlog_wait(a) do {} while (0)
#define ha_binlog_end(a) do {} while (0)
#endif
+
+#endif
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2010-03-15 11:51:23 +0000
+++ b/sql/log_event.h 2010-04-05 08:49:56 +0000
@@ -1371,7 +1371,7 @@
MODE_PIPES_AS_CONCAT==0x2
MODE_ANSI_QUOTES==0x4
MODE_IGNORE_SPACE==0x8
- MODE_NOT_USED==0x10
+ MODE_CREATE_OPTIONS_NOERR==0x10
MODE_ONLY_FULL_GROUP_BY==0x20
MODE_NO_UNSIGNED_SUBTRACTION==0x40
MODE_NO_DIR_IN_CREATE==0x80
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2010-03-15 11:51:23 +0000
+++ b/sql/mysql_priv.h 2010-04-05 08:49:56 +0000
@@ -54,7 +54,6 @@
#include "sql_plugin.h"
#include "scheduler.h"
#include "log_slow.h"
-
class Parser_state;
/**
@@ -520,7 +519,7 @@
#define MODE_PIPES_AS_CONCAT 2
#define MODE_ANSI_QUOTES 4
#define MODE_IGNORE_SPACE 8
-#define MODE_NOT_USED 16
+#define MODE_CREATE_OPTIONS_NOERR 16
#define MODE_ONLY_FULL_GROUP_BY 32
#define MODE_NO_UNSIGNED_SUBTRACTION 64
#define MODE_NO_DIR_IN_CREATE 128
@@ -783,6 +782,7 @@
ulonglong *engine_data);
#include "sql_string.h"
#include "sql_list.h"
+#include "create_options.h"
#include "sql_map.h"
#include "my_decimal.h"
#include "handler.h"
@@ -1508,7 +1508,8 @@
char *change, List<String> *interval_list,
CHARSET_INFO *cs,
uint uint_geom_type,
- Virtual_column_info *vcol_info);
+ Virtual_column_info *vcol_info,
+ engine_option_value *create_options);
Create_field * new_create_field(THD *thd, char *field_name, enum_field_types type,
char *length, char *decimals,
uint type_modifier,
@@ -2625,4 +2626,14 @@
#endif /* MYSQL_CLIENT */
+/* Define to force use of my_malloc() if the allocated memory block is big */
+
+#ifndef HAVE_ALLOCA
+#define my_safe_alloca(size, min_length) my_alloca(size)
+#define my_safe_afree(ptr, size, min_length) my_afree(ptr)
+#else
+#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(0)))
+#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0))
+#endif
+
#endif /* MYSQL_PRIV_H */
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-15 11:51:23 +0000
+++ b/sql/mysqld.cc 2010-04-05 08:49:56 +0000
@@ -243,7 +243,7 @@
static const char *sql_mode_names[]=
{
"REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
- "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
+ "CREATE_OPTIONS_NOERR", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
"NO_DIR_IN_CREATE",
"POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
"NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
@@ -263,7 +263,7 @@
/*PIPES_AS_CONCAT*/ 15,
/*ANSI_QUOTES*/ 11,
/*IGNORE_SPACE*/ 12,
- /*?*/ 1,
+ /*CREATE_OPTIONS_NOERR*/ 20,
/*ONLY_FULL_GROUP_BY*/ 18,
/*NO_UNSIGNED_SUBTRACTION*/ 23,
/*NO_DIR_IN_CREATE*/ 16,
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2010-03-15 11:51:23 +0000
+++ b/sql/share/errmsg.txt 2010-04-05 08:49:56 +0000
@@ -6240,3 +6240,8 @@
ER_DEBUG_SYNC_HIT_LIMIT
eng "debug sync point hit limit reached"
ger "Debug Sync Point Hit Limit erreicht"
+
+ER_UNKNOWN_OPTION
+ eng "Unknown option '%-.64s'"
+ER_BAD_OPTION_VALUE
+ eng "Incorrect value '%-.64s' for option '%-.64s'"
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sp.cc 2010-04-05 08:49:56 +0000
@@ -147,7 +147,8 @@
{
{ C_STRING_WITH_LEN("sql_mode") },
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
- "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
+ "'IGNORE_SPACE','CREATE_OPTIONS_NOERR','ONLY_FULL_GROUP_BY',"
+ "'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sp_head.cc 2010-04-05 08:49:56 +0000
@@ -2216,7 +2216,7 @@
lex->charset ? lex->charset :
thd->variables.collation_database,
lex->uint_geom_type,
- lex->vcol_info))
+ lex->vcol_info, NULL))
return TRUE;
if (field_def->interval_list.elements)
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-03-16 12:38:35 +0000
+++ b/sql/sql_class.cc 2010-04-05 08:49:56 +0000
@@ -106,6 +106,7 @@
key_create_info(rhs.key_create_info),
columns(rhs.columns, mem_root),
name(rhs.name),
+ option_list(rhs.option_list),
generated(rhs.generated)
{
list_copy_and_replace_each_value(columns, mem_root);
@@ -775,6 +776,7 @@
void THD::push_internal_handler(Internal_error_handler *handler)
{
+ DBUG_ENTER("THD::push_internal_handler");
if (m_internal_handler)
{
handler->m_prev_internal_handler= m_internal_handler;
@@ -784,6 +786,7 @@
{
m_internal_handler= handler;
}
+ DBUG_VOID_RETURN;
}
@@ -803,8 +806,10 @@
void THD::pop_internal_handler()
{
+ DBUG_ENTER("THD::pop_internal_handler");
DBUG_ASSERT(m_internal_handler != NULL);
m_internal_handler= m_internal_handler->m_prev_internal_handler;
+ DBUG_VOID_RETURN;
}
extern "C"
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_class.h 2010-04-05 08:49:56 +0000
@@ -204,13 +204,15 @@
KEY_CREATE_INFO key_create_info;
List<Key_part_spec> columns;
const char *name;
+ engine_option_value *option_list;
bool generated;
Key(enum Keytype type_par, const char *name_arg,
KEY_CREATE_INFO *key_info_arg,
- bool generated_arg, List<Key_part_spec> &cols)
+ bool generated_arg, List<Key_part_spec> &cols,
+ engine_option_value *create_opt)
:type(type_par), key_create_info(*key_info_arg), columns(cols),
- name(name_arg), generated(generated_arg)
+ name(name_arg), option_list(create_opt), generated(generated_arg)
{}
Key(const Key &rhs, MEM_ROOT *mem_root);
virtual ~Key() {}
@@ -239,7 +241,7 @@
Foreign_key(const char *name_arg, List<Key_part_spec> &cols,
Table_ident *table, List<Key_part_spec> &ref_cols,
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
- :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols),
+ :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL),
ref_table(table), ref_columns(ref_cols),
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
match_opt(match_opt_arg)
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_insert.cc 2010-04-05 08:49:56 +0000
@@ -72,15 +72,6 @@
#endif
static bool check_view_insertability(THD *thd, TABLE_LIST *view);
-/* Define to force use of my_malloc() if the allocated memory block is big */
-
-#ifndef HAVE_ALLOCA
-#define my_safe_alloca(size, min_length) my_alloca(size)
-#define my_safe_afree(ptr, size, min_length) my_afree(ptr)
-#else
-#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(0)))
-#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0))
-#endif
/*
Check that insert/update fields are from the same single table of a view.
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_lex.h 2010-04-05 08:49:56 +0000
@@ -1747,6 +1747,11 @@
const char *stmt_definition_end;
/**
+ Collects create options for Field and KEY
+ */
+ engine_option_value *option_list, *option_list_last;
+
+ /**
During name resolution search only in the table list given by
Name_resolution_context::first_name_resolution_table and
Name_resolution_context::last_name_resolution_table
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-03-16 12:38:35 +0000
+++ b/sql/sql_parse.cc 2010-04-05 08:49:56 +0000
@@ -6155,7 +6155,8 @@
char *change,
List<String> *interval_list, CHARSET_INFO *cs,
uint uint_geom_type,
- Virtual_column_info *vcol_info)
+ Virtual_column_info *vcol_info,
+ engine_option_value *create_options)
{
register Create_field *new_field;
LEX *lex= thd->lex;
@@ -6173,7 +6174,7 @@
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
key= new Key(Key::PRIMARY, NullS,
&default_key_create_info,
- 0, lex->col_list);
+ 0, lex->col_list, NULL);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty();
}
@@ -6183,7 +6184,7 @@
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
key= new Key(Key::UNIQUE, NullS,
&default_key_create_info, 0,
- lex->col_list);
+ lex->col_list, NULL);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty();
}
@@ -6241,7 +6242,8 @@
if (!(new_field= new Create_field()) ||
new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
default_value, on_update_value, comment, change,
- interval_list, cs, uint_geom_type, vcol_info))
+ interval_list, cs, uint_geom_type, vcol_info,
+ create_options))
DBUG_RETURN(1);
lex->alter_info.create_list.push_back(new_field);
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_show.cc 2010-04-05 08:49:56 +0000
@@ -951,6 +951,30 @@
DBUG_RETURN(0);
}
+
+/**
+ Goes through all character combinations and ensure that it is number.
+
+ @param name attribute name
+ @param name_length length of name
+
+ @retval # Pointer to conflicting character
+ @retval 0 No conflicting character
+*/
+
+static const char *is_unsigned_number(const char *name, uint name_length)
+{
+ const char *end= name + name_length;
+
+ for (; name < end ; name++)
+ {
+ uchar chr= (uchar) *name;
+ if (chr < '0' || chr > '9')
+ return name;
+ }
+ return 0;
+}
+
/*
Go through all character combinations and ensure that sql_lex.cc can
parse it as an identifier.
@@ -1013,7 +1037,7 @@
/*
The identifier must be quoted as it includes a quote character or
- it's a keyword
+ it's a keyword
*/
VOID(packet->reserve(length*2 + 2));
@@ -1076,7 +1100,6 @@
return '`';
}
-
/* Append directory name (if exists) to CREATE INFO */
static void append_directory(THD *thd, String *packet, const char *dir_type,
@@ -1173,6 +1196,32 @@
return has_default;
}
+
+/**
+ Appends list of options to string
+
+ @param thd thread handler
+ @param packet string to append
+ @param opt list of options
+*/
+
+static void append_create_options(THD *thd, String *packet,
+ engine_option_value *opt)
+{
+ for(; opt; opt= opt->next)
+ {
+ DBUG_ASSERT(opt->value.str);
+ packet->append(' ');
+ append_identifier(thd, packet, opt->name.str, opt->name.length);
+ packet->append('=');
+ if (!opt->quoted_value && opt->value.length < 21 &&
+ is_unsigned_number(opt->value.str, opt->value.length) == NULL)
+ packet->append(opt->value.str, opt->value.length);
+ else
+ append_unescaped(packet, opt->value.str, opt->value.length);
+ }
+}
+
/*
Build a CREATE TABLE statement for a table.
@@ -1355,6 +1404,8 @@
packet->append(STRING_WITH_LEN(" COMMENT "));
append_unescaped(packet, field->comment.str, field->comment.length);
}
+ if (field->option_list)
+ append_create_options(thd, packet, field->option_list);
}
key_info= table->key_info;
@@ -1426,6 +1477,8 @@
append_identifier(thd, packet, parser_name->str, parser_name->length);
packet->append(STRING_WITH_LEN(" */ "));
}
+ if (key_info->option_list)
+ append_create_options(thd, packet, key_info->option_list);
}
/*
@@ -1585,6 +1638,10 @@
packet->append(STRING_WITH_LEN(" CONNECTION="));
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
}
+ /* create_table_options can be NULL for temporary tables */
+ if (share->option_list)
+ append_create_options(thd, packet,
+ share->option_list);
append_directory(thd, packet, "DATA", create_info.data_file_name);
append_directory(thd, packet, "INDEX", create_info.index_file_name);
}
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_table.cc 2010-04-05 08:49:56 +0000
@@ -2863,6 +2863,11 @@
sql_field->offset= record_offset;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
auto_increment++;
+ if (parse_option_list(thd, &sql_field->option_struct,
+ sql_field->option_list,
+ create_info->db_type->field_opt_rules, FALSE,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
/*
For now skip fields that are not physically stored in the database
(virtual fields) and update their offset later
@@ -3061,6 +3066,12 @@
key_info->key_part=key_part_info;
key_info->usable_key_parts= key_number;
key_info->algorithm= key->key_create_info.algorithm;
+ key_info->option_list= key->option_list;
+ if (parse_option_list(thd, &key_info->option_struct,
+ key_info->option_list,
+ create_info->db_type->key_opt_rules, FALSE,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
if (key->type == Key::FULLTEXT)
{
@@ -3438,6 +3449,12 @@
}
}
+ if (parse_option_list(thd, &create_info->option_struct,
+ create_info->option_list,
+ create_info->db_type->table_opt_rules, FALSE,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
+
DBUG_RETURN(FALSE);
}
@@ -5679,6 +5696,7 @@
KEY_PART_INFO *key_part;
KEY_PART_INFO *end;
THD *thd= table->in_use;
+ uint i;
/*
Remember if the new definition has new VARCHAR column;
create_info->varchar will be reset in mysql_prepare_create_table.
@@ -5766,6 +5784,25 @@
DBUG_RETURN(0);
}
+ create_info->fields= table->s->fields;
+ create_info->keys= table->s->keys;
+ if (!(create_info->old_new_fileds_option_struct[0]=
+ (void**)thd->alloc(sizeof(void*) * 2 * (create_info->fields) +
+ sizeof(void*) * 2 * (create_info->keys))))
+ DBUG_RETURN(1);
+ bzero(create_info->old_new_fileds_option_struct[0],
+ sizeof(void*) * 2 * (create_info->fields) +
+ sizeof(void*) * 2 * (create_info->keys));
+ create_info->old_new_fileds_option_struct[1]=
+ create_info->old_new_fileds_option_struct[0] +
+ sizeof(void*) * (create_info->fields);
+ create_info->old_new_keys_option_struct[0]=
+ create_info->old_new_fileds_option_struct[1] +
+ sizeof(void*) * (create_info->fields);
+ create_info->old_new_keys_option_struct[1]=
+ create_info->old_new_keys_option_struct[0] +
+ sizeof(void*) * (create_info->keys);
+
/*
Use transformed info to evaluate possibility of fast ALTER TABLE
but use the preserved field to persist modifications.
@@ -5776,12 +5813,15 @@
/* Go through fields and check if the original ones are compatible
with new table.
*/
- for (f_ptr= table->field, new_field= new_field_it++,
+ for (i= 0, f_ptr= table->field, new_field= new_field_it++,
tmp_new_field= tmp_new_field_it++;
(field= *f_ptr);
+ i++,
f_ptr++, new_field= new_field_it++,
tmp_new_field= tmp_new_field_it++)
{
+ create_info->old_new_fileds_option_struct[0][i]= field->option_struct;
+
/* Make sure we have at least the default charset in use. */
if (!new_field->charset)
new_field->charset= create_info->default_table_charset;
@@ -5809,6 +5849,10 @@
DBUG_RETURN(0);
}
+ /* to allow check_if_incompatible_data compare */
+ create_info->old_new_fileds_option_struct[1][i]=
+ tmp_new_field->option_struct;
+
/* Don't pack rows in old tables if the user has requested this. */
if (create_info->row_type == ROW_TYPE_DYNAMIC ||
(tmp_new_field->flags & BLOB_FLAG) ||
@@ -5934,8 +5978,9 @@
/*
Step through all keys of the new table and find matching old keys.
*/
- for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
+ for (i= 0, new_key= *key_info_buffer; new_key < new_key_end; i++, new_key++)
{
+ create_info->old_new_keys_option_struct[0][i]= new_key->option_struct;
/* Search an old key with the same name. */
for (table_key= table->key_info; table_key < table_key_end; table_key++)
{
@@ -5956,9 +6001,13 @@
}
DBUG_PRINT("info", ("index added: '%s'", new_key->name));
}
+ else
+ create_info->old_new_keys_option_struct[1][i]=
+ new_key->option_struct;
}
/* Check if changes are compatible with current handler without a copy */
+ create_info->old_option_struct= table->s->option_struct;
if (table->file->check_if_incompatible_data(create_info, changes))
{
DBUG_PRINT("info", ("check_if_incompatible_data() -> "
@@ -6132,6 +6181,16 @@
}
restore_record(table, s->default_values); // Empty record for DEFAULT
+ if (create_info->option_list)
+ {
+ create_info->option_list=
+ merge_engine_table_options(table->s->option_list,
+ create_info->option_list,
+ thd->mem_root);
+ }
+ else
+ create_info->option_list= table->s->option_list;
+
/*
First collect all fields from table which isn't in drop_list
*/
@@ -6384,7 +6443,7 @@
key= new Key(key_type, key_name,
&key_create_info,
test(key_info->flags & HA_GENERATED_KEY),
- key_parts);
+ key_parts, key_info->option_list);
new_key_list.push_back(key);
}
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_view.cc 2010-04-05 08:49:56 +0000
@@ -1183,7 +1183,7 @@
+ MODE_PIPES_AS_CONCAT affect expression parsing
+ MODE_ANSI_QUOTES affect expression parsing
+ MODE_IGNORE_SPACE affect expression parsing
- - MODE_NOT_USED not used :)
+ - MODE_CREATE_OPTIONS_NOERR affect only CREATE/ALTER TABLE parsing
* MODE_ONLY_FULL_GROUP_BY affect execution
* MODE_NO_UNSIGNED_SUBTRACTION affect execution
- MODE_NO_DIR_IN_CREATE affect table creation only
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-03-15 11:51:23 +0000
+++ b/sql/sql_yacc.yy 2010-04-05 08:49:56 +0000
@@ -607,6 +607,7 @@
lex->alter_info.flags= ALTER_ADD_INDEX;
lex->col_list.empty();
lex->change= NullS;
+ lex->option_list= lex->option_list_last= NULL;
return FALSE;
}
@@ -616,7 +617,7 @@
{
Key *key;
key= new Key(type, name, info ? info : &lex->key_create_info, generated,
- lex->col_list);
+ lex->col_list, lex->option_list);
if (key == NULL)
return TRUE;
@@ -3895,7 +3896,11 @@
;
create2a:
- field_list ')' opt_create_table_options
+ field_list ')'
+ {
+ Lex->create_info.option_list= Lex->option_list_last= NULL;
+ }
+ opt_create_table_options
opt_partitioning
create3 {}
| opt_partitioning
@@ -4748,6 +4753,39 @@
Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
Lex->create_info.transactional= $3;
}
+ | IDENT_sys equal TEXT_STRING_sys
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->create_info.option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ident
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->create_info.option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ulonglong_num
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3,
+ &Lex->create_info.option_list,
+ &Lex->option_list_last,
+ YYTHD->mem_root);
+ }
+ | IDENT_sys equal DEFAULT
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ NULL, 0,
+ &Lex->create_info.option_list,
+ &Lex->option_list_last);
+ }
;
default_charset:
@@ -4869,25 +4907,33 @@
;
key_def:
- normal_key_type opt_ident key_alg '(' key_list ')' normal_key_options
+ normal_key_type opt_ident key_alg '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ normal_key_options
{
if (add_create_index (Lex, $1, $2))
MYSQL_YYABORT;
}
| fulltext opt_key_or_index opt_ident init_key_options
- '(' key_list ')' fulltext_key_options
+ '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ fulltext_key_options
{
if (add_create_index (Lex, $1, $3))
MYSQL_YYABORT;
}
| spatial opt_key_or_index opt_ident init_key_options
- '(' key_list ')' spatial_key_options
+ '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ spatial_key_options
{
if (add_create_index (Lex, $1, $3))
MYSQL_YYABORT;
}
| opt_constraint constraint_key_type opt_ident key_alg
- '(' key_list ')' normal_key_options
+ '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ normal_key_options
{
if (add_create_index (Lex, $2, $3 ? $3 : $1))
MYSQL_YYABORT;
@@ -4950,6 +4996,7 @@
lex->comment=null_lex_str;
lex->charset=NULL;
lex->vcol_info= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
field_def
{
@@ -4960,7 +5007,7 @@
&lex->comment,
lex->change,&lex->interval_list,lex->charset,
lex->uint_geom_type,
- lex->vcol_info))
+ lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
}
;
@@ -5380,6 +5427,39 @@
Lex->charset=$2;
}
}
+ | IDENT_sys equal TEXT_STRING_sys
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ident
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ulonglong_num
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3,
+ &Lex->option_list,
+ &Lex->option_list_last,
+ YYTHD->mem_root);
+ }
+ | IDENT_sys equal DEFAULT
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ NULL, 0,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
;
now_or_signed_literal:
@@ -5669,6 +5749,39 @@
all_key_opt:
KEY_BLOCK_SIZE opt_equal ulong_num
{ Lex->key_create_info.block_size= $3; }
+ | IDENT_sys equal TEXT_STRING_sys
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ident
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
+ | IDENT_sys equal ulonglong_num
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3,
+ &Lex->option_list,
+ &Lex->option_list_last,
+ YYTHD->mem_root);
+ }
+ | IDENT_sys equal DEFAULT
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ NULL, 0,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ }
;
normal_key_opt:
@@ -6158,6 +6271,7 @@
LEX *lex=Lex;
lex->change= $3.str;
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
+ lex->option_list= lex->option_list_last= NULL;
}
field_spec opt_place
| MODIFY_SYM opt_column field_ident
@@ -6169,6 +6283,7 @@
lex->charset= NULL;
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
lex->vcol_info= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
field_def
{
@@ -6180,7 +6295,7 @@
&lex->comment,
$3.str, &lex->interval_list, lex->charset,
lex->uint_geom_type,
- lex->vcol_info))
+ lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
}
opt_place
@@ -6287,8 +6402,7 @@
}
| create_table_options_space_separated
{
- LEX *lex=Lex;
- lex->alter_info.flags|= ALTER_OPTIONS;
+ Lex->alter_info.flags|= ALTER_OPTIONS;
}
| FORCE_SYM
{
@@ -13630,6 +13744,7 @@
lex->interval_list.empty();
lex->type= 0;
lex->vcol_info= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
type /* $11 */
{ /* $12 */
@@ -13880,6 +13995,7 @@
}
;
+
/**
@} (end of group Parser)
*/
=== modified file 'sql/structs.h'
--- a/sql/structs.h 2010-02-01 06:14:12 +0000
+++ b/sql/structs.h 2010-04-05 08:49:56 +0000
@@ -68,6 +68,7 @@
uint8 null_bit; /* Position to null_bit */
} KEY_PART_INFO ;
+class engine_option_value;
typedef struct st_key {
uint key_length; /* Tot length of key */
@@ -101,6 +102,9 @@
int bdb_return_if_eq;
} handler;
struct st_table *table;
+ /** reference to the list of options or NULL */
+ engine_option_value *option_list;
+ void *option_struct; /* structure with parsed options */
} KEY;
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2010-03-15 11:51:23 +0000
+++ b/sql/table.cc 2010-04-05 08:49:56 +0000
@@ -667,12 +667,13 @@
uint db_create_options, keys, key_parts, n_length;
uint key_info_length, com_length, null_bit_pos;
uint vcol_screen_length;
- uint extra_rec_buf_length;
+ uint extra_rec_buf_length, options_len;
uint i,j;
bool use_hash;
char *keynames, *names, *comment_pos, *vcol_screen_pos;
uchar *record;
- uchar *disk_buff, *strpos, *null_flags, *null_pos;
+ uchar *disk_buff, *strpos, *null_flags, *null_pos, *options;
+ uchar *buff= 0;
ulong pos, record_offset, *rec_per_key, rec_buff_length;
handler *handler_file= 0;
KEY *keyinfo;
@@ -788,7 +789,6 @@
for (i=0 ; i < keys ; i++, keyinfo++)
{
- keyinfo->table= 0; // Updated in open_frm
if (new_frm_ver >= 3)
{
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
@@ -858,15 +858,14 @@
if ((n_length= uint4korr(head+55)))
{
/* Read extra data segment */
- uchar *buff, *next_chunk, *buff_end;
+ uchar *next_chunk, *buff_end;
DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
goto err;
if (my_pread(file, buff, n_length, record_offset + share->reclength,
MYF(MY_NABP)))
{
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
share->connect_string.length= uint2korr(buff);
if (!(share->connect_string.str= strmake_root(&share->mem_root,
@@ -874,8 +873,7 @@
share->connect_string.
length)))
{
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
next_chunk+= share->connect_string.length + 2;
buff_end= buff + n_length;
@@ -895,8 +893,7 @@
plugin_data(tmp_plugin, handlerton *)))
{
/* bad file, legacy_db_type did not match the name */
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
/*
tmp_plugin is locked with a local lock.
@@ -925,8 +922,7 @@
error= 8;
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"--skip-partition");
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
plugin_unlock(NULL, share->db_plugin);
share->db_plugin= ha_lock_engine(NULL, partition_hton);
@@ -940,8 +936,7 @@
/* purecov: begin inspected */
error= 8;
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
/* purecov: end */
}
next_chunk+= str_db_type_length + 2;
@@ -957,16 +952,14 @@
memdup_root(&share->mem_root, next_chunk + 4,
partition_info_len + 1)))
{
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
}
#else
if (partition_info_len)
{
DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined"));
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
#endif
next_chunk+= 5 + partition_info_len;
@@ -992,6 +985,16 @@
#endif
next_chunk++;
}
+ if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
+ {
+ /*
+ store options position, but skip till the time we will
+ know number of fields
+ */
+ options_len= uint4korr(next_chunk);
+ options= next_chunk + 4;
+ next_chunk+= options_len + 4;
+ }
keyinfo= share->key_info;
for (i= 0; i < keys; i++, keyinfo++)
{
@@ -1002,8 +1005,7 @@
{
DBUG_PRINT("error",
("fulltext key uses parser that is not defined in .frm"));
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
parser_name.str= (char*) next_chunk;
parser_name.length= strlen((char*) next_chunk);
@@ -1013,12 +1015,10 @@
if (! keyinfo->parser)
{
my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str);
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
}
}
- my_free(buff, MYF(0));
}
share->key_block_size= uint2korr(head+62);
@@ -1028,21 +1028,21 @@
share->rec_buff_length= rec_buff_length;
if (!(record= (uchar *) alloc_root(&share->mem_root,
rec_buff_length)))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
share->default_values= record;
if (my_pread(file, record, (size_t) share->reclength,
record_offset, MYF(MY_NABP)))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
if (my_read(file, head,288,MYF(MY_NABP)))
- goto err;
+ goto free_and_err;
#ifdef HAVE_CRYPTED_FRM
if (crypted)
{
crypted->decode((char*) head+256,288-256);
if (sint2korr(head+284) != 0) // Should be 0
- goto err; // Wrong password
+ goto free_and_err; // Wrong password
}
#endif
@@ -1062,6 +1062,8 @@
share->comment.length);
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length, vcol_screen_length));
+
+
if (!(field_ptr = (Field **)
alloc_root(&share->mem_root,
(uint) ((share->fields+1)*sizeof(Field*)+
@@ -1070,14 +1072,14 @@
keys+3)*sizeof(char *)+
(n_length+int_length+com_length+
vcol_screen_length)))))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
share->field= field_ptr;
read_length=(uint) (share->fields * field_pack_length +
pos+ (uint) (n_length+int_length+com_length+
vcol_screen_length));
if (read_string(file,(uchar**) &disk_buff,read_length))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
#ifdef HAVE_CRYPTED_FRM
if (crypted)
{
@@ -1104,7 +1106,7 @@
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
if (share->fieldnames.count != share->fields)
- goto err;
+ goto free_and_err;
fix_type_pointers(&interval_array, share->intervals, interval_count,
&names);
@@ -1118,7 +1120,7 @@
uint count= (uint) (interval->count + 1) * sizeof(uint);
if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
count)))
- goto err;
+ goto free_and_err;
for (count= 0; count < interval->count; count++)
{
char *val= (char*) interval->type_names[count];
@@ -1134,7 +1136,7 @@
/* Allocate handler */
if (!(handler_file= get_new_handler(share, thd->mem_root,
share->db_type())))
- goto err;
+ goto free_and_err;
record= share->default_values-1; /* Fieldstart = 1 */
if (share->null_field_first)
@@ -1196,7 +1198,7 @@
charset= &my_charset_bin;
#else
error= 4; // unsupported field type
- goto err;
+ goto free_and_err;
#endif
}
else
@@ -1207,7 +1209,7 @@
{
error= 5; // Unknown or unavailable charset
errarg= (int) strpos[14];
- goto err;
+ goto free_and_err;
}
}
@@ -1247,7 +1249,7 @@
if ((uint)vcol_screen_pos[0] != 1)
{
error= 4;
- goto err;
+ goto free_and_err;
}
field_type= (enum_field_types) (uchar) vcol_screen_pos[1];
fld_stored_in_db= (bool) (uint) vcol_screen_pos[2];
@@ -1256,7 +1258,7 @@
(char *)memdup_root(&share->mem_root,
vcol_screen_pos+(uint)FRM_VCOL_HEADER_SIZE,
vcol_expr_length)))
- goto err;
+ goto free_and_err;
vcol_info->expr_str.length= vcol_expr_length;
vcol_screen_pos+= vcol_info_length;
share->vfields++;
@@ -1346,7 +1348,7 @@
if (!reg_field) // Not supported field type
{
error= 4;
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
}
reg_field->field_index= i;
@@ -1385,7 +1387,7 @@
sent (OOM).
*/
error= 8;
- goto err;
+ goto free_and_err;
}
}
if (!reg_field->stored_in_db)
@@ -1462,7 +1464,7 @@
if (!key_part->fieldnr)
{
error= 4; // Wrong file
- goto err;
+ goto free_and_err;
}
field= key_part->field= share->field[key_part->fieldnr-1];
key_part->type= field->key_type();
@@ -1627,6 +1629,15 @@
null_length, 255);
}
+ if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
+ {
+ DBUG_ASSERT(options_len);
+ if (engine_table_options_frm_read(options, options_len, share) ||
+ parse_engine_table_options(thd, handler_file->ht, share))
+ goto free_and_err;
+ }
+ my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
+
if (share->found_next_number_field)
{
reg_field= *share->found_next_number_field;
@@ -1685,6 +1696,8 @@
#endif
DBUG_RETURN (0);
+ free_and_err:
+ my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
err:
share->error= error;
share->open_errno= my_errno;
@@ -2883,6 +2896,7 @@
ulong length;
uchar fill[IO_SIZE];
int create_flags= O_RDWR | O_TRUNC;
+ DBUG_ENTER("create_frm");
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
create_flags|= O_EXCL | O_NOFOLLOW;
@@ -2964,7 +2978,7 @@
{
VOID(my_close(file,MYF(0)));
VOID(my_delete(name,MYF(0)));
- return(-1);
+ DBUG_RETURN(-1);
}
}
}
@@ -2975,7 +2989,7 @@
else
my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
}
- return (file);
+ DBUG_RETURN(file);
} /* create_frm */
@@ -2994,6 +3008,7 @@
create_info->comment= share->comment;
create_info->transactional= share->transactional;
create_info->page_checksum= share->page_checksum;
+ create_info->option_list= share->option_list;
DBUG_VOID_RETURN;
}
=== modified file 'sql/table.h'
--- a/sql/table.h 2010-02-12 08:47:31 +0000
+++ b/sql/table.h 2010-04-05 08:49:56 +0000
@@ -340,6 +340,8 @@
#ifdef NOT_YET
struct st_table *open_tables; /* link to open tables */
#endif
+ engine_option_value *option_list; /* text options for table */
+ void *option_struct; /* structure with parsed options */
/* The following is copied to each TABLE on OPEN */
Field **field;
=== modified file 'sql/unireg.cc'
--- a/sql/unireg.cc 2010-01-04 17:54:42 +0000
+++ b/sql/unireg.cc 2010-04-05 08:49:56 +0000
@@ -29,6 +29,9 @@
#define FCOMP 17 /* Bytes for a packed field */
+/* max length of options in frm which be allocated on stack */
+#define OPTIONS_ON_STACK 256
+
static uchar * pack_screens(List<Create_field> &create_fields,
uint *info_length, uint *screens, bool small_file);
static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info,
@@ -46,6 +49,18 @@
uint reclength, ulong data_offset,
handler *handler);
+/*
+ We declare engine_table_options_frm_length end
+ engine_table_options_frm_image here because
+ List, Create_field, KEY are not declared in create_options.h
+*/
+uint engine_table_options_frm_length(engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info);
+uchar *engine_table_options_frm_image(uchar *buff,
+ engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info);
/**
An interceptor to hijack ER_TOO_MANY_FIELDS error from
pack_screens and retry again without UNIREG screens.
@@ -75,6 +90,7 @@
return is_handled;
}
+
/*
Create a frm (table definition) file
@@ -107,6 +123,7 @@
ulong key_buff_length;
File file;
ulong filepos, data_offset;
+ uint options_len;
uchar fileinfo[64],forminfo[288],*keybuff;
TYPELIB formnames;
uchar *screen_buff;
@@ -183,6 +200,15 @@
create_info->extra_size+= key_info[i].parser_name->length + 1;
}
+ options_len= engine_table_options_frm_length(create_info->option_list,
+ create_fields,
+ keys, key_info);
+ if (options_len)
+ {
+ create_info->table_options|= HA_OPTION_TEXT_CREATE_OPTIONS;
+ create_info->extra_size+= (options_len + 4);
+ }
+
if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo,
create_info, keys)) < 0)
{
@@ -294,6 +320,25 @@
if (my_write(file, (uchar*) buff, 6, MYF_RW))
goto err;
}
+
+ if (options_len)
+ {
+ uchar *optbuff= (uchar *)my_safe_alloca(options_len + 4, OPTIONS_ON_STACK);
+ my_bool error;
+ DBUG_PRINT("info", ("Create options length: %u", options_len));
+ if (!optbuff)
+ goto err;
+ int4store(optbuff, options_len);
+ engine_table_options_frm_image(optbuff + 4,
+ create_info->option_list,
+ create_fields,
+ keys, key_info);
+ error= my_write(file, optbuff, options_len + 4, MYF_RW);
+ my_safe_afree(optbuff, options_len + 4, OPTIONS_ON_STACK);
+ if (error)
+ goto err;
+ }
+
for (i= 0; i < keys; i++)
{
if (key_info[i].parser_name)
=== modified file 'storage/example/ha_example.cc'
--- a/storage/example/ha_example.cc 2010-03-03 14:44:14 +0000
+++ b/storage/example/ha_example.cc 2010-04-05 08:49:56 +0000
@@ -113,6 +113,47 @@
/* The mutex used to init the hash; variable for example share methods */
pthread_mutex_t example_mutex;
+
+/**
+ structure for CREATE TABLE options (table options)
+*/
+
+struct example_table_options_struct
+{
+ const char *strparam;
+ ulonglong ullparam;
+ uint enumparam;
+ bool boolparam;
+};
+
+
+/**
+ structure for CREATE TABLE options (table options)
+*/
+
+struct example_field_options_struct
+{
+ const char *compex_param_to_parse_it_in_engine;
+};
+
+#define ha_table_option_struct example_table_options_struct
+ha_create_table_option example_table_option_list[]=
+{
+ HA_TOPTION_ULL("ULL", ullparam, UINT_MAX32, 0, UINT_MAX32, 1),
+ HA_TOPTION_STRING("STR", strparam),
+ HA_TOPTION_ENUM("one_or_two", enumparam, "one,two", 0),
+ HA_TOPTION_BOOL("YESNO", boolparam, 1),
+ HA_TOPTION_END
+};
+
+#define ha_field_option_struct example_field_options_struct
+ha_create_table_option example_field_option_list[]=
+{
+ HA_FOPTION_STRING("COMPLEX", compex_param_to_parse_it_in_engine),
+ HA_FOPTION_END
+};
+
+
/**
@brief
Function we use in the creation of our hash to get key.
@@ -138,6 +179,9 @@
example_hton->state= SHOW_OPTION_YES;
example_hton->create= example_create_handler;
example_hton->flags= HTON_CAN_RECREATE;
+ example_hton->table_opt_rules= example_table_option_list;
+ example_hton->field_opt_rules= example_field_option_list;
+ example_hton->key_opt_rules= NULL;
DBUG_RETURN(0);
}
@@ -774,27 +818,6 @@
/**
@brief
- Renames a table from one name to another via an alter table call.
-
- @details
- If you do not implement this, the default rename_table() is called from
- handler.cc and it will delete all files with the file extensions returned
- by bas_ext().
-
- Called from sql_table.cc by mysql_rename_table().
-
- @see
- mysql_rename_table() in sql_table.cc
-*/
-int ha_example::rename_table(const char * from, const char * to)
-{
- DBUG_ENTER("ha_example::rename_table ");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
-}
-
-
-/**
- @brief
Given a starting key and an ending key, estimate the number of rows that
will exist between the two keys.
@@ -836,15 +859,110 @@
int ha_example::create(const char *name, TABLE *table_arg,
HA_CREATE_INFO *create_info)
{
+ example_table_options_struct *prm=
+ (example_table_options_struct *)table_arg->s->option_struct;
DBUG_ENTER("ha_example::create");
/*
- This is not implemented but we want someone to be able to see that it
- works.
+ This example shows how to support custom engine specific table and field
+ options.
*/
+ DBUG_ASSERT(prm);
+ DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\
+ "boolparam: %u",
+ (prm->strparam ? prm->strparam : "<NULL>"),
+ prm->ullparam, prm->enumparam, prm->boolparam));
+ for (Field **field= table_arg->s->field; *field; field++)
+ {
+ example_field_options_struct *fprm=
+ (example_field_options_struct *)(*field)->option_struct;
+ DBUG_ASSERT(fprm);
+ DBUG_PRINT("info", ("field: %s complex: '%-.64s'",
+ (*field)->field_name,
+ (fprm->compex_param_to_parse_it_in_engine ?
+ fprm->compex_param_to_parse_it_in_engine :
+ "<NULL>")));
+
+ }
+
DBUG_RETURN(0);
}
+/**
+ check_if_incompatible_data() called if ALTER TABLE can't detect otherwise
+ if new and old definition are compatible
+
+ @details If there are no other explicit signs like changed number of
+ fields this function will be called by compare_tables()
+ (sql/sql_tables.cc) to decide should we rewrite whole table or only .frm
+ file.
+
+*/
+
+bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes)
+{
+ example_table_options_struct *prmo, *prmn;
+ uint i;
+ DBUG_ENTER("ha_example::check_if_incompatible_data");
+ DBUG_ASSERT(info->option_struct);
+ DBUG_ASSERT(info->old_option_struct);
+ /*
+ This example shows how custom engine specific table and field
+ options can be accessed from this function to be compared.
+ */
+
+ prmn= (example_table_options_struct *)info->option_struct;
+ DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u "\
+ "boolparam: %u",
+ (prmn->strparam ? prmn->strparam : "<NULL>"),
+ prmn->ullparam, prmn->enumparam, prmn->boolparam));
+
+ prmo= (example_table_options_struct *)info->old_option_struct;
+ DBUG_PRINT("info", ("old strparam: '%-.64s' ullparam: %llu enumparam: %u "\
+ "boolparam: %u",
+ (prmo->strparam ? prmo->strparam : "<NULL>"),
+ prmo->ullparam, prmo->enumparam, prmo->boolparam));
+
+ /* check important parameters */
+ if (prmn->ullparam != prmo->ullparam || prmn->boolparam != prmo->boolparam)
+ DBUG_RETURN(COMPATIBLE_DATA_NO);
+
+ for (i= 0; i < info->fields; i++)
+ {
+ example_field_options_struct *fprmo, *fprmn;
+ if (info->old_new_fileds_option_struct[1][i])
+ {
+ fprmn=
+ (example_field_options_struct *)
+ info->old_new_fileds_option_struct[1][i];
+ DBUG_PRINT("info", ("old field: %u new complex: '%-.64s'", i,
+ (fprmn->compex_param_to_parse_it_in_engine ?
+ fprmn->compex_param_to_parse_it_in_engine :
+ "<NULL>")));
+ /*
+ if (!structure_is_the_same(fprmn->compex_param_to_parse_it_in_engine,
+ fprmo->compex_param_to_parse_it_in_engine)
+ DBUG_RETURN(COMPATIBLE_DATA_NO);
+ */
+ }
+ else
+ DBUG_PRINT("info", ("old field %i did not changed", i));
+
+ fprmo=
+ (example_field_options_struct *)info->old_new_fileds_option_struct[0][i];
+ DBUG_ASSERT(fprmo);
+ DBUG_PRINT("info", ("old field: %u old complex: '%-.64s'", i,
+ (fprmo->compex_param_to_parse_it_in_engine ?
+ fprmo->compex_param_to_parse_it_in_engine :
+ "<NULL>")));
+ }
+
+ DBUG_RETURN(COMPATIBLE_DATA_YES);
+}
+
+
+
struct st_mysql_storage_engine example_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
=== modified file 'storage/example/ha_example.h'
--- a/storage/example/ha_example.h 2007-08-13 13:11:25 +0000
+++ b/storage/example/ha_example.h 2010-04-05 08:49:56 +0000
@@ -242,9 +242,10 @@
ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key);
int delete_table(const char *from);
- int rename_table(const char * from, const char * to);
int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); ///< required
+ bool check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); ///< required
=== modified file 'storage/pbxt/src/discover_xt.cc'
--- a/storage/pbxt/src/discover_xt.cc 2010-02-01 06:14:12 +0000
+++ b/storage/pbxt/src/discover_xt.cc 2010-04-05 08:49:56 +0000
@@ -1623,7 +1623,7 @@
#endif
NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/,
NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/,
- NULL /*vcol_info*/))
+ NULL /*vcol_info*/, NULL /* create options */))
#endif
goto error;
1
0
W dniu 2010-04-04 12:59, Henrik Ingo pisze:
> On Sat, Apr 3, 2010 at 8:23 PM, Mchl<mchlpl(a)gmail.com> wrote:
>> Regarding comment from colincharles here:
>> http://www.bytebot.net/blog/archives/2010/04/02/mariadb-5-1-44-released
>
> Hi Mchl!
>
> I'm currently traveling / on easter vacation, but Colin or Kristian
> Cc'd here can respond to your questions.
>
>> I am assuming that by 'resources' needed for creeating win32 builds, you
>> mean a buildbot slave.
>
> Yes and no. If you want to contribute a buildbot slave, this is appreciated.
>
> But with the above we actually refer to the fact that most of our
> developers use Linux as primary platform, and the QA and build system
> doesn't work "by itself" on Windows, so we actually would need someone
> to work on the build scripts, the automated tests and even fix MariaDB
> source code on Windows. Currently MariaDB does not compile at all on
> 64 bit Windows, and the test scripts are unreliable producing spurious
> failures that are not real MariaDB failures.
>
>> I have an Athlon XP box under my desk, which used to be my primary
>> machine, but right now is being used mostly for backups, so most of the
>> time it does nothing but gathers dust. I could probably set it up with
>> another hard disk, install Windows XP/Vista on it and donate it for
>> MariaDB builds. It depends on a few factors though.
>> 1. How autoamted is the process? Ideally all I would like to do is to
>> switch the power on, login and let the machine do its job with as little
>> interaction from my side as possible.
>> 2. How often and for how long would it need to run? I can run it for
>> 8-10 hours several times a week, but certainly not 24/7
>> 3. How much upload/download bandwidth is required? While my download
>> bandwidth is pretty good, my upload is not. Still, as long as we are not
>> talking several tens of gigabytes per day, I should manage.
>>
>> Also please take into consideration, that I've never done anything like
>> this before, so I might require a lot of help setting this up.
>>
>> Please tell me what you think! ;)
>
> Colin and Kristian will help you out here...
>
> Thanks for offering to help!
>
> henrik
>
>
Thanks a lot for replying!
That doesn't sound too good to me. I'm mostly PHP/JS developer, and
while I know some C++ it is almost certainly too little to be able to
contribute to MariaDB code. Most of all I'm afraid I cannot commit much
time to this.
I will take a look at how all this looks like, but it can be just way
over my head.
Anyway, if this doesn't work, this machine is still here to use if you
have a need for a slave for any linux flavor (or other OS) I could
install on this hardware and that would be less problematic to maintain
for an unexperienced person like me.
Also I would like to apologise to all list members, for apparently
contacting them directly instead of posting to the list. It was my first
attempt at using launchpad's lists, and it seems I did something wrong.
Mchl
1
0

Re: [Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2742) WL#86
by Michael Widenius 04 Apr '10
by Michael Widenius 04 Apr '10
04 Apr '10
Hi!
>>>>> "Igor" == Igor Babaev <igor(a)askmonty.org> writes:
Igor> Please review this patch that is based on the contribution patch
Igor> attached to WL#86.
<cut>
First some things we discussed in Iceland:
Functions with starts with s_.... should be changed to simple_....
Move select.test to suite/select and run it with different keycache
parameters (to not repeat select.result)
Igor> 2742 Igor Babaev 2010-02-16
Igor> WL#86: Partitioned key cache for MyISAM.
Igor> This is the base patch for the task.
Igor> === modified file 'mysys/mf_keycache.c'
Igor> +#define KEYCACHE_BASE_EXPR(f, pos)
Igor> \
Igor> + ((ulong) ((pos) / keycache->key_cache_block_size) + (ulong) (f))
Igor> #define KEYCACHE_HASH(f, pos)
Igor> \
Igor> -(((ulong) ((pos) / keycache->key_cache_block_size) +
Igor> \
Igor> - (ulong) (f)) &
Igor> (keycache->hash_entries-1))
Igor> + ((KEYCACHE_BASE_EXPR(f, pos) / keycache->hash_factor) &
Igor> \
Igor> + (keycache->hash_entries-1))
Igor> #define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1))
As all the divisiors are powers of two, would it be more efficent to store
the shift factor in 'keycache' and do shifts instead of / ?
(I assume that even on modern CPU:s shift is much faster then /)
Igor> +static
Igor> +void s_finish_resize_key_cache(void *keycache_cb,
Igor> + my_bool with_resize_queue,
Igor> + my_bool acquire_lock)
Igor> +{
Igor> + S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
Igor> + DBUG_ENTER("s_finish_resize_key_cache");
Igor> +
Igor> + if (acquire_lock)
Igor> + keycache_pthread_mutex_lock(&keycache->cache_lock);
Igor> +
Add after this:
safe_mutex_assert_owner((&keycache->cache_lock);
<cut>
Igor> +static
Igor> +int s_resize_key_cache(void *keycache_cb, uint key_cache_block_size,
Igor> + size_t use_mem, uint division_limit,
Igor> + uint age_threshold)
Igor> +{
Igor> + S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
It may be better if this function would take S_KEY_CACHE_CB as a parameter.
This can easily be done by doing a cast when storing the function pointer
into the st_key_cache_funcs array.
This way all casts are in one place and all real functions can avoid
casts. The same thing applies for all other interface functions.
This mainly makes the real code look a bit nicer
Igor> + int blocks= 0;
Igor> + DBUG_ENTER("s_resize_key_cache");
Igor> +
Igor> + if (!keycache->key_cache_inited)
Igor> + DBUG_RETURN(keycache->disk_blocks);
Shouldn't we return 0 if cache was not initied ?
(if not inited, disk_blocks may contain random data)
Igor> @@ -670,7 +894,7 @@ finish:
Igor> /*
Igor> Increment counter blocking resize key cache operation
Igor> */
Igor> -static inline void inc_counter_for_resize_op(KEY_CACHE *keycache)
Igor> +static inline void inc_counter_for_resize_op(S_KEY_CACHE_CB *keycache)
Igor> {
Igor> keycache->cnt_for_resize_op++;
Igor> }
Igor> @@ -680,35 +904,49 @@ static inline void inc_counter_for_resiz
Igor> Decrement counter blocking resize key cache operation;
Igor> Signal the operation to proceed when counter becomes equal zero
Igor> */
Igor> -static inline void dec_counter_for_resize_op(KEY_CACHE *keycache)
Igor> +static inline void dec_counter_for_resize_op(S_KEY_CACHE_CB *keycache)
Many changes are just like the one above.
Wouldn't it been easier to keep KEY_CACHE as the orignal value
and add KEY_CACHE_MULTI as the new one ?
(This would make future merger with the MySQL code easier too)
<cut>
Igor> +
Igor> +/*
Igor> + Get statistics for a simple key cache
Igor> +
Igor> + SYNOPSIS
Igor> + get_key_cache_statistics()
Igor> + keycache_cb pointer to the control block of a simple key cache
Igor> + partition_no partition number (not used)
Igor> + key_cache_stats OUT pointer to the structure for the returned
Igor> statistics
Igor> +
Igor> + DESCRIPTION
Igor> + This function is the implementation of the get_key_cache_statistics
Igor> + interface function that is employed by simple (non-partitioned) key
Igor> caches.
Igor> + The function considers the parameter keycache_cb as a pointer to the
Igor> + control block structure of the type S_KEY_CACHE_CB for a simple key
Igor> cache.
Igor> + This function returns the statistical data for the key cache.
Igor> + The parameter partition_no is not used by this function.
Igor> +
Igor> + RETURN
Igor> + none
Igor> +
Igor> +*/
A small thing, but better point them out (to ensure we agree on the
coding style):
Remove the extra empty line after 'none'.
The current style is:
No empty lines at end of comments
One empty line between function comment and function.
Two empty lines before function comment (to separate it from previous function)
Igor> +
Igor> +static
Igor> +void s_get_key_cache_statistics(void *keycache_cb,
Igor> + uint partition_no __attribute__((unused)),
Igor> + KEY_CACHE_STATISTICS *key_cache_stats)
Igor> +{
Igor> + S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
Igor> + DBUG_ENTER("s_get_key_cache_statistics");
Igor> +
Igor> + key_cache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
Igor> + key_cache_stats->block_size= (longlong) keycache->key_cache_block_size;
Igor> + key_cache_stats->blocks_used= keycache->blocks_used;
Igor> + key_cache_stats->blocks_unused= keycache->blocks_unused;
Igor> + key_cache_stats->blocks_changed= keycache->global_blocks_changed;
Igor> + key_cache_stats->read_requests= keycache->global_cache_r_requests;
Igor> + key_cache_stats->reads= keycache->global_cache_read;
Igor> + key_cache_stats->write_requests= keycache->global_cache_w_requests;
Igor> + key_cache_stats->writes= keycache->global_cache_write;
Igor> + DBUG_VOID_RETURN;
Igor> +}
Please ensure that all keycache variables are of the same style.
Use either keycache or key_cache everywhere!
(See above for confusing example)
Igor> +
Igor> +
Igor> +static size_t s_key_cache_stat_var_offsets[]=
Igor> +{
Igor> + offsetof(S_KEY_CACHE_CB, blocks_used),
Igor> + offsetof(S_KEY_CACHE_CB, blocks_unused),
Igor> + offsetof(S_KEY_CACHE_CB, global_blocks_changed),
Igor> + offsetof(S_KEY_CACHE_CB, global_cache_w_requests),
Igor> + offsetof(S_KEY_CACHE_CB, global_cache_write),
Igor> + offsetof(S_KEY_CACHE_CB, global_cache_r_requests),
Igor> + offsetof(S_KEY_CACHE_CB, global_cache_read)
Igor> +};
Igor> +
Igor> +
Igor> +/*
Igor> + Get the value of a statistical variable for a simple key cache
Igor> +
Igor> + SYNOPSIS
Igor> + s_get_key_cache_stat_value()
Igor> + keycache_cb pointer to the control block of a simple key cache
Igor> + var_no the ordered number of a statistical variable
Igor> +
Igor> + DESCRIPTION
Igor> + This function is the implementation of the s_get_key_cache_stat_value
Igor> + interface function that is employed by simple (non-partitioned) key
Igor> caches.
Igor> + The function considers the parameter keycache_cb as a pointer to the
Igor> + control block structure of the type S_KEY_CACHE_CB for a simple key
Igor> cache.
Igor> + This function returns the value of the statistical variable var_no
Igor> + for this key cache. The variables are numbered starting from 0 to 6.
Igor> +
Igor> + RETURN
Igor> + The value of the specified statistical variable
Igor> +
Igor> +*/
Igor> +
Igor> +static
Igor> +ulonglong s_get_key_cache_stat_value(void *keycache_cb, uint var_no)
Igor> +{
Igor> + S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
Igor> + size_t var_ofs= s_key_cache_stat_var_offsets[var_no];
Igor> + ulonglong res= 0;
Igor> + DBUG_ENTER("s_get_key_cache_stat_value");
Igor> +
Igor> + if (var_no < 3)
Change the above to a define that is in the header file and add a
comment to where s_key_cache_stat_var_offsets are defined).
(Otherwise someone will surely break things sooner or later!)
Igor> + res= (ulonglong) (*(long *) ((char *) keycache + var_ofs));
Igor> + else
Igor> + res= *(ulonglong *) ((char *) keycache + var_ofs);
Igor> +
Igor> + DBUG_RETURN(res);
Igor> +}
Igor> +
Igor> +
Igor> +/*
Igor> + The array of pointer to the key cache interface functions used for simple
Igor> + key caches. Any simple key cache objects including those incorporated
Igor> into
Igor> + partitioned keys caches exploit this array.
Igor> +
Igor> + The current implementation of these functions allows to call them from
Igor> + the MySQL server code directly. We don't do it though.
Igor> +*/
Igor> +
Igor> +static KEY_CACHE_FUNCS s_key_cache_funcs =
Igor> +{
Igor> + s_init_key_cache,
Igor> + s_resize_key_cache,
Igor> + s_change_key_cache_param,
Igor> + s_key_cache_read,
Igor> + s_key_cache_insert,
Igor> + s_key_cache_write,
Igor> + s_flush_key_blocks,
Igor> + s_reset_key_cache_counters,
Igor> + s_end_key_cache,
Igor> + s_get_key_cache_statistics,
Igor> + s_get_key_cache_stat_value
Igor> +};
Here is where you can add casts so that you don't need them in the functions.
<cut>
Igor> +/* Control block for a partitioned key cache */
Igor> +
Igor> +typedef struct st_p_key_cache_cb
Igor> +{
Igor> + my_bool key_cache_inited; /*<=> control block is allocated
Igor> */
Igor> + S_KEY_CACHE_CB **partition_array; /* array of the key cache
Igor> partitions */
Igor> + uint partitions; /* number of partitions in the key
Igor> cache */
Igor> + size_t key_cache_mem_size; /* specified size of the cache memory
Igor> */
Igor> + uint key_cache_block_size; /* size of the page buffer of a cache
Igor> block */
Igor> +} P_KEY_CACHE_CB;
Please move the uint values after each other (gives better alignment)
Igor> +
Igor> +static
Igor> +void p_end_key_cache(void *keycache_cb, my_bool cleanup);
Move the above declaration to start of file (together with all other
static declarations)
<cut>
Igor> +
Igor> +static
Igor> +S_KEY_CACHE_CB *get_key_cache_partition_for_write(P_KEY_CACHE_CB
Igor> *keycache,
Igor> + File file, my_off_t
Igor> filepos,
Igor> + ulonglong*
Igor> dirty_part_map)
Put a new line after 'S_KEY_CACHE_CB *'; this makes the line more readable.
Igor> + If keycache->key_cache_inited != 0 then we assume that the memory for
Igor> + the array of partitions has been already allocated.
Igor> +
Igor> + It's assumed that no two threads call this function simultaneously
Igor> + referring to the same key cache handle.
Igor> +*/
I don't think we can assume that any memory is initialized to 0.
Better to have an argument that tells if the memory is already
initialized or not.
Igor> +
Igor> +static
Igor> +int p_init_key_cache(void *keycache_cb, uint key_cache_block_size,
Igor> + size_t use_mem, uint division_limit,
Igor> + uint age_threshold)
Igor> +{
Igor> + int i;
Igor> + size_t mem_per_cache;
Igor> + int cnt;
Igor> + S_KEY_CACHE_CB *partition;
Igor> + S_KEY_CACHE_CB **partition_ptr;
Igor> + P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
Igor> + uint partitions= keycache->partitions;
It would be better if partitions would be part of the init call, as
otherwise the caller need to initialize the keycache->partitions
before the call, which is more cumbersome.
Igor> + int blocks= -1;
Igor> + DBUG_ENTER("p_init_key_cache");
Igor> +
Igor> + keycache->key_cache_block_size = key_cache_block_size;
Igor> +
Igor> + if (keycache->key_cache_inited)
Remove above test; We can't make a decisions bases on a struct that we are
about to initialize.
Igor> + partition_ptr= keycache->partition_array;
Igor> + else
Igor> + {
Igor> + if(!(partition_ptr=
Igor> + (S_KEY_CACHE_CB **) my_malloc(sizeof(S_KEY_CACHE_CB *) * partitions,
Igor> + MYF(0))))
Igor> + DBUG_RETURN(blocks);
MYF(0) -> MYF(MY_WME) (So that we get a proper error message)
Please return -1 instead of blocks (easier to understand).
Igor> + keycache->partition_array= partition_ptr;
Igor> + }
Igor> +
Igor> + mem_per_cache = use_mem / partitions;
Igor> +
Igor> + for (i= 0; i < (int) partitions; i++)
Igor> + {
Igor> + my_bool key_cache_inited= keycache->key_cache_inited;
Igor> + if (key_cache_inited)
Igor> + partition= *partition_ptr;
Igor> + else
Igor> + {
Igor> + if (!(partition= (S_KEY_CACHE_CB *)
Igor> my_malloc(sizeof(S_KEY_CACHE_CB),
Igor> + MYF(0))))
Igor> + continue;
If we fail, shouldn't we abort ?
After all, we can't assume we will be able to allocate any other
partition after this one.
Here we should probably use MYF(MY_WME) too.
Igor> + partition->key_cache_inited= 0;
Igor> + }
Igor> +
Igor> + if ((cnt= s_init_key_cache(partition,
Igor> + key_cache_block_size, mem_per_cache,
Igor> + division_limit, age_threshold)) <= 0)
Igor> + {
Igor> + s_end_key_cache(partition, 1);
Igor> + my_free((uchar *) partition, MYF(0));
my_free() don't need a cast.
Igor> + partition= 0;
Igor> + if (key_cache_inited)
Igor> + {
Igor> + memmove(partition_ptr, partition_ptr+1,
Igor> + sizeof(partition_ptr)*(partitions-i-1));
Igor> + }
Igor> + if (i == 0)
Igor> + {
Igor> + i--;
Igor> + partitions--;
Igor> + if (partitions)
Igor> + mem_per_cache = use_mem / partitions;
Igor> + }
Igor> + continue;
Igor> + }
I don't like the above code to try to recalculate the memory size:
- You uncrease the size of the next partitions, but the total will
not be use_mem anyway, so it's a bit pointless.
- It will make the caches of different sizes, which is probably not
what the user wants anyway.
I think it would be better to be able to just fail if we can't
allocate all memory.
- Less confusing for the user
- If we get a memory error here, something is probably very wrong anyway so
it's better to release memory and abort.
- Simpler code
Igor> + if (blocks < 0)
Igor> + blocks= 0;
Whey the special logic with the first loop ?
Please add a commment or just set block to 0 instead of -1 and
set block to -1 on error / at abort
<cut>
Igor> +static
Igor> +int p_resize_key_cache(void *keycache_cb, uint key_cache_block_size,
Igor> + size_t use_mem, uint division_limit,
Igor> + uint age_threshold)
Igor> +{
Igor> + uint i;
Igor> + P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
Igor> + uint partitions= keycache->partitions;
Igor> + my_bool cleanup= use_mem == 0;
Igor> + int blocks= -1;
Igor> + int err= 0;
Igor> + DBUG_ENTER("p_resize_key_cache");
Igor> + if (use_mem == 0)
Change to test if (cleanup)
Igor> + {
Igor> + p_end_key_cache(keycache_cb, 0);
Igor> + DBUG_RETURN(blocks);
change to return -1
Igor> + }
Igor> + for (i= 0; i < partitions; i++)
Igor> + {
Igor> + err|= s_prepare_resize_key_cache(keycache->partition_array[i], 0, 1);
Igor> + }
Igor> + if (!err && use_mem)
You don't need to test use_mem here (you know it's not 0)
Igor> + blocks= p_init_key_cache(keycache_cb, key_cache_block_size, use_mem,
Igor> + division_limit, age_threshold);
Igor> + if (blocks > 0 && !cleanup)
Cleanup is always 0 here (as otherwise we return -1 at function start
functabove)
Igor> + {
Igor> + for (i= 0; i < partitions; i++)
Igor> + {
Igor> + s_finish_resize_key_cache(keycache->partition_array[i], 0, 1);
Igor> + }
Igor> + }
Igor> + DBUG_RETURN(blocks);
Igor> +}
<cut>
Igor> +static
Igor> +void p_end_key_cache(void *keycache_cb, my_bool cleanup)
Igor> +{
Igor> + uint i;
Igor> + P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
Igor> + uint partitions= keycache->partitions;
Igor> + DBUG_ENTER("p_end_key_cache");
Igor> + DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache));
Igor> +
Igor> + for (i= 0; i < partitions; i++)
Igor> + {
Igor> + s_end_key_cache(keycache->partition_array[i], cleanup);
Igor> + }
Igor> + if (cleanup) {
Move { to next line
Igor> + for (i= 0; i < partitions; i++)
Igor> + my_free((uchar*) keycache->partition_array[i], MYF(0));
Igor> + my_free((uchar*) keycache->partition_array, MYF(0));
Igor> + keycache->key_cache_inited= 0;
Igor> + }
Igor> + DBUG_VOID_RETURN;
Igor> +}
<cut>
Offset variable can be used (it's only set).
Igor> +static
Igor> +int p_key_cache_insert(void *keycache_cb,
Igor> + File file, my_off_t filepos, int level,
Igor> + uchar *buff, uint length)
Igor> +{
Igor> + uint w_length;
Igor> + P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
Igor> + uint offset= (uint) (filepos % keycache->key_cache_block_size);
Igor> + DBUG_ENTER("p_key_cache_insert");
Igor> + DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
Igor> + (uint) file,(ulong) filepos, length));
Igor> +
Igor> +
Igor> + /* Write data in key_cache_block_size increments */
Igor> + do
Igor> + {
Igor> + S_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
Igor> + file, filepos);
Igor> + w_length= length;
Igor> + set_if_smaller(w_length, keycache->key_cache_block_size);
Should be:
set_if_smaller(w_length, keycache->key_cache_block_size - offset);
Igor> + if (s_key_cache_insert((void *) partition,
Igor> + file, filepos, level,
Igor> + buff, w_length))
Igor> + DBUG_RETURN(1);
Igor> +
<cut>
Igor> +static
Igor> +int p_key_cache_write(void *keycache_cb,
Igor> + File file, void *file_extra,
Igor> + my_off_t filepos, int level,
Igor> + uchar *buff, uint length,
Igor> + uint block_length __attribute__((unused)),
Igor> + int dont_write)
Igor> +{
Igor> + uint w_length;
Igor> + ulonglong *part_map= (ulonglong *) file_extra;
Igor> + P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
Igor> + uint offset= (uint) (filepos % keycache->key_cache_block_size);
Igor> + DBUG_ENTER("p_key_cache_write");
Igor> + DBUG_PRINT("enter",
Igor> + ("fd: %u pos: %lu length: %u block_length: %u"
Igor> + " key_block_length: %u",
Igor> + (uint) file, (ulong) filepos, length, block_length,
Igor> + keycache ? keycache->key_cache_block_size : 0));
Igor> +
Igor> +
Igor> + /* Write data in key_cache_block_size increments */
Igor> + do
Igor> + {
Igor> + S_KEY_CACHE_CB *partition= get_key_cache_partition_for_write(keycache,
Igor> + file,
Igor> filepos,
Igor> + part_map);
Igor> + w_length = length;
Igor> + set_if_smaller(w_length, keycache->key_cache_block_size );
Should be:
set_if_smaller(w_length, keycache->key_cache_block_size - offset);
Igor> + if (s_key_cache_write(partition,
Igor> + file, 0, filepos, level,
Igor> + buff, w_length, block_length,
Igor> + dont_write))
Igor> + DBUG_RETURN(1);
<cut>
Igor> +static
Igor> +int p_flush_key_blocks(void *keycache_cb,
Igor> + File file, void *file_extra,
Igor> + enum flush_type type)
Igor> +{
Igor> + uint i;
Igor> + P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
Igor> + uint partitions= keycache->partitions;
Igor> + int err= 0;
Igor> + ulonglong *dirty_part_map= (ulonglong *) file_extra;
Igor> + DBUG_ENTER("p_flush_key_blocks");
Igor> + DBUG_PRINT("enter", ("keycache: 0x%lx", (long) keycache));
Igor> +
Igor> + for (i= 0; i < partitions; i++)
Igor> + {
Igor> + S_KEY_CACHE_CB *partition= keycache->partition_array[i];
Igor> + if ((type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE) &&
Igor> + !((*dirty_part_map) & (1<<i)))
Change 1<<i to ((ulonglong) 1 << i)
Igor> + continue;
Igor> + err+= test(s_flush_key_blocks(partition, file, 0, type));
You can change the + to |, and then remove the err > 0 below.
Igor> + }
Igor> + *dirty_part_map= 0;
Igor> +
Igor> + if (err > 0)
Igor> + err= 1;
Igor> +
Igor> + DBUG_RETURN(err);
Igor> +}
<cut>
Igor> +static
Igor> +void p_get_key_cache_statistics(void *keycache_cb, uint partition_no,
Igor> + KEY_CACHE_STATISTICS *key_cache_stats)
Igor> +{
Igor> + uint i;
Igor> + S_KEY_CACHE_CB *partition;
Igor> + P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
Igor> + uint partitions= keycache->partitions;
Igor> + DBUG_ENTER("p_get_key_cache_statistics_");
Igor> +
Igor> + if (partition_no != 0)
Igor> + {
Igor> + partition= keycache->partition_array[partition_no-1];
Igor> + s_get_key_cache_statistics((void *) partition, 0, key_cache_stats);
Igor> + DBUG_VOID_RETURN;
Igor> + }
Igor> + key_cache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
Igor> + key_cache_stats->block_size= (longlong) keycache->key_cache_block_size;
Igor> + for (i = 0; i < partitions; i++)
Igor> + {
Igor> + partition= keycache->partition_array[i];
Igor> + key_cache_stats->blocks_used+= partition->blocks_used;
Igor> + key_cache_stats->blocks_unused+= partition->blocks_unused;
Igor> + key_cache_stats->blocks_changed+= partition->global_blocks_changed;
Igor> + key_cache_stats->read_requests+= partition->global_cache_r_requests;
Igor> + key_cache_stats->reads+= partition->global_cache_read;
Igor> + key_cache_stats->write_requests+= partition->global_cache_w_requests;
Igor> + key_cache_stats->writes+= partition->global_cache_write;
Igor> + }
Shouldn't you start by reseting key_cache_stats ?
I think it's better to do the reset here than in
get_key_cache_statistics()
As you don't need the reset when you call s_get_key_cache_statistics()
(as this overwrites all stats entries)
Igor> + DBUG_VOID_RETURN;
Igor> +}
<cut>
Igor> +static
Igor> +ulonglong p_get_key_cache_stat_value(void *keycache_cb, uint var_no)
Igor> +{
Igor> + uint i;
Igor> + P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
Igor> + uint partitions= keycache->partitions;
Igor> + size_t var_ofs= s_key_cache_stat_var_offsets[var_no];
Igor> + ulonglong res= 0;
Igor> + DBUG_ENTER("p_get_key_cache_stat_value");
Igor> +
Igor> + if (var_no < 3)
Change to define (see earlier comment)
<cut>
Igor> +int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
Igor> + size_t use_mem, uint division_limit,
Igor> + uint age_threshold, uint partitions)
Igor> +{
Igor> + void *keycache_cb;
Igor> + int blocks;
Igor> + if (keycache->key_cache_inited)
Igor> + keycache_cb= keycache->keycache_cb;
See earlier comment about making this a parameter.
<cut>
Igor> +int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
Igor> + size_t use_mem, uint division_limit, uint age_threshold)
Igor> +{
Igor> + int blocks= -1;
Igor> + if (keycache->key_cache_inited)
Igor> + {
Igor> + if ((uint) keycache->param_partitions != keycache->partitions &&
Igor> use_mem)
Igor> + blocks= repartition_key_cache (keycache,
Igor> + key_cache_block_size, use_mem,
Igor> + division_limit, age_threshold,
Igor> + (uint) keycache->param_partitions);
Remove space after function name
Igor> + else
Igor> + {
Igor> + blocks= keycache->interface_funcs->resize(keycache->keycache_cb,
Igor> + key_cache_block_size,
Igor> + use_mem, division_limit,
Igor> + age_threshold);
Igor> +
Igor> + if (keycache->partitions)
Igor> + keycache->partitions=
Igor> + ((P_KEY_CACHE_CB *)(keycache->keycache_cb))->partitions;
Igor> + }
Igor> + if (blocks <= 0)
Igor> + keycache->can_be_used= 0;
The last should probably be:
keycache->can_be_used= (blocks >= 0);
Safer, as it ensures that can_be_used is always correct.
Igor> +uchar *key_cache_read(KEY_CACHE *keycache,
Igor> + File file, my_off_t filepos, int level,
Igor> + uchar *buff, uint length,
Igor> + uint block_length, int return_buffer)
Igor> +{
Igor> + if (keycache->key_cache_inited && keycache->can_be_used)
Could we change this to only depend on keycache->can_be_used ?
(Faster if)
We can of course assume that keycache_init() has been called for the object.
Igor> + return keycache->interface_funcs->read(keycache->keycache_cb,
Igor> + file, filepos, level,
Igor> + buff, length,
Igor> + block_length, return_buffer);
Igor> +
Igor> + /* We can't use mutex here as the key cache may not be initialized */
Igor> + keycache->global_cache_r_requests++;
Igor> + keycache->global_cache_read++;
Igor> +
Igor> + if (my_pread(file, (uchar*) buff, length, filepos, MYF(MY_NABP)))
Igor> + return (uchar *) 0;
Igor> +
Igor> + return buff;
Igor> +}
<cut>
Igor> +int key_cache_insert(KEY_CACHE *keycache,
Igor> + File file, my_off_t filepos, int level,
Igor> + uchar *buff, uint length)
Igor> +{
Igor> + if (keycache->key_cache_inited && keycache->can_be_used)
Same here as above.
Igor> + return keycache->interface_funcs->insert(keycache->keycache_cb,
Igor> + file, filepos, level,
Igor> + buff, length);
Igor> + return 0;
Igor> +}
Igor> +
<cut>
Igor> +int key_cache_write(KEY_CACHE *keycache,
Igor> + File file, void *file_extra,
Igor> + my_off_t filepos, int level,
Igor> + uchar *buff, uint length,
Igor> + uint block_length, int force_write)
Igor> +{
Igor> + if (keycache->key_cache_inited && keycache->can_be_used)
And here.
Igor> +void get_key_cache_statistics(KEY_CACHE *keycache, uint partition_no,
Igor> + KEY_CACHE_STATISTICS *key_cache_stats)
Igor> +{
Igor> + bzero(key_cache_stats, sizeof(KEY_CACHE_STATISTICS));
Remove the above; Better to assume that get_stats() overwrites this.
(Which is the case for s_get_key_cache_statistics())
<cut>
Igor> === modified file 'sql/handler.cc'
Igor> --- a/sql/handler.cc 2010-02-01 06:14:12 +0000
Igor> +int ha_repartition_key_cache(KEY_CACHE *key_cache)
Igor> +{
Igor> + DBUG_ENTER("ha_repartition_key_cache");
Igor> +
Igor> + if (key_cache->key_cache_inited)
Igor> + {
Igor> + pthread_mutex_lock(&LOCK_global_system_variables);
Igor> + size_t tmp_buff_size= (size_t) key_cache->param_buff_size;
Igor> + long tmp_block_size= (long) key_cache->param_block_size;
Igor> + uint division_limit= key_cache->param_division_limit;
Igor> + uint age_threshold= key_cache->param_age_threshold;
Igor> + uint partitions= key_cache->param_partitions;
Igor> + pthread_mutex_unlock(&LOCK_global_system_variables);
Igor> + DBUG_RETURN(!repartition_key_cache(key_cache, tmp_block_size,
Igor> + tmp_buff_size,
Igor> + division_limit, age_threshold,
Igor> + partitions));
Igor> + }
key_cache_inited may be 0 if we used a 0 size key cache.
In this case one can't reparttion this cache. Is this correct?
Assume on does the following:
- Set key cache size to 0
- changes partition numbers
- set key cache to 1G
In this case, will things work and the new key cache have the new
number of partitions ?
(It may work, just wanted to be sure that you have tested this)
<cut>
Igor> === modified file 'sql/sql_show.cc'
Igor> --- a/sql/sql_show.cc 2010-02-01 06:14:12 +0000
Igor> +++ b/sql/sql_show.cc 2010-02-16 16:41:11 +0000
Igor> @@ -2220,6 +2220,31 @@ void remove_status_vars(SHOW_VAR *list)
Igor> }
Igor> +
Igor> +static void update_key_cache_stat_var(KEY_CACHE *key_cache, size_t ofs)
Igor> +{
Igor> + uint var_no;
Igor> + switch (ofs) {
Igor> + case offsetof(KEY_CACHE, blocks_used):
Igor> + case offsetof(KEY_CACHE, blocks_unused):
Igor> + case offsetof(KEY_CACHE, global_blocks_changed):
Igor> + var_no= (ofs-offsetof(KEY_CACHE, blocks_used))/sizeof(ulong);
Igor> + *(ulong *)((char *) key_cache + ofs)=
Igor> + (ulong) get_key_cache_stat_value(key_cache, var_no);
Igor> + break;
Igor> + case offsetof(KEY_CACHE, global_cache_r_requests):
Igor> + case offsetof(KEY_CACHE, global_cache_read):
Igor> + case offsetof(KEY_CACHE, global_cache_w_requests):
Igor> + case offsetof(KEY_CACHE, global_cache_write):
Igor> + var_no= 3+(ofs-offsetof(KEY_CACHE, global_cache_w_requests))/
Igor> + sizeof(ulonglong);
Change 3 to constant.
Igor> + *(ulonglong *)((char *) key_cache + ofs)=
Igor> + get_key_cache_stat_value(key_cache, var_no);
Igor> + break;
Igor> + }
Igor> +}
<cut>
Igor> +static
Igor> +int store_key_cache_table_record(THD *thd, TABLE *table,
Igor> + const char *name, uint name_length,
Igor> + KEY_CACHE *key_cache,
Igor> + uint partitions, uint partition_no)
Igor> +{
Igor> + KEY_CACHE_STATISTICS key_cache_stats;
Igor> + uint err;
Igor> + DBUG_ENTER("store_key_cache_table_record");
Igor> +
Igor> + get_key_cache_statistics(key_cache, partition_no, &key_cache_stats);
Igor> +
Igor> + if (key_cache_stats.mem_size == 0)
Igor> + DBUG_RETURN(0);
Shouldn't we also here test for keycache->key_cache_inited ?
Regards,
Monty
3
2

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2748)
by Igor Babaev 03 Apr '10
by Igor Babaev 03 Apr '10
03 Apr '10
#At lp:maria/5.2 based on revid:igor@askmonty.org-20100401214240-7ee610nf0169tqy8
2748 Igor Babaev 2010-04-03 [merge]
Merge with the latest changes of 5.2
added:
mysql-test/suite/pbxt/r/pbxt_xa.result
mysql-test/suite/pbxt/t/pbxt_xa.test
mysql-test/suite/pbxt/t/suite.opt
modified:
BUILD/compile-solaris-sparc
CMakeLists.txt
cmd-line-utils/libedit/filecomplete.c
config/ac-macros/plugins.m4
configure.in
extra/comp_err.c
extra/libevent/evbuffer.c
extra/libevent/event.c
extra/libevent/kqueue.c
extra/libevent/signal.c
include/m_ctype.h
include/my_global.h
include/mysql/plugin.h
include/mysql/plugin_auth.h.pp
include/sql_common.h
libmysqld/CMakeLists.txt
mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test
mysql-test/include/default_mysqld.cnf
mysql-test/lib/My/SafeProcess/safe_process.cc
mysql-test/lib/mtr_cases.pm
mysql-test/lib/v1/mysql-test-run.pl
mysql-test/r/status_user.result
mysql-test/suite/funcs_1/r/is_columns_is.result
mysql-test/suite/parts/t/rpl_partition.test
mysql-test/suite/rpl/r/rpl_do_grant.result
mysql-test/suite/rpl/r/rpl_optimize.result
mysql-test/suite/rpl/t/rpl_do_grant.test
mysql-test/suite/rpl/t/rpl_name_const.test
mysql-test/suite/rpl/t/rpl_optimize.test
mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
mysql-test/suite/rpl/t/rpl_row_trig003.test
mysql-test/t/bug47671-master.opt
mysql-test/t/ctype_latin1_de-master.opt
mysql-test/t/ctype_ucs2_def-master.opt
mysys/mf_keycache.c
mysys/my_gethostbyname.c
plugin/auth/auth_socket.c
plugin/auth/dialog.c
plugin/daemon_example/daemon_example.cc
plugin/fulltext/plugin_example.c
server-tools/CMakeLists.txt
server-tools/instance-manager/CMakeLists.txt
sql-common/client.c
sql/client_settings.h
sql/ha_ndbcluster.cc
sql/ha_partition.cc
sql/handler.cc
sql/item.cc
sql/item.h
sql/item_cmpfunc.cc
sql/item_create.cc
sql/item_create.h
sql/item_sum.cc
sql/item_sum.h
sql/log.cc
sql/log_event.cc
sql/mysqld.cc
sql/net_serv.cc
sql/set_var.cc
sql/sp_head.cc
sql/sql_acl.cc
sql/sql_builtin.cc.in
sql/sql_class.cc
sql/sql_class.h
sql/sql_plugin.cc
sql/sql_plugin.h
sql/sql_show.cc
sql/sql_table.cc
sql/sql_view.cc
sql/sql_yacc.yy
storage/archive/ha_archive.cc
storage/blackhole/ha_blackhole.cc
storage/csv/ha_tina.cc
storage/example/ha_example.cc
storage/example/ha_example.h
storage/federated/ha_federated.cc
storage/federatedx/ha_federatedx.cc
storage/heap/ha_heap.cc
storage/ibmdb2i/ha_ibmdb2i.cc
storage/innobase/handler/ha_innodb.cc
storage/innodb_plugin/handler/i_s.cc
storage/maria/ha_maria.cc
storage/maria/ma_loghandler.c
storage/maria/ma_search.c
storage/maria/maria_def.h
storage/myisam/ft_stopwords.c
storage/myisam/ha_myisam.cc
storage/myisammrg/ha_myisammrg.cc
storage/myisammrg/myrg_open.c
storage/pbxt/src/ha_pbxt.cc
storage/xtradb/handler/ha_innodb.cc
storage/xtradb/handler/i_s.cc
storage/xtradb/handler/i_s.h
storage/xtradb/include/page0page.h
storage/xtradb/include/page0page.ic
storage/xtradb/include/ut0lst.h
storage/xtradb/log/log0recv.c
strings/ctype-ucs2.c
strings/ctype-utf8.c
strings/my_vsnprintf.c
support-files/compiler_warnings.supp
unittest/mysys/waiting_threads-t.c
=== modified file 'BUILD/compile-solaris-sparc'
--- a/BUILD/compile-solaris-sparc 2008-09-30 20:57:48 +0000
+++ b/BUILD/compile-solaris-sparc 2010-03-31 19:12:21 +0000
@@ -9,6 +9,6 @@ PATH=$PATH:/usr/ccs/bin:/usr/local/bin
path=`dirname $0`
. "$path/autorun.sh"
-CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" LIBS="-lmtmalloc" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa $EXTRA_FLAGS $EXTRA_CFLAGS" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g $EXTRA_FLAGS $EXTRA_CXXFLAGS" LIBS="-lmtmalloc" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
make -j 4
=== modified file 'CMakeLists.txt'
--- a/CMakeLists.txt 2010-03-15 11:51:23 +0000
+++ b/CMakeLists.txt 2010-04-02 09:20:09 +0000
@@ -38,6 +38,7 @@ ADD_DEFINITIONS(-DMYSQL_DATADIR="c:/Prog
ADD_DEFINITIONS(-DDEFAULT_CHARSET_HOME="c:/Program Files/MySQL/MySQL Server ${MYSQL_BASE_VERSION}/")
ADD_DEFINITIONS(-DPACKAGE=mysql)
ADD_DEFINITIONS(-DSHAREDIR="share")
+ADD_DEFINITIONS(-DPLUGINDIR="lib/plugin")
# Set debug options
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFORCE_INIT_OF_VARS")
@@ -260,7 +261,7 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
ENDIF(WITH_${ENGINE}_STORAGE_ENGINE AND MYSQL_PLUGIN_STATIC)
IF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_${PLUGIN_NAME}_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${PLUGIN_NAME}_plugin")
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${PLUGIN_NAME})
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
@@ -279,7 +280,7 @@ ENDFOREACH(SUBDIR ${STORAGE_SUBDIRS})
# Special handling for partition(not really pluggable)
IF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_PARTITION_STORAGE_ENGINE")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_partition_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_partition_plugin")
ENDIF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
# Special handling for tmp tables with the maria engine
=== modified file 'cmd-line-utils/libedit/filecomplete.c'
--- a/cmd-line-utils/libedit/filecomplete.c 2009-04-30 11:53:30 +0000
+++ b/cmd-line-utils/libedit/filecomplete.c 2010-03-31 19:12:21 +0000
@@ -95,10 +95,9 @@ static char break_chars[] = { ' ', '\t',
char *
fn_tilde_expand(const char *txt)
{
- struct passwd pwres, *pass;
+ struct passwd *pass;
char *temp;
size_t len = 0;
- char pwbuf[1024];
if (txt[0] != '~')
return (strdup(txt));
=== modified file 'config/ac-macros/plugins.m4'
--- a/config/ac-macros/plugins.m4 2010-03-29 15:14:28 +0000
+++ b/config/ac-macros/plugins.m4 2010-04-01 14:34:51 +0000
@@ -460,7 +460,7 @@ dnl Although this is "pretty", it breaks
])
])
])
- mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]"
+ maria_plugin_defs="$maria_plugin_defs, [builtin_maria_]$2[_plugin]"
[with_plugin_]$2=yes
AC_MSG_RESULT([yes])
m4_ifdef([$11], [
=== modified file 'configure.in'
--- a/configure.in 2010-03-29 15:13:53 +0000
+++ b/configure.in 2010-04-01 14:34:51 +0000
@@ -2872,7 +2872,7 @@ AC_SUBST(server_scripts)
AC_SUBST(mysql_plugin_dirs)
AC_SUBST(mysql_plugin_libs)
-AC_SUBST(mysql_plugin_defs)
+AC_SUBST(maria_plugin_defs)
# Now that sql_client_dirs and sql_server_dirs are stable, determine the union.
=== modified file 'extra/comp_err.c'
--- a/extra/comp_err.c 2009-11-20 10:11:31 +0000
+++ b/extra/comp_err.c 2010-03-30 12:36:49 +0000
@@ -660,7 +660,7 @@ static ha_checksum checksum_format_speci
case 'u':
case 'x':
case 's':
- chksum= my_checksum(chksum, start, (uint) (p + 1 - start));
+ chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start));
start= 0; /* Not in format specifier anymore */
break;
=== modified file 'extra/libevent/evbuffer.c'
--- a/extra/libevent/evbuffer.c 2010-02-01 06:14:12 +0000
+++ b/extra/libevent/evbuffer.c 2010-04-02 09:20:09 +0000
@@ -75,8 +75,7 @@ bufferevent_add(struct event *ev, int ti
*/
void
-bufferevent_read_pressure_cb(struct evbuffer *buf,
- size_t old __attribute__((unused)), size_t now,
+bufferevent_read_pressure_cb(struct evbuffer *buf, size_t old, size_t now,
void *arg) {
struct bufferevent *bufev = arg;
/*
=== modified file 'extra/libevent/event.c'
--- a/extra/libevent/event.c 2010-01-06 19:20:16 +0000
+++ b/extra/libevent/event.c 2010-04-02 09:20:09 +0000
@@ -394,8 +394,7 @@ event_base_get_method(struct event_base
}
static void
-event_loopexit_cb(int fd __attribute__((unused)),
- short what __attribute__((unused)), void *arg)
+event_loopexit_cb(int fd, short what, void *arg)
{
struct event_base *base = arg;
base->event_gotterm = 1;
=== modified file 'extra/libevent/kqueue.c'
--- a/extra/libevent/kqueue.c 2009-03-12 22:27:35 +0000
+++ b/extra/libevent/kqueue.c 2010-03-30 12:36:49 +0000
@@ -144,7 +144,7 @@ kq_init(struct event_base *base)
*/
if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
- kqueueop->events[0].ident != -1 ||
+ ((int) kqueueop->events[0].ident) != -1 ||
kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue; not using.", __func__);
free(kqueueop->changes);
=== modified file 'extra/libevent/signal.c'
--- a/extra/libevent/signal.c 2010-01-06 19:20:16 +0000
+++ b/extra/libevent/signal.c 2010-04-02 09:20:09 +0000
@@ -69,7 +69,7 @@ static void evsignal_handler(int sig);
/* Callback for when the signal handler write a byte to our signaling socket */
static void
-evsignal_cb(int fd, short what __attribute((unused)), void *arg __attribute((unused)))
+evsignal_cb(int fd, short what, void *arg)
{
static char signals[100];
#ifdef WIN32
=== modified file 'include/m_ctype.h'
--- a/include/m_ctype.h 2010-03-31 18:37:45 +0000
+++ b/include/m_ctype.h 2010-04-02 09:20:09 +0000
@@ -311,7 +311,9 @@ struct charset_info_st
#define ILLEGAL_CHARSET_INFO_NUMBER (~0U)
extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_bin;
-extern struct charset_info_st my_charset_bin;
+extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_latin1;
+extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_filename;
+
extern struct charset_info_st my_charset_big5_chinese_ci;
extern struct charset_info_st my_charset_big5_bin;
extern struct charset_info_st my_charset_cp932_japanese_ci;
@@ -324,7 +326,6 @@ extern struct charset_info_st my_charset
extern struct charset_info_st my_charset_gb2312_bin;
extern struct charset_info_st my_charset_gbk_chinese_ci;
extern struct charset_info_st my_charset_gbk_bin;
-extern struct charset_info_st my_charset_latin1;
extern struct charset_info_st my_charset_latin1_german2_ci;
extern struct charset_info_st my_charset_latin1_bin;
extern struct charset_info_st my_charset_latin2_czech_ci;
@@ -341,7 +342,6 @@ extern struct charset_info_st my_charset
extern struct charset_info_st my_charset_utf8_unicode_ci;
extern struct charset_info_st my_charset_utf8_bin;
extern struct charset_info_st my_charset_cp1250_czech_ci;
-extern struct charset_info_st my_charset_filename;
/* declarations for simple charsets */
extern size_t my_strnxfrm_simple(CHARSET_INFO *, uchar *, size_t,
=== modified file 'include/my_global.h'
--- a/include/my_global.h 2010-03-29 15:13:53 +0000
+++ b/include/my_global.h 2010-04-02 09:20:09 +0000
@@ -1522,6 +1522,9 @@ do { doubleget_union _tmp; \
#elif defined(HAVE_DLFCN_H)
#include <dlfcn.h>
#endif
+#ifndef HAVE_DLERROR
+#define dlerror() ""
+#endif
#endif
/* FreeBSD 2.2.2 does not define RTLD_NOW) */
@@ -1529,7 +1532,7 @@ do { doubleget_union _tmp; \
#define RTLD_NOW 1
#endif
-#ifndef HAVE_DLERROR
+#ifndef HAVE_DLOPEN
#define dlerror() "No support for dynamic loading (static build?)"
#define dlopen(A,B) 0
#define dlsym(A,B) 0
=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h 2010-03-29 15:13:53 +0000
+++ b/include/mysql/plugin.h 2010-04-01 14:34:51 +0000
@@ -57,7 +57,10 @@ typedef struct st_mysql_xid MYSQL_XID;
Plugin API. Common for all plugin types.
*/
+/* MySQL plugin interface version */
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
+/* MariaDB plugin interface version */
+#define MARIA_PLUGIN_INTERFACE_VERSION 0x0100
/*
The allowable types of plugins
@@ -81,6 +84,14 @@ typedef struct st_mysql_xid MYSQL_XID;
#define PLUGIN_LICENSE_GPL_STRING "GPL"
#define PLUGIN_LICENSE_BSD_STRING "BSD"
+/* definitions of code maturity for plugins */
+#define MariaDB_PLUGIN_MATURITY_UNKNOWN 0
+#define MariaDB_PLUGIN_MATURITY_EXPERIMENTAL 1
+#define MariaDB_PLUGIN_MATURITY_ALPHA 2
+#define MariaDB_PLUGIN_MATURITY_BETA 3
+#define MariaDB_PLUGIN_MATURITY_GAMMA 4
+#define MariaDB_PLUGIN_MATURITY_STABLE 5
+
/*
Macros for beginning and ending plugin declarations. Between
mysql_declare_plugin and mysql_declare_plugin_end there should
@@ -93,11 +104,24 @@ typedef struct st_mysql_xid MYSQL_XID;
int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
int PSIZE= sizeof(struct st_mysql_plugin); \
struct st_mysql_plugin DECLS[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+int VERSION= MARIA_PLUGIN_INTERFACE_VERSION; \
+int PSIZE= sizeof(struct st_maria_plugin); \
+struct st_maria_plugin DECLS[]= {
+
#else
+
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]= {
+
#endif
#define mysql_declare_plugin(NAME) \
@@ -106,7 +130,14 @@ __MYSQL_DECLARE_PLUGIN(NAME, \
builtin_ ## NAME ## _sizeof_struct_st_plugin, \
builtin_ ## NAME ## _plugin)
+#define maria_declare_plugin(NAME) \
+MARIA_DECLARE_PLUGIN__(NAME, \
+ builtin_maria_ ## NAME ## _plugin_interface_version, \
+ builtin_maria_ ## NAME ## _sizeof_struct_st_plugin, \
+ builtin_maria_ ## NAME ## _plugin)
+
#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0}}
+#define maria_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
/*
declarations for SHOW STATUS support in plugins
@@ -403,6 +434,30 @@ struct st_mysql_plugin
void * __reserved1; /* reserved for dependency checking */
};
+/*
+ MariaDB extension for plugins declaration structure.
+
+ It also copy current MySQL plugin fields to have more independency
+ in plugins extension
+*/
+
+struct st_maria_plugin
+{
+ int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ void *info; /* pointer to type-specific plugin descriptor */
+ const char *name; /* plugin name */
+ const char *author; /* plugin author (for SHOW PLUGINS) */
+ const char *descr; /* general descriptive text (for SHOW PLUGINS ) */
+ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */
+ int (*init)(void *); /* the function to invoke when plugin is loaded */
+ int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
+ unsigned int version; /* plugin version (for SHOW PLUGINS) */
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info; /* plugin version string */
+ int maturity; /* MariaDB_PLUGIN_MATURITY_XXX */
+};
+
/*************************************************************************
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
*/
=== modified file 'include/mysql/plugin_auth.h.pp'
--- a/include/mysql/plugin_auth.h.pp 2010-03-29 15:13:53 +0000
+++ b/include/mysql/plugin_auth.h.pp 2010-04-01 14:34:51 +0000
@@ -77,6 +77,22 @@ struct st_mysql_plugin
struct st_mysql_sys_var **system_vars;
void * __reserved1;
};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ int maturity;
+};
enum enum_ftparser_mode
{
MYSQL_FTPARSER_SIMPLE_MODE= 0,
=== modified file 'include/sql_common.h'
--- a/include/sql_common.h 2010-03-29 15:13:53 +0000
+++ b/include/sql_common.h 2010-04-01 09:04:26 +0000
@@ -96,7 +96,7 @@ void set_mysql_extended_error(MYSQL *mys
struct st_plugin_vio_info;
void mpvio_info(Vio *vio, struct st_plugin_vio_info *info);
int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
- char *data_plugin, const char *db);
+ const char *data_plugin, const char *db);
int mysql_client_plugin_init();
void mysql_client_plugin_deinit();
struct st_mysql_client_plugin;
=== modified file 'libmysqld/CMakeLists.txt'
--- a/libmysqld/CMakeLists.txt 2010-01-31 09:13:21 +0000
+++ b/libmysqld/CMakeLists.txt 2010-04-02 18:51:02 +0000
@@ -104,7 +104,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libm
../sql-common/client.c ../sql-common/my_time.c
../sql-common/my_user.c ../sql-common/pack.c
../sql/password.c ../sql/discover.cc ../sql/derror.cc
- ../sql/field.cc ../sql/field_conv.cc
+ ../sql/field.cc ../sql/field_conv.cc ../sql-common/client_plugin.c
../sql/filesort.cc ../sql/gstream.cc ../sql/ha_partition.cc
../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc
../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc
=== modified file 'mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test'
--- a/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-01-22 09:38:21 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-03-28 18:10:00 +0000
@@ -157,3 +157,4 @@ INSERT INTO t1 VALUES (1);
DROP TEMPORARY TABLE t1;
+--sync_slave_with_master
=== modified file 'mysql-test/include/default_mysqld.cnf'
--- a/mysql-test/include/default_mysqld.cnf 2008-04-08 14:51:26 +0000
+++ b/mysql-test/include/default_mysqld.cnf 2010-03-28 18:10:00 +0000
@@ -2,7 +2,7 @@
[mysqld]
open-files-limit= 1024
local-infile
-default-character-set= latin1
+character-set-server= latin1
# Increase default connect_timeout to avoid intermittent
# disconnects when test servers are put under load see BUG#28359
=== modified file 'mysql-test/lib/My/SafeProcess/safe_process.cc'
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc 2009-07-08 12:31:22 +0000
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc 2010-03-28 18:10:00 +0000
@@ -159,7 +159,7 @@ int main(int argc, char* const argv[] )
signal(SIGCHLD, handle_signal);
signal(SIGABRT, handle_abort);
- sprintf(safe_process_name, "safe_process[%d]", own_pid);
+ sprintf(safe_process_name, "safe_process[%d]", (int) own_pid);
message("Started");
=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm 2010-01-15 15:27:55 +0000
+++ b/mysql-test/lib/mtr_cases.pm 2010-03-30 12:36:49 +0000
@@ -681,6 +681,8 @@ sub optimize_cases {
if ( $default_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
if ( $default_engine =~ /^innodb/i );
+ $tinfo->{'pbxt_test'}= 1
+ if ( $default_engine =~ /^pbxt/i );
}
}
@@ -778,6 +780,8 @@ sub collect_one_test_case {
my $disabled= shift;
my $suite_opts= shift;
+ my $local_default_storage_engine= $default_storage_engine;
+
#print "collect_one_test_case\n";
#print " suitedir: $suitedir\n";
#print " testdir: $testdir\n";
@@ -932,15 +936,26 @@ sub collect_one_test_case {
tags_from_test_file($tinfo,"$testdir/${tname}.test");
- if ( defined $default_storage_engine )
+ # Get default storage engine from suite.opt file
+
+ if (defined $suite_opts &&
+ "@$suite_opts" =~ "default-storage-engine=\s*([^\s]*)")
+ {
+ $local_default_storage_engine= $1;
+ }
+
+ if ( defined $local_default_storage_engine )
{
# Different default engine is used
# tag test to require that engine
$tinfo->{'ndb_test'}= 1
- if ( $default_storage_engine =~ /^ndb/i );
+ if ( $local_default_storage_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
- if ( $default_storage_engine =~ /^innodb/i );
+ if ( $local_default_storage_engine =~ /^innodb/i );
+
+ $tinfo->{'pbxt_test'}= 1
+ if ( $local_default_storage_engine =~ /^pbxt/i );
}
@@ -1103,6 +1118,28 @@ sub collect_one_test_case {
$tinfo->{template_path}= $config;
}
+ if ( $tinfo->{'pbxt_test'} )
+ {
+ # This is a test that needs pbxt
+ if ( $::mysqld_variables{'pbxt'} eq "OFF" ||
+ ! exists $::mysqld_variables{'pbxt'} )
+ {
+ # Engine is not supported, skip it
+ $tinfo->{'skip'}= 1;
+ return $tinfo;
+ }
+ }
+ else
+ {
+ # Only disable engine if it's on by default (to avoid warnings about
+ # not existing loose options
+ if ( $::mysqld_variables{'pbxt'} eq "ON")
+ {
+ push(@{$tinfo->{'master_opt'}}, "--loose-skip-pbxt");
+ push(@{$tinfo->{'slave_opt'}}, "--loose-skip-pbxt");
+ }
+ }
+
if ( $tinfo->{'example_plugin_test'} )
{
if ( !$ENV{'EXAMPLE_PLUGIN'} )
@@ -1156,6 +1193,7 @@ my @tags=
["include/have_log_bin.inc", "need_binlog", 1],
["include/have_innodb.inc", "innodb_test", 1],
+ ["include/have_pbxt.inc", "pbxt_test", 1],
["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1],
["include/have_ndb.inc", "ndb_test", 1],
=== modified file 'mysql-test/lib/v1/mysql-test-run.pl'
--- a/mysql-test/lib/v1/mysql-test-run.pl 2010-03-04 08:03:07 +0000
+++ b/mysql-test/lib/v1/mysql-test-run.pl 2010-03-28 18:10:00 +0000
@@ -3965,7 +3965,7 @@ sub mysqld_arguments ($$$$) {
}
}
- mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
+ mtr_add_arg($args, "%s--character-set-server-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
=== modified file 'mysql-test/r/status_user.result'
--- a/mysql-test/r/status_user.result 2010-03-21 20:58:19 +0000
+++ b/mysql-test/r/status_user.result 2010-04-02 18:51:02 +0000
@@ -137,7 +137,7 @@ ROWS_INSERTED 8
ROWS_UPDATED 5
SELECT_COMMANDS 3
UPDATE_COMMANDS 11
-OTHER_COMMANDS 9
+OTHER_COMMANDS 7
COMMIT_TRANSACTIONS 19
ROLLBACK_TRANSACTIONS 2
DENIED_CONNECTIONS 0
@@ -154,7 +154,7 @@ ROWS_INSERTED 8
ROWS_UPDATED 5
SELECT_COMMANDS 3
UPDATE_COMMANDS 11
-OTHER_COMMANDS 9
+OTHER_COMMANDS 7
COMMIT_TRANSACTIONS 19
ROLLBACK_TRANSACTIONS 2
DENIED_CONNECTIONS 0
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_is.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result 2010-02-01 06:14:12 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result 2010-04-02 10:03:39 +0000
@@ -271,10 +271,12 @@ NULL information_schema PBXT_STATISTICS
NULL information_schema PBXT_STATISTICS Name 2 NO varchar 40 120 NULL NULL utf8 utf8_general_ci varchar(40) select
NULL information_schema PBXT_STATISTICS Value 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(8) select
NULL information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PLUGINS PLUGIN_AUTH_VERSION 12 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
NULL information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
NULL information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select
NULL information_schema PLUGINS PLUGIN_LICENSE 10 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
+NULL information_schema PLUGINS PLUGIN_MATURITY 11 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
NULL information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select
NULL information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
@@ -791,6 +793,8 @@ NULL information_schema PBXT_STATISTICS
3.0000 information_schema PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64)
1.0000 information_schema PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext
3.0000 information_schema PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80)
+3.0000 information_schema PLUGINS PLUGIN_MATURITY varchar 12 36 utf8 utf8_general_ci varchar(12)
+3.0000 information_schema PLUGINS PLUGIN_AUTH_VERSION varchar 80 240 utf8 utf8_general_ci varchar(80)
NULL information_schema PROCESSLIST ID bigint NULL NULL NULL NULL bigint(4)
3.0000 information_schema PROCESSLIST USER varchar 16 48 utf8 utf8_general_ci varchar(16)
3.0000 information_schema PROCESSLIST HOST varchar 64 192 utf8 utf8_general_ci varchar(64)
=== modified file 'mysql-test/suite/parts/t/rpl_partition.test'
--- a/mysql-test/suite/parts/t/rpl_partition.test 2009-02-01 12:00:48 +0000
+++ b/mysql-test/suite/parts/t/rpl_partition.test 2010-03-29 19:07:45 +0000
@@ -1,6 +1,7 @@
--source include/have_partition.inc
--source include/have_innodb.inc
--source include/master-slave.inc
+--source include/big_test.inc
--vertical_results
=== added file 'mysql-test/suite/pbxt/r/pbxt_xa.result'
--- a/mysql-test/suite/pbxt/r/pbxt_xa.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/r/pbxt_xa.result 2010-03-24 22:12:39 +0000
@@ -0,0 +1,18 @@
+drop table if exists t1, t2;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+SELECT @@log_bin;
+@@log_bin
+0
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+a
+1
+select * from t2;
+b
+2
+drop table t1, t2;
+drop database pbxt;
=== added file 'mysql-test/suite/pbxt/t/pbxt_xa.test'
--- a/mysql-test/suite/pbxt/t/pbxt_xa.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/pbxt_xa.test 2010-03-24 22:12:39 +0000
@@ -0,0 +1,23 @@
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+#
+# bug lp:544173, xa crash with two 2pc-capable storage engines without binlog
+#
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+# verify that binlog is off
+SELECT @@log_bin;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+select * from t2;
+drop table t1, t2;
+drop database pbxt;
+
=== added file 'mysql-test/suite/pbxt/t/suite.opt'
--- a/mysql-test/suite/pbxt/t/suite.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/suite.opt 2010-03-30 12:36:49 +0000
@@ -0,0 +1 @@
+--default-storage-engine=pbxt
=== modified file 'mysql-test/suite/rpl/r/rpl_do_grant.result'
--- a/mysql-test/suite/rpl/r/rpl_do_grant.result 2010-03-16 12:38:35 +0000
+++ b/mysql-test/suite/rpl/r/rpl_do_grant.result 2010-04-01 09:04:26 +0000
@@ -165,10 +165,9 @@ USE test;
DROP FUNCTION bug42217_db.upgrade_del_func;
DROP FUNCTION bug42217_db.upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
-USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+stop slave;
+DROP USER 'create_rout_db'@'localhost';
######## BUG#49119 #######
### i) test case from the 'how to repeat section'
stop slave;
=== modified file 'mysql-test/suite/rpl/r/rpl_optimize.result'
--- a/mysql-test/suite/rpl/r/rpl_optimize.result 2010-01-13 09:00:03 +0000
+++ b/mysql-test/suite/rpl/r/rpl_optimize.result 2010-03-31 19:12:21 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+drop tables if exists t1;
CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
create table t1 (a int not null auto_increment primary key, b int, key(b));
INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
=== modified file 'mysql-test/suite/rpl/t/rpl_do_grant.test'
--- a/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-03-16 12:38:35 +0000
+++ b/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-04-01 09:04:26 +0000
@@ -209,12 +209,18 @@ USE test;
DROP FUNCTION bug42217_db.upgrade_del_func;
DROP FUNCTION bug42217_db.upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+
+sync_slave_with_master;
+
+# Drop the user that was already dropped on the slave
connection slave;
-USE mtr;
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+--disable_warnings
+stop slave;
+connection master;
+DROP USER 'create_rout_db'@'localhost';
+--enable_warnings
# BUG#49119: Master crashes when executing 'REVOKE ... ON
# {PROCEDURE|FUNCTION} FROM ...'
=== modified file 'mysql-test/suite/rpl/t/rpl_name_const.test'
--- a/mysql-test/suite/rpl/t/rpl_name_const.test 2009-04-08 23:42:51 +0000
+++ b/mysql-test/suite/rpl/t/rpl_name_const.test 2010-03-28 18:10:00 +0000
@@ -45,3 +45,4 @@ select * from t1 order by id;
connection master;
drop table t1;
drop procedure test_procedure;
+--sync_slave_with_master
=== modified file 'mysql-test/suite/rpl/t/rpl_optimize.test'
--- a/mysql-test/suite/rpl/t/rpl_optimize.test 2010-03-04 08:03:07 +0000
+++ b/mysql-test/suite/rpl/t/rpl_optimize.test 2010-03-31 19:12:21 +0000
@@ -15,6 +15,10 @@
-- source include/not_staging.inc
-- source include/master-slave.inc
+--disable_warnings
+drop tables if exists t1;
+--enable_warnings
+
CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
create table t1 (a int not null auto_increment primary key, b int, key(b));
@@ -51,10 +55,9 @@ sync_with_master; # won't work if slave
connection master; # cleanup
drop table t1;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
# If the machine is so fast that slave syncs before OPTIMIZE
-# starts, this test wil demonstrate nothing but will pass.
+# starts, this test will demonstrate nothing but will pass.
# End of 4.1 tests
=== modified file 'mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test'
--- a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2007-12-12 10:14:59 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2010-03-28 18:10:00 +0000
@@ -53,6 +53,7 @@ UPDATE t1 SET a=99 WHERE a = 0;
SHOW BINLOG EVENTS;
DROP TABLE t1;
+--sync_slave_with_master
# BUG#17620: Replicate (Row Based) Fails when Query Cache enabled on
# slave
=== modified file 'mysql-test/suite/rpl/t/rpl_row_trig003.test'
--- a/mysql-test/suite/rpl/t/rpl_row_trig003.test 2007-12-06 15:27:10 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_trig003.test 2010-03-29 19:07:45 +0000
@@ -149,6 +149,8 @@ DROP TABLE IF EXISTS test.t2;
DROP TABLE IF EXISTS test.t3;
--enable_warnings
+sync_slave_with_master;
+
diff_files $MYSQLTEST_VARDIR/tmp/trg003_master.sql $MYSQLTEST_VARDIR/tmp/trg003_slave.sql;
# End of 5.0 test case
=== modified file 'mysql-test/t/bug47671-master.opt'
--- a/mysql-test/t/bug47671-master.opt 2009-11-25 06:55:49 +0000
+++ b/mysql-test/t/bug47671-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-character-set=utf8 --skip-character-set-client-handshake
+--character-set-server=utf8 --skip-character-set-client-handshake
=== modified file 'mysql-test/t/ctype_latin1_de-master.opt'
--- a/mysql-test/t/ctype_latin1_de-master.opt 2003-05-21 23:57:27 +0000
+++ b/mysql-test/t/ctype_latin1_de-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-character-set=latin1 --default-collation=latin1_german2_ci
+--character-set-server=latin1 --default-collation=latin1_german2_ci
=== modified file 'mysql-test/t/ctype_ucs2_def-master.opt'
--- a/mysql-test/t/ctype_ucs2_def-master.opt 2007-02-19 11:04:38 +0000
+++ b/mysql-test/t/ctype_ucs2_def-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-collation=ucs2_unicode_ci --default-character-set=ucs2,latin1
+--default-collation=ucs2_unicode_ci --character-set-server=ucs2,latin1
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2010-04-01 21:42:40 +0000
+++ b/mysys/mf_keycache.c 2010-04-03 20:19:35 +0000
@@ -4222,6 +4222,12 @@ restart:
uint next_status;
uint hash_requests;
+ LINT_INIT(next_hash_link);
+ LINT_INIT(next_diskpos);
+ LINT_INIT(next_file);
+ LINT_INIT(next_status);
+ LINT_INIT(hash_requests);
+
total_found++;
found++;
KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used);
=== modified file 'mysys/my_gethostbyname.c'
--- a/mysys/my_gethostbyname.c 2006-12-31 00:32:21 +0000
+++ b/mysys/my_gethostbyname.c 2010-03-31 20:50:54 +0000
@@ -91,9 +91,12 @@ extern pthread_mutex_t LOCK_gethostbynam
is finished with the structure.
*/
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
+struct hostent *
+my_gethostbyname_r(const char *name,
+ struct hostent *result __attribute__((unused)),
+ char *buffer __attribute__((unused)),
+ int buflen __attribute__((unused)),
+ int *h_errnop)
{
struct hostent *hp;
pthread_mutex_lock(&LOCK_gethostbyname_r);
=== modified file 'plugin/auth/auth_socket.c'
--- a/plugin/auth/auth_socket.c 2010-03-29 15:13:53 +0000
+++ b/plugin/auth/auth_socket.c 2010-04-01 14:34:51 +0000
@@ -99,4 +99,21 @@ mysql_declare_plugin(socket_auth)
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(socket_auth)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &socket_auth_handler,
+ "socket_peercred",
+ "Sergei Golubchik",
+ "Unix Socket based authentication",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+mysql_declare_plugin_end;
=== modified file 'plugin/auth/dialog.c'
--- a/plugin/auth/dialog.c 2010-03-31 18:37:45 +0000
+++ b/plugin/auth/dialog.c 2010-04-01 14:34:51 +0000
@@ -171,6 +171,38 @@ mysql_declare_plugin(dialog)
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(dialog)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &two_handler,
+ "two_questions",
+ "Sergei Golubchik",
+ "Dialog plugin demo 1",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &three_handler,
+ "three_attempts",
+ "Sergei Golubchik",
+ "Dialog plugin demo 2",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+maria_declare_plugin_end;
/********************* CLIENT SIDE ***************************************/
/*
=== modified file 'plugin/daemon_example/daemon_example.cc'
--- a/plugin/daemon_example/daemon_example.cc 2007-06-27 14:49:12 +0000
+++ b/plugin/daemon_example/daemon_example.cc 2010-04-01 14:34:51 +0000
@@ -200,3 +200,20 @@ mysql_declare_plugin(daemon_example)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(daemon_example)
+{
+ MYSQL_DAEMON_PLUGIN,
+ &daemon_example_plugin,
+ "daemon_example",
+ "Brian Aker",
+ "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
+ PLUGIN_LICENSE_GPL,
+ daemon_example_plugin_init, /* Plugin Init */
+ daemon_example_plugin_deinit, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'plugin/fulltext/plugin_example.c'
--- a/plugin/fulltext/plugin_example.c 2010-01-04 17:54:42 +0000
+++ b/plugin/fulltext/plugin_example.c 2010-04-01 14:34:51 +0000
@@ -270,4 +270,21 @@ mysql_declare_plugin(ftexample)
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(ftexample)
+{
+ MYSQL_FTPARSER_PLUGIN, /* type */
+ &simple_parser_descriptor, /* descriptor */
+ "simple_parser", /* name */
+ "MySQL AB", /* author */
+ "Simple Full-Text Parser", /* description */
+ PLUGIN_LICENSE_GPL,
+ simple_parser_plugin_init, /* init function (when loaded) */
+ simple_parser_plugin_deinit,/* deinit function (when unloaded) */
+ 0x0001, /* version */
+ simple_status, /* status variables */
+ simple_system_variables, /* system variables */
+ "0.01", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'server-tools/CMakeLists.txt'
--- a/server-tools/CMakeLists.txt 2007-02-14 11:42:11 +0000
+++ b/server-tools/CMakeLists.txt 2010-04-02 09:20:09 +0000
@@ -27,7 +27,7 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc co
user_management_commands.cc
../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
- ../../libmysql/errmsg.c)
+ ../../libmysql/errmsg.c ../../sql-common/client_plugin.c)
ADD_DEPENDENCIES(mysqlmanager GenError)
TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32)
=== modified file 'server-tools/instance-manager/CMakeLists.txt'
--- a/server-tools/instance-manager/CMakeLists.txt 2007-12-27 17:16:02 +0000
+++ b/server-tools/instance-manager/CMakeLists.txt 2010-04-02 09:20:09 +0000
@@ -28,7 +28,7 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc co
user_management_commands.cc ../../mysys/my_rnd.c
../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
- ../../libmysql/errmsg.c)
+ ../../libmysql/errmsg.c ../../sql-common/client_plugin.c)
ADD_DEPENDENCIES(mysqlmanager GenError)
TARGET_LINK_LIBRARIES(mysqlmanager debug dbug mysys strings taocrypt vio yassl zlib wsock32)
=== modified file 'sql-common/client.c'
--- a/sql-common/client.c 2010-03-29 15:13:53 +0000
+++ b/sql-common/client.c 2010-04-02 09:20:09 +0000
@@ -2345,7 +2345,7 @@ void mpvio_info(Vio *vio, MYSQL_PLUGIN_V
case VIO_TYPE_SSL:
{
struct sockaddr addr;
- socklen_t addrlen= sizeof(addr);
+ SOCKET_SIZE_TYPE addrlen= sizeof(addr);
if (getsockname(vio->sd, &addr, &addrlen))
return;
info->protocol= addr.sa_family == AF_UNIX ?
@@ -2360,7 +2360,7 @@ void mpvio_info(Vio *vio, MYSQL_PLUGIN_V
return;
case VIO_TYPE_SHARED_MEMORY:
info->protocol= MYSQL_VIO_MEMORY;
- info->handle= vio->handle_client_file_map; /* or what ? */
+ info->handle= vio->handle_file_map; /* or what ? */
return;
#endif
default: DBUG_ASSERT(0);
@@ -2394,7 +2394,7 @@ static void client_mpvio_info(MYSQL_PLUG
*/
int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
- char *data_plugin, const char *db)
+ const char *data_plugin, const char *db)
{
const char *auth_plugin_name;
auth_plugin_t *auth_plugin;
@@ -2540,7 +2540,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
char buff[NAME_LEN+USERNAME_LENGTH+100];
int scramble_data_len, pkt_scramble_len;
char *end, *host_info=0, *server_version_end, *pkt_end;
- char *scramble_data, *scramble_plugin;
+ char *scramble_data;
+ const char *scramble_plugin;
my_socket sock;
in_addr_t ip_addr;
struct sockaddr_in sock_addr;
=== modified file 'sql/client_settings.h'
--- a/sql/client_settings.h 2010-03-29 15:13:53 +0000
+++ b/sql/client_settings.h 2010-04-02 09:20:09 +0000
@@ -29,7 +29,6 @@
#define mysql_master_send_query(A, B, C) 1
#define mysql_slave_send_query(A, B, C) 1
#define mysql_rpl_probe(mysql) 0
-#undef HAVE_SMEM
#undef _CUSTOMCONFIG_
#define mysql_server_init(a,b,c) mysql_client_plugin_init()
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2010-03-29 15:13:53 +0000
+++ b/sql/ha_ndbcluster.cc 2010-04-01 14:34:51 +0000
@@ -10564,6 +10564,23 @@ mysql_declare_plugin(ndbcluster)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ndbcluster)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ndbcluster_storage_engine,
+ ndbcluster_hton_name,
+ "MySQL AB",
+ "Clustered, fault-tolerant tables",
+ PLUGIN_LICENSE_GPL,
+ ndbcluster_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ ndb_status_variables_export,/* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
#else
int Sun_ar_require_a_symbol_here= 0;
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2010-03-15 11:51:23 +0000
+++ b/sql/ha_partition.cc 2010-04-01 14:34:51 +0000
@@ -6715,5 +6715,22 @@ mysql_declare_plugin(partition)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(partition)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &partition_storage_engine,
+ "partition",
+ "Mikael Ronstrom, MySQL AB",
+ "Partition Storage Engine Helper",
+ PLUGIN_LICENSE_GPL,
+ partition_initialize, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#endif
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-03-29 21:16:12 +0000
+++ b/sql/handler.cc 2010-04-03 20:19:35 +0000
@@ -4282,7 +4282,7 @@ int handler::read_multi_range_first(KEY_
*/
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
- int result;
+ int result= 0;
DBUG_ENTER("handler::read_multi_range_next");
/* We should not be called after the last call returned EOF. */
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2010-03-15 11:51:23 +0000
+++ b/sql/item.cc 2010-04-01 09:04:26 +0000
@@ -7040,7 +7040,7 @@ bool Item_cache_int::cache_value()
}
-void Item_cache_int::store(Item *item, longlong val_arg)
+void Item_cache_int::store_longlong(Item *item, longlong val_arg)
{
/* An explicit values is given, save it. */
value_cached= TRUE;
=== modified file 'sql/item.h'
--- a/sql/item.h 2010-03-15 11:51:23 +0000
+++ b/sql/item.h 2010-04-01 09:04:26 +0000
@@ -1132,7 +1132,8 @@ class Field_enumerator
{
public:
virtual void visit_field(Field *field)= 0;
- virtual ~Field_enumerator() {}; /* purecov: inspected */
+ virtual ~Field_enumerator() {}; /* purecov: inspected */
+ Field_enumerator() {} /* Remove gcc warning */
};
@@ -3148,7 +3149,7 @@ public:
Item_cache_int(enum_field_types field_type_arg):
Item_cache(field_type_arg), value(0) {}
- void store(Item *item, longlong val_arg);
+ void store_longlong(Item *item, longlong val_arg);
double val_real();
longlong val_int();
String* val_str(String *str);
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2010-03-04 08:03:07 +0000
+++ b/sql/item_cmpfunc.cc 2010-03-28 18:10:00 +0000
@@ -879,7 +879,7 @@ get_time_value(THD *thd, Item ***item_ar
Item_cache_int *cache= new Item_cache_int();
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
@@ -917,13 +917,13 @@ int Arg_comparator::set_cmp_func(Item_re
cache->set_used_tables(1);
if (!(*a)->is_datetime())
{
- cache->store((*a), const_value);
+ cache->store_longlong((*a), const_value);
a_cache= cache;
a= (Item **)&a_cache;
}
else
{
- cache->store((*b), const_value);
+ cache->store_longlong((*b), const_value);
b_cache= cache;
b= (Item **)&b_cache;
}
@@ -1145,7 +1145,7 @@ get_datetime_value(THD *thd, Item ***ite
Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
=== modified file 'sql/item_create.cc'
--- a/sql/item_create.cc 2010-03-04 08:03:07 +0000
+++ b/sql/item_create.cc 2010-03-29 19:07:45 +0000
@@ -76,7 +76,7 @@ public:
@param thd The current thread
@return An item representing the function call
*/
- virtual Item *create(THD *thd) = 0;
+ virtual Item *create_builder(THD *thd) = 0;
protected:
/** Constructor. */
@@ -101,7 +101,7 @@ public:
@param arg1 The first argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1) = 0;
+ virtual Item *create_1_arg(THD *thd, Item *arg1) = 0;
protected:
/** Constructor. */
@@ -127,7 +127,7 @@ public:
@param arg2 The second argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2) = 0;
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) = 0;
protected:
/** Constructor. */
@@ -154,7 +154,7 @@ public:
@param arg3 The third argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
protected:
/** Constructor. */
@@ -171,8 +171,8 @@ protected:
class Create_sp_func : public Create_qfunc
{
public:
- virtual Item *create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list);
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list);
static Create_sp_func s_singleton;
@@ -217,7 +217,7 @@ protected:
class Create_func_abs : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_abs s_singleton;
@@ -230,7 +230,7 @@ protected:
class Create_func_acos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_acos s_singleton;
@@ -243,7 +243,7 @@ protected:
class Create_func_addtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_addtime s_singleton;
@@ -256,7 +256,7 @@ protected:
class Create_func_aes_encrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_encrypt s_singleton;
@@ -269,7 +269,7 @@ protected:
class Create_func_aes_decrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_decrypt s_singleton;
@@ -283,7 +283,7 @@ protected:
class Create_func_area : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_area s_singleton;
@@ -298,7 +298,7 @@ protected:
class Create_func_as_wkb : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkb s_singleton;
@@ -313,7 +313,7 @@ protected:
class Create_func_as_wkt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkt s_singleton;
@@ -327,7 +327,7 @@ protected:
class Create_func_asin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_asin s_singleton;
@@ -353,7 +353,7 @@ protected:
class Create_func_benchmark : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_benchmark s_singleton;
@@ -366,7 +366,7 @@ protected:
class Create_func_bin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bin s_singleton;
@@ -379,7 +379,7 @@ protected:
class Create_func_bit_count : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_count s_singleton;
@@ -392,7 +392,7 @@ protected:
class Create_func_bit_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_length s_singleton;
@@ -405,7 +405,7 @@ protected:
class Create_func_ceiling : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ceiling s_singleton;
@@ -419,7 +419,7 @@ protected:
class Create_func_centroid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_centroid s_singleton;
@@ -433,7 +433,7 @@ protected:
class Create_func_char_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_char_length s_singleton;
@@ -446,7 +446,7 @@ protected:
class Create_func_coercibility : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_coercibility s_singleton;
@@ -459,7 +459,7 @@ protected:
class Create_func_compress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_compress s_singleton;
@@ -498,7 +498,7 @@ protected:
class Create_func_connection_id : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_connection_id s_singleton;
@@ -512,7 +512,7 @@ protected:
class Create_func_contains : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_contains s_singleton;
@@ -526,7 +526,7 @@ protected:
class Create_func_conv : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_conv s_singleton;
@@ -539,7 +539,7 @@ protected:
class Create_func_convert_tz : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_convert_tz s_singleton;
@@ -552,7 +552,7 @@ protected:
class Create_func_cos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cos s_singleton;
@@ -565,7 +565,7 @@ protected:
class Create_func_cot : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cot s_singleton;
@@ -578,7 +578,7 @@ protected:
class Create_func_crc32 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_crc32 s_singleton;
@@ -592,7 +592,7 @@ protected:
class Create_func_crosses : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_crosses s_singleton;
@@ -606,7 +606,7 @@ protected:
class Create_func_date_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_date_format s_singleton;
@@ -619,7 +619,7 @@ protected:
class Create_func_datediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_datediff s_singleton;
@@ -632,7 +632,7 @@ protected:
class Create_func_dayname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayname s_singleton;
@@ -645,7 +645,7 @@ protected:
class Create_func_dayofmonth : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofmonth s_singleton;
@@ -658,7 +658,7 @@ protected:
class Create_func_dayofweek : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofweek s_singleton;
@@ -671,7 +671,7 @@ protected:
class Create_func_dayofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofyear s_singleton;
@@ -684,7 +684,7 @@ protected:
class Create_func_decode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_decode s_singleton;
@@ -697,7 +697,7 @@ protected:
class Create_func_degrees : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_degrees s_singleton;
@@ -737,7 +737,7 @@ protected:
class Create_func_dimension : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dimension s_singleton;
@@ -752,7 +752,7 @@ protected:
class Create_func_disjoint : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_disjoint s_singleton;
@@ -779,7 +779,7 @@ protected:
class Create_func_encode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_encode s_singleton;
@@ -806,7 +806,7 @@ protected:
class Create_func_endpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_endpoint s_singleton;
@@ -821,7 +821,7 @@ protected:
class Create_func_envelope : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_envelope s_singleton;
@@ -836,7 +836,7 @@ protected:
class Create_func_equals : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_equals s_singleton;
@@ -850,7 +850,7 @@ protected:
class Create_func_exp : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exp s_singleton;
@@ -877,7 +877,7 @@ protected:
class Create_func_exteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exteriorring s_singleton;
@@ -904,7 +904,7 @@ protected:
class Create_func_find_in_set : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_find_in_set s_singleton;
@@ -917,7 +917,7 @@ protected:
class Create_func_floor : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_floor s_singleton;
@@ -930,7 +930,7 @@ protected:
class Create_func_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_format s_singleton;
@@ -943,7 +943,7 @@ protected:
class Create_func_found_rows : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_found_rows s_singleton;
@@ -956,7 +956,7 @@ protected:
class Create_func_from_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_from_days s_singleton;
@@ -1013,7 +1013,7 @@ protected:
class Create_func_geometry_type : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_geometry_type s_singleton;
@@ -1028,7 +1028,7 @@ protected:
class Create_func_geometryn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_geometryn s_singleton;
@@ -1042,7 +1042,7 @@ protected:
class Create_func_get_lock : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_get_lock s_singleton;
@@ -1056,7 +1056,7 @@ protected:
class Create_func_glength : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_glength s_singleton;
@@ -1083,7 +1083,7 @@ protected:
class Create_func_hex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_hex s_singleton;
@@ -1096,7 +1096,7 @@ protected:
class Create_func_ifnull : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_ifnull s_singleton;
@@ -1109,7 +1109,7 @@ protected:
class Create_func_inet_ntoa : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_ntoa s_singleton;
@@ -1122,7 +1122,7 @@ protected:
class Create_func_inet_aton : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_aton s_singleton;
@@ -1135,7 +1135,7 @@ protected:
class Create_func_instr : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_instr s_singleton;
@@ -1149,7 +1149,7 @@ protected:
class Create_func_interiorringn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_interiorringn s_singleton;
@@ -1164,7 +1164,7 @@ protected:
class Create_func_intersects : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_intersects s_singleton;
@@ -1178,7 +1178,7 @@ protected:
class Create_func_is_free_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_free_lock s_singleton;
@@ -1191,7 +1191,7 @@ protected:
class Create_func_is_used_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_used_lock s_singleton;
@@ -1205,7 +1205,7 @@ protected:
class Create_func_isclosed : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isclosed s_singleton;
@@ -1220,7 +1220,7 @@ protected:
class Create_func_isempty : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isempty s_singleton;
@@ -1234,7 +1234,7 @@ protected:
class Create_func_isnull : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isnull s_singleton;
@@ -1248,7 +1248,7 @@ protected:
class Create_func_issimple : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_issimple s_singleton;
@@ -1262,7 +1262,7 @@ protected:
class Create_func_last_day : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_last_day s_singleton;
@@ -1288,7 +1288,7 @@ protected:
class Create_func_lcase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_lcase s_singleton;
@@ -1314,7 +1314,7 @@ protected:
class Create_func_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_length s_singleton;
@@ -1327,7 +1327,7 @@ protected:
class Create_func_ln : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ln s_singleton;
@@ -1340,7 +1340,7 @@ protected:
class Create_func_load_file : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_load_file s_singleton;
@@ -1379,7 +1379,7 @@ protected:
class Create_func_log10 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log10 s_singleton;
@@ -1392,7 +1392,7 @@ protected:
class Create_func_log2 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log2 s_singleton;
@@ -1405,7 +1405,7 @@ protected:
class Create_func_lpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_lpad s_singleton;
@@ -1418,7 +1418,7 @@ protected:
class Create_func_ltrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ltrim s_singleton;
@@ -1431,7 +1431,7 @@ protected:
class Create_func_makedate : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_makedate s_singleton;
@@ -1444,7 +1444,7 @@ protected:
class Create_func_maketime : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_maketime s_singleton;
@@ -1483,7 +1483,7 @@ protected:
class Create_func_md5 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_md5 s_singleton;
@@ -1496,7 +1496,7 @@ protected:
class Create_func_monthname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_monthname s_singleton;
@@ -1509,7 +1509,7 @@ protected:
class Create_func_name_const : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_name_const s_singleton;
@@ -1522,7 +1522,7 @@ protected:
class Create_func_nullif : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_nullif s_singleton;
@@ -1536,7 +1536,7 @@ protected:
class Create_func_numgeometries : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numgeometries s_singleton;
@@ -1551,7 +1551,7 @@ protected:
class Create_func_numinteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numinteriorring s_singleton;
@@ -1566,7 +1566,7 @@ protected:
class Create_func_numpoints : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numpoints s_singleton;
@@ -1580,7 +1580,7 @@ protected:
class Create_func_oct : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_oct s_singleton;
@@ -1593,7 +1593,7 @@ protected:
class Create_func_ord : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ord s_singleton;
@@ -1607,7 +1607,7 @@ protected:
class Create_func_overlaps : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_overlaps s_singleton;
@@ -1621,7 +1621,7 @@ protected:
class Create_func_period_add : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_add s_singleton;
@@ -1634,7 +1634,7 @@ protected:
class Create_func_period_diff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_diff s_singleton;
@@ -1647,7 +1647,7 @@ protected:
class Create_func_pi : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_pi s_singleton;
@@ -1661,7 +1661,7 @@ protected:
class Create_func_pointn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pointn s_singleton;
@@ -1675,7 +1675,7 @@ protected:
class Create_func_pow : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pow s_singleton;
@@ -1688,7 +1688,7 @@ protected:
class Create_func_quote : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_quote s_singleton;
@@ -1701,7 +1701,7 @@ protected:
class Create_func_radians : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_radians s_singleton;
@@ -1727,7 +1727,7 @@ protected:
class Create_func_release_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_release_lock s_singleton;
@@ -1740,7 +1740,7 @@ protected:
class Create_func_reverse : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_reverse s_singleton;
@@ -1766,7 +1766,7 @@ protected:
class Create_func_row_count : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_row_count s_singleton;
@@ -1779,7 +1779,7 @@ protected:
class Create_func_rpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_rpad s_singleton;
@@ -1792,7 +1792,7 @@ protected:
class Create_func_rtrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_rtrim s_singleton;
@@ -1805,7 +1805,7 @@ protected:
class Create_func_sec_to_time : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sec_to_time s_singleton;
@@ -1818,7 +1818,7 @@ protected:
class Create_func_sha : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sha s_singleton;
@@ -1831,7 +1831,7 @@ protected:
class Create_func_sign : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sign s_singleton;
@@ -1844,7 +1844,7 @@ protected:
class Create_func_sin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sin s_singleton;
@@ -1857,7 +1857,7 @@ protected:
class Create_func_sleep : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sleep s_singleton;
@@ -1870,7 +1870,7 @@ protected:
class Create_func_soundex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_soundex s_singleton;
@@ -1883,7 +1883,7 @@ protected:
class Create_func_space : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_space s_singleton;
@@ -1896,7 +1896,7 @@ protected:
class Create_func_sqrt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sqrt s_singleton;
@@ -1910,7 +1910,7 @@ protected:
class Create_func_srid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_srid s_singleton;
@@ -1925,7 +1925,7 @@ protected:
class Create_func_startpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_startpoint s_singleton;
@@ -1939,7 +1939,7 @@ protected:
class Create_func_str_to_date : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_str_to_date s_singleton;
@@ -1952,7 +1952,7 @@ protected:
class Create_func_strcmp : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_strcmp s_singleton;
@@ -1965,7 +1965,7 @@ protected:
class Create_func_substr_index : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_substr_index s_singleton;
@@ -1978,7 +1978,7 @@ protected:
class Create_func_subtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_subtime s_singleton;
@@ -1991,7 +1991,7 @@ protected:
class Create_func_tan : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_tan s_singleton;
@@ -2004,7 +2004,7 @@ protected:
class Create_func_time_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_time_format s_singleton;
@@ -2017,7 +2017,7 @@ protected:
class Create_func_time_to_sec : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_time_to_sec s_singleton;
@@ -2030,7 +2030,7 @@ protected:
class Create_func_timediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_timediff s_singleton;
@@ -2043,7 +2043,7 @@ protected:
class Create_func_to_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_to_days s_singleton;
@@ -2057,7 +2057,7 @@ protected:
class Create_func_touches : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_touches s_singleton;
@@ -2071,7 +2071,7 @@ protected:
class Create_func_ucase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ucase s_singleton;
@@ -2084,7 +2084,7 @@ protected:
class Create_func_uncompress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompress s_singleton;
@@ -2097,7 +2097,7 @@ protected:
class Create_func_uncompressed_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompressed_length s_singleton;
@@ -2110,7 +2110,7 @@ protected:
class Create_func_unhex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_unhex s_singleton;
@@ -2136,7 +2136,7 @@ protected:
class Create_func_uuid : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid s_singleton;
@@ -2149,7 +2149,7 @@ protected:
class Create_func_uuid_short : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid_short s_singleton;
@@ -2162,7 +2162,7 @@ protected:
class Create_func_version : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_version s_singleton;
@@ -2175,7 +2175,7 @@ protected:
class Create_func_weekday : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekday s_singleton;
@@ -2188,7 +2188,7 @@ protected:
class Create_func_weekofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekofyear s_singleton;
@@ -2202,7 +2202,7 @@ protected:
class Create_func_within : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_within s_singleton;
@@ -2217,7 +2217,7 @@ protected:
class Create_func_x : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_x s_singleton;
@@ -2231,7 +2231,7 @@ protected:
class Create_func_xml_extractvalue : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_xml_extractvalue s_singleton;
@@ -2244,7 +2244,7 @@ protected:
class Create_func_xml_update : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_xml_update s_singleton;
@@ -2258,7 +2258,7 @@ protected:
class Create_func_y : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_y s_singleton;
@@ -2353,7 +2353,7 @@ Create_qfunc::create(THD *thd, LEX_STRIN
if (thd->lex->copy_db_to(&db.str, &db.length))
return NULL;
- return create(thd, db, name, false, item_list);
+ return create_with_db(thd, db, name, false, item_list);
}
@@ -2470,8 +2470,8 @@ Create_udf_func::create(THD *thd, udf_fu
Create_sp_func Create_sp_func::s_singleton;
Item*
-Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list)
+Create_sp_func::create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list)
{
int arg_count= 0;
Item *func= NULL;
@@ -2538,7 +2538,7 @@ Create_func_arg0::create(THD *thd, LEX_S
return NULL;
}
- return create(thd);
+ return create_builder(thd);
}
@@ -2564,7 +2564,7 @@ Create_func_arg1::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1);
+ return create_1_arg(thd, param_1);
}
@@ -2592,7 +2592,7 @@ Create_func_arg2::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2);
+ return create_2_arg(thd, param_1, param_2);
}
@@ -2622,14 +2622,14 @@ Create_func_arg3::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2, param_3);
+ return create_3_arg(thd, param_1, param_2, param_3);
}
Create_func_abs Create_func_abs::s_singleton;
Item*
-Create_func_abs::create(THD *thd, Item *arg1)
+Create_func_abs::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_abs(arg1);
}
@@ -2638,7 +2638,7 @@ Create_func_abs::create(THD *thd, Item *
Create_func_acos Create_func_acos::s_singleton;
Item*
-Create_func_acos::create(THD *thd, Item *arg1)
+Create_func_acos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_acos(arg1);
}
@@ -2647,7 +2647,7 @@ Create_func_acos::create(THD *thd, Item
Create_func_addtime Create_func_addtime::s_singleton;
Item*
-Create_func_addtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_addtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 0);
}
@@ -2656,7 +2656,7 @@ Create_func_addtime::create(THD *thd, It
Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton;
Item*
-Create_func_aes_encrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_encrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_encrypt(arg1, arg2);
}
@@ -2665,7 +2665,7 @@ Create_func_aes_encrypt::create(THD *thd
Create_func_aes_decrypt Create_func_aes_decrypt::s_singleton;
Item*
-Create_func_aes_decrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_decrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_decrypt(arg1, arg2);
}
@@ -2675,7 +2675,7 @@ Create_func_aes_decrypt::create(THD *thd
Create_func_area Create_func_area::s_singleton;
Item*
-Create_func_area::create(THD *thd, Item *arg1)
+Create_func_area::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_area(arg1);
}
@@ -2686,7 +2686,7 @@ Create_func_area::create(THD *thd, Item
Create_func_as_wkb Create_func_as_wkb::s_singleton;
Item*
-Create_func_as_wkb::create(THD *thd, Item *arg1)
+Create_func_as_wkb::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkb(arg1);
}
@@ -2697,7 +2697,7 @@ Create_func_as_wkb::create(THD *thd, Ite
Create_func_as_wkt Create_func_as_wkt::s_singleton;
Item*
-Create_func_as_wkt::create(THD *thd, Item *arg1)
+Create_func_as_wkt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkt(arg1);
}
@@ -2707,7 +2707,7 @@ Create_func_as_wkt::create(THD *thd, Ite
Create_func_asin Create_func_asin::s_singleton;
Item*
-Create_func_asin::create(THD *thd, Item *arg1)
+Create_func_asin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_asin(arg1);
}
@@ -2753,7 +2753,7 @@ Create_func_atan::create_native(THD *thd
Create_func_benchmark Create_func_benchmark::s_singleton;
Item*
-Create_func_benchmark::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_benchmark::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_benchmark(arg1, arg2);
@@ -2763,7 +2763,7 @@ Create_func_benchmark::create(THD *thd,
Create_func_bin Create_func_bin::s_singleton;
Item*
-Create_func_bin::create(THD *thd, Item *arg1)
+Create_func_bin::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i2= new (thd->mem_root) Item_int((int32) 2,1);
@@ -2774,7 +2774,7 @@ Create_func_bin::create(THD *thd, Item *
Create_func_bit_count Create_func_bit_count::s_singleton;
Item*
-Create_func_bit_count::create(THD *thd, Item *arg1)
+Create_func_bit_count::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_count(arg1);
}
@@ -2783,7 +2783,7 @@ Create_func_bit_count::create(THD *thd,
Create_func_bit_length Create_func_bit_length::s_singleton;
Item*
-Create_func_bit_length::create(THD *thd, Item *arg1)
+Create_func_bit_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_length(arg1);
}
@@ -2792,7 +2792,7 @@ Create_func_bit_length::create(THD *thd,
Create_func_ceiling Create_func_ceiling::s_singleton;
Item*
-Create_func_ceiling::create(THD *thd, Item *arg1)
+Create_func_ceiling::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ceiling(arg1);
}
@@ -2802,7 +2802,7 @@ Create_func_ceiling::create(THD *thd, It
Create_func_centroid Create_func_centroid::s_singleton;
Item*
-Create_func_centroid::create(THD *thd, Item *arg1)
+Create_func_centroid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_centroid(arg1);
}
@@ -2812,7 +2812,7 @@ Create_func_centroid::create(THD *thd, I
Create_func_char_length Create_func_char_length::s_singleton;
Item*
-Create_func_char_length::create(THD *thd, Item *arg1)
+Create_func_char_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_char_length(arg1);
}
@@ -2821,7 +2821,7 @@ Create_func_char_length::create(THD *thd
Create_func_coercibility Create_func_coercibility::s_singleton;
Item*
-Create_func_coercibility::create(THD *thd, Item *arg1)
+Create_func_coercibility::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_coercibility(arg1);
}
@@ -2873,7 +2873,7 @@ Create_func_concat_ws::create_native(THD
Create_func_compress Create_func_compress::s_singleton;
Item*
-Create_func_compress::create(THD *thd, Item *arg1)
+Create_func_compress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_compress(arg1);
}
@@ -2882,7 +2882,7 @@ Create_func_compress::create(THD *thd, I
Create_func_connection_id Create_func_connection_id::s_singleton;
Item*
-Create_func_connection_id::create(THD *thd)
+Create_func_connection_id::create_builder(THD *thd)
{
thd->lex->safe_to_cache_query= 0;
return new (thd->mem_root) Item_func_connection_id();
@@ -2893,7 +2893,7 @@ Create_func_connection_id::create(THD *t
Create_func_contains Create_func_contains::s_singleton;
Item*
-Create_func_contains::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_contains::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CONTAINS_FUNC);
@@ -2904,7 +2904,7 @@ Create_func_contains::create(THD *thd, I
Create_func_conv Create_func_conv::s_singleton;
Item*
-Create_func_conv::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_conv::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_conv(arg1, arg2, arg3);
}
@@ -2913,7 +2913,7 @@ Create_func_conv::create(THD *thd, Item
Create_func_convert_tz Create_func_convert_tz::s_singleton;
Item*
-Create_func_convert_tz::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_convert_tz::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_convert_tz(arg1, arg2, arg3);
}
@@ -2922,7 +2922,7 @@ Create_func_convert_tz::create(THD *thd,
Create_func_cos Create_func_cos::s_singleton;
Item*
-Create_func_cos::create(THD *thd, Item *arg1)
+Create_func_cos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_cos(arg1);
}
@@ -2931,7 +2931,7 @@ Create_func_cos::create(THD *thd, Item *
Create_func_cot Create_func_cot::s_singleton;
Item*
-Create_func_cot::create(THD *thd, Item *arg1)
+Create_func_cot::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "1", 1, 1);
Item *i2= new (thd->mem_root) Item_func_tan(arg1);
@@ -2942,7 +2942,7 @@ Create_func_cot::create(THD *thd, Item *
Create_func_crc32 Create_func_crc32::s_singleton;
Item*
-Create_func_crc32::create(THD *thd, Item *arg1)
+Create_func_crc32::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_crc32(arg1);
}
@@ -2952,7 +2952,7 @@ Create_func_crc32::create(THD *thd, Item
Create_func_crosses Create_func_crosses::s_singleton;
Item*
-Create_func_crosses::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_crosses::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CROSSES_FUNC);
@@ -2963,7 +2963,7 @@ Create_func_crosses::create(THD *thd, It
Create_func_date_format Create_func_date_format::s_singleton;
Item*
-Create_func_date_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_date_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 0);
}
@@ -2972,7 +2972,7 @@ Create_func_date_format::create(THD *thd
Create_func_datediff Create_func_datediff::s_singleton;
Item*
-Create_func_datediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_datediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
Item *i1= new (thd->mem_root) Item_func_to_days(arg1);
Item *i2= new (thd->mem_root) Item_func_to_days(arg2);
@@ -2984,7 +2984,7 @@ Create_func_datediff::create(THD *thd, I
Create_func_dayname Create_func_dayname::s_singleton;
Item*
-Create_func_dayname::create(THD *thd, Item *arg1)
+Create_func_dayname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayname(arg1);
}
@@ -2993,7 +2993,7 @@ Create_func_dayname::create(THD *thd, It
Create_func_dayofmonth Create_func_dayofmonth::s_singleton;
Item*
-Create_func_dayofmonth::create(THD *thd, Item *arg1)
+Create_func_dayofmonth::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofmonth(arg1);
}
@@ -3002,7 +3002,7 @@ Create_func_dayofmonth::create(THD *thd,
Create_func_dayofweek Create_func_dayofweek::s_singleton;
Item*
-Create_func_dayofweek::create(THD *thd, Item *arg1)
+Create_func_dayofweek::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 1);
}
@@ -3011,7 +3011,7 @@ Create_func_dayofweek::create(THD *thd,
Create_func_dayofyear Create_func_dayofyear::s_singleton;
Item*
-Create_func_dayofyear::create(THD *thd, Item *arg1)
+Create_func_dayofyear::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofyear(arg1);
}
@@ -3020,7 +3020,7 @@ Create_func_dayofyear::create(THD *thd,
Create_func_decode Create_func_decode::s_singleton;
Item*
-Create_func_decode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_decode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_decode(arg1, arg2);
}
@@ -3029,7 +3029,7 @@ Create_func_decode::create(THD *thd, Ite
Create_func_degrees Create_func_degrees::s_singleton;
Item*
-Create_func_degrees::create(THD *thd, Item *arg1)
+Create_func_degrees::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "degrees", arg1,
180/M_PI, 0.0);
@@ -3114,7 +3114,7 @@ Create_func_des_encrypt::create_native(T
Create_func_dimension Create_func_dimension::s_singleton;
Item*
-Create_func_dimension::create(THD *thd, Item *arg1)
+Create_func_dimension::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dimension(arg1);
}
@@ -3125,7 +3125,7 @@ Create_func_dimension::create(THD *thd,
Create_func_disjoint Create_func_disjoint::s_singleton;
Item*
-Create_func_disjoint::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_disjoint::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_DISJOINT_FUNC);
@@ -3157,7 +3157,7 @@ Create_func_elt::create_native(THD *thd,
Create_func_encode Create_func_encode::s_singleton;
Item*
-Create_func_encode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_encode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_encode(arg1, arg2);
}
@@ -3205,7 +3205,7 @@ Create_func_encrypt::create_native(THD *
Create_func_endpoint Create_func_endpoint::s_singleton;
Item*
-Create_func_endpoint::create(THD *thd, Item *arg1)
+Create_func_endpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_ENDPOINT);
@@ -3217,7 +3217,7 @@ Create_func_endpoint::create(THD *thd, I
Create_func_envelope Create_func_envelope::s_singleton;
Item*
-Create_func_envelope::create(THD *thd, Item *arg1)
+Create_func_envelope::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_envelope(arg1);
}
@@ -3228,7 +3228,7 @@ Create_func_envelope::create(THD *thd, I
Create_func_equals Create_func_equals::s_singleton;
Item*
-Create_func_equals::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_equals::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_EQUALS_FUNC);
@@ -3239,7 +3239,7 @@ Create_func_equals::create(THD *thd, Ite
Create_func_exp Create_func_exp::s_singleton;
Item*
-Create_func_exp::create(THD *thd, Item *arg1)
+Create_func_exp::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_exp(arg1);
}
@@ -3302,7 +3302,7 @@ Create_func_export_set::create_native(TH
Create_func_exteriorring Create_func_exteriorring::s_singleton;
Item*
-Create_func_exteriorring::create(THD *thd, Item *arg1)
+Create_func_exteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_EXTERIORRING);
@@ -3334,7 +3334,7 @@ Create_func_field::create_native(THD *th
Create_func_find_in_set Create_func_find_in_set::s_singleton;
Item*
-Create_func_find_in_set::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_find_in_set::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_find_in_set(arg1, arg2);
}
@@ -3343,7 +3343,7 @@ Create_func_find_in_set::create(THD *thd
Create_func_floor Create_func_floor::s_singleton;
Item*
-Create_func_floor::create(THD *thd, Item *arg1)
+Create_func_floor::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_floor(arg1);
}
@@ -3352,7 +3352,7 @@ Create_func_floor::create(THD *thd, Item
Create_func_format Create_func_format::s_singleton;
Item*
-Create_func_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_format(arg1, arg2);
}
@@ -3361,7 +3361,7 @@ Create_func_format::create(THD *thd, Ite
Create_func_found_rows Create_func_found_rows::s_singleton;
Item*
-Create_func_found_rows::create(THD *thd)
+Create_func_found_rows::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -3372,7 +3372,7 @@ Create_func_found_rows::create(THD *thd)
Create_func_from_days Create_func_from_days::s_singleton;
Item*
-Create_func_from_days::create(THD *thd, Item *arg1)
+Create_func_from_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_from_days(arg1);
}
@@ -3500,7 +3500,7 @@ Create_func_geometry_from_wkb::create_na
Create_func_geometry_type Create_func_geometry_type::s_singleton;
Item*
-Create_func_geometry_type::create(THD *thd, Item *arg1)
+Create_func_geometry_type::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_geometry_type(arg1);
}
@@ -3511,7 +3511,7 @@ Create_func_geometry_type::create(THD *t
Create_func_geometryn Create_func_geometryn::s_singleton;
Item*
-Create_func_geometryn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_geometryn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_GEOMETRYN);
@@ -3522,7 +3522,7 @@ Create_func_geometryn::create(THD *thd,
Create_func_get_lock Create_func_get_lock::s_singleton;
Item*
-Create_func_get_lock::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_get_lock::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3534,7 +3534,7 @@ Create_func_get_lock::create(THD *thd, I
Create_func_glength Create_func_glength::s_singleton;
Item*
-Create_func_glength::create(THD *thd, Item *arg1)
+Create_func_glength::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_glength(arg1);
}
@@ -3565,7 +3565,7 @@ Create_func_greatest::create_native(THD
Create_func_hex Create_func_hex::s_singleton;
Item*
-Create_func_hex::create(THD *thd, Item *arg1)
+Create_func_hex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_hex(arg1);
}
@@ -3574,7 +3574,7 @@ Create_func_hex::create(THD *thd, Item *
Create_func_ifnull Create_func_ifnull::s_singleton;
Item*
-Create_func_ifnull::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_ifnull::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_ifnull(arg1, arg2);
}
@@ -3583,7 +3583,7 @@ Create_func_ifnull::create(THD *thd, Ite
Create_func_inet_ntoa Create_func_inet_ntoa::s_singleton;
Item*
-Create_func_inet_ntoa::create(THD *thd, Item *arg1)
+Create_func_inet_ntoa::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_ntoa(arg1);
}
@@ -3592,7 +3592,7 @@ Create_func_inet_ntoa::create(THD *thd,
Create_func_inet_aton Create_func_inet_aton::s_singleton;
Item*
-Create_func_inet_aton::create(THD *thd, Item *arg1)
+Create_func_inet_aton::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_aton(arg1);
}
@@ -3601,7 +3601,7 @@ Create_func_inet_aton::create(THD *thd,
Create_func_instr Create_func_instr::s_singleton;
Item*
-Create_func_instr::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_instr::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_locate(arg1, arg2);
}
@@ -3611,7 +3611,7 @@ Create_func_instr::create(THD *thd, Item
Create_func_interiorringn Create_func_interiorringn::s_singleton;
Item*
-Create_func_interiorringn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_interiorringn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_INTERIORRINGN);
@@ -3623,7 +3623,7 @@ Create_func_interiorringn::create(THD *t
Create_func_intersects Create_func_intersects::s_singleton;
Item*
-Create_func_intersects::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_intersects::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_INTERSECTS_FUNC);
@@ -3634,7 +3634,7 @@ Create_func_intersects::create(THD *thd,
Create_func_is_free_lock Create_func_is_free_lock::s_singleton;
Item*
-Create_func_is_free_lock::create(THD *thd, Item *arg1)
+Create_func_is_free_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3645,7 +3645,7 @@ Create_func_is_free_lock::create(THD *th
Create_func_is_used_lock Create_func_is_used_lock::s_singleton;
Item*
-Create_func_is_used_lock::create(THD *thd, Item *arg1)
+Create_func_is_used_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3657,7 +3657,7 @@ Create_func_is_used_lock::create(THD *th
Create_func_isclosed Create_func_isclosed::s_singleton;
Item*
-Create_func_isclosed::create(THD *thd, Item *arg1)
+Create_func_isclosed::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isclosed(arg1);
}
@@ -3668,7 +3668,7 @@ Create_func_isclosed::create(THD *thd, I
Create_func_isempty Create_func_isempty::s_singleton;
Item*
-Create_func_isempty::create(THD *thd, Item *arg1)
+Create_func_isempty::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isempty(arg1);
}
@@ -3678,7 +3678,7 @@ Create_func_isempty::create(THD *thd, It
Create_func_isnull Create_func_isnull::s_singleton;
Item*
-Create_func_isnull::create(THD *thd, Item *arg1)
+Create_func_isnull::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isnull(arg1);
}
@@ -3688,7 +3688,7 @@ Create_func_isnull::create(THD *thd, Ite
Create_func_issimple Create_func_issimple::s_singleton;
Item*
-Create_func_issimple::create(THD *thd, Item *arg1)
+Create_func_issimple::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_issimple(arg1);
}
@@ -3698,7 +3698,7 @@ Create_func_issimple::create(THD *thd, I
Create_func_last_day Create_func_last_day::s_singleton;
Item*
-Create_func_last_day::create(THD *thd, Item *arg1)
+Create_func_last_day::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_last_day(arg1);
}
@@ -3744,7 +3744,7 @@ Create_func_last_insert_id::create_nativ
Create_func_lcase Create_func_lcase::s_singleton;
Item*
-Create_func_lcase::create(THD *thd, Item *arg1)
+Create_func_lcase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_lcase(arg1);
}
@@ -3774,7 +3774,7 @@ Create_func_least::create_native(THD *th
Create_func_length Create_func_length::s_singleton;
Item*
-Create_func_length::create(THD *thd, Item *arg1)
+Create_func_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_length(arg1);
}
@@ -3783,7 +3783,7 @@ Create_func_length::create(THD *thd, Ite
Create_func_ln Create_func_ln::s_singleton;
Item*
-Create_func_ln::create(THD *thd, Item *arg1)
+Create_func_ln::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ln(arg1);
}
@@ -3792,7 +3792,7 @@ Create_func_ln::create(THD *thd, Item *a
Create_func_load_file Create_func_load_file::s_singleton;
Item*
-Create_func_load_file::create(THD *thd, Item *arg1)
+Create_func_load_file::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3881,7 +3881,7 @@ Create_func_log::create_native(THD *thd,
Create_func_log10 Create_func_log10::s_singleton;
Item*
-Create_func_log10::create(THD *thd, Item *arg1)
+Create_func_log10::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log10(arg1);
}
@@ -3890,7 +3890,7 @@ Create_func_log10::create(THD *thd, Item
Create_func_log2 Create_func_log2::s_singleton;
Item*
-Create_func_log2::create(THD *thd, Item *arg1)
+Create_func_log2::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log2(arg1);
}
@@ -3899,7 +3899,7 @@ Create_func_log2::create(THD *thd, Item
Create_func_lpad Create_func_lpad::s_singleton;
Item*
-Create_func_lpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_lpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_lpad(arg1, arg2, arg3);
}
@@ -3908,7 +3908,7 @@ Create_func_lpad::create(THD *thd, Item
Create_func_ltrim Create_func_ltrim::s_singleton;
Item*
-Create_func_ltrim::create(THD *thd, Item *arg1)
+Create_func_ltrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ltrim(arg1);
}
@@ -3917,7 +3917,7 @@ Create_func_ltrim::create(THD *thd, Item
Create_func_makedate Create_func_makedate::s_singleton;
Item*
-Create_func_makedate::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_makedate::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_makedate(arg1, arg2);
}
@@ -3926,7 +3926,7 @@ Create_func_makedate::create(THD *thd, I
Create_func_maketime Create_func_maketime::s_singleton;
Item*
-Create_func_maketime::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_maketime::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_maketime(arg1, arg2, arg3);
}
@@ -4001,7 +4001,7 @@ Create_func_master_pos_wait::create_nati
Create_func_md5 Create_func_md5::s_singleton;
Item*
-Create_func_md5::create(THD *thd, Item *arg1)
+Create_func_md5::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_md5(arg1);
}
@@ -4010,7 +4010,7 @@ Create_func_md5::create(THD *thd, Item *
Create_func_monthname Create_func_monthname::s_singleton;
Item*
-Create_func_monthname::create(THD *thd, Item *arg1)
+Create_func_monthname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_monthname(arg1);
}
@@ -4019,7 +4019,7 @@ Create_func_monthname::create(THD *thd,
Create_func_name_const Create_func_name_const::s_singleton;
Item*
-Create_func_name_const::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_name_const::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_name_const(arg1, arg2);
}
@@ -4028,7 +4028,7 @@ Create_func_name_const::create(THD *thd,
Create_func_nullif Create_func_nullif::s_singleton;
Item*
-Create_func_nullif::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_nullif::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_nullif(arg1, arg2);
}
@@ -4038,7 +4038,7 @@ Create_func_nullif::create(THD *thd, Ite
Create_func_numgeometries Create_func_numgeometries::s_singleton;
Item*
-Create_func_numgeometries::create(THD *thd, Item *arg1)
+Create_func_numgeometries::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numgeometries(arg1);
}
@@ -4049,7 +4049,7 @@ Create_func_numgeometries::create(THD *t
Create_func_numinteriorring Create_func_numinteriorring::s_singleton;
Item*
-Create_func_numinteriorring::create(THD *thd, Item *arg1)
+Create_func_numinteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numinteriorring(arg1);
}
@@ -4060,7 +4060,7 @@ Create_func_numinteriorring::create(THD
Create_func_numpoints Create_func_numpoints::s_singleton;
Item*
-Create_func_numpoints::create(THD *thd, Item *arg1)
+Create_func_numpoints::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numpoints(arg1);
}
@@ -4070,7 +4070,7 @@ Create_func_numpoints::create(THD *thd,
Create_func_oct Create_func_oct::s_singleton;
Item*
-Create_func_oct::create(THD *thd, Item *arg1)
+Create_func_oct::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i8= new (thd->mem_root) Item_int((int32) 8,1);
@@ -4081,7 +4081,7 @@ Create_func_oct::create(THD *thd, Item *
Create_func_ord Create_func_ord::s_singleton;
Item*
-Create_func_ord::create(THD *thd, Item *arg1)
+Create_func_ord::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ord(arg1);
}
@@ -4091,7 +4091,7 @@ Create_func_ord::create(THD *thd, Item *
Create_func_overlaps Create_func_overlaps::s_singleton;
Item*
-Create_func_overlaps::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_overlaps::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_OVERLAPS_FUNC);
@@ -4102,7 +4102,7 @@ Create_func_overlaps::create(THD *thd, I
Create_func_period_add Create_func_period_add::s_singleton;
Item*
-Create_func_period_add::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_add::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_add(arg1, arg2);
}
@@ -4111,7 +4111,7 @@ Create_func_period_add::create(THD *thd,
Create_func_period_diff Create_func_period_diff::s_singleton;
Item*
-Create_func_period_diff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_diff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_diff(arg1, arg2);
}
@@ -4120,7 +4120,7 @@ Create_func_period_diff::create(THD *thd
Create_func_pi Create_func_pi::s_singleton;
Item*
-Create_func_pi::create(THD *thd)
+Create_func_pi::create_builder(THD *thd)
{
return new (thd->mem_root) Item_static_float_func("pi()", M_PI, 6, 8);
}
@@ -4130,7 +4130,7 @@ Create_func_pi::create(THD *thd)
Create_func_pointn Create_func_pointn::s_singleton;
Item*
-Create_func_pointn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pointn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_POINTN);
@@ -4141,7 +4141,7 @@ Create_func_pointn::create(THD *thd, Ite
Create_func_pow Create_func_pow::s_singleton;
Item*
-Create_func_pow::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pow::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_pow(arg1, arg2);
}
@@ -4150,7 +4150,7 @@ Create_func_pow::create(THD *thd, Item *
Create_func_quote Create_func_quote::s_singleton;
Item*
-Create_func_quote::create(THD *thd, Item *arg1)
+Create_func_quote::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_quote(arg1);
}
@@ -4159,7 +4159,7 @@ Create_func_quote::create(THD *thd, Item
Create_func_radians Create_func_radians::s_singleton;
Item*
-Create_func_radians::create(THD *thd, Item *arg1)
+Create_func_radians::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "radians", arg1,
M_PI/180, 0.0);
@@ -4216,7 +4216,7 @@ Create_func_rand::create_native(THD *thd
Create_func_release_lock Create_func_release_lock::s_singleton;
Item*
-Create_func_release_lock::create(THD *thd, Item *arg1)
+Create_func_release_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4227,7 +4227,7 @@ Create_func_release_lock::create(THD *th
Create_func_reverse Create_func_reverse::s_singleton;
Item*
-Create_func_reverse::create(THD *thd, Item *arg1)
+Create_func_reverse::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_reverse(arg1);
}
@@ -4274,7 +4274,7 @@ Create_func_round::create_native(THD *th
Create_func_row_count Create_func_row_count::s_singleton;
Item*
-Create_func_row_count::create(THD *thd)
+Create_func_row_count::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4285,7 +4285,7 @@ Create_func_row_count::create(THD *thd)
Create_func_rpad Create_func_rpad::s_singleton;
Item*
-Create_func_rpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_rpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_rpad(arg1, arg2, arg3);
}
@@ -4294,7 +4294,7 @@ Create_func_rpad::create(THD *thd, Item
Create_func_rtrim Create_func_rtrim::s_singleton;
Item*
-Create_func_rtrim::create(THD *thd, Item *arg1)
+Create_func_rtrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_rtrim(arg1);
}
@@ -4303,7 +4303,7 @@ Create_func_rtrim::create(THD *thd, Item
Create_func_sec_to_time Create_func_sec_to_time::s_singleton;
Item*
-Create_func_sec_to_time::create(THD *thd, Item *arg1)
+Create_func_sec_to_time::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sec_to_time(arg1);
}
@@ -4312,7 +4312,7 @@ Create_func_sec_to_time::create(THD *thd
Create_func_sha Create_func_sha::s_singleton;
Item*
-Create_func_sha::create(THD *thd, Item *arg1)
+Create_func_sha::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sha(arg1);
}
@@ -4321,7 +4321,7 @@ Create_func_sha::create(THD *thd, Item *
Create_func_sign Create_func_sign::s_singleton;
Item*
-Create_func_sign::create(THD *thd, Item *arg1)
+Create_func_sign::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sign(arg1);
}
@@ -4330,7 +4330,7 @@ Create_func_sign::create(THD *thd, Item
Create_func_sin Create_func_sin::s_singleton;
Item*
-Create_func_sin::create(THD *thd, Item *arg1)
+Create_func_sin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sin(arg1);
}
@@ -4339,7 +4339,7 @@ Create_func_sin::create(THD *thd, Item *
Create_func_sleep Create_func_sleep::s_singleton;
Item*
-Create_func_sleep::create(THD *thd, Item *arg1)
+Create_func_sleep::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4350,7 +4350,7 @@ Create_func_sleep::create(THD *thd, Item
Create_func_soundex Create_func_soundex::s_singleton;
Item*
-Create_func_soundex::create(THD *thd, Item *arg1)
+Create_func_soundex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_soundex(arg1);
}
@@ -4359,7 +4359,7 @@ Create_func_soundex::create(THD *thd, It
Create_func_space Create_func_space::s_singleton;
Item*
-Create_func_space::create(THD *thd, Item *arg1)
+Create_func_space::create_1_arg(THD *thd, Item *arg1)
{
/**
TODO: Fix Bug#23637
@@ -4387,7 +4387,7 @@ Create_func_space::create(THD *thd, Item
Create_func_sqrt Create_func_sqrt::s_singleton;
Item*
-Create_func_sqrt::create(THD *thd, Item *arg1)
+Create_func_sqrt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sqrt(arg1);
}
@@ -4397,7 +4397,7 @@ Create_func_sqrt::create(THD *thd, Item
Create_func_srid Create_func_srid::s_singleton;
Item*
-Create_func_srid::create(THD *thd, Item *arg1)
+Create_func_srid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_srid(arg1);
}
@@ -4408,7 +4408,7 @@ Create_func_srid::create(THD *thd, Item
Create_func_startpoint Create_func_startpoint::s_singleton;
Item*
-Create_func_startpoint::create(THD *thd, Item *arg1)
+Create_func_startpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_STARTPOINT);
@@ -4419,7 +4419,7 @@ Create_func_startpoint::create(THD *thd,
Create_func_str_to_date Create_func_str_to_date::s_singleton;
Item*
-Create_func_str_to_date::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_str_to_date::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_str_to_date(arg1, arg2);
}
@@ -4428,7 +4428,7 @@ Create_func_str_to_date::create(THD *thd
Create_func_strcmp Create_func_strcmp::s_singleton;
Item*
-Create_func_strcmp::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_strcmp::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_strcmp(arg1, arg2);
}
@@ -4437,7 +4437,7 @@ Create_func_strcmp::create(THD *thd, Ite
Create_func_substr_index Create_func_substr_index::s_singleton;
Item*
-Create_func_substr_index::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_substr_index::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_substr_index(arg1, arg2, arg3);
}
@@ -4446,7 +4446,7 @@ Create_func_substr_index::create(THD *th
Create_func_subtime Create_func_subtime::s_singleton;
Item*
-Create_func_subtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_subtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 1);
}
@@ -4455,7 +4455,7 @@ Create_func_subtime::create(THD *thd, It
Create_func_tan Create_func_tan::s_singleton;
Item*
-Create_func_tan::create(THD *thd, Item *arg1)
+Create_func_tan::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_tan(arg1);
}
@@ -4464,7 +4464,7 @@ Create_func_tan::create(THD *thd, Item *
Create_func_time_format Create_func_time_format::s_singleton;
Item*
-Create_func_time_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_time_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 1);
}
@@ -4473,7 +4473,7 @@ Create_func_time_format::create(THD *thd
Create_func_time_to_sec Create_func_time_to_sec::s_singleton;
Item*
-Create_func_time_to_sec::create(THD *thd, Item *arg1)
+Create_func_time_to_sec::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_time_to_sec(arg1);
}
@@ -4482,7 +4482,7 @@ Create_func_time_to_sec::create(THD *thd
Create_func_timediff Create_func_timediff::s_singleton;
Item*
-Create_func_timediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_timediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_timediff(arg1, arg2);
}
@@ -4491,7 +4491,7 @@ Create_func_timediff::create(THD *thd, I
Create_func_to_days Create_func_to_days::s_singleton;
Item*
-Create_func_to_days::create(THD *thd, Item *arg1)
+Create_func_to_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_to_days(arg1);
}
@@ -4501,7 +4501,7 @@ Create_func_to_days::create(THD *thd, It
Create_func_touches Create_func_touches::s_singleton;
Item*
-Create_func_touches::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_touches::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_TOUCHES_FUNC);
@@ -4512,7 +4512,7 @@ Create_func_touches::create(THD *thd, It
Create_func_ucase Create_func_ucase::s_singleton;
Item*
-Create_func_ucase::create(THD *thd, Item *arg1)
+Create_func_ucase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ucase(arg1);
}
@@ -4521,7 +4521,7 @@ Create_func_ucase::create(THD *thd, Item
Create_func_uncompress Create_func_uncompress::s_singleton;
Item*
-Create_func_uncompress::create(THD *thd, Item *arg1)
+Create_func_uncompress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompress(arg1);
}
@@ -4530,7 +4530,7 @@ Create_func_uncompress::create(THD *thd,
Create_func_uncompressed_length Create_func_uncompressed_length::s_singleton;
Item*
-Create_func_uncompressed_length::create(THD *thd, Item *arg1)
+Create_func_uncompressed_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompressed_length(arg1);
}
@@ -4539,7 +4539,7 @@ Create_func_uncompressed_length::create(
Create_func_unhex Create_func_unhex::s_singleton;
Item*
-Create_func_unhex::create(THD *thd, Item *arg1)
+Create_func_unhex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_unhex(arg1);
}
@@ -4584,7 +4584,7 @@ Create_func_unix_timestamp::create_nativ
Create_func_uuid Create_func_uuid::s_singleton;
Item*
-Create_func_uuid::create(THD *thd)
+Create_func_uuid::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4595,7 +4595,7 @@ Create_func_uuid::create(THD *thd)
Create_func_uuid_short Create_func_uuid_short::s_singleton;
Item*
-Create_func_uuid_short::create(THD *thd)
+Create_func_uuid_short::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4606,7 +4606,7 @@ Create_func_uuid_short::create(THD *thd)
Create_func_version Create_func_version::s_singleton;
Item*
-Create_func_version::create(THD *thd)
+Create_func_version::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
return new (thd->mem_root) Item_static_string_func("version()",
@@ -4620,7 +4620,7 @@ Create_func_version::create(THD *thd)
Create_func_weekday Create_func_weekday::s_singleton;
Item*
-Create_func_weekday::create(THD *thd, Item *arg1)
+Create_func_weekday::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 0);
}
@@ -4629,7 +4629,7 @@ Create_func_weekday::create(THD *thd, It
Create_func_weekofyear Create_func_weekofyear::s_singleton;
Item*
-Create_func_weekofyear::create(THD *thd, Item *arg1)
+Create_func_weekofyear::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "0", 3, 1);
return new (thd->mem_root) Item_func_week(arg1, i1);
@@ -4640,7 +4640,7 @@ Create_func_weekofyear::create(THD *thd,
Create_func_within Create_func_within::s_singleton;
Item*
-Create_func_within::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_within::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_WITHIN_FUNC);
@@ -4652,7 +4652,7 @@ Create_func_within::create(THD *thd, Ite
Create_func_x Create_func_x::s_singleton;
Item*
-Create_func_x::create(THD *thd, Item *arg1)
+Create_func_x::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_x(arg1);
}
@@ -4662,7 +4662,7 @@ Create_func_x::create(THD *thd, Item *ar
Create_func_xml_extractvalue Create_func_xml_extractvalue::s_singleton;
Item*
-Create_func_xml_extractvalue::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_xml_extractvalue::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_xml_extractvalue(arg1, arg2);
}
@@ -4671,7 +4671,7 @@ Create_func_xml_extractvalue::create(THD
Create_func_xml_update Create_func_xml_update::s_singleton;
Item*
-Create_func_xml_update::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_xml_update::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_xml_update(arg1, arg2, arg3);
}
@@ -4681,7 +4681,7 @@ Create_func_xml_update::create(THD *thd,
Create_func_y Create_func_y::s_singleton;
Item*
-Create_func_y::create(THD *thd, Item *arg1)
+Create_func_y::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_y(arg1);
}
=== modified file 'sql/item_create.h'
--- a/sql/item_create.h 2007-08-15 13:43:08 +0000
+++ b/sql/item_create.h 2010-03-28 18:10:00 +0000
@@ -91,8 +91,9 @@ public:
@param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call
*/
- virtual Item* create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list) = 0;
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name,
+ List<Item> *item_list) = 0;
protected:
/** Constructor. */
=== modified file 'sql/item_sum.cc'
--- a/sql/item_sum.cc 2010-01-15 15:27:55 +0000
+++ b/sql/item_sum.cc 2010-03-28 18:10:00 +0000
@@ -642,7 +642,7 @@ Item_sum_hybrid::fix_fields(THD *thd, It
default:
DBUG_ASSERT(0);
};
- setup(args[0], NULL);
+ setup_item(args[0], NULL);
/* MIN/MAX can return NULL for empty set indepedent of the used column */
maybe_null= 1;
unsigned_flag=item->unsigned_flag;
@@ -676,7 +676,7 @@ Item_sum_hybrid::fix_fields(THD *thd, It
of the original MIN/MAX object and it is saved in this object's cache.
*/
-void Item_sum_hybrid::setup(Item *item, Item *value_arg)
+void Item_sum_hybrid::setup_item(Item *item, Item *value_arg)
{
value= Item_cache::get_cache(item);
value->setup(item);
@@ -1646,7 +1646,7 @@ void Item_sum_hybrid::no_rows_in_result(
Item *Item_sum_min::copy_or_same(THD* thd)
{
Item_sum_min *item= new (thd->mem_root) Item_sum_min(thd, this);
- item->setup(args[0], value);
+ item->setup_item(args[0], value);
return item;
}
@@ -1669,7 +1669,7 @@ bool Item_sum_min::add()
Item *Item_sum_max::copy_or_same(THD* thd)
{
Item_sum_max *item= new (thd->mem_root) Item_sum_max(thd, this);
- item->setup(args[0], value);
+ item->setup_item(args[0], value);
return item;
}
=== modified file 'sql/item_sum.h'
--- a/sql/item_sum.h 2010-02-01 06:14:12 +0000
+++ b/sql/item_sum.h 2010-04-01 09:04:26 +0000
@@ -870,7 +870,7 @@ protected:
was_values(item->was_values)
{ }
bool fix_fields(THD *, Item **);
- void setup(Item *item, Item *value_arg);
+ void setup_item(Item *item, Item *value_arg);
void clear();
double val_real();
longlong val_int();
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-03-15 11:51:23 +0000
+++ b/sql/log.cc 2010-04-01 14:34:51 +0000
@@ -5424,7 +5424,7 @@ int TC_LOG_MMAP::open(const char *opt_na
pg->state=POOL;
pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST);
pthread_cond_init (&pg->cond, 0);
- pg->start=(my_xid *)(data + i*tc_log_page_size);
+ pg->ptr= pg->start=(my_xid *)(data + i*tc_log_page_size);
pg->size=pg->free=tc_log_page_size/sizeof(my_xid);
pg->end=pg->start + pg->size;
}
@@ -5659,7 +5659,15 @@ int TC_LOG_MMAP::sync()
/* marking 'syncing' slot free */
pthread_mutex_lock(&LOCK_sync);
syncing=0;
- pthread_cond_signal(&active->cond); // wake up a new syncer
+ /*
+ we check the "active" pointer without LOCK_active. Still, it's safe -
+ "active" can change from NULL to not NULL any time, but it
+ will take LOCK_sync before waiting on active->cond. That is, it can never
+ miss a signal.
+ And "active" can change to NULL only after LOCK_sync, so this is safe too.
+ */
+ if (active)
+ pthread_cond_signal(&active->cond); // wake up a new syncer
pthread_mutex_unlock(&LOCK_sync);
return err;
}
@@ -6028,3 +6036,20 @@ mysql_declare_plugin(binlog)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(binlog)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &binlog_storage_engine,
+ "binlog",
+ "MySQL AB",
+ "This is a pseudo storage engine to represent the binlog in a transaction",
+ PLUGIN_LICENSE_GPL,
+ binlog_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2010-03-15 11:51:23 +0000
+++ b/sql/log_event.cc 2010-04-02 09:20:09 +0000
@@ -1716,8 +1716,7 @@ beg:
case MYSQL_TYPE_DATETIME:
{
- size_t d, t;
- uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
+ uint64 d, t, i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
d= i64 / 1000000;
t= i64 % 1000000;
my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-31 23:10:03 +0000
+++ b/sql/mysqld.cc 2010-04-03 20:19:35 +0000
@@ -6646,8 +6646,6 @@ Can't be set to 1 if --log-slave-updates
{"shared-memory", OPT_ENABLE_SHARED_MEMORY,
"Enable the shared memory.",(uchar**) &opt_enable_shared_memory, (uchar**) &opt_enable_shared_memory,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
-#ifdef HAVE_SMEM
{"shared-memory-base-name",OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -8378,6 +8376,8 @@ mysqld_get_one_option(int optid,
case (int) OPT_INIT_RPL_ROLE:
{
int role;
+ LINT_INIT(role);
+
if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role))
{
rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
@@ -8434,6 +8434,8 @@ mysqld_get_one_option(int optid,
case OPT_BINLOG_FORMAT:
{
int id;
+ LINT_INIT(id);
+
if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id))
{
global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
@@ -8684,6 +8686,8 @@ mysqld_get_one_option(int optid,
else
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type))
delay_key_write_options= (uint) type-1;
}
@@ -8695,6 +8699,8 @@ mysqld_get_one_option(int optid,
case OPT_TX_ISOLATION:
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type))
global_system_variables.tx_isolation= (type-1);
break;
@@ -8782,6 +8788,7 @@ mysqld_get_one_option(int optid,
ulong method_conv;
int method;
LINT_INIT(method_conv);
+ LINT_INIT(method);
myisam_stats_method_str= argument;
if (!find_opt_type(argument, &myisam_stats_method_typelib,
@@ -8844,6 +8851,7 @@ mysqld_get_one_option(int optid,
case OPT_THREAD_HANDLING:
{
int id;
+ LINT_INIT(id);
if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id))
global_system_variables.thread_handling= id - 1;
opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];
=== modified file 'sql/net_serv.cc'
--- a/sql/net_serv.cc 2010-02-23 12:04:58 +0000
+++ b/sql/net_serv.cc 2010-03-29 19:07:45 +0000
@@ -279,7 +279,7 @@ static int net_data_is_ready(my_socket s
@param clear_buffer if <> 0, then clear all data from comm buff
*/
-void net_clear(NET *net, my_bool clear_buffer)
+void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
size_t count;
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2010-03-29 21:16:12 +0000
+++ b/sql/set_var.cc 2010-04-03 20:19:35 +0000
@@ -1269,16 +1269,16 @@ uchar *sys_var_set::value_ptr(THD *thd,
void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
{
- slave_exec_mode_options= 0;
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ slave_exec_mode_options= (ULL(1) << SLAVE_EXEC_MODE_STRICT);
}
bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
{
bool rc= sys_var_set::check(thd, var);
if (!rc &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ test_all_bits(var->save_result.ulong_value,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
rc= true;
my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
@@ -1300,15 +1300,16 @@ void fix_slave_exec_mode(enum_var_type t
DBUG_ENTER("fix_slave_exec_mode");
compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT
> SLAVE_EXEC_MODE_LAST_BIT - 1);
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ if (test_all_bits(slave_exec_mode_options,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
sql_print_error("Ambiguous slave modes combination."
" STRICT will be used");
- bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT);
+ slave_exec_mode_options&= ~(ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT);
}
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ if (!(slave_exec_mode_options & (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT)))
+ slave_exec_mode_options|= (ULL(1)<< SLAVE_EXEC_MODE_STRICT);
DBUG_VOID_RETURN;
}
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sp_head.cc 2010-04-01 09:04:26 +0000
@@ -2089,6 +2089,8 @@ sp_head::reset_lex(THD *thd)
sublex->dec= NULL;
sublex->interval_list.empty();
sublex->type= 0;
+ sublex->uint_geom_type= 0;
+ sublex->vcol_info= 0;
DBUG_RETURN(FALSE);
}
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-03-31 18:37:45 +0000
+++ b/sql/sql_acl.cc 2010-04-02 20:08:40 +0000
@@ -536,6 +536,9 @@ static my_bool acl_load(THD *thd, TABLE_
while (!(read_record_info.read_record(&read_record_info)))
{
ACL_USER user;
+ char *password;
+ uint password_len;
+
bzero(&user, sizeof(user));
update_hostname(&user.host, get_field(&mem, table->field[0]));
user.user= get_field(&mem, table->field[1]);
@@ -548,8 +551,8 @@ static my_bool acl_load(THD *thd, TABLE_
continue;
}
- char *password= get_field(thd->mem_root, table->field[2]);
- uint password_len= password ? strlen(password) : 0;
+ password= get_field(&mem, table->field[2]);
+ password_len= password ? strlen(password) : 0;
user.auth_string.str= password ? password : const_cast<char*>("");
user.auth_string.length= password_len;
set_user_salt(&user, password, password_len);
@@ -6846,6 +6849,7 @@ bool check_routine_level_acl(THD *thd, c
#define initialized 0
#define decrease_user_connections(X) /* nothing */
#define check_for_max_user_connections(X,Y) 0
+#define get_or_create_user_conn(A,B,C,D) 0
#endif
#endif
#ifndef HAVE_OPENSSL
@@ -7826,15 +7830,15 @@ static int do_auth_once(THD *thd, LEX_ST
bool unlock_plugin= false;
plugin_ref plugin;
+#ifdef EMBEDDED_LIBRARY
+ plugin= native_password_plugin;
+#else
if (auth_plugin_name->str == native_password_plugin_name.str)
plugin= native_password_plugin;
- else
-#ifndef EMBEDDED_LIBRARY
- if (auth_plugin_name->str == old_password_plugin_name.str)
+ else if (auth_plugin_name->str == old_password_plugin_name.str)
plugin= old_password_plugin;
- else
- if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
- MYSQL_AUTHENTICATION_PLUGIN)))
+ else if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
+ MYSQL_AUTHENTICATION_PLUGIN)))
unlock_plugin= true;
#endif
@@ -8257,3 +8261,35 @@ mysql_declare_plugin(mysql_password)
}
mysql_declare_plugin_end;
+maria_declare_plugin(mysql_password)
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &native_password_handler, /* type descriptor */
+ native_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Native MySQL authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* String version */
+ MariaDB_PLUGIN_MATURITY_BETA /* Maturity */
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &old_password_handler, /* type descriptor */
+ old_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Old MySQL-4.0 authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* String version */
+ MariaDB_PLUGIN_MATURITY_BETA /* Maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/sql_builtin.cc.in'
--- a/sql/sql_builtin.cc.in 2010-03-29 15:13:53 +0000
+++ b/sql/sql_builtin.cc.in 2010-04-01 14:34:51 +0000
@@ -16,13 +16,12 @@
#include <my_global.h>
#include <mysql/plugin.h>
-typedef struct st_mysql_plugin builtin_plugin[];
+typedef struct st_maria_plugin builtin_maria_plugin[];
-extern builtin_plugin
- builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@;
+extern builtin_maria_plugin
+ builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@;
-struct st_mysql_plugin *mysqld_builtins[]=
+struct st_maria_plugin *mariadb_builtins[]=
{
- builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
+ builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@,(struct st_maria_plugin *)0
};
-
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_class.cc 2010-04-02 18:51:02 +0000
@@ -924,7 +924,7 @@ void THD::update_stats(void)
/* A SQL query. */
if (lex->sql_command == SQLCOM_SELECT)
select_commands++;
- else if (! sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
+ else if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
{
/* Ignore 'SHOW ' commands */
}
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-29 15:13:53 +0000
+++ b/sql/sql_class.h 2010-04-01 09:04:26 +0000
@@ -63,6 +63,7 @@ public:
bool report_error(THD *thd);
bool is_invalidated() const { return m_invalidated; }
void reset_reprepare_observer() { m_invalidated= FALSE; }
+ Reprepare_observer() {} /* Remove gcc warning */
private:
bool m_invalidated;
};
@@ -1117,6 +1118,7 @@ public:
/* Ignore error */
return TRUE;
}
+ Dummy_error_handler() {} /* Remove gcc warning */
};
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_plugin.cc 2010-04-01 20:05:09 +0000
@@ -20,7 +20,7 @@
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
-extern struct st_mysql_plugin *mysqld_builtins[];
+extern struct st_maria_plugin *mariadb_builtins[];
/**
@note The order of the enumeration is critical.
@@ -78,6 +78,14 @@ static const char *sizeof_st_plugin_sym=
"_mysql_sizeof_struct_st_plugin_";
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
static int min_plugin_interface_version= MYSQL_PLUGIN_INTERFACE_VERSION & ~0xFF;
+static const char *maria_plugin_interface_version_sym=
+ "_maria_plugin_interface_version_";
+static const char *maria_sizeof_st_plugin_sym=
+ "_maria_sizeof_struct_st_plugin_";
+static const char *maria_plugin_declarations_sym=
+ "_maria_plugin_declarations_";
+static int min_maria_plugin_interface_version=
+ MARIA_PLUGIN_INTERFACE_VERSION & ~0xFF;
#endif
/* Note that 'int version' must be the first field of every plugin
@@ -211,7 +219,7 @@ static bool plugin_load_list(MEM_ROOT *t
const char *list);
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
int *, char **);
-static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *,
+static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *,
struct st_plugin_int **);
static void unlock_variables(THD *thd, struct system_variables *vars);
static void cleanup_variables(THD *thd, struct system_variables *vars);
@@ -368,6 +376,225 @@ static inline void free_plugin_mem(struc
}
+/**
+ Reads data from mysql plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report What errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+#ifdef HAVE_DLOPEN
+static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+ /* Determine interface version */
+ if (!sym)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= 0;
+ plugin_dl->mysqlversion= *(int *)sym;
+ /* Versioning */
+ if (plugin_dl->mysqlversion < min_plugin_interface_version ||
+ (plugin_dl->mysqlversion >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ /* convert mysql declaration to maria one */
+ {
+ int i;
+ uint sizeof_st_plugin;
+ struct st_mysql_plugin *old;
+ struct st_maria_plugin *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ DBUG_ASSERT(min_plugin_interface_version == 0);
+ sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
+ }
+
+ for (i= 0;
+ ((struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc((i + 1) * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old= (struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ {
+
+ cur->type= old->type;
+ cur->info= old->info;
+ cur->name= old->name;
+ cur->author= old->author;
+ cur->descr= old->descr;
+ cur->license= old->license;
+ cur->init= old->init;
+ cur->deinit= old->deinit;
+ cur->version= old->version;
+ cur->status_vars= old->status_vars;
+ cur->system_vars= old->system_vars;
+ /*
+ Something like this should be added to process
+ new mysql plugin versions:
+ if (plugin_dl->mysqlversion > 0x0101)
+ {
+ cur->newfield= CONSTANT_MEANS_UNKNOWN;
+ }
+ else
+ {
+ cur->newfield= old->newfield;
+ }
+ */
+ /* Maria only fields */
+ cur->version_info= "Unknown";
+ cur->maturity= MariaDB_PLUGIN_MATURITY_UNKNOWN;
+ }
+ plugin_dl->allocated= true;
+ plugin_dl->plugins= (struct st_maria_plugin *)cur;
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Reads data from maria plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report what errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+
+ /* Determine interface version */
+ if (!(sym))
+ {
+ /*
+ Actually this branch impossible because in case of absence of maria
+ version we try mysql version.
+ */
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY,
+ maria_plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= *(int *)sym;
+ plugin_dl->mysqlversion= 0;
+ /* Versioning */
+ if (plugin_dl->mariaversion < min_maria_plugin_interface_version ||
+ (plugin_dl->mariaversion >> 8) > (MARIA_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, maria_plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, maria_plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+ if (plugin_dl->mariaversion != MARIA_PLUGIN_INTERFACE_VERSION)
+ {
+ uint sizeof_st_plugin;
+ struct st_maria_plugin *old, *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, maria_sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, maria_sizeof_st_plugin_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ if (sizeof_st_plugin != sizeof(st_mysql_plugin))
+ {
+ int i;
+ for (i= 0;
+ ((struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc((i + 1) * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old= (struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ memcpy(cur + i, old, min(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ plugin_dl->allocated= true;
+ }
+ }
+ plugin_dl->plugins= (struct st_maria_plugin *)sym;
+
+ DBUG_RETURN(FALSE);
+}
+#endif HAVE_DLOPEN
+
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
#ifdef HAVE_DLOPEN
@@ -415,22 +642,21 @@ static st_plugin_dl *plugin_dl_add(const
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg);
DBUG_RETURN(0);
}
- /* Determine interface version */
- if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
+
+ /* Checks which plugin interface present and reads info */
+ if (!(sym= dlsym(plugin_dl.handle, maria_plugin_interface_version_sym)))
{
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
- DBUG_RETURN(0);
+ if (read_mysql_plugin_info(&plugin_dl,
+ dlsym(plugin_dl.handle,
+ plugin_interface_version_sym),
+ dlpath,
+ report))
+ DBUG_RETURN(0);
}
- plugin_dl.version= *(int *)sym;
- /* Versioning */
- if (plugin_dl.version < min_plugin_interface_version ||
- (plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
+ else
{
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
- "plugin interface version mismatch");
- DBUG_RETURN(0);
+ if (read_maria_plugin_info(&plugin_dl, sym, dlpath, report))
+ DBUG_RETURN(0);
}
/* link the services in */
@@ -438,7 +664,7 @@ static st_plugin_dl *plugin_dl_add(const
{
if ((sym= dlsym(plugin_dl.handle, list_of_services[i].name)))
{
- uint ver= (uint)(intptr)*(void**)sym;
+ uint ver= (uint)(intptr) *(void **)sym;
if (ver > list_of_services[i].version ||
(ver >> 8) < (list_of_services[i].version >> 8))
{
@@ -449,72 +675,9 @@ static st_plugin_dl *plugin_dl_add(const
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, buf);
DBUG_RETURN(0);
}
- *(void**)sym= list_of_services[i].service;
- }
- }
-
- /* Find plugin declarations */
- if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
- {
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym);
- DBUG_RETURN(0);
- }
-
- if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
- {
- uint sizeof_st_plugin;
- struct st_mysql_plugin *old, *cur;
- char *ptr= (char *)sym;
-
- if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym)))
- sizeof_st_plugin= *(int *)sym;
- else
- {
-#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, sizeof_st_plugin_sym);
- DBUG_RETURN(0);
-#else
- /*
- When the following assert starts failing, we'll have to switch
- to the upper branch of the #ifdef
- */
- DBUG_ASSERT(min_plugin_interface_version == 0);
- sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
-#endif
- }
-
- if (sizeof_st_plugin != sizeof(st_mysql_plugin))
- {
- for (i= 0;
- ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- /* no op */;
-
- cur= (struct st_mysql_plugin*)
- my_malloc((i+1)*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
- if (!cur)
- {
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
- DBUG_RETURN(0);
- }
- /*
- All st_plugin fields not initialized in the plugin explicitly, are
- set to 0. It matches C standard behaviour for struct initializers that
- have less values than the struct definition.
- */
- for (i=0;
- (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
-
- sym= cur;
- plugin_dl.allocated= true;
+ *(void **)sym= list_of_services[i].service;
}
}
- plugin_dl.plugins= (struct st_mysql_plugin *)sym;
/* Duplicate and convert dll name */
plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1;
@@ -756,7 +919,7 @@ static bool plugin_add(MEM_ROOT *tmp_roo
int *argc, char **argv, int report)
{
struct st_plugin_int tmp;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
DBUG_ENTER("plugin_add");
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
{
@@ -1161,8 +1324,8 @@ int plugin_init(int *argc, char **argv,
{
uint i;
bool is_myisam;
- struct st_mysql_plugin **builtins;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin **builtins;
+ struct st_maria_plugin *plugin;
struct st_plugin_int tmp, *plugin_ptr, **reap;
MEM_ROOT tmp_root;
bool reaped_mandatory_plugin= FALSE;
@@ -1201,7 +1364,7 @@ int plugin_init(int *argc, char **argv,
/*
First we register builtin plugins
*/
- for (builtins= mysqld_builtins; *builtins; builtins++)
+ for (builtins= mariadb_builtins; *builtins; builtins++)
{
for (plugin= *builtins; plugin->info; plugin++)
{
@@ -1316,7 +1479,7 @@ err:
}
-static bool register_builtin(struct st_mysql_plugin *plugin,
+static bool register_builtin(struct st_maria_plugin *plugin,
struct st_plugin_int *tmp,
struct st_plugin_int **ptr)
{
@@ -1352,7 +1515,7 @@ static bool register_builtin(struct st_m
RETURN
false - plugin registered successfully
*/
-bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
+bool plugin_register_builtin(THD *thd, struct st_maria_plugin *plugin)
{
struct st_plugin_int tmp, *ptr;
bool result= true;
@@ -1481,7 +1644,7 @@ static bool plugin_load_list(MEM_ROOT *t
char buffer[FN_REFLEN];
LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
struct st_plugin_dl *plugin_dl;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
char *p= buffer;
DBUG_ENTER("plugin_load_list");
while (list)
=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_plugin.h 2010-04-01 14:34:51 +0000
@@ -52,8 +52,9 @@ struct st_plugin_dl
{
LEX_STRING dl;
void *handle;
- struct st_mysql_plugin *plugins;
- int version;
+ struct st_maria_plugin *plugins;
+ int mysqlversion;
+ int mariaversion;
bool allocated;
uint ref_count; /* number of plugins loaded from the library */
};
@@ -63,7 +64,7 @@ struct st_plugin_dl
struct st_plugin_int
{
LEX_STRING name;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
struct st_plugin_dl *plugin_dl;
uint state;
uint ref_count; /* number of threads using the plugin */
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-04-01 21:42:40 +0000
+++ b/sql/sql_show.cc 2010-04-03 20:19:35 +0000
@@ -94,11 +94,21 @@ static int make_version_string(char *buf
return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
}
+
+static const LEX_STRING maturity_name[]={
+ { C_STRING_WITH_LEN("Unknown") },
+ { C_STRING_WITH_LEN("Experimental") },
+ { C_STRING_WITH_LEN("Alpha") },
+ { C_STRING_WITH_LEN("Beta") },
+ { C_STRING_WITH_LEN("Gamma") },
+ { C_STRING_WITH_LEN("Stable") }};
+
+
static my_bool show_plugins(THD *thd, plugin_ref plugin,
void *arg)
{
TABLE *table= (TABLE*) arg;
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
CHARSET_INFO *cs= system_charset_info;
char version_buf[20];
@@ -143,7 +153,7 @@ static my_bool show_plugins(THD *thd, pl
table->field[5]->set_notnull();
table->field[6]->store(version_buf,
make_version_string(version_buf, sizeof(version_buf),
- plugin_dl->version),
+ plugin_dl->mariaversion),
cs);
table->field[6]->set_notnull();
}
@@ -186,6 +196,26 @@ static my_bool show_plugins(THD *thd, pl
}
table->field[9]->set_notnull();
+ if ((uint) plug->maturity <= MariaDB_PLUGIN_MATURITY_STABLE)
+ table->field[10]->store(maturity_name[plug->maturity].str,
+ maturity_name[plug->maturity].length,
+ cs);
+ else
+ {
+ DBUG_ASSERT(0);
+ table->field[10]->store("Unknown", 7, cs);
+ }
+ table->field[10]->set_notnull();
+
+ if (plug->version_info)
+ {
+ table->field[11]->store(plug->version_info,
+ strlen(plug->version_info), cs);
+ table->field[11]->set_notnull();
+ }
+ else
+ table->field[11]->set_null();
+
return schema_table_store_record(thd, table);
}
@@ -2527,8 +2557,8 @@ int send_user_stats(THD* thd, HASH *all_
table->field[j++]->store(user_stats->user, user_stats->user_name_length,
system_charset_info);
table->field[j++]->store((longlong)user_stats->total_connections,TRUE);
- table->field[j++]->store((longlong)user_stats->concurrent_connections);
- table->field[j++]->store((longlong)user_stats->connected_time);
+ table->field[j++]->store((longlong)user_stats->concurrent_connections, TRUE);
+ table->field[j++]->store((longlong)user_stats->connected_time, TRUE);
table->field[j++]->store((double)user_stats->busy_time);
table->field[j++]->store((double)user_stats->cpu_time);
table->field[j++]->store((longlong)user_stats->bytes_received, TRUE);
@@ -4426,7 +4456,7 @@ static my_bool iter_schema_engines(THD *
if (plugin_state(plugin) != PLUGIN_IS_READY)
{
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
if (!(wild && wild[0] &&
wild_case_compare(scs, plug->name,wild)))
{
@@ -7207,6 +7237,8 @@ ST_FIELD_INFO plugin_fields_info[]=
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
+ {"PLUGIN_MATURITY", 12, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+ {"PLUGIN_AUTH_VERSION", 80, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_table.cc 2010-04-01 09:04:26 +0000
@@ -5704,6 +5704,10 @@ compare_tables(TABLE *table,
*/
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
uint db_options= 0; /* not used */
+
+ /* Set default value for return value (to ensure it's always set) */
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+
/* Create the prepared information. */
if (mysql_prepare_create_table(thd, create_info,
&tmp_alter_info,
@@ -5762,7 +5766,6 @@ compare_tables(TABLE *table,
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
{
DBUG_PRINT("info", ("Basic checks -> ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5792,7 +5795,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("NULL behaviour difference in field '%s' -> "
"ALTER_TABLE_DATA_CHANGED", new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5828,7 +5830,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED",
new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
// Clear indexed marker
@@ -5963,7 +5964,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("check_if_incompatible_data() -> "
"ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_view.cc 2010-03-30 12:36:49 +0000
@@ -1034,10 +1034,12 @@ bool mysql_make_view(THD *thd, File_pars
bool parse_status;
bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables);
-
DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
+ LINT_INIT(parse_status);
+ LINT_INIT(view_select);
+
if (table->view)
{
/*
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-03-29 15:13:53 +0000
+++ b/sql/sql_yacc.yy 2010-04-01 09:04:26 +0000
@@ -2342,6 +2342,7 @@ sp_init_param:
lex->interval_list.empty();
lex->uint_geom_type= 0;
+ lex->vcol_info= 0;
}
;
@@ -8190,7 +8191,7 @@ function_call_generic:
builder= find_qualified_function_builder(thd);
DBUG_ASSERT(builder);
- item= builder->create(thd, $1, $3, true, $5);
+ item= builder->create_with_db(thd, $1, $3, true, $5);
if (! ($$= item))
{
=== modified file 'storage/archive/ha_archive.cc'
--- a/storage/archive/ha_archive.cc 2010-03-04 08:03:07 +0000
+++ b/storage/archive/ha_archive.cc 2010-04-01 14:34:51 +0000
@@ -1655,4 +1655,21 @@ mysql_declare_plugin(archive)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(archive)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &archive_storage_engine,
+ "ARCHIVE",
+ "Brian Aker, MySQL AB",
+ "Archive storage engine",
+ PLUGIN_LICENSE_GPL,
+ archive_db_init, /* Plugin Init */
+ archive_db_done, /* Plugin Deinit */
+ 0x0300 /* 3.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/blackhole/ha_blackhole.cc'
--- a/storage/blackhole/ha_blackhole.cc 2009-10-16 10:29:42 +0000
+++ b/storage/blackhole/ha_blackhole.cc 2010-04-01 14:34:51 +0000
@@ -369,3 +369,20 @@ mysql_declare_plugin(blackhole)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(blackhole)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &blackhole_storage_engine,
+ "BLACKHOLE",
+ "MySQL AB",
+ "/dev/null storage engine (anything you write to it disappears)",
+ PLUGIN_LICENSE_GPL,
+ blackhole_init, /* Plugin Init */
+ blackhole_fini, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/csv/ha_tina.cc'
--- a/storage/csv/ha_tina.cc 2009-12-03 11:19:05 +0000
+++ b/storage/csv/ha_tina.cc 2010-04-01 14:34:51 +0000
@@ -1636,4 +1636,20 @@ mysql_declare_plugin(csv)
NULL /* config options */
}
mysql_declare_plugin_end;
-
+maria_declare_plugin(csv)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &csv_storage_engine,
+ "CSV",
+ "Brian Aker, MySQL AB",
+ "CSV storage engine",
+ PLUGIN_LICENSE_GPL,
+ tina_init_func, /* Plugin Init */
+ tina_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/example/ha_example.cc'
--- a/storage/example/ha_example.cc 2010-03-03 14:44:14 +0000
+++ b/storage/example/ha_example.cc 2010-04-01 14:34:51 +0000
@@ -924,3 +924,20 @@ mysql_declare_plugin(example)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(example)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &example_storage_engine,
+ "EXAMPLE",
+ "Brian Aker, MySQL AB",
+ "Example storage engine",
+ PLUGIN_LICENSE_GPL,
+ example_init_func, /* Plugin Init */
+ example_done_func, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ func_status, /* status variables */
+ example_system_variables, /* system variables */
+ "0.1", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/example/ha_example.h'
--- a/storage/example/ha_example.h 2007-08-13 13:11:25 +0000
+++ b/storage/example/ha_example.h 2010-03-28 18:10:00 +0000
@@ -155,7 +155,8 @@ public:
/** @brief
This method will never be called if you do not implement indexes.
*/
- virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
+ virtual double read_time(uint index, uint ranges, ha_rows rows)
+ { return (double) rows / 20.0+1; }
/*
Everything below are methods that we implement in ha_example.cc.
=== modified file 'storage/federated/ha_federated.cc'
--- a/storage/federated/ha_federated.cc 2009-09-07 20:50:10 +0000
+++ b/storage/federated/ha_federated.cc 2010-04-01 14:34:51 +0000
@@ -3379,3 +3379,20 @@ mysql_declare_plugin(federated)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federated_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith and Brian Aker, MySQL AB",
+ "Federated MySQL storage engine",
+ PLUGIN_LICENSE_GPL,
+ federated_db_init, /* Plugin Init */
+ federated_done, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/federatedx/ha_federatedx.cc'
--- a/storage/federatedx/ha_federatedx.cc 2010-03-10 10:32:14 +0000
+++ b/storage/federatedx/ha_federatedx.cc 2010-04-01 14:34:51 +0000
@@ -3505,9 +3505,26 @@ mysql_declare_plugin(federated)
PLUGIN_LICENSE_GPL,
federatedx_db_init, /* Plugin Init */
federatedx_done, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
+ 0x0200 /* 2.0 */,
NULL, /* status variables */
NULL, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federatedx_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith",
+ "FederatedX pluggable storage engine",
+ PLUGIN_LICENSE_GPL,
+ federatedx_db_init, /* Plugin Init */
+ federatedx_done, /* Plugin Deinit */
+ 0x0200 /* 2.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "2.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/heap/ha_heap.cc'
--- a/storage/heap/ha_heap.cc 2009-09-07 20:50:10 +0000
+++ b/storage/heap/ha_heap.cc 2010-04-01 14:34:51 +0000
@@ -767,3 +767,20 @@ mysql_declare_plugin(heap)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(heap)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &heap_storage_engine,
+ "MEMORY",
+ "MySQL AB",
+ "Hash based, stored in memory, useful for temporary tables",
+ PLUGIN_LICENSE_GPL,
+ heap_init,
+ NULL,
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/ibmdb2i/ha_ibmdb2i.cc'
--- a/storage/ibmdb2i/ha_ibmdb2i.cc 2009-12-11 07:01:16 +0000
+++ b/storage/ibmdb2i/ha_ibmdb2i.cc 2010-04-01 14:34:51 +0000
@@ -3357,3 +3357,20 @@ mysql_declare_plugin(ibmdb2i)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ibmdb2i)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ibmdb2i_storage_engine,
+ "IBMDB2I",
+ "The IBM development team in Rochester, Minnesota",
+ "IBM DB2 for i Storage Engine",
+ PLUGIN_LICENSE_GPL,
+ ibmdb2i_init_func, /* Plugin Init */
+ ibmdb2i_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ ibmdb2i_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_UNKNOWN /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc 2010-03-15 11:51:23 +0000
+++ b/storage/innobase/handler/ha_innodb.cc 2010-04-01 14:34:51 +0000
@@ -8930,6 +8930,23 @@ mysql_declare_plugin(innobase)
NULL /* reserved */
}
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase OY",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ innodb_status_variables_export, /* status variables */
+ innobase_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE, /* maturity */
+}
+maria_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/innodb_plugin/handler/i_s.cc'
--- a/storage/innodb_plugin/handler/i_s.cc 2009-10-12 12:00:56 +0000
+++ b/storage/innodb_plugin/handler/i_s.cc 2010-04-01 14:34:51 +0000
@@ -455,6 +455,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -730,6 +783,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -913,6 +1019,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
@@ -1245,6 +1404,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1295,6 +1507,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -1511,6 +1777,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1561,6 +1880,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc 2010-03-15 11:51:23 +0000
+++ b/storage/maria/ha_maria.cc 2010-04-01 14:34:51 +0000
@@ -3471,9 +3471,26 @@ mysql_declare_plugin(maria)
PLUGIN_LICENSE_GPL,
ha_maria_init, /* Plugin Init */
NULL, /* Plugin Deinit */
- 0x0100, /* 1.0 */
+ 0x0105, /* 1.5 */
status_variables, /* status variables */
system_variables, /* system variables */
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(maria)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &maria_storage_engine,
+ "MARIA",
+ "MySQL AB",
+ "Crash-safe tables with MyISAM heritage",
+ PLUGIN_LICENSE_GPL,
+ ha_maria_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0105, /* 1.5 */
+ status_variables, /* status variables */
+ system_variables, /* system variables */
+ "1.5", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2010-03-30 12:35:15 +0000
+++ b/storage/maria/ma_loghandler.c 2010-04-02 09:20:09 +0000
@@ -1275,7 +1275,10 @@ static my_bool translog_set_lsn_for_file
{
LOGHANDLER_FILE_INFO info;
File fd= open_logfile_by_number_no_cache(file);
+
LINT_INIT_STRUCT(info);
+ LINT_INIT(info.max_lsn);
+
if ((fd < 0) ||
((translog_read_file_header(&info, fd) ||
(cmp_translog_addr(lsn, info.max_lsn) > 0 &&
@@ -3968,6 +3971,7 @@ my_bool translog_init_with_table(const c
{
LOGHANDLER_FILE_INFO info;
LINT_INIT_STRUCT(info);
+
/*
Accessing &log_descriptor.open_files without mutex is safe
because it is initialization
=== modified file 'storage/maria/ma_search.c'
--- a/storage/maria/ma_search.c 2010-03-15 11:51:23 +0000
+++ b/storage/maria/ma_search.c 2010-04-01 09:04:26 +0000
@@ -76,8 +76,8 @@ int _ma_search(register MARIA_HA *info,
bmove512(info->keyread_buff, page_buff, info->s->block_size);
/* Save position for a possible read next / previous */
- info->int_keypos= info->keyread_buff + (ulonglong) info->int_keypos;
- info->int_maxpos= info->keyread_buff + (ulonglong) info->int_maxpos;
+ info->int_keypos= info->keyread_buff + info->keypos_offset;
+ info->int_maxpos= info->keyread_buff + info->maxpos_offset;
info->int_keytree_version= key->keyinfo->version;
info->last_search_keypage= info->last_keypage;
info->page_changed= 0;
@@ -214,8 +214,8 @@ static int _ma_search_no_save(register M
info->cur_row.trid= _ma_trid_from_key(&info->last_key);
/* Store offset to key */
- info->int_keypos= (uchar*) (keypos - page.buff);
- info->int_maxpos= (uchar*) (maxpos - page.buff);
+ info->keypos_offset= (uint) (keypos - page.buff);
+ info->maxpos_offset= (uint) (maxpos - page.buff);
info->int_nod_flag= nod_flag;
info->last_keypage= pos;
*res_page_link= page_link;
=== modified file 'storage/maria/maria_def.h'
--- a/storage/maria/maria_def.h 2010-03-09 19:22:24 +0000
+++ b/storage/maria/maria_def.h 2010-03-28 18:10:00 +0000
@@ -506,8 +506,10 @@ struct st_maria_handler
uchar *first_mbr_key; /* Searhed spatial key */
uchar *rec_buff; /* Temp buffer for recordpack */
uchar *blob_buff; /* Temp buffer for blobs */
- uchar *int_keypos, /* Save position for next/previous */
- *int_maxpos; /* -""- */
+ uchar *int_keypos; /* Save position for next/previous */
+ uchar *int_maxpos; /* -""- */
+ uint keypos_offset; /* Tmp storage for offset int_keypos */
+ uint maxpos_offset; /* Tmp storage for offset int_maxpos */
uchar *update_field_data; /* Used by update in rows-in-block */
uint int_nod_flag; /* -""- */
uint32 int_keytree_version; /* -""- */
=== modified file 'storage/myisam/ft_stopwords.c'
--- a/storage/myisam/ft_stopwords.c 2010-03-10 10:32:14 +0000
+++ b/storage/myisam/ft_stopwords.c 2010-03-28 18:10:00 +0000
@@ -44,9 +44,10 @@ static void FT_STOPWORD_free(FT_STOPWORD
static int ft_add_stopword(const char *w)
{
FT_STOPWORD sw;
- return !w ||
- (((sw.len= (uint) strlen(sw.pos=(const uchar *)w)) >= ft_min_word_len) &&
- (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL));
+ return (!w ||
+ (((sw.len= (uint) strlen((char*) (sw.pos=(const uchar *)w))) >=
+ ft_min_word_len) &&
+ (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL)));
}
int ft_init_stopwords()
=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc 2010-01-04 17:54:42 +0000
+++ b/storage/myisam/ha_myisam.cc 2010-04-01 14:34:51 +0000
@@ -2174,6 +2174,23 @@ mysql_declare_plugin(myisam)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisam)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisam_storage_engine,
+ "MyISAM",
+ "MySQL AB",
+ "Default engine as of MySQL 3.23 with great performance",
+ PLUGIN_LICENSE_GPL,
+ myisam_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#ifdef HAVE_QUERY_CACHE
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2010-03-04 08:03:07 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-04-01 14:34:51 +0000
@@ -382,7 +382,7 @@ static MI_INFO *myisammrg_attach_childre
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
}
DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d",
- my_errno ? NULL : (long) myisam, my_errno));
+ my_errno ? 0L : (long) myisam, my_errno));
err:
DBUG_RETURN(my_errno ? NULL : myisam);
@@ -1289,3 +1289,20 @@ mysql_declare_plugin(myisammrg)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisammrg)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisammrg_storage_engine,
+ "MRG_MYISAM",
+ "MySQL AB",
+ "Collection of identical MyISAM tables",
+ PLUGIN_LICENSE_GPL,
+ myisammrg_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/myisammrg/myrg_open.c'
--- a/storage/myisammrg/myrg_open.c 2009-09-23 13:21:29 +0000
+++ b/storage/myisammrg/myrg_open.c 2010-03-30 12:36:49 +0000
@@ -239,6 +239,7 @@ MYRG_INFO *myrg_parent_open(const char *
rc= 1;
errpos= 0;
bzero((char*) &file_cache, sizeof(file_cache));
+ LINT_INIT(m_info);
/* Open MERGE meta file. */
if ((fd= my_open(fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT,
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- a/storage/pbxt/src/ha_pbxt.cc 2010-03-31 18:37:45 +0000
+++ b/storage/pbxt/src/ha_pbxt.cc 2010-04-01 14:34:51 +0000
@@ -5919,6 +5919,40 @@ mysql_declare_plugin(pbxt)
drizzle_declare_plugin_end;
#else
mysql_declare_plugin_end;
+#ifdef MARIADB_BASE_VERSION
+maria_declare_plugin(pbxt)
+{ /* PBXT */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &pbxt_storage_engine,
+ "PBXT",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "High performance, multi-versioning transactional engine",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init, /* Plugin Init */
+ pbxt_end, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ NULL, /* status variables */
+ pbxt_system_variables, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+},
+{ /* PBXT_STATISTICS */
+ MYSQL_INFORMATION_SCHEMA_PLUGIN,
+ &pbxt_statitics,
+ "PBXT_STATISTICS",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "PBXT internal system statitics",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init_statistics, /* plugin init */
+ pbxt_exit_statistics, /* plugin deinit */
+ 0x0005,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
+#endif
#endif
#if defined(XT_WIN) && defined(XT_COREDUMP)
=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- a/storage/xtradb/handler/ha_innodb.cc 2010-02-01 06:14:12 +0000
+++ b/storage/xtradb/handler/ha_innodb.cc 2010-04-01 14:34:51 +0000
@@ -10818,6 +10818,39 @@ i_s_innodb_index_stats,
i_s_innodb_admin_command,
i_s_innodb_patches
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{ /* InnoDB */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase Oy",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ INNODB_VERSION_SHORT,
+ innodb_status_variables_export,/* status variables */
+ innobase_system_variables, /* system variables */
+ INNODB_VERSION_STR, /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+},
+i_s_innodb_rseg_maria,
+i_s_innodb_buffer_pool_pages_maria,
+i_s_innodb_buffer_pool_pages_index_maria,
+i_s_innodb_buffer_pool_pages_blob_maria,
+i_s_innodb_trx_maria,
+i_s_innodb_locks_maria,
+i_s_innodb_lock_waits_maria,
+i_s_innodb_cmp_maria,
+i_s_innodb_cmp_reset_maria,
+i_s_innodb_cmpmem_maria,
+i_s_innodb_cmpmem_reset_maria,
+i_s_innodb_table_stats_maria,
+i_s_innodb_index_stats_maria,
+i_s_innodb_admin_command_maria,
+i_s_innodb_patches_maria
+maria_declare_plugin_end;
+
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/xtradb/handler/i_s.cc'
--- a/storage/xtradb/handler/i_s.cc 2010-01-28 11:35:10 +0000
+++ b/storage/xtradb/handler/i_s.cc 2010-04-01 14:34:51 +0000
@@ -393,6 +393,59 @@ UNIV_INTERN struct st_mysql_plugin
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_patches_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "XTRADB_ENHANCEMENTS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Percona"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Enhancements applied to InnoDB plugin"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_patches_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_fields_info[] =
{
@@ -1040,6 +1093,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1089,6 +1195,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool index pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1138,6 +1297,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool blob pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
static ST_FIELD_INFO innodb_trx_fields_info[] =
@@ -1373,6 +1585,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -1648,6 +1914,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -1831,6 +2150,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
@@ -2163,6 +2535,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2213,6 +2638,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -2431,6 +2909,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2481,6 +3012,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
@@ -2660,6 +3245,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_rseg_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_RSEG"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB rollback segment information"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_rseg_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_table_stats_info[] =
@@ -2940,6 +3578,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_table_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_TABLE_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB table statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_table_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats =
{
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
@@ -2956,6 +3611,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_index_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_INDEX_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB index statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_index_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_admin_command_info[] =
@@ -2988,7 +3660,6 @@ i_s_innodb_admin_command_fill(
COND* cond)
{
TABLE* i_s_table = (TABLE *) tables->table;
- CHARSET_INFO *cs= system_charset_info;
char** query_str;
char* ptr;
char quote = '\0';
@@ -3122,3 +3793,20 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_admin_command_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "XtraDB specific command acceptor"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_admin_command_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
=== modified file 'storage/xtradb/handler/i_s.h'
--- a/storage/xtradb/handler/i_s.h 2009-11-04 20:11:12 +0000
+++ b/storage/xtradb/handler/i_s.h 2010-04-01 14:34:51 +0000
@@ -42,4 +42,20 @@ extern struct st_mysql_plugin i_s_innodb
extern struct st_mysql_plugin i_s_innodb_index_stats;
extern struct st_mysql_plugin i_s_innodb_admin_command;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria;
+extern struct st_maria_plugin i_s_innodb_trx_maria;
+extern struct st_maria_plugin i_s_innodb_locks_maria;
+extern struct st_maria_plugin i_s_innodb_lock_waits_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_reset_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_reset_maria;
+extern struct st_maria_plugin i_s_innodb_patches_maria;
+extern struct st_maria_plugin i_s_innodb_rseg_maria;
+extern struct st_maria_plugin i_s_innodb_table_stats_maria;
+extern struct st_maria_plugin i_s_innodb_index_stats_maria;
+extern struct st_maria_plugin i_s_innodb_admin_command_maria;
+
#endif /* i_s_h */
=== modified file 'storage/xtradb/include/page0page.h'
--- a/storage/xtradb/include/page0page.h 2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/page0page.h 2010-03-28 18:10:00 +0000
@@ -517,7 +517,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec); /*!< in: pointer to record */
+ const rec_t* rec); /*!< in: pointer to record */
/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
=== modified file 'storage/xtradb/include/page0page.ic'
--- a/storage/xtradb/include/page0page.ic 2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/page0page.ic 2010-03-28 18:10:00 +0000
@@ -731,7 +731,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec) /*!< in: pointer to record */
+ const rec_t* rec) /*!< in: pointer to record */
{
return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
}
=== modified file 'storage/xtradb/include/ut0lst.h'
--- a/storage/xtradb/include/ut0lst.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0lst.h 2010-03-30 12:36:49 +0000
@@ -158,7 +158,7 @@ Inserts a NODE2 after NODE1 in a list.
/** Invalidate the pointers in a list node.
@param NAME list name
@param N pointer to the node that was removed */
-# define UT_LIST_REMOVE_CLEAR(NAME, N) while (0)
+# define UT_LIST_REMOVE_CLEAR(NAME, N) {} while (0)
#endif
/*******************************************************************//**
=== modified file 'storage/xtradb/log/log0recv.c'
--- a/storage/xtradb/log/log0recv.c 2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/log/log0recv.c 2010-03-31 20:50:54 +0000
@@ -3280,7 +3280,6 @@ recv_recovery_from_checkpoint_finish(voi
#endif /* UNIV_DEBUG */
if (recv_needed_recovery && srv_recovery_stats) {
- FILE* file = stderr;
ulint i;
fprintf(stderr,
=== modified file 'strings/ctype-ucs2.c'
--- a/strings/ctype-ucs2.c 2010-03-15 11:51:23 +0000
+++ b/strings/ctype-ucs2.c 2010-04-01 09:04:26 +0000
@@ -203,7 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@@ -317,7 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_I
const char *s, const char *t, size_t len)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const char *se=s+len;
const char *te=t+len;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@@ -1384,7 +1384,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
=== modified file 'strings/ctype-utf8.c'
--- a/strings/ctype-utf8.c 2010-01-06 19:20:16 +0000
+++ b/strings/ctype-utf8.c 2010-04-01 09:04:26 +0000
@@ -2308,7 +2308,7 @@ static int my_strnncoll_utf8(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc), t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@@ -2378,7 +2378,7 @@ static int my_strnncollsp_utf8(CHARSET_I
my_bool diff_if_only_endspace_difference)
{
int s_res, t_res, res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se= s+slen, *te= t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
=== modified file 'strings/my_vsnprintf.c'
--- a/strings/my_vsnprintf.c 2010-03-03 14:44:14 +0000
+++ b/strings/my_vsnprintf.c 2010-04-01 09:04:26 +0000
@@ -400,16 +400,18 @@ start:
case 's':
{
char *par= args_arr[print_arr[i].arg_idx].str_arg;
- width= (print_arr[i].flags & WIDTH_ARG) ?
- args_arr[print_arr[i].width].longlong_arg : print_arr[i].width;
+ width= ((print_arr[i].flags & WIDTH_ARG) ?
+ (uint) args_arr[print_arr[i].width].longlong_arg :
+ (uint) print_arr[i].width);
to= process_str_arg(cs, to, end, width, par, print_arr[i].flags);
break;
}
case 'b':
{
char *par = args_arr[print_arr[i].arg_idx].str_arg;
- width= (print_arr[i].flags & WIDTH_ARG) ?
- args_arr[print_arr[i].width].longlong_arg : print_arr[i].width;
+ width= ((print_arr[i].flags & WIDTH_ARG) ?
+ (uint) args_arr[print_arr[i].width].longlong_arg :
+ (uint) print_arr[i].width);
to= process_bin_arg(to, end, width, par);
break;
}
@@ -428,8 +430,9 @@ start:
{
/* Integer parameter */
longlong larg;
- length= (print_arr[i].flags & LENGTH_ARG) ?
- args_arr[print_arr[i].length].longlong_arg : print_arr[i].length;
+ length= ((print_arr[i].flags & LENGTH_ARG) ?
+ args_arr[print_arr[i].length].longlong_arg :
+ (longlong) print_arr[i].length);
if (args_arr[print_arr[i].arg_idx].have_longlong)
larg = args_arr[print_arr[i].arg_idx].longlong_arg;
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-03-10 10:32:14 +0000
+++ b/support-files/compiler_warnings.supp 2010-04-01 09:40:11 +0000
@@ -27,7 +27,7 @@ pars0grm.tab.c: .*'yyerrorlab' : unrefer
_flex_tmp.c: .*not enough actual parameters for macro 'yywrap'.*
pars0lex.l: .*conversion from 'ulint' to 'int', possible loss of data.*
btr/btr0cur\.c: .*value computed is not used.*: 3175-3375
-include/buf0buf\.ic: unused parameter ‘mtr’
+include/buf0buf\.ic: unused parameter .*mtr.*
fil/fil0fil\.c: pointer targets in passing argument.*differ in signedness
fil/fil0fil\.c: comparison between signed and unsigned : 3100-3199
fil/fil0fil\.c: unused parameter
@@ -39,6 +39,7 @@ sync/sync0rw\.c: unused parameter
sync/sync0sync\.c: unused parameter
sync/sync0sync\.c: unused variable
ut/ut0ut\.c: ignoring return value of
+srv/srv0srv\.c: value computed is not used
#
# bdb is not critical to keep up to date
@@ -53,6 +54,12 @@ db_vrfy.c : .*comparison is always false
# readline is not maintained by us
#
.*/cmd-line-utils/readline/.* : .*
+readline\.c : unused parameter
+term\.c : unused parameter
+vi\.c : unused parameter
+common\.c : unused parameter
+term\.c : .*
+
#
# Ignore some warnings in libevent, which is not maintained by us.
@@ -66,6 +73,16 @@ db_vrfy.c : .*comparison is always false
/usr/share/aclocal/audiofile.m4 : .*
#
+# Ignore strict-aliasing warnings (for now)
+#
+.*: break strict-aliasing rules
+
+#
+# Ignore not important declaration warnings
+#
+.*: only defines private constructors and has no friends
+
+#
# Ignore all conversion warnings on windows 64
# (Is safe as we are not yet supporting strings >= 2G)
#
@@ -100,6 +117,11 @@ db_vrfy.c : .*comparison is always false
storage/maria/ma_pagecache.c: .*'info_check_pin' defined but not used
#
+# Pbxt
+#
+xaction_xt\.cc: may be used uninitialized in this function
+
+#
# I think these are due to mix of C and C++.
#
storage/pbxt/ : typedef.*was ignored in this declaration
@@ -112,6 +134,7 @@ include/runtime.hpp: .*pure_error.*
.*/extra/yassl/taocrypt/src/blowfish\.cpp: array subscript is above array bounds
.*/extra/yassl/taocrypt/src/file\.cpp: ignoring return value
.*/extra/yassl/taocrypt/src/integer\.cpp: control reaches end of non-void function
+mySTL/algorithm\.hpp: is used uninitialized in this function
#
# Groff warnings on OpenSUSE.
@@ -123,18 +146,18 @@ include/runtime.hpp: .*pure_error.*
#
listener.cc : .*conversion from 'SOCKET' to 'int'.*
net_serv.cc : .*conversion from 'SOCKET' to 'int'.*
-set_var.cc: right-hand operand of comma has no effect : 1000-1400
-
# allow a little moving space for the warning below
-mi_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
-ma_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
+mi_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
+ma_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
#
# Wrong compiler warnings
#
.* : .*no matching operator delete found; memory will not be freed if initialization throws an exception.*
-ctype-simple.c : .*unary minus operator applied to unsigned type, result still unsigned.*
+ctype-simple\.c : .*unary minus operator applied to unsigned type, result still unsigned.*
# Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478
-regexec\.c : .*passing argument 3 of.*matcher.* discards qualifiers from pointer target type.*
+regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type
+libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000
+storage/xtradb/dict/dict0dict\.c : passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
=== modified file 'unittest/mysys/waiting_threads-t.c'
--- a/unittest/mysys/waiting_threads-t.c 2010-01-28 14:49:14 +0000
+++ b/unittest/mysys/waiting_threads-t.c 2010-03-30 12:36:49 +0000
@@ -258,7 +258,7 @@ void do_tests()
#define test_kill_strategy(X) \
diag("kill strategy: " #X); \
DBUG_EXECUTE("reset_file", \
- { rewind(DBUG_FILE); (void) ftruncate(fileno(DBUG_FILE), 0); }); \
+ { rewind(DBUG_FILE); my_chsize(fileno(DBUG_FILE), 0, 0, MYF(MY_WME)); }); \
DBUG_PRINT("info", ("kill strategy: " #X)); \
kill_strategy=X; \
do_one_test();
1
0
Regarding comment from colincharles here:
http://www.bytebot.net/blog/archives/2010/04/02/mariadb-5-1-44-released
I am assuming that by 'resources' needed for creeating win32 builds, you
mean a buildbot slave.
I have an Athlon XP box under my desk, which used to be my primary
machine, but right now is being used mostly for backups, so most of the
time it does nothing but gathers dust. I could probably set it up with
another hard disk, install Windows XP/Vista on it and donate it for
MariaDB builds. It depends on a few factors though.
1. How autoamted is the process? Ideally all I would like to do is to
switch the power on, login and let the machine do its job with as little
interaction from my side as possible.
2. How often and for how long would it need to run? I can run it for
8-10 hours several times a week, but certainly not 24/7
3. How much upload/download bandwidth is required? While my download
bandwidth is pretty good, my upload is not. Still, as long as we are not
talking several tens of gigabytes per day, I should manage.
Also please take into consideration, that I've never done anything like
this before, so I might require a lot of help setting this up.
Please tell me what you think! ;)
Mchl
--
This message was sent from Launchpad by the user
Mchl (https://launchpad.net/~mchlpl)
using the "Contact this team" link on the Maria Discuss
team page to each member directly.
For more information see
https://help.launchpad.net/YourAccount/ContactingPeople
1
0

[Maria-developers] FYI Current stable subquery optimizations pushed to lp:~maria-captains/maria/5.3
by Sergey Petrunya 03 Apr '10
by Sergey Petrunya 03 Apr '10
03 Apr '10
Hello,
As requested, I've pushed the latest 'stable'(*) version of subquery optimizations
into lp:~maria-captains/maria/5.3.
(*) - stable here means:
= there are no subquery-optimizations related failures in buildbot
= there are no known "new" subquery issues (there are still some subquery
code issues that were inherited from buildbot, though).
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
1
0

[Maria-developers] Rev 2771: embedded builds used to refer to undefined functions inside if(0) { } in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 02 Apr '10
by serg@askmonty.org 02 Apr '10
02 Apr '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2771
revision-id: sergii(a)pisem.net-20100402200840-0nctbdvalpetkkzp
parent: sergii(a)pisem.net-20100402185102-3jj9hj51tfjblsyu
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: 5.2
timestamp: Fri 2010-04-02 22:08:40 +0200
message:
embedded builds used to refer to undefined functions inside if(0) { }
gcc optimized this dead code away, and does not notice that functions
were undefined. Other compilers are more picky
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-04-01 14:34:51 +0000
+++ b/sql/sql_acl.cc 2010-04-02 20:08:40 +0000
@@ -6849,6 +6849,7 @@ bool check_routine_level_acl(THD *thd, c
#define initialized 0
#define decrease_user_connections(X) /* nothing */
#define check_for_max_user_connections(X,Y) 0
+#define get_or_create_user_conn(A,B,C,D) 0
#endif
#endif
#ifndef HAVE_OPENSSL
1
0

[Maria-developers] Rev 2770: more fixes for windows and status_user.test in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 02 Apr '10
by serg@askmonty.org 02 Apr '10
02 Apr '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2770
revision-id: sergii(a)pisem.net-20100402185102-3jj9hj51tfjblsyu
parent: sergii(a)pisem.net-20100402092009-fsk3s46z6furxi1k
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: 5.2
timestamp: Fri 2010-04-02 20:51:02 +0200
message:
more fixes for windows and status_user.test
=== modified file 'libmysqld/CMakeLists.txt'
--- a/libmysqld/CMakeLists.txt 2010-01-31 09:13:21 +0000
+++ b/libmysqld/CMakeLists.txt 2010-04-02 18:51:02 +0000
@@ -104,7 +104,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libm
../sql-common/client.c ../sql-common/my_time.c
../sql-common/my_user.c ../sql-common/pack.c
../sql/password.c ../sql/discover.cc ../sql/derror.cc
- ../sql/field.cc ../sql/field_conv.cc
+ ../sql/field.cc ../sql/field_conv.cc ../sql-common/client_plugin.c
../sql/filesort.cc ../sql/gstream.cc ../sql/ha_partition.cc
../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc
../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc
=== modified file 'mysql-test/r/status_user.result'
--- a/mysql-test/r/status_user.result 2010-03-21 20:58:19 +0000
+++ b/mysql-test/r/status_user.result 2010-04-02 18:51:02 +0000
@@ -137,7 +137,7 @@ ROWS_INSERTED 8
ROWS_UPDATED 5
SELECT_COMMANDS 3
UPDATE_COMMANDS 11
-OTHER_COMMANDS 9
+OTHER_COMMANDS 7
COMMIT_TRANSACTIONS 19
ROLLBACK_TRANSACTIONS 2
DENIED_CONNECTIONS 0
@@ -154,7 +154,7 @@ ROWS_INSERTED 8
ROWS_UPDATED 5
SELECT_COMMANDS 3
UPDATE_COMMANDS 11
-OTHER_COMMANDS 9
+OTHER_COMMANDS 7
COMMIT_TRANSACTIONS 19
ROLLBACK_TRANSACTIONS 2
DENIED_CONNECTIONS 0
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-04-02 09:20:09 +0000
+++ b/sql/sql_class.cc 2010-04-02 18:51:02 +0000
@@ -924,7 +924,7 @@ void THD::update_stats(void)
/* A SQL query. */
if (lex->sql_command == SQLCOM_SELECT)
select_commands++;
- else if (! (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND))
+ else if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
{
/* Ignore 'SHOW ' commands */
}
1
0

[Maria-developers] bzr commit into file:///home/tsk/mprog/src/5.3-subqueries/ branch (timour:2788)
by timour@askmonty.org 02 Apr '10
by timour@askmonty.org 02 Apr '10
02 Apr '10
#At file:///home/tsk/mprog/src/5.3-subqueries/ based on revid:psergey@askmonty.org-20100329200940-9ikx6gpww0gtsx00
2788 timour(a)askmonty.org 2010-04-02
MWL#68: Subquery optimization: Efficient NOT IN execution with NULLs
Fixed an error where the priority queue for the indexes used for partial
matching was not emptied after each execution in all cases.
modified:
sql/item_subselect.cc
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2010-03-29 14:04:35 +0000
+++ b/sql/item_subselect.cc 2010-04-02 14:27:06 +0000
@@ -3882,8 +3882,9 @@ subselect_hash_sj_engine::make_unique_en
cur_ref_buff + test(maybe_null), we could
use that information instead.
*/
+
cur_ref_buff + null_count,
- null_count ? tab->ref.key_buff : 0,
+ null_count ? cur_ref_buff : 0,
cur_key_part->length, tab->ref.items[i]);
cur_ref_buff+= cur_key_part->store_length;
}
@@ -4908,6 +4909,8 @@ bool subselect_rowid_merge_engine::parti
/* If there is a non-NULL key, it must be the first key in the keys array. */
DBUG_ASSERT(!non_null_key || (non_null_key && merge_keys[0] == non_null_key));
+ /* The prioryty queue for keys must be empty. */
+ DBUG_ASSERT(!pq.elements);
/* All data accesses during execution are via handler::ha_rnd_pos() */
tmp_table->file->ha_rnd_init(0);
@@ -5031,6 +5034,7 @@ bool subselect_rowid_merge_engine::parti
DBUG_ASSERT(FALSE);
end:
+ queue_remove_all(&pq);
tmp_table->file->ha_rnd_end();
return res;
}
1
0

[Maria-developers] Rev 2769: fixes for windows builds in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 02 Apr '10
by serg@askmonty.org 02 Apr '10
02 Apr '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2769
revision-id: sergii(a)pisem.net-20100402092009-fsk3s46z6furxi1k
parent: sanja(a)askmonty.org-20100402100339-oxwd8hcrstv3gs1o
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: 5.2
timestamp: Fri 2010-04-02 11:20:09 +0200
message:
fixes for windows builds
=== modified file 'CMakeLists.txt'
--- a/CMakeLists.txt 2010-04-01 14:34:51 +0000
+++ b/CMakeLists.txt 2010-04-02 09:20:09 +0000
@@ -38,6 +38,7 @@ ADD_DEFINITIONS(-DMYSQL_DATADIR="c:/Prog
ADD_DEFINITIONS(-DDEFAULT_CHARSET_HOME="c:/Program Files/MySQL/MySQL Server ${MYSQL_BASE_VERSION}/")
ADD_DEFINITIONS(-DPACKAGE=mysql)
ADD_DEFINITIONS(-DSHAREDIR="share")
+ADD_DEFINITIONS(-DPLUGINDIR="lib/plugin")
# Set debug options
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFORCE_INIT_OF_VARS")
=== modified file 'extra/libevent/evbuffer.c'
--- a/extra/libevent/evbuffer.c 2010-02-01 06:14:12 +0000
+++ b/extra/libevent/evbuffer.c 2010-04-02 09:20:09 +0000
@@ -75,8 +75,7 @@ bufferevent_add(struct event *ev, int ti
*/
void
-bufferevent_read_pressure_cb(struct evbuffer *buf,
- size_t old __attribute__((unused)), size_t now,
+bufferevent_read_pressure_cb(struct evbuffer *buf, size_t old, size_t now,
void *arg) {
struct bufferevent *bufev = arg;
/*
=== modified file 'extra/libevent/event.c'
--- a/extra/libevent/event.c 2010-01-06 19:20:16 +0000
+++ b/extra/libevent/event.c 2010-04-02 09:20:09 +0000
@@ -394,8 +394,7 @@ event_base_get_method(struct event_base
}
static void
-event_loopexit_cb(int fd __attribute__((unused)),
- short what __attribute__((unused)), void *arg)
+event_loopexit_cb(int fd, short what, void *arg)
{
struct event_base *base = arg;
base->event_gotterm = 1;
=== modified file 'extra/libevent/signal.c'
--- a/extra/libevent/signal.c 2010-01-06 19:20:16 +0000
+++ b/extra/libevent/signal.c 2010-04-02 09:20:09 +0000
@@ -69,7 +69,7 @@ static void evsignal_handler(int sig);
/* Callback for when the signal handler write a byte to our signaling socket */
static void
-evsignal_cb(int fd, short what __attribute((unused)), void *arg __attribute((unused)))
+evsignal_cb(int fd, short what, void *arg)
{
static char signals[100];
#ifdef WIN32
=== modified file 'include/m_ctype.h'
--- a/include/m_ctype.h 2010-03-31 18:37:45 +0000
+++ b/include/m_ctype.h 2010-04-02 09:20:09 +0000
@@ -311,7 +311,9 @@ struct charset_info_st
#define ILLEGAL_CHARSET_INFO_NUMBER (~0U)
extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_bin;
-extern struct charset_info_st my_charset_bin;
+extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_latin1;
+extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_filename;
+
extern struct charset_info_st my_charset_big5_chinese_ci;
extern struct charset_info_st my_charset_big5_bin;
extern struct charset_info_st my_charset_cp932_japanese_ci;
@@ -324,7 +326,6 @@ extern struct charset_info_st my_charset
extern struct charset_info_st my_charset_gb2312_bin;
extern struct charset_info_st my_charset_gbk_chinese_ci;
extern struct charset_info_st my_charset_gbk_bin;
-extern struct charset_info_st my_charset_latin1;
extern struct charset_info_st my_charset_latin1_german2_ci;
extern struct charset_info_st my_charset_latin1_bin;
extern struct charset_info_st my_charset_latin2_czech_ci;
@@ -341,7 +342,6 @@ extern struct charset_info_st my_charset
extern struct charset_info_st my_charset_utf8_unicode_ci;
extern struct charset_info_st my_charset_utf8_bin;
extern struct charset_info_st my_charset_cp1250_czech_ci;
-extern struct charset_info_st my_charset_filename;
/* declarations for simple charsets */
extern size_t my_strnxfrm_simple(CHARSET_INFO *, uchar *, size_t,
=== modified file 'include/my_global.h'
--- a/include/my_global.h 2010-03-29 15:13:53 +0000
+++ b/include/my_global.h 2010-04-02 09:20:09 +0000
@@ -1522,6 +1522,9 @@ do { doubleget_union _tmp; \
#elif defined(HAVE_DLFCN_H)
#include <dlfcn.h>
#endif
+#ifndef HAVE_DLERROR
+#define dlerror() ""
+#endif
#endif
/* FreeBSD 2.2.2 does not define RTLD_NOW) */
@@ -1529,7 +1532,7 @@ do { doubleget_union _tmp; \
#define RTLD_NOW 1
#endif
-#ifndef HAVE_DLERROR
+#ifndef HAVE_DLOPEN
#define dlerror() "No support for dynamic loading (static build?)"
#define dlopen(A,B) 0
#define dlsym(A,B) 0
=== modified file 'server-tools/CMakeLists.txt'
--- a/server-tools/CMakeLists.txt 2007-02-14 11:42:11 +0000
+++ b/server-tools/CMakeLists.txt 2010-04-02 09:20:09 +0000
@@ -27,7 +27,7 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc co
user_management_commands.cc
../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
- ../../libmysql/errmsg.c)
+ ../../libmysql/errmsg.c ../../sql-common/client_plugin.c)
ADD_DEPENDENCIES(mysqlmanager GenError)
TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32)
=== modified file 'server-tools/instance-manager/CMakeLists.txt'
--- a/server-tools/instance-manager/CMakeLists.txt 2007-12-27 17:16:02 +0000
+++ b/server-tools/instance-manager/CMakeLists.txt 2010-04-02 09:20:09 +0000
@@ -28,7 +28,7 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc co
user_management_commands.cc ../../mysys/my_rnd.c
../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
- ../../libmysql/errmsg.c)
+ ../../libmysql/errmsg.c ../../sql-common/client_plugin.c)
ADD_DEPENDENCIES(mysqlmanager GenError)
TARGET_LINK_LIBRARIES(mysqlmanager debug dbug mysys strings taocrypt vio yassl zlib wsock32)
=== modified file 'sql-common/client.c'
--- a/sql-common/client.c 2010-04-01 09:04:26 +0000
+++ b/sql-common/client.c 2010-04-02 09:20:09 +0000
@@ -2345,7 +2345,7 @@ void mpvio_info(Vio *vio, MYSQL_PLUGIN_V
case VIO_TYPE_SSL:
{
struct sockaddr addr;
- socklen_t addrlen= sizeof(addr);
+ SOCKET_SIZE_TYPE addrlen= sizeof(addr);
if (getsockname(vio->sd, &addr, &addrlen))
return;
info->protocol= addr.sa_family == AF_UNIX ?
@@ -2360,7 +2360,7 @@ void mpvio_info(Vio *vio, MYSQL_PLUGIN_V
return;
case VIO_TYPE_SHARED_MEMORY:
info->protocol= MYSQL_VIO_MEMORY;
- info->handle= vio->handle_client_file_map; /* or what ? */
+ info->handle= vio->handle_file_map; /* or what ? */
return;
#endif
default: DBUG_ASSERT(0);
=== modified file 'sql/client_settings.h'
--- a/sql/client_settings.h 2010-03-29 15:13:53 +0000
+++ b/sql/client_settings.h 2010-04-02 09:20:09 +0000
@@ -29,7 +29,6 @@
#define mysql_master_send_query(A, B, C) 1
#define mysql_slave_send_query(A, B, C) 1
#define mysql_rpl_probe(mysql) 0
-#undef HAVE_SMEM
#undef _CUSTOMCONFIG_
#define mysql_server_init(a,b,c) mysql_client_plugin_init()
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2010-03-15 11:51:23 +0000
+++ b/sql/log_event.cc 2010-04-02 09:20:09 +0000
@@ -1716,8 +1716,7 @@ beg:
case MYSQL_TYPE_DATETIME:
{
- size_t d, t;
- uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
+ uint64 d, t, i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
d= i64 / 1000000;
t= i64 % 1000000;
my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-04-01 09:04:26 +0000
+++ b/sql/mysqld.cc 2010-04-02 09:20:09 +0000
@@ -6645,8 +6645,6 @@ Can't be set to 1 if --log-slave-updates
{"shared-memory", OPT_ENABLE_SHARED_MEMORY,
"Enable the shared memory.",(uchar**) &opt_enable_shared_memory, (uchar**) &opt_enable_shared_memory,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
-#ifdef HAVE_SMEM
{"shared-memory-base-name",OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_class.cc 2010-04-02 09:20:09 +0000
@@ -924,7 +924,7 @@ void THD::update_stats(void)
/* A SQL query. */
if (lex->sql_command == SQLCOM_SELECT)
select_commands++;
- else if (! sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
+ else if (! (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND))
{
/* Ignore 'SHOW ' commands */
}
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-04-01 14:34:51 +0000
+++ b/sql/sql_show.cc 2010-04-02 09:20:09 +0000
@@ -2529,8 +2529,8 @@ int send_user_stats(THD* thd, HASH *all_
table->field[j++]->store(user_stats->user, user_stats->user_name_length,
system_charset_info);
table->field[j++]->store((longlong)user_stats->total_connections,TRUE);
- table->field[j++]->store((longlong)user_stats->concurrent_connections);
- table->field[j++]->store((longlong)user_stats->connected_time);
+ table->field[j++]->store((longlong)user_stats->concurrent_connections, TRUE);
+ table->field[j++]->store((longlong)user_stats->connected_time, TRUE);
table->field[j++]->store((double)user_stats->busy_time);
table->field[j++]->store((double)user_stats->cpu_time);
table->field[j++]->store((longlong)user_stats->bytes_received, TRUE);
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2010-04-01 09:04:26 +0000
+++ b/storage/maria/ma_loghandler.c 2010-04-02 09:20:09 +0000
@@ -1274,10 +1274,11 @@ static my_bool translog_set_lsn_for_file
for (file= from_file; file <= to_file; file++)
{
LOGHANDLER_FILE_INFO info;
- LINT_INIT(info.max_lsn);
-
File fd= open_logfile_by_number_no_cache(file);
+
LINT_INIT_STRUCT(info);
+ LINT_INIT(info.max_lsn);
+
if ((fd < 0) ||
((translog_read_file_header(&info, fd) ||
(cmp_translog_addr(lsn, info.max_lsn) > 0 &&
1
0

[Maria-developers] Rev 2768: Fixed the test according to the new plugin information in file:///Users/bell/maria/bzr/work-maria-5.2-plugin/
by sanja@askmonty.org 02 Apr '10
by sanja@askmonty.org 02 Apr '10
02 Apr '10
At file:///Users/bell/maria/bzr/work-maria-5.2-plugin/
------------------------------------------------------------
revno: 2768
revision-id: sanja(a)askmonty.org-20100402100339-oxwd8hcrstv3gs1o
parent: sanja(a)askmonty.org-20100401200509-o67qhkcgzv5s9oai
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-plugin
timestamp: Fri 2010-04-02 13:03:39 +0300
message:
Fixed the test according to the new plugin information
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_is.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result 2010-02-01 06:14:12 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result 2010-04-02 10:03:39 +0000
@@ -271,10 +271,12 @@ NULL information_schema PBXT_STATISTICS
NULL information_schema PBXT_STATISTICS Name 2 NO varchar 40 120 NULL NULL utf8 utf8_general_ci varchar(40) select
NULL information_schema PBXT_STATISTICS Value 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(8) select
NULL information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PLUGINS PLUGIN_AUTH_VERSION 12 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
NULL information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
NULL information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select
NULL information_schema PLUGINS PLUGIN_LICENSE 10 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
+NULL information_schema PLUGINS PLUGIN_MATURITY 11 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
NULL information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select
NULL information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
@@ -791,6 +793,8 @@ NULL information_schema PBXT_STATISTICS
3.0000 information_schema PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64)
1.0000 information_schema PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext
3.0000 information_schema PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80)
+3.0000 information_schema PLUGINS PLUGIN_MATURITY varchar 12 36 utf8 utf8_general_ci varchar(12)
+3.0000 information_schema PLUGINS PLUGIN_AUTH_VERSION varchar 80 240 utf8 utf8_general_ci varchar(80)
NULL information_schema PROCESSLIST ID bigint NULL NULL NULL NULL bigint(4)
3.0000 information_schema PROCESSLIST USER varchar 16 48 utf8 utf8_general_ci varchar(16)
3.0000 information_schema PROCESSLIST HOST varchar 64 192 utf8 utf8_general_ci varchar(64)
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2747)
by Igor Babaev 02 Apr '10
by Igor Babaev 02 Apr '10
02 Apr '10
#At lp:maria/5.2 based on revid:igor@askmonty.org-20100331233728-obczp1ecrffnaa2s
2747 Igor Babaev 2010-04-01
Post-review fixes.
modified:
include/keycache.h
mysql-test/r/key_cache.result
mysql-test/t/key_cache.test
mysys/mf_keycache.c
sql/sql_show.cc
=== modified file 'include/keycache.h'
--- a/include/keycache.h 2010-02-16 16:41:11 +0000
+++ b/include/keycache.h 2010-04-01 21:42:40 +0000
@@ -37,7 +37,6 @@ C_MODE_START
#define MAX_KEY_CACHE_PARTITIONS 64
-
/* The structure to get statistical data about a key cache */
typedef struct st_key_cache_statistics
@@ -53,6 +52,8 @@ typedef struct st_key_cache_statistics
ulonglong writes; /* number of actual writes from buffers into files */
} KEY_CACHE_STATISTICS;
+#define NO_LONG_KEY_CACHE_STAT_VARIABLES 3
+
/* The type of a key cache object */
typedef enum key_cache_type
{
@@ -61,6 +62,55 @@ typedef enum key_cache_type
} KEY_CACHE_TYPE;
+typedef
+ int (*INIT_KEY_CACHE)
+ (void *, uint key_cache_block_size,
+ size_t use_mem, uint division_limit, uint age_threshold);
+typedef
+ int (*RESIZE_KEY_CACHE)
+ (void *, uint key_cache_block_size,
+ size_t use_mem, uint division_limit, uint age_threshold);
+typedef
+ void (*CHANGE_KEY_CACHE_PARAM)
+ (void *keycache_cb,
+ uint division_limit, uint age_threshold);
+typedef
+ uchar* (*KEY_CACHE_READ)
+ (void *keycache_cb,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length, int return_buffer);
+typedef
+ int (*KEY_CACHE_INSERT)
+ (void *keycache_cb,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length);
+typedef
+ int (*KEY_CACHE_WRITE)
+ (void *keycache_cb,
+ File file, void *file_extra,
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length, int force_write);
+typedef
+ int (*FLUSH_KEY_BLOCKS)
+ (void *keycache_cb,
+ int file, void *file_extra,
+ enum flush_type type);
+typedef
+ int (*RESET_KEY_CACHE_COUNTERS)
+ (const char *name, void *keycache_cb);
+typedef
+ void (*END_KEY_CACHE)
+ (void *keycache_cb, my_bool cleanup);
+typedef
+ void (*GET_KEY_CACHE_STATISTICS)
+ (void *keycache_cb, uint partition_no,
+ KEY_CACHE_STATISTICS *key_cache_stats);
+typedef
+ ulonglong (*GET_KEY_CACHE_STAT_VALUE)
+ (void *keycache_cb, uint var_no);
+
/*
An object of the type KEY_CACHE_FUNCS contains pointers to all functions
from the key cache interface.
@@ -74,32 +124,17 @@ typedef enum key_cache_type
typedef struct st_key_cache_funcs
{
- int (*init) (void *, uint key_cache_block_size,
- size_t use_mem, uint division_limit, uint age_threshold);
- int (*resize) (void *, uint key_cache_block_size,
- size_t use_mem, uint division_limit, uint age_threshold);
- void (*change_param) (void *keycache_cb,
- uint division_limit, uint age_threshold);
- uchar* (*read) (void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length, int return_buffer);
- int (*insert) (void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length);
- int (*write) (void *keycache_cb,
- File file, void *file_extra,
- my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length, int force_write);
- int (*flush) (void *keycache_cb,
- int file, void *file_extra,
- enum flush_type type);
- int (*reset_counters) (const char *name, void *keycache_cb);
- void (*end) (void *keycache_cb, my_bool cleanup);
- void (*get_stats) (void *keycache_cb, uint partition_no,
- KEY_CACHE_STATISTICS *key_cache_stats);
- ulonglong (*get_stat_val) (void *keycache_cb, uint var_no);
+ INIT_KEY_CACHE init;
+ RESIZE_KEY_CACHE resize;
+ CHANGE_KEY_CACHE_PARAM change_param;
+ KEY_CACHE_READ read;
+ KEY_CACHE_INSERT insert;
+ KEY_CACHE_WRITE write;
+ FLUSH_KEY_BLOCKS flush;
+ RESET_KEY_CACHE_COUNTERS reset_counters;
+ END_KEY_CACHE end;
+ GET_KEY_CACHE_STATISTICS get_stats;
+ GET_KEY_CACHE_STAT_VALUE get_stat_val;
} KEY_CACHE_FUNCS;
=== modified file 'mysql-test/r/key_cache.result'
--- a/mysql-test/r/key_cache.result 2010-03-31 23:37:28 +0000
+++ b/mysql-test/r/key_cache.result 2010-04-01 21:42:40 +0000
@@ -672,12 +672,12 @@ insert into t2 values (2000, 3, 'yyyy');
select * from information_schema.key_caches where key_cache_name like "keycache2"
and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache2 NULL NULL 1048576 1024 0 # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3
select * from information_schema.key_caches where key_cache_name like "key%"
and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19
-keycache2 NULL NULL 1048576 1024 0 # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3
cache index t2 in keycache1;
Table Op Msg_type Msg_text
test.t2 assign_to_keycache status OK
@@ -718,7 +718,7 @@ KEY_CACHE_NAME PARTITIONS PARTITION_NUMB
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 3201 43 1594 30
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=2*1024;
insert into t2 values (7000, 3, 'yyyy');
select * from information_schema.key_caches where partition_number is null;
@@ -726,66 +726,72 @@ KEY_CACHE_NAME PARTITIONS PARTITION_NUMB
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 6 6 3 3
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=8*1024;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 3 NULL 262143 8192 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
insert into t2 values (8000, 3, 'yyyy');
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 3 NULL 262143 8192 # # 0 6 5 3 3
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_buffer_size=64*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=2*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 3 NULL 65535 2048 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=8*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_buffer_size=0;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=8*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_buffer_size=0;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_buffer_size=128*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 1 NULL 131072 8192 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 7 NULL 131068 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
drop table t1,t2;
set global keycache1.key_buffer_size=0;
set global keycache2.key_buffer_size=0;
=== modified file 'mysql-test/t/key_cache.test'
--- a/mysql-test/t/key_cache.test 2010-03-31 23:37:28 +0000
+++ b/mysql-test/t/key_cache.test 2010-04-01 21:42:40 +0000
@@ -469,6 +469,8 @@ insert into t2 values (7000, 3, 'yyyy');
select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=8*1024;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
insert into t2 values (8000, 3, 'yyyy');
--replace_column 6 # 7 #
select * from information_schema.key_caches where partition_number is null;
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2010-02-16 16:41:11 +0000
+++ b/mysys/mf_keycache.c 2010-04-01 21:42:40 +0000
@@ -49,6 +49,7 @@
One cache can handle many files.
It must contain buffers of the same blocksize.
+
init_key_cache() should be used to init cache handler.
The free list (free_block_list) is a stack like structure.
@@ -151,7 +152,7 @@ typedef struct st_keycache_wqueue
/* Control block for a simple (non-partitioned) key cache */
-typedef struct st_s_key_cache_cb
+typedef struct st_simple_key_cache_cb
{
my_bool key_cache_inited; /* <=> control block is allocated */
my_bool in_resize; /* true during resize operation */
@@ -202,7 +203,7 @@ typedef struct st_s_key_cache_cb
int blocks; /* max number of blocks in the cache */
uint hash_factor; /* factor used to calculate hash function */
my_bool in_init; /* Set to 1 in MySQL during init/resize */
-} S_KEY_CACHE_CB;
+} SIMPLE_KEY_CACHE_CB;
/*
Some compilation flags have been added specifically for this module
@@ -314,12 +315,8 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cac
#define FLUSH_CACHE 2000 /* sort this many blocks at once */
-static int flush_all_key_blocks(S_KEY_CACHE_CB *keycache);
-/*
-static void s_change_key_cache_param(void *keycache_cb, uint division_limit,
- uint age_threshold);
-*/
-static void s_end_key_cache(void *keycache_cb, my_bool cleanup);
+static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache);
+static void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup);
#ifdef THREAD
static void wait_on_queue(KEYCACHE_WQUEUE *wqueue,
pthread_mutex_t *mutex);
@@ -328,9 +325,9 @@ static void release_whole_queue(KEYCACHE
#define wait_on_queue(wqueue, mutex) do {} while (0)
#define release_whole_queue(wqueue) do {} while (0)
#endif
-static void free_block(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block);
+static void free_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block);
#if !defined(DBUG_OFF)
-static void test_key_cache(S_KEY_CACHE_CB *keycache,
+static void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
const char *where, my_bool lock);
#endif
#define KEYCACHE_BASE_EXPR(f, pos) \
@@ -433,7 +430,7 @@ static int keycache_pthread_cond_signal(
#define inline /* disabled inline for easier debugging */
static int fail_block(BLOCK_LINK *block);
static int fail_hlink(HASH_LINK *hlink);
-static int cache_empty(S_KEY_CACHE_CB *keycache);
+static int cache_empty(SIMPLE_KEY_CACHE_CB *keycache);
#endif
@@ -447,8 +444,8 @@ static inline uint next_power(uint value
Initialize a simple key cache
SYNOPSIS
- s_init_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ init_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
key_cache_block_size size of blocks to keep cached data
use_mem memory to use for the key cache buferrs/structures
division_limit division limit (may be zero)
@@ -458,8 +455,8 @@ static inline uint next_power(uint value
This function is the implementation of the init_key_cache interface
function that is employed by simple (non-partitioned) key caches.
The function builds a simple key cache and initializes the control block
- structure of the type S_KEY_CACHE_CB that is used for this key cache.
- The parameter keycache_cb is supposed to point to this structure.
+ structure of the type SIMPLE_KEY_CACHE_CB that is used for this key cache.
+ The parameter keycache is supposed to point to this structure.
The parameter key_cache_block_size specifies the size of the blocks in
the key cache to be built. The parameters division_limit and age_threshhold
determine the initial values of those characteristics of the key cache
@@ -478,19 +475,17 @@ static inline uint next_power(uint value
It's assumed that no two threads call this function simultaneously
referring to the same key cache handle.
-
*/
static
-int s_init_key_cache(void *keycache_cb, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
ulong blocks, hash_links;
size_t length;
int error;
- DBUG_ENTER("init_key_cache");
+ DBUG_ENTER("init_simple_key_cache");
DBUG_ASSERT(key_cache_block_size >= 512);
KEYCACHE_DEBUG_OPEN;
@@ -653,16 +648,16 @@ err:
Prepare for resizing a simple key cache
SYNOPSIS
- s_prepare_resize_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ prepare_resize_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
with_resize_queue <=> resize queue is used
release_lock <=> release the key cache lock before return
DESCRIPTION
This function flushes all dirty pages from a simple key cache and after
- this it destroys the key cache calling s_end_key_cache. The function
- considers the parameter keycache_cb as a pointer to the control block
- structure of the type S_KEY_CACHE_CB for this key cache.
+ this it destroys the key cache calling end_simple_key_cache. The function
+ takes the parameter keycache as a pointer to the control block
+ structure of the type SIMPLE_KEY_CACHE_CB for this key cache.
The parameter with_resize_queue determines weather the resize queue is
involved (MySQL server never uses this queue). The parameter release_lock
says weather the key cache lock must be released before return from
@@ -673,19 +668,18 @@ err:
1 - otherwise.
NOTES
- This function is the called by s_resize_key_cache and p_resize_key_cache
- that resize simple and partitioned key caches respectively.
-
+ This function is the called by resize_simple_key_cache and
+ resize_partitioned_key_cache that resize simple and partitioned key caches
+ respectively.
*/
static
-int s_prepare_resize_key_cache(void *keycache_cb,
- my_bool with_resize_queue,
- my_bool release_lock)
+int prepare_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
+ my_bool with_resize_queue,
+ my_bool release_lock)
{
int res= 0;
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_prepare_resize_key_cache");
+ DBUG_ENTER("prepare_resize_simple_key_cache");
keycache_pthread_mutex_lock(&keycache->cache_lock);
@@ -749,7 +743,7 @@ int s_prepare_resize_key_cache(void *key
KEYCACHE_DBUG_ASSERT(keycache->cnt_for_resize_op == 0);
#endif
- s_end_key_cache(keycache_cb, 0);
+ end_simple_key_cache(keycache, 0);
finish:
if (release_lock)
@@ -762,16 +756,16 @@ finish:
Finalize resizing a simple key cache
SYNOPSIS
- s_finish_resize_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ finish_resize_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
with_resize_queue <=> resize queue is used
acquire_lock <=> acquire the key cache lock at start
DESCRIPTION
This function performs finalizing actions for the operation of
- resizing a simple key cache. The function considers the parameter
- keycache_cb as a pointer to the control block structure of the type
- S_KEY_CACHE_CB for this key cache. The function sets the flag
+ resizing a simple key cache. The function takes the parameter
+ keycache as a pointer to the control block structure of the type
+ SIMPLE_KEY_CACHE_CB for this key cache. The function sets the flag
in_resize in this structure to FALSE.
The parameter with_resize_queue determines weather the resize queue
is involved (MySQL server never uses this queue).
@@ -782,22 +776,23 @@ finish:
none
NOTES
- This function is the called by s_resize_key_cache and p_resize_key_cache
- that resize simple and partitioned key caches respectively.
-
+ This function is the called by resize_simple_key_cache and
+ resize_partitioned_key_cache that resize simple and partitioned key caches
+ respectively.
*/
static
-void s_finish_resize_key_cache(void *keycache_cb,
- my_bool with_resize_queue,
- my_bool acquire_lock)
+void finish_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
+ my_bool with_resize_queue,
+ my_bool acquire_lock)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_finish_resize_key_cache");
+ DBUG_ENTER("finish_resize_simple_key_cache");
if (acquire_lock)
keycache_pthread_mutex_lock(&keycache->cache_lock);
-
+
+ safe_mutex_assert_owner(&keycache->cache_lock);
+
/*
Mark the resize finished. This allows other threads to start a
resize or to request new cache blocks.
@@ -820,8 +815,8 @@ void s_finish_resize_key_cache(void *key
Resize a simple key cache
SYNOPSIS
- s_resize_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ resize_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
key_cache_block_size size of blocks to keep cached data
use_mem memory to use for the key cache buffers/structures
division_limit new division limit (if not zero)
@@ -830,8 +825,8 @@ void s_finish_resize_key_cache(void *key
DESCRIPTION
This function is the implementation of the resize_key_cache interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for the simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key
cache to be resized.
The parameter key_cache_block_size specifies the new size of the blocks in
the key cache. The parameters division_limit and age_threshold
@@ -845,47 +840,45 @@ void s_finish_resize_key_cache(void *key
0 - otherwise.
NOTES.
- The function first calls the function s_prepare_resize_key_cache
+ The function first calls the function prepare_resize_simple_key_cache
to flush all dirty blocks from key cache, to free memory used
for key cache blocks and auxiliary structures. After this the
function builds a new key cache with new parameters.
This implementation doesn't block the calls and executions of other
functions from the key cache interface. However it assumes that the
- calls of s_resize_key_cache itself are serialized.
+ calls of resize_simple_key_cache itself are serialized.
The function starts the operation only when all other threads
performing operations with the key cache let her to proceed
(when cnt_for_resize=0).
-
*/
static
-int s_resize_key_cache(void *keycache_cb, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+int resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
int blocks= 0;
- DBUG_ENTER("s_resize_key_cache");
+ DBUG_ENTER("resize_simple_key_cache");
if (!keycache->key_cache_inited)
- DBUG_RETURN(keycache->disk_blocks);
+ DBUG_RETURN(blocks);
/*
Note that the cache_lock mutex and the resize_queue are left untouched.
We do not lose the cache_lock and will release it only at the end of
this function.
*/
- if (s_prepare_resize_key_cache(keycache_cb, 1, 0))
+ if (prepare_resize_simple_key_cache(keycache, 1, 0))
goto finish;
/* The following will work even if use_mem is 0 */
- blocks= s_init_key_cache(keycache, key_cache_block_size, use_mem,
- division_limit, age_threshold);
+ blocks= init_simple_key_cache(keycache, key_cache_block_size, use_mem,
+ division_limit, age_threshold);
finish:
- s_finish_resize_key_cache(keycache_cb, 1, 0);
+ finish_resize_simple_key_cache(keycache, 1, 0);
DBUG_RETURN(blocks);
}
@@ -894,7 +887,7 @@ finish:
/*
Increment counter blocking resize key cache operation
*/
-static inline void inc_counter_for_resize_op(S_KEY_CACHE_CB *keycache)
+static inline void inc_counter_for_resize_op(SIMPLE_KEY_CACHE_CB *keycache)
{
keycache->cnt_for_resize_op++;
}
@@ -904,7 +897,7 @@ static inline void inc_counter_for_resiz
Decrement counter blocking resize key cache operation;
Signal the operation to proceed when counter becomes equal zero
*/
-static inline void dec_counter_for_resize_op(S_KEY_CACHE_CB *keycache)
+static inline void dec_counter_for_resize_op(SIMPLE_KEY_CACHE_CB *keycache)
{
if (!--keycache->cnt_for_resize_op)
release_whole_queue(&keycache->waiting_for_resize_cnt);
@@ -915,16 +908,16 @@ static inline void dec_counter_for_resiz
Change key cache parameters of a simple key cache
SYNOPSIS
- s_change_key_cache_param()
- keycache_cb pointer to the control block of a simple key cache
+ change_simple_key_cache_param()
+ keycache pointer to the control block of a simple key cache
division_limit new division limit (if not zero)
age_threshold new age threshold (if not zero)
DESCRIPTION
This function is the implementation of the change_key_cache_param interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for the simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key
cache where new values of the division limit and the age threshold used
for midpoint insertion strategy are to be set. The parameters
division_limit and age_threshold provide these new values.
@@ -938,15 +931,13 @@ static inline void dec_counter_for_resiz
This function changes some parameters of a given key cache without
reformatting it. The function does not touch the contents the key
cache blocks.
-
*/
static
-void s_change_key_cache_param(void *keycache_cb, uint division_limit,
- uint age_threshold)
+void change_simple_key_cache_param(SIMPLE_KEY_CACHE_CB *keycache, uint division_limit,
+ uint age_threshold)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_change_key_cache_param");
+ DBUG_ENTER("change_simple_key_cache_param");
keycache_pthread_mutex_lock(&keycache->cache_lock);
if (division_limit)
keycache->min_warm_blocks= (keycache->disk_blocks *
@@ -963,15 +954,15 @@ void s_change_key_cache_param(void *keyc
Destroy a simple key cache
SYNOPSIS
- s_end_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ end_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
cleanup <=> complete free (free also mutex for key cache)
DESCRIPTION
This function is the implementation of the end_key_cache interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for the simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key
cache to be destroyed.
The function frees the memory allocated for the key cache blocks and
auxiliary structures. If the value of the parameter cleanup is TRUE
@@ -982,10 +973,9 @@ void s_change_key_cache_param(void *keyc
*/
static
-void s_end_key_cache(void *keycache_cb, my_bool cleanup)
+void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_end_key_cache");
+ DBUG_ENTER("end_simple_key_cache");
DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache));
if (!keycache->key_cache_inited)
@@ -1276,7 +1266,7 @@ static inline void link_changed(BLOCK_LI
void
*/
-static void link_to_file_list(S_KEY_CACHE_CB *keycache,
+static void link_to_file_list(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block, int file,
my_bool unlink_block)
{
@@ -1317,7 +1307,7 @@ static void link_to_file_list(S_KEY_CACH
void
*/
-static void link_to_changed_list(S_KEY_CACHE_CB *keycache,
+static void link_to_changed_list(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block)
{
DBUG_ASSERT(block->status & BLOCK_IN_USE);
@@ -1372,8 +1362,8 @@ static void link_to_changed_list(S_KEY_C
not linked in the LRU ring.
*/
-static void link_block(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block, my_bool hot,
- my_bool at_end)
+static void link_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block,
+ my_bool hot, my_bool at_end)
{
BLOCK_LINK *ins;
BLOCK_LINK **pins;
@@ -1493,7 +1483,7 @@ static void link_block(S_KEY_CACHE_CB *k
See NOTES for link_block
*/
-static void unlink_block(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
+static void unlink_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
{
DBUG_ASSERT((block->status & ~BLOCK_CHANGED) == (BLOCK_READ | BLOCK_IN_USE));
DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/
@@ -1551,7 +1541,8 @@ static void unlink_block(S_KEY_CACHE_CB
RETURN
void
*/
-static void reg_requests(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block, int count)
+static void reg_requests(SIMPLE_KEY_CACHE_CB *keycache,
+ BLOCK_LINK *block, int count)
{
DBUG_ASSERT(block->status & BLOCK_IN_USE);
DBUG_ASSERT(block->hash_link);
@@ -1594,7 +1585,7 @@ static void reg_requests(S_KEY_CACHE_CB
not linked in the LRU ring.
*/
-static void unreg_request(S_KEY_CACHE_CB *keycache,
+static void unreg_request(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block, int at_end)
{
DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
@@ -1683,7 +1674,7 @@ static void remove_reader(BLOCK_LINK *bl
signals on its termination
*/
-static void wait_for_readers(S_KEY_CACHE_CB *keycache,
+static void wait_for_readers(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block)
{
#ifdef THREAD
@@ -1732,7 +1723,7 @@ static inline void link_hash(HASH_LINK *
Remove a hash link from the hash table
*/
-static void unlink_hash(S_KEY_CACHE_CB *keycache, HASH_LINK *hash_link)
+static void unlink_hash(SIMPLE_KEY_CACHE_CB *keycache, HASH_LINK *hash_link)
{
KEYCACHE_DBUG_PRINT("unlink_hash", ("fd: %u pos_ %lu #requests=%u",
(uint) hash_link->file,(ulong) hash_link->diskpos, hash_link->requests));
@@ -1788,7 +1779,7 @@ static void unlink_hash(S_KEY_CACHE_CB *
Get the hash link for a page
*/
-static HASH_LINK *get_hash_link(S_KEY_CACHE_CB *keycache,
+static HASH_LINK *get_hash_link(SIMPLE_KEY_CACHE_CB *keycache,
int file, my_off_t filepos)
{
reg1 HASH_LINK *hash_link, **start;
@@ -1909,7 +1900,7 @@ restart:
waits until first of this operations links any block back.
*/
-static BLOCK_LINK *find_key_block(S_KEY_CACHE_CB *keycache,
+static BLOCK_LINK *find_key_block(SIMPLE_KEY_CACHE_CB *keycache,
File file, my_off_t filepos,
int init_hits_left,
int wrmode, int *page_st)
@@ -2669,7 +2660,7 @@ restart:
portion is less than read_length, but not less than min_length.
*/
-static void read_block(S_KEY_CACHE_CB *keycache,
+static void read_block(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block, uint read_length,
uint min_length, my_bool primary)
{
@@ -2761,8 +2752,8 @@ static void read_block(S_KEY_CACHE_CB *k
SYNOPSIS
- s_key_cache_read()
- keycache_cb pointer to the control block of a simple key cache
+ simple_key_cache_read()
+ keycache pointer to the control block of a simple key cache
file handler for the file for the block of data to be read
filepos position of the block of data in the file
level determines the weight of the data
@@ -2774,8 +2765,8 @@ static void read_block(S_KEY_CACHE_CB *k
DESCRIPTION
This function is the implementation of the key_cache_read interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
cache.
In a general case the function reads a block of data from the key cache
into the buffer buff of the size specified by the parameter length. The
@@ -2799,20 +2790,18 @@ static void read_block(S_KEY_CACHE_CB *k
NOTES
Filepos must be a multiple of 'block_length', but it doesn't
have to be a multiple of key_cache_block_size;
-
*/
-uchar *s_key_cache_read(void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int return_buffer __attribute__((unused)))
+uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int return_buffer __attribute__((unused)))
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
my_bool locked_and_incremented= FALSE;
int error=0;
uchar *start= buff;
- DBUG_ENTER("s_key_cache_read");
+ DBUG_ENTER("simple_key_cache_read");
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
(uint) file, (ulong) filepos, length));
@@ -3010,8 +2999,8 @@ end:
Insert a block of file data from a buffer into a simple key cache
SYNOPSIS
- s_key_cache_insert()
- keycache_cb pointer to the control block of a simple key cache
+ simple_key_cache_insert()
+ keycache pointer to the control block of a simple key cache
file handler for the file to insert data from
filepos position of the block of data in the file to insert
level determines the weight of the data
@@ -3021,8 +3010,8 @@ end:
DESCRIPTION
This function is the implementation of the key_cache_insert interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
cache.
The function writes a block of file data from a buffer into the key cache.
The buffer is specified with the parameters buff and length - the pointer
@@ -3045,11 +3034,10 @@ end:
*/
static
-int s_key_cache_insert(void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length)
+int simple_key_cache_insert(SIMPLE_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
int error= 0;
DBUG_ENTER("key_cache_insert");
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
@@ -3272,8 +3260,8 @@ int s_key_cache_insert(void *keycache_cb
SYNOPSIS
- s_key_cache_write()
- keycache_cb pointer to the control block of a simple key cache
+ simple_key_cache_write()
+ keycache pointer to the control block of a simple key cache
file handler for the file to write data to
file_extra maps of key cache partitions containing
dirty pages from file
@@ -3287,8 +3275,8 @@ int s_key_cache_insert(void *keycache_cb
DESCRIPTION
This function is the implementation of the key_cache_write interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
cache.
In a general case the function copies data from a buffer into the key
cache. The buffer is specified with the parameters buff and length -
@@ -3304,7 +3292,8 @@ int s_key_cache_insert(void *keycache_cb
The parameter file_extra currently makes sense only for simple key caches
that are elements of a partitioned key cache. It provides a pointer to the
shared bitmap of the partitions that may contains dirty pages for the file.
- This bitmap is used to optimize the function p_flush_key_blocks.
+ This bitmap is used to optimize the function
+ flush_partitioned_key_cache_blocks.
RETURN VALUE
0 if a success, 1 - otherwise.
@@ -3312,21 +3301,19 @@ int s_key_cache_insert(void *keycache_cb
NOTES
This implementation exploits the fact that the function is called only
when a thread has got an exclusive lock for the key file.
-
*/
static
-int s_key_cache_write(void *keycache_cb,
- File file, void *file_extra __attribute__((unused)),
- my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int dont_write)
+int simple_key_cache_write(SIMPLE_KEY_CACHE_CB *keycache,
+ File file, void *file_extra __attribute__((unused)),
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int dont_write)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
my_bool locked_and_incremented= FALSE;
int error=0;
- DBUG_ENTER("s_key_cache_write");
+ DBUG_ENTER("simple_key_cache_write");
DBUG_PRINT("enter",
("fd: %u pos: %lu length: %u block_length: %u"
" key_block_length: %u",
@@ -3641,7 +3628,7 @@ end:
Block must have a request registered on it.
*/
-static void free_block(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
+static void free_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
{
KEYCACHE_THREAD_TRACE("free block");
KEYCACHE_DBUG_PRINT("free_block",
@@ -3781,7 +3768,7 @@ static int cmp_sec_link(BLOCK_LINK **a,
free used blocks if requested
*/
-static int flush_cached_blocks(S_KEY_CACHE_CB *keycache,
+static int flush_cached_blocks(SIMPLE_KEY_CACHE_CB *keycache,
File file, BLOCK_LINK **cache,
BLOCK_LINK **end,
enum flush_type type)
@@ -3909,7 +3896,7 @@ static int flush_cached_blocks(S_KEY_CAC
1 error
*/
-static int flush_key_blocks_int(S_KEY_CACHE_CB *keycache,
+static int flush_key_blocks_int(SIMPLE_KEY_CACHE_CB *keycache,
File file, enum flush_type type)
{
BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache;
@@ -4349,8 +4336,8 @@ err:
SYNOPSIS
- s_flush_key_blocks()
- keycache_cb pointer to the control block of a simple key cache
+ flush_simple_key_blocks()
+ keycache pointer to the control block of a simple key cache
file handler for the file to flush to
file_extra maps of key cache partitions containing
dirty pages from file (not used)
@@ -4359,7 +4346,7 @@ err:
DESCRIPTION
This function is the implementation of the flush_key_blocks interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
+ The function takes the parameter keycache as a pointer to the
control block structure of the type S_KEY_CACHE_CB for a simple key
cache.
In a general case the function flushes the data from all dirty key
@@ -4378,16 +4365,14 @@ err:
NOTES
This implementation exploits the fact that the function is called only
when a thread has got an exclusive lock for the key file.
-
*/
static
-int s_flush_key_blocks(void *keycache_cb,
- File file,
- void *file_extra __attribute__((unused)),
- enum flush_type type)
+int flush_simple_key_cache_blocks(SIMPLE_KEY_CACHE_CB *keycache,
+ File file,
+ void *file_extra __attribute__((unused)),
+ enum flush_type type)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
int res= 0;
DBUG_ENTER("flush_key_blocks");
DBUG_PRINT("enter", ("keycache: 0x%lx", (long) keycache));
@@ -4440,7 +4425,7 @@ int s_flush_key_blocks(void *keycache_cb
!= 0 Error
*/
-static int flush_all_key_blocks(S_KEY_CACHE_CB *keycache)
+static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
{
BLOCK_LINK *block;
uint total_found;
@@ -4546,14 +4531,14 @@ static int flush_all_key_blocks(S_KEY_CA
Reset the counters of a simple key cache
SYNOPSIS
- s_reset_key_cache_counters()
+ reset_simple_key_cache_counters()
name the name of a key cache
- keycache_cb pointer to the control block of a simple key cache
+ keycache pointer to the control block of a simple key cache
DESCRIPTION
This function is the implementation of the reset_key_cache_counters
interface function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
+ The function takes the parameter keycache as a pointer to the
control block structure of the type S_KEY_CACHE_CB for a simple key cache.
This function resets the values of all statistical counters for the key
cache to 0.
@@ -4561,15 +4546,13 @@ static int flush_all_key_blocks(S_KEY_CA
RETURN
0 on success (always because it can't fail)
-
*/
static
-int s_reset_key_cache_counters(const char *name __attribute__((unused)),
- void *keycache_cb)
+int reset_simple_key_cache_counters(const char *name __attribute__((unused)),
+ SIMPLE_KEY_CACHE_CB *keycache)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_reset_key_cache_counters");
+ DBUG_ENTER("reset_simple_key_cache_counters");
if (!keycache->key_cache_inited)
{
DBUG_PRINT("info", ("Key cache %s not initialized.", name));
@@ -4590,9 +4573,10 @@ int s_reset_key_cache_counters(const cha
/*
Test if disk-cache is ok
*/
-static void test_key_cache(S_KEY_CACHE_CB *keycache __attribute__((unused)),
- const char *where __attribute__((unused)),
- my_bool lock __attribute__((unused)))
+static
+void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache __attribute__((unused)),
+ const char *where __attribute__((unused)),
+ my_bool lock __attribute__((unused)))
{
/* TODO */
}
@@ -4604,7 +4588,7 @@ static void test_key_cache(S_KEY_CACHE_C
#define MAX_QUEUE_LEN 100
-static void keycache_dump(S_KEY_CACHE_CB *keycache)
+static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache)
{
FILE *keycache_dump_file=fopen(KEYCACHE_DUMP_FILE, "w");
struct st_my_thread_var *last;
@@ -4844,7 +4828,7 @@ static int fail_hlink(HASH_LINK *hlink)
return 0; /* Let the assert fail. */
}
-static int cache_empty(S_KEY_CACHE_CB *keycache)
+static int cache_empty(SIMPLE_KEY_CACHE_CB *keycache)
{
int errcnt= 0;
int idx;
@@ -4887,54 +4871,57 @@ static int cache_empty(S_KEY_CACHE_CB *k
Get statistics for a simple key cache
SYNOPSIS
- get_key_cache_statistics()
- keycache_cb pointer to the control block of a simple key cache
+ get_simple_key_cache_statistics()
+ keycache pointer to the control block of a simple key cache
partition_no partition number (not used)
key_cache_stats OUT pointer to the structure for the returned statistics
DESCRIPTION
This function is the implementation of the get_key_cache_statistics
interface function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key cache.
- This function returns the statistical data for the key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
+ cache. This function returns the statistical data for the key cache.
The parameter partition_no is not used by this function.
RETURN
none
-
*/
static
-void s_get_key_cache_statistics(void *keycache_cb,
- uint partition_no __attribute__((unused)),
- KEY_CACHE_STATISTICS *key_cache_stats)
-{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_get_key_cache_statistics");
-
- key_cache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
- key_cache_stats->block_size= (longlong) keycache->key_cache_block_size;
- key_cache_stats->blocks_used= keycache->blocks_used;
- key_cache_stats->blocks_unused= keycache->blocks_unused;
- key_cache_stats->blocks_changed= keycache->global_blocks_changed;
- key_cache_stats->read_requests= keycache->global_cache_r_requests;
- key_cache_stats->reads= keycache->global_cache_read;
- key_cache_stats->write_requests= keycache->global_cache_w_requests;
- key_cache_stats->writes= keycache->global_cache_write;
+void get_simple_key_cache_statistics(SIMPLE_KEY_CACHE_CB *keycache,
+ uint partition_no __attribute__((unused)),
+ KEY_CACHE_STATISTICS *keycache_stats)
+{
+ DBUG_ENTER("simple_get_key_cache_statistics");
+
+ keycache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
+ keycache_stats->block_size= (longlong) keycache->key_cache_block_size;
+ keycache_stats->blocks_used= keycache->blocks_used;
+ keycache_stats->blocks_unused= keycache->blocks_unused;
+ keycache_stats->blocks_changed= keycache->global_blocks_changed;
+ keycache_stats->read_requests= keycache->global_cache_r_requests;
+ keycache_stats->reads= keycache->global_cache_read;
+ keycache_stats->write_requests= keycache->global_cache_w_requests;
+ keycache_stats->writes= keycache->global_cache_write;
DBUG_VOID_RETURN;
}
-static size_t s_key_cache_stat_var_offsets[]=
+/*
+ Offsets of the statistical values in the control block for a simple key cache
+ The first NO_LONG_KEY_CACHE_STAT_VARIABLES=3 are of the ulong type while the
+ remaining are of the ulonglong type.
+ */
+static size_t simple_key_cache_stat_var_offsets[]=
{
- offsetof(S_KEY_CACHE_CB, blocks_used),
- offsetof(S_KEY_CACHE_CB, blocks_unused),
- offsetof(S_KEY_CACHE_CB, global_blocks_changed),
- offsetof(S_KEY_CACHE_CB, global_cache_w_requests),
- offsetof(S_KEY_CACHE_CB, global_cache_write),
- offsetof(S_KEY_CACHE_CB, global_cache_r_requests),
- offsetof(S_KEY_CACHE_CB, global_cache_read)
+ offsetof(SIMPLE_KEY_CACHE_CB, blocks_used),
+ offsetof(SIMPLE_KEY_CACHE_CB, blocks_unused),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_blocks_changed),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_w_requests),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_write),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_r_requests),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_read)
};
@@ -4942,16 +4929,16 @@ static size_t s_key_cache_stat_var_offse
Get the value of a statistical variable for a simple key cache
SYNOPSIS
- s_get_key_cache_stat_value()
- keycache_cb pointer to the control block of a simple key cache
+ get_simple_key_cache_stat_value()
+ keycache pointer to the control block of a simple key cache
var_no the ordered number of a statistical variable
DESCRIPTION
- This function is the implementation of the s_get_key_cache_stat_value
+ This function is the implementation of the get_simple_key_cache_stat_value
interface function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key cache.
- This function returns the value of the statistical variable var_no
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
+ cache. This function returns the value of the statistical variable var_no
for this key cache. The variables are numbered starting from 0 to 6.
RETURN
@@ -4960,12 +4947,12 @@ static size_t s_key_cache_stat_var_offse
*/
static
-ulonglong s_get_key_cache_stat_value(void *keycache_cb, uint var_no)
+ulonglong get_simple_key_cache_stat_value(SIMPLE_KEY_CACHE_CB *keycache,
+ uint var_no)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- size_t var_ofs= s_key_cache_stat_var_offsets[var_no];
+ size_t var_ofs= simple_key_cache_stat_var_offsets[var_no];
ulonglong res= 0;
- DBUG_ENTER("s_get_key_cache_stat_value");
+ DBUG_ENTER("get_simple_key_cache_stat_value");
if (var_no < 3)
res= (ulonglong) (*(long *) ((char *) keycache + var_ofs));
@@ -4985,19 +4972,19 @@ ulonglong s_get_key_cache_stat_value(voi
the MySQL server code directly. We don't do it though.
*/
-static KEY_CACHE_FUNCS s_key_cache_funcs =
+static KEY_CACHE_FUNCS simple_key_cache_funcs =
{
- s_init_key_cache,
- s_resize_key_cache,
- s_change_key_cache_param,
- s_key_cache_read,
- s_key_cache_insert,
- s_key_cache_write,
- s_flush_key_blocks,
- s_reset_key_cache_counters,
- s_end_key_cache,
- s_get_key_cache_statistics,
- s_get_key_cache_stat_value
+ (INIT_KEY_CACHE) init_simple_key_cache,
+ (RESIZE_KEY_CACHE) resize_simple_key_cache,
+ (CHANGE_KEY_CACHE_PARAM) change_simple_key_cache_param,
+ (KEY_CACHE_READ) simple_key_cache_read,
+ (KEY_CACHE_INSERT) simple_key_cache_insert,
+ (KEY_CACHE_WRITE) simple_key_cache_write,
+ (FLUSH_KEY_BLOCKS) flush_simple_key_cache_blocks,
+ (RESET_KEY_CACHE_COUNTERS) reset_simple_key_cache_counters,
+ (END_KEY_CACHE) end_simple_key_cache,
+ (GET_KEY_CACHE_STATISTICS) get_simple_key_cache_statistics,
+ (GET_KEY_CACHE_STAT_VALUE) get_simple_key_cache_stat_value
};
@@ -5038,17 +5025,22 @@ static KEY_CACHE_FUNCS s_key_cache_funcs
/* Control block for a partitioned key cache */
-typedef struct st_p_key_cache_cb
+typedef struct st_partitioned_key_cache_cb
{
my_bool key_cache_inited; /*<=> control block is allocated */
- S_KEY_CACHE_CB **partition_array; /* array of the key cache partitions */
- uint partitions; /* number of partitions in the key cache */
+ SIMPLE_KEY_CACHE_CB **partition_array; /* the key cache partitions */
size_t key_cache_mem_size; /* specified size of the cache memory */
uint key_cache_block_size; /* size of the page buffer of a cache block */
-} P_KEY_CACHE_CB;
+ uint partitions; /* number of partitions in the key cache */
+} PARTITIONED_KEY_CACHE_CB;
static
-void p_end_key_cache(void *keycache_cb, my_bool cleanup);
+void end_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ my_bool cleanup);
+
+static int
+reset_partitioned_key_cache_counters(const char *name,
+ PARTITIONED_KEY_CACHE_CB *keycache);
/*
Determine the partition to which the index block to read is ascribed
@@ -5070,11 +5062,12 @@ void p_end_key_cache(void *keycache_cb,
file block is ascribed.
*/
-static
-S_KEY_CACHE_CB *get_key_cache_partition(P_KEY_CACHE_CB *keycache,
- File file, my_off_t filepos)
+static
+SIMPLE_KEY_CACHE_CB *
+get_key_cache_partition(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos)
{
- uint i= KEYCACHE_BASE_EXPR( file, filepos) % keycache->partitions;
+ uint i= KEYCACHE_BASE_EXPR(file, filepos) % keycache->partitions;
return keycache->partition_array[i];
}
@@ -5101,10 +5094,10 @@ S_KEY_CACHE_CB *get_key_cache_partition(
file block is ascribed.
*/
-static
-S_KEY_CACHE_CB *get_key_cache_partition_for_write(P_KEY_CACHE_CB *keycache,
- File file, my_off_t filepos,
- ulonglong* dirty_part_map)
+static SIMPLE_KEY_CACHE_CB
+*get_key_cache_partition_for_write(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos,
+ ulonglong* dirty_part_map)
{
uint i= KEYCACHE_BASE_EXPR( file, filepos) % keycache->partitions;
*dirty_part_map|= 1<<i;
@@ -5116,8 +5109,8 @@ S_KEY_CACHE_CB *get_key_cache_partition_
Initialize a partitioned key cache
SYNOPSIS
- p_init_key_cache()
- keycache_cb pointer to the control block of a partitioned key cache
+ init_partitioned_key_cache()
+ keycache pointer to the control block of a partitioned key cache
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for all key cache partitions
division_limit division limit (may be zero)
@@ -5127,17 +5120,17 @@ S_KEY_CACHE_CB *get_key_cache_partition_
This function is the implementation of the init_key_cache interface function
that is employed by partitioned key caches.
The function builds and initializes an array of simple key caches, and then
- initializes the control block structure of the type P_KEY_CACHE_CB that is
- used for a partitioned key cache. The parameter keycache_cb is supposed to
- point to this structure. The number of partitions in the partitioned key
- cache to be built must be passed through the field 'partitions' of this
- structure. The parameter key_cache_block_size specifies the size of the
- blocks in the the simple key caches to be built. The parameters
- division_limit and age_threshold determine the initial values of those
- characteristics of the simple key caches that are used for midpoint
- insertion strategy. The parameter use_mem specifies the total amount of
- memory to be allocated for the key cache blocks in all simple key caches
- and for all auxiliary structures.
+ initializes the control block structure of the type PARTITIONED_KEY_CACHE_CB
+ that is used for a partitioned key cache. The parameter keycache is
+ supposed to point to this structure. The number of partitions in the
+ partitioned key cache to be built must be passed through the field
+ 'partitions' of this structure. The parameter key_cache_block_size specifies
+ the size of the blocks in the the simple key caches to be built.
+ The parameters division_limit and age_threshold determine the initial
+ values of those characteristics of the simple key caches that are used for
+ midpoint insertion strategy. The parameter use_mem specifies the total
+ amount of memory to be allocated for the key cache blocks in all simple key
+ caches and for all auxiliary structures.
RETURN VALUE
total number of blocks in key cache partitions, if successful,
@@ -5152,19 +5145,19 @@ S_KEY_CACHE_CB *get_key_cache_partition_
*/
static
-int p_init_key_cache(void *keycache_cb, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+int init_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
int i;
size_t mem_per_cache;
int cnt;
- S_KEY_CACHE_CB *partition;
- S_KEY_CACHE_CB **partition_ptr;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
+ SIMPLE_KEY_CACHE_CB *partition;
+ SIMPLE_KEY_CACHE_CB **partition_ptr;
uint partitions= keycache->partitions;
- int blocks= -1;
- DBUG_ENTER("p_init_key_cache");
+ int blocks= 0;
+ DBUG_ENTER("partitioned_init_key_cache");
keycache->key_cache_block_size = key_cache_block_size;
@@ -5173,9 +5166,9 @@ int p_init_key_cache(void *keycache_cb,
else
{
if(!(partition_ptr=
- (S_KEY_CACHE_CB **) my_malloc(sizeof(S_KEY_CACHE_CB *) * partitions,
- MYF(0))))
- DBUG_RETURN(blocks);
+ (SIMPLE_KEY_CACHE_CB **) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB *) *
+ partitions, MYF(MY_WME))))
+ DBUG_RETURN(-1);
keycache->partition_array= partition_ptr;
}
@@ -5188,36 +5181,35 @@ int p_init_key_cache(void *keycache_cb,
partition= *partition_ptr;
else
{
- if (!(partition= (S_KEY_CACHE_CB *) my_malloc(sizeof(S_KEY_CACHE_CB),
- MYF(0))))
+ if (!(partition=
+ (SIMPLE_KEY_CACHE_CB *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB),
+ MYF(MY_WME))))
continue;
partition->key_cache_inited= 0;
}
- if ((cnt= s_init_key_cache(partition,
- key_cache_block_size, mem_per_cache,
- division_limit, age_threshold)) <= 0)
+ if ((cnt= init_simple_key_cache(partition,
+ key_cache_block_size, mem_per_cache,
+ division_limit, age_threshold)) <= 0)
{
- s_end_key_cache(partition, 1);
- my_free((uchar *) partition, MYF(0));
+ end_simple_key_cache(partition, 1);
+ my_free(partition, MYF(0));
partition= 0;
if (key_cache_inited)
{
memmove(partition_ptr, partition_ptr+1,
sizeof(partition_ptr)*(partitions-i-1));
}
+ if (!--partitions)
+ break;
if (i == 0)
{
i--;
- partitions--;
- if (partitions)
- mem_per_cache = use_mem / partitions;
+ mem_per_cache = use_mem / partitions;
+ continue;
}
- continue;
}
- if (blocks < 0)
- blocks= 0;
blocks+= cnt;
*partition_ptr++= partition;
}
@@ -5229,6 +5221,9 @@ int p_init_key_cache(void *keycache_cb,
keycache->key_cache_inited= 1;
+ if (!partitions)
+ blocks= -1;
+
DBUG_RETURN(blocks);
}
@@ -5237,8 +5232,8 @@ int p_init_key_cache(void *keycache_cb,
Resize a partitioned key cache
SYNOPSIS
- p_resize_key_cache()
- keycache_cb pointer to the control block of a partitioned key cache
+ resize_partitioned_key_cache()
+ keycache pointer to the control block of a partitioned key cache
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for the new key cache
division_limit new division limit (if not zero)
@@ -5247,9 +5242,9 @@ int p_init_key_cache(void *keycache_cb,
DESCRIPTION
This function is the implementation of the resize_key_cache interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for the partitioned
- key cache to be resized.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for the
+ partitioned key cache to be resized.
The parameter key_cache_block_size specifies the new size of the blocks in
the simple key caches that comprise the partitioned key cache.
The parameters division_limit and age_threshold determine the new initial
@@ -5263,48 +5258,47 @@ int p_init_key_cache(void *keycache_cb,
0 - otherwise.
NOTES.
- The function first calls s_prepare_resize_key_cache for each simple
+ The function first calls prepare_resize_simple_key_cache for each simple
key cache effectively flushing all dirty pages from it and destroying
- the key cache. Then p_init_key cache is called. This call builds all
- the new array of simple key caches containing the same number of
- elements as the old one. After this the function calls the function
- s_finish_resize_key_cache for each simple key cache from this array.
+ the key cache. Then init_partitioned_key_cache is called. This call builds
+ a new array of simple key caches containing the same number of elements
+ as the old one. After this the function calls the function
+ finish_resize_simple_key_cache for each simple key cache from this array.
This implementation doesn't block the calls and executions of other
functions from the key cache interface. However it assumes that the
- calls of s_resize_key_cache itself are serialized.
-
+ calls of resize_partitioned_key_cache itself are serialized.
*/
static
-int p_resize_key_cache(void *keycache_cb, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+int resize_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
my_bool cleanup= use_mem == 0;
int blocks= -1;
int err= 0;
- DBUG_ENTER("p_resize_key_cache");
- if (use_mem == 0)
+ DBUG_ENTER("partitioned_resize_key_cache");
+ if (cleanup)
{
- p_end_key_cache(keycache_cb, 0);
- DBUG_RETURN(blocks);
+ end_partitioned_key_cache(keycache, 0);
+ DBUG_RETURN(-1);
}
for (i= 0; i < partitions; i++)
{
- err|= s_prepare_resize_key_cache(keycache->partition_array[i], 0, 1);
+ err|= prepare_resize_simple_key_cache(keycache->partition_array[i], 0, 1);
}
- if (!err && use_mem)
- blocks= p_init_key_cache(keycache_cb, key_cache_block_size, use_mem,
- division_limit, age_threshold);
- if (blocks > 0 && !cleanup)
+ if (!err)
+ blocks= init_partitioned_key_cache(keycache, key_cache_block_size,
+ use_mem, division_limit, age_threshold);
+ if (blocks > 0)
{
for (i= 0; i < partitions; i++)
{
- s_finish_resize_key_cache(keycache->partition_array[i], 0, 1);
+ finish_resize_simple_key_cache(keycache->partition_array[i], 0, 1);
}
}
DBUG_RETURN(blocks);
@@ -5315,17 +5309,17 @@ int p_resize_key_cache(void *keycache_cb
Change key cache parameters of a partitioned key cache
SYNOPSIS
- p_change_key_cache_param()
- keycache_cb pointer to the control block of a partitioned key cache
+ partitioned_change_key_cache_param()
+ keycache pointer to the control block of a partitioned key cache
division_limit new division limit (if not zero)
age_threshold new age threshold (if not zero)
DESCRIPTION
This function is the implementation of the change_key_cache_param interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for the simple key
- cache where new values of the division limit and the age threshold used
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for the simple
+ key cache where new values of the division limit and the age threshold used
for midpoint insertion strategy are to be set. The parameters
division_limit and age_threshold provide these new values.
@@ -5333,23 +5327,22 @@ int p_resize_key_cache(void *keycache_cb
none
NOTES
- The function just calls s_change_key_cache_param for each element from the
- array of simple caches that comprise the partitioned key cache.
-
+ The function just calls change_simple_key_cache_param for each element from
+ the array of simple caches that comprise the partitioned key cache.
*/
static
-void p_change_key_cache_param(void *keycache_cb, uint division_limit,
- uint age_threshold)
+void change_partitioned_key_cache_param(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint division_limit,
+ uint age_threshold)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
- DBUG_ENTER("p_change_key_cache_param");
+ DBUG_ENTER("partitioned_change_key_cache_param");
for (i= 0; i < partitions; i++)
{
- s_change_key_cache_param(keycache->partition_array[i], division_limit,
- age_threshold);
+ change_simple_key_cache_param(keycache->partition_array[i], division_limit,
+ age_threshold);
}
DBUG_VOID_RETURN;
}
@@ -5359,17 +5352,17 @@ void p_change_key_cache_param(void *keyc
Destroy a partitioned key cache
SYNOPSIS
- p_end_key_cache()
- keycache_cb pointer to the control block of a partitioned key cache
+ end_partitioned_key_cache()
+ keycache pointer to the control block of a partitioned key cache
cleanup <=> complete free (free also control block structures
for all simple key caches)
DESCRIPTION
This function is the implementation of the end_key_cache interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for the partitioned
- key cache to be destroyed.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for the
+ partitioned key cache to be destroyed.
The function frees the memory allocated for the cache blocks and
auxiliary structures used by simple key caches that comprise the
partitioned key cache. If the value of the parameter cleanup is TRUE
@@ -5378,23 +5371,23 @@ void p_change_key_cache_param(void *keyc
RETURN VALUE
none
-
*/
static
-void p_end_key_cache(void *keycache_cb, my_bool cleanup)
+void end_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ my_bool cleanup)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
- DBUG_ENTER("p_end_key_cache");
+ DBUG_ENTER("partitioned_end_key_cache");
DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache));
for (i= 0; i < partitions; i++)
{
- s_end_key_cache(keycache->partition_array[i], cleanup);
+ end_simple_key_cache(keycache->partition_array[i], cleanup);
}
- if (cleanup) {
+ if (cleanup)
+ {
for (i= 0; i < partitions; i++)
my_free((uchar*) keycache->partition_array[i], MYF(0));
my_free((uchar*) keycache->partition_array, MYF(0));
@@ -5409,8 +5402,8 @@ void p_end_key_cache(void *keycache_cb,
SYNOPSIS
- p_key_cache_read()
- keycache_cb pointer to the control block of a partitioned key cache
+ partitioned_key_cache_read()
+ keycache pointer to the control block of a partitioned key cache
file handler for the file for the block of data to be read
filepos position of the block of data in the file
level determines the weight of the data
@@ -5422,9 +5415,9 @@ void p_end_key_cache(void *keycache_cb,
DESCRIPTION
This function is the implementation of the key_cache_read interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
In a general case the function reads a block of data from the key cache
into the buffer buff of the size specified by the parameter length. The
beginning of the block of data to be read is specified by the parameters
@@ -5432,7 +5425,7 @@ void p_end_key_cache(void *keycache_cb,
of the buffer. The data is read into the buffer in key_cache_block_size
increments. To read each portion the function first finds out in what
partition of the key cache this portion(page) is to be saved, and calls
- s_key_cache_read with the pointer to the corresponding simple key as
+ simple_key_cache_read with the pointer to the corresponding simple key as
its first parameter.
If the parameter return_buffer is not ignored and its value is TRUE, and
the data to be read of the specified size block_length can be read from one
@@ -5445,21 +5438,19 @@ void p_end_key_cache(void *keycache_cb,
RETURN VALUE
Returns address from where the data is placed if successful, 0 - otherwise.
-
*/
static
-uchar *p_key_cache_read(void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int return_buffer __attribute__((unused)))
+uchar *partitioned_key_cache_read(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int return_buffer __attribute__((unused)))
{
uint r_length;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint offset= (uint) (filepos % keycache->key_cache_block_size);
uchar *start= buff;
- DBUG_ENTER("p_key_cache_read");
+ DBUG_ENTER("partitioned_key_cache_read");
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
(uint) file, (ulong) filepos, length));
@@ -5471,15 +5462,15 @@ uchar *p_key_cache_read(void *keycache_c
/* Read data in key_cache_block_size increments */
do
{
- S_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
- file, filepos);
+ SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
+ file, filepos);
uchar *ret_buff= 0;
r_length= length;
set_if_smaller(r_length, keycache->key_cache_block_size - offset);
- ret_buff= s_key_cache_read((void *) partition,
- file, filepos, level,
- buff, r_length,
- block_length, return_buffer);
+ ret_buff= simple_key_cache_read((void *) partition,
+ file, filepos, level,
+ buff, r_length,
+ block_length, return_buffer);
if (ret_buff == 0)
DBUG_RETURN(0);
#ifndef THREAD
@@ -5500,8 +5491,8 @@ uchar *p_key_cache_read(void *keycache_c
Insert a block of file data from a buffer into a partitioned key cache
SYNOPSIS
- p_key_cache_insert()
- keycache_cb pointer to the control block of a partitioned key cache
+ partitioned_key_cache_insert()
+ keycache pointer to the control block of a partitioned key cache
file handler for the file to insert data from
filepos position of the block of data in the file to insert
level determines the weight of the data
@@ -5511,9 +5502,9 @@ uchar *p_key_cache_read(void *keycache_c
DESCRIPTION
This function is the implementation of the key_cache_insert interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned key
- cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
The function writes a block of file data from a buffer into the key cache.
The buffer is specified with the parameters buff and length - the pointer
to the beginning of the buffer and its size respectively. It's assumed
@@ -5521,8 +5512,8 @@ uchar *p_key_cache_read(void *keycache_c
filepos. The data is copied from the buffer in key_cache_block_size
increments. For every portion of data the function finds out in what simple
key cache from the array of partitions the data must be stored, and after
- this calls s_key_cache_insert to copy the data into a key buffer of this
- simple key cache.
+ this calls simple_key_cache_insert to copy the data into a key buffer of
+ this simple key cache.
The parameter level is used to set one characteristic for the key buffers
loaded with the data from buff. The characteristic is used only by the
midpoint insertion strategy.
@@ -5534,18 +5525,16 @@ uchar *p_key_cache_read(void *keycache_c
The function is used by MyISAM to move all blocks from a index file to
the key cache. It can be performed in parallel with reading the file data
from the key buffers by other threads.
-
*/
static
-int p_key_cache_insert(void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length)
+int partitioned_key_cache_insert(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length)
{
uint w_length;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint offset= (uint) (filepos % keycache->key_cache_block_size);
- DBUG_ENTER("p_key_cache_insert");
+ DBUG_ENTER("partitioned_key_cache_insert");
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
(uint) file,(ulong) filepos, length));
@@ -5553,13 +5542,13 @@ int p_key_cache_insert(void *keycache_cb
/* Write data in key_cache_block_size increments */
do
{
- S_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
- file, filepos);
+ SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
+ file, filepos);
w_length= length;
- set_if_smaller(w_length, keycache->key_cache_block_size);
- if (s_key_cache_insert((void *) partition,
- file, filepos, level,
- buff, w_length))
+ set_if_smaller(w_length, keycache->key_cache_block_size - offset);
+ if (simple_key_cache_insert((void *) partition,
+ file, filepos, level,
+ buff, w_length))
DBUG_RETURN(1);
filepos+= w_length;
@@ -5576,8 +5565,8 @@ int p_key_cache_insert(void *keycache_cb
SYNOPSIS
- p_key_cache_write()
- keycache_cb pointer to the control block of a partitioned key cache
+ partitioned_key_cache_write()
+ keycache pointer to the control block of a partitioned key cache
file handler for the file to write data to
filepos position in the file to write data to
level determines the weight of the data
@@ -5591,9 +5580,9 @@ int p_key_cache_insert(void *keycache_cb
DESCRIPTION
This function is the implementation of the key_cache_write interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
In a general case the function copies data from a buffer into the key
cache. The buffer is specified with the parameters buff and length -
the pointer to the beginning of the buffer and its size respectively.
@@ -5601,8 +5590,8 @@ int p_key_cache_insert(void *keycache_cb
starting from the position filepos. The data is copied from the buffer
in key_cache_block_size increments. For every portion of data the
function finds out in what simple key cache from the array of partitions
- the data must be stored, and after this calls s_key_cache_write to copy
- the data into a key buffer of this simple key cache.
+ the data must be stored, and after this calls simple_key_cache_write to
+ copy the data into a key buffer of this simple key cache.
If the value of the parameter dont_write is FALSE then the function
also writes the data into file.
The parameter level is used to set one characteristic for the key buffers
@@ -5610,7 +5599,7 @@ int p_key_cache_insert(void *keycache_cb
the midpoint insertion strategy.
The parameter file_expra provides a pointer to the shared bitmap of
the partitions that may contains dirty pages for the file. This bitmap
- is used to optimize the function p_flush_key_blocks.
+ is used to optimize the function flush_partitioned_key_cache_blocks.
RETURN VALUE
0 if a success, 1 - otherwise.
@@ -5618,22 +5607,20 @@ int p_key_cache_insert(void *keycache_cb
NOTES
This implementation exploits the fact that the function is called only
when a thread has got an exclusive lock for the key file.
-
*/
static
-int p_key_cache_write(void *keycache_cb,
- File file, void *file_extra,
- my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int dont_write)
+int partitioned_key_cache_write(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, void *file_extra,
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int dont_write)
{
uint w_length;
ulonglong *part_map= (ulonglong *) file_extra;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint offset= (uint) (filepos % keycache->key_cache_block_size);
- DBUG_ENTER("p_key_cache_write");
+ DBUG_ENTER("partitioned_key_cache_write");
DBUG_PRINT("enter",
("fd: %u pos: %lu length: %u block_length: %u"
" key_block_length: %u",
@@ -5644,15 +5631,16 @@ int p_key_cache_write(void *keycache_cb,
/* Write data in key_cache_block_size increments */
do
{
- S_KEY_CACHE_CB *partition= get_key_cache_partition_for_write(keycache,
- file, filepos,
- part_map);
+ SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition_for_write(keycache,
+ file,
+ filepos,
+ part_map);
w_length = length;
- set_if_smaller(w_length, keycache->key_cache_block_size );
- if (s_key_cache_write(partition,
- file, 0, filepos, level,
- buff, w_length, block_length,
- dont_write))
+ set_if_smaller(w_length, keycache->key_cache_block_size - offset );
+ if (simple_key_cache_write(partition,
+ file, 0, filepos, level,
+ buff, w_length, block_length,
+ dont_write))
DBUG_RETURN(1);
filepos+= w_length;
@@ -5669,8 +5657,8 @@ int p_key_cache_write(void *keycache_cb,
SYNOPSIS
- p_flush_key_blocks()
- keycache_cb pointer to the control block of a partitioned key cache
+ flush_partitioned_key_cache_blocks()
+ keycache pointer to the control block of a partitioned key cache
file handler for the file to flush to
file_extra maps of key cache partitions containing
dirty pages from file (not used)
@@ -5679,9 +5667,9 @@ int p_key_cache_write(void *keycache_cb,
DESCRIPTION
This function is the implementation of the flush_key_blocks interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
In a general case the function flushes the data from all dirty key
buffers related to the file 'file' into this file. The function does
exactly this if the value of the parameter type is FLUSH_KEEP. If the
@@ -5689,12 +5677,12 @@ int p_key_cache_write(void *keycache_cb,
releases the key buffers containing data from 'file' for new usage.
If the value of the parameter type is FLUSH_IGNORE_CHANGED the function
just releases the key buffers containing data from 'file'.
- The function performs the operation by calling s_flush_key_blocks
- for the elements of the array of the simple key caches that comprise
- the partitioned key_cache. If the value of the parameter type is
- FLUSH_KEEP s_flush_key_blocks is called only for the partitions with
- possibly dirty pages marked in the bitmap pointed to by the parameter
- file_extra.
+ The function performs the operation by calling the function
+ flush_simple_key_cache_blocks for the elements of the array of the
+ simple key caches that comprise the partitioned key_cache. If the value
+ of the parameter type is FLUSH_KEEP s_flush_key_blocks is called only
+ for the partitions with possibly dirty pages marked in the bitmap
+ pointed to by the parameter file_extra.
RETURN
0 ok
@@ -5703,35 +5691,30 @@ int p_key_cache_write(void *keycache_cb,
NOTES
This implementation exploits the fact that the function is called only
when a thread has got an exclusive lock for the key file.
-
*/
static
-int p_flush_key_blocks(void *keycache_cb,
- File file, void *file_extra,
- enum flush_type type)
+int flush_partitioned_key_cache_blocks(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, void *file_extra,
+ enum flush_type type)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
int err= 0;
ulonglong *dirty_part_map= (ulonglong *) file_extra;
- DBUG_ENTER("p_flush_key_blocks");
+ DBUG_ENTER("partitioned_flush_key_blocks");
DBUG_PRINT("enter", ("keycache: 0x%lx", (long) keycache));
for (i= 0; i < partitions; i++)
{
- S_KEY_CACHE_CB *partition= keycache->partition_array[i];
+ SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i];
if ((type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE) &&
- !((*dirty_part_map) & (1<<i)))
+ !((*dirty_part_map) & ((ulonglong) 1 << i)))
continue;
- err+= test(s_flush_key_blocks(partition, file, 0, type));
+ err|= test(flush_simple_key_cache_blocks(partition, file, 0, type));
}
*dirty_part_map= 0;
- if (err > 0)
- err= 1;
-
DBUG_RETURN(err);
}
@@ -5740,38 +5723,36 @@ int p_flush_key_blocks(void *keycache_cb
Reset the counters of a partitioned key cache
SYNOPSIS
- p_reset_key_cache_counters()
+ reset_partitioned_key_cache_counters()
name the name of a key cache
- keycache_cb pointer to the control block of a partitioned key cache
+ keycache pointer to the control block of a partitioned key cache
DESCRIPTION
This function is the implementation of the reset_key_cache_counters
interface function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a partitioned
key cache.
This function resets the values of the statistical counters of the simple
key caches comprising partitioned key cache to 0. It does it by calling
- s_reset_key_cache_counters for each key cache partition.
+ reset_simple_key_cache_counters for each key cache partition.
The parameter name is currently not used.
RETURN
0 on success (always because it can't fail)
-
*/
-static
-int p_reset_key_cache_counters(const char *name __attribute__((unused)),
- void *keycache_cb)
+static int
+reset_partitioned_key_cache_counters(const char *name __attribute__((unused)),
+ PARTITIONED_KEY_CACHE_CB *keycache)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
- DBUG_ENTER("p_reset_key_cache_counters");
+ DBUG_ENTER("partitioned_reset_key_cache_counters");
for (i = 0; i < partitions; i++)
{
- s_reset_key_cache_counters(name, keycache->partition_array[i]);
+ reset_simple_key_cache_counters(name, keycache->partition_array[i]);
}
DBUG_RETURN(0);
}
@@ -5781,17 +5762,17 @@ int p_reset_key_cache_counters(const cha
Get statistics for a partition key cache
SYNOPSIS
- p_get_key_cache_statistics()
- keycache_cb pointer to the control block of a partitioned key cache
+ get_partitioned_key_cache_statistics()
+ keycache pointer to the control block of a partitioned key cache
partition_no partition number to get statistics for
key_cache_stats OUT pointer to the structure for the returned statistics
DESCRIPTION
This function is the implementation of the get_key_cache_statistics
interface function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for
+ a partitioned key cache.
If the value of the parameter partition_no is equal to 0 then aggregated
statistics for all partitions is returned in the fields of the
structure key_cache_stat of the type KEY_CACHE_STATISTICS . Otherwise
@@ -5801,37 +5782,38 @@ int p_reset_key_cache_counters(const cha
RETURN
none
-
*/
static
-void p_get_key_cache_statistics(void *keycache_cb, uint partition_no,
- KEY_CACHE_STATISTICS *key_cache_stats)
+void
+get_partitioned_key_cache_statistics(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint partition_no,
+ KEY_CACHE_STATISTICS *keycache_stats)
{
uint i;
- S_KEY_CACHE_CB *partition;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
+ SIMPLE_KEY_CACHE_CB *partition;
uint partitions= keycache->partitions;
- DBUG_ENTER("p_get_key_cache_statistics_");
+ DBUG_ENTER("get_partitioned_key_cache_statistics");
if (partition_no != 0)
{
partition= keycache->partition_array[partition_no-1];
- s_get_key_cache_statistics((void *) partition, 0, key_cache_stats);
+ get_simple_key_cache_statistics((void *) partition, 0, keycache_stats);
DBUG_VOID_RETURN;
}
- key_cache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
- key_cache_stats->block_size= (longlong) keycache->key_cache_block_size;
+ bzero(keycache_stats, sizeof(KEY_CACHE_STATISTICS));
+ keycache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
+ keycache_stats->block_size= (longlong) keycache->key_cache_block_size;
for (i = 0; i < partitions; i++)
{
partition= keycache->partition_array[i];
- key_cache_stats->blocks_used+= partition->blocks_used;
- key_cache_stats->blocks_unused+= partition->blocks_unused;
- key_cache_stats->blocks_changed+= partition->global_blocks_changed;
- key_cache_stats->read_requests+= partition->global_cache_r_requests;
- key_cache_stats->reads+= partition->global_cache_read;
- key_cache_stats->write_requests+= partition->global_cache_w_requests;
- key_cache_stats->writes+= partition->global_cache_write;
+ keycache_stats->blocks_used+= partition->blocks_used;
+ keycache_stats->blocks_unused+= partition->blocks_unused;
+ keycache_stats->blocks_changed+= partition->global_blocks_changed;
+ keycache_stats->read_requests+= partition->global_cache_r_requests;
+ keycache_stats->reads+= partition->global_cache_read;
+ keycache_stats->write_requests+= partition->global_cache_w_requests;
+ keycache_stats->writes+= partition->global_cache_write;
}
DBUG_VOID_RETURN;
}
@@ -5840,16 +5822,16 @@ void p_get_key_cache_statistics(void *ke
Get the value of a statistical variable for a partitioned key cache
SYNOPSIS
- p_get_key_cache_stat_value()
- keycache_cb pointer to the control block of a partitioned key cache
+ get_partitioned_key_cache_stat_value()
+ keycache pointer to the control block of a partitioned key cache
var_no the ordered number of a statistical variable
DESCRIPTION
This function is the implementation of the get_key_cache_stat_value
interface function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
This function returns the value of the statistical variable var_no
for this key cache. The variables are numbered starting from 0 to 6.
The returned value is calculated as the sum of the values of the
@@ -5858,24 +5840,24 @@ void p_get_key_cache_statistics(void *ke
RETURN
The value of the specified statistical variable
-
*/
static
-ulonglong p_get_key_cache_stat_value(void *keycache_cb, uint var_no)
+ulonglong
+get_partitioned_key_cache_stat_value(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint var_no)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
- size_t var_ofs= s_key_cache_stat_var_offsets[var_no];
+ size_t var_ofs= simple_key_cache_stat_var_offsets[var_no];
ulonglong res= 0;
- DBUG_ENTER("p_get_key_cache_stat_value");
+ DBUG_ENTER("get_partitioned_key_cache_stat_value");
- if (var_no < 3)
+ if (var_no < NO_LONG_KEY_CACHE_STAT_VARIABLES)
{
for (i = 0; i < partitions; i++)
{
- S_KEY_CACHE_CB *partition= keycache->partition_array[i];
+ SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i];
res+= (ulonglong) (*(long *) ((char *) partition + var_ofs));
}
}
@@ -5883,7 +5865,7 @@ ulonglong p_get_key_cache_stat_value(voi
{
for (i = 0; i < partitions; i++)
{
- S_KEY_CACHE_CB *partition= keycache->partition_array[i];
+ SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i];
res+= *(ulonglong *) ((char *) partition + var_ofs);
}
}
@@ -5901,19 +5883,19 @@ ulonglong p_get_key_cache_stat_value(voi
wrappers must be used for this purpose.
*/
-static KEY_CACHE_FUNCS p_key_cache_funcs =
+static KEY_CACHE_FUNCS partitioned_key_cache_funcs =
{
- p_init_key_cache,
- p_resize_key_cache,
- p_change_key_cache_param,
- p_key_cache_read,
- p_key_cache_insert,
- p_key_cache_write,
- p_flush_key_blocks,
- p_reset_key_cache_counters,
- p_end_key_cache,
- p_get_key_cache_statistics,
- p_get_key_cache_stat_value
+ (INIT_KEY_CACHE) init_partitioned_key_cache,
+ (RESIZE_KEY_CACHE) resize_partitioned_key_cache,
+ (CHANGE_KEY_CACHE_PARAM) change_partitioned_key_cache_param,
+ (KEY_CACHE_READ) partitioned_key_cache_read,
+ (KEY_CACHE_INSERT) partitioned_key_cache_insert,
+ (KEY_CACHE_WRITE) partitioned_key_cache_write,
+ (FLUSH_KEY_BLOCKS) flush_partitioned_key_cache_blocks,
+ (RESET_KEY_CACHE_COUNTERS) reset_partitioned_key_cache_counters,
+ (END_KEY_CACHE) end_partitioned_key_cache,
+ (GET_KEY_CACHE_STATISTICS) get_partitioned_key_cache_statistics,
+ (GET_KEY_CACHE_STAT_VALUE) get_partitioned_key_cache_stat_value
};
@@ -5926,12 +5908,12 @@ static KEY_CACHE_FUNCS p_key_cache_funcs
partitioned key caches. Each type (class) has its own implementation of the
basic key cache operations used the MyISAM storage engine. The pointers
to the implementation functions are stored in two static structures of the
- type KEY_CACHE_FUNC: s_key_cache_funcs - for simple key caches, and
- p_key_cache_funcs - for partitioned key caches. When a key cache object is
- created the constructor procedure init_key_cache places a pointer to the
- corresponding table into one of its fields. The procedure also initializes
- a control block for the key cache oject and saves the pointer to this
- block in another field of the key cache object.
+ type KEY_CACHE_FUNC: simple_key_cache_funcs - for simple key caches, and
+ partitioned_key_cache_funcs - for partitioned key caches. When a key cache
+ object is created the constructor procedure init_key_cache places a pointer
+ to the corresponding table into one of its fields. The procedure also
+ initializes a control block for the key cache oject and saves the pointer
+ to this block in another field of the key cache object.
When a key cache wrapper function is invoked for a key cache object to
perform a basic key cache operation it looks into the interface table
associated with the key cache oject and calls the corresponding
@@ -5982,7 +5964,6 @@ static KEY_CACHE_FUNCS p_key_cache_funcs
It's assumed that no two threads call this function simultaneously
referring to the same key cache handle.
-
*/
int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
@@ -5997,19 +5978,21 @@ int init_key_cache(KEY_CACHE *keycache,
{
if (partitions == 0)
{
- if (!(keycache_cb= (void *) my_malloc(sizeof(S_KEY_CACHE_CB), MYF(0))))
+ if (!(keycache_cb= (void *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB),
+ MYF(0))))
return 0;
- ((S_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
+ ((SIMPLE_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
keycache->key_cache_type= SIMPLE_KEY_CACHE;
- keycache->interface_funcs= &s_key_cache_funcs;
+ keycache->interface_funcs= &simple_key_cache_funcs;
}
else
{
- if (!(keycache_cb= (void *) my_malloc(sizeof(P_KEY_CACHE_CB), MYF(0))))
+ if (!(keycache_cb= (void *) my_malloc(sizeof(PARTITIONED_KEY_CACHE_CB),
+ MYF(0))))
return 0;
- ((P_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
+ ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
keycache->key_cache_type= PARTITIONED_KEY_CACHE;
- keycache->interface_funcs= &p_key_cache_funcs;
+ keycache->interface_funcs= &partitioned_key_cache_funcs;
}
keycache->keycache_cb= keycache_cb;
keycache->key_cache_inited= 1;
@@ -6017,14 +6000,15 @@ int init_key_cache(KEY_CACHE *keycache,
if (partitions != 0)
{
- ((P_KEY_CACHE_CB *) keycache_cb)->partitions= partitions;
+ ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions= partitions;
}
keycache->can_be_used= 0;
blocks= keycache->interface_funcs->init(keycache_cb, key_cache_block_size,
use_mem, division_limit,
age_threshold);
keycache->partitions= partitions ?
- ((P_KEY_CACHE_CB *) keycache_cb)->partitions : 0;
+ ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions :
+ 0;
DBUG_ASSERT(partitions <= MAX_KEY_CACHE_PARTITIONS);
if (blocks > 0)
keycache->can_be_used= 1;
@@ -6037,7 +6021,7 @@ int init_key_cache(KEY_CACHE *keycache,
SYNOPSIS
resize_key_cache()
- keycache pointer to the key cache to be resized
+ keycache pointer to the key cache to be resized
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for the new key cache
division_limit new division limit (if not zero)
@@ -6064,7 +6048,6 @@ int init_key_cache(KEY_CACHE *keycache,
Currently the function is called when the values of the variables
key_buffer_size and/or key_cache_block_size are being reset for
the key cache keycache.
-
*/
int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
@@ -6074,10 +6057,10 @@ int resize_key_cache(KEY_CACHE *keycache
if (keycache->key_cache_inited)
{
if ((uint) keycache->param_partitions != keycache->partitions && use_mem)
- blocks= repartition_key_cache (keycache,
- key_cache_block_size, use_mem,
- division_limit, age_threshold,
- (uint) keycache->param_partitions);
+ blocks= repartition_key_cache(keycache,
+ key_cache_block_size, use_mem,
+ division_limit, age_threshold,
+ (uint) keycache->param_partitions);
else
{
blocks= keycache->interface_funcs->resize(keycache->keycache_cb,
@@ -6087,10 +6070,10 @@ int resize_key_cache(KEY_CACHE *keycache
if (keycache->partitions)
keycache->partitions=
- ((P_KEY_CACHE_CB *)(keycache->keycache_cb))->partitions;
+ ((PARTITIONED_KEY_CACHE_CB *)(keycache->keycache_cb))->partitions;
}
- if (blocks <= 0)
- keycache->can_be_used= 0;
+
+ keycache->can_be_used= (blocks >= 0);
}
return blocks;
}
@@ -6117,7 +6100,6 @@ int resize_key_cache(KEY_CACHE *keycache
Currently the function is called when the values of the variables
key_cache_division_limit and/or key_cache_age_threshold are being reset
for the key cache keycache.
-
*/
void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
@@ -6262,7 +6244,6 @@ uchar *key_cache_read(KEY_CACHE *keycach
the key cache.
It is assumed that it may be performed in parallel with reading the file
data from the key buffers by other threads.
-
*/
int key_cache_insert(KEY_CACHE *keycache,
@@ -6316,7 +6297,6 @@ int key_cache_insert(KEY_CACHE *keycache
NOTES
This implementation may exploit the fact that the function is called only
when a thread has got an exclusive lock for the key file.
-
*/
int key_cache_write(KEY_CACHE *keycache,
@@ -6373,7 +6353,6 @@ int key_cache_write(KEY_CACHE *keycache,
NOTES
Any implementation of the function may exploit the fact that the function
is called only when a thread has got an exclusive lock for the key file.
-
*/
int flush_key_blocks(KEY_CACHE *keycache,
@@ -6406,7 +6385,6 @@ int flush_key_blocks(KEY_CACHE *keycache
NOTES
This procedure is used by process_key_caches() to reset the counters of all
currently used key caches, both the default one and the named ones.
-
*/
int reset_key_cache_counters(const char *name __attribute__((unused)),
@@ -6441,13 +6419,11 @@ int reset_key_cache_counters(const char
RETURN
none
-
*/
void get_key_cache_statistics(KEY_CACHE *keycache, uint partition_no,
KEY_CACHE_STATISTICS *key_cache_stats)
{
- bzero(key_cache_stats, sizeof(KEY_CACHE_STATISTICS));
if (keycache->key_cache_inited)
{
keycache->interface_funcs->get_stats(keycache->keycache_cb,
@@ -6484,7 +6460,6 @@ void get_key_cache_statistics(KEY_CACHE
reads 4
write_requests 5
writes 6
-
*/
ulonglong get_key_cache_stat_value(KEY_CACHE *keycache, uint var_no)
@@ -6534,7 +6509,6 @@ ulonglong get_key_cache_stat_value(KEY_C
Currently the function is called when the value of the variable
key_cache_partitions is being reset for the key cache keycache.
-
*/
int repartition_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-03-29 21:16:12 +0000
+++ b/sql/sql_show.cc 2010-04-01 21:42:40 +0000
@@ -2235,8 +2235,9 @@ static void update_key_cache_stat_var(KE
case offsetof(KEY_CACHE, global_cache_read):
case offsetof(KEY_CACHE, global_cache_w_requests):
case offsetof(KEY_CACHE, global_cache_write):
- var_no= 3+(ofs-offsetof(KEY_CACHE, global_cache_w_requests))/
- sizeof(ulonglong);
+ var_no= NO_LONG_KEY_CACHE_STAT_VARIABLES +
+ (ofs-offsetof(KEY_CACHE, global_cache_w_requests))/
+ sizeof(ulonglong);
*(ulonglong *)((char *) key_cache + ofs)=
get_key_cache_stat_value(key_cache, var_no);
break;
@@ -6643,13 +6644,13 @@ int store_key_cache_table_record(THD *th
KEY_CACHE *key_cache,
uint partitions, uint partition_no)
{
- KEY_CACHE_STATISTICS key_cache_stats;
+ KEY_CACHE_STATISTICS keycache_stats;
uint err;
DBUG_ENTER("store_key_cache_table_record");
- get_key_cache_statistics(key_cache, partition_no, &key_cache_stats);
+ get_key_cache_statistics(key_cache, partition_no, &keycache_stats);
- if (key_cache_stats.mem_size == 0)
+ if (!key_cache->key_cache_inited || keycache_stats.mem_size == 0)
DBUG_RETURN(0);
restore_record(table, s->default_values);
@@ -6669,15 +6670,15 @@ int store_key_cache_table_record(THD *th
table->field[2]->set_notnull();
table->field[2]->store((long) partition_no, TRUE);
}
- table->field[3]->store(key_cache_stats.mem_size, TRUE);
- table->field[4]->store(key_cache_stats.block_size, TRUE);
- table->field[5]->store(key_cache_stats.blocks_used, TRUE);
- table->field[6]->store(key_cache_stats.blocks_unused, TRUE);
- table->field[7]->store(key_cache_stats.blocks_changed, TRUE);
- table->field[8]->store(key_cache_stats.read_requests, TRUE);
- table->field[9]->store(key_cache_stats.reads, TRUE);
- table->field[10]->store(key_cache_stats.write_requests, TRUE);
- table->field[11]->store(key_cache_stats.writes, TRUE);
+ table->field[3]->store(keycache_stats.mem_size, TRUE);
+ table->field[4]->store(keycache_stats.block_size, TRUE);
+ table->field[5]->store(keycache_stats.blocks_used, TRUE);
+ table->field[6]->store(keycache_stats.blocks_unused, TRUE);
+ table->field[7]->store(keycache_stats.blocks_changed, TRUE);
+ table->field[8]->store(keycache_stats.read_requests, TRUE);
+ table->field[9]->store(keycache_stats.reads, TRUE);
+ table->field[10]->store(keycache_stats.write_requests, TRUE);
+ table->field[11]->store(keycache_stats.writes, TRUE);
err= schema_table_store_record(thd, table);
DBUG_RETURN(err);
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2747)
by Igor Babaev 02 Apr '10
by Igor Babaev 02 Apr '10
02 Apr '10
#At lp:maria/5.2 based on revid:igor@askmonty.org-20100331233728-obczp1ecrffnaa2s
2747 Igor Babaev 2010-04-01
Post-review fixes.
modified:
include/keycache.h
mysql-test/r/key_cache.result
mysql-test/t/key_cache.test
mysys/mf_keycache.c
sql/sql_show.cc
=== modified file 'include/keycache.h'
--- a/include/keycache.h 2010-02-16 16:41:11 +0000
+++ b/include/keycache.h 2010-04-01 21:26:08 +0000
@@ -37,7 +37,6 @@ C_MODE_START
#define MAX_KEY_CACHE_PARTITIONS 64
-
/* The structure to get statistical data about a key cache */
typedef struct st_key_cache_statistics
@@ -53,6 +52,8 @@ typedef struct st_key_cache_statistics
ulonglong writes; /* number of actual writes from buffers into files */
} KEY_CACHE_STATISTICS;
+#define NO_LONG_KEY_CACHE_STAT_VARIABLES 3
+
/* The type of a key cache object */
typedef enum key_cache_type
{
@@ -61,6 +62,55 @@ typedef enum key_cache_type
} KEY_CACHE_TYPE;
+typedef
+ int (*INIT_KEY_CACHE)
+ (void *, uint key_cache_block_size,
+ size_t use_mem, uint division_limit, uint age_threshold);
+typedef
+ int (*RESIZE_KEY_CACHE)
+ (void *, uint key_cache_block_size,
+ size_t use_mem, uint division_limit, uint age_threshold);
+typedef
+ void (*CHANGE_KEY_CACHE_PARAM)
+ (void *keycache_cb,
+ uint division_limit, uint age_threshold);
+typedef
+ uchar* (*KEY_CACHE_READ)
+ (void *keycache_cb,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length, int return_buffer);
+typedef
+ int (*KEY_CACHE_INSERT)
+ (void *keycache_cb,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length);
+typedef
+ int (*KEY_CACHE_WRITE)
+ (void *keycache_cb,
+ File file, void *file_extra,
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length, int force_write);
+typedef
+ int (*FLUSH_KEY_BLOCKS)
+ (void *keycache_cb,
+ int file, void *file_extra,
+ enum flush_type type);
+typedef
+ int (*RESET_KEY_CACHE_COUNTERS)
+ (const char *name, void *keycache_cb);
+typedef
+ void (*END_KEY_CACHE)
+ (void *keycache_cb, my_bool cleanup);
+typedef
+ void (*GET_KEY_CACHE_STATISTICS)
+ (void *keycache_cb, uint partition_no,
+ KEY_CACHE_STATISTICS *key_cache_stats);
+typedef
+ ulonglong (*GET_KEY_CACHE_STAT_VALUE)
+ (void *keycache_cb, uint var_no);
+
/*
An object of the type KEY_CACHE_FUNCS contains pointers to all functions
from the key cache interface.
@@ -74,32 +124,17 @@ typedef enum key_cache_type
typedef struct st_key_cache_funcs
{
- int (*init) (void *, uint key_cache_block_size,
- size_t use_mem, uint division_limit, uint age_threshold);
- int (*resize) (void *, uint key_cache_block_size,
- size_t use_mem, uint division_limit, uint age_threshold);
- void (*change_param) (void *keycache_cb,
- uint division_limit, uint age_threshold);
- uchar* (*read) (void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length, int return_buffer);
- int (*insert) (void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length);
- int (*write) (void *keycache_cb,
- File file, void *file_extra,
- my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length, int force_write);
- int (*flush) (void *keycache_cb,
- int file, void *file_extra,
- enum flush_type type);
- int (*reset_counters) (const char *name, void *keycache_cb);
- void (*end) (void *keycache_cb, my_bool cleanup);
- void (*get_stats) (void *keycache_cb, uint partition_no,
- KEY_CACHE_STATISTICS *key_cache_stats);
- ulonglong (*get_stat_val) (void *keycache_cb, uint var_no);
+ INIT_KEY_CACHE init;
+ RESIZE_KEY_CACHE resize;
+ CHANGE_KEY_CACHE_PARAM change_param;
+ KEY_CACHE_READ read;
+ KEY_CACHE_INSERT insert;
+ KEY_CACHE_WRITE write;
+ FLUSH_KEY_BLOCKS flush;
+ RESET_KEY_CACHE_COUNTERS reset_counters;
+ END_KEY_CACHE end;
+ GET_KEY_CACHE_STATISTICS get_stats;
+ GET_KEY_CACHE_STAT_VALUE get_stat_val;
} KEY_CACHE_FUNCS;
=== modified file 'mysql-test/r/key_cache.result'
--- a/mysql-test/r/key_cache.result 2010-03-31 23:37:28 +0000
+++ b/mysql-test/r/key_cache.result 2010-04-01 21:26:08 +0000
@@ -672,12 +672,12 @@ insert into t2 values (2000, 3, 'yyyy');
select * from information_schema.key_caches where key_cache_name like "keycache2"
and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache2 NULL NULL 1048576 1024 0 # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3
select * from information_schema.key_caches where key_cache_name like "key%"
and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19
-keycache2 NULL NULL 1048576 1024 0 # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 6 # 0 6 6 3 3
cache index t2 in keycache1;
Table Op Msg_type Msg_text
test.t2 assign_to_keycache status OK
@@ -718,7 +718,7 @@ KEY_CACHE_NAME PARTITIONS PARTITION_NUMB
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 3201 43 1594 30
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=2*1024;
insert into t2 values (7000, 3, 'yyyy');
select * from information_schema.key_caches where partition_number is null;
@@ -726,66 +726,72 @@ KEY_CACHE_NAME PARTITIONS PARTITION_NUMB
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 6 6 3 3
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=8*1024;
+select * from information_schema.key_caches where partition_number is null;
+KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
+default 2 NULL 32768 1024 # # 0 3172 24 1552 18
+small NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache1 3 NULL 262143 8192 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
insert into t2 values (8000, 3, 'yyyy');
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 3 NULL 262143 8192 # # 0 6 5 3 3
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_buffer_size=64*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=2*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 3 NULL 65535 2048 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=8*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_buffer_size=0;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=8*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_buffer_size=0;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_buffer_size=128*1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 1 NULL 131072 8192 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=1024;
select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 7 NULL 131068 1024 # # 0 0 0 0 0
-keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
+keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
drop table t1,t2;
set global keycache1.key_buffer_size=0;
set global keycache2.key_buffer_size=0;
=== modified file 'mysql-test/t/key_cache.test'
--- a/mysql-test/t/key_cache.test 2010-03-31 23:37:28 +0000
+++ b/mysql-test/t/key_cache.test 2010-04-01 21:26:08 +0000
@@ -469,6 +469,8 @@ insert into t2 values (7000, 3, 'yyyy');
select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=8*1024;
+--replace_column 6 # 7 #
+select * from information_schema.key_caches where partition_number is null;
insert into t2 values (8000, 3, 'yyyy');
--replace_column 6 # 7 #
select * from information_schema.key_caches where partition_number is null;
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2010-02-16 16:41:11 +0000
+++ b/mysys/mf_keycache.c 2010-04-01 21:26:08 +0000
@@ -49,6 +49,7 @@
One cache can handle many files.
It must contain buffers of the same blocksize.
+
init_key_cache() should be used to init cache handler.
The free list (free_block_list) is a stack like structure.
@@ -151,7 +152,7 @@ typedef struct st_keycache_wqueue
/* Control block for a simple (non-partitioned) key cache */
-typedef struct st_s_key_cache_cb
+typedef struct st_simple_key_cache_cb
{
my_bool key_cache_inited; /* <=> control block is allocated */
my_bool in_resize; /* true during resize operation */
@@ -202,7 +203,7 @@ typedef struct st_s_key_cache_cb
int blocks; /* max number of blocks in the cache */
uint hash_factor; /* factor used to calculate hash function */
my_bool in_init; /* Set to 1 in MySQL during init/resize */
-} S_KEY_CACHE_CB;
+} SIMPLE_KEY_CACHE_CB;
/*
Some compilation flags have been added specifically for this module
@@ -314,12 +315,8 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cac
#define FLUSH_CACHE 2000 /* sort this many blocks at once */
-static int flush_all_key_blocks(S_KEY_CACHE_CB *keycache);
-/*
-static void s_change_key_cache_param(void *keycache_cb, uint division_limit,
- uint age_threshold);
-*/
-static void s_end_key_cache(void *keycache_cb, my_bool cleanup);
+static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache);
+static void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup);
#ifdef THREAD
static void wait_on_queue(KEYCACHE_WQUEUE *wqueue,
pthread_mutex_t *mutex);
@@ -328,9 +325,9 @@ static void release_whole_queue(KEYCACHE
#define wait_on_queue(wqueue, mutex) do {} while (0)
#define release_whole_queue(wqueue) do {} while (0)
#endif
-static void free_block(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block);
+static void free_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block);
#if !defined(DBUG_OFF)
-static void test_key_cache(S_KEY_CACHE_CB *keycache,
+static void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
const char *where, my_bool lock);
#endif
#define KEYCACHE_BASE_EXPR(f, pos) \
@@ -433,7 +430,7 @@ static int keycache_pthread_cond_signal(
#define inline /* disabled inline for easier debugging */
static int fail_block(BLOCK_LINK *block);
static int fail_hlink(HASH_LINK *hlink);
-static int cache_empty(S_KEY_CACHE_CB *keycache);
+static int cache_empty(SIMPLE_KEY_CACHE_CB *keycache);
#endif
@@ -447,8 +444,8 @@ static inline uint next_power(uint value
Initialize a simple key cache
SYNOPSIS
- s_init_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ init_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
key_cache_block_size size of blocks to keep cached data
use_mem memory to use for the key cache buferrs/structures
division_limit division limit (may be zero)
@@ -458,8 +455,8 @@ static inline uint next_power(uint value
This function is the implementation of the init_key_cache interface
function that is employed by simple (non-partitioned) key caches.
The function builds a simple key cache and initializes the control block
- structure of the type S_KEY_CACHE_CB that is used for this key cache.
- The parameter keycache_cb is supposed to point to this structure.
+ structure of the type SIMPLE_KEY_CACHE_CB that is used for this key cache.
+ The parameter keycache is supposed to point to this structure.
The parameter key_cache_block_size specifies the size of the blocks in
the key cache to be built. The parameters division_limit and age_threshhold
determine the initial values of those characteristics of the key cache
@@ -478,19 +475,17 @@ static inline uint next_power(uint value
It's assumed that no two threads call this function simultaneously
referring to the same key cache handle.
-
*/
static
-int s_init_key_cache(void *keycache_cb, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
ulong blocks, hash_links;
size_t length;
int error;
- DBUG_ENTER("init_key_cache");
+ DBUG_ENTER("init_simple_key_cache");
DBUG_ASSERT(key_cache_block_size >= 512);
KEYCACHE_DEBUG_OPEN;
@@ -653,16 +648,16 @@ err:
Prepare for resizing a simple key cache
SYNOPSIS
- s_prepare_resize_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ prepare_resize_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
with_resize_queue <=> resize queue is used
release_lock <=> release the key cache lock before return
DESCRIPTION
This function flushes all dirty pages from a simple key cache and after
- this it destroys the key cache calling s_end_key_cache. The function
- considers the parameter keycache_cb as a pointer to the control block
- structure of the type S_KEY_CACHE_CB for this key cache.
+ this it destroys the key cache calling end_simple_key_cache. The function
+ takes the parameter keycache as a pointer to the control block
+ structure of the type SIMPLE_KEY_CACHE_CB for this key cache.
The parameter with_resize_queue determines weather the resize queue is
involved (MySQL server never uses this queue). The parameter release_lock
says weather the key cache lock must be released before return from
@@ -673,19 +668,18 @@ err:
1 - otherwise.
NOTES
- This function is the called by s_resize_key_cache and p_resize_key_cache
- that resize simple and partitioned key caches respectively.
-
+ This function is the called by resize_simple_key_cache and
+ resize_partitioned_key_cache that resize simple and partitioned key caches
+ respectively.
*/
static
-int s_prepare_resize_key_cache(void *keycache_cb,
- my_bool with_resize_queue,
- my_bool release_lock)
+int prepare_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
+ my_bool with_resize_queue,
+ my_bool release_lock)
{
int res= 0;
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_prepare_resize_key_cache");
+ DBUG_ENTER("prepare_resize_simple_key_cache");
keycache_pthread_mutex_lock(&keycache->cache_lock);
@@ -749,7 +743,7 @@ int s_prepare_resize_key_cache(void *key
KEYCACHE_DBUG_ASSERT(keycache->cnt_for_resize_op == 0);
#endif
- s_end_key_cache(keycache_cb, 0);
+ end_simple_key_cache(keycache, 0);
finish:
if (release_lock)
@@ -762,16 +756,16 @@ finish:
Finalize resizing a simple key cache
SYNOPSIS
- s_finish_resize_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ finish_resize_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
with_resize_queue <=> resize queue is used
acquire_lock <=> acquire the key cache lock at start
DESCRIPTION
This function performs finalizing actions for the operation of
- resizing a simple key cache. The function considers the parameter
- keycache_cb as a pointer to the control block structure of the type
- S_KEY_CACHE_CB for this key cache. The function sets the flag
+ resizing a simple key cache. The function takes the parameter
+ keycache as a pointer to the control block structure of the type
+ SIMPLE_KEY_CACHE_CB for this key cache. The function sets the flag
in_resize in this structure to FALSE.
The parameter with_resize_queue determines weather the resize queue
is involved (MySQL server never uses this queue).
@@ -782,22 +776,24 @@ finish:
none
NOTES
- This function is the called by s_resize_key_cache and p_resize_key_cache
- that resize simple and partitioned key caches respectively.
+ This function is the called by resize_simple_key_cache and
+ resize_partitioned_key_cache that resize simple and partitioned key caches
+ respectively.
*/
static
-void s_finish_resize_key_cache(void *keycache_cb,
- my_bool with_resize_queue,
- my_bool acquire_lock)
+void finish_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
+ my_bool with_resize_queue,
+ my_bool acquire_lock)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_finish_resize_key_cache");
+ DBUG_ENTER("finish_resize_simple_key_cache");
if (acquire_lock)
keycache_pthread_mutex_lock(&keycache->cache_lock);
-
+
+ safe_mutex_assert_owner(&keycache->cache_lock);
+
/*
Mark the resize finished. This allows other threads to start a
resize or to request new cache blocks.
@@ -820,8 +816,8 @@ void s_finish_resize_key_cache(void *key
Resize a simple key cache
SYNOPSIS
- s_resize_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ resize_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
key_cache_block_size size of blocks to keep cached data
use_mem memory to use for the key cache buffers/structures
division_limit new division limit (if not zero)
@@ -830,8 +826,8 @@ void s_finish_resize_key_cache(void *key
DESCRIPTION
This function is the implementation of the resize_key_cache interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for the simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key
cache to be resized.
The parameter key_cache_block_size specifies the new size of the blocks in
the key cache. The parameters division_limit and age_threshold
@@ -845,14 +841,14 @@ void s_finish_resize_key_cache(void *key
0 - otherwise.
NOTES.
- The function first calls the function s_prepare_resize_key_cache
+ The function first calls the function prepare_resize_simple_key_cache
to flush all dirty blocks from key cache, to free memory used
for key cache blocks and auxiliary structures. After this the
function builds a new key cache with new parameters.
This implementation doesn't block the calls and executions of other
functions from the key cache interface. However it assumes that the
- calls of s_resize_key_cache itself are serialized.
+ calls of resize_simple_key_cache itself are serialized.
The function starts the operation only when all other threads
performing operations with the key cache let her to proceed
@@ -861,31 +857,30 @@ void s_finish_resize_key_cache(void *key
*/
static
-int s_resize_key_cache(void *keycache_cb, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+int resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
int blocks= 0;
- DBUG_ENTER("s_resize_key_cache");
+ DBUG_ENTER("resize_simple_key_cache");
if (!keycache->key_cache_inited)
- DBUG_RETURN(keycache->disk_blocks);
+ DBUG_RETURN(blocks);
/*
Note that the cache_lock mutex and the resize_queue are left untouched.
We do not lose the cache_lock and will release it only at the end of
this function.
*/
- if (s_prepare_resize_key_cache(keycache_cb, 1, 0))
+ if (prepare_resize_simple_key_cache(keycache, 1, 0))
goto finish;
/* The following will work even if use_mem is 0 */
- blocks= s_init_key_cache(keycache, key_cache_block_size, use_mem,
- division_limit, age_threshold);
+ blocks= init_simple_key_cache(keycache, key_cache_block_size, use_mem,
+ division_limit, age_threshold);
finish:
- s_finish_resize_key_cache(keycache_cb, 1, 0);
+ finish_resize_simple_key_cache(keycache, 1, 0);
DBUG_RETURN(blocks);
}
@@ -894,7 +889,7 @@ finish:
/*
Increment counter blocking resize key cache operation
*/
-static inline void inc_counter_for_resize_op(S_KEY_CACHE_CB *keycache)
+static inline void inc_counter_for_resize_op(SIMPLE_KEY_CACHE_CB *keycache)
{
keycache->cnt_for_resize_op++;
}
@@ -904,7 +899,7 @@ static inline void inc_counter_for_resiz
Decrement counter blocking resize key cache operation;
Signal the operation to proceed when counter becomes equal zero
*/
-static inline void dec_counter_for_resize_op(S_KEY_CACHE_CB *keycache)
+static inline void dec_counter_for_resize_op(SIMPLE_KEY_CACHE_CB *keycache)
{
if (!--keycache->cnt_for_resize_op)
release_whole_queue(&keycache->waiting_for_resize_cnt);
@@ -915,16 +910,16 @@ static inline void dec_counter_for_resiz
Change key cache parameters of a simple key cache
SYNOPSIS
- s_change_key_cache_param()
- keycache_cb pointer to the control block of a simple key cache
+ change_simple_key_cache_param()
+ keycache pointer to the control block of a simple key cache
division_limit new division limit (if not zero)
age_threshold new age threshold (if not zero)
DESCRIPTION
This function is the implementation of the change_key_cache_param interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for the simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key
cache where new values of the division limit and the age threshold used
for midpoint insertion strategy are to be set. The parameters
division_limit and age_threshold provide these new values.
@@ -942,11 +937,10 @@ static inline void dec_counter_for_resiz
*/
static
-void s_change_key_cache_param(void *keycache_cb, uint division_limit,
- uint age_threshold)
+void change_simple_key_cache_param(SIMPLE_KEY_CACHE_CB *keycache, uint division_limit,
+ uint age_threshold)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_change_key_cache_param");
+ DBUG_ENTER("change_simple_key_cache_param");
keycache_pthread_mutex_lock(&keycache->cache_lock);
if (division_limit)
keycache->min_warm_blocks= (keycache->disk_blocks *
@@ -963,15 +957,15 @@ void s_change_key_cache_param(void *keyc
Destroy a simple key cache
SYNOPSIS
- s_end_key_cache()
- keycache_cb pointer to the control block of a simple key cache
+ end_simple_key_cache()
+ keycache pointer to the control block of a simple key cache
cleanup <=> complete free (free also mutex for key cache)
DESCRIPTION
This function is the implementation of the end_key_cache interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for the simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for the simple key
cache to be destroyed.
The function frees the memory allocated for the key cache blocks and
auxiliary structures. If the value of the parameter cleanup is TRUE
@@ -982,10 +976,9 @@ void s_change_key_cache_param(void *keyc
*/
static
-void s_end_key_cache(void *keycache_cb, my_bool cleanup)
+void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_end_key_cache");
+ DBUG_ENTER("end_simple_key_cache");
DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache));
if (!keycache->key_cache_inited)
@@ -1276,7 +1269,7 @@ static inline void link_changed(BLOCK_LI
void
*/
-static void link_to_file_list(S_KEY_CACHE_CB *keycache,
+static void link_to_file_list(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block, int file,
my_bool unlink_block)
{
@@ -1317,7 +1310,7 @@ static void link_to_file_list(S_KEY_CACH
void
*/
-static void link_to_changed_list(S_KEY_CACHE_CB *keycache,
+static void link_to_changed_list(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block)
{
DBUG_ASSERT(block->status & BLOCK_IN_USE);
@@ -1372,8 +1365,8 @@ static void link_to_changed_list(S_KEY_C
not linked in the LRU ring.
*/
-static void link_block(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block, my_bool hot,
- my_bool at_end)
+static void link_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block,
+ my_bool hot, my_bool at_end)
{
BLOCK_LINK *ins;
BLOCK_LINK **pins;
@@ -1493,7 +1486,7 @@ static void link_block(S_KEY_CACHE_CB *k
See NOTES for link_block
*/
-static void unlink_block(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
+static void unlink_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
{
DBUG_ASSERT((block->status & ~BLOCK_CHANGED) == (BLOCK_READ | BLOCK_IN_USE));
DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/
@@ -1551,7 +1544,8 @@ static void unlink_block(S_KEY_CACHE_CB
RETURN
void
*/
-static void reg_requests(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block, int count)
+static void reg_requests(SIMPLE_KEY_CACHE_CB *keycache,
+ BLOCK_LINK *block, int count)
{
DBUG_ASSERT(block->status & BLOCK_IN_USE);
DBUG_ASSERT(block->hash_link);
@@ -1594,7 +1588,7 @@ static void reg_requests(S_KEY_CACHE_CB
not linked in the LRU ring.
*/
-static void unreg_request(S_KEY_CACHE_CB *keycache,
+static void unreg_request(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block, int at_end)
{
DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
@@ -1683,7 +1677,7 @@ static void remove_reader(BLOCK_LINK *bl
signals on its termination
*/
-static void wait_for_readers(S_KEY_CACHE_CB *keycache,
+static void wait_for_readers(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block)
{
#ifdef THREAD
@@ -1732,7 +1726,7 @@ static inline void link_hash(HASH_LINK *
Remove a hash link from the hash table
*/
-static void unlink_hash(S_KEY_CACHE_CB *keycache, HASH_LINK *hash_link)
+static void unlink_hash(SIMPLE_KEY_CACHE_CB *keycache, HASH_LINK *hash_link)
{
KEYCACHE_DBUG_PRINT("unlink_hash", ("fd: %u pos_ %lu #requests=%u",
(uint) hash_link->file,(ulong) hash_link->diskpos, hash_link->requests));
@@ -1788,7 +1782,7 @@ static void unlink_hash(S_KEY_CACHE_CB *
Get the hash link for a page
*/
-static HASH_LINK *get_hash_link(S_KEY_CACHE_CB *keycache,
+static HASH_LINK *get_hash_link(SIMPLE_KEY_CACHE_CB *keycache,
int file, my_off_t filepos)
{
reg1 HASH_LINK *hash_link, **start;
@@ -1909,7 +1903,7 @@ restart:
waits until first of this operations links any block back.
*/
-static BLOCK_LINK *find_key_block(S_KEY_CACHE_CB *keycache,
+static BLOCK_LINK *find_key_block(SIMPLE_KEY_CACHE_CB *keycache,
File file, my_off_t filepos,
int init_hits_left,
int wrmode, int *page_st)
@@ -2669,7 +2663,7 @@ restart:
portion is less than read_length, but not less than min_length.
*/
-static void read_block(S_KEY_CACHE_CB *keycache,
+static void read_block(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block, uint read_length,
uint min_length, my_bool primary)
{
@@ -2761,8 +2755,8 @@ static void read_block(S_KEY_CACHE_CB *k
SYNOPSIS
- s_key_cache_read()
- keycache_cb pointer to the control block of a simple key cache
+ simple_key_cache_read()
+ keycache pointer to the control block of a simple key cache
file handler for the file for the block of data to be read
filepos position of the block of data in the file
level determines the weight of the data
@@ -2774,8 +2768,8 @@ static void read_block(S_KEY_CACHE_CB *k
DESCRIPTION
This function is the implementation of the key_cache_read interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
cache.
In a general case the function reads a block of data from the key cache
into the buffer buff of the size specified by the parameter length. The
@@ -2802,17 +2796,16 @@ static void read_block(S_KEY_CACHE_CB *k
*/
-uchar *s_key_cache_read(void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int return_buffer __attribute__((unused)))
+uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int return_buffer __attribute__((unused)))
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
my_bool locked_and_incremented= FALSE;
int error=0;
uchar *start= buff;
- DBUG_ENTER("s_key_cache_read");
+ DBUG_ENTER("simple_key_cache_read");
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
(uint) file, (ulong) filepos, length));
@@ -3010,8 +3003,8 @@ end:
Insert a block of file data from a buffer into a simple key cache
SYNOPSIS
- s_key_cache_insert()
- keycache_cb pointer to the control block of a simple key cache
+ simple_key_cache_insert()
+ keycache pointer to the control block of a simple key cache
file handler for the file to insert data from
filepos position of the block of data in the file to insert
level determines the weight of the data
@@ -3021,8 +3014,8 @@ end:
DESCRIPTION
This function is the implementation of the key_cache_insert interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
cache.
The function writes a block of file data from a buffer into the key cache.
The buffer is specified with the parameters buff and length - the pointer
@@ -3045,11 +3038,10 @@ end:
*/
static
-int s_key_cache_insert(void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length)
+int simple_key_cache_insert(SIMPLE_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
int error= 0;
DBUG_ENTER("key_cache_insert");
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
@@ -3272,8 +3264,8 @@ int s_key_cache_insert(void *keycache_cb
SYNOPSIS
- s_key_cache_write()
- keycache_cb pointer to the control block of a simple key cache
+ simple_key_cache_write()
+ keycache pointer to the control block of a simple key cache
file handler for the file to write data to
file_extra maps of key cache partitions containing
dirty pages from file
@@ -3287,8 +3279,8 @@ int s_key_cache_insert(void *keycache_cb
DESCRIPTION
This function is the implementation of the key_cache_write interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
cache.
In a general case the function copies data from a buffer into the key
cache. The buffer is specified with the parameters buff and length -
@@ -3304,7 +3296,8 @@ int s_key_cache_insert(void *keycache_cb
The parameter file_extra currently makes sense only for simple key caches
that are elements of a partitioned key cache. It provides a pointer to the
shared bitmap of the partitions that may contains dirty pages for the file.
- This bitmap is used to optimize the function p_flush_key_blocks.
+ This bitmap is used to optimize the function
+ flush_partitioned_key_cache_blocks.
RETURN VALUE
0 if a success, 1 - otherwise.
@@ -3316,17 +3309,16 @@ int s_key_cache_insert(void *keycache_cb
*/
static
-int s_key_cache_write(void *keycache_cb,
- File file, void *file_extra __attribute__((unused)),
- my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int dont_write)
+int simple_key_cache_write(SIMPLE_KEY_CACHE_CB *keycache,
+ File file, void *file_extra __attribute__((unused)),
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int dont_write)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
my_bool locked_and_incremented= FALSE;
int error=0;
- DBUG_ENTER("s_key_cache_write");
+ DBUG_ENTER("simple_key_cache_write");
DBUG_PRINT("enter",
("fd: %u pos: %lu length: %u block_length: %u"
" key_block_length: %u",
@@ -3641,7 +3633,7 @@ end:
Block must have a request registered on it.
*/
-static void free_block(S_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
+static void free_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block)
{
KEYCACHE_THREAD_TRACE("free block");
KEYCACHE_DBUG_PRINT("free_block",
@@ -3781,7 +3773,7 @@ static int cmp_sec_link(BLOCK_LINK **a,
free used blocks if requested
*/
-static int flush_cached_blocks(S_KEY_CACHE_CB *keycache,
+static int flush_cached_blocks(SIMPLE_KEY_CACHE_CB *keycache,
File file, BLOCK_LINK **cache,
BLOCK_LINK **end,
enum flush_type type)
@@ -3909,7 +3901,7 @@ static int flush_cached_blocks(S_KEY_CAC
1 error
*/
-static int flush_key_blocks_int(S_KEY_CACHE_CB *keycache,
+static int flush_key_blocks_int(SIMPLE_KEY_CACHE_CB *keycache,
File file, enum flush_type type)
{
BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache;
@@ -4349,8 +4341,8 @@ err:
SYNOPSIS
- s_flush_key_blocks()
- keycache_cb pointer to the control block of a simple key cache
+ flush_simple_key_blocks()
+ keycache pointer to the control block of a simple key cache
file handler for the file to flush to
file_extra maps of key cache partitions containing
dirty pages from file (not used)
@@ -4359,7 +4351,7 @@ err:
DESCRIPTION
This function is the implementation of the flush_key_blocks interface
function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
+ The function takes the parameter keycache as a pointer to the
control block structure of the type S_KEY_CACHE_CB for a simple key
cache.
In a general case the function flushes the data from all dirty key
@@ -4382,12 +4374,11 @@ err:
*/
static
-int s_flush_key_blocks(void *keycache_cb,
- File file,
- void *file_extra __attribute__((unused)),
- enum flush_type type)
+int flush_simple_key_cache_blocks(SIMPLE_KEY_CACHE_CB *keycache,
+ File file,
+ void *file_extra __attribute__((unused)),
+ enum flush_type type)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
int res= 0;
DBUG_ENTER("flush_key_blocks");
DBUG_PRINT("enter", ("keycache: 0x%lx", (long) keycache));
@@ -4440,7 +4431,7 @@ int s_flush_key_blocks(void *keycache_cb
!= 0 Error
*/
-static int flush_all_key_blocks(S_KEY_CACHE_CB *keycache)
+static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
{
BLOCK_LINK *block;
uint total_found;
@@ -4546,14 +4537,14 @@ static int flush_all_key_blocks(S_KEY_CA
Reset the counters of a simple key cache
SYNOPSIS
- s_reset_key_cache_counters()
+ reset_simple_key_cache_counters()
name the name of a key cache
- keycache_cb pointer to the control block of a simple key cache
+ keycache pointer to the control block of a simple key cache
DESCRIPTION
This function is the implementation of the reset_key_cache_counters
interface function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
+ The function takes the parameter keycache as a pointer to the
control block structure of the type S_KEY_CACHE_CB for a simple key cache.
This function resets the values of all statistical counters for the key
cache to 0.
@@ -4565,11 +4556,10 @@ static int flush_all_key_blocks(S_KEY_CA
*/
static
-int s_reset_key_cache_counters(const char *name __attribute__((unused)),
- void *keycache_cb)
+int reset_simple_key_cache_counters(const char *name __attribute__((unused)),
+ SIMPLE_KEY_CACHE_CB *keycache)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_reset_key_cache_counters");
+ DBUG_ENTER("reset_simple_key_cache_counters");
if (!keycache->key_cache_inited)
{
DBUG_PRINT("info", ("Key cache %s not initialized.", name));
@@ -4590,9 +4580,10 @@ int s_reset_key_cache_counters(const cha
/*
Test if disk-cache is ok
*/
-static void test_key_cache(S_KEY_CACHE_CB *keycache __attribute__((unused)),
- const char *where __attribute__((unused)),
- my_bool lock __attribute__((unused)))
+static
+void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache __attribute__((unused)),
+ const char *where __attribute__((unused)),
+ my_bool lock __attribute__((unused)))
{
/* TODO */
}
@@ -4604,7 +4595,7 @@ static void test_key_cache(S_KEY_CACHE_C
#define MAX_QUEUE_LEN 100
-static void keycache_dump(S_KEY_CACHE_CB *keycache)
+static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache)
{
FILE *keycache_dump_file=fopen(KEYCACHE_DUMP_FILE, "w");
struct st_my_thread_var *last;
@@ -4844,7 +4835,7 @@ static int fail_hlink(HASH_LINK *hlink)
return 0; /* Let the assert fail. */
}
-static int cache_empty(S_KEY_CACHE_CB *keycache)
+static int cache_empty(SIMPLE_KEY_CACHE_CB *keycache)
{
int errcnt= 0;
int idx;
@@ -4887,54 +4878,57 @@ static int cache_empty(S_KEY_CACHE_CB *k
Get statistics for a simple key cache
SYNOPSIS
- get_key_cache_statistics()
- keycache_cb pointer to the control block of a simple key cache
+ get_simple_key_cache_statistics()
+ keycache pointer to the control block of a simple key cache
partition_no partition number (not used)
key_cache_stats OUT pointer to the structure for the returned statistics
DESCRIPTION
This function is the implementation of the get_key_cache_statistics
interface function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key cache.
- This function returns the statistical data for the key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
+ cache. This function returns the statistical data for the key cache.
The parameter partition_no is not used by this function.
RETURN
none
-
*/
static
-void s_get_key_cache_statistics(void *keycache_cb,
- uint partition_no __attribute__((unused)),
- KEY_CACHE_STATISTICS *key_cache_stats)
-{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- DBUG_ENTER("s_get_key_cache_statistics");
-
- key_cache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
- key_cache_stats->block_size= (longlong) keycache->key_cache_block_size;
- key_cache_stats->blocks_used= keycache->blocks_used;
- key_cache_stats->blocks_unused= keycache->blocks_unused;
- key_cache_stats->blocks_changed= keycache->global_blocks_changed;
- key_cache_stats->read_requests= keycache->global_cache_r_requests;
- key_cache_stats->reads= keycache->global_cache_read;
- key_cache_stats->write_requests= keycache->global_cache_w_requests;
- key_cache_stats->writes= keycache->global_cache_write;
+void get_simple_key_cache_statistics(SIMPLE_KEY_CACHE_CB *keycache,
+ uint partition_no __attribute__((unused)),
+ KEY_CACHE_STATISTICS *keycache_stats)
+{
+ DBUG_ENTER("simple_get_key_cache_statistics");
+
+ keycache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
+ keycache_stats->block_size= (longlong) keycache->key_cache_block_size;
+ keycache_stats->blocks_used= keycache->blocks_used;
+ keycache_stats->blocks_unused= keycache->blocks_unused;
+ keycache_stats->blocks_changed= keycache->global_blocks_changed;
+ keycache_stats->read_requests= keycache->global_cache_r_requests;
+ keycache_stats->reads= keycache->global_cache_read;
+ keycache_stats->write_requests= keycache->global_cache_w_requests;
+ keycache_stats->writes= keycache->global_cache_write;
DBUG_VOID_RETURN;
}
-static size_t s_key_cache_stat_var_offsets[]=
+/*
+ Offsets of the statistical values in the control block for a simple key cache
+ The first NO_LONG_KEY_CACHE_STAT_VARIABLES=3 are of the ulong type while the
+ remaining are of the ulonglong type.
+ */
+static size_t simple_key_cache_stat_var_offsets[]=
{
- offsetof(S_KEY_CACHE_CB, blocks_used),
- offsetof(S_KEY_CACHE_CB, blocks_unused),
- offsetof(S_KEY_CACHE_CB, global_blocks_changed),
- offsetof(S_KEY_CACHE_CB, global_cache_w_requests),
- offsetof(S_KEY_CACHE_CB, global_cache_write),
- offsetof(S_KEY_CACHE_CB, global_cache_r_requests),
- offsetof(S_KEY_CACHE_CB, global_cache_read)
+ offsetof(SIMPLE_KEY_CACHE_CB, blocks_used),
+ offsetof(SIMPLE_KEY_CACHE_CB, blocks_unused),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_blocks_changed),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_w_requests),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_write),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_r_requests),
+ offsetof(SIMPLE_KEY_CACHE_CB, global_cache_read)
};
@@ -4942,16 +4936,16 @@ static size_t s_key_cache_stat_var_offse
Get the value of a statistical variable for a simple key cache
SYNOPSIS
- s_get_key_cache_stat_value()
- keycache_cb pointer to the control block of a simple key cache
+ get_simple_key_cache_stat_value()
+ keycache pointer to the control block of a simple key cache
var_no the ordered number of a statistical variable
DESCRIPTION
- This function is the implementation of the s_get_key_cache_stat_value
+ This function is the implementation of the get_simple_key_cache_stat_value
interface function that is employed by simple (non-partitioned) key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type S_KEY_CACHE_CB for a simple key cache.
- This function returns the value of the statistical variable var_no
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type SIMPLE_KEY_CACHE_CB for a simple key
+ cache. This function returns the value of the statistical variable var_no
for this key cache. The variables are numbered starting from 0 to 6.
RETURN
@@ -4960,12 +4954,12 @@ static size_t s_key_cache_stat_var_offse
*/
static
-ulonglong s_get_key_cache_stat_value(void *keycache_cb, uint var_no)
+ulonglong get_simple_key_cache_stat_value(SIMPLE_KEY_CACHE_CB *keycache,
+ uint var_no)
{
- S_KEY_CACHE_CB *keycache= (S_KEY_CACHE_CB *) keycache_cb;
- size_t var_ofs= s_key_cache_stat_var_offsets[var_no];
+ size_t var_ofs= simple_key_cache_stat_var_offsets[var_no];
ulonglong res= 0;
- DBUG_ENTER("s_get_key_cache_stat_value");
+ DBUG_ENTER("get_simple_key_cache_stat_value");
if (var_no < 3)
res= (ulonglong) (*(long *) ((char *) keycache + var_ofs));
@@ -4985,19 +4979,19 @@ ulonglong s_get_key_cache_stat_value(voi
the MySQL server code directly. We don't do it though.
*/
-static KEY_CACHE_FUNCS s_key_cache_funcs =
+static KEY_CACHE_FUNCS simple_key_cache_funcs =
{
- s_init_key_cache,
- s_resize_key_cache,
- s_change_key_cache_param,
- s_key_cache_read,
- s_key_cache_insert,
- s_key_cache_write,
- s_flush_key_blocks,
- s_reset_key_cache_counters,
- s_end_key_cache,
- s_get_key_cache_statistics,
- s_get_key_cache_stat_value
+ (INIT_KEY_CACHE) init_simple_key_cache,
+ (RESIZE_KEY_CACHE) resize_simple_key_cache,
+ (CHANGE_KEY_CACHE_PARAM) change_simple_key_cache_param,
+ (KEY_CACHE_READ) simple_key_cache_read,
+ (KEY_CACHE_INSERT) simple_key_cache_insert,
+ (KEY_CACHE_WRITE) simple_key_cache_write,
+ (FLUSH_KEY_BLOCKS) flush_simple_key_cache_blocks,
+ (RESET_KEY_CACHE_COUNTERS) reset_simple_key_cache_counters,
+ (END_KEY_CACHE) end_simple_key_cache,
+ (GET_KEY_CACHE_STATISTICS) get_simple_key_cache_statistics,
+ (GET_KEY_CACHE_STAT_VALUE) get_simple_key_cache_stat_value
};
@@ -5038,17 +5032,22 @@ static KEY_CACHE_FUNCS s_key_cache_funcs
/* Control block for a partitioned key cache */
-typedef struct st_p_key_cache_cb
+typedef struct st_partitioned_key_cache_cb
{
my_bool key_cache_inited; /*<=> control block is allocated */
- S_KEY_CACHE_CB **partition_array; /* array of the key cache partitions */
- uint partitions; /* number of partitions in the key cache */
+ SIMPLE_KEY_CACHE_CB **partition_array; /* the key cache partitions */
size_t key_cache_mem_size; /* specified size of the cache memory */
uint key_cache_block_size; /* size of the page buffer of a cache block */
-} P_KEY_CACHE_CB;
+ uint partitions; /* number of partitions in the key cache */
+} PARTITIONED_KEY_CACHE_CB;
static
-void p_end_key_cache(void *keycache_cb, my_bool cleanup);
+void end_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ my_bool cleanup);
+
+static int
+reset_partitioned_key_cache_counters(const char *name,
+ PARTITIONED_KEY_CACHE_CB *keycache);
/*
Determine the partition to which the index block to read is ascribed
@@ -5070,11 +5069,12 @@ void p_end_key_cache(void *keycache_cb,
file block is ascribed.
*/
-static
-S_KEY_CACHE_CB *get_key_cache_partition(P_KEY_CACHE_CB *keycache,
- File file, my_off_t filepos)
+static
+SIMPLE_KEY_CACHE_CB *
+get_key_cache_partition(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos)
{
- uint i= KEYCACHE_BASE_EXPR( file, filepos) % keycache->partitions;
+ uint i= KEYCACHE_BASE_EXPR(file, filepos) % keycache->partitions;
return keycache->partition_array[i];
}
@@ -5101,10 +5101,10 @@ S_KEY_CACHE_CB *get_key_cache_partition(
file block is ascribed.
*/
-static
-S_KEY_CACHE_CB *get_key_cache_partition_for_write(P_KEY_CACHE_CB *keycache,
- File file, my_off_t filepos,
- ulonglong* dirty_part_map)
+static SIMPLE_KEY_CACHE_CB
+*get_key_cache_partition_for_write(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos,
+ ulonglong* dirty_part_map)
{
uint i= KEYCACHE_BASE_EXPR( file, filepos) % keycache->partitions;
*dirty_part_map|= 1<<i;
@@ -5116,8 +5116,8 @@ S_KEY_CACHE_CB *get_key_cache_partition_
Initialize a partitioned key cache
SYNOPSIS
- p_init_key_cache()
- keycache_cb pointer to the control block of a partitioned key cache
+ init_partitioned_key_cache()
+ keycache pointer to the control block of a partitioned key cache
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for all key cache partitions
division_limit division limit (may be zero)
@@ -5127,17 +5127,17 @@ S_KEY_CACHE_CB *get_key_cache_partition_
This function is the implementation of the init_key_cache interface function
that is employed by partitioned key caches.
The function builds and initializes an array of simple key caches, and then
- initializes the control block structure of the type P_KEY_CACHE_CB that is
- used for a partitioned key cache. The parameter keycache_cb is supposed to
- point to this structure. The number of partitions in the partitioned key
- cache to be built must be passed through the field 'partitions' of this
- structure. The parameter key_cache_block_size specifies the size of the
- blocks in the the simple key caches to be built. The parameters
- division_limit and age_threshold determine the initial values of those
- characteristics of the simple key caches that are used for midpoint
- insertion strategy. The parameter use_mem specifies the total amount of
- memory to be allocated for the key cache blocks in all simple key caches
- and for all auxiliary structures.
+ initializes the control block structure of the type PARTITIONED_KEY_CACHE_CB
+ that is used for a partitioned key cache. The parameter keycache is
+ supposed to point to this structure. The number of partitions in the
+ partitioned key cache to be built must be passed through the field
+ 'partitions' of this structure. The parameter key_cache_block_size specifies
+ the size of the blocks in the the simple key caches to be built.
+ The parameters division_limit and age_threshold determine the initial
+ values of those characteristics of the simple key caches that are used for
+ midpoint insertion strategy. The parameter use_mem specifies the total
+ amount of memory to be allocated for the key cache blocks in all simple key
+ caches and for all auxiliary structures.
RETURN VALUE
total number of blocks in key cache partitions, if successful,
@@ -5152,19 +5152,19 @@ S_KEY_CACHE_CB *get_key_cache_partition_
*/
static
-int p_init_key_cache(void *keycache_cb, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+int init_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
int i;
size_t mem_per_cache;
int cnt;
- S_KEY_CACHE_CB *partition;
- S_KEY_CACHE_CB **partition_ptr;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
+ SIMPLE_KEY_CACHE_CB *partition;
+ SIMPLE_KEY_CACHE_CB **partition_ptr;
uint partitions= keycache->partitions;
- int blocks= -1;
- DBUG_ENTER("p_init_key_cache");
+ int blocks= 0;
+ DBUG_ENTER("partitioned_init_key_cache");
keycache->key_cache_block_size = key_cache_block_size;
@@ -5173,9 +5173,9 @@ int p_init_key_cache(void *keycache_cb,
else
{
if(!(partition_ptr=
- (S_KEY_CACHE_CB **) my_malloc(sizeof(S_KEY_CACHE_CB *) * partitions,
- MYF(0))))
- DBUG_RETURN(blocks);
+ (SIMPLE_KEY_CACHE_CB **) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB *) *
+ partitions, MYF(MY_WME))))
+ DBUG_RETURN(-1);
keycache->partition_array= partition_ptr;
}
@@ -5188,36 +5188,35 @@ int p_init_key_cache(void *keycache_cb,
partition= *partition_ptr;
else
{
- if (!(partition= (S_KEY_CACHE_CB *) my_malloc(sizeof(S_KEY_CACHE_CB),
- MYF(0))))
+ if (!(partition=
+ (SIMPLE_KEY_CACHE_CB *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB),
+ MYF(MY_WME))))
continue;
partition->key_cache_inited= 0;
}
- if ((cnt= s_init_key_cache(partition,
- key_cache_block_size, mem_per_cache,
- division_limit, age_threshold)) <= 0)
+ if ((cnt= init_simple_key_cache(partition,
+ key_cache_block_size, mem_per_cache,
+ division_limit, age_threshold)) <= 0)
{
- s_end_key_cache(partition, 1);
- my_free((uchar *) partition, MYF(0));
+ end_simple_key_cache(partition, 1);
+ my_free(partition, MYF(0));
partition= 0;
if (key_cache_inited)
{
memmove(partition_ptr, partition_ptr+1,
sizeof(partition_ptr)*(partitions-i-1));
}
+ if (!--partitions)
+ break;
if (i == 0)
{
i--;
- partitions--;
- if (partitions)
- mem_per_cache = use_mem / partitions;
+ mem_per_cache = use_mem / partitions;
+ continue;
}
- continue;
}
- if (blocks < 0)
- blocks= 0;
blocks+= cnt;
*partition_ptr++= partition;
}
@@ -5229,6 +5228,9 @@ int p_init_key_cache(void *keycache_cb,
keycache->key_cache_inited= 1;
+ if (!partitions)
+ blocks= -1;
+
DBUG_RETURN(blocks);
}
@@ -5237,8 +5239,8 @@ int p_init_key_cache(void *keycache_cb,
Resize a partitioned key cache
SYNOPSIS
- p_resize_key_cache()
- keycache_cb pointer to the control block of a partitioned key cache
+ resize_partitioned_key_cache()
+ keycache pointer to the control block of a partitioned key cache
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for the new key cache
division_limit new division limit (if not zero)
@@ -5247,9 +5249,9 @@ int p_init_key_cache(void *keycache_cb,
DESCRIPTION
This function is the implementation of the resize_key_cache interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for the partitioned
- key cache to be resized.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for the
+ partitioned key cache to be resized.
The parameter key_cache_block_size specifies the new size of the blocks in
the simple key caches that comprise the partitioned key cache.
The parameters division_limit and age_threshold determine the new initial
@@ -5263,48 +5265,48 @@ int p_init_key_cache(void *keycache_cb,
0 - otherwise.
NOTES.
- The function first calls s_prepare_resize_key_cache for each simple
+ The function first calls prepare_resize_simple_key_cache for each simple
key cache effectively flushing all dirty pages from it and destroying
- the key cache. Then p_init_key cache is called. This call builds all
- the new array of simple key caches containing the same number of
- elements as the old one. After this the function calls the function
- s_finish_resize_key_cache for each simple key cache from this array.
+ the key cache. Then init_partitioned_key_cache is called. This call builds
+ a new array of simple key caches containing the same number of elements
+ as the old one. After this the function calls the function
+ finish_resize_simple_key_cache for each simple key cache from this array.
This implementation doesn't block the calls and executions of other
functions from the key cache interface. However it assumes that the
- calls of s_resize_key_cache itself are serialized.
+ calls of resize_partitioned_key_cache itself are serialized.
*/
static
-int p_resize_key_cache(void *keycache_cb, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+int resize_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint key_cache_block_size,
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
my_bool cleanup= use_mem == 0;
int blocks= -1;
int err= 0;
- DBUG_ENTER("p_resize_key_cache");
- if (use_mem == 0)
+ DBUG_ENTER("partitioned_resize_key_cache");
+ if (cleanup)
{
- p_end_key_cache(keycache_cb, 0);
- DBUG_RETURN(blocks);
+ end_partitioned_key_cache(keycache, 0);
+ DBUG_RETURN(-1);
}
for (i= 0; i < partitions; i++)
{
- err|= s_prepare_resize_key_cache(keycache->partition_array[i], 0, 1);
+ err|= prepare_resize_simple_key_cache(keycache->partition_array[i], 0, 1);
}
- if (!err && use_mem)
- blocks= p_init_key_cache(keycache_cb, key_cache_block_size, use_mem,
- division_limit, age_threshold);
- if (blocks > 0 && !cleanup)
+ if (!err)
+ blocks= init_partitioned_key_cache(keycache, key_cache_block_size,
+ use_mem, division_limit, age_threshold);
+ if (blocks > 0)
{
for (i= 0; i < partitions; i++)
{
- s_finish_resize_key_cache(keycache->partition_array[i], 0, 1);
+ finish_resize_simple_key_cache(keycache->partition_array[i], 0, 1);
}
}
DBUG_RETURN(blocks);
@@ -5315,17 +5317,17 @@ int p_resize_key_cache(void *keycache_cb
Change key cache parameters of a partitioned key cache
SYNOPSIS
- p_change_key_cache_param()
- keycache_cb pointer to the control block of a partitioned key cache
+ partitioned_change_key_cache_param()
+ keycache pointer to the control block of a partitioned key cache
division_limit new division limit (if not zero)
age_threshold new age threshold (if not zero)
DESCRIPTION
This function is the implementation of the change_key_cache_param interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for the simple key
- cache where new values of the division limit and the age threshold used
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for the simple
+ key cache where new values of the division limit and the age threshold used
for midpoint insertion strategy are to be set. The parameters
division_limit and age_threshold provide these new values.
@@ -5333,23 +5335,23 @@ int p_resize_key_cache(void *keycache_cb
none
NOTES
- The function just calls s_change_key_cache_param for each element from the
- array of simple caches that comprise the partitioned key cache.
+ The function just calls change_simple_key_cache_param for each element from
+ the array of simple caches that comprise the partitioned key cache.
*/
static
-void p_change_key_cache_param(void *keycache_cb, uint division_limit,
- uint age_threshold)
+void change_partitioned_key_cache_param(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint division_limit,
+ uint age_threshold)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
- DBUG_ENTER("p_change_key_cache_param");
+ DBUG_ENTER("partitioned_change_key_cache_param");
for (i= 0; i < partitions; i++)
{
- s_change_key_cache_param(keycache->partition_array[i], division_limit,
- age_threshold);
+ change_simple_key_cache_param(keycache->partition_array[i], division_limit,
+ age_threshold);
}
DBUG_VOID_RETURN;
}
@@ -5359,17 +5361,17 @@ void p_change_key_cache_param(void *keyc
Destroy a partitioned key cache
SYNOPSIS
- p_end_key_cache()
- keycache_cb pointer to the control block of a partitioned key cache
+ end_partitioned_key_cache()
+ keycache pointer to the control block of a partitioned key cache
cleanup <=> complete free (free also control block structures
for all simple key caches)
DESCRIPTION
This function is the implementation of the end_key_cache interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for the partitioned
- key cache to be destroyed.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for the
+ partitioned key cache to be destroyed.
The function frees the memory allocated for the cache blocks and
auxiliary structures used by simple key caches that comprise the
partitioned key cache. If the value of the parameter cleanup is TRUE
@@ -5382,19 +5384,20 @@ void p_change_key_cache_param(void *keyc
*/
static
-void p_end_key_cache(void *keycache_cb, my_bool cleanup)
+void end_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
+ my_bool cleanup)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
- DBUG_ENTER("p_end_key_cache");
+ DBUG_ENTER("partitioned_end_key_cache");
DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache));
for (i= 0; i < partitions; i++)
{
- s_end_key_cache(keycache->partition_array[i], cleanup);
+ end_simple_key_cache(keycache->partition_array[i], cleanup);
}
- if (cleanup) {
+ if (cleanup)
+ {
for (i= 0; i < partitions; i++)
my_free((uchar*) keycache->partition_array[i], MYF(0));
my_free((uchar*) keycache->partition_array, MYF(0));
@@ -5409,8 +5412,8 @@ void p_end_key_cache(void *keycache_cb,
SYNOPSIS
- p_key_cache_read()
- keycache_cb pointer to the control block of a partitioned key cache
+ partitioned_key_cache_read()
+ keycache pointer to the control block of a partitioned key cache
file handler for the file for the block of data to be read
filepos position of the block of data in the file
level determines the weight of the data
@@ -5422,9 +5425,9 @@ void p_end_key_cache(void *keycache_cb,
DESCRIPTION
This function is the implementation of the key_cache_read interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
In a general case the function reads a block of data from the key cache
into the buffer buff of the size specified by the parameter length. The
beginning of the block of data to be read is specified by the parameters
@@ -5432,7 +5435,7 @@ void p_end_key_cache(void *keycache_cb,
of the buffer. The data is read into the buffer in key_cache_block_size
increments. To read each portion the function first finds out in what
partition of the key cache this portion(page) is to be saved, and calls
- s_key_cache_read with the pointer to the corresponding simple key as
+ simple_key_cache_read with the pointer to the corresponding simple key as
its first parameter.
If the parameter return_buffer is not ignored and its value is TRUE, and
the data to be read of the specified size block_length can be read from one
@@ -5449,17 +5452,16 @@ void p_end_key_cache(void *keycache_cb,
*/
static
-uchar *p_key_cache_read(void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int return_buffer __attribute__((unused)))
+uchar *partitioned_key_cache_read(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int return_buffer __attribute__((unused)))
{
uint r_length;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint offset= (uint) (filepos % keycache->key_cache_block_size);
uchar *start= buff;
- DBUG_ENTER("p_key_cache_read");
+ DBUG_ENTER("partitioned_key_cache_read");
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
(uint) file, (ulong) filepos, length));
@@ -5471,15 +5473,15 @@ uchar *p_key_cache_read(void *keycache_c
/* Read data in key_cache_block_size increments */
do
{
- S_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
- file, filepos);
+ SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
+ file, filepos);
uchar *ret_buff= 0;
r_length= length;
set_if_smaller(r_length, keycache->key_cache_block_size - offset);
- ret_buff= s_key_cache_read((void *) partition,
- file, filepos, level,
- buff, r_length,
- block_length, return_buffer);
+ ret_buff= simple_key_cache_read((void *) partition,
+ file, filepos, level,
+ buff, r_length,
+ block_length, return_buffer);
if (ret_buff == 0)
DBUG_RETURN(0);
#ifndef THREAD
@@ -5500,8 +5502,8 @@ uchar *p_key_cache_read(void *keycache_c
Insert a block of file data from a buffer into a partitioned key cache
SYNOPSIS
- p_key_cache_insert()
- keycache_cb pointer to the control block of a partitioned key cache
+ partitioned_key_cache_insert()
+ keycache pointer to the control block of a partitioned key cache
file handler for the file to insert data from
filepos position of the block of data in the file to insert
level determines the weight of the data
@@ -5511,9 +5513,9 @@ uchar *p_key_cache_read(void *keycache_c
DESCRIPTION
This function is the implementation of the key_cache_insert interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned key
- cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
The function writes a block of file data from a buffer into the key cache.
The buffer is specified with the parameters buff and length - the pointer
to the beginning of the buffer and its size respectively. It's assumed
@@ -5521,8 +5523,8 @@ uchar *p_key_cache_read(void *keycache_c
filepos. The data is copied from the buffer in key_cache_block_size
increments. For every portion of data the function finds out in what simple
key cache from the array of partitions the data must be stored, and after
- this calls s_key_cache_insert to copy the data into a key buffer of this
- simple key cache.
+ this calls simple_key_cache_insert to copy the data into a key buffer of
+ this simple key cache.
The parameter level is used to set one characteristic for the key buffers
loaded with the data from buff. The characteristic is used only by the
midpoint insertion strategy.
@@ -5538,14 +5540,13 @@ uchar *p_key_cache_read(void *keycache_c
*/
static
-int p_key_cache_insert(void *keycache_cb,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length)
+int partitioned_key_cache_insert(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, my_off_t filepos, int level,
+ uchar *buff, uint length)
{
uint w_length;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint offset= (uint) (filepos % keycache->key_cache_block_size);
- DBUG_ENTER("p_key_cache_insert");
+ DBUG_ENTER("partitioned_key_cache_insert");
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
(uint) file,(ulong) filepos, length));
@@ -5553,13 +5554,13 @@ int p_key_cache_insert(void *keycache_cb
/* Write data in key_cache_block_size increments */
do
{
- S_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
- file, filepos);
+ SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition(keycache,
+ file, filepos);
w_length= length;
- set_if_smaller(w_length, keycache->key_cache_block_size);
- if (s_key_cache_insert((void *) partition,
- file, filepos, level,
- buff, w_length))
+ set_if_smaller(w_length, keycache->key_cache_block_size - offset);
+ if (simple_key_cache_insert((void *) partition,
+ file, filepos, level,
+ buff, w_length))
DBUG_RETURN(1);
filepos+= w_length;
@@ -5576,8 +5577,8 @@ int p_key_cache_insert(void *keycache_cb
SYNOPSIS
- p_key_cache_write()
- keycache_cb pointer to the control block of a partitioned key cache
+ partitioned_key_cache_write()
+ keycache pointer to the control block of a partitioned key cache
file handler for the file to write data to
filepos position in the file to write data to
level determines the weight of the data
@@ -5591,9 +5592,9 @@ int p_key_cache_insert(void *keycache_cb
DESCRIPTION
This function is the implementation of the key_cache_write interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
In a general case the function copies data from a buffer into the key
cache. The buffer is specified with the parameters buff and length -
the pointer to the beginning of the buffer and its size respectively.
@@ -5601,8 +5602,8 @@ int p_key_cache_insert(void *keycache_cb
starting from the position filepos. The data is copied from the buffer
in key_cache_block_size increments. For every portion of data the
function finds out in what simple key cache from the array of partitions
- the data must be stored, and after this calls s_key_cache_write to copy
- the data into a key buffer of this simple key cache.
+ the data must be stored, and after this calls simple_key_cache_write to
+ copy the data into a key buffer of this simple key cache.
If the value of the parameter dont_write is FALSE then the function
also writes the data into file.
The parameter level is used to set one characteristic for the key buffers
@@ -5610,7 +5611,7 @@ int p_key_cache_insert(void *keycache_cb
the midpoint insertion strategy.
The parameter file_expra provides a pointer to the shared bitmap of
the partitions that may contains dirty pages for the file. This bitmap
- is used to optimize the function p_flush_key_blocks.
+ is used to optimize the function flush_partitioned_key_cache_blocks.
RETURN VALUE
0 if a success, 1 - otherwise.
@@ -5622,18 +5623,17 @@ int p_key_cache_insert(void *keycache_cb
*/
static
-int p_key_cache_write(void *keycache_cb,
- File file, void *file_extra,
- my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int dont_write)
+int partitioned_key_cache_write(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, void *file_extra,
+ my_off_t filepos, int level,
+ uchar *buff, uint length,
+ uint block_length __attribute__((unused)),
+ int dont_write)
{
uint w_length;
ulonglong *part_map= (ulonglong *) file_extra;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint offset= (uint) (filepos % keycache->key_cache_block_size);
- DBUG_ENTER("p_key_cache_write");
+ DBUG_ENTER("partitioned_key_cache_write");
DBUG_PRINT("enter",
("fd: %u pos: %lu length: %u block_length: %u"
" key_block_length: %u",
@@ -5644,15 +5644,16 @@ int p_key_cache_write(void *keycache_cb,
/* Write data in key_cache_block_size increments */
do
{
- S_KEY_CACHE_CB *partition= get_key_cache_partition_for_write(keycache,
- file, filepos,
- part_map);
+ SIMPLE_KEY_CACHE_CB *partition= get_key_cache_partition_for_write(keycache,
+ file,
+ filepos,
+ part_map);
w_length = length;
- set_if_smaller(w_length, keycache->key_cache_block_size );
- if (s_key_cache_write(partition,
- file, 0, filepos, level,
- buff, w_length, block_length,
- dont_write))
+ set_if_smaller(w_length, keycache->key_cache_block_size - offset );
+ if (simple_key_cache_write(partition,
+ file, 0, filepos, level,
+ buff, w_length, block_length,
+ dont_write))
DBUG_RETURN(1);
filepos+= w_length;
@@ -5669,8 +5670,8 @@ int p_key_cache_write(void *keycache_cb,
SYNOPSIS
- p_flush_key_blocks()
- keycache_cb pointer to the control block of a partitioned key cache
+ flush_partitioned_key_cache_blocks()
+ keycache pointer to the control block of a partitioned key cache
file handler for the file to flush to
file_extra maps of key cache partitions containing
dirty pages from file (not used)
@@ -5679,9 +5680,9 @@ int p_key_cache_write(void *keycache_cb,
DESCRIPTION
This function is the implementation of the flush_key_blocks interface
function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
In a general case the function flushes the data from all dirty key
buffers related to the file 'file' into this file. The function does
exactly this if the value of the parameter type is FLUSH_KEEP. If the
@@ -5689,12 +5690,12 @@ int p_key_cache_write(void *keycache_cb,
releases the key buffers containing data from 'file' for new usage.
If the value of the parameter type is FLUSH_IGNORE_CHANGED the function
just releases the key buffers containing data from 'file'.
- The function performs the operation by calling s_flush_key_blocks
- for the elements of the array of the simple key caches that comprise
- the partitioned key_cache. If the value of the parameter type is
- FLUSH_KEEP s_flush_key_blocks is called only for the partitions with
- possibly dirty pages marked in the bitmap pointed to by the parameter
- file_extra.
+ The function performs the operation by calling the function
+ flush_simple_key_cache_blocks for the elements of the array of the
+ simple key caches that comprise the partitioned key_cache. If the value
+ of the parameter type is FLUSH_KEEP s_flush_key_blocks is called only
+ for the partitions with possibly dirty pages marked in the bitmap
+ pointed to by the parameter file_extra.
RETURN
0 ok
@@ -5707,31 +5708,27 @@ int p_key_cache_write(void *keycache_cb,
*/
static
-int p_flush_key_blocks(void *keycache_cb,
- File file, void *file_extra,
- enum flush_type type)
+int flush_partitioned_key_cache_blocks(PARTITIONED_KEY_CACHE_CB *keycache,
+ File file, void *file_extra,
+ enum flush_type type)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
int err= 0;
ulonglong *dirty_part_map= (ulonglong *) file_extra;
- DBUG_ENTER("p_flush_key_blocks");
+ DBUG_ENTER("partitioned_flush_key_blocks");
DBUG_PRINT("enter", ("keycache: 0x%lx", (long) keycache));
for (i= 0; i < partitions; i++)
{
- S_KEY_CACHE_CB *partition= keycache->partition_array[i];
+ SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i];
if ((type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE) &&
- !((*dirty_part_map) & (1<<i)))
+ !((*dirty_part_map) & ((ulonglong) 1 << i)))
continue;
- err+= test(s_flush_key_blocks(partition, file, 0, type));
+ err|= test(flush_simple_key_cache_blocks(partition, file, 0, type));
}
*dirty_part_map= 0;
- if (err > 0)
- err= 1;
-
DBUG_RETURN(err);
}
@@ -5740,19 +5737,19 @@ int p_flush_key_blocks(void *keycache_cb
Reset the counters of a partitioned key cache
SYNOPSIS
- p_reset_key_cache_counters()
+ reset_partitioned_key_cache_counters()
name the name of a key cache
- keycache_cb pointer to the control block of a partitioned key cache
+ keycache pointer to the control block of a partitioned key cache
DESCRIPTION
This function is the implementation of the reset_key_cache_counters
interface function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a partitioned
key cache.
This function resets the values of the statistical counters of the simple
key caches comprising partitioned key cache to 0. It does it by calling
- s_reset_key_cache_counters for each key cache partition.
+ reset_simple_key_cache_counters for each key cache partition.
The parameter name is currently not used.
RETURN
@@ -5760,18 +5757,17 @@ int p_flush_key_blocks(void *keycache_cb
*/
-static
-int p_reset_key_cache_counters(const char *name __attribute__((unused)),
- void *keycache_cb)
+static int
+reset_partitioned_key_cache_counters(const char *name __attribute__((unused)),
+ PARTITIONED_KEY_CACHE_CB *keycache)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
- DBUG_ENTER("p_reset_key_cache_counters");
+ DBUG_ENTER("partitioned_reset_key_cache_counters");
for (i = 0; i < partitions; i++)
{
- s_reset_key_cache_counters(name, keycache->partition_array[i]);
+ reset_simple_key_cache_counters(name, keycache->partition_array[i]);
}
DBUG_RETURN(0);
}
@@ -5781,17 +5777,17 @@ int p_reset_key_cache_counters(const cha
Get statistics for a partition key cache
SYNOPSIS
- p_get_key_cache_statistics()
- keycache_cb pointer to the control block of a partitioned key cache
+ get_partitioned_key_cache_statistics()
+ keycache pointer to the control block of a partitioned key cache
partition_no partition number to get statistics for
key_cache_stats OUT pointer to the structure for the returned statistics
DESCRIPTION
This function is the implementation of the get_key_cache_statistics
interface function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for
+ a partitioned key cache.
If the value of the parameter partition_no is equal to 0 then aggregated
statistics for all partitions is returned in the fields of the
structure key_cache_stat of the type KEY_CACHE_STATISTICS . Otherwise
@@ -5805,33 +5801,35 @@ int p_reset_key_cache_counters(const cha
*/
static
-void p_get_key_cache_statistics(void *keycache_cb, uint partition_no,
- KEY_CACHE_STATISTICS *key_cache_stats)
+void
+get_partitioned_key_cache_statistics(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint partition_no,
+ KEY_CACHE_STATISTICS *keycache_stats)
{
uint i;
- S_KEY_CACHE_CB *partition;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
+ SIMPLE_KEY_CACHE_CB *partition;
uint partitions= keycache->partitions;
- DBUG_ENTER("p_get_key_cache_statistics_");
+ DBUG_ENTER("get_partitioned_key_cache_statistics");
if (partition_no != 0)
{
partition= keycache->partition_array[partition_no-1];
- s_get_key_cache_statistics((void *) partition, 0, key_cache_stats);
+ get_simple_key_cache_statistics((void *) partition, 0, keycache_stats);
DBUG_VOID_RETURN;
}
- key_cache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
- key_cache_stats->block_size= (longlong) keycache->key_cache_block_size;
+ bzero(keycache_stats, sizeof(KEY_CACHE_STATISTICS));
+ keycache_stats->mem_size= (longlong) keycache->key_cache_mem_size;
+ keycache_stats->block_size= (longlong) keycache->key_cache_block_size;
for (i = 0; i < partitions; i++)
{
partition= keycache->partition_array[i];
- key_cache_stats->blocks_used+= partition->blocks_used;
- key_cache_stats->blocks_unused+= partition->blocks_unused;
- key_cache_stats->blocks_changed+= partition->global_blocks_changed;
- key_cache_stats->read_requests+= partition->global_cache_r_requests;
- key_cache_stats->reads+= partition->global_cache_read;
- key_cache_stats->write_requests+= partition->global_cache_w_requests;
- key_cache_stats->writes+= partition->global_cache_write;
+ keycache_stats->blocks_used+= partition->blocks_used;
+ keycache_stats->blocks_unused+= partition->blocks_unused;
+ keycache_stats->blocks_changed+= partition->global_blocks_changed;
+ keycache_stats->read_requests+= partition->global_cache_r_requests;
+ keycache_stats->reads+= partition->global_cache_read;
+ keycache_stats->write_requests+= partition->global_cache_w_requests;
+ keycache_stats->writes+= partition->global_cache_write;
}
DBUG_VOID_RETURN;
}
@@ -5840,16 +5838,16 @@ void p_get_key_cache_statistics(void *ke
Get the value of a statistical variable for a partitioned key cache
SYNOPSIS
- p_get_key_cache_stat_value()
- keycache_cb pointer to the control block of a partitioned key cache
+ get_partitioned_key_cache_stat_value()
+ keycache pointer to the control block of a partitioned key cache
var_no the ordered number of a statistical variable
DESCRIPTION
This function is the implementation of the get_key_cache_stat_value
interface function that is employed by partitioned key caches.
- The function considers the parameter keycache_cb as a pointer to the
- control block structure of the type P_KEY_CACHE_CB for a partitioned
- key cache.
+ The function takes the parameter keycache as a pointer to the
+ control block structure of the type PARTITIONED_KEY_CACHE_CB for a
+ partitioned key cache.
This function returns the value of the statistical variable var_no
for this key cache. The variables are numbered starting from 0 to 6.
The returned value is calculated as the sum of the values of the
@@ -5862,20 +5860,21 @@ void p_get_key_cache_statistics(void *ke
*/
static
-ulonglong p_get_key_cache_stat_value(void *keycache_cb, uint var_no)
+ulonglong
+get_partitioned_key_cache_stat_value(PARTITIONED_KEY_CACHE_CB *keycache,
+ uint var_no)
{
uint i;
- P_KEY_CACHE_CB *keycache= (P_KEY_CACHE_CB *) keycache_cb;
uint partitions= keycache->partitions;
- size_t var_ofs= s_key_cache_stat_var_offsets[var_no];
+ size_t var_ofs= simple_key_cache_stat_var_offsets[var_no];
ulonglong res= 0;
- DBUG_ENTER("p_get_key_cache_stat_value");
+ DBUG_ENTER("get_partitioned_key_cache_stat_value");
- if (var_no < 3)
+ if (var_no < NO_LONG_KEY_CACHE_STAT_VARIABLES)
{
for (i = 0; i < partitions; i++)
{
- S_KEY_CACHE_CB *partition= keycache->partition_array[i];
+ SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i];
res+= (ulonglong) (*(long *) ((char *) partition + var_ofs));
}
}
@@ -5883,7 +5882,7 @@ ulonglong p_get_key_cache_stat_value(voi
{
for (i = 0; i < partitions; i++)
{
- S_KEY_CACHE_CB *partition= keycache->partition_array[i];
+ SIMPLE_KEY_CACHE_CB *partition= keycache->partition_array[i];
res+= *(ulonglong *) ((char *) partition + var_ofs);
}
}
@@ -5901,19 +5900,19 @@ ulonglong p_get_key_cache_stat_value(voi
wrappers must be used for this purpose.
*/
-static KEY_CACHE_FUNCS p_key_cache_funcs =
+static KEY_CACHE_FUNCS partitioned_key_cache_funcs =
{
- p_init_key_cache,
- p_resize_key_cache,
- p_change_key_cache_param,
- p_key_cache_read,
- p_key_cache_insert,
- p_key_cache_write,
- p_flush_key_blocks,
- p_reset_key_cache_counters,
- p_end_key_cache,
- p_get_key_cache_statistics,
- p_get_key_cache_stat_value
+ (INIT_KEY_CACHE) init_partitioned_key_cache,
+ (RESIZE_KEY_CACHE) resize_partitioned_key_cache,
+ (CHANGE_KEY_CACHE_PARAM) change_partitioned_key_cache_param,
+ (KEY_CACHE_READ) partitioned_key_cache_read,
+ (KEY_CACHE_INSERT) partitioned_key_cache_insert,
+ (KEY_CACHE_WRITE) partitioned_key_cache_write,
+ (FLUSH_KEY_BLOCKS) flush_partitioned_key_cache_blocks,
+ (RESET_KEY_CACHE_COUNTERS) reset_partitioned_key_cache_counters,
+ (END_KEY_CACHE) end_partitioned_key_cache,
+ (GET_KEY_CACHE_STATISTICS) get_partitioned_key_cache_statistics,
+ (GET_KEY_CACHE_STAT_VALUE) get_partitioned_key_cache_stat_value
};
@@ -5926,12 +5925,12 @@ static KEY_CACHE_FUNCS p_key_cache_funcs
partitioned key caches. Each type (class) has its own implementation of the
basic key cache operations used the MyISAM storage engine. The pointers
to the implementation functions are stored in two static structures of the
- type KEY_CACHE_FUNC: s_key_cache_funcs - for simple key caches, and
- p_key_cache_funcs - for partitioned key caches. When a key cache object is
- created the constructor procedure init_key_cache places a pointer to the
- corresponding table into one of its fields. The procedure also initializes
- a control block for the key cache oject and saves the pointer to this
- block in another field of the key cache object.
+ type KEY_CACHE_FUNC: simple_key_cache_funcs - for simple key caches, and
+ partitioned_key_cache_funcs - for partitioned key caches. When a key cache
+ object is created the constructor procedure init_key_cache places a pointer
+ to the corresponding table into one of its fields. The procedure also
+ initializes a control block for the key cache oject and saves the pointer
+ to this block in another field of the key cache object.
When a key cache wrapper function is invoked for a key cache object to
perform a basic key cache operation it looks into the interface table
associated with the key cache oject and calls the corresponding
@@ -5997,19 +5996,21 @@ int init_key_cache(KEY_CACHE *keycache,
{
if (partitions == 0)
{
- if (!(keycache_cb= (void *) my_malloc(sizeof(S_KEY_CACHE_CB), MYF(0))))
+ if (!(keycache_cb= (void *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB),
+ MYF(0))))
return 0;
- ((S_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
+ ((SIMPLE_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
keycache->key_cache_type= SIMPLE_KEY_CACHE;
- keycache->interface_funcs= &s_key_cache_funcs;
+ keycache->interface_funcs= &simple_key_cache_funcs;
}
else
{
- if (!(keycache_cb= (void *) my_malloc(sizeof(P_KEY_CACHE_CB), MYF(0))))
+ if (!(keycache_cb= (void *) my_malloc(sizeof(PARTITIONED_KEY_CACHE_CB),
+ MYF(0))))
return 0;
- ((P_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
+ ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
keycache->key_cache_type= PARTITIONED_KEY_CACHE;
- keycache->interface_funcs= &p_key_cache_funcs;
+ keycache->interface_funcs= &partitioned_key_cache_funcs;
}
keycache->keycache_cb= keycache_cb;
keycache->key_cache_inited= 1;
@@ -6017,14 +6018,15 @@ int init_key_cache(KEY_CACHE *keycache,
if (partitions != 0)
{
- ((P_KEY_CACHE_CB *) keycache_cb)->partitions= partitions;
+ ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions= partitions;
}
keycache->can_be_used= 0;
blocks= keycache->interface_funcs->init(keycache_cb, key_cache_block_size,
use_mem, division_limit,
age_threshold);
keycache->partitions= partitions ?
- ((P_KEY_CACHE_CB *) keycache_cb)->partitions : 0;
+ ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions :
+ 0;
DBUG_ASSERT(partitions <= MAX_KEY_CACHE_PARTITIONS);
if (blocks > 0)
keycache->can_be_used= 1;
@@ -6037,7 +6039,7 @@ int init_key_cache(KEY_CACHE *keycache,
SYNOPSIS
resize_key_cache()
- keycache pointer to the key cache to be resized
+ keycache pointer to the key cache to be resized
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for the new key cache
division_limit new division limit (if not zero)
@@ -6074,10 +6076,10 @@ int resize_key_cache(KEY_CACHE *keycache
if (keycache->key_cache_inited)
{
if ((uint) keycache->param_partitions != keycache->partitions && use_mem)
- blocks= repartition_key_cache (keycache,
- key_cache_block_size, use_mem,
- division_limit, age_threshold,
- (uint) keycache->param_partitions);
+ blocks= repartition_key_cache(keycache,
+ key_cache_block_size, use_mem,
+ division_limit, age_threshold,
+ (uint) keycache->param_partitions);
else
{
blocks= keycache->interface_funcs->resize(keycache->keycache_cb,
@@ -6087,10 +6089,10 @@ int resize_key_cache(KEY_CACHE *keycache
if (keycache->partitions)
keycache->partitions=
- ((P_KEY_CACHE_CB *)(keycache->keycache_cb))->partitions;
+ ((PARTITIONED_KEY_CACHE_CB *)(keycache->keycache_cb))->partitions;
}
- if (blocks <= 0)
- keycache->can_be_used= 0;
+
+ keycache->can_be_used= (blocks >= 0);
}
return blocks;
}
@@ -6447,7 +6449,6 @@ int reset_key_cache_counters(const char
void get_key_cache_statistics(KEY_CACHE *keycache, uint partition_no,
KEY_CACHE_STATISTICS *key_cache_stats)
{
- bzero(key_cache_stats, sizeof(KEY_CACHE_STATISTICS));
if (keycache->key_cache_inited)
{
keycache->interface_funcs->get_stats(keycache->keycache_cb,
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-03-29 21:16:12 +0000
+++ b/sql/sql_show.cc 2010-04-01 21:26:08 +0000
@@ -2235,8 +2235,9 @@ static void update_key_cache_stat_var(KE
case offsetof(KEY_CACHE, global_cache_read):
case offsetof(KEY_CACHE, global_cache_w_requests):
case offsetof(KEY_CACHE, global_cache_write):
- var_no= 3+(ofs-offsetof(KEY_CACHE, global_cache_w_requests))/
- sizeof(ulonglong);
+ var_no= NO_LONG_KEY_CACHE_STAT_VARIABLES +
+ (ofs-offsetof(KEY_CACHE, global_cache_w_requests))/
+ sizeof(ulonglong);
*(ulonglong *)((char *) key_cache + ofs)=
get_key_cache_stat_value(key_cache, var_no);
break;
@@ -6643,13 +6644,13 @@ int store_key_cache_table_record(THD *th
KEY_CACHE *key_cache,
uint partitions, uint partition_no)
{
- KEY_CACHE_STATISTICS key_cache_stats;
+ KEY_CACHE_STATISTICS keycache_stats;
uint err;
DBUG_ENTER("store_key_cache_table_record");
- get_key_cache_statistics(key_cache, partition_no, &key_cache_stats);
+ get_key_cache_statistics(key_cache, partition_no, &keycache_stats);
- if (key_cache_stats.mem_size == 0)
+ if (!key_cache->key_cache_inited || keycache_stats.mem_size == 0)
DBUG_RETURN(0);
restore_record(table, s->default_values);
@@ -6669,15 +6670,15 @@ int store_key_cache_table_record(THD *th
table->field[2]->set_notnull();
table->field[2]->store((long) partition_no, TRUE);
}
- table->field[3]->store(key_cache_stats.mem_size, TRUE);
- table->field[4]->store(key_cache_stats.block_size, TRUE);
- table->field[5]->store(key_cache_stats.blocks_used, TRUE);
- table->field[6]->store(key_cache_stats.blocks_unused, TRUE);
- table->field[7]->store(key_cache_stats.blocks_changed, TRUE);
- table->field[8]->store(key_cache_stats.read_requests, TRUE);
- table->field[9]->store(key_cache_stats.reads, TRUE);
- table->field[10]->store(key_cache_stats.write_requests, TRUE);
- table->field[11]->store(key_cache_stats.writes, TRUE);
+ table->field[3]->store(keycache_stats.mem_size, TRUE);
+ table->field[4]->store(keycache_stats.block_size, TRUE);
+ table->field[5]->store(keycache_stats.blocks_used, TRUE);
+ table->field[6]->store(keycache_stats.blocks_unused, TRUE);
+ table->field[7]->store(keycache_stats.blocks_changed, TRUE);
+ table->field[8]->store(keycache_stats.read_requests, TRUE);
+ table->field[9]->store(keycache_stats.reads, TRUE);
+ table->field[10]->store(keycache_stats.write_requests, TRUE);
+ table->field[11]->store(keycache_stats.writes, TRUE);
err= schema_table_store_record(thd, table);
DBUG_RETURN(err);
1
0

[Maria-developers] Rev 2767: Fied problem with of compilation without dynamic plugin loading. in file:///Users/bell/maria/bzr/work-maria-5.2-plugin/
by sanja@askmonty.org 01 Apr '10
by sanja@askmonty.org 01 Apr '10
01 Apr '10
At file:///Users/bell/maria/bzr/work-maria-5.2-plugin/
------------------------------------------------------------
revno: 2767
revision-id: sanja(a)askmonty.org-20100401200509-o67qhkcgzv5s9oai
parent: sanja(a)askmonty.org-20100401143451-z7dyg1mj84zf8ue5
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-plugin
timestamp: Thu 2010-04-01 23:05:09 +0300
message:
Fied problem with of compilation without dynamic plugin loading.
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-04-01 14:34:51 +0000
+++ b/sql/sql_plugin.cc 2010-04-01 20:05:09 +0000
@@ -388,6 +388,7 @@ static inline void free_plugin_mem(struc
@retval TRUE ERROR
*/
+#ifdef HAVE_DLOPEN
static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl,
void *sym, char *dlpath,
int report)
@@ -592,6 +593,7 @@ static my_bool read_maria_plugin_info(st
DBUG_RETURN(FALSE);
}
+#endif HAVE_DLOPEN
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
1
0

Re: [Maria-developers] [Fwd: WorkLog sends out too many mail-copies to maria-developers]
by Kristian Nielsen 01 Apr '10
by Kristian Nielsen 01 Apr '10
01 Apr '10
Bryan Alsdorf <bryan(a)askmonty.org> writes:
> Here is a message from Arjen regarding worklog. I haven't messed with
> it and I believe you are currently maintaining it.
>
> Thoughts?
I agree that Worklog mail sending is annoying/broken as it is now.
Unfortunately I don't know how to fix it, and I don't have the time currently
to investigate.
One thing we could do is disable the worklog-db(a)askmonty.org alias (eg. send
it to /dev/null). This should disable sending the mails to the mailing list at
least.
- Kristian.
> -------- Original Message --------
> Subject: WorkLog sends out too many mail-copies to maria-developers
> Date: Thu, 11 Mar 2010 08:59:22 +1000
> From: Arjen Lentz <arjen(a)openquery.com>
> To: Bryan Alsdorf <bryan(a)askmonty.org>
>
> Hi Bryan
>
> I think worklog is doing fail on mailouts. it sends to maria-
> developers list as well as a direct addressee. as a result is sends
> out multiples to maria-developers. it seems...
> archivist confirms this, for one item he also got 6 identical emails.
>
> Cheers,
> Arjen.
4
3

[Maria-developers] Rev 2766: Maria WL#61 in file:///home/bell/maria/bzr/work-maria-5.2-plugin/
by sanja@askmonty.org 01 Apr '10
by sanja@askmonty.org 01 Apr '10
01 Apr '10
At file:///home/bell/maria/bzr/work-maria-5.2-plugin/
------------------------------------------------------------
revno: 2766
revision-id: sanja(a)askmonty.org-20100401143451-z7dyg1mj84zf8ue5
parent: monty(a)askmonty.org-20100401100115-iz32pn7zhx2e237e
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-plugin
timestamp: Thu 2010-04-01 17:34:51 +0300
message:
Maria WL#61
Interface for maria extensions.
Alternative plugin interface with additional info (maturity and string version).
=== modified file 'CMakeLists.txt'
--- a/CMakeLists.txt 2010-03-15 11:51:23 +0000
+++ b/CMakeLists.txt 2010-04-01 14:34:51 +0000
@@ -260,7 +260,7 @@
ENDIF(WITH_${ENGINE}_STORAGE_ENGINE AND MYSQL_PLUGIN_STATIC)
IF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_${PLUGIN_NAME}_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${PLUGIN_NAME}_plugin")
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${PLUGIN_NAME})
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
@@ -279,7 +279,7 @@
# Special handling for partition(not really pluggable)
IF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_PARTITION_STORAGE_ENGINE")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_partition_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_partition_plugin")
ENDIF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
# Special handling for tmp tables with the maria engine
=== modified file 'config/ac-macros/plugins.m4'
--- a/config/ac-macros/plugins.m4 2010-03-29 15:14:28 +0000
+++ b/config/ac-macros/plugins.m4 2010-04-01 14:34:51 +0000
@@ -460,7 +460,7 @@
])
])
])
- mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]"
+ maria_plugin_defs="$maria_plugin_defs, [builtin_maria_]$2[_plugin]"
[with_plugin_]$2=yes
AC_MSG_RESULT([yes])
m4_ifdef([$11], [
=== modified file 'configure.in'
--- a/configure.in 2010-03-29 15:13:53 +0000
+++ b/configure.in 2010-04-01 14:34:51 +0000
@@ -2872,7 +2872,7 @@
AC_SUBST(mysql_plugin_dirs)
AC_SUBST(mysql_plugin_libs)
-AC_SUBST(mysql_plugin_defs)
+AC_SUBST(maria_plugin_defs)
# Now that sql_client_dirs and sql_server_dirs are stable, determine the union.
=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h 2010-03-29 15:13:53 +0000
+++ b/include/mysql/plugin.h 2010-04-01 14:34:51 +0000
@@ -57,7 +57,10 @@
Plugin API. Common for all plugin types.
*/
+/* MySQL plugin interface version */
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
+/* MariaDB plugin interface version */
+#define MARIA_PLUGIN_INTERFACE_VERSION 0x0100
/*
The allowable types of plugins
@@ -81,6 +84,14 @@
#define PLUGIN_LICENSE_GPL_STRING "GPL"
#define PLUGIN_LICENSE_BSD_STRING "BSD"
+/* definitions of code maturity for plugins */
+#define MariaDB_PLUGIN_MATURITY_UNKNOWN 0
+#define MariaDB_PLUGIN_MATURITY_EXPERIMENTAL 1
+#define MariaDB_PLUGIN_MATURITY_ALPHA 2
+#define MariaDB_PLUGIN_MATURITY_BETA 3
+#define MariaDB_PLUGIN_MATURITY_GAMMA 4
+#define MariaDB_PLUGIN_MATURITY_STABLE 5
+
/*
Macros for beginning and ending plugin declarations. Between
mysql_declare_plugin and mysql_declare_plugin_end there should
@@ -93,11 +104,24 @@
int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
int PSIZE= sizeof(struct st_mysql_plugin); \
struct st_mysql_plugin DECLS[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+int VERSION= MARIA_PLUGIN_INTERFACE_VERSION; \
+int PSIZE= sizeof(struct st_maria_plugin); \
+struct st_maria_plugin DECLS[]= {
+
#else
+
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]= {
+
#endif
#define mysql_declare_plugin(NAME) \
@@ -106,7 +130,14 @@
builtin_ ## NAME ## _sizeof_struct_st_plugin, \
builtin_ ## NAME ## _plugin)
+#define maria_declare_plugin(NAME) \
+MARIA_DECLARE_PLUGIN__(NAME, \
+ builtin_maria_ ## NAME ## _plugin_interface_version, \
+ builtin_maria_ ## NAME ## _sizeof_struct_st_plugin, \
+ builtin_maria_ ## NAME ## _plugin)
+
#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0}}
+#define maria_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
/*
declarations for SHOW STATUS support in plugins
@@ -403,6 +434,30 @@
void * __reserved1; /* reserved for dependency checking */
};
+/*
+ MariaDB extension for plugins declaration structure.
+
+ It also copy current MySQL plugin fields to have more independency
+ in plugins extension
+*/
+
+struct st_maria_plugin
+{
+ int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ void *info; /* pointer to type-specific plugin descriptor */
+ const char *name; /* plugin name */
+ const char *author; /* plugin author (for SHOW PLUGINS) */
+ const char *descr; /* general descriptive text (for SHOW PLUGINS ) */
+ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */
+ int (*init)(void *); /* the function to invoke when plugin is loaded */
+ int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
+ unsigned int version; /* plugin version (for SHOW PLUGINS) */
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info; /* plugin version string */
+ int maturity; /* MariaDB_PLUGIN_MATURITY_XXX */
+};
+
/*************************************************************************
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
*/
=== modified file 'include/mysql/plugin_auth.h.pp'
--- a/include/mysql/plugin_auth.h.pp 2010-03-29 15:13:53 +0000
+++ b/include/mysql/plugin_auth.h.pp 2010-04-01 14:34:51 +0000
@@ -77,6 +77,22 @@
struct st_mysql_sys_var **system_vars;
void * __reserved1;
};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ int maturity;
+};
enum enum_ftparser_mode
{
MYSQL_FTPARSER_SIMPLE_MODE= 0,
=== modified file 'plugin/auth/auth_socket.c'
--- a/plugin/auth/auth_socket.c 2010-03-29 15:13:53 +0000
+++ b/plugin/auth/auth_socket.c 2010-04-01 14:34:51 +0000
@@ -99,4 +99,21 @@
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(socket_auth)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &socket_auth_handler,
+ "socket_peercred",
+ "Sergei Golubchik",
+ "Unix Socket based authentication",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+mysql_declare_plugin_end;
=== modified file 'plugin/auth/dialog.c'
--- a/plugin/auth/dialog.c 2010-03-31 18:37:45 +0000
+++ b/plugin/auth/dialog.c 2010-04-01 14:34:51 +0000
@@ -171,6 +171,38 @@
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(dialog)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &two_handler,
+ "two_questions",
+ "Sergei Golubchik",
+ "Dialog plugin demo 1",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &three_handler,
+ "three_attempts",
+ "Sergei Golubchik",
+ "Dialog plugin demo 2",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+maria_declare_plugin_end;
/********************* CLIENT SIDE ***************************************/
/*
=== modified file 'plugin/daemon_example/daemon_example.cc'
--- a/plugin/daemon_example/daemon_example.cc 2007-06-27 14:49:12 +0000
+++ b/plugin/daemon_example/daemon_example.cc 2010-04-01 14:34:51 +0000
@@ -200,3 +200,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(daemon_example)
+{
+ MYSQL_DAEMON_PLUGIN,
+ &daemon_example_plugin,
+ "daemon_example",
+ "Brian Aker",
+ "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
+ PLUGIN_LICENSE_GPL,
+ daemon_example_plugin_init, /* Plugin Init */
+ daemon_example_plugin_deinit, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'plugin/fulltext/plugin_example.c'
--- a/plugin/fulltext/plugin_example.c 2010-01-04 17:54:42 +0000
+++ b/plugin/fulltext/plugin_example.c 2010-04-01 14:34:51 +0000
@@ -270,4 +270,21 @@
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(ftexample)
+{
+ MYSQL_FTPARSER_PLUGIN, /* type */
+ &simple_parser_descriptor, /* descriptor */
+ "simple_parser", /* name */
+ "MySQL AB", /* author */
+ "Simple Full-Text Parser", /* description */
+ PLUGIN_LICENSE_GPL,
+ simple_parser_plugin_init, /* init function (when loaded) */
+ simple_parser_plugin_deinit,/* deinit function (when unloaded) */
+ 0x0001, /* version */
+ simple_status, /* status variables */
+ simple_system_variables, /* system variables */
+ "0.01", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2010-03-29 15:13:53 +0000
+++ b/sql/ha_ndbcluster.cc 2010-04-01 14:34:51 +0000
@@ -10564,6 +10564,23 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ndbcluster)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ndbcluster_storage_engine,
+ ndbcluster_hton_name,
+ "MySQL AB",
+ "Clustered, fault-tolerant tables",
+ PLUGIN_LICENSE_GPL,
+ ndbcluster_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ ndb_status_variables_export,/* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
#else
int Sun_ar_require_a_symbol_here= 0;
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2010-03-15 11:51:23 +0000
+++ b/sql/ha_partition.cc 2010-04-01 14:34:51 +0000
@@ -6715,5 +6715,22 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(partition)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &partition_storage_engine,
+ "partition",
+ "Mikael Ronstrom, MySQL AB",
+ "Partition Storage Engine Helper",
+ PLUGIN_LICENSE_GPL,
+ partition_initialize, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#endif
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-04-01 09:04:26 +0000
+++ b/sql/log.cc 2010-04-01 14:34:51 +0000
@@ -6036,3 +6036,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(binlog)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &binlog_storage_engine,
+ "binlog",
+ "MySQL AB",
+ "This is a pseudo storage engine to represent the binlog in a transaction",
+ PLUGIN_LICENSE_GPL,
+ binlog_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-04-01 09:04:26 +0000
+++ b/sql/sql_acl.cc 2010-04-01 14:34:51 +0000
@@ -8260,3 +8260,35 @@
}
mysql_declare_plugin_end;
+maria_declare_plugin(mysql_password)
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &native_password_handler, /* type descriptor */
+ native_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Native MySQL authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* String version */
+ MariaDB_PLUGIN_MATURITY_BETA /* Maturity */
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &old_password_handler, /* type descriptor */
+ old_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Old MySQL-4.0 authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* String version */
+ MariaDB_PLUGIN_MATURITY_BETA /* Maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/sql_builtin.cc.in'
--- a/sql/sql_builtin.cc.in 2010-03-29 15:13:53 +0000
+++ b/sql/sql_builtin.cc.in 2010-04-01 14:34:51 +0000
@@ -16,13 +16,12 @@
#include <my_global.h>
#include <mysql/plugin.h>
-typedef struct st_mysql_plugin builtin_plugin[];
-
-extern builtin_plugin
- builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@;
-
-struct st_mysql_plugin *mysqld_builtins[]=
+typedef struct st_maria_plugin builtin_maria_plugin[];
+
+extern builtin_maria_plugin
+ builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@;
+
+struct st_maria_plugin *mariadb_builtins[]=
{
- builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
+ builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@,(struct st_maria_plugin *)0
};
-
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_plugin.cc 2010-04-01 14:34:51 +0000
@@ -20,7 +20,7 @@
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
-extern struct st_mysql_plugin *mysqld_builtins[];
+extern struct st_maria_plugin *mariadb_builtins[];
/**
@note The order of the enumeration is critical.
@@ -78,6 +78,14 @@
"_mysql_sizeof_struct_st_plugin_";
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
static int min_plugin_interface_version= MYSQL_PLUGIN_INTERFACE_VERSION & ~0xFF;
+static const char *maria_plugin_interface_version_sym=
+ "_maria_plugin_interface_version_";
+static const char *maria_sizeof_st_plugin_sym=
+ "_maria_sizeof_struct_st_plugin_";
+static const char *maria_plugin_declarations_sym=
+ "_maria_plugin_declarations_";
+static int min_maria_plugin_interface_version=
+ MARIA_PLUGIN_INTERFACE_VERSION & ~0xFF;
#endif
/* Note that 'int version' must be the first field of every plugin
@@ -211,7 +219,7 @@
const char *list);
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
int *, char **);
-static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *,
+static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *,
struct st_plugin_int **);
static void unlock_variables(THD *thd, struct system_variables *vars);
static void cleanup_variables(THD *thd, struct system_variables *vars);
@@ -368,6 +376,223 @@
}
+/**
+ Reads data from mysql plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report What errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+ /* Determine interface version */
+ if (!sym)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= 0;
+ plugin_dl->mysqlversion= *(int *)sym;
+ /* Versioning */
+ if (plugin_dl->mysqlversion < min_plugin_interface_version ||
+ (plugin_dl->mysqlversion >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ /* convert mysql declaration to maria one */
+ {
+ int i;
+ uint sizeof_st_plugin;
+ struct st_mysql_plugin *old;
+ struct st_maria_plugin *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ DBUG_ASSERT(min_plugin_interface_version == 0);
+ sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
+ }
+
+ for (i= 0;
+ ((struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc((i + 1) * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old= (struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ {
+
+ cur->type= old->type;
+ cur->info= old->info;
+ cur->name= old->name;
+ cur->author= old->author;
+ cur->descr= old->descr;
+ cur->license= old->license;
+ cur->init= old->init;
+ cur->deinit= old->deinit;
+ cur->version= old->version;
+ cur->status_vars= old->status_vars;
+ cur->system_vars= old->system_vars;
+ /*
+ Something like this should be added to process
+ new mysql plugin versions:
+ if (plugin_dl->mysqlversion > 0x0101)
+ {
+ cur->newfield= CONSTANT_MEANS_UNKNOWN;
+ }
+ else
+ {
+ cur->newfield= old->newfield;
+ }
+ */
+ /* Maria only fields */
+ cur->version_info= "Unknown";
+ cur->maturity= MariaDB_PLUGIN_MATURITY_UNKNOWN;
+ }
+ plugin_dl->allocated= true;
+ plugin_dl->plugins= (struct st_maria_plugin *)cur;
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Reads data from maria plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report what errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+
+ /* Determine interface version */
+ if (!(sym))
+ {
+ /*
+ Actually this branch impossible because in case of absence of maria
+ version we try mysql version.
+ */
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY,
+ maria_plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= *(int *)sym;
+ plugin_dl->mysqlversion= 0;
+ /* Versioning */
+ if (plugin_dl->mariaversion < min_maria_plugin_interface_version ||
+ (plugin_dl->mariaversion >> 8) > (MARIA_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, maria_plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, maria_plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+ if (plugin_dl->mariaversion != MARIA_PLUGIN_INTERFACE_VERSION)
+ {
+ uint sizeof_st_plugin;
+ struct st_maria_plugin *old, *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, maria_sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, maria_sizeof_st_plugin_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ if (sizeof_st_plugin != sizeof(st_mysql_plugin))
+ {
+ int i;
+ for (i= 0;
+ ((struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc((i + 1) * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old= (struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ memcpy(cur + i, old, min(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ plugin_dl->allocated= true;
+ }
+ }
+ plugin_dl->plugins= (struct st_maria_plugin *)sym;
+
+ DBUG_RETURN(FALSE);
+}
+
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
#ifdef HAVE_DLOPEN
@@ -415,22 +640,21 @@
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg);
DBUG_RETURN(0);
}
- /* Determine interface version */
- if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
+
+ /* Checks which plugin interface present and reads info */
+ if (!(sym= dlsym(plugin_dl.handle, maria_plugin_interface_version_sym)))
{
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
- DBUG_RETURN(0);
+ if (read_mysql_plugin_info(&plugin_dl,
+ dlsym(plugin_dl.handle,
+ plugin_interface_version_sym),
+ dlpath,
+ report))
+ DBUG_RETURN(0);
}
- plugin_dl.version= *(int *)sym;
- /* Versioning */
- if (plugin_dl.version < min_plugin_interface_version ||
- (plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
+ else
{
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
- "plugin interface version mismatch");
- DBUG_RETURN(0);
+ if (read_maria_plugin_info(&plugin_dl, sym, dlpath, report))
+ DBUG_RETURN(0);
}
/* link the services in */
@@ -438,7 +662,7 @@
{
if ((sym= dlsym(plugin_dl.handle, list_of_services[i].name)))
{
- uint ver= (uint)(intptr)*(void**)sym;
+ uint ver= (uint)(intptr) *(void **)sym;
if (ver > list_of_services[i].version ||
(ver >> 8) < (list_of_services[i].version >> 8))
{
@@ -449,72 +673,9 @@
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, buf);
DBUG_RETURN(0);
}
- *(void**)sym= list_of_services[i].service;
- }
- }
-
- /* Find plugin declarations */
- if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
- {
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym);
- DBUG_RETURN(0);
- }
-
- if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
- {
- uint sizeof_st_plugin;
- struct st_mysql_plugin *old, *cur;
- char *ptr= (char *)sym;
-
- if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym)))
- sizeof_st_plugin= *(int *)sym;
- else
- {
-#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, sizeof_st_plugin_sym);
- DBUG_RETURN(0);
-#else
- /*
- When the following assert starts failing, we'll have to switch
- to the upper branch of the #ifdef
- */
- DBUG_ASSERT(min_plugin_interface_version == 0);
- sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
-#endif
- }
-
- if (sizeof_st_plugin != sizeof(st_mysql_plugin))
- {
- for (i= 0;
- ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- /* no op */;
-
- cur= (struct st_mysql_plugin*)
- my_malloc((i+1)*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
- if (!cur)
- {
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
- DBUG_RETURN(0);
- }
- /*
- All st_plugin fields not initialized in the plugin explicitly, are
- set to 0. It matches C standard behaviour for struct initializers that
- have less values than the struct definition.
- */
- for (i=0;
- (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
-
- sym= cur;
- plugin_dl.allocated= true;
- }
- }
- plugin_dl.plugins= (struct st_mysql_plugin *)sym;
+ *(void **)sym= list_of_services[i].service;
+ }
+ }
/* Duplicate and convert dll name */
plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1;
@@ -756,7 +917,7 @@
int *argc, char **argv, int report)
{
struct st_plugin_int tmp;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
DBUG_ENTER("plugin_add");
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
{
@@ -1161,8 +1322,8 @@
{
uint i;
bool is_myisam;
- struct st_mysql_plugin **builtins;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin **builtins;
+ struct st_maria_plugin *plugin;
struct st_plugin_int tmp, *plugin_ptr, **reap;
MEM_ROOT tmp_root;
bool reaped_mandatory_plugin= FALSE;
@@ -1201,7 +1362,7 @@
/*
First we register builtin plugins
*/
- for (builtins= mysqld_builtins; *builtins; builtins++)
+ for (builtins= mariadb_builtins; *builtins; builtins++)
{
for (plugin= *builtins; plugin->info; plugin++)
{
@@ -1316,7 +1477,7 @@
}
-static bool register_builtin(struct st_mysql_plugin *plugin,
+static bool register_builtin(struct st_maria_plugin *plugin,
struct st_plugin_int *tmp,
struct st_plugin_int **ptr)
{
@@ -1352,7 +1513,7 @@
RETURN
false - plugin registered successfully
*/
-bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
+bool plugin_register_builtin(THD *thd, struct st_maria_plugin *plugin)
{
struct st_plugin_int tmp, *ptr;
bool result= true;
@@ -1481,7 +1642,7 @@
char buffer[FN_REFLEN];
LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
struct st_plugin_dl *plugin_dl;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
char *p= buffer;
DBUG_ENTER("plugin_load_list");
while (list)
=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_plugin.h 2010-04-01 14:34:51 +0000
@@ -52,8 +52,9 @@
{
LEX_STRING dl;
void *handle;
- struct st_mysql_plugin *plugins;
- int version;
+ struct st_maria_plugin *plugins;
+ int mysqlversion;
+ int mariaversion;
bool allocated;
uint ref_count; /* number of plugins loaded from the library */
};
@@ -63,7 +64,7 @@
struct st_plugin_int
{
LEX_STRING name;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
struct st_plugin_dl *plugin_dl;
uint state;
uint ref_count; /* number of threads using the plugin */
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_show.cc 2010-04-01 14:34:51 +0000
@@ -94,11 +94,21 @@
return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
}
+
+static const LEX_STRING maturity_name[]={
+ { C_STRING_WITH_LEN("Unknown") },
+ { C_STRING_WITH_LEN("Experimental") },
+ { C_STRING_WITH_LEN("Alpha") },
+ { C_STRING_WITH_LEN("Beta") },
+ { C_STRING_WITH_LEN("Gamma") },
+ { C_STRING_WITH_LEN("Stable") }};
+
+
static my_bool show_plugins(THD *thd, plugin_ref plugin,
void *arg)
{
TABLE *table= (TABLE*) arg;
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
CHARSET_INFO *cs= system_charset_info;
char version_buf[20];
@@ -143,7 +153,7 @@
table->field[5]->set_notnull();
table->field[6]->store(version_buf,
make_version_string(version_buf, sizeof(version_buf),
- plugin_dl->version),
+ plugin_dl->mariaversion),
cs);
table->field[6]->set_notnull();
}
@@ -186,6 +196,26 @@
}
table->field[9]->set_notnull();
+ if ((uint) plug->maturity <= MariaDB_PLUGIN_MATURITY_STABLE)
+ table->field[10]->store(maturity_name[plug->maturity].str,
+ maturity_name[plug->maturity].length,
+ cs);
+ else
+ {
+ DBUG_ASSERT(0);
+ table->field[10]->store("Unknown", 7, cs);
+ }
+ table->field[10]->set_notnull();
+
+ if (plug->version_info)
+ {
+ table->field[11]->store(plug->version_info,
+ strlen(plug->version_info), cs);
+ table->field[11]->set_notnull();
+ }
+ else
+ table->field[11]->set_null();
+
return schema_table_store_record(thd, table);
}
@@ -4398,7 +4428,7 @@
if (plugin_state(plugin) != PLUGIN_IS_READY)
{
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
if (!(wild && wild[0] &&
wild_case_compare(scs, plug->name,wild)))
{
@@ -7095,6 +7125,8 @@
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
+ {"PLUGIN_MATURITY", 12, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+ {"PLUGIN_AUTH_VERSION", 80, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
=== modified file 'storage/archive/ha_archive.cc'
--- a/storage/archive/ha_archive.cc 2010-03-04 08:03:07 +0000
+++ b/storage/archive/ha_archive.cc 2010-04-01 14:34:51 +0000
@@ -1655,4 +1655,21 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(archive)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &archive_storage_engine,
+ "ARCHIVE",
+ "Brian Aker, MySQL AB",
+ "Archive storage engine",
+ PLUGIN_LICENSE_GPL,
+ archive_db_init, /* Plugin Init */
+ archive_db_done, /* Plugin Deinit */
+ 0x0300 /* 3.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/blackhole/ha_blackhole.cc'
--- a/storage/blackhole/ha_blackhole.cc 2009-10-16 10:29:42 +0000
+++ b/storage/blackhole/ha_blackhole.cc 2010-04-01 14:34:51 +0000
@@ -369,3 +369,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(blackhole)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &blackhole_storage_engine,
+ "BLACKHOLE",
+ "MySQL AB",
+ "/dev/null storage engine (anything you write to it disappears)",
+ PLUGIN_LICENSE_GPL,
+ blackhole_init, /* Plugin Init */
+ blackhole_fini, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/csv/ha_tina.cc'
--- a/storage/csv/ha_tina.cc 2009-12-03 11:19:05 +0000
+++ b/storage/csv/ha_tina.cc 2010-04-01 14:34:51 +0000
@@ -1636,4 +1636,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
-
+maria_declare_plugin(csv)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &csv_storage_engine,
+ "CSV",
+ "Brian Aker, MySQL AB",
+ "CSV storage engine",
+ PLUGIN_LICENSE_GPL,
+ tina_init_func, /* Plugin Init */
+ tina_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/example/ha_example.cc'
--- a/storage/example/ha_example.cc 2010-03-03 14:44:14 +0000
+++ b/storage/example/ha_example.cc 2010-04-01 14:34:51 +0000
@@ -924,3 +924,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(example)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &example_storage_engine,
+ "EXAMPLE",
+ "Brian Aker, MySQL AB",
+ "Example storage engine",
+ PLUGIN_LICENSE_GPL,
+ example_init_func, /* Plugin Init */
+ example_done_func, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ func_status, /* status variables */
+ example_system_variables, /* system variables */
+ "0.1", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/federated/ha_federated.cc'
--- a/storage/federated/ha_federated.cc 2009-09-07 20:50:10 +0000
+++ b/storage/federated/ha_federated.cc 2010-04-01 14:34:51 +0000
@@ -3379,3 +3379,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federated_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith and Brian Aker, MySQL AB",
+ "Federated MySQL storage engine",
+ PLUGIN_LICENSE_GPL,
+ federated_db_init, /* Plugin Init */
+ federated_done, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/federatedx/ha_federatedx.cc'
--- a/storage/federatedx/ha_federatedx.cc 2010-03-10 10:32:14 +0000
+++ b/storage/federatedx/ha_federatedx.cc 2010-04-01 14:34:51 +0000
@@ -3505,9 +3505,26 @@
PLUGIN_LICENSE_GPL,
federatedx_db_init, /* Plugin Init */
federatedx_done, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
+ 0x0200 /* 2.0 */,
NULL, /* status variables */
NULL, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federatedx_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith",
+ "FederatedX pluggable storage engine",
+ PLUGIN_LICENSE_GPL,
+ federatedx_db_init, /* Plugin Init */
+ federatedx_done, /* Plugin Deinit */
+ 0x0200 /* 2.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "2.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/heap/ha_heap.cc'
--- a/storage/heap/ha_heap.cc 2009-09-07 20:50:10 +0000
+++ b/storage/heap/ha_heap.cc 2010-04-01 14:34:51 +0000
@@ -767,3 +767,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(heap)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &heap_storage_engine,
+ "MEMORY",
+ "MySQL AB",
+ "Hash based, stored in memory, useful for temporary tables",
+ PLUGIN_LICENSE_GPL,
+ heap_init,
+ NULL,
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/ibmdb2i/ha_ibmdb2i.cc'
--- a/storage/ibmdb2i/ha_ibmdb2i.cc 2009-12-11 07:01:16 +0000
+++ b/storage/ibmdb2i/ha_ibmdb2i.cc 2010-04-01 14:34:51 +0000
@@ -3357,3 +3357,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ibmdb2i)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ibmdb2i_storage_engine,
+ "IBMDB2I",
+ "The IBM development team in Rochester, Minnesota",
+ "IBM DB2 for i Storage Engine",
+ PLUGIN_LICENSE_GPL,
+ ibmdb2i_init_func, /* Plugin Init */
+ ibmdb2i_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ ibmdb2i_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_UNKNOWN /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc 2010-03-15 11:51:23 +0000
+++ b/storage/innobase/handler/ha_innodb.cc 2010-04-01 14:34:51 +0000
@@ -8930,6 +8930,23 @@
NULL /* reserved */
}
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase OY",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ innodb_status_variables_export, /* status variables */
+ innobase_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE, /* maturity */
+}
+maria_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/innodb_plugin/handler/i_s.cc'
--- a/storage/innodb_plugin/handler/i_s.cc 2009-10-12 12:00:56 +0000
+++ b/storage/innodb_plugin/handler/i_s.cc 2010-04-01 14:34:51 +0000
@@ -455,6 +455,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -730,6 +783,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -913,6 +1019,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
@@ -1245,6 +1404,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1295,6 +1507,60 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -1511,6 +1777,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1561,6 +1880,60 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc 2010-03-15 11:51:23 +0000
+++ b/storage/maria/ha_maria.cc 2010-04-01 14:34:51 +0000
@@ -3471,9 +3471,26 @@
PLUGIN_LICENSE_GPL,
ha_maria_init, /* Plugin Init */
NULL, /* Plugin Deinit */
- 0x0100, /* 1.0 */
+ 0x0105, /* 1.5 */
status_variables, /* status variables */
system_variables, /* system variables */
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(maria)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &maria_storage_engine,
+ "MARIA",
+ "MySQL AB",
+ "Crash-safe tables with MyISAM heritage",
+ PLUGIN_LICENSE_GPL,
+ ha_maria_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0105, /* 1.5 */
+ status_variables, /* status variables */
+ system_variables, /* system variables */
+ "1.5", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc 2010-01-04 17:54:42 +0000
+++ b/storage/myisam/ha_myisam.cc 2010-04-01 14:34:51 +0000
@@ -2174,6 +2174,23 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisam)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisam_storage_engine,
+ "MyISAM",
+ "MySQL AB",
+ "Default engine as of MySQL 3.23 with great performance",
+ PLUGIN_LICENSE_GPL,
+ myisam_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#ifdef HAVE_QUERY_CACHE
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2010-03-30 12:36:49 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-04-01 14:34:51 +0000
@@ -1289,3 +1289,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisammrg)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisammrg_storage_engine,
+ "MRG_MYISAM",
+ "MySQL AB",
+ "Collection of identical MyISAM tables",
+ PLUGIN_LICENSE_GPL,
+ myisammrg_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- a/storage/pbxt/src/ha_pbxt.cc 2010-03-31 18:37:45 +0000
+++ b/storage/pbxt/src/ha_pbxt.cc 2010-04-01 14:34:51 +0000
@@ -5919,6 +5919,40 @@
drizzle_declare_plugin_end;
#else
mysql_declare_plugin_end;
+#ifdef MARIADB_BASE_VERSION
+maria_declare_plugin(pbxt)
+{ /* PBXT */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &pbxt_storage_engine,
+ "PBXT",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "High performance, multi-versioning transactional engine",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init, /* Plugin Init */
+ pbxt_end, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ NULL, /* status variables */
+ pbxt_system_variables, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+},
+{ /* PBXT_STATISTICS */
+ MYSQL_INFORMATION_SCHEMA_PLUGIN,
+ &pbxt_statitics,
+ "PBXT_STATISTICS",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "PBXT internal system statitics",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init_statistics, /* plugin init */
+ pbxt_exit_statistics, /* plugin deinit */
+ 0x0005,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
+#endif
#endif
#if defined(XT_WIN) && defined(XT_COREDUMP)
=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- a/storage/xtradb/handler/ha_innodb.cc 2010-02-01 06:14:12 +0000
+++ b/storage/xtradb/handler/ha_innodb.cc 2010-04-01 14:34:51 +0000
@@ -10818,6 +10818,39 @@
i_s_innodb_admin_command,
i_s_innodb_patches
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{ /* InnoDB */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase Oy",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ INNODB_VERSION_SHORT,
+ innodb_status_variables_export,/* status variables */
+ innobase_system_variables, /* system variables */
+ INNODB_VERSION_STR, /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+},
+i_s_innodb_rseg_maria,
+i_s_innodb_buffer_pool_pages_maria,
+i_s_innodb_buffer_pool_pages_index_maria,
+i_s_innodb_buffer_pool_pages_blob_maria,
+i_s_innodb_trx_maria,
+i_s_innodb_locks_maria,
+i_s_innodb_lock_waits_maria,
+i_s_innodb_cmp_maria,
+i_s_innodb_cmp_reset_maria,
+i_s_innodb_cmpmem_maria,
+i_s_innodb_cmpmem_reset_maria,
+i_s_innodb_table_stats_maria,
+i_s_innodb_index_stats_maria,
+i_s_innodb_admin_command_maria,
+i_s_innodb_patches_maria
+maria_declare_plugin_end;
+
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/xtradb/handler/i_s.cc'
--- a/storage/xtradb/handler/i_s.cc 2010-03-31 20:50:54 +0000
+++ b/storage/xtradb/handler/i_s.cc 2010-04-01 14:34:51 +0000
@@ -393,6 +393,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_patches_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "XTRADB_ENHANCEMENTS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Percona"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Enhancements applied to InnoDB plugin"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_patches_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_fields_info[] =
{
@@ -1040,6 +1093,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1089,6 +1195,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool index pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1138,6 +1297,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool blob pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
static ST_FIELD_INFO innodb_trx_fields_info[] =
@@ -1373,6 +1585,60 @@
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -1648,6 +1914,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -1831,6 +2150,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
@@ -2163,6 +2535,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2213,6 +2638,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -2431,6 +2909,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2481,6 +3012,60 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
@@ -2660,6 +3245,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_rseg_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_RSEG"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB rollback segment information"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_rseg_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_table_stats_info[] =
@@ -2940,6 +3578,23 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_table_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_TABLE_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB table statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_table_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats =
{
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
@@ -2956,6 +3611,23 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_index_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_INDEX_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB index statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_index_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_admin_command_info[] =
@@ -3121,3 +3793,20 @@
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_admin_command_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "XtraDB specific command acceptor"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_admin_command_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
=== modified file 'storage/xtradb/handler/i_s.h'
--- a/storage/xtradb/handler/i_s.h 2009-11-04 20:11:12 +0000
+++ b/storage/xtradb/handler/i_s.h 2010-04-01 14:34:51 +0000
@@ -42,4 +42,20 @@
extern struct st_mysql_plugin i_s_innodb_index_stats;
extern struct st_mysql_plugin i_s_innodb_admin_command;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria;
+extern struct st_maria_plugin i_s_innodb_trx_maria;
+extern struct st_maria_plugin i_s_innodb_locks_maria;
+extern struct st_maria_plugin i_s_innodb_lock_waits_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_reset_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_reset_maria;
+extern struct st_maria_plugin i_s_innodb_patches_maria;
+extern struct st_maria_plugin i_s_innodb_rseg_maria;
+extern struct st_maria_plugin i_s_innodb_table_stats_maria;
+extern struct st_maria_plugin i_s_innodb_index_stats_maria;
+extern struct st_maria_plugin i_s_innodb_admin_command_maria;
+
#endif /* i_s_h */
1
0

[Maria-developers] Rev 2761: Maria WL#61 in file:///Users/bell/maria/bzr/work-maria-5.2-engine-backup/
by sanja@askmonty.org 01 Apr '10
by sanja@askmonty.org 01 Apr '10
01 Apr '10
At file:///Users/bell/maria/bzr/work-maria-5.2-engine-backup/
------------------------------------------------------------
revno: 2761
revision-id: sanja(a)askmonty.org-20100401121502-80l92vwisynnoizv
parent: sanja(a)askmonty.org-20100330123515-4p8q03xccl3d6k59
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-engine-backup
timestamp: Thu 2010-04-01 15:15:02 +0300
message:
Maria WL#61
Interface for maria extensions.
Alternative plugin interface with additional info (maturity and string version).
=== modified file 'CMakeLists.txt'
--- a/CMakeLists.txt 2010-03-15 11:51:23 +0000
+++ b/CMakeLists.txt 2010-04-01 12:15:02 +0000
@@ -260,7 +260,7 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
ENDIF(WITH_${ENGINE}_STORAGE_ENGINE AND MYSQL_PLUGIN_STATIC)
IF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_${PLUGIN_NAME}_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${PLUGIN_NAME}_plugin")
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${PLUGIN_NAME})
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
@@ -279,7 +279,7 @@ ENDFOREACH(SUBDIR ${STORAGE_SUBDIRS})
# Special handling for partition(not really pluggable)
IF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_PARTITION_STORAGE_ENGINE")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_partition_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_partition_plugin")
ENDIF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
# Special handling for tmp tables with the maria engine
=== modified file 'config/ac-macros/plugins.m4'
--- a/config/ac-macros/plugins.m4 2010-03-29 15:14:28 +0000
+++ b/config/ac-macros/plugins.m4 2010-04-01 12:15:02 +0000
@@ -460,7 +460,7 @@ dnl Although this is "pretty", it breaks
])
])
])
- mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]"
+ maria_plugin_defs="$maria_plugin_defs, [builtin_maria_]$2[_plugin]"
[with_plugin_]$2=yes
AC_MSG_RESULT([yes])
m4_ifdef([$11], [
=== modified file 'configure.in'
--- a/configure.in 2010-03-29 15:13:53 +0000
+++ b/configure.in 2010-04-01 12:15:02 +0000
@@ -2872,7 +2872,7 @@ AC_SUBST(server_scripts)
AC_SUBST(mysql_plugin_dirs)
AC_SUBST(mysql_plugin_libs)
-AC_SUBST(mysql_plugin_defs)
+AC_SUBST(maria_plugin_defs)
# Now that sql_client_dirs and sql_server_dirs are stable, determine the union.
=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h 2010-03-29 15:13:53 +0000
+++ b/include/mysql/plugin.h 2010-04-01 12:15:02 +0000
@@ -57,7 +57,10 @@ typedef struct st_mysql_xid MYSQL_XID;
Plugin API. Common for all plugin types.
*/
+/* MySQL plugin interface version */
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
+/* MariaDB plugin interface version */
+#define MARIA_PLUGIN_INTERFACE_VERSION 0x0100
/*
The allowable types of plugins
@@ -81,6 +84,14 @@ typedef struct st_mysql_xid MYSQL_XID;
#define PLUGIN_LICENSE_GPL_STRING "GPL"
#define PLUGIN_LICENSE_BSD_STRING "BSD"
+/* definitions of code maturity for plugins */
+#define MariaDB_PLUGIN_MATURITY_UNKNOWN 0
+#define MariaDB_PLUGIN_MATURITY_EXPERIMENTAL 1
+#define MariaDB_PLUGIN_MATURITY_ALPHA 2
+#define MariaDB_PLUGIN_MATURITY_BETA 3
+#define MariaDB_PLUGIN_MATURITY_GAMMA 4
+#define MariaDB_PLUGIN_MATURITY_STABLE 5
+
/*
Macros for beginning and ending plugin declarations. Between
mysql_declare_plugin and mysql_declare_plugin_end there should
@@ -93,7 +105,14 @@ typedef struct st_mysql_xid MYSQL_XID;
int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
int PSIZE= sizeof(struct st_mysql_plugin); \
struct st_mysql_plugin DECLS[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+int VERSION= MARIA_PLUGIN_INTERFACE_VERSION; \
+int PSIZE= sizeof(struct st_maria_plugin); \
+struct st_maria_plugin DECLS[]= {
+
#else
+
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
@@ -98,6 +117,12 @@ struct st_mysql_plugin DECLS[]= {
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]= {
+
#endif
#define mysql_declare_plugin(NAME) \
@@ -106,7 +131,14 @@ __MYSQL_DECLARE_PLUGIN(NAME, \
builtin_ ## NAME ## _sizeof_struct_st_plugin, \
builtin_ ## NAME ## _plugin)
+#define maria_declare_plugin(NAME) \
+MARIA_DECLARE_PLUGIN__(NAME, \
+ builtin_maria_ ## NAME ## _plugin_interface_version, \
+ builtin_maria_ ## NAME ## _sizeof_struct_st_plugin, \
+ builtin_maria_ ## NAME ## _plugin)
+
#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0}}
+#define maria_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
/*
declarations for SHOW STATUS support in plugins
@@ -403,6 +435,30 @@ struct st_mysql_plugin
void * __reserved1; /* reserved for dependency checking */
};
+/*
+ MariaDB extension for plugins declaration structure.
+
+ It also copy current MySQL plugin fields to have more independency
+ in plugins extension
+*/
+
+struct st_maria_plugin
+{
+ int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ void *info; /* pointer to type-specific plugin descriptor */
+ const char *name; /* plugin name */
+ const char *author; /* plugin author (for SHOW PLUGINS) */
+ const char *descr; /* general descriptive text (for SHOW PLUGINS ) */
+ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */
+ int (*init)(void *); /* the function to invoke when plugin is loaded */
+ int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
+ unsigned int version; /* plugin version (for SHOW PLUGINS) */
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info; /* plugin version string */
+ int maturity; /* MariaDB_PLUGIN_MATURITY_XXX */
+};
+
/*************************************************************************
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
*/
=== modified file 'include/mysql/plugin_auth.h.pp'
--- a/include/mysql/plugin_auth.h.pp 2010-03-29 15:13:53 +0000
+++ b/include/mysql/plugin_auth.h.pp 2010-04-01 12:15:02 +0000
@@ -77,6 +77,22 @@ struct st_mysql_plugin
struct st_mysql_sys_var **system_vars;
void * __reserved1;
};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ int maturity;
+};
enum enum_ftparser_mode
{
MYSQL_FTPARSER_SIMPLE_MODE= 0,
=== modified file 'plugin/auth/auth_socket.c'
--- a/plugin/auth/auth_socket.c 2010-03-29 15:13:53 +0000
+++ b/plugin/auth/auth_socket.c 2010-04-01 12:15:02 +0000
@@ -99,4 +99,21 @@ mysql_declare_plugin(socket_auth)
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(socket_auth)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &socket_auth_handler,
+ "socket_peercred",
+ "Sergei Golubchik",
+ "Unix Socket based authentication",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+mysql_declare_plugin_end;
=== modified file 'plugin/auth/dialog.c'
--- a/plugin/auth/dialog.c 2010-03-29 15:13:53 +0000
+++ b/plugin/auth/dialog.c 2010-04-01 12:15:02 +0000
@@ -165,6 +165,38 @@ mysql_declare_plugin(dialog)
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(dialog)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &two_handler,
+ "two_questions",
+ "Sergei Golubchik",
+ "Dialog plugin demo 1",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &three_handler,
+ "three_attempts",
+ "Sergei Golubchik",
+ "Dialog plugin demo 2",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+maria_declare_plugin_end;
/********************* CLIENT SIDE ***************************************/
/*
=== modified file 'plugin/daemon_example/daemon_example.cc'
--- a/plugin/daemon_example/daemon_example.cc 2007-06-27 14:49:12 +0000
+++ b/plugin/daemon_example/daemon_example.cc 2010-04-01 12:15:02 +0000
@@ -200,3 +200,20 @@ mysql_declare_plugin(daemon_example)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(daemon_example)
+{
+ MYSQL_DAEMON_PLUGIN,
+ &daemon_example_plugin,
+ "daemon_example",
+ "Brian Aker",
+ "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
+ PLUGIN_LICENSE_GPL,
+ daemon_example_plugin_init, /* Plugin Init */
+ daemon_example_plugin_deinit, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'plugin/fulltext/plugin_example.c'
--- a/plugin/fulltext/plugin_example.c 2010-01-04 17:54:42 +0000
+++ b/plugin/fulltext/plugin_example.c 2010-04-01 12:15:02 +0000
@@ -270,4 +270,21 @@ mysql_declare_plugin(ftexample)
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(ftexample)
+{
+ MYSQL_FTPARSER_PLUGIN, /* type */
+ &simple_parser_descriptor, /* descriptor */
+ "simple_parser", /* name */
+ "MySQL AB", /* author */
+ "Simple Full-Text Parser", /* description */
+ PLUGIN_LICENSE_GPL,
+ simple_parser_plugin_init, /* init function (when loaded) */
+ simple_parser_plugin_deinit,/* deinit function (when unloaded) */
+ 0x0001, /* version */
+ simple_status, /* status variables */
+ simple_system_variables, /* system variables */
+ "0.01", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2010-03-29 15:13:53 +0000
+++ b/sql/ha_ndbcluster.cc 2010-04-01 12:15:02 +0000
@@ -10564,6 +10564,23 @@ mysql_declare_plugin(ndbcluster)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ndbcluster)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ndbcluster_storage_engine,
+ ndbcluster_hton_name,
+ "MySQL AB",
+ "Clustered, fault-tolerant tables",
+ PLUGIN_LICENSE_GPL,
+ ndbcluster_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ ndb_status_variables_export,/* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
#else
int Sun_ar_require_a_symbol_here= 0;
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2010-03-15 11:51:23 +0000
+++ b/sql/ha_partition.cc 2010-04-01 12:15:02 +0000
@@ -6715,5 +6715,22 @@ mysql_declare_plugin(partition)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(partition)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &partition_storage_engine,
+ "partition",
+ "Mikael Ronstrom, MySQL AB",
+ "Partition Storage Engine Helper",
+ PLUGIN_LICENSE_GPL,
+ partition_initialize, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#endif
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-03-15 11:51:23 +0000
+++ b/sql/log.cc 2010-04-01 12:15:02 +0000
@@ -6028,3 +6028,20 @@ mysql_declare_plugin(binlog)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(binlog)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &binlog_storage_engine,
+ "binlog",
+ "MySQL AB",
+ "This is a pseudo storage engine to represent the binlog in a transaction",
+ PLUGIN_LICENSE_GPL,
+ binlog_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_acl.cc 2010-04-01 12:15:02 +0000
@@ -8254,3 +8254,35 @@ mysql_declare_plugin(mysql_password)
}
mysql_declare_plugin_end;
+maria_declare_plugin(mysql_password)
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &native_password_handler, /* type descriptor */
+ native_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Native MySQL authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* String version */
+ MariaDB_PLUGIN_MATURITY_BETA /* Maturity */
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &old_password_handler, /* type descriptor */
+ old_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Old MySQL-4.0 authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* String version */
+ MariaDB_PLUGIN_MATURITY_BETA /* Maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/sql_builtin.cc.in'
--- a/sql/sql_builtin.cc.in 2010-03-29 15:13:53 +0000
+++ b/sql/sql_builtin.cc.in 2010-04-01 12:15:02 +0000
@@ -16,13 +16,12 @@
#include <my_global.h>
#include <mysql/plugin.h>
-typedef struct st_mysql_plugin builtin_plugin[];
+typedef struct st_maria_plugin builtin_maria_plugin[];
-extern builtin_plugin
- builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@;
+extern builtin_maria_plugin
+ builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@;
-struct st_mysql_plugin *mysqld_builtins[]=
+struct st_maria_plugin *mariadb_builtins[]=
{
- builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
+ builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@,(struct st_maria_plugin *)0
};
-
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_plugin.cc 2010-04-01 12:15:02 +0000
@@ -20,7 +20,7 @@
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
-extern struct st_mysql_plugin *mysqld_builtins[];
+extern struct st_maria_plugin *mariadb_builtins[];
/**
@note The order of the enumeration is critical.
@@ -78,6 +78,14 @@ static const char *sizeof_st_plugin_sym=
"_mysql_sizeof_struct_st_plugin_";
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
static int min_plugin_interface_version= MYSQL_PLUGIN_INTERFACE_VERSION & ~0xFF;
+static const char *maria_plugin_interface_version_sym=
+ "_maria_plugin_interface_version_";
+static const char *maria_sizeof_st_plugin_sym=
+ "_maria_sizeof_struct_st_plugin_";
+static const char *maria_plugin_declarations_sym=
+ "_maria_plugin_declarations_";
+static int min_maria_plugin_interface_version=
+ MARIA_PLUGIN_INTERFACE_VERSION & ~0xFF;
#endif
/* Note that 'int version' must be the first field of every plugin
@@ -211,7 +219,7 @@ static bool plugin_load_list(MEM_ROOT *t
const char *list);
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
int *, char **);
-static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *,
+static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *,
struct st_plugin_int **);
static void unlock_variables(THD *thd, struct system_variables *vars);
static void cleanup_variables(THD *thd, struct system_variables *vars);
@@ -368,6 +376,223 @@ static inline void free_plugin_mem(struc
}
+/**
+ Reads data from mysql plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report What errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+ /* Determine interface version */
+ if (!sym)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= 0;
+ plugin_dl->mysqlversion= *(int *)sym;
+ /* Versioning */
+ if (plugin_dl->mysqlversion < min_plugin_interface_version ||
+ (plugin_dl->mysqlversion >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ /* convert mysql declaration to maria one */
+ {
+ int i;
+ uint sizeof_st_plugin;
+ struct st_mysql_plugin *old;
+ struct st_maria_plugin *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ DBUG_ASSERT(min_plugin_interface_version == 0);
+ sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
+ }
+
+ for (i= 0;
+ ((struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc((i + 1) * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old= (struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ {
+
+ cur->type= old->type;
+ cur->info= old->info;
+ cur->name= old->name;
+ cur->author= old->author;
+ cur->descr= old->descr;
+ cur->license= old->license;
+ cur->init= old->init;
+ cur->deinit= old->deinit;
+ cur->version= old->version;
+ cur->status_vars= old->status_vars;
+ cur->system_vars= old->system_vars;
+ /*
+ Something like this should be added to process
+ new mysql plugin versions:
+ if (plugin_dl->mysqlversion > 0x0101)
+ {
+ cur->newfield= CONSTANT_MEANS_UNKNOWN;
+ }
+ else
+ {
+ cur->newfield= old->newfield;
+ }
+ */
+ /* Maria only fields */
+ cur->version_info= "Unknown";
+ cur->maturity= MariaDB_PLUGIN_MATURITY_UNKNOWN;
+ }
+ plugin_dl->allocated= true;
+ plugin_dl->plugins= (struct st_maria_plugin *)cur;
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Reads data from maria plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report what errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+
+ /* Determine interface version */
+ if (!(sym))
+ {
+ /*
+ Actually this branch impossible because in case of absence of maria
+ version we try mysql version.
+ */
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY,
+ maria_plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= *(int *)sym;
+ plugin_dl->mysqlversion= 0;
+ /* Versioning */
+ if (plugin_dl->mariaversion < min_maria_plugin_interface_version ||
+ (plugin_dl->mariaversion >> 8) > (MARIA_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, maria_plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, maria_plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+ if (plugin_dl->mariaversion != MARIA_PLUGIN_INTERFACE_VERSION)
+ {
+ uint sizeof_st_plugin;
+ struct st_maria_plugin *old, *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, maria_sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, maria_sizeof_st_plugin_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ if (sizeof_st_plugin != sizeof(st_mysql_plugin))
+ {
+ int i;
+ for (i= 0;
+ ((struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc((i + 1) * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old= (struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ memcpy(cur + i, old, min(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ plugin_dl->allocated= true;
+ }
+ }
+ plugin_dl->plugins= (struct st_maria_plugin *)sym;
+
+ DBUG_RETURN(FALSE);
+}
+
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
#ifdef HAVE_DLOPEN
@@ -415,22 +640,21 @@ static st_plugin_dl *plugin_dl_add(const
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg);
DBUG_RETURN(0);
}
- /* Determine interface version */
- if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
+
+ /* Checks which plugin interface present and reads info */
+ if (!(sym= dlsym(plugin_dl.handle, maria_plugin_interface_version_sym)))
{
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
- DBUG_RETURN(0);
+ if (read_mysql_plugin_info(&plugin_dl,
+ dlsym(plugin_dl.handle,
+ plugin_interface_version_sym),
+ dlpath,
+ report))
+ DBUG_RETURN(0);
}
- plugin_dl.version= *(int *)sym;
- /* Versioning */
- if (plugin_dl.version < min_plugin_interface_version ||
- (plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
+ else
{
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
- "plugin interface version mismatch");
- DBUG_RETURN(0);
+ if (read_maria_plugin_info(&plugin_dl, sym, dlpath, report))
+ DBUG_RETURN(0);
}
/* link the services in */
@@ -438,7 +662,7 @@ static st_plugin_dl *plugin_dl_add(const
{
if ((sym= dlsym(plugin_dl.handle, list_of_services[i].name)))
{
- uint ver= (uint)(intptr)*(void**)sym;
+ uint ver= (uint)(intptr) *(void **)sym;
if (ver > list_of_services[i].version ||
(ver >> 8) < (list_of_services[i].version >> 8))
{
@@ -449,72 +673,9 @@ static st_plugin_dl *plugin_dl_add(const
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, buf);
DBUG_RETURN(0);
}
- *(void**)sym= list_of_services[i].service;
- }
- }
-
- /* Find plugin declarations */
- if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
- {
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym);
- DBUG_RETURN(0);
- }
-
- if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
- {
- uint sizeof_st_plugin;
- struct st_mysql_plugin *old, *cur;
- char *ptr= (char *)sym;
-
- if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym)))
- sizeof_st_plugin= *(int *)sym;
- else
- {
-#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, sizeof_st_plugin_sym);
- DBUG_RETURN(0);
-#else
- /*
- When the following assert starts failing, we'll have to switch
- to the upper branch of the #ifdef
- */
- DBUG_ASSERT(min_plugin_interface_version == 0);
- sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
-#endif
- }
-
- if (sizeof_st_plugin != sizeof(st_mysql_plugin))
- {
- for (i= 0;
- ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- /* no op */;
-
- cur= (struct st_mysql_plugin*)
- my_malloc((i+1)*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
- if (!cur)
- {
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
- DBUG_RETURN(0);
- }
- /*
- All st_plugin fields not initialized in the plugin explicitly, are
- set to 0. It matches C standard behaviour for struct initializers that
- have less values than the struct definition.
- */
- for (i=0;
- (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
-
- sym= cur;
- plugin_dl.allocated= true;
+ *(void **)sym= list_of_services[i].service;
}
}
- plugin_dl.plugins= (struct st_mysql_plugin *)sym;
/* Duplicate and convert dll name */
plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1;
@@ -756,7 +917,7 @@ static bool plugin_add(MEM_ROOT *tmp_roo
int *argc, char **argv, int report)
{
struct st_plugin_int tmp;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
DBUG_ENTER("plugin_add");
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
{
@@ -1161,8 +1322,8 @@ int plugin_init(int *argc, char **argv,
{
uint i;
bool is_myisam;
- struct st_mysql_plugin **builtins;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin **builtins;
+ struct st_maria_plugin *plugin;
struct st_plugin_int tmp, *plugin_ptr, **reap;
MEM_ROOT tmp_root;
bool reaped_mandatory_plugin= FALSE;
@@ -1201,7 +1362,7 @@ int plugin_init(int *argc, char **argv,
/*
First we register builtin plugins
*/
- for (builtins= mysqld_builtins; *builtins; builtins++)
+ for (builtins= mariadb_builtins; *builtins; builtins++)
{
for (plugin= *builtins; plugin->info; plugin++)
{
@@ -1316,7 +1477,7 @@ err:
}
-static bool register_builtin(struct st_mysql_plugin *plugin,
+static bool register_builtin(struct st_maria_plugin *plugin,
struct st_plugin_int *tmp,
struct st_plugin_int **ptr)
{
@@ -1352,7 +1513,7 @@ static bool register_builtin(struct st_m
RETURN
false - plugin registered successfully
*/
-bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
+bool plugin_register_builtin(THD *thd, struct st_maria_plugin *plugin)
{
struct st_plugin_int tmp, *ptr;
bool result= true;
@@ -1481,7 +1642,7 @@ static bool plugin_load_list(MEM_ROOT *t
char buffer[FN_REFLEN];
LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
struct st_plugin_dl *plugin_dl;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
char *p= buffer;
DBUG_ENTER("plugin_load_list");
while (list)
=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_plugin.h 2010-04-01 12:15:02 +0000
@@ -52,8 +52,9 @@ struct st_plugin_dl
{
LEX_STRING dl;
void *handle;
- struct st_mysql_plugin *plugins;
- int version;
+ struct st_maria_plugin *plugins;
+ int mysqlversion;
+ int mariaversion;
bool allocated;
uint ref_count; /* number of plugins loaded from the library */
};
@@ -63,7 +64,7 @@ struct st_plugin_dl
struct st_plugin_int
{
LEX_STRING name;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
struct st_plugin_dl *plugin_dl;
uint state;
uint ref_count; /* number of threads using the plugin */
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_show.cc 2010-04-01 12:15:02 +0000
@@ -94,11 +94,21 @@ static int make_version_string(char *buf
return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
}
+
+static const LEX_STRING maturity_name[]={
+ { C_STRING_WITH_LEN("Unknown") },
+ { C_STRING_WITH_LEN("Experimental") },
+ { C_STRING_WITH_LEN("Alpha") },
+ { C_STRING_WITH_LEN("Beta") },
+ { C_STRING_WITH_LEN("Gamma") },
+ { C_STRING_WITH_LEN("Stable") }};
+
+
static my_bool show_plugins(THD *thd, plugin_ref plugin,
void *arg)
{
TABLE *table= (TABLE*) arg;
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
CHARSET_INFO *cs= system_charset_info;
char version_buf[20];
@@ -143,7 +153,7 @@ static my_bool show_plugins(THD *thd, pl
table->field[5]->set_notnull();
table->field[6]->store(version_buf,
make_version_string(version_buf, sizeof(version_buf),
- plugin_dl->version),
+ plugin_dl->mariaversion),
cs);
table->field[6]->set_notnull();
}
@@ -186,6 +196,26 @@ static my_bool show_plugins(THD *thd, pl
}
table->field[9]->set_notnull();
+ if ((uint) plug->maturity <= MariaDB_PLUGIN_MATURITY_STABLE)
+ table->field[10]->store(maturity_name[plug->maturity].str,
+ maturity_name[plug->maturity].length,
+ cs);
+ else
+ {
+ DBUG_ASSERT(0);
+ table->field[10]->store("Unknown", 7, cs);
+ }
+ table->field[10]->set_notnull();
+
+ if (plug->version_info)
+ {
+ table->field[11]->store(plug->version_info,
+ strlen(plug->version_info), cs);
+ table->field[11]->set_notnull();
+ }
+ else
+ table->field[11]->set_null();
+
return schema_table_store_record(thd, table);
}
@@ -4398,7 +4428,7 @@ static my_bool iter_schema_engines(THD *
if (plugin_state(plugin) != PLUGIN_IS_READY)
{
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
if (!(wild && wild[0] &&
wild_case_compare(scs, plug->name,wild)))
{
@@ -7095,6 +7125,8 @@ ST_FIELD_INFO plugin_fields_info[]=
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
+ {"PLUGIN_MATURITY", 12, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+ {"PLUGIN_AUTH_VERSION", 80, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
=== modified file 'storage/archive/ha_archive.cc'
--- a/storage/archive/ha_archive.cc 2010-03-04 08:03:07 +0000
+++ b/storage/archive/ha_archive.cc 2010-04-01 12:15:02 +0000
@@ -1655,4 +1655,21 @@ mysql_declare_plugin(archive)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(archive)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &archive_storage_engine,
+ "ARCHIVE",
+ "Brian Aker, MySQL AB",
+ "Archive storage engine",
+ PLUGIN_LICENSE_GPL,
+ archive_db_init, /* Plugin Init */
+ archive_db_done, /* Plugin Deinit */
+ 0x0300 /* 3.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/blackhole/ha_blackhole.cc'
--- a/storage/blackhole/ha_blackhole.cc 2009-10-16 10:29:42 +0000
+++ b/storage/blackhole/ha_blackhole.cc 2010-04-01 12:15:02 +0000
@@ -369,3 +369,20 @@ mysql_declare_plugin(blackhole)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(blackhole)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &blackhole_storage_engine,
+ "BLACKHOLE",
+ "MySQL AB",
+ "/dev/null storage engine (anything you write to it disappears)",
+ PLUGIN_LICENSE_GPL,
+ blackhole_init, /* Plugin Init */
+ blackhole_fini, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/csv/ha_tina.cc'
--- a/storage/csv/ha_tina.cc 2009-12-03 11:19:05 +0000
+++ b/storage/csv/ha_tina.cc 2010-04-01 12:15:02 +0000
@@ -1636,4 +1636,20 @@ mysql_declare_plugin(csv)
NULL /* config options */
}
mysql_declare_plugin_end;
-
+maria_declare_plugin(csv)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &csv_storage_engine,
+ "CSV",
+ "Brian Aker, MySQL AB",
+ "CSV storage engine",
+ PLUGIN_LICENSE_GPL,
+ tina_init_func, /* Plugin Init */
+ tina_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/example/ha_example.cc'
--- a/storage/example/ha_example.cc 2010-03-03 14:44:14 +0000
+++ b/storage/example/ha_example.cc 2010-04-01 12:15:02 +0000
@@ -924,3 +924,20 @@ mysql_declare_plugin(example)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(example)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &example_storage_engine,
+ "EXAMPLE",
+ "Brian Aker, MySQL AB",
+ "Example storage engine",
+ PLUGIN_LICENSE_GPL,
+ example_init_func, /* Plugin Init */
+ example_done_func, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ func_status, /* status variables */
+ example_system_variables, /* system variables */
+ "0.1", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/federated/ha_federated.cc'
--- a/storage/federated/ha_federated.cc 2009-09-07 20:50:10 +0000
+++ b/storage/federated/ha_federated.cc 2010-04-01 12:15:02 +0000
@@ -3379,3 +3379,20 @@ mysql_declare_plugin(federated)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federated_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith and Brian Aker, MySQL AB",
+ "Federated MySQL storage engine",
+ PLUGIN_LICENSE_GPL,
+ federated_db_init, /* Plugin Init */
+ federated_done, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/federatedx/ha_federatedx.cc'
--- a/storage/federatedx/ha_federatedx.cc 2010-03-10 10:32:14 +0000
+++ b/storage/federatedx/ha_federatedx.cc 2010-04-01 12:15:02 +0000
@@ -3505,9 +3505,26 @@ mysql_declare_plugin(federated)
PLUGIN_LICENSE_GPL,
federatedx_db_init, /* Plugin Init */
federatedx_done, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
+ 0x0200 /* 2.0 */,
NULL, /* status variables */
NULL, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federatedx_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith",
+ "FederatedX pluggable storage engine",
+ PLUGIN_LICENSE_GPL,
+ federatedx_db_init, /* Plugin Init */
+ federatedx_done, /* Plugin Deinit */
+ 0x0200 /* 2.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "2.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/heap/ha_heap.cc'
--- a/storage/heap/ha_heap.cc 2009-09-07 20:50:10 +0000
+++ b/storage/heap/ha_heap.cc 2010-04-01 12:15:02 +0000
@@ -767,3 +767,20 @@ mysql_declare_plugin(heap)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(heap)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &heap_storage_engine,
+ "MEMORY",
+ "MySQL AB",
+ "Hash based, stored in memory, useful for temporary tables",
+ PLUGIN_LICENSE_GPL,
+ heap_init,
+ NULL,
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/ibmdb2i/ha_ibmdb2i.cc'
--- a/storage/ibmdb2i/ha_ibmdb2i.cc 2009-12-11 07:01:16 +0000
+++ b/storage/ibmdb2i/ha_ibmdb2i.cc 2010-04-01 12:15:02 +0000
@@ -3357,3 +3357,20 @@ mysql_declare_plugin(ibmdb2i)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ibmdb2i)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ibmdb2i_storage_engine,
+ "IBMDB2I",
+ "The IBM development team in Rochester, Minnesota",
+ "IBM DB2 for i Storage Engine",
+ PLUGIN_LICENSE_GPL,
+ ibmdb2i_init_func, /* Plugin Init */
+ ibmdb2i_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ ibmdb2i_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_UNKNOWN /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc 2010-03-15 11:51:23 +0000
+++ b/storage/innobase/handler/ha_innodb.cc 2010-04-01 12:15:02 +0000
@@ -8930,6 +8930,23 @@ mysql_declare_plugin(innobase)
NULL /* reserved */
}
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase OY",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ innodb_status_variables_export, /* status variables */
+ innobase_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE, /* maturity */
+}
+maria_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/innodb_plugin/handler/i_s.cc'
--- a/storage/innodb_plugin/handler/i_s.cc 2009-10-12 12:00:56 +0000
+++ b/storage/innodb_plugin/handler/i_s.cc 2010-04-01 12:15:02 +0000
@@ -455,6 +455,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -730,6 +783,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -913,6 +1019,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
@@ -1245,6 +1404,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1295,6 +1507,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -1511,6 +1777,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1561,6 +1880,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc 2010-03-15 11:51:23 +0000
+++ b/storage/maria/ha_maria.cc 2010-04-01 12:15:02 +0000
@@ -3471,9 +3471,26 @@ mysql_declare_plugin(maria)
PLUGIN_LICENSE_GPL,
ha_maria_init, /* Plugin Init */
NULL, /* Plugin Deinit */
- 0x0100, /* 1.0 */
+ 0x0105, /* 1.5 */
status_variables, /* status variables */
system_variables, /* system variables */
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(maria)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &maria_storage_engine,
+ "MARIA",
+ "MySQL AB",
+ "Crash-safe tables with MyISAM heritage",
+ PLUGIN_LICENSE_GPL,
+ ha_maria_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0105, /* 1.5 */
+ status_variables, /* status variables */
+ system_variables, /* system variables */
+ "1.5", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc 2010-01-04 17:54:42 +0000
+++ b/storage/myisam/ha_myisam.cc 2010-04-01 12:15:02 +0000
@@ -2174,6 +2174,23 @@ mysql_declare_plugin(myisam)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisam)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisam_storage_engine,
+ "MyISAM",
+ "MySQL AB",
+ "Default engine as of MySQL 3.23 with great performance",
+ PLUGIN_LICENSE_GPL,
+ myisam_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#ifdef HAVE_QUERY_CACHE
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2010-03-04 08:03:07 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-04-01 12:15:02 +0000
@@ -1289,3 +1289,20 @@ mysql_declare_plugin(myisammrg)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisammrg)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisammrg_storage_engine,
+ "MRG_MYISAM",
+ "MySQL AB",
+ "Collection of identical MyISAM tables",
+ PLUGIN_LICENSE_GPL,
+ myisammrg_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- a/storage/pbxt/src/ha_pbxt.cc 2010-03-03 14:44:14 +0000
+++ b/storage/pbxt/src/ha_pbxt.cc 2010-04-01 12:15:02 +0000
@@ -5921,6 +5921,40 @@ mysql_declare_plugin(pbxt)
drizzle_declare_plugin_end;
#else
mysql_declare_plugin_end;
+#ifdef MARIADB_BASE_VERSION
+maria_declare_plugin(pbxt)
+{ /* PBXT */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &pbxt_storage_engine,
+ "PBXT",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "High performance, multi-versioning transactional engine",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init, /* Plugin Init */
+ pbxt_end, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ NULL, /* status variables */
+ pbxt_system_variables, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+},
+{ /* PBXT_STATISTICS */
+ MYSQL_INFORMATION_SCHEMA_PLUGIN,
+ &pbxt_statitics,
+ "PBXT_STATISTICS",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "PBXT internal system statitics",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init_statistics, /* plugin init */
+ pbxt_exit_statistics, /* plugin deinit */
+ 0x0005,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
+#endif
#endif
#if defined(XT_WIN) && defined(XT_COREDUMP)
=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- a/storage/xtradb/handler/ha_innodb.cc 2010-02-01 06:14:12 +0000
+++ b/storage/xtradb/handler/ha_innodb.cc 2010-04-01 12:15:02 +0000
@@ -10818,6 +10818,39 @@ i_s_innodb_index_stats,
i_s_innodb_admin_command,
i_s_innodb_patches
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{ /* InnoDB */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase Oy",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ INNODB_VERSION_SHORT,
+ innodb_status_variables_export,/* status variables */
+ innobase_system_variables, /* system variables */
+ INNODB_VERSION_STR, /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+},
+i_s_innodb_rseg_maria,
+i_s_innodb_buffer_pool_pages_maria,
+i_s_innodb_buffer_pool_pages_index_maria,
+i_s_innodb_buffer_pool_pages_blob_maria,
+i_s_innodb_trx_maria,
+i_s_innodb_locks_maria,
+i_s_innodb_lock_waits_maria,
+i_s_innodb_cmp_maria,
+i_s_innodb_cmp_reset_maria,
+i_s_innodb_cmpmem_maria,
+i_s_innodb_cmpmem_reset_maria,
+i_s_innodb_table_stats_maria,
+i_s_innodb_index_stats_maria,
+i_s_innodb_admin_command_maria,
+i_s_innodb_patches_maria
+maria_declare_plugin_end;
+
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/xtradb/handler/i_s.cc'
--- a/storage/xtradb/handler/i_s.cc 2010-01-28 11:35:10 +0000
+++ b/storage/xtradb/handler/i_s.cc 2010-04-01 12:15:02 +0000
@@ -393,6 +393,59 @@ UNIV_INTERN struct st_mysql_plugin
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_patches_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "XTRADB_ENHANCEMENTS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Percona"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Enhancements applied to InnoDB plugin"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_patches_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_fields_info[] =
{
@@ -1040,6 +1093,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1089,6 +1195,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool index pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1138,6 +1297,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool blob pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
static ST_FIELD_INFO innodb_trx_fields_info[] =
@@ -1373,6 +1585,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -1648,6 +1914,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -1831,22 +2150,75 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
-/*******************************************************************//**
-Common function to fill any of the dynamic tables:
-INFORMATION_SCHEMA.innodb_trx
-INFORMATION_SCHEMA.innodb_locks
-INFORMATION_SCHEMA.innodb_lock_waits
-@return 0 on success */
-static
-int
-trx_i_s_common_fill_table(
-/*======================*/
- THD* thd, /*!< in: thread */
- TABLE_LIST* tables, /*!< in/out: tables to fill */
- COND* cond) /*!< in: condition (not used) */
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
{
- const char* table_name;
- int ret;
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
+/*******************************************************************//**
+Common function to fill any of the dynamic tables:
+INFORMATION_SCHEMA.innodb_trx
+INFORMATION_SCHEMA.innodb_locks
+INFORMATION_SCHEMA.innodb_lock_waits
+@return 0 on success */
+static
+int
+trx_i_s_common_fill_table(
+/*======================*/
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (not used) */
+{
+ const char* table_name;
+ int ret;
trx_i_s_cache_t* cache;
DBUG_ENTER("trx_i_s_common_fill_table");
@@ -2163,6 +2535,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2213,6 +2638,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -2431,6 +2909,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2481,6 +3012,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
@@ -2660,6 +3245,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_rseg_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_RSEG"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB rollback segment information"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_rseg_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_table_stats_info[] =
@@ -2940,6 +3578,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_table_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_TABLE_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB table statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_table_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats =
{
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
@@ -2956,6 +3611,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_index_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_INDEX_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB index statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_index_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_admin_command_info[] =
@@ -3122,3 +3794,20 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_admin_command_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "XtraDB specific command acceptor"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_admin_command_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
=== modified file 'storage/xtradb/handler/i_s.h'
--- a/storage/xtradb/handler/i_s.h 2009-11-04 20:11:12 +0000
+++ b/storage/xtradb/handler/i_s.h 2010-04-01 12:15:02 +0000
@@ -42,4 +42,20 @@ extern struct st_mysql_plugin i_s_innodb
extern struct st_mysql_plugin i_s_innodb_index_stats;
extern struct st_mysql_plugin i_s_innodb_admin_command;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria;
+extern struct st_maria_plugin i_s_innodb_trx_maria;
+extern struct st_maria_plugin i_s_innodb_locks_maria;
+extern struct st_maria_plugin i_s_innodb_lock_waits_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_reset_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_reset_maria;
+extern struct st_maria_plugin i_s_innodb_patches_maria;
+extern struct st_maria_plugin i_s_innodb_rseg_maria;
+extern struct st_maria_plugin i_s_innodb_table_stats_maria;
+extern struct st_maria_plugin i_s_innodb_index_stats_maria;
+extern struct st_maria_plugin i_s_innodb_admin_command_maria;
+
#endif /* i_s_h */
1
0

[Maria-developers] New (by Shinguz): Index usage tracker (103)
by worklog-noreply@askmonty.org 01 Apr '10
by worklog-noreply@askmonty.org 01 Apr '10
01 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Index usage tracker
CREATION DATE..: Wed, 10 Mar 2010, 11:29
SUPERVISOR.....: Bothorsen
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-BackLog
TASK ID........: 103 (http://askmonty.org/worklog/?tid=103)
VERSION........: Benchmarks-3.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
What indexes are needed is often easy to find. What is more difficult is to find
which indexes are not used at all.
Thus some statistics about the index usage would be nice.
I think Percona has already something like this done some time ago. And big O
has similar functionality.
I could imagine something like this:
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| table_name | index_name | index_length | create_time | update_time
| use_time | read_first | read_key | read_next | full_scan |
range_scan |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| test_table | idx1 | 1234567890 | 2010-01-01 00:00:00 | 2010-01-01
00:00:00 | 2010-03-10 11:34:56 | 1234 | 42560 | 2468 | 234 |
321 |
| test_table | idx2 | 123456 | 2010-01-01 00:00:00 | NULL
| NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx3 | 234561 | 2010-01-01 00:00:00 | 2010-03-10
11:12:34 | 2010-03-10 11:34:56 | 7890 | 89890 | 15780 | 678 |
321 |
| test_table | idx4 | 345612 | 2010-01-01 00:00:00 | 2010-03-10
11:34:56 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx5 | 456123 | 2010-01-01 00:00:00 | 2010-03-10
06:56:12 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx6 | 561234 | 2010-01-01 00:00:00 | 2010-03-10
01:12:34 | 2010-03-10 11:34:42 | 3456 | 12356 | 6912 | 123 |
12 |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
3
2

[Maria-developers] Updated (by Monty): Index usage tracker (103)
by worklog-noreply@askmonty.org 01 Apr '10
by worklog-noreply@askmonty.org 01 Apr '10
01 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Index usage tracker
CREATION DATE..: Wed, 10 Mar 2010, 11:29
SUPERVISOR.....: Bothorsen
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-BackLog
TASK ID........: 103 (http://askmonty.org/worklog/?tid=103)
VERSION........: Server-9.x
STATUS.........: Complete
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
-=-=(Monty - Thu, 01 Apr 2010, 12:00)=-=-
Version updated.
--- /tmp/wklog.103.old.21119 2010-04-01 12:00:42.000000000 +0000
+++ /tmp/wklog.103.new.21119 2010-04-01 12:00:42.000000000 +0000
@@ -1 +1 @@
-Benchmarks-3.0
+Server-9.x
-=-=(Monty - Thu, 01 Apr 2010, 12:00)=-=-
Status updated.
--- /tmp/wklog.103.old.21119 2010-04-01 12:00:42.000000000 +0000
+++ /tmp/wklog.103.new.21119 2010-04-01 12:00:42.000000000 +0000
@@ -1 +1 @@
-Un-Assigned
+Complete
-=-=(Monty - Thu, 01 Apr 2010, 12:00)=-=-
High Level Description modified.
--- /tmp/wklog.103.old.21108 2010-04-01 12:00:33.000000000 +0000
+++ /tmp/wklog.103.new.21108 2010-04-01 12:00:33.000000000 +0000
@@ -1,3 +1,7 @@
+Update: We have already in MariaDB 5.2 SHOW INDEX STATISTICS that provides the
+requested information.
+
+
What indexes are needed is often easy to find. What is more difficult is to find
which indexes are not used at all.
@@ -33,6 +37,7 @@
12 |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
+
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
-=-=(Shinguz - Wed, 10 Mar 2010, 11:30)=-=-
High Level Description modified.
--- /tmp/wklog.103.old.30875 2010-03-10 11:30:45.000000000 +0000
+++ /tmp/wklog.103.new.30875 2010-03-10 11:30:45.000000000 +0000
@@ -35,3 +35,6 @@
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
+
+If some more specification is need for implementation let me know and I will
+collect the stuff from the sources mentioned above.
DESCRIPTION:
Update: We have already in MariaDB 5.2 SHOW INDEX STATISTICS that provides the
requested information.
What indexes are needed is often easy to find. What is more difficult is to find
which indexes are not used at all.
Thus some statistics about the index usage would be nice.
I think Percona has already something like this done some time ago. And big O
has similar functionality.
I could imagine something like this:
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| table_name | index_name | index_length | create_time | update_time
| use_time | read_first | read_key | read_next | full_scan |
range_scan |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| test_table | idx1 | 1234567890 | 2010-01-01 00:00:00 | 2010-01-01
00:00:00 | 2010-03-10 11:34:56 | 1234 | 42560 | 2468 | 234 |
321 |
| test_table | idx2 | 123456 | 2010-01-01 00:00:00 | NULL
| NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx3 | 234561 | 2010-01-01 00:00:00 | 2010-03-10
11:12:34 | 2010-03-10 11:34:56 | 7890 | 89890 | 15780 | 678 |
321 |
| test_table | idx4 | 345612 | 2010-01-01 00:00:00 | 2010-03-10
11:34:56 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx5 | 456123 | 2010-01-01 00:00:00 | 2010-03-10
06:56:12 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx6 | 561234 | 2010-01-01 00:00:00 | 2010-03-10
01:12:34 | 2010-03-10 11:34:42 | 3456 | 12356 | 6912 | 123 |
12 |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
If some more specification is need for implementation let me know and I will
collect the stuff from the sources mentioned above.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Updated (by Monty): Index usage tracker (103)
by worklog-noreply@askmonty.org 01 Apr '10
by worklog-noreply@askmonty.org 01 Apr '10
01 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Index usage tracker
CREATION DATE..: Wed, 10 Mar 2010, 11:29
SUPERVISOR.....: Bothorsen
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-BackLog
TASK ID........: 103 (http://askmonty.org/worklog/?tid=103)
VERSION........: Server-9.x
STATUS.........: Complete
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
-=-=(Monty - Thu, 01 Apr 2010, 12:00)=-=-
Version updated.
--- /tmp/wklog.103.old.21119 2010-04-01 12:00:42.000000000 +0000
+++ /tmp/wklog.103.new.21119 2010-04-01 12:00:42.000000000 +0000
@@ -1 +1 @@
-Benchmarks-3.0
+Server-9.x
-=-=(Monty - Thu, 01 Apr 2010, 12:00)=-=-
Status updated.
--- /tmp/wklog.103.old.21119 2010-04-01 12:00:42.000000000 +0000
+++ /tmp/wklog.103.new.21119 2010-04-01 12:00:42.000000000 +0000
@@ -1 +1 @@
-Un-Assigned
+Complete
-=-=(Monty - Thu, 01 Apr 2010, 12:00)=-=-
High Level Description modified.
--- /tmp/wklog.103.old.21108 2010-04-01 12:00:33.000000000 +0000
+++ /tmp/wklog.103.new.21108 2010-04-01 12:00:33.000000000 +0000
@@ -1,3 +1,7 @@
+Update: We have already in MariaDB 5.2 SHOW INDEX STATISTICS that provides the
+requested information.
+
+
What indexes are needed is often easy to find. What is more difficult is to find
which indexes are not used at all.
@@ -33,6 +37,7 @@
12 |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
+
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
-=-=(Shinguz - Wed, 10 Mar 2010, 11:30)=-=-
High Level Description modified.
--- /tmp/wklog.103.old.30875 2010-03-10 11:30:45.000000000 +0000
+++ /tmp/wklog.103.new.30875 2010-03-10 11:30:45.000000000 +0000
@@ -35,3 +35,6 @@
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
+
+If some more specification is need for implementation let me know and I will
+collect the stuff from the sources mentioned above.
DESCRIPTION:
Update: We have already in MariaDB 5.2 SHOW INDEX STATISTICS that provides the
requested information.
What indexes are needed is often easy to find. What is more difficult is to find
which indexes are not used at all.
Thus some statistics about the index usage would be nice.
I think Percona has already something like this done some time ago. And big O
has similar functionality.
I could imagine something like this:
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| table_name | index_name | index_length | create_time | update_time
| use_time | read_first | read_key | read_next | full_scan |
range_scan |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| test_table | idx1 | 1234567890 | 2010-01-01 00:00:00 | 2010-01-01
00:00:00 | 2010-03-10 11:34:56 | 1234 | 42560 | 2468 | 234 |
321 |
| test_table | idx2 | 123456 | 2010-01-01 00:00:00 | NULL
| NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx3 | 234561 | 2010-01-01 00:00:00 | 2010-03-10
11:12:34 | 2010-03-10 11:34:56 | 7890 | 89890 | 15780 | 678 |
321 |
| test_table | idx4 | 345612 | 2010-01-01 00:00:00 | 2010-03-10
11:34:56 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx5 | 456123 | 2010-01-01 00:00:00 | 2010-03-10
06:56:12 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx6 | 561234 | 2010-01-01 00:00:00 | 2010-03-10
01:12:34 | 2010-03-10 11:34:42 | 3456 | 12356 | 6912 | 123 |
12 |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
If some more specification is need for implementation let me know and I will
collect the stuff from the sources mentioned above.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Updated (by Monty): Index usage tracker (103)
by worklog-noreply@askmonty.org 01 Apr '10
by worklog-noreply@askmonty.org 01 Apr '10
01 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Index usage tracker
CREATION DATE..: Wed, 10 Mar 2010, 11:29
SUPERVISOR.....: Bothorsen
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-BackLog
TASK ID........: 103 (http://askmonty.org/worklog/?tid=103)
VERSION........: Benchmarks-3.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
-=-=(Monty - Thu, 01 Apr 2010, 12:00)=-=-
High Level Description modified.
--- /tmp/wklog.103.old.21108 2010-04-01 12:00:33.000000000 +0000
+++ /tmp/wklog.103.new.21108 2010-04-01 12:00:33.000000000 +0000
@@ -1,3 +1,7 @@
+Update: We have already in MariaDB 5.2 SHOW INDEX STATISTICS that provides the
+requested information.
+
+
What indexes are needed is often easy to find. What is more difficult is to find
which indexes are not used at all.
@@ -33,6 +37,7 @@
12 |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
+
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
-=-=(Shinguz - Wed, 10 Mar 2010, 11:30)=-=-
High Level Description modified.
--- /tmp/wklog.103.old.30875 2010-03-10 11:30:45.000000000 +0000
+++ /tmp/wklog.103.new.30875 2010-03-10 11:30:45.000000000 +0000
@@ -35,3 +35,6 @@
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
+
+If some more specification is need for implementation let me know and I will
+collect the stuff from the sources mentioned above.
DESCRIPTION:
Update: We have already in MariaDB 5.2 SHOW INDEX STATISTICS that provides the
requested information.
What indexes are needed is often easy to find. What is more difficult is to find
which indexes are not used at all.
Thus some statistics about the index usage would be nice.
I think Percona has already something like this done some time ago. And big O
has similar functionality.
I could imagine something like this:
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| table_name | index_name | index_length | create_time | update_time
| use_time | read_first | read_key | read_next | full_scan |
range_scan |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| test_table | idx1 | 1234567890 | 2010-01-01 00:00:00 | 2010-01-01
00:00:00 | 2010-03-10 11:34:56 | 1234 | 42560 | 2468 | 234 |
321 |
| test_table | idx2 | 123456 | 2010-01-01 00:00:00 | NULL
| NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx3 | 234561 | 2010-01-01 00:00:00 | 2010-03-10
11:12:34 | 2010-03-10 11:34:56 | 7890 | 89890 | 15780 | 678 |
321 |
| test_table | idx4 | 345612 | 2010-01-01 00:00:00 | 2010-03-10
11:34:56 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx5 | 456123 | 2010-01-01 00:00:00 | 2010-03-10
06:56:12 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx6 | 561234 | 2010-01-01 00:00:00 | 2010-03-10
01:12:34 | 2010-03-10 11:34:42 | 3456 | 12356 | 6912 | 123 |
12 |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
If some more specification is need for implementation let me know and I will
collect the stuff from the sources mentioned above.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Updated (by Monty): Index usage tracker (103)
by worklog-noreply@askmonty.org 01 Apr '10
by worklog-noreply@askmonty.org 01 Apr '10
01 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Index usage tracker
CREATION DATE..: Wed, 10 Mar 2010, 11:29
SUPERVISOR.....: Bothorsen
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Client-BackLog
TASK ID........: 103 (http://askmonty.org/worklog/?tid=103)
VERSION........: Benchmarks-3.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
-=-=(Monty - Thu, 01 Apr 2010, 12:00)=-=-
High Level Description modified.
--- /tmp/wklog.103.old.21108 2010-04-01 12:00:33.000000000 +0000
+++ /tmp/wklog.103.new.21108 2010-04-01 12:00:33.000000000 +0000
@@ -1,3 +1,7 @@
+Update: We have already in MariaDB 5.2 SHOW INDEX STATISTICS that provides the
+requested information.
+
+
What indexes are needed is often easy to find. What is more difficult is to find
which indexes are not used at all.
@@ -33,6 +37,7 @@
12 |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
+
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
-=-=(Shinguz - Wed, 10 Mar 2010, 11:30)=-=-
High Level Description modified.
--- /tmp/wklog.103.old.30875 2010-03-10 11:30:45.000000000 +0000
+++ /tmp/wklog.103.new.30875 2010-03-10 11:30:45.000000000 +0000
@@ -35,3 +35,6 @@
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
+
+If some more specification is need for implementation let me know and I will
+collect the stuff from the sources mentioned above.
DESCRIPTION:
Update: We have already in MariaDB 5.2 SHOW INDEX STATISTICS that provides the
requested information.
What indexes are needed is often easy to find. What is more difficult is to find
which indexes are not used at all.
Thus some statistics about the index usage would be nice.
I think Percona has already something like this done some time ago. And big O
has similar functionality.
I could imagine something like this:
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| table_name | index_name | index_length | create_time | update_time
| use_time | read_first | read_key | read_next | full_scan |
range_scan |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
| test_table | idx1 | 1234567890 | 2010-01-01 00:00:00 | 2010-01-01
00:00:00 | 2010-03-10 11:34:56 | 1234 | 42560 | 2468 | 234 |
321 |
| test_table | idx2 | 123456 | 2010-01-01 00:00:00 | NULL
| NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx3 | 234561 | 2010-01-01 00:00:00 | 2010-03-10
11:12:34 | 2010-03-10 11:34:56 | 7890 | 89890 | 15780 | 678 |
321 |
| test_table | idx4 | 345612 | 2010-01-01 00:00:00 | 2010-03-10
11:34:56 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx5 | 456123 | 2010-01-01 00:00:00 | 2010-03-10
06:56:12 | NULL | 0 | 0 | 0 | 0 |
0 |
| test_table | idx6 | 561234 | 2010-01-01 00:00:00 | 2010-03-10
01:12:34 | 2010-03-10 11:34:42 | 3456 | 12356 | 6912 | 123 |
12 |
+------------+------------+--------------+---------------------+---------------------+---------------------+------------+----------+-----------+-----------+------------+
Possibly this could/should be implemented on the handler interface level because
there we know what we are touching? But I am not familiar with the code.
If some more specification is need for implementation let me know and I will
collect the stuff from the sources mentioned above.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Rev 2761: Maria WL#61 in file:///Users/bell/maria/bzr/work-maria-5.2-engine-backup/
by sanja@askmonty.org 01 Apr '10
by sanja@askmonty.org 01 Apr '10
01 Apr '10
At file:///Users/bell/maria/bzr/work-maria-5.2-engine-backup/
------------------------------------------------------------
revno: 2761
revision-id: sanja(a)askmonty.org-20100330203255-1pyz892qsqg1liov
parent: sanja(a)askmonty.org-20100330123515-4p8q03xccl3d6k59
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-engine-backup
timestamp: Tue 2010-03-30 23:32:55 +0300
message:
Maria WL#61
Interface for maria extensions.
Alternative plugin interface with additional info (maturity and string version).
=== modified file 'CMakeLists.txt'
--- a/CMakeLists.txt 2010-03-15 11:51:23 +0000
+++ b/CMakeLists.txt 2010-03-30 20:32:55 +0000
@@ -260,7 +260,7 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
ENDIF(WITH_${ENGINE}_STORAGE_ENGINE AND MYSQL_PLUGIN_STATIC)
IF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_${PLUGIN_NAME}_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${PLUGIN_NAME}_plugin")
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${PLUGIN_NAME})
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
@@ -279,7 +279,7 @@ ENDFOREACH(SUBDIR ${STORAGE_SUBDIRS})
# Special handling for partition(not really pluggable)
IF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_PARTITION_STORAGE_ENGINE")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_partition_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_partition_plugin")
ENDIF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
# Special handling for tmp tables with the maria engine
=== modified file 'config/ac-macros/plugins.m4'
--- a/config/ac-macros/plugins.m4 2010-03-29 15:14:28 +0000
+++ b/config/ac-macros/plugins.m4 2010-03-30 20:32:55 +0000
@@ -460,7 +460,7 @@ dnl Although this is "pretty", it breaks
])
])
])
- mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]"
+ maria_plugin_defs="$maria_plugin_defs, [builtin_maria_]$2[_plugin]"
[with_plugin_]$2=yes
AC_MSG_RESULT([yes])
m4_ifdef([$11], [
=== modified file 'configure.in'
--- a/configure.in 2010-03-29 15:13:53 +0000
+++ b/configure.in 2010-03-30 20:32:55 +0000
@@ -2872,7 +2872,7 @@ AC_SUBST(server_scripts)
AC_SUBST(mysql_plugin_dirs)
AC_SUBST(mysql_plugin_libs)
-AC_SUBST(mysql_plugin_defs)
+AC_SUBST(maria_plugin_defs)
# Now that sql_client_dirs and sql_server_dirs are stable, determine the union.
=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h 2010-03-29 15:13:53 +0000
+++ b/include/mysql/plugin.h 2010-03-30 20:32:55 +0000
@@ -57,7 +57,10 @@ typedef struct st_mysql_xid MYSQL_XID;
Plugin API. Common for all plugin types.
*/
+/* MySQL plugin interface version */
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
+/* MariaDB plugin interface version */
+#define MARIA_PLUGIN_INTERFACE_VERSION 0x0100
/*
The allowable types of plugins
@@ -81,6 +84,14 @@ typedef struct st_mysql_xid MYSQL_XID;
#define PLUGIN_LICENSE_GPL_STRING "GPL"
#define PLUGIN_LICENSE_BSD_STRING "BSD"
+/* definitions of code maturity for plugins */
+#define MariaDB_PLUGIN_MATURITY_UNKNOWN 0
+#define MariaDB_PLUGIN_MATURITY_EXPERIMENTAL 1
+#define MariaDB_PLUGIN_MATURITY_ALPHA 2
+#define MariaDB_PLUGIN_MATURITY_BETA 3
+#define MariaDB_PLUGIN_MATURITY_GAMMA 4
+#define MariaDB_PLUGIN_MATURITY_STABLE 5
+
/*
Macros for beginning and ending plugin declarations. Between
mysql_declare_plugin and mysql_declare_plugin_end there should
@@ -93,7 +105,14 @@ typedef struct st_mysql_xid MYSQL_XID;
int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
int PSIZE= sizeof(struct st_mysql_plugin); \
struct st_mysql_plugin DECLS[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+int VERSION= MARIA_PLUGIN_INTERFACE_VERSION; \
+int PSIZE= sizeof(struct st_maria_plugin); \
+struct st_maria_plugin DECLS[]= {
+
#else
+
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
@@ -98,6 +117,12 @@ struct st_mysql_plugin DECLS[]= {
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]= {
+
#endif
#define mysql_declare_plugin(NAME) \
@@ -106,7 +131,14 @@ __MYSQL_DECLARE_PLUGIN(NAME, \
builtin_ ## NAME ## _sizeof_struct_st_plugin, \
builtin_ ## NAME ## _plugin)
+#define maria_declare_plugin(NAME) \
+MARIA_DECLARE_PLUGIN__(NAME, \
+ builtin_maria_ ## NAME ## _plugin_interface_version, \
+ builtin_maria_ ## NAME ## _sizeof_struct_st_plugin, \
+ builtin_maria_ ## NAME ## _plugin)
+
#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0}}
+#define maria_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
/*
declarations for SHOW STATUS support in plugins
@@ -403,6 +435,30 @@ struct st_mysql_plugin
void * __reserved1; /* reserved for dependency checking */
};
+/*
+ MariaDB extension for plugins declaration structure.
+
+ It also copy current MySQL plugin fields to have more independency
+ in plugins extension
+*/
+
+struct st_maria_plugin
+{
+ int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ void *info; /* pointer to type-specific plugin descriptor */
+ const char *name; /* plugin name */
+ const char *author; /* plugin author (for SHOW PLUGINS) */
+ const char *descr; /* general descriptive text (for SHOW PLUGINS ) */
+ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */
+ int (*init)(void *); /* the function to invoke when plugin is loaded */
+ int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
+ unsigned int version; /* plugin version (for SHOW PLUGINS) */
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info; /* plugin version string */
+ int maturity; /* MariaDB_PLUGIN_MATURITY_XXX */
+};
+
/*************************************************************************
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
*/
=== modified file 'include/mysql/plugin_auth.h.pp'
--- a/include/mysql/plugin_auth.h.pp 2010-03-29 15:13:53 +0000
+++ b/include/mysql/plugin_auth.h.pp 2010-03-30 20:32:55 +0000
@@ -77,6 +77,22 @@ struct st_mysql_plugin
struct st_mysql_sys_var **system_vars;
void * __reserved1;
};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ int maturity;
+};
enum enum_ftparser_mode
{
MYSQL_FTPARSER_SIMPLE_MODE= 0,
=== modified file 'plugin/auth/auth_socket.c'
--- a/plugin/auth/auth_socket.c 2010-03-29 15:13:53 +0000
+++ b/plugin/auth/auth_socket.c 2010-03-30 20:32:55 +0000
@@ -99,4 +99,21 @@ mysql_declare_plugin(socket_auth)
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(socket_auth)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &socket_auth_handler,
+ "socket_peercred",
+ "Sergei Golubchik",
+ "Unix Socket based authentication",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+mysql_declare_plugin_end;
=== modified file 'plugin/auth/dialog.c'
--- a/plugin/auth/dialog.c 2010-03-29 15:13:53 +0000
+++ b/plugin/auth/dialog.c 2010-03-30 20:32:55 +0000
@@ -165,6 +165,38 @@ mysql_declare_plugin(dialog)
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(dialog)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &two_handler,
+ "two_questions",
+ "Sergei Golubchik",
+ "Dialog plugin demo 1",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &three_handler,
+ "three_attempts",
+ "Sergei Golubchik",
+ "Dialog plugin demo 2",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+maria_declare_plugin_end;
/********************* CLIENT SIDE ***************************************/
/*
=== modified file 'plugin/daemon_example/daemon_example.cc'
--- a/plugin/daemon_example/daemon_example.cc 2007-06-27 14:49:12 +0000
+++ b/plugin/daemon_example/daemon_example.cc 2010-03-30 20:32:55 +0000
@@ -200,3 +200,20 @@ mysql_declare_plugin(daemon_example)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(daemon_example)
+{
+ MYSQL_DAEMON_PLUGIN,
+ &daemon_example_plugin,
+ "daemon_example",
+ "Brian Aker",
+ "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
+ PLUGIN_LICENSE_GPL,
+ daemon_example_plugin_init, /* Plugin Init */
+ daemon_example_plugin_deinit, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'plugin/fulltext/plugin_example.c'
--- a/plugin/fulltext/plugin_example.c 2010-01-04 17:54:42 +0000
+++ b/plugin/fulltext/plugin_example.c 2010-03-30 20:32:55 +0000
@@ -270,4 +270,21 @@ mysql_declare_plugin(ftexample)
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(ftexample)
+{
+ MYSQL_FTPARSER_PLUGIN, /* type */
+ &simple_parser_descriptor, /* descriptor */
+ "simple_parser", /* name */
+ "MySQL AB", /* author */
+ "Simple Full-Text Parser", /* description */
+ PLUGIN_LICENSE_GPL,
+ simple_parser_plugin_init, /* init function (when loaded) */
+ simple_parser_plugin_deinit,/* deinit function (when unloaded) */
+ 0x0001, /* version */
+ simple_status, /* status variables */
+ simple_system_variables, /* system variables */
+ "0.01", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2010-03-29 15:13:53 +0000
+++ b/sql/ha_ndbcluster.cc 2010-03-30 20:32:55 +0000
@@ -10564,6 +10564,23 @@ mysql_declare_plugin(ndbcluster)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ndbcluster)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ndbcluster_storage_engine,
+ ndbcluster_hton_name,
+ "MySQL AB",
+ "Clustered, fault-tolerant tables",
+ PLUGIN_LICENSE_GPL,
+ ndbcluster_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ ndb_status_variables_export,/* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
#else
int Sun_ar_require_a_symbol_here= 0;
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2010-03-15 11:51:23 +0000
+++ b/sql/ha_partition.cc 2010-03-30 20:32:55 +0000
@@ -6715,5 +6715,22 @@ mysql_declare_plugin(partition)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(partition)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &partition_storage_engine,
+ "partition",
+ "Mikael Ronstrom, MySQL AB",
+ "Partition Storage Engine Helper",
+ PLUGIN_LICENSE_GPL,
+ partition_initialize, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#endif
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-03-15 11:51:23 +0000
+++ b/sql/log.cc 2010-03-30 20:32:55 +0000
@@ -6028,3 +6028,20 @@ mysql_declare_plugin(binlog)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(binlog)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &binlog_storage_engine,
+ "binlog",
+ "MySQL AB",
+ "This is a pseudo storage engine to represent the binlog in a transaction",
+ PLUGIN_LICENSE_GPL,
+ binlog_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_acl.cc 2010-03-30 20:32:55 +0000
@@ -8254,3 +8254,35 @@ mysql_declare_plugin(mysql_password)
}
mysql_declare_plugin_end;
+maria_declare_plugin(mysql_password)
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &native_password_handler, /* type descriptor */
+ native_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Native MySQL authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* String version */
+ MariaDB_PLUGIN_MATURITY_BETA /* Maturity */
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &old_password_handler, /* type descriptor */
+ old_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Old MySQL-4.0 authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* String version */
+ MariaDB_PLUGIN_MATURITY_BETA /* Maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/sql_builtin.cc.in'
--- a/sql/sql_builtin.cc.in 2010-03-29 15:13:53 +0000
+++ b/sql/sql_builtin.cc.in 2010-03-30 20:32:55 +0000
@@ -16,13 +16,12 @@
#include <my_global.h>
#include <mysql/plugin.h>
-typedef struct st_mysql_plugin builtin_plugin[];
+typedef struct st_maria_plugin builtin_maria_plugin[];
-extern builtin_plugin
- builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@;
+extern builtin_maria_plugin
+ builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@;
-struct st_mysql_plugin *mysqld_builtins[]=
+struct st_maria_plugin *mariadb_builtins[]=
{
- builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
+ builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin@maria_plugin_defs@,(struct st_maria_plugin *)0
};
-
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_plugin.cc 2010-03-30 20:32:55 +0000
@@ -20,7 +20,7 @@
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
-extern struct st_mysql_plugin *mysqld_builtins[];
+extern struct st_maria_plugin *mariadb_builtins[];
/**
@note The order of the enumeration is critical.
@@ -78,6 +78,14 @@ static const char *sizeof_st_plugin_sym=
"_mysql_sizeof_struct_st_plugin_";
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
static int min_plugin_interface_version= MYSQL_PLUGIN_INTERFACE_VERSION & ~0xFF;
+static const char *maria_plugin_interface_version_sym=
+ "_maria_plugin_interface_version_";
+static const char *maria_sizeof_st_plugin_sym=
+ "_maria_sizeof_struct_st_plugin_";
+static const char *maria_plugin_declarations_sym=
+ "_maria_plugin_declarations_";
+static int min_maria_plugin_interface_version=
+ MARIA_PLUGIN_INTERFACE_VERSION & ~0xFF;
#endif
/* Note that 'int version' must be the first field of every plugin
@@ -211,7 +219,7 @@ static bool plugin_load_list(MEM_ROOT *t
const char *list);
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
int *, char **);
-static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *,
+static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *,
struct st_plugin_int **);
static void unlock_variables(THD *thd, struct system_variables *vars);
static void cleanup_variables(THD *thd, struct system_variables *vars);
@@ -368,6 +376,223 @@ static inline void free_plugin_mem(struc
}
+/**
+ Reads data from mysql plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report What errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+ /* Determine interface version */
+ if (!sym)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= 0;
+ plugin_dl->mysqlversion= *(int *)sym;
+ /* Versioning */
+ if (plugin_dl->mysqlversion < min_plugin_interface_version ||
+ (plugin_dl->mysqlversion >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ /* convert mysql declaration to maria one */
+ {
+ int i;
+ uint sizeof_st_plugin;
+ struct st_mysql_plugin *old;
+ struct st_maria_plugin *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ DBUG_ASSERT(min_plugin_interface_version == 0);
+ sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
+ }
+
+ for (i= 0;
+ ((struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc((i + 1) * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old= (struct st_mysql_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ {
+
+ cur->type= old->type;
+ cur->info= old->info;
+ cur->name= old->name;
+ cur->author= old->author;
+ cur->descr= old->descr;
+ cur->license= old->license;
+ cur->init= old->init;
+ cur->deinit= old->deinit;
+ cur->version= old->version;
+ cur->status_vars= old->status_vars;
+ cur->system_vars= old->system_vars;
+ /*
+ Something like this should be added to process
+ new mysql plugin versions:
+ if (plugin_dl->mysqlversion > 0x0101)
+ {
+ cur->newfield= CONSTANT_MEANS_UNKNOWN;
+ }
+ else
+ {
+ cur->newfield= old->newfield;
+ }
+ */
+ /* Maria only fields */
+ cur->version_info= "Unknown";
+ cur->maturity= MariaDB_PLUGIN_MATURITY_UNKNOWN;
+ }
+ plugin_dl->allocated= true;
+ plugin_dl->plugins= (struct st_maria_plugin *)cur;
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Reads data from maria plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report what errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+
+ /* Determine interface version */
+ if (!(sym))
+ {
+ /*
+ Actually this branch impossible because in case of absence of maria
+ version we try mysql version.
+ */
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY,
+ maria_plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= *(int *)sym;
+ plugin_dl->mysqlversion= 0;
+ /* Versioning */
+ if (plugin_dl->mariaversion < min_maria_plugin_interface_version ||
+ (plugin_dl->mariaversion >> 8) > (MARIA_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, maria_plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, maria_plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+ if (plugin_dl->mariaversion != MARIA_PLUGIN_INTERFACE_VERSION)
+ {
+ uint sizeof_st_plugin;
+ struct st_maria_plugin *old, *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, maria_sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, maria_sizeof_st_plugin_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ if (sizeof_st_plugin != sizeof(st_mysql_plugin))
+ {
+ int i;
+ for (i= 0;
+ ((struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc((i + 1) * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old= (struct st_maria_plugin *)(ptr + i * sizeof_st_plugin))->info;
+ i++)
+ memcpy(cur + i, old, min(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ plugin_dl->allocated= true;
+ }
+ }
+ plugin_dl->plugins= (struct st_maria_plugin *)sym;
+
+ DBUG_RETURN(FALSE);
+}
+
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
#ifdef HAVE_DLOPEN
@@ -415,22 +640,21 @@ static st_plugin_dl *plugin_dl_add(const
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg);
DBUG_RETURN(0);
}
- /* Determine interface version */
- if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
+
+ /* Checks which plugin interface present and reads info */
+ if (!(sym= dlsym(plugin_dl.handle, maria_plugin_interface_version_sym)))
{
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
- DBUG_RETURN(0);
+ if (read_mysql_plugin_info(&plugin_dl,
+ dlsym(plugin_dl.handle,
+ plugin_interface_version_sym),
+ dlpath,
+ report))
+ DBUG_RETURN(0);
}
- plugin_dl.version= *(int *)sym;
- /* Versioning */
- if (plugin_dl.version < min_plugin_interface_version ||
- (plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
+ else
{
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
- "plugin interface version mismatch");
- DBUG_RETURN(0);
+ if (read_maria_plugin_info(&plugin_dl, sym, dlpath, report))
+ DBUG_RETURN(0);
}
/* link the services in */
@@ -438,7 +662,7 @@ static st_plugin_dl *plugin_dl_add(const
{
if ((sym= dlsym(plugin_dl.handle, list_of_services[i].name)))
{
- uint ver= (uint)(intptr)*(void**)sym;
+ uint ver= (uint)(intptr) *(void **)sym;
if (ver > list_of_services[i].version ||
(ver >> 8) < (list_of_services[i].version >> 8))
{
@@ -449,72 +673,9 @@ static st_plugin_dl *plugin_dl_add(const
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, buf);
DBUG_RETURN(0);
}
- *(void**)sym= list_of_services[i].service;
- }
- }
-
- /* Find plugin declarations */
- if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
- {
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym);
- DBUG_RETURN(0);
- }
-
- if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
- {
- uint sizeof_st_plugin;
- struct st_mysql_plugin *old, *cur;
- char *ptr= (char *)sym;
-
- if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym)))
- sizeof_st_plugin= *(int *)sym;
- else
- {
-#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, sizeof_st_plugin_sym);
- DBUG_RETURN(0);
-#else
- /*
- When the following assert starts failing, we'll have to switch
- to the upper branch of the #ifdef
- */
- DBUG_ASSERT(min_plugin_interface_version == 0);
- sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
-#endif
- }
-
- if (sizeof_st_plugin != sizeof(st_mysql_plugin))
- {
- for (i= 0;
- ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- /* no op */;
-
- cur= (struct st_mysql_plugin*)
- my_malloc((i+1)*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
- if (!cur)
- {
- free_plugin_mem(&plugin_dl);
- report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
- DBUG_RETURN(0);
- }
- /*
- All st_plugin fields not initialized in the plugin explicitly, are
- set to 0. It matches C standard behaviour for struct initializers that
- have less values than the struct definition.
- */
- for (i=0;
- (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
-
- sym= cur;
- plugin_dl.allocated= true;
+ *(void **)sym= list_of_services[i].service;
}
}
- plugin_dl.plugins= (struct st_mysql_plugin *)sym;
/* Duplicate and convert dll name */
plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1;
@@ -756,7 +917,7 @@ static bool plugin_add(MEM_ROOT *tmp_roo
int *argc, char **argv, int report)
{
struct st_plugin_int tmp;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
DBUG_ENTER("plugin_add");
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
{
@@ -1161,8 +1322,8 @@ int plugin_init(int *argc, char **argv,
{
uint i;
bool is_myisam;
- struct st_mysql_plugin **builtins;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin **builtins;
+ struct st_maria_plugin *plugin;
struct st_plugin_int tmp, *plugin_ptr, **reap;
MEM_ROOT tmp_root;
bool reaped_mandatory_plugin= FALSE;
@@ -1201,7 +1362,7 @@ int plugin_init(int *argc, char **argv,
/*
First we register builtin plugins
*/
- for (builtins= mysqld_builtins; *builtins; builtins++)
+ for (builtins= mariadb_builtins; *builtins; builtins++)
{
for (plugin= *builtins; plugin->info; plugin++)
{
@@ -1316,7 +1477,7 @@ err:
}
-static bool register_builtin(struct st_mysql_plugin *plugin,
+static bool register_builtin(struct st_maria_plugin *plugin,
struct st_plugin_int *tmp,
struct st_plugin_int **ptr)
{
@@ -1352,7 +1513,7 @@ static bool register_builtin(struct st_m
RETURN
false - plugin registered successfully
*/
-bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
+bool plugin_register_builtin(THD *thd, struct st_maria_plugin *plugin)
{
struct st_plugin_int tmp, *ptr;
bool result= true;
@@ -1481,7 +1642,7 @@ static bool plugin_load_list(MEM_ROOT *t
char buffer[FN_REFLEN];
LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
struct st_plugin_dl *plugin_dl;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
char *p= buffer;
DBUG_ENTER("plugin_load_list");
while (list)
=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_plugin.h 2010-03-30 20:32:55 +0000
@@ -52,8 +52,9 @@ struct st_plugin_dl
{
LEX_STRING dl;
void *handle;
- struct st_mysql_plugin *plugins;
- int version;
+ struct st_maria_plugin *plugins;
+ int mysqlversion;
+ int mariaversion;
bool allocated;
uint ref_count; /* number of plugins loaded from the library */
};
@@ -63,7 +64,7 @@ struct st_plugin_dl
struct st_plugin_int
{
LEX_STRING name;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
struct st_plugin_dl *plugin_dl;
uint state;
uint ref_count; /* number of threads using the plugin */
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_show.cc 2010-03-30 20:32:55 +0000
@@ -94,11 +94,21 @@ static int make_version_string(char *buf
return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
}
+
+static const LEX_STRING maturity_name[]={
+ { C_STRING_WITH_LEN("Unknown") },
+ { C_STRING_WITH_LEN("Experimental") },
+ { C_STRING_WITH_LEN("Alpha") },
+ { C_STRING_WITH_LEN("Beta") },
+ { C_STRING_WITH_LEN("Gamma") },
+ { C_STRING_WITH_LEN("Stable") }};
+
+
static my_bool show_plugins(THD *thd, plugin_ref plugin,
void *arg)
{
TABLE *table= (TABLE*) arg;
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
CHARSET_INFO *cs= system_charset_info;
char version_buf[20];
@@ -143,7 +153,7 @@ static my_bool show_plugins(THD *thd, pl
table->field[5]->set_notnull();
table->field[6]->store(version_buf,
make_version_string(version_buf, sizeof(version_buf),
- plugin_dl->version),
+ plugin_dl->mariaversion),
cs);
table->field[6]->set_notnull();
}
@@ -186,6 +196,26 @@ static my_bool show_plugins(THD *thd, pl
}
table->field[9]->set_notnull();
+ if ((uint) plug->maturity <= MariaDB_PLUGIN_MATURITY_STABLE)
+ table->field[10]->store(maturity_name[plug->maturity].str,
+ maturity_name[plug->maturity].length,
+ cs);
+ else
+ {
+ DBUG_ASSERT(0);
+ table->field[10]->store("Unknown", 7, cs);
+ }
+ table->field[10]->set_notnull();
+
+ if (plug->version_info)
+ {
+ table->field[11]->store(plug->version_info,
+ strlen(plug->version_info), cs);
+ table->field[11]->set_notnull();
+ }
+ else
+ table->field[11]->set_null();
+
return schema_table_store_record(thd, table);
}
@@ -4398,7 +4428,7 @@ static my_bool iter_schema_engines(THD *
if (plugin_state(plugin) != PLUGIN_IS_READY)
{
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
if (!(wild && wild[0] &&
wild_case_compare(scs, plug->name,wild)))
{
@@ -7095,6 +7125,8 @@ ST_FIELD_INFO plugin_fields_info[]=
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
+ {"PLUGIN_MATURITY", 12, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+ {"PLUGIN_AUTH_VERSION", 80, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
=== modified file 'storage/archive/ha_archive.cc'
--- a/storage/archive/ha_archive.cc 2010-03-04 08:03:07 +0000
+++ b/storage/archive/ha_archive.cc 2010-03-30 20:32:55 +0000
@@ -1655,4 +1655,21 @@ mysql_declare_plugin(archive)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(archive)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &archive_storage_engine,
+ "ARCHIVE",
+ "Brian Aker, MySQL AB",
+ "Archive storage engine",
+ PLUGIN_LICENSE_GPL,
+ archive_db_init, /* Plugin Init */
+ archive_db_done, /* Plugin Deinit */
+ 0x0300 /* 3.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/blackhole/ha_blackhole.cc'
--- a/storage/blackhole/ha_blackhole.cc 2009-10-16 10:29:42 +0000
+++ b/storage/blackhole/ha_blackhole.cc 2010-03-30 20:32:55 +0000
@@ -369,3 +369,20 @@ mysql_declare_plugin(blackhole)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(blackhole)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &blackhole_storage_engine,
+ "BLACKHOLE",
+ "MySQL AB",
+ "/dev/null storage engine (anything you write to it disappears)",
+ PLUGIN_LICENSE_GPL,
+ blackhole_init, /* Plugin Init */
+ blackhole_fini, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/csv/ha_tina.cc'
--- a/storage/csv/ha_tina.cc 2009-12-03 11:19:05 +0000
+++ b/storage/csv/ha_tina.cc 2010-03-30 20:32:55 +0000
@@ -1636,4 +1636,20 @@ mysql_declare_plugin(csv)
NULL /* config options */
}
mysql_declare_plugin_end;
-
+maria_declare_plugin(csv)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &csv_storage_engine,
+ "CSV",
+ "Brian Aker, MySQL AB",
+ "CSV storage engine",
+ PLUGIN_LICENSE_GPL,
+ tina_init_func, /* Plugin Init */
+ tina_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/example/ha_example.cc'
--- a/storage/example/ha_example.cc 2010-03-03 14:44:14 +0000
+++ b/storage/example/ha_example.cc 2010-03-30 20:32:55 +0000
@@ -924,3 +924,20 @@ mysql_declare_plugin(example)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(example)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &example_storage_engine,
+ "EXAMPLE",
+ "Brian Aker, MySQL AB",
+ "Example storage engine",
+ PLUGIN_LICENSE_GPL,
+ example_init_func, /* Plugin Init */
+ example_done_func, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ func_status, /* status variables */
+ example_system_variables, /* system variables */
+ "0.1", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/federated/ha_federated.cc'
--- a/storage/federated/ha_federated.cc 2009-09-07 20:50:10 +0000
+++ b/storage/federated/ha_federated.cc 2010-03-30 20:32:55 +0000
@@ -3379,3 +3379,20 @@ mysql_declare_plugin(federated)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federated_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith and Brian Aker, MySQL AB",
+ "Federated MySQL storage engine",
+ PLUGIN_LICENSE_GPL,
+ federated_db_init, /* Plugin Init */
+ federated_done, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/federatedx/ha_federatedx.cc'
--- a/storage/federatedx/ha_federatedx.cc 2010-03-10 10:32:14 +0000
+++ b/storage/federatedx/ha_federatedx.cc 2010-03-30 20:32:55 +0000
@@ -3505,9 +3505,26 @@ mysql_declare_plugin(federated)
PLUGIN_LICENSE_GPL,
federatedx_db_init, /* Plugin Init */
federatedx_done, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
+ 0x0200 /* 2.0 */,
NULL, /* status variables */
NULL, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federatedx_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith",
+ "FederatedX pluggable storage engine",
+ PLUGIN_LICENSE_GPL,
+ federatedx_db_init, /* Plugin Init */
+ federatedx_done, /* Plugin Deinit */
+ 0x0200 /* 2.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "2.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/heap/ha_heap.cc'
--- a/storage/heap/ha_heap.cc 2009-09-07 20:50:10 +0000
+++ b/storage/heap/ha_heap.cc 2010-03-30 20:32:55 +0000
@@ -767,3 +767,20 @@ mysql_declare_plugin(heap)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(heap)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &heap_storage_engine,
+ "MEMORY",
+ "MySQL AB",
+ "Hash based, stored in memory, useful for temporary tables",
+ PLUGIN_LICENSE_GPL,
+ heap_init,
+ NULL,
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/ibmdb2i/ha_ibmdb2i.cc'
--- a/storage/ibmdb2i/ha_ibmdb2i.cc 2009-12-11 07:01:16 +0000
+++ b/storage/ibmdb2i/ha_ibmdb2i.cc 2010-03-30 20:32:55 +0000
@@ -3357,3 +3357,20 @@ mysql_declare_plugin(ibmdb2i)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ibmdb2i)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ibmdb2i_storage_engine,
+ "IBMDB2I",
+ "The IBM development team in Rochester, Minnesota",
+ "IBM DB2 for i Storage Engine",
+ PLUGIN_LICENSE_GPL,
+ ibmdb2i_init_func, /* Plugin Init */
+ ibmdb2i_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ ibmdb2i_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_UNKNOWN /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc 2010-03-15 11:51:23 +0000
+++ b/storage/innobase/handler/ha_innodb.cc 2010-03-30 20:32:55 +0000
@@ -8930,6 +8930,23 @@ mysql_declare_plugin(innobase)
NULL /* reserved */
}
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase OY",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ innodb_status_variables_export, /* status variables */
+ innobase_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE, /* maturity */
+}
+maria_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/innodb_plugin/handler/i_s.cc'
--- a/storage/innodb_plugin/handler/i_s.cc 2009-10-12 12:00:56 +0000
+++ b/storage/innodb_plugin/handler/i_s.cc 2010-03-30 20:32:55 +0000
@@ -455,6 +455,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -730,6 +783,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -913,6 +1019,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
@@ -1245,6 +1404,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1295,6 +1507,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -1511,6 +1777,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1561,6 +1880,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc 2010-03-15 11:51:23 +0000
+++ b/storage/maria/ha_maria.cc 2010-03-30 20:32:55 +0000
@@ -3471,9 +3471,26 @@ mysql_declare_plugin(maria)
PLUGIN_LICENSE_GPL,
ha_maria_init, /* Plugin Init */
NULL, /* Plugin Deinit */
- 0x0100, /* 1.0 */
+ 0x0105, /* 1.5 */
status_variables, /* status variables */
system_variables, /* system variables */
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(maria)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &maria_storage_engine,
+ "MARIA",
+ "MySQL AB",
+ "Crash-safe tables with MyISAM heritage",
+ PLUGIN_LICENSE_GPL,
+ ha_maria_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0105, /* 1.5 */
+ status_variables, /* status variables */
+ system_variables, /* system variables */
+ "1.5", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc 2010-01-04 17:54:42 +0000
+++ b/storage/myisam/ha_myisam.cc 2010-03-30 20:32:55 +0000
@@ -2174,6 +2174,23 @@ mysql_declare_plugin(myisam)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisam)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisam_storage_engine,
+ "MyISAM",
+ "MySQL AB",
+ "Default engine as of MySQL 3.23 with great performance",
+ PLUGIN_LICENSE_GPL,
+ myisam_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#ifdef HAVE_QUERY_CACHE
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2010-03-04 08:03:07 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-03-30 20:32:55 +0000
@@ -1289,3 +1289,20 @@ mysql_declare_plugin(myisammrg)
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisammrg)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisammrg_storage_engine,
+ "MRG_MYISAM",
+ "MySQL AB",
+ "Collection of identical MyISAM tables",
+ PLUGIN_LICENSE_GPL,
+ myisammrg_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- a/storage/pbxt/src/ha_pbxt.cc 2010-03-03 14:44:14 +0000
+++ b/storage/pbxt/src/ha_pbxt.cc 2010-03-30 20:32:55 +0000
@@ -5921,6 +5921,40 @@ mysql_declare_plugin(pbxt)
drizzle_declare_plugin_end;
#else
mysql_declare_plugin_end;
+#ifdef MARIADB_BASE_VERSION
+maria_declare_plugin(pbxt)
+{ /* PBXT */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &pbxt_storage_engine,
+ "PBXT",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "High performance, multi-versioning transactional engine",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init, /* Plugin Init */
+ pbxt_end, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ NULL, /* status variables */
+ pbxt_system_variables, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+},
+{ /* PBXT_STATISTICS */
+ MYSQL_INFORMATION_SCHEMA_PLUGIN,
+ &pbxt_statitics,
+ "PBXT_STATISTICS",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "PBXT internal system statitics",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init_statistics, /* plugin init */
+ pbxt_exit_statistics, /* plugin deinit */
+ 0x0005,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
+#endif
#endif
#if defined(XT_WIN) && defined(XT_COREDUMP)
=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- a/storage/xtradb/handler/ha_innodb.cc 2010-02-01 06:14:12 +0000
+++ b/storage/xtradb/handler/ha_innodb.cc 2010-03-30 20:32:55 +0000
@@ -10818,6 +10818,39 @@ i_s_innodb_index_stats,
i_s_innodb_admin_command,
i_s_innodb_patches
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{ /* InnoDB */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase Oy",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ INNODB_VERSION_SHORT,
+ innodb_status_variables_export,/* status variables */
+ innobase_system_variables, /* system variables */
+ INNODB_VERSION_STR, /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+},
+i_s_innodb_rseg_maria,
+i_s_innodb_buffer_pool_pages_maria,
+i_s_innodb_buffer_pool_pages_index_maria,
+i_s_innodb_buffer_pool_pages_blob_maria,
+i_s_innodb_trx_maria,
+i_s_innodb_locks_maria,
+i_s_innodb_lock_waits_maria,
+i_s_innodb_cmp_maria,
+i_s_innodb_cmp_reset_maria,
+i_s_innodb_cmpmem_maria,
+i_s_innodb_cmpmem_reset_maria,
+i_s_innodb_table_stats_maria,
+i_s_innodb_index_stats_maria,
+i_s_innodb_admin_command_maria,
+i_s_innodb_patches_maria
+maria_declare_plugin_end;
+
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/xtradb/handler/i_s.cc'
--- a/storage/xtradb/handler/i_s.cc 2010-01-28 11:35:10 +0000
+++ b/storage/xtradb/handler/i_s.cc 2010-03-30 20:32:55 +0000
@@ -393,6 +393,59 @@ UNIV_INTERN struct st_mysql_plugin
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_patches_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "XTRADB_ENHANCEMENTS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Percona"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Enhancements applied to InnoDB plugin"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_patches_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_fields_info[] =
{
@@ -1040,6 +1093,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1089,6 +1195,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool index pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1138,6 +1297,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool blob pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
static ST_FIELD_INFO innodb_trx_fields_info[] =
@@ -1373,6 +1585,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -1648,6 +1914,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -1831,22 +2150,75 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
-/*******************************************************************//**
-Common function to fill any of the dynamic tables:
-INFORMATION_SCHEMA.innodb_trx
-INFORMATION_SCHEMA.innodb_locks
-INFORMATION_SCHEMA.innodb_lock_waits
-@return 0 on success */
-static
-int
-trx_i_s_common_fill_table(
-/*======================*/
- THD* thd, /*!< in: thread */
- TABLE_LIST* tables, /*!< in/out: tables to fill */
- COND* cond) /*!< in: condition (not used) */
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
{
- const char* table_name;
- int ret;
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
+/*******************************************************************//**
+Common function to fill any of the dynamic tables:
+INFORMATION_SCHEMA.innodb_trx
+INFORMATION_SCHEMA.innodb_locks
+INFORMATION_SCHEMA.innodb_lock_waits
+@return 0 on success */
+static
+int
+trx_i_s_common_fill_table(
+/*======================*/
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (not used) */
+{
+ const char* table_name;
+ int ret;
trx_i_s_cache_t* cache;
DBUG_ENTER("trx_i_s_common_fill_table");
@@ -2163,6 +2535,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2213,6 +2638,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -2431,6 +2909,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2481,6 +3012,60 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
@@ -2660,6 +3245,59 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_rseg_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_RSEG"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB rollback segment information"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_rseg_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_table_stats_info[] =
@@ -2940,6 +3578,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_table_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_TABLE_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB table statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_table_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats =
{
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
@@ -2956,6 +3611,23 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_index_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_INDEX_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB index statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_index_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_admin_command_info[] =
@@ -3122,3 +3794,20 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_admin_command_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "XtraDB specific command acceptor"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_admin_command_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
=== modified file 'storage/xtradb/handler/i_s.h'
--- a/storage/xtradb/handler/i_s.h 2009-11-04 20:11:12 +0000
+++ b/storage/xtradb/handler/i_s.h 2010-03-30 20:32:55 +0000
@@ -42,4 +42,20 @@ extern struct st_mysql_plugin i_s_innodb
extern struct st_mysql_plugin i_s_innodb_index_stats;
extern struct st_mysql_plugin i_s_innodb_admin_command;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria;
+extern struct st_maria_plugin i_s_innodb_trx_maria;
+extern struct st_maria_plugin i_s_innodb_locks_maria;
+extern struct st_maria_plugin i_s_innodb_lock_waits_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_reset_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_reset_maria;
+extern struct st_maria_plugin i_s_innodb_patches_maria;
+extern struct st_maria_plugin i_s_innodb_rseg_maria;
+extern struct st_maria_plugin i_s_innodb_table_stats_maria;
+extern struct st_maria_plugin i_s_innodb_index_stats_maria;
+extern struct st_maria_plugin i_s_innodb_admin_command_maria;
+
#endif /* i_s_h */
2
1

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (monty:2765)
by Michael Widenius 01 Apr '10
by Michael Widenius 01 Apr '10
01 Apr '10
#At lp:maria/5.2 based on revid:monty@askmonty.org-20100401091008-1tfywox0wefeygvb
2765 Michael Widenius 2010-04-01 [merge]
Auto merge with 5.1
modified:
support-files/compiler_warnings.supp
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-04-01 09:08:42 +0000
+++ b/support-files/compiler_warnings.supp 2010-04-01 09:40:11 +0000
@@ -27,7 +27,7 @@ pars0grm.tab.c: .*'yyerrorlab' : unrefer
_flex_tmp.c: .*not enough actual parameters for macro 'yywrap'.*
pars0lex.l: .*conversion from 'ulint' to 'int', possible loss of data.*
btr/btr0cur\.c: .*value computed is not used.*: 3175-3375
-include/buf0buf\.ic: unused parameter ���mtr���
+include/buf0buf\.ic: unused parameter .*mtr.*
fil/fil0fil\.c: pointer targets in passing argument.*differ in signedness
fil/fil0fil\.c: comparison between signed and unsigned : 3100-3199
fil/fil0fil\.c: unused parameter
@@ -58,7 +58,7 @@ readline\.c : unused parameter
term\.c : unused parameter
vi\.c : unused parameter
common\.c : unused parameter
-term\.c : *.*
+term\.c : .*
#
1
0

[Maria-developers] Rev 2751: options for CREATE TABLE (MWL#43) in file:///home/bell/maria/bzr/work-maria-5.2-createoptions2/
by sanja@askmonty.org 01 Apr '10
by sanja@askmonty.org 01 Apr '10
01 Apr '10
At file:///home/bell/maria/bzr/work-maria-5.2-createoptions2/
------------------------------------------------------------
revno: 2751
revision-id: sanja(a)askmonty.org-20100326215117-svblh338osfg4i1c
parent: sergii(a)pisem.net-20100323092233-t2gwaclx94hd6exa
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-createoptions2
timestamp: Fri 2010-03-26 23:51:17 +0200
message:
options for CREATE TABLE (MWL#43)
=== modified file 'Docs/sp-imp-spec.txt'
--- a/Docs/sp-imp-spec.txt 2004-03-23 11:04:40 +0000
+++ b/Docs/sp-imp-spec.txt 2010-03-26 21:51:17 +0000
@@ -1075,7 +1075,7 @@
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
- 'NOT_USED',
+ 'CREATE_OPTIONS_ERR',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
@@ -1097,4 +1097,4 @@
) comment='Stored Procedures';
--
-
\ No newline at end of file
+
=== modified file 'include/my_base.h'
--- a/include/my_base.h 2010-02-10 19:06:24 +0000
+++ b/include/my_base.h 2010-03-26 21:51:17 +0000
@@ -314,6 +314,8 @@
#define HA_OPTION_RELIES_ON_SQL_LAYER 512
#define HA_OPTION_NULL_FIELDS 1024
#define HA_OPTION_PAGE_CHECKSUM 2048
+/* .frm has extra create options in linked-list format */
+#define HA_OPTION_TEXT_CREATE_OPTIONS (1L << 14)
#define HA_OPTION_TEMP_COMPRESS_RECORD (1L << 15) /* set by isamchk */
#define HA_OPTION_READ_ONLY_DATA (1L << 16) /* Set by isamchk */
#define HA_OPTION_NO_CHECKSUM (1L << 17)
=== modified file 'libmysqld/CMakeLists.txt'
--- a/libmysqld/CMakeLists.txt 2010-01-31 09:13:21 +0000
+++ b/libmysqld/CMakeLists.txt 2010-03-26 21:51:17 +0000
@@ -139,7 +139,8 @@
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
../sql/partition_info.cc ../sql/sql_connect.cc
- ../sql/scheduler.cc ../sql/event_parse_data.cc
+ ../sql/scheduler.cc ../sql/event_parse_data.cc
+ ../sql/create_options.cc
${GEN_SOURCES}
${LIB_SOURCES})
=== modified file 'libmysqld/Makefile.am'
--- a/libmysqld/Makefile.am 2009-12-03 11:19:05 +0000
+++ b/libmysqld/Makefile.am 2010-03-26 21:51:17 +0000
@@ -75,7 +75,7 @@
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
debug_sync.cc \
- sql_tablespace.cc \
+ sql_tablespace.cc create_options.cc \
rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc event_parse_data.cc opt_table_elimination.cc
=== added file 'mysql-test/r/create_options.result'
--- a/mysql-test/r/create_options.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/create_options.result 2010-03-26 21:51:17 +0000
@@ -0,0 +1,169 @@
+drop table if exists t1;
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='';
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+Warnings:
+Warning 1650 Unknown option 'fkey'='vvv'
+Warning 1650 Unknown option 'dff'='vvv'
+Warning 1650 Unknown option 'tkey1'='1v1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey='vvv',
+ KEY `akey` (`a`) dff='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey1='1v1'
+drop table t1;
+#reassiginig options in the same line
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1;
+Warnings:
+Warning 1650 Unknown option 'fkey'='vvv'
+Warning 1650 Unknown option 'dff'='vvv'
+Warning 1650 Unknown option 'tkey1'='1v2'
+Warning 1650 Unknown option 'tkey2'='2v1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey='vvv',
+ KEY `akey` (`a`) dff='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey1='1v2' tkey2='2v1'
+#add option
+alter table t1 tkey4=4v1;
+Warnings:
+Warning 1650 Unknown option 'tkey4'='4v1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey='vvv',
+ KEY `akey` (`a`) dff='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey1='1v2' tkey2='2v1' tkey4='4v1'
+#remove options
+alter table t1 tkey3=DEFAULT tkey4=DEFAULT;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey='vvv',
+ KEY `akey` (`a`) dff='vvv'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey1='1v2' tkey2='2v1'
+drop table t1;
+create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1;
+Warnings:
+Warning 1650 Unknown option 'fkey1'='v1'
+Warning 1650 Unknown option 'kkey1'='v1'
+Warning 1650 Unknown option 'tkey2'='2v1'
+Warning 1650 Unknown option 'tkey3'='3v1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey1='v1',
+ KEY `akey` (`a`) kkey1='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+#change field with option with the same option
+alter table t1 change a a int `FKEY1`='v1';
+Warnings:
+Warning 1650 Unknown option 'FKEY1'='v1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL FKEY1='v1',
+ KEY `akey` (`a`) kkey1='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+#change field with option with a different option
+alter table t1 change a a int fkey1=v2;
+Warnings:
+Warning 1650 Unknown option 'fkey1'='v2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey1='v2',
+ KEY `akey` (`a`) kkey1='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+#new column no options
+alter table t1 add column b int;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey1='v2',
+ `b` int(11) DEFAULT NULL,
+ KEY `akey` (`a`) kkey1='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+#new key with options
+alter table t1 add key bkey (b) kkey2=v1;
+Warnings:
+Warning 1650 Unknown option 'kkey2'='v1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey1='v2',
+ `b` int(11) DEFAULT NULL,
+ KEY `akey` (`a`) kkey1='v1',
+ KEY `bkey` (`b`) kkey2='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+#new column with options
+alter table t1 add column c int fkey1=v1 fkey2=v2;
+Warnings:
+Warning 1650 Unknown option 'fkey1'='v1'
+Warning 1650 Unknown option 'fkey2'='v2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey1='v2',
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL fkey1='v1' fkey2='v2',
+ KEY `akey` (`a`) kkey1='v1',
+ KEY `bkey` (`b`) kkey2='v1'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+#new key no options
+alter table t1 add key ckey (c);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey1='v2',
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL fkey1='v1' fkey2='v2',
+ KEY `akey` (`a`) kkey1='v1',
+ KEY `bkey` (`b`) kkey2='v1',
+ KEY `ckey` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+#drop column
+alter table t1 drop b;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey1='v2',
+ `c` int(11) DEFAULT NULL fkey1='v1' fkey2='v2',
+ KEY `akey` (`a`) kkey1='v1',
+ KEY `ckey` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+#add column with options after delete
+alter table t1 add column b int fkey2=v1;
+Warnings:
+Warning 1650 Unknown option 'fkey2'='v1'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey1='v2',
+ `c` int(11) DEFAULT NULL fkey1='v1' fkey2='v2',
+ `b` int(11) DEFAULT NULL fkey2='v1',
+ KEY `akey` (`a`) kkey1='v1',
+ KEY `ckey` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+#add key
+alter table t1 add key bkey (b) kkey2=v2;
+Warnings:
+Warning 1650 Unknown option 'kkey2'='v2'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL fkey1='v2',
+ `c` int(11) DEFAULT NULL fkey1='v1' fkey2='v2',
+ `b` int(11) DEFAULT NULL fkey2='v1',
+ KEY `akey` (`a`) kkey1='v1',
+ KEY `ckey` (`c`),
+ KEY `bkey` (`b`) kkey2='v2'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 tkey2='2v1' tkey3='3v1'
+drop table t1;
+#error on unknown option
+SET SQL_MODE='CREATE_OPTIONS_ERR';
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+ERROR HY000: Unknown option 'fkey'='vvv'
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/r/events_bugs.result'
--- a/mysql-test/r/events_bugs.result 2009-03-11 20:30:56 +0000
+++ b/mysql-test/r/events_bugs.result 2010-03-26 21:51:17 +0000
@@ -729,9 +729,8 @@
create event e1 on schedule every 1 day do select 1;
select @@sql_mode;
@@sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,CREATE_OPTIONS_ERR,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
set @@sql_mode= @old_mode;
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.event where name = 'p' and sql_mode = @full_mode;
name
=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result 2010-03-15 11:51:23 +0000
+++ b/mysql-test/r/information_schema.result 2010-03-26 21:51:17 +0000
@@ -615,7 +615,7 @@
proc definer char(77)
proc created timestamp
proc modified timestamp
-proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
proc comment char(64)
proc character_set_client char(32)
proc collation_connection char(32)
=== modified file 'mysql-test/r/plugin_load.result'
--- a/mysql-test/r/plugin_load.result 2008-01-26 00:05:15 +0000
+++ b/mysql-test/r/plugin_load.result 2010-03-26 21:51:17 +0000
@@ -1,3 +1,43 @@
SELECT @@global.example_enum_var = 'e2';
@@global.example_enum_var = 'e2'
1
+#legal values
+CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example UUL=10000 STR='dskj' one_or_two='one' YESNO=0;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL complex='c,f,f,f'
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 UUL=10000 STR='dskj' one_or_two='one' YESNO=0
+drop table t1;
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='';
+#illegal value fixed
+CREATE TABLE t1 (a int) ENGINE=example UUL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+Warnings:
+Warning 1651 Incorrect option value 'UUL'='10000000000000000000'
+Warning 1651 Incorrect option value 'one_or_two'='ttt'
+Warning 1651 Incorrect option value 'YESNO'='SSS'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 UUL=4294967295 YESNO=0
+#alter table
+alter table t1 UUL=10000000;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 YESNO=0 UUL=10000000
+alter table t1 change a a int complex='c,c,c';
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL complex='c,c,c'
+) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 YESNO=0 UUL=10000000
+drop table t1;
+#illegal value error
+SET SQL_MODE='CREATE_OPTIONS_ERR';
+CREATE TABLE t1 (a int) ENGINE=example UUL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+ERROR HY000: Incorrect option value 'UUL'='10000000000000000000'
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/r/sp.result'
--- a/mysql-test/r/sp.result 2009-12-23 13:44:03 +0000
+++ b/mysql-test/r/sp.result 2010-03-26 21:51:17 +0000
@@ -6940,9 +6940,8 @@
call p();
select @@sql_mode;
@@sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,CREATE_OPTIONS_ERR,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
set @@sql_mode= @old_mode;
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.proc where name = 'p' and sql_mode = @full_mode;
name
=== modified file 'mysql-test/r/system_mysql_db.result'
--- a/mysql-test/r/system_mysql_db.result 2009-10-27 10:09:36 +0000
+++ b/mysql-test/r/system_mysql_db.result 2010-03-26 21:51:17 +0000
@@ -200,7 +200,7 @@
`definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
@@ -225,7 +225,7 @@
`ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
- `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
+ `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`originator` int(10) unsigned NOT NULL,
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2009-10-28 09:23:02 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2010-03-26 21:51:17 +0000
@@ -49,7 +49,7 @@
NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references
NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
+NULL mysql event sql_mode 15 NO set 488 1464 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references
NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references
@@ -124,7 +124,7 @@
NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references
NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references
-NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
+NULL mysql proc sql_mode 15 NO set 488 1464 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
@@ -327,7 +327,7 @@
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql event sql_mode set 488 1464 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -402,7 +402,7 @@
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql proc sql_mode set 488 1464 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result 2009-05-19 16:43:50 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result 2010-03-26 21:51:17 +0000
@@ -49,7 +49,7 @@
NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI
NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE')
NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64)
@@ -124,7 +124,7 @@
NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER')
NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')
-NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI
NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL
@@ -327,7 +327,7 @@
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -402,7 +402,7 @@
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
=== added file 'mysql-test/t/create_options.test'
--- a/mysql-test/t/create_options.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/create_options.test 2010-03-26 21:51:17 +0000
@@ -0,0 +1,63 @@
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='';
+
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+show create table t1;
+drop table t1;
+
+--echo #reassiginig options in the same line
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1;
+show create table t1;
+
+-- echo #add option
+alter table t1 tkey4=4v1;
+show create table t1;
+
+--echo #remove options
+alter table t1 tkey3=DEFAULT tkey4=DEFAULT;
+show create table t1;
+
+drop table t1;
+
+create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1;
+show create table t1;
+
+--echo #change field with option with the same option
+alter table t1 change a a int `FKEY1`='v1';
+show create table t1;
+--echo #change field with option with a different option
+alter table t1 change a a int fkey1=v2;
+show create table t1;
+--echo #new column no options
+alter table t1 add column b int;
+show create table t1;
+--echo #new key with options
+alter table t1 add key bkey (b) kkey2=v1;
+show create table t1;
+--echo #new column with options
+alter table t1 add column c int fkey1=v1 fkey2=v2;
+show create table t1;
+--echo #new key no options
+alter table t1 add key ckey (c);
+show create table t1;
+--echo #drop column
+alter table t1 drop b;
+show create table t1;
+--echo #add column with options after delete
+alter table t1 add column b int fkey2=v1;
+show create table t1;
+--echo #add key
+alter table t1 add key bkey (b) kkey2=v2;
+show create table t1;
+drop table t1;
+
+--echo #error on unknown option
+SET SQL_MODE='CREATE_OPTIONS_ERR';
+--error ER_UNKNOWN_OPTION
+create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
+
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/t/events_bugs.test'
--- a/mysql-test/t/events_bugs.test 2009-03-11 20:30:56 +0000
+++ b/mysql-test/t/events_bugs.test 2010-03-26 21:51:17 +0000
@@ -1204,7 +1204,6 @@
select @@sql_mode;
set @@sql_mode= @old_mode;
# Rename SQL modes that differ in name between the server and the table definition.
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.event where name = 'p' and sql_mode = @full_mode;
drop event e1;
=== modified file 'mysql-test/t/exampledb.test'
--- a/mysql-test/t/exampledb.test 2006-05-05 17:08:40 +0000
+++ b/mysql-test/t/exampledb.test 2010-03-26 21:51:17 +0000
@@ -20,3 +20,4 @@
drop table t1;
# End of 4.1 tests
+
=== modified file 'mysql-test/t/plugin_load.test'
--- a/mysql-test/t/plugin_load.test 2009-10-08 08:39:15 +0000
+++ b/mysql-test/t/plugin_load.test 2010-03-26 21:51:17 +0000
@@ -2,3 +2,30 @@
--source include/have_example_plugin.inc
SELECT @@global.example_enum_var = 'e2';
+
+--echo #legal values
+CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example UUL=10000 STR='dskj' one_or_two='one' YESNO=0;
+show create table t1;
+drop table t1;
+
+SET @OLD_SQL_MODE=@@SQL_MODE;
+SET SQL_MODE='';
+
+--echo #illegal value fixed
+CREATE TABLE t1 (a int) ENGINE=example UUL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+show create table t1;
+
+--echo #alter table
+alter table t1 UUL=10000000;
+show create table t1;
+alter table t1 change a a int complex='c,c,c';
+show create table t1;
+drop table t1;
+
+
+--echo #illegal value error
+SET SQL_MODE='CREATE_OPTIONS_ERR';
+--error ER_BAD_OPTION_VALUE
+CREATE TABLE t1 (a int) ENGINE=example UUL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
+
+SET @@SQL_MODE=@OLD_SQL_MODE;
=== modified file 'mysql-test/t/sp.test'
--- a/mysql-test/t/sp.test 2009-12-23 13:44:03 +0000
+++ b/mysql-test/t/sp.test 2010-03-26 21:51:17 +0000
@@ -8210,7 +8210,6 @@
select @@sql_mode;
set @@sql_mode= @old_mode;
# Rename SQL modes that differ in name between the server and the table definition.
-select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.proc where name = 'p' and sql_mode = @full_mode;
drop procedure p;
=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql 2009-10-27 10:09:36 +0000
+++ b/scripts/mysql_system_tables.sql 2010-03-26 21:51:17 +0000
@@ -60,7 +60,7 @@
CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones';
-CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
+CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'CREATE_OPTIONS_ERR', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
@@ -80,7 +80,7 @@
EXECUTE stmt;
DROP PREPARE stmt;
-CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
+CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;
=== modified file 'scripts/mysql_system_tables_fix.sql'
--- a/scripts/mysql_system_tables_fix.sql 2009-12-03 16:15:47 +0000
+++ b/scripts/mysql_system_tables_fix.sql 2010-03-26 21:51:17 +0000
@@ -368,7 +368,7 @@
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
- 'NOT_USED',
+ 'CREATE_OPTIONS_ERR',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
@@ -482,14 +482,14 @@
ALTER TABLE event DROP PRIMARY KEY;
ALTER TABLE event ADD PRIMARY KEY(db, name);
# Add sql_mode column just in case.
-ALTER TABLE event ADD sql_mode set ('NOT_USED') AFTER on_completion;
+ALTER TABLE event ADD sql_mode set ('CREATE_OPTIONS_ERR') AFTER on_completion;
# Update list of sql_mode values.
ALTER TABLE event MODIFY sql_mode
set('REAL_AS_FLOAT',
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
- 'NOT_USED',
+ 'CREATE_OPTIONS_ERR',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2010-03-03 14:44:14 +0000
+++ b/sql/CMakeLists.txt 2010-03-26 21:51:17 +0000
@@ -77,6 +77,7 @@
rpl_rli.cc rpl_mi.cc sql_servers.cc
sql_connect.cc scheduler.cc
sql_profile.cc event_parse_data.cc opt_table_elimination.cc
+ create_options.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
${PROJECT_SOURCE_DIR}/include/mysqld_error.h
=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am 2010-03-03 14:44:14 +0000
+++ b/sql/Makefile.am 2010-03-26 21:51:17 +0000
@@ -78,7 +78,8 @@
sql_plugin.h authors.h event_parse_data.h \
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
- contributors.h sql_servers.h
+ contributors.h sql_servers.h \
+ create_options.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
@@ -124,7 +125,7 @@
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_servers.cc event_parse_data.cc \
- opt_table_elimination.cc
+ opt_table_elimination.cc create_options.cc
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc 2010-03-15 11:51:23 +0000
+++ b/sql/event_db_repository.cc 2010-03-26 21:51:17 +0000
@@ -105,7 +105,8 @@
{
{ C_STRING_WITH_LEN("sql_mode") },
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
- "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
+ "'IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY',"
+ "'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2010-03-17 02:32:31 +0000
+++ b/sql/field.cc 2010-03-26 21:51:17 +0000
@@ -1308,7 +1308,8 @@
utype unireg_check_arg, const char *field_name_arg)
:ptr(ptr_arg), null_ptr(null_ptr_arg),
table(0), orig_table(0), table_name(0),
- field_name(field_name_arg),
+ field_name(field_name_arg), option_list(0),
+ option_struct(0), new_option_struct(0),
key_start(0), part_of_key(0), part_of_key_not_clustered(0),
part_of_sortkey(0), unireg_check(unireg_check_arg),
field_length(length_arg), null_bit(null_bit_arg),
@@ -9567,7 +9568,8 @@
Item *fld_on_update_value, LEX_STRING *fld_comment,
char *fld_change, List<String> *fld_interval_list,
CHARSET_INFO *fld_charset, uint fld_geom_type,
- Virtual_column_info *fld_vcol_info)
+ Virtual_column_info *fld_vcol_info,
+ engine_option_value *create_opt)
{
uint sign_len, allowed_type_modifier= 0;
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
@@ -9578,6 +9580,7 @@
field_name= fld_name;
def= fld_default_value;
flags= fld_type_modifier;
+ option_list= create_opt;
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
Field::NEXT_NUMBER : Field::NONE);
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
@@ -10217,6 +10220,8 @@
decimals= old_field->decimals();
vcol_info= old_field->vcol_info;
stored_in_db= old_field->stored_in_db;
+ option_list= old_field->option_list;
+ option_struct= NULL;
/* Fix if the original table had 4 byte pointer blobs */
if (flags & BLOB_FLAG)
@@ -10291,6 +10296,22 @@
/**
+ Makes a clone of this object for ALTER/CREATE TABLE
+
+ @note: We need to do the clone of the list because in
+ ALTER TABLE we may change the list for the cloned field
+
+ @param mem_root MEM_ROOT where to clone the field
+*/
+
+Create_field *Create_field::clone(MEM_ROOT *mem_root) const
+{
+ Create_field *res= new (mem_root) Create_field(*this);
+ return res;
+}
+
+
+/**
maximum possible display length for blob.
@return
=== modified file 'sql/field.h'
--- a/sql/field.h 2010-03-15 11:51:23 +0000
+++ b/sql/field.h 2010-03-26 21:51:17 +0000
@@ -137,6 +137,14 @@
struct st_table *table; // Pointer for table
struct st_table *orig_table; // Pointer to original table
const char **table_name, *field_name;
+ /** reference to the list of options or NULL */
+ engine_option_value *option_list;
+ void *option_struct; /* structure with parsed options */
+ /**
+ structure with parsed new field parameters in ALTER TABLE for
+ check_if_incompatible_data()
+ */
+ void *new_option_struct;
LEX_STRING comment;
/* Field is part of the following keys */
key_map key_start, part_of_key, part_of_key_not_clustered;
@@ -2145,6 +2153,9 @@
CHARSET_INFO *charset;
Field::geometry_type geom_type;
Field *field; // For alter table
+ engine_option_value *option_list;
+ /** structure with parsed options (for comparing fields in ALTER TABLE) */
+ void *option_struct;
uint8 row,col,sc_length,interval_id; // For rea_create_table
uint offset,pack_flag;
@@ -2162,11 +2173,11 @@
*/
bool stored_in_db;
- Create_field() :after(0) {}
+ Create_field() :after(0), option_list(NULL), option_struct(NULL)
+ {}
Create_field(Field *field, Field *orig_field);
/* Used to make a clone of this object for ALTER/CREATE TABLE */
- Create_field *clone(MEM_ROOT *mem_root) const
- { return new (mem_root) Create_field(*this); }
+ Create_field *clone(MEM_ROOT *mem_root) const;
void create_length_to_internal_length(void);
/* Init for a tmp table field. To be extended if need be. */
@@ -2178,8 +2189,8 @@
char *decimals, uint type_modifier, Item *default_value,
Item *on_update_value, LEX_STRING *comment, char *change,
List<String> *interval_list, CHARSET_INFO *cs,
- uint uint_geom_type,
- Virtual_column_info *vcol_info);
+ uint uint_geom_type, Virtual_column_info *vcol_info,
+ engine_option_value *option_list);
bool field_flags_are_binary()
{
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2010-03-15 11:51:23 +0000
+++ b/sql/ha_partition.cc 2010-03-26 21:51:17 +0000
@@ -1218,7 +1218,9 @@
DBUG_ENTER("prepare_new_partition");
if ((error= set_up_table_before_create(tbl, part_name, create_info,
- 0, p_elem)))
+ 0, p_elem)) ||
+ parse_engine_table_options(ha_thd(), file->ht,
+ file->table_share))
goto error_create;
if ((error= file->ha_create(part_name, tbl, create_info)))
{
@@ -1869,6 +1871,8 @@
{
if ((error= set_up_table_before_create(table_arg, from_buff,
create_info, i, NULL)) ||
+ parse_engine_table_options(ha_thd(), (*file)->ht,
+ (*file)->table_share) ||
((error= (*file)->ha_create(from_buff, table_arg, create_info))))
goto create_error;
}
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-03-15 11:51:23 +0000
+++ b/sql/handler.cc 2010-03-26 21:51:17 +0000
@@ -3716,7 +3716,12 @@
name= get_canonical_filename(table.file, share.path.str, name_buff);
+ if (parse_engine_table_options(thd, table.file->ht, &share))
+ goto err;
+
error= table.file->ha_create(name, &table, create_info);
+
+
VOID(closefrm(&table, 0));
if (error)
{
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2010-02-01 06:14:12 +0000
+++ b/sql/handler.h 2010-03-26 21:51:17 +0000
@@ -16,6 +16,9 @@
/* Definitions for parameters to do with handler-routines */
+#ifndef _HANDLER_H
+#define _HANDLER_H
+
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
@@ -23,6 +26,7 @@
#include <my_handler.h>
#include <ft_global.h>
#include <keycache.h>
+#include "create_options.h"
#ifndef NO_HASH
#define NO_HASH /* Not yet implemented */
@@ -516,6 +520,7 @@
struct st_table;
typedef struct st_table TABLE;
typedef struct st_table_share TABLE_SHARE;
+class engine_option;
struct st_foreign_key_info;
typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len,
@@ -549,6 +554,71 @@
enum log_status status;
};
+enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */
+ HA_OPTION_TYPE_STRING, /* char * */
+ HA_OPTION_TYPE_ENUM, /* uint */
+ HA_OPTION_TYPE_BOOL}; /* uint */
+
+#define HA_xOPTION_ULL(name, struc, field, def, min, max, blk_siz) \
+ { HA_OPTION_TYPE_ULL, name, sizeof(name)-1, \
+ offsetof(struc, field), def, min, max, blk_siz, 0 }
+#define HA_xOPTION_STRING(name, struc, field) \
+ { HA_OPTION_TYPE_STRING, name, sizeof(name)-1, \
+ offsetof(struc, field), 0, 0, 0, 0, 0 }
+#define HA_xOPTION_ENUM(name, struc, field, values, def) \
+ { HA_OPTION_TYPE_ENUM, name, sizeof(name)-1, \
+ offsetof(struc, field), def, 0, \
+ sizeof(values)-1, 0, values }
+#define HA_xOPTION_BOOL(name, struc, field, def) \
+ { HA_OPTION_TYPE_BOOL, name, sizeof(name)-1, \
+ offsetof(struc, field), def, 0, 1, 0, 0 }
+#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0 }
+
+#define HA_TOPTION_ULL(name, field, def, min, max, blk_siz) \
+ HA_xOPTION_ULL(name, ha_table_option_struct, field, def, min, max, blk_siz)
+#define HA_TOPTION_STRING(name, field) \
+ HA_xOPTION_STRING(name, ha_table_option_struct, field)
+#define HA_TOPTION_ENUM(name, field, values, def) \
+ HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def)
+#define HA_TOPTION_BOOL(name, field, def) \
+ HA_xOPTION_BOOL(name, ha_table_option_struct, field, def)
+#define HA_TOPTION_END HA_xOPTION_END
+
+#define HA_FOPTION_ULL(name, field, def, min, max, blk_siz) \
+ HA_xOPTION_ULL(name, ha_field_option_struct, field, def, min, max, blk_siz)
+#define HA_FOPTION_STRING(name, field) \
+ HA_xOPTION_STRING(name, ha_field_option_struct, field)
+#define HA_FOPTION_ENUM(name, field, values, def) \
+ HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def)
+#define HA_FOPTION_BOOL(name, field, def) \
+ HA_xOPTION_BOOL(name, ha_field_option_struct, field, def)
+#define HA_FOPTION_END HA_xOPTION_END
+
+#define HA_KOPTION_ULL(name, field, def, min, max, blk_siz) \
+ HA_xOPTION_ULL(name, ha_key_option_struct, field, def, min, max, blk_siz)
+#define HA_KOPTION_STRING(name, field) \
+ HA_xOPTION_STRING(name, ha_key_option_struct, field)
+#define HA_KOPTION_ENUM(name, field, values, def) \
+ HA_xOPTION_ENUM(name, ha_key_option_struct, field, values, def)
+#define HA_KOPTION_BOOL(name, field, values, def) \
+ HA_xOPTION_BOOL(name, ha_key_option_struct, field, values, def)
+#define HA_KOPTION_END HA_xOPTION_END
+
+typedef struct st_ha_create_table_option {
+ enum ha_option_type type;
+ const char *name;
+ size_t name_length;
+ ptrdiff_t offset;
+ ulonglong def_value;
+ ulonglong min_value, max_value, block_size;
+ const char *values;
+} ha_create_table_option;
+
+typedef struct st_ha_create_table_option_rules {
+ ha_create_table_option *table,
+ *field,
+ *key;
+} ha_create_table_option_rules;
enum handler_iterator_type
{
@@ -721,7 +791,7 @@
int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
const char *name);
uint32 license; /* Flag for Engine License */
- void *data; /* Location for engines to keep personal structures */
+ ha_create_table_option_rules *table_options_rules;
};
@@ -950,6 +1020,16 @@
bool varchar; /* 1 if table has a VARCHAR */
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
enum ha_choice page_checksum; /* If we have page_checksums */
+ engine_option_value *option_list; /* list of table create options */
+ engine_option_value *option_list_last;
+ /** structure with parsed options (for comparing fields in ALTER TABLE) */
+ void *option_struct;
+ /* following 4 fields assigned only for check_if_incompatible_data() */
+ void *old_option_struct;
+ Field **old_field;
+ KEY *old_key_info;
+ uint old_keys;
+
} HA_CREATE_INFO;
@@ -2241,3 +2321,5 @@
#define ha_binlog_wait(a) do {} while (0)
#define ha_binlog_end(a) do {} while (0)
#endif
+
+#endif
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2010-03-15 11:51:23 +0000
+++ b/sql/log_event.h 2010-03-26 21:51:17 +0000
@@ -1371,7 +1371,7 @@
MODE_PIPES_AS_CONCAT==0x2
MODE_ANSI_QUOTES==0x4
MODE_IGNORE_SPACE==0x8
- MODE_NOT_USED==0x10
+ MODE_CREATE_OPTIONS_ERR==0x10
MODE_ONLY_FULL_GROUP_BY==0x20
MODE_NO_UNSIGNED_SUBTRACTION==0x40
MODE_NO_DIR_IN_CREATE==0x80
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2010-03-15 11:51:23 +0000
+++ b/sql/mysql_priv.h 2010-03-26 21:51:17 +0000
@@ -54,7 +54,6 @@
#include "sql_plugin.h"
#include "scheduler.h"
#include "log_slow.h"
-
class Parser_state;
/**
@@ -520,7 +519,7 @@
#define MODE_PIPES_AS_CONCAT 2
#define MODE_ANSI_QUOTES 4
#define MODE_IGNORE_SPACE 8
-#define MODE_NOT_USED 16
+#define MODE_CREATE_OPTIONS_ERR 16
#define MODE_ONLY_FULL_GROUP_BY 32
#define MODE_NO_UNSIGNED_SUBTRACTION 64
#define MODE_NO_DIR_IN_CREATE 128
@@ -783,6 +782,7 @@
ulonglong *engine_data);
#include "sql_string.h"
#include "sql_list.h"
+#include "create_options.h"
#include "sql_map.h"
#include "my_decimal.h"
#include "handler.h"
@@ -1508,7 +1508,8 @@
char *change, List<String> *interval_list,
CHARSET_INFO *cs,
uint uint_geom_type,
- Virtual_column_info *vcol_info);
+ Virtual_column_info *vcol_info,
+ engine_option_value *create_options);
Create_field * new_create_field(THD *thd, char *field_name, enum_field_types type,
char *length, char *decimals,
uint type_modifier,
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-15 11:51:23 +0000
+++ b/sql/mysqld.cc 2010-03-26 21:51:17 +0000
@@ -243,7 +243,7 @@
static const char *sql_mode_names[]=
{
"REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
- "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
+ "CREATE_OPTIONS_ERR", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
"NO_DIR_IN_CREATE",
"POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
"NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
@@ -263,7 +263,7 @@
/*PIPES_AS_CONCAT*/ 15,
/*ANSI_QUOTES*/ 11,
/*IGNORE_SPACE*/ 12,
- /*?*/ 1,
+ /*CREATE_OPTIONS_ERR*/ 18,
/*ONLY_FULL_GROUP_BY*/ 18,
/*NO_UNSIGNED_SUBTRACTION*/ 23,
/*NO_DIR_IN_CREATE*/ 16,
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2010-03-15 11:51:23 +0000
+++ b/sql/share/errmsg.txt 2010-03-26 21:51:17 +0000
@@ -6240,3 +6240,8 @@
ER_DEBUG_SYNC_HIT_LIMIT
eng "debug sync point hit limit reached"
ger "Debug Sync Point Hit Limit erreicht"
+
+ER_UNKNOWN_OPTION
+ eng "Unknown option '%-.64s'='%-.64s'"
+ER_BAD_OPTION_VALUE
+ eng "Incorrect option value '%-.64s'='%-.64s'"
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sp.cc 2010-03-26 21:51:17 +0000
@@ -147,7 +147,8 @@
{
{ C_STRING_WITH_LEN("sql_mode") },
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
- "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
+ "'IGNORE_SPACE','CREATE_OPTIONS_ERR','ONLY_FULL_GROUP_BY',"
+ "'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sp_head.cc 2010-03-26 21:51:17 +0000
@@ -2216,7 +2216,7 @@
lex->charset ? lex->charset :
thd->variables.collation_database,
lex->uint_geom_type,
- lex->vcol_info))
+ lex->vcol_info, lex->option_list))
return TRUE;
if (field_def->interval_list.elements)
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-03-16 12:38:35 +0000
+++ b/sql/sql_class.cc 2010-03-26 21:51:17 +0000
@@ -106,6 +106,7 @@
key_create_info(rhs.key_create_info),
columns(rhs.columns, mem_root),
name(rhs.name),
+ option_list(rhs.option_list),
generated(rhs.generated)
{
list_copy_and_replace_each_value(columns, mem_root);
@@ -775,6 +776,7 @@
void THD::push_internal_handler(Internal_error_handler *handler)
{
+ DBUG_ENTER("THD::push_internal_handler");
if (m_internal_handler)
{
handler->m_prev_internal_handler= m_internal_handler;
@@ -784,6 +786,7 @@
{
m_internal_handler= handler;
}
+ DBUG_VOID_RETURN;
}
@@ -803,8 +806,10 @@
void THD::pop_internal_handler()
{
+ DBUG_ENTER("THD::pop_internal_handler");
DBUG_ASSERT(m_internal_handler != NULL);
m_internal_handler= m_internal_handler->m_prev_internal_handler;
+ DBUG_VOID_RETURN;
}
extern "C"
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_class.h 2010-03-26 21:51:17 +0000
@@ -204,13 +204,15 @@
KEY_CREATE_INFO key_create_info;
List<Key_part_spec> columns;
const char *name;
+ engine_option_value *option_list;
bool generated;
Key(enum Keytype type_par, const char *name_arg,
KEY_CREATE_INFO *key_info_arg,
- bool generated_arg, List<Key_part_spec> &cols)
+ bool generated_arg, List<Key_part_spec> &cols,
+ engine_option_value *create_opt)
:type(type_par), key_create_info(*key_info_arg), columns(cols),
- name(name_arg), generated(generated_arg)
+ name(name_arg), option_list(create_opt), generated(generated_arg)
{}
Key(const Key &rhs, MEM_ROOT *mem_root);
virtual ~Key() {}
@@ -239,7 +241,7 @@
Foreign_key(const char *name_arg, List<Key_part_spec> &cols,
Table_ident *table, List<Key_part_spec> &ref_cols,
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
- :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols),
+ :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL),
ref_table(table), ref_columns(ref_cols),
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
match_opt(match_opt_arg)
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_lex.h 2010-03-26 21:51:17 +0000
@@ -869,6 +869,7 @@
#define ALTER_ALL_PARTITION (1L << 21)
#define ALTER_REMOVE_PARTITIONING (1L << 22)
#define ALTER_FOREIGN_KEY (1L << 23)
+#define ALTER_CREATE_OPT (1L << 24)
enum enum_alter_table_change_level
{
@@ -1747,6 +1748,11 @@
const char *stmt_definition_end;
/**
+ Collects create options for Field and KEY
+ */
+ engine_option_value *option_list, *option_list_last;
+
+ /**
During name resolution search only in the table list given by
Name_resolution_context::first_name_resolution_table and
Name_resolution_context::last_name_resolution_table
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-03-16 12:38:35 +0000
+++ b/sql/sql_parse.cc 2010-03-26 21:51:17 +0000
@@ -6155,7 +6155,8 @@
char *change,
List<String> *interval_list, CHARSET_INFO *cs,
uint uint_geom_type,
- Virtual_column_info *vcol_info)
+ Virtual_column_info *vcol_info,
+ engine_option_value *create_options)
{
register Create_field *new_field;
LEX *lex= thd->lex;
@@ -6173,7 +6174,7 @@
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
key= new Key(Key::PRIMARY, NullS,
&default_key_create_info,
- 0, lex->col_list);
+ 0, lex->col_list, NULL);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty();
}
@@ -6183,7 +6184,7 @@
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
key= new Key(Key::UNIQUE, NullS,
&default_key_create_info, 0,
- lex->col_list);
+ lex->col_list, NULL);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty();
}
@@ -6241,7 +6242,8 @@
if (!(new_field= new Create_field()) ||
new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
default_value, on_update_value, comment, change,
- interval_list, cs, uint_geom_type, vcol_info))
+ interval_list, cs, uint_geom_type, vcol_info,
+ create_options))
DBUG_RETURN(1);
lex->alter_info.create_list.push_back(new_field);
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_show.cc 2010-03-26 21:51:17 +0000
@@ -83,6 +83,11 @@
static void
append_algorithm(TABLE_LIST *table, String *buff);
+static void
+append_quoted(THD *thd, String *packet, const char *name, uint length,
+ int q);
+static int get_quote_char_for_option(THD *thd, const char *name, uint length);
+
static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table);
/***************************************************************************
@@ -951,6 +956,30 @@
DBUG_RETURN(0);
}
+
+/**
+ Goes through all character combinations and ensure that it is number.
+
+ @param name attribute name
+ @param name_length length of name
+
+ @retval # Pointer to conflicting character
+ @retval 0 No conflicting character
+*/
+
+static const char *is_unsigned_number(const char *name, uint name_length)
+{
+ const char *end= name + name_length;
+
+ for (; name < end ; name++)
+ {
+ uchar chr= (uchar) *name;
+ if (chr < '0' || chr > '9')
+ return name;
+ }
+ return 0;
+}
+
/*
Go through all character combinations and ensure that sql_lex.cc can
parse it as an identifier.
@@ -1001,19 +1030,26 @@
void
append_identifier(THD *thd, String *packet, const char *name, uint length)
{
+ int q= get_quote_char_for_identifier(thd, name, length);
+
+ append_quoted(thd, packet, name, length, q);
+}
+
+static void
+append_quoted(THD *thd, String *packet, const char *name, uint length,
+ int q)
+{
+ char quote_char;
const char *name_end;
- char quote_char;
- int q= get_quote_char_for_identifier(thd, name, length);
if (q == EOF)
{
packet->append(name, length, packet->charset());
return;
}
-
/*
The identifier must be quoted as it includes a quote character or
- it's a keyword
+ it's a keyword
*/
VOID(packet->reserve(length*2 + 2));
@@ -1076,6 +1112,27 @@
return '`';
}
+/**
+ Gets the quote character for displaying an option key.
+
+ @param thd Thread handler
+ @param name name to quote
+ @param length length of name
+
+ @retval EOF No quote character is needed
+ @retval # Quote character
+*/
+
+static int get_quote_char_for_option(THD *thd, const char *name, uint length)
+{
+ if (length &&
+ !require_quotes(name, length))
+ return EOF;
+ if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
+ return '"';
+ return '`';
+}
+
/* Append directory name (if exists) to CREATE INFO */
@@ -1173,6 +1230,35 @@
return has_default;
}
+
+/**
+ Appends list of options to string
+
+ @param thd thread handler
+ @param packet string to append
+ @param opt list of options
+*/
+
+static void append_create_options(THD *thd, String *packet,
+ engine_option_value *opt)
+{
+ for(; opt; opt= opt->next)
+ {
+ packet->append(' ');
+ {
+ int q= get_quote_char_for_option(thd, opt->name.str, opt->name.length);
+
+ append_quoted(thd, packet, opt->name.str, opt->name.length, q);
+ }
+ packet->append('=');
+ if (opt->value.length < 21 &&
+ is_unsigned_number(opt->value.str, opt->value.length) == NULL)
+ packet->append(opt->value.str, opt->value.length);
+ else
+ append_unescaped(packet, opt->value.str, opt->value.length);
+ }
+}
+
/*
Build a CREATE TABLE statement for a table.
@@ -1355,6 +1441,8 @@
packet->append(STRING_WITH_LEN(" COMMENT "));
append_unescaped(packet, field->comment.str, field->comment.length);
}
+ if (field->option_list)
+ append_create_options(thd, packet, field->option_list);
}
key_info= table->key_info;
@@ -1426,6 +1514,8 @@
append_identifier(thd, packet, parser_name->str, parser_name->length);
packet->append(STRING_WITH_LEN(" */ "));
}
+ if (key_info->option_list)
+ append_create_options(thd, packet, key_info->option_list);
}
/*
@@ -1585,6 +1675,10 @@
packet->append(STRING_WITH_LEN(" CONNECTION="));
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
}
+ /* create_table_options can be NULL for temporary tables */
+ if (share->option_list)
+ append_create_options(thd, packet,
+ share->option_list);
append_directory(thd, packet, "DATA", create_info.data_file_name);
append_directory(thd, packet, "INDEX", create_info.index_file_name);
}
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_table.cc 2010-03-26 21:51:17 +0000
@@ -2562,6 +2562,7 @@
ulong record_offset= 0;
KEY *key_info;
KEY_PART_INFO *key_part_info;
+ ha_create_table_option_rules *rules, fake_empty={NULL,NULL,NULL};
int timestamps= 0, timestamps_with_niladic= 0;
int field_no,dup_no;
int select_field_pos,auto_increment=0;
@@ -2570,6 +2571,10 @@
uint total_uneven_bit_length= 0;
DBUG_ENTER("mysql_prepare_create_table");
+ rules= (create_info->db_type->table_options_rules ?
+ create_info->db_type->table_options_rules:
+ &fake_empty);
+
select_field_pos= alter_info->create_list.elements - select_field_count;
null_fields=blob_columns=0;
create_info->varchar= 0;
@@ -2863,6 +2868,11 @@
sql_field->offset= record_offset;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
auto_increment++;
+ if (parse_option_list(thd, &sql_field->option_struct,
+ sql_field->option_list,
+ rules->field, FALSE,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
/*
For now skip fields that are not physically stored in the database
(virtual fields) and update their offset later
@@ -3061,6 +3071,12 @@
key_info->key_part=key_part_info;
key_info->usable_key_parts= key_number;
key_info->algorithm= key->key_create_info.algorithm;
+ key_info->option_list= key->option_list;
+ if (parse_option_list(thd, &key_info->option_struct,
+ key_info->option_list,
+ rules->key, FALSE,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
if (key->type == Key::FULLTEXT)
{
@@ -3438,6 +3454,12 @@
}
}
+ if (parse_option_list(thd, &create_info->option_struct,
+ create_info->option_list,
+ rules->table, FALSE,
+ thd->mem_root))
+ DBUG_RETURN(TRUE);
+
DBUG_RETURN(FALSE);
}
@@ -5809,6 +5831,9 @@
DBUG_RETURN(0);
}
+ /* to allow check_if_incompatible_data compare */
+ field->new_option_struct= tmp_new_field->option_struct;
+
/* Don't pack rows in old tables if the user has requested this. */
if (create_info->row_type == ROW_TYPE_DYNAMIC ||
(tmp_new_field->flags & BLOB_FLAG) ||
@@ -5956,9 +5981,15 @@
}
DBUG_PRINT("info", ("index added: '%s'", new_key->name));
}
+ else
+ table_key->new_option_struct= new_key->option_struct;
}
/* Check if changes are compatible with current handler without a copy */
+ create_info->old_option_struct= table->s->option_struct;
+ create_info->old_field= table->field;
+ create_info->old_keys= table->s->keys;
+ create_info->old_key_info= table->key_info;
if (table->file->check_if_incompatible_data(create_info, changes))
{
DBUG_PRINT("info", ("check_if_incompatible_data() -> "
@@ -6132,6 +6163,16 @@
}
restore_record(table, s->default_values); // Empty record for DEFAULT
+ if (create_info->option_list)
+ {
+ create_info->option_list=
+ merge_engine_table_options(table->s->option_list,
+ create_info->option_list,
+ thd->mem_root);
+ }
+ else
+ create_info->option_list= table->s->option_list;
+
/*
First collect all fields from table which isn't in drop_list
*/
@@ -6384,7 +6425,7 @@
key= new Key(key_type, key_name,
&key_create_info,
test(key_info->flags & HA_GENERATED_KEY),
- key_parts);
+ key_parts, key_info->option_list);
new_key_list.push_back(key);
}
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_view.cc 2010-03-26 21:51:17 +0000
@@ -1183,7 +1183,7 @@
+ MODE_PIPES_AS_CONCAT affect expression parsing
+ MODE_ANSI_QUOTES affect expression parsing
+ MODE_IGNORE_SPACE affect expression parsing
- - MODE_NOT_USED not used :)
+ - MODE_CREATE_OPTIONS_ERR affect only CREATE/ALTER TABLE parsing
* MODE_ONLY_FULL_GROUP_BY affect execution
* MODE_NO_UNSIGNED_SUBTRACTION affect execution
- MODE_NO_DIR_IN_CREATE affect table creation only
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-03-15 11:51:23 +0000
+++ b/sql/sql_yacc.yy 2010-03-26 21:51:17 +0000
@@ -607,6 +607,7 @@
lex->alter_info.flags= ALTER_ADD_INDEX;
lex->col_list.empty();
lex->change= NullS;
+ lex->option_list= lex->option_list_last= NULL;
return FALSE;
}
@@ -616,7 +617,7 @@
{
Key *key;
key= new Key(type, name, info ? info : &lex->key_create_info, generated,
- lex->col_list);
+ lex->col_list, lex->option_list);
if (key == NULL)
return TRUE;
@@ -1858,6 +1859,8 @@
lex->create_info.default_table_charset= NULL;
lex->name.str= 0;
lex->name.length= 0;
+ lex->create_info.option_list=
+ lex->create_info.option_list_last= NULL;
}
create2
{
@@ -2340,6 +2343,7 @@
lex->interval_list.empty();
lex->uint_geom_type= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
;
@@ -4748,6 +4752,43 @@
Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
Lex->create_info.transactional= $3;
}
+ | IDENT_sys equal TEXT_STRING_sys
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->create_info.option_list,
+ &Lex->create_info.option_list_last);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
+ | IDENT_sys equal ident
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->create_info.option_list,
+ &Lex->create_info.option_list_last);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
+ | IDENT_sys equal ulonglong_num
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3,
+ &Lex->create_info.option_list,
+ &Lex->create_info.option_list_last,
+ YYTHD->mem_root);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
+ | IDENT_sys equal DEFAULT
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ NULL, 0,
+ &Lex->create_info.option_list,
+ &Lex->create_info.option_list_last);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
;
default_charset:
@@ -4869,25 +4910,33 @@
;
key_def:
- normal_key_type opt_ident key_alg '(' key_list ')' normal_key_options
+ normal_key_type opt_ident key_alg '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ normal_key_options
{
if (add_create_index (Lex, $1, $2))
MYSQL_YYABORT;
}
| fulltext opt_key_or_index opt_ident init_key_options
- '(' key_list ')' fulltext_key_options
+ '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ fulltext_key_options
{
if (add_create_index (Lex, $1, $3))
MYSQL_YYABORT;
}
| spatial opt_key_or_index opt_ident init_key_options
- '(' key_list ')' spatial_key_options
+ '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ spatial_key_options
{
if (add_create_index (Lex, $1, $3))
MYSQL_YYABORT;
}
| opt_constraint constraint_key_type opt_ident key_alg
- '(' key_list ')' normal_key_options
+ '(' key_list ')'
+ { Lex->option_list= Lex->option_list_last= NULL; }
+ normal_key_options
{
if (add_create_index (Lex, $2, $3 ? $3 : $1))
MYSQL_YYABORT;
@@ -4950,6 +4999,7 @@
lex->comment=null_lex_str;
lex->charset=NULL;
lex->vcol_info= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
field_def
{
@@ -4960,7 +5010,7 @@
&lex->comment,
lex->change,&lex->interval_list,lex->charset,
lex->uint_geom_type,
- lex->vcol_info))
+ lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
}
;
@@ -5380,6 +5430,43 @@
Lex->charset=$2;
}
}
+ | IDENT_sys equal TEXT_STRING_sys
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
+ | IDENT_sys equal ident
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
+ | IDENT_sys equal ulonglong_num
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3,
+ &Lex->option_list,
+ &Lex->option_list_last,
+ YYTHD->mem_root);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
+ | IDENT_sys equal DEFAULT
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ NULL, 0,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
;
now_or_signed_literal:
@@ -5669,6 +5756,43 @@
all_key_opt:
KEY_BLOCK_SIZE opt_equal ulong_num
{ Lex->key_create_info.block_size= $3; }
+ | IDENT_sys equal TEXT_STRING_sys
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
+ | IDENT_sys equal ident
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3.str, $3.length,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
+ | IDENT_sys equal ulonglong_num
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ $3,
+ &Lex->option_list,
+ &Lex->option_list_last,
+ YYTHD->mem_root);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
+ | IDENT_sys equal DEFAULT
+ {
+ new (YYTHD->mem_root)
+ engine_option_value($1,
+ NULL, 0,
+ &Lex->option_list,
+ &Lex->option_list_last);
+ Lex->alter_info.flags|= ALTER_CREATE_OPT;
+ }
;
normal_key_opt:
@@ -6158,6 +6282,7 @@
LEX *lex=Lex;
lex->change= $3.str;
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
+ lex->option_list= lex->option_list_last= NULL;
}
field_spec opt_place
| MODIFY_SYM opt_column field_ident
@@ -6169,6 +6294,7 @@
lex->charset= NULL;
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
lex->vcol_info= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
field_def
{
@@ -6180,7 +6306,7 @@
&lex->comment,
$3.str, &lex->interval_list, lex->charset,
lex->uint_geom_type,
- lex->vcol_info))
+ lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
}
opt_place
@@ -6287,8 +6413,7 @@
}
| create_table_options_space_separated
{
- LEX *lex=Lex;
- lex->alter_info.flags|= ALTER_OPTIONS;
+ Lex->alter_info.flags|= ALTER_OPTIONS;
}
| FORCE_SYM
{
@@ -13630,6 +13755,7 @@
lex->interval_list.empty();
lex->type= 0;
lex->vcol_info= 0;
+ lex->option_list= lex->option_list_last= NULL;
}
type /* $11 */
{ /* $12 */
@@ -13880,6 +14006,7 @@
}
;
+
/**
@} (end of group Parser)
*/
=== modified file 'sql/structs.h'
--- a/sql/structs.h 2010-02-01 06:14:12 +0000
+++ b/sql/structs.h 2010-03-26 21:51:17 +0000
@@ -68,6 +68,7 @@
uint8 null_bit; /* Position to null_bit */
} KEY_PART_INFO ;
+class engine_option_value;
typedef struct st_key {
uint key_length; /* Tot length of key */
@@ -101,6 +102,14 @@
int bdb_return_if_eq;
} handler;
struct st_table *table;
+ /** reference to the list of options or NULL */
+ engine_option_value *option_list;
+ void *option_struct; /* structure with parsed options */
+ /**
+ structure with parsed new field parameters in ALTER TABLE for
+ check_if_incompatible_data()
+ */
+ void *new_option_struct;
} KEY;
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2010-03-15 11:51:23 +0000
+++ b/sql/table.cc 2010-03-26 21:51:17 +0000
@@ -667,12 +667,13 @@
uint db_create_options, keys, key_parts, n_length;
uint key_info_length, com_length, null_bit_pos;
uint vcol_screen_length;
- uint extra_rec_buf_length;
+ uint extra_rec_buf_length, options_len;
uint i,j;
bool use_hash;
char *keynames, *names, *comment_pos, *vcol_screen_pos;
uchar *record;
- uchar *disk_buff, *strpos, *null_flags, *null_pos;
+ uchar *disk_buff, *strpos, *null_flags, *null_pos, *options;
+ uchar *buff= 0;
ulong pos, record_offset, *rec_per_key, rec_buff_length;
handler *handler_file= 0;
KEY *keyinfo;
@@ -788,7 +789,6 @@
for (i=0 ; i < keys ; i++, keyinfo++)
{
- keyinfo->table= 0; // Updated in open_frm
if (new_frm_ver >= 3)
{
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
@@ -858,15 +858,14 @@
if ((n_length= uint4korr(head+55)))
{
/* Read extra data segment */
- uchar *buff, *next_chunk, *buff_end;
+ uchar *next_chunk, *buff_end;
DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
goto err;
if (my_pread(file, buff, n_length, record_offset + share->reclength,
MYF(MY_NABP)))
{
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
share->connect_string.length= uint2korr(buff);
if (!(share->connect_string.str= strmake_root(&share->mem_root,
@@ -874,8 +873,7 @@
share->connect_string.
length)))
{
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
next_chunk+= share->connect_string.length + 2;
buff_end= buff + n_length;
@@ -895,8 +893,7 @@
plugin_data(tmp_plugin, handlerton *)))
{
/* bad file, legacy_db_type did not match the name */
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
/*
tmp_plugin is locked with a local lock.
@@ -925,8 +922,7 @@
error= 8;
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"--skip-partition");
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
plugin_unlock(NULL, share->db_plugin);
share->db_plugin= ha_lock_engine(NULL, partition_hton);
@@ -940,8 +936,7 @@
/* purecov: begin inspected */
error= 8;
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
/* purecov: end */
}
next_chunk+= str_db_type_length + 2;
@@ -957,16 +952,14 @@
memdup_root(&share->mem_root, next_chunk + 4,
partition_info_len + 1)))
{
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
}
#else
if (partition_info_len)
{
DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined"));
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
#endif
next_chunk+= 5 + partition_info_len;
@@ -992,6 +985,17 @@
#endif
next_chunk++;
}
+ if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
+ {
+ /*
+ store options position, but skip till the time we will
+ know number of fields
+ */
+ options_len= uint4korr(next_chunk);
+ options= next_chunk + 4;
+ next_chunk+= options_len;
+ options_len-= 4;
+ }
keyinfo= share->key_info;
for (i= 0; i < keys; i++, keyinfo++)
{
@@ -1002,8 +1006,7 @@
{
DBUG_PRINT("error",
("fulltext key uses parser that is not defined in .frm"));
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
parser_name.str= (char*) next_chunk;
parser_name.length= strlen((char*) next_chunk);
@@ -1013,12 +1016,10 @@
if (! keyinfo->parser)
{
my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str);
- my_free(buff, MYF(0));
- goto err;
+ goto free_and_err;
}
}
}
- my_free(buff, MYF(0));
}
share->key_block_size= uint2korr(head+62);
@@ -1028,21 +1029,21 @@
share->rec_buff_length= rec_buff_length;
if (!(record= (uchar *) alloc_root(&share->mem_root,
rec_buff_length)))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
share->default_values= record;
if (my_pread(file, record, (size_t) share->reclength,
record_offset, MYF(MY_NABP)))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
if (my_read(file, head,288,MYF(MY_NABP)))
- goto err;
+ goto free_and_err;
#ifdef HAVE_CRYPTED_FRM
if (crypted)
{
crypted->decode((char*) head+256,288-256);
if (sint2korr(head+284) != 0) // Should be 0
- goto err; // Wrong password
+ goto free_and_err; // Wrong password
}
#endif
@@ -1062,6 +1063,8 @@
share->comment.length);
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length, vcol_screen_length));
+
+
if (!(field_ptr = (Field **)
alloc_root(&share->mem_root,
(uint) ((share->fields+1)*sizeof(Field*)+
@@ -1070,14 +1073,14 @@
keys+3)*sizeof(char *)+
(n_length+int_length+com_length+
vcol_screen_length)))))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
share->field= field_ptr;
read_length=(uint) (share->fields * field_pack_length +
pos+ (uint) (n_length+int_length+com_length+
vcol_screen_length));
if (read_string(file,(uchar**) &disk_buff,read_length))
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
#ifdef HAVE_CRYPTED_FRM
if (crypted)
{
@@ -1104,7 +1107,7 @@
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
if (share->fieldnames.count != share->fields)
- goto err;
+ goto free_and_err;
fix_type_pointers(&interval_array, share->intervals, interval_count,
&names);
@@ -1118,7 +1121,7 @@
uint count= (uint) (interval->count + 1) * sizeof(uint);
if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
count)))
- goto err;
+ goto free_and_err;
for (count= 0; count < interval->count; count++)
{
char *val= (char*) interval->type_names[count];
@@ -1134,7 +1137,7 @@
/* Allocate handler */
if (!(handler_file= get_new_handler(share, thd->mem_root,
share->db_type())))
- goto err;
+ goto free_and_err;
record= share->default_values-1; /* Fieldstart = 1 */
if (share->null_field_first)
@@ -1196,7 +1199,7 @@
charset= &my_charset_bin;
#else
error= 4; // unsupported field type
- goto err;
+ goto free_and_err;
#endif
}
else
@@ -1207,7 +1210,7 @@
{
error= 5; // Unknown or unavailable charset
errarg= (int) strpos[14];
- goto err;
+ goto free_and_err;
}
}
@@ -1247,7 +1250,7 @@
if ((uint)vcol_screen_pos[0] != 1)
{
error= 4;
- goto err;
+ goto free_and_err;
}
field_type= (enum_field_types) (uchar) vcol_screen_pos[1];
fld_stored_in_db= (bool) (uint) vcol_screen_pos[2];
@@ -1256,7 +1259,7 @@
(char *)memdup_root(&share->mem_root,
vcol_screen_pos+(uint)FRM_VCOL_HEADER_SIZE,
vcol_expr_length)))
- goto err;
+ goto free_and_err;
vcol_info->expr_str.length= vcol_expr_length;
vcol_screen_pos+= vcol_info_length;
share->vfields++;
@@ -1346,7 +1349,7 @@
if (!reg_field) // Not supported field type
{
error= 4;
- goto err; /* purecov: inspected */
+ goto free_and_err; /* purecov: inspected */
}
reg_field->field_index= i;
@@ -1385,7 +1388,7 @@
sent (OOM).
*/
error= 8;
- goto err;
+ goto free_and_err;
}
}
if (!reg_field->stored_in_db)
@@ -1462,7 +1465,7 @@
if (!key_part->fieldnr)
{
error= 4; // Wrong file
- goto err;
+ goto free_and_err;
}
field= key_part->field= share->field[key_part->fieldnr-1];
key_part->type= field->key_type();
@@ -1627,6 +1630,15 @@
null_length, 255);
}
+ if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
+ {
+ DBUG_ASSERT(options_len);
+ if (engine_table_options_frm_read(options, options_len, share) ||
+ parse_engine_table_options(thd, handler_file->ht, share))
+ goto free_and_err;
+ }
+ my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
+
if (share->found_next_number_field)
{
reg_field= *share->found_next_number_field;
@@ -1685,6 +1697,8 @@
#endif
DBUG_RETURN (0);
+ free_and_err:
+ my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
err:
share->error= error;
share->open_errno= my_errno;
@@ -2883,6 +2897,7 @@
ulong length;
uchar fill[IO_SIZE];
int create_flags= O_RDWR | O_TRUNC;
+ DBUG_ENTER("create_frm");
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
create_flags|= O_EXCL | O_NOFOLLOW;
@@ -2964,7 +2979,7 @@
{
VOID(my_close(file,MYF(0)));
VOID(my_delete(name,MYF(0)));
- return(-1);
+ DBUG_RETURN(-1);
}
}
}
@@ -2975,7 +2990,7 @@
else
my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
}
- return (file);
+ DBUG_RETURN(file);
} /* create_frm */
@@ -2993,7 +3008,7 @@
create_info->table_charset= 0;
create_info->comment= share->comment;
create_info->transactional= share->transactional;
- create_info->page_checksum= share->page_checksum;
+ create_info->option_list= share->option_list;
DBUG_VOID_RETURN;
}
=== modified file 'sql/table.h'
--- a/sql/table.h 2010-02-12 08:47:31 +0000
+++ b/sql/table.h 2010-03-26 21:51:17 +0000
@@ -340,6 +340,8 @@
#ifdef NOT_YET
struct st_table *open_tables; /* link to open tables */
#endif
+ engine_option_value *option_list; /* text options for table */
+ void *option_struct; /* structure with parsed options */
/* The following is copied to each TABLE on OPEN */
Field **field;
=== modified file 'sql/unireg.cc'
--- a/sql/unireg.cc 2010-01-04 17:54:42 +0000
+++ b/sql/unireg.cc 2010-03-26 21:51:17 +0000
@@ -46,6 +46,13 @@
uint reclength, ulong data_offset,
handler *handler);
+uint engine_table_options_frm_length(engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info);
+uchar *engine_table_options_frm_image(uchar *buff,
+ engine_option_value *table_option_list,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info);
/**
An interceptor to hijack ER_TOO_MANY_FIELDS error from
pack_screens and retry again without UNIREG screens.
@@ -75,6 +82,7 @@
return is_handled;
}
+
/*
Create a frm (table definition) file
@@ -107,6 +115,7 @@
ulong key_buff_length;
File file;
ulong filepos, data_offset;
+ uint options_len= 0;
uchar fileinfo[64],forminfo[288],*keybuff;
TYPELIB formnames;
uchar *screen_buff;
@@ -183,6 +192,17 @@
create_info->extra_size+= key_info[i].parser_name->length + 1;
}
+ {
+ options_len= engine_table_options_frm_length(create_info->option_list,
+ create_fields,
+ keys, key_info);
+ if (options_len)
+ {
+ create_info->table_options|= HA_OPTION_TEXT_CREATE_OPTIONS;
+ create_info->extra_size+= (options_len+= 4);
+ }
+ }
+
if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo,
create_info, keys)) < 0)
{
@@ -294,6 +314,25 @@
if (my_write(file, (uchar*) buff, 6, MYF_RW))
goto err;
}
+
+ if (options_len)
+ {
+ uchar *optbuff= (uchar *)my_malloc(options_len, MYF(0));
+ my_bool error;
+ DBUG_PRINT("info", ("Create options length: %u", options_len));
+ if (!optbuff)
+ goto err;
+ int4store(optbuff, options_len);
+ engine_table_options_frm_image(optbuff + 4,
+ create_info->option_list,
+ create_fields,
+ keys, key_info);
+ error= my_write(file, optbuff, options_len, MYF_RW);
+ my_free(optbuff, MYF(0));
+ if (error)
+ goto err;
+ }
+
for (i= 0; i < keys; i++)
{
if (key_info[i].parser_name)
=== modified file 'storage/example/ha_example.cc'
--- a/storage/example/ha_example.cc 2010-03-03 14:44:14 +0000
+++ b/storage/example/ha_example.cc 2010-03-26 21:51:17 +0000
@@ -62,7 +62,7 @@
ha_example::rnd_next
ha_example::rnd_next
ha_example::rnd_next
- ha_example::rnd_next
+ ha_example::rnd_nex/t
ha_example::rnd_next
ha_example::rnd_next
ha_example::rnd_next
@@ -113,6 +113,55 @@
/* The mutex used to init the hash; variable for example share methods */
pthread_mutex_t example_mutex;
+
+/**
+ structure for CREATE TABLE options (table options)
+*/
+
+struct example_table_options_struct
+{
+ const char *strparam;
+ ulonglong ullparam;
+ uint enumparam;
+ uint boolparam;
+};
+
+
+/**
+ structure for CREATE TABLE options (table options)
+*/
+
+struct example_field_options_struct
+{
+ const char *compex_param_to_parse_it_in_engine;
+};
+
+#define ha_table_option_struct example_table_options_struct
+ha_create_table_option example_table_option_list[]=
+{
+ HA_TOPTION_ULL("UUL", ullparam, UINT_MAX32, 0, UINT_MAX32, 1),
+ HA_TOPTION_STRING("STR", strparam),
+ HA_TOPTION_ENUM("one_or_two", enumparam, "one,two", 0),
+ HA_TOPTION_BOOL("YESNO", boolparam, 1),
+ HA_TOPTION_END
+};
+
+#define ha_field_option_struct example_field_options_struct
+ha_create_table_option example_field_option_list[]=
+{
+ HA_FOPTION_STRING("COMPLEX", compex_param_to_parse_it_in_engine),
+ HA_FOPTION_END
+};
+
+
+ha_create_table_option_rules example_table_option_list_rules=
+{
+ example_table_option_list,
+ example_field_option_list,
+ NULL
+};
+
+
/**
@brief
Function we use in the creation of our hash to get key.
@@ -138,6 +187,7 @@
example_hton->state= SHOW_OPTION_YES;
example_hton->create= example_create_handler;
example_hton->flags= HTON_CAN_RECREATE;
+ example_hton->table_options_rules= &example_table_option_list_rules;
DBUG_RETURN(0);
}
@@ -789,7 +839,7 @@
int ha_example::rename_table(const char * from, const char * to)
{
DBUG_ENTER("ha_example::rename_table ");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ DBUG_RETURN(0);
}
@@ -836,14 +886,85 @@
int ha_example::create(const char *name, TABLE *table_arg,
HA_CREATE_INFO *create_info)
{
+ example_table_options_struct *prm=
+ (example_table_options_struct *)table_arg->s->option_struct;
DBUG_ENTER("ha_example::create");
/*
This is not implemented but we want someone to be able to see that it
works.
*/
+
+ DBUG_ASSERT(prm);
+ DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\
+ "boolparam: %u",
+ (prm->strparam ? prm->strparam : "<NULL>"),
+ prm->ullparam, prm->enumparam, prm->boolparam));
+ for (Field **field= table_arg->s->field; *field; field++)
+ {
+ example_field_options_struct *fprm=
+ (example_field_options_struct *)(*field)->option_struct;
+ DBUG_ASSERT(fprm);
+ DBUG_PRINT("info", ("field: %s complex: '%-.64s'",
+ (*field)->field_name,
+ (fprm->compex_param_to_parse_it_in_engine ?
+ fprm->compex_param_to_parse_it_in_engine :
+ "<NULL>")));
+
+ }
+
DBUG_RETURN(0);
}
+bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes)
+{
+ example_table_options_struct *prm;
+ DBUG_ENTER("ha_example::check_if_incompatible_data");
+ DBUG_ASSERT(info->option_struct);
+ DBUG_ASSERT(info->old_option_struct);
+ DBUG_ASSERT(info->old_option_struct);
+ prm= (example_table_options_struct *)info->option_struct;
+ DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u "\
+ "boolparam: %u",
+ (prm->strparam ? prm->strparam : "<NULL>"),
+ prm->ullparam, prm->enumparam, prm->boolparam));
+
+ prm= (example_table_options_struct *)info->old_option_struct;
+ DBUG_PRINT("info", ("old strparam: '%-.64s' ullparam: %llu enumparam: %u "\
+ "boolparam: %u",
+ (prm->strparam ? prm->strparam : "<NULL>"),
+ prm->ullparam, prm->enumparam, prm->boolparam));
+
+ for (Field **field= info->old_field; *field; field++)
+ {
+ example_field_options_struct *fprm;
+ if ((*field)->new_option_struct)
+ {
+ fprm=
+ (example_field_options_struct *)(*field)->new_option_struct;
+ DBUG_PRINT("info", ("new field: %s complex: '%-.64s'",
+ (*field)->field_name,
+ (fprm->compex_param_to_parse_it_in_engine ?
+ fprm->compex_param_to_parse_it_in_engine :
+ "<NULL>")));
+ }
+ else
+ DBUG_PRINT("info", ("new field %s is the same", (*field)->field_name));
+
+ fprm=
+ (example_field_options_struct *)(*field)->option_struct;
+ DBUG_ASSERT(fprm);
+ DBUG_PRINT("info", ("old field: %s complex: '%-.64s'",
+ (*field)->field_name,
+ (fprm->compex_param_to_parse_it_in_engine ?
+ fprm->compex_param_to_parse_it_in_engine :
+ "<NULL>")));
+ }
+
+ DBUG_RETURN(COMPATIBLE_DATA_YES);
+}
+
+
struct st_mysql_storage_engine example_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
=== modified file 'storage/example/ha_example.h'
--- a/storage/example/ha_example.h 2007-08-13 13:11:25 +0000
+++ b/storage/example/ha_example.h 2010-03-26 21:51:17 +0000
@@ -245,6 +245,8 @@
int rename_table(const char * from, const char * to);
int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); ///< required
+ bool check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); ///< required
=== modified file 'storage/pbxt/src/discover_xt.cc'
--- a/storage/pbxt/src/discover_xt.cc 2010-02-01 06:14:12 +0000
+++ b/storage/pbxt/src/discover_xt.cc 2010-03-26 21:51:17 +0000
@@ -1623,7 +1623,7 @@
#endif
NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/,
NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/,
- NULL /*vcol_info*/))
+ NULL /*vcol_info*/, NULL /* create options */))
#endif
goto error;
2
1

[Maria-developers] [Branch ~maria-captains/maria/5.1] Rev 2840: Fixed wrong regexps
by noreply@launchpad.net 01 Apr '10
by noreply@launchpad.net 01 Apr '10
01 Apr '10
------------------------------------------------------------
revno: 2840
committer: Michael Widenius <monty(a)askmonty.org>
branch nick: maria-5.1
timestamp: Thu 2010-04-01 12:40:11 +0300
message:
Fixed wrong regexps
modified:
support-files/compiler_warnings.supp
--
lp:maria
https://code.launchpad.net/~maria-captains/maria/5.1
Your team Maria developers is subscribed to branch lp:maria.
To unsubscribe from this branch go to https://code.launchpad.net/~maria-captains/maria/5.1/+edit-subscription
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2840)
by Michael Widenius 01 Apr '10
by Michael Widenius 01 Apr '10
01 Apr '10
#At lp:maria based on revid:monty@askmonty.org-20100401090842-f0oddzva8k49zwsy
2840 Michael Widenius 2010-04-01
Fixed wrong regexps
modified:
support-files/compiler_warnings.supp
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-04-01 09:08:42 +0000
+++ b/support-files/compiler_warnings.supp 2010-04-01 09:40:11 +0000
@@ -27,7 +27,7 @@ pars0grm.tab.c: .*'yyerrorlab' : unrefer
_flex_tmp.c: .*not enough actual parameters for macro 'yywrap'.*
pars0lex.l: .*conversion from 'ulint' to 'int', possible loss of data.*
btr/btr0cur\.c: .*value computed is not used.*: 3175-3375
-include/buf0buf\.ic: unused parameter ���mtr���
+include/buf0buf\.ic: unused parameter .*mtr.*
fil/fil0fil\.c: pointer targets in passing argument.*differ in signedness
fil/fil0fil\.c: comparison between signed and unsigned : 3100-3199
fil/fil0fil\.c: unused parameter
@@ -58,7 +58,7 @@ readline\.c : unused parameter
term\.c : unused parameter
vi\.c : unused parameter
common\.c : unused parameter
-term\.c : *.*
+term\.c : .*
#
1
0

[Maria-developers] [Branch ~maria-captains/maria/5.1] Rev 2839: Added missing space before :, which caused failuers in buildbot
by noreply@launchpad.net 01 Apr '10
by noreply@launchpad.net 01 Apr '10
01 Apr '10
------------------------------------------------------------
revno: 2839
committer: Michael Widenius <monty(a)askmonty.org>
branch nick: maria-5.1
timestamp: Thu 2010-04-01 12:08:42 +0300
message:
Added missing space before :, which caused failuers in buildbot
modified:
support-files/compiler_warnings.supp
--
lp:maria
https://code.launchpad.net/~maria-captains/maria/5.1
Your team Maria developers is subscribed to branch lp:maria.
To unsubscribe from this branch go to https://code.launchpad.net/~maria-captains/maria/5.1/+edit-subscription
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (monty:2764)
by Michael Widenius 01 Apr '10
by Michael Widenius 01 Apr '10
01 Apr '10
#At lp:maria/5.2 based on revid:monty@askmonty.org-20100401090935-b2yfd23r67e7sl42
2764 Michael Widenius 2010-04-01 [merge]
Auto merge with 5.1
modified:
support-files/compiler_warnings.supp
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-03-31 19:12:21 +0000
+++ b/support-files/compiler_warnings.supp 2010-04-01 09:08:42 +0000
@@ -160,4 +160,4 @@ ctype-simple\.c : .*unary minus operator
# Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478
regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type
libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000
-storage/xtradb/dict/dict0dict\.c: passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
+storage/xtradb/dict/dict0dict\.c : passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (monty:2763)
by Michael Widenius 01 Apr '10
by Michael Widenius 01 Apr '10
01 Apr '10
#At lp:maria/5.2 based on revid:monty@askmonty.org-20100401090426-sldnxikmb2x1og23
2763 Michael Widenius 2010-04-01 [merge]
Auto merge with 5.1
modified:
mysys/my_gethostbyname.c
storage/xtradb/handler/i_s.cc
storage/xtradb/log/log0recv.c
=== modified file 'mysys/my_gethostbyname.c'
--- a/mysys/my_gethostbyname.c 2010-03-30 12:36:49 +0000
+++ b/mysys/my_gethostbyname.c 2010-03-31 20:50:54 +0000
@@ -95,7 +95,7 @@ struct hostent *
my_gethostbyname_r(const char *name,
struct hostent *result __attribute__((unused)),
char *buffer __attribute__((unused)),
- int buflen__attribute__((unused)),
+ int buflen __attribute__((unused)),
int *h_errnop)
{
struct hostent *hp;
=== modified file 'storage/xtradb/handler/i_s.cc'
--- a/storage/xtradb/handler/i_s.cc 2010-01-28 11:35:10 +0000
+++ b/storage/xtradb/handler/i_s.cc 2010-03-31 20:50:54 +0000
@@ -2988,7 +2988,6 @@ i_s_innodb_admin_command_fill(
COND* cond)
{
TABLE* i_s_table = (TABLE *) tables->table;
- CHARSET_INFO *cs= system_charset_info;
char** query_str;
char* ptr;
char quote = '\0';
=== modified file 'storage/xtradb/log/log0recv.c'
--- a/storage/xtradb/log/log0recv.c 2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/log/log0recv.c 2010-03-31 20:50:54 +0000
@@ -3280,7 +3280,6 @@ recv_recovery_from_checkpoint_finish(voi
#endif /* UNIV_DEBUG */
if (recv_needed_recovery && srv_recovery_stats) {
- FILE* file = stderr;
ulint i;
fprintf(stderr,
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2839)
by Michael Widenius 01 Apr '10
by Michael Widenius 01 Apr '10
01 Apr '10
#At lp:maria based on revid:monty@askmonty.org-20100331205054-jj7383wd8gcw7mzi
2839 Michael Widenius 2010-04-01
Added missing space before :, which caused failuers in buildbot
modified:
support-files/compiler_warnings.supp
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-03-31 19:12:21 +0000
+++ b/support-files/compiler_warnings.supp 2010-04-01 09:08:42 +0000
@@ -160,4 +160,4 @@ ctype-simple\.c : .*unary minus operator
# Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478
regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type
libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000
-storage/xtradb/dict/dict0dict\.c: passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
+storage/xtradb/dict/dict0dict\.c : passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (monty:2762)
by Michael Widenius 01 Apr '10
by Michael Widenius 01 Apr '10
01 Apr '10
#At lp:maria/5.2 based on revid:monty@askmonty.org-20100331183745-0bpzimnis0s9hnai
2762 Michael Widenius 2010-04-01 [merge]
Merge with 5.1
Fixed valgrind warnings found from running main.connect under valgrind
added:
mysql-test/suite/pbxt/r/pbxt_xa.result
mysql-test/suite/pbxt/t/pbxt_xa.test
mysql-test/suite/pbxt/t/suite.opt
modified:
BUILD/compile-solaris-sparc
cmd-line-utils/libedit/filecomplete.c
extra/comp_err.c
extra/libevent/kqueue.c
include/sql_common.h
mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test
mysql-test/include/default_mysqld.cnf
mysql-test/lib/My/SafeProcess/safe_process.cc
mysql-test/lib/mtr_cases.pm
mysql-test/lib/v1/mysql-test-run.pl
mysql-test/suite/parts/t/rpl_partition.test
mysql-test/suite/rpl/r/rpl_do_grant.result
mysql-test/suite/rpl/r/rpl_optimize.result
mysql-test/suite/rpl/t/rpl_do_grant.test
mysql-test/suite/rpl/t/rpl_name_const.test
mysql-test/suite/rpl/t/rpl_optimize.test
mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
mysql-test/suite/rpl/t/rpl_row_trig003.test
mysql-test/t/bug47671-master.opt
mysql-test/t/ctype_latin1_de-master.opt
mysql-test/t/ctype_ucs2_def-master.opt
mysys/mf_keycache.c
mysys/my_gethostbyname.c
sql-common/client.c
sql/handler.cc
sql/item.cc
sql/item.h
sql/item_cmpfunc.cc
sql/item_create.cc
sql/item_create.h
sql/item_sum.cc
sql/item_sum.h
sql/log.cc
sql/mysqld.cc
sql/net_serv.cc
sql/set_var.cc
sql/sp_head.cc
sql/sql_acl.cc
sql/sql_class.h
sql/sql_table.cc
sql/sql_view.cc
sql/sql_yacc.yy
storage/example/ha_example.h
storage/maria/ma_loghandler.c
storage/maria/ma_search.c
storage/maria/maria_def.h
storage/myisam/ft_stopwords.c
storage/myisammrg/ha_myisammrg.cc
storage/myisammrg/myrg_open.c
storage/xtradb/include/page0page.h
storage/xtradb/include/page0page.ic
storage/xtradb/include/ut0lst.h
strings/ctype-ucs2.c
strings/ctype-utf8.c
strings/my_vsnprintf.c
support-files/compiler_warnings.supp
unittest/mysys/waiting_threads-t.c
per-file messages:
sql/sp_head.cc
Ensure that vcol_info is reset
sql/sql_acl.cc
Fixed usage of wrong memroot for password
sql/sql_yacc.yy
Ensure that vcol_info is reset
=== modified file 'BUILD/compile-solaris-sparc'
--- a/BUILD/compile-solaris-sparc 2008-09-30 20:57:48 +0000
+++ b/BUILD/compile-solaris-sparc 2010-03-31 19:12:21 +0000
@@ -9,6 +9,6 @@ PATH=$PATH:/usr/ccs/bin:/usr/local/bin
path=`dirname $0`
. "$path/autorun.sh"
-CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" LIBS="-lmtmalloc" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa $EXTRA_FLAGS $EXTRA_CFLAGS" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g $EXTRA_FLAGS $EXTRA_CXXFLAGS" LIBS="-lmtmalloc" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
make -j 4
=== modified file 'cmd-line-utils/libedit/filecomplete.c'
--- a/cmd-line-utils/libedit/filecomplete.c 2009-04-30 11:53:30 +0000
+++ b/cmd-line-utils/libedit/filecomplete.c 2010-03-31 19:12:21 +0000
@@ -95,10 +95,9 @@ static char break_chars[] = { ' ', '\t',
char *
fn_tilde_expand(const char *txt)
{
- struct passwd pwres, *pass;
+ struct passwd *pass;
char *temp;
size_t len = 0;
- char pwbuf[1024];
if (txt[0] != '~')
return (strdup(txt));
=== modified file 'extra/comp_err.c'
--- a/extra/comp_err.c 2009-11-20 10:11:31 +0000
+++ b/extra/comp_err.c 2010-03-30 12:36:49 +0000
@@ -660,7 +660,7 @@ static ha_checksum checksum_format_speci
case 'u':
case 'x':
case 's':
- chksum= my_checksum(chksum, start, (uint) (p + 1 - start));
+ chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start));
start= 0; /* Not in format specifier anymore */
break;
=== modified file 'extra/libevent/kqueue.c'
--- a/extra/libevent/kqueue.c 2009-03-12 22:27:35 +0000
+++ b/extra/libevent/kqueue.c 2010-03-30 12:36:49 +0000
@@ -144,7 +144,7 @@ kq_init(struct event_base *base)
*/
if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
- kqueueop->events[0].ident != -1 ||
+ ((int) kqueueop->events[0].ident) != -1 ||
kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue; not using.", __func__);
free(kqueueop->changes);
=== modified file 'include/sql_common.h'
--- a/include/sql_common.h 2010-03-29 15:13:53 +0000
+++ b/include/sql_common.h 2010-04-01 09:04:26 +0000
@@ -96,7 +96,7 @@ void set_mysql_extended_error(MYSQL *mys
struct st_plugin_vio_info;
void mpvio_info(Vio *vio, struct st_plugin_vio_info *info);
int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
- char *data_plugin, const char *db);
+ const char *data_plugin, const char *db);
int mysql_client_plugin_init();
void mysql_client_plugin_deinit();
struct st_mysql_client_plugin;
=== modified file 'mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test'
--- a/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-01-22 09:38:21 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-03-28 18:10:00 +0000
@@ -157,3 +157,4 @@ INSERT INTO t1 VALUES (1);
DROP TEMPORARY TABLE t1;
+--sync_slave_with_master
=== modified file 'mysql-test/include/default_mysqld.cnf'
--- a/mysql-test/include/default_mysqld.cnf 2008-04-08 14:51:26 +0000
+++ b/mysql-test/include/default_mysqld.cnf 2010-03-28 18:10:00 +0000
@@ -2,7 +2,7 @@
[mysqld]
open-files-limit= 1024
local-infile
-default-character-set= latin1
+character-set-server= latin1
# Increase default connect_timeout to avoid intermittent
# disconnects when test servers are put under load see BUG#28359
=== modified file 'mysql-test/lib/My/SafeProcess/safe_process.cc'
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc 2009-07-08 12:31:22 +0000
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc 2010-03-28 18:10:00 +0000
@@ -159,7 +159,7 @@ int main(int argc, char* const argv[] )
signal(SIGCHLD, handle_signal);
signal(SIGABRT, handle_abort);
- sprintf(safe_process_name, "safe_process[%d]", own_pid);
+ sprintf(safe_process_name, "safe_process[%d]", (int) own_pid);
message("Started");
=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm 2010-01-15 15:27:55 +0000
+++ b/mysql-test/lib/mtr_cases.pm 2010-03-30 12:36:49 +0000
@@ -681,6 +681,8 @@ sub optimize_cases {
if ( $default_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
if ( $default_engine =~ /^innodb/i );
+ $tinfo->{'pbxt_test'}= 1
+ if ( $default_engine =~ /^pbxt/i );
}
}
@@ -778,6 +780,8 @@ sub collect_one_test_case {
my $disabled= shift;
my $suite_opts= shift;
+ my $local_default_storage_engine= $default_storage_engine;
+
#print "collect_one_test_case\n";
#print " suitedir: $suitedir\n";
#print " testdir: $testdir\n";
@@ -932,15 +936,26 @@ sub collect_one_test_case {
tags_from_test_file($tinfo,"$testdir/${tname}.test");
- if ( defined $default_storage_engine )
+ # Get default storage engine from suite.opt file
+
+ if (defined $suite_opts &&
+ "@$suite_opts" =~ "default-storage-engine=\s*([^\s]*)")
+ {
+ $local_default_storage_engine= $1;
+ }
+
+ if ( defined $local_default_storage_engine )
{
# Different default engine is used
# tag test to require that engine
$tinfo->{'ndb_test'}= 1
- if ( $default_storage_engine =~ /^ndb/i );
+ if ( $local_default_storage_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
- if ( $default_storage_engine =~ /^innodb/i );
+ if ( $local_default_storage_engine =~ /^innodb/i );
+
+ $tinfo->{'pbxt_test'}= 1
+ if ( $local_default_storage_engine =~ /^pbxt/i );
}
@@ -1103,6 +1118,28 @@ sub collect_one_test_case {
$tinfo->{template_path}= $config;
}
+ if ( $tinfo->{'pbxt_test'} )
+ {
+ # This is a test that needs pbxt
+ if ( $::mysqld_variables{'pbxt'} eq "OFF" ||
+ ! exists $::mysqld_variables{'pbxt'} )
+ {
+ # Engine is not supported, skip it
+ $tinfo->{'skip'}= 1;
+ return $tinfo;
+ }
+ }
+ else
+ {
+ # Only disable engine if it's on by default (to avoid warnings about
+ # not existing loose options
+ if ( $::mysqld_variables{'pbxt'} eq "ON")
+ {
+ push(@{$tinfo->{'master_opt'}}, "--loose-skip-pbxt");
+ push(@{$tinfo->{'slave_opt'}}, "--loose-skip-pbxt");
+ }
+ }
+
if ( $tinfo->{'example_plugin_test'} )
{
if ( !$ENV{'EXAMPLE_PLUGIN'} )
@@ -1156,6 +1193,7 @@ my @tags=
["include/have_log_bin.inc", "need_binlog", 1],
["include/have_innodb.inc", "innodb_test", 1],
+ ["include/have_pbxt.inc", "pbxt_test", 1],
["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1],
["include/have_ndb.inc", "ndb_test", 1],
=== modified file 'mysql-test/lib/v1/mysql-test-run.pl'
--- a/mysql-test/lib/v1/mysql-test-run.pl 2010-03-04 08:03:07 +0000
+++ b/mysql-test/lib/v1/mysql-test-run.pl 2010-03-28 18:10:00 +0000
@@ -3965,7 +3965,7 @@ sub mysqld_arguments ($$$$) {
}
}
- mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
+ mtr_add_arg($args, "%s--character-set-server-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
=== modified file 'mysql-test/suite/parts/t/rpl_partition.test'
--- a/mysql-test/suite/parts/t/rpl_partition.test 2009-02-01 12:00:48 +0000
+++ b/mysql-test/suite/parts/t/rpl_partition.test 2010-03-29 19:07:45 +0000
@@ -1,6 +1,7 @@
--source include/have_partition.inc
--source include/have_innodb.inc
--source include/master-slave.inc
+--source include/big_test.inc
--vertical_results
=== added file 'mysql-test/suite/pbxt/r/pbxt_xa.result'
--- a/mysql-test/suite/pbxt/r/pbxt_xa.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/r/pbxt_xa.result 2010-03-24 22:12:39 +0000
@@ -0,0 +1,18 @@
+drop table if exists t1, t2;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+SELECT @@log_bin;
+@@log_bin
+0
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+a
+1
+select * from t2;
+b
+2
+drop table t1, t2;
+drop database pbxt;
=== added file 'mysql-test/suite/pbxt/t/pbxt_xa.test'
--- a/mysql-test/suite/pbxt/t/pbxt_xa.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/pbxt_xa.test 2010-03-24 22:12:39 +0000
@@ -0,0 +1,23 @@
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+#
+# bug lp:544173, xa crash with two 2pc-capable storage engines without binlog
+#
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+# verify that binlog is off
+SELECT @@log_bin;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+select * from t2;
+drop table t1, t2;
+drop database pbxt;
+
=== added file 'mysql-test/suite/pbxt/t/suite.opt'
--- a/mysql-test/suite/pbxt/t/suite.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/suite.opt 2010-03-30 12:36:49 +0000
@@ -0,0 +1 @@
+--default-storage-engine=pbxt
=== modified file 'mysql-test/suite/rpl/r/rpl_do_grant.result'
--- a/mysql-test/suite/rpl/r/rpl_do_grant.result 2010-03-16 12:38:35 +0000
+++ b/mysql-test/suite/rpl/r/rpl_do_grant.result 2010-04-01 09:04:26 +0000
@@ -165,10 +165,9 @@ USE test;
DROP FUNCTION bug42217_db.upgrade_del_func;
DROP FUNCTION bug42217_db.upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
-USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+stop slave;
+DROP USER 'create_rout_db'@'localhost';
######## BUG#49119 #######
### i) test case from the 'how to repeat section'
stop slave;
=== modified file 'mysql-test/suite/rpl/r/rpl_optimize.result'
--- a/mysql-test/suite/rpl/r/rpl_optimize.result 2010-01-13 09:00:03 +0000
+++ b/mysql-test/suite/rpl/r/rpl_optimize.result 2010-03-31 19:12:21 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+drop tables if exists t1;
CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
create table t1 (a int not null auto_increment primary key, b int, key(b));
INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
=== modified file 'mysql-test/suite/rpl/t/rpl_do_grant.test'
--- a/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-03-16 12:38:35 +0000
+++ b/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-04-01 09:04:26 +0000
@@ -209,12 +209,18 @@ USE test;
DROP FUNCTION bug42217_db.upgrade_del_func;
DROP FUNCTION bug42217_db.upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+
+sync_slave_with_master;
+
+# Drop the user that was already dropped on the slave
connection slave;
-USE mtr;
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+--disable_warnings
+stop slave;
+connection master;
+DROP USER 'create_rout_db'@'localhost';
+--enable_warnings
# BUG#49119: Master crashes when executing 'REVOKE ... ON
# {PROCEDURE|FUNCTION} FROM ...'
=== modified file 'mysql-test/suite/rpl/t/rpl_name_const.test'
--- a/mysql-test/suite/rpl/t/rpl_name_const.test 2009-04-08 23:42:51 +0000
+++ b/mysql-test/suite/rpl/t/rpl_name_const.test 2010-03-28 18:10:00 +0000
@@ -45,3 +45,4 @@ select * from t1 order by id;
connection master;
drop table t1;
drop procedure test_procedure;
+--sync_slave_with_master
=== modified file 'mysql-test/suite/rpl/t/rpl_optimize.test'
--- a/mysql-test/suite/rpl/t/rpl_optimize.test 2010-03-04 08:03:07 +0000
+++ b/mysql-test/suite/rpl/t/rpl_optimize.test 2010-03-31 19:12:21 +0000
@@ -15,6 +15,10 @@
-- source include/not_staging.inc
-- source include/master-slave.inc
+--disable_warnings
+drop tables if exists t1;
+--enable_warnings
+
CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
create table t1 (a int not null auto_increment primary key, b int, key(b));
@@ -51,10 +55,9 @@ sync_with_master; # won't work if slave
connection master; # cleanup
drop table t1;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
# If the machine is so fast that slave syncs before OPTIMIZE
-# starts, this test wil demonstrate nothing but will pass.
+# starts, this test will demonstrate nothing but will pass.
# End of 4.1 tests
=== modified file 'mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test'
--- a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2007-12-12 10:14:59 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2010-03-28 18:10:00 +0000
@@ -53,6 +53,7 @@ UPDATE t1 SET a=99 WHERE a = 0;
SHOW BINLOG EVENTS;
DROP TABLE t1;
+--sync_slave_with_master
# BUG#17620: Replicate (Row Based) Fails when Query Cache enabled on
# slave
=== modified file 'mysql-test/suite/rpl/t/rpl_row_trig003.test'
--- a/mysql-test/suite/rpl/t/rpl_row_trig003.test 2007-12-06 15:27:10 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_trig003.test 2010-03-29 19:07:45 +0000
@@ -149,6 +149,8 @@ DROP TABLE IF EXISTS test.t2;
DROP TABLE IF EXISTS test.t3;
--enable_warnings
+sync_slave_with_master;
+
diff_files $MYSQLTEST_VARDIR/tmp/trg003_master.sql $MYSQLTEST_VARDIR/tmp/trg003_slave.sql;
# End of 5.0 test case
=== modified file 'mysql-test/t/bug47671-master.opt'
--- a/mysql-test/t/bug47671-master.opt 2009-11-25 06:55:49 +0000
+++ b/mysql-test/t/bug47671-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-character-set=utf8 --skip-character-set-client-handshake
+--character-set-server=utf8 --skip-character-set-client-handshake
=== modified file 'mysql-test/t/ctype_latin1_de-master.opt'
--- a/mysql-test/t/ctype_latin1_de-master.opt 2003-05-21 23:57:27 +0000
+++ b/mysql-test/t/ctype_latin1_de-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-character-set=latin1 --default-collation=latin1_german2_ci
+--character-set-server=latin1 --default-collation=latin1_german2_ci
=== modified file 'mysql-test/t/ctype_ucs2_def-master.opt'
--- a/mysql-test/t/ctype_ucs2_def-master.opt 2007-02-19 11:04:38 +0000
+++ b/mysql-test/t/ctype_ucs2_def-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-collation=ucs2_unicode_ci --default-character-set=ucs2,latin1
+--default-collation=ucs2_unicode_ci --character-set-server=ucs2,latin1
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2009-12-03 11:19:05 +0000
+++ b/mysys/mf_keycache.c 2010-03-30 12:36:49 +0000
@@ -3924,6 +3924,12 @@ restart:
uint next_status;
uint hash_requests;
+ LINT_INIT(next_hash_link);
+ LINT_INIT(next_diskpos);
+ LINT_INIT(next_file);
+ LINT_INIT(next_status);
+ LINT_INIT(hash_requests);
+
total_found++;
found++;
KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used);
=== modified file 'mysys/my_gethostbyname.c'
--- a/mysys/my_gethostbyname.c 2006-12-31 00:32:21 +0000
+++ b/mysys/my_gethostbyname.c 2010-03-30 12:36:49 +0000
@@ -91,9 +91,12 @@ extern pthread_mutex_t LOCK_gethostbynam
is finished with the structure.
*/
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
+struct hostent *
+my_gethostbyname_r(const char *name,
+ struct hostent *result __attribute__((unused)),
+ char *buffer __attribute__((unused)),
+ int buflen__attribute__((unused)),
+ int *h_errnop)
{
struct hostent *hp;
pthread_mutex_lock(&LOCK_gethostbyname_r);
=== modified file 'sql-common/client.c'
--- a/sql-common/client.c 2010-03-29 15:13:53 +0000
+++ b/sql-common/client.c 2010-04-01 09:04:26 +0000
@@ -2394,7 +2394,7 @@ static void client_mpvio_info(MYSQL_PLUG
*/
int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
- char *data_plugin, const char *db)
+ const char *data_plugin, const char *db)
{
const char *auth_plugin_name;
auth_plugin_t *auth_plugin;
@@ -2540,7 +2540,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
char buff[NAME_LEN+USERNAME_LENGTH+100];
int scramble_data_len, pkt_scramble_len;
char *end, *host_info=0, *server_version_end, *pkt_end;
- char *scramble_data, *scramble_plugin;
+ char *scramble_data;
+ const char *scramble_plugin;
my_socket sock;
in_addr_t ip_addr;
struct sockaddr_in sock_addr;
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-03-25 13:33:39 +0000
+++ b/sql/handler.cc 2010-04-01 09:04:26 +0000
@@ -4252,7 +4252,7 @@ int handler::read_multi_range_first(KEY_
*/
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
- int result;
+ int result= 0;
DBUG_ENTER("handler::read_multi_range_next");
/* We should not be called after the last call returned EOF. */
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2010-03-15 11:51:23 +0000
+++ b/sql/item.cc 2010-04-01 09:04:26 +0000
@@ -7040,7 +7040,7 @@ bool Item_cache_int::cache_value()
}
-void Item_cache_int::store(Item *item, longlong val_arg)
+void Item_cache_int::store_longlong(Item *item, longlong val_arg)
{
/* An explicit values is given, save it. */
value_cached= TRUE;
=== modified file 'sql/item.h'
--- a/sql/item.h 2010-03-15 11:51:23 +0000
+++ b/sql/item.h 2010-04-01 09:04:26 +0000
@@ -1132,7 +1132,8 @@ class Field_enumerator
{
public:
virtual void visit_field(Field *field)= 0;
- virtual ~Field_enumerator() {}; /* purecov: inspected */
+ virtual ~Field_enumerator() {}; /* purecov: inspected */
+ Field_enumerator() {} /* Remove gcc warning */
};
@@ -3148,7 +3149,7 @@ public:
Item_cache_int(enum_field_types field_type_arg):
Item_cache(field_type_arg), value(0) {}
- void store(Item *item, longlong val_arg);
+ void store_longlong(Item *item, longlong val_arg);
double val_real();
longlong val_int();
String* val_str(String *str);
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2010-03-04 08:03:07 +0000
+++ b/sql/item_cmpfunc.cc 2010-03-28 18:10:00 +0000
@@ -879,7 +879,7 @@ get_time_value(THD *thd, Item ***item_ar
Item_cache_int *cache= new Item_cache_int();
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
@@ -917,13 +917,13 @@ int Arg_comparator::set_cmp_func(Item_re
cache->set_used_tables(1);
if (!(*a)->is_datetime())
{
- cache->store((*a), const_value);
+ cache->store_longlong((*a), const_value);
a_cache= cache;
a= (Item **)&a_cache;
}
else
{
- cache->store((*b), const_value);
+ cache->store_longlong((*b), const_value);
b_cache= cache;
b= (Item **)&b_cache;
}
@@ -1145,7 +1145,7 @@ get_datetime_value(THD *thd, Item ***ite
Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
=== modified file 'sql/item_create.cc'
--- a/sql/item_create.cc 2010-03-04 08:03:07 +0000
+++ b/sql/item_create.cc 2010-03-29 19:07:45 +0000
@@ -76,7 +76,7 @@ public:
@param thd The current thread
@return An item representing the function call
*/
- virtual Item *create(THD *thd) = 0;
+ virtual Item *create_builder(THD *thd) = 0;
protected:
/** Constructor. */
@@ -101,7 +101,7 @@ public:
@param arg1 The first argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1) = 0;
+ virtual Item *create_1_arg(THD *thd, Item *arg1) = 0;
protected:
/** Constructor. */
@@ -127,7 +127,7 @@ public:
@param arg2 The second argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2) = 0;
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) = 0;
protected:
/** Constructor. */
@@ -154,7 +154,7 @@ public:
@param arg3 The third argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
protected:
/** Constructor. */
@@ -171,8 +171,8 @@ protected:
class Create_sp_func : public Create_qfunc
{
public:
- virtual Item *create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list);
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list);
static Create_sp_func s_singleton;
@@ -217,7 +217,7 @@ protected:
class Create_func_abs : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_abs s_singleton;
@@ -230,7 +230,7 @@ protected:
class Create_func_acos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_acos s_singleton;
@@ -243,7 +243,7 @@ protected:
class Create_func_addtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_addtime s_singleton;
@@ -256,7 +256,7 @@ protected:
class Create_func_aes_encrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_encrypt s_singleton;
@@ -269,7 +269,7 @@ protected:
class Create_func_aes_decrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_decrypt s_singleton;
@@ -283,7 +283,7 @@ protected:
class Create_func_area : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_area s_singleton;
@@ -298,7 +298,7 @@ protected:
class Create_func_as_wkb : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkb s_singleton;
@@ -313,7 +313,7 @@ protected:
class Create_func_as_wkt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkt s_singleton;
@@ -327,7 +327,7 @@ protected:
class Create_func_asin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_asin s_singleton;
@@ -353,7 +353,7 @@ protected:
class Create_func_benchmark : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_benchmark s_singleton;
@@ -366,7 +366,7 @@ protected:
class Create_func_bin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bin s_singleton;
@@ -379,7 +379,7 @@ protected:
class Create_func_bit_count : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_count s_singleton;
@@ -392,7 +392,7 @@ protected:
class Create_func_bit_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_length s_singleton;
@@ -405,7 +405,7 @@ protected:
class Create_func_ceiling : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ceiling s_singleton;
@@ -419,7 +419,7 @@ protected:
class Create_func_centroid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_centroid s_singleton;
@@ -433,7 +433,7 @@ protected:
class Create_func_char_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_char_length s_singleton;
@@ -446,7 +446,7 @@ protected:
class Create_func_coercibility : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_coercibility s_singleton;
@@ -459,7 +459,7 @@ protected:
class Create_func_compress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_compress s_singleton;
@@ -498,7 +498,7 @@ protected:
class Create_func_connection_id : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_connection_id s_singleton;
@@ -512,7 +512,7 @@ protected:
class Create_func_contains : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_contains s_singleton;
@@ -526,7 +526,7 @@ protected:
class Create_func_conv : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_conv s_singleton;
@@ -539,7 +539,7 @@ protected:
class Create_func_convert_tz : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_convert_tz s_singleton;
@@ -552,7 +552,7 @@ protected:
class Create_func_cos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cos s_singleton;
@@ -565,7 +565,7 @@ protected:
class Create_func_cot : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cot s_singleton;
@@ -578,7 +578,7 @@ protected:
class Create_func_crc32 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_crc32 s_singleton;
@@ -592,7 +592,7 @@ protected:
class Create_func_crosses : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_crosses s_singleton;
@@ -606,7 +606,7 @@ protected:
class Create_func_date_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_date_format s_singleton;
@@ -619,7 +619,7 @@ protected:
class Create_func_datediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_datediff s_singleton;
@@ -632,7 +632,7 @@ protected:
class Create_func_dayname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayname s_singleton;
@@ -645,7 +645,7 @@ protected:
class Create_func_dayofmonth : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofmonth s_singleton;
@@ -658,7 +658,7 @@ protected:
class Create_func_dayofweek : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofweek s_singleton;
@@ -671,7 +671,7 @@ protected:
class Create_func_dayofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofyear s_singleton;
@@ -684,7 +684,7 @@ protected:
class Create_func_decode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_decode s_singleton;
@@ -697,7 +697,7 @@ protected:
class Create_func_degrees : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_degrees s_singleton;
@@ -737,7 +737,7 @@ protected:
class Create_func_dimension : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dimension s_singleton;
@@ -752,7 +752,7 @@ protected:
class Create_func_disjoint : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_disjoint s_singleton;
@@ -779,7 +779,7 @@ protected:
class Create_func_encode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_encode s_singleton;
@@ -806,7 +806,7 @@ protected:
class Create_func_endpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_endpoint s_singleton;
@@ -821,7 +821,7 @@ protected:
class Create_func_envelope : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_envelope s_singleton;
@@ -836,7 +836,7 @@ protected:
class Create_func_equals : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_equals s_singleton;
@@ -850,7 +850,7 @@ protected:
class Create_func_exp : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exp s_singleton;
@@ -877,7 +877,7 @@ protected:
class Create_func_exteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exteriorring s_singleton;
@@ -904,7 +904,7 @@ protected:
class Create_func_find_in_set : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_find_in_set s_singleton;
@@ -917,7 +917,7 @@ protected:
class Create_func_floor : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_floor s_singleton;
@@ -930,7 +930,7 @@ protected:
class Create_func_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_format s_singleton;
@@ -943,7 +943,7 @@ protected:
class Create_func_found_rows : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_found_rows s_singleton;
@@ -956,7 +956,7 @@ protected:
class Create_func_from_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_from_days s_singleton;
@@ -1013,7 +1013,7 @@ protected:
class Create_func_geometry_type : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_geometry_type s_singleton;
@@ -1028,7 +1028,7 @@ protected:
class Create_func_geometryn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_geometryn s_singleton;
@@ -1042,7 +1042,7 @@ protected:
class Create_func_get_lock : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_get_lock s_singleton;
@@ -1056,7 +1056,7 @@ protected:
class Create_func_glength : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_glength s_singleton;
@@ -1083,7 +1083,7 @@ protected:
class Create_func_hex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_hex s_singleton;
@@ -1096,7 +1096,7 @@ protected:
class Create_func_ifnull : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_ifnull s_singleton;
@@ -1109,7 +1109,7 @@ protected:
class Create_func_inet_ntoa : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_ntoa s_singleton;
@@ -1122,7 +1122,7 @@ protected:
class Create_func_inet_aton : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_aton s_singleton;
@@ -1135,7 +1135,7 @@ protected:
class Create_func_instr : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_instr s_singleton;
@@ -1149,7 +1149,7 @@ protected:
class Create_func_interiorringn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_interiorringn s_singleton;
@@ -1164,7 +1164,7 @@ protected:
class Create_func_intersects : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_intersects s_singleton;
@@ -1178,7 +1178,7 @@ protected:
class Create_func_is_free_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_free_lock s_singleton;
@@ -1191,7 +1191,7 @@ protected:
class Create_func_is_used_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_used_lock s_singleton;
@@ -1205,7 +1205,7 @@ protected:
class Create_func_isclosed : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isclosed s_singleton;
@@ -1220,7 +1220,7 @@ protected:
class Create_func_isempty : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isempty s_singleton;
@@ -1234,7 +1234,7 @@ protected:
class Create_func_isnull : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isnull s_singleton;
@@ -1248,7 +1248,7 @@ protected:
class Create_func_issimple : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_issimple s_singleton;
@@ -1262,7 +1262,7 @@ protected:
class Create_func_last_day : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_last_day s_singleton;
@@ -1288,7 +1288,7 @@ protected:
class Create_func_lcase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_lcase s_singleton;
@@ -1314,7 +1314,7 @@ protected:
class Create_func_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_length s_singleton;
@@ -1327,7 +1327,7 @@ protected:
class Create_func_ln : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ln s_singleton;
@@ -1340,7 +1340,7 @@ protected:
class Create_func_load_file : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_load_file s_singleton;
@@ -1379,7 +1379,7 @@ protected:
class Create_func_log10 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log10 s_singleton;
@@ -1392,7 +1392,7 @@ protected:
class Create_func_log2 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log2 s_singleton;
@@ -1405,7 +1405,7 @@ protected:
class Create_func_lpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_lpad s_singleton;
@@ -1418,7 +1418,7 @@ protected:
class Create_func_ltrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ltrim s_singleton;
@@ -1431,7 +1431,7 @@ protected:
class Create_func_makedate : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_makedate s_singleton;
@@ -1444,7 +1444,7 @@ protected:
class Create_func_maketime : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_maketime s_singleton;
@@ -1483,7 +1483,7 @@ protected:
class Create_func_md5 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_md5 s_singleton;
@@ -1496,7 +1496,7 @@ protected:
class Create_func_monthname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_monthname s_singleton;
@@ -1509,7 +1509,7 @@ protected:
class Create_func_name_const : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_name_const s_singleton;
@@ -1522,7 +1522,7 @@ protected:
class Create_func_nullif : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_nullif s_singleton;
@@ -1536,7 +1536,7 @@ protected:
class Create_func_numgeometries : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numgeometries s_singleton;
@@ -1551,7 +1551,7 @@ protected:
class Create_func_numinteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numinteriorring s_singleton;
@@ -1566,7 +1566,7 @@ protected:
class Create_func_numpoints : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numpoints s_singleton;
@@ -1580,7 +1580,7 @@ protected:
class Create_func_oct : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_oct s_singleton;
@@ -1593,7 +1593,7 @@ protected:
class Create_func_ord : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ord s_singleton;
@@ -1607,7 +1607,7 @@ protected:
class Create_func_overlaps : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_overlaps s_singleton;
@@ -1621,7 +1621,7 @@ protected:
class Create_func_period_add : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_add s_singleton;
@@ -1634,7 +1634,7 @@ protected:
class Create_func_period_diff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_diff s_singleton;
@@ -1647,7 +1647,7 @@ protected:
class Create_func_pi : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_pi s_singleton;
@@ -1661,7 +1661,7 @@ protected:
class Create_func_pointn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pointn s_singleton;
@@ -1675,7 +1675,7 @@ protected:
class Create_func_pow : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pow s_singleton;
@@ -1688,7 +1688,7 @@ protected:
class Create_func_quote : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_quote s_singleton;
@@ -1701,7 +1701,7 @@ protected:
class Create_func_radians : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_radians s_singleton;
@@ -1727,7 +1727,7 @@ protected:
class Create_func_release_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_release_lock s_singleton;
@@ -1740,7 +1740,7 @@ protected:
class Create_func_reverse : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_reverse s_singleton;
@@ -1766,7 +1766,7 @@ protected:
class Create_func_row_count : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_row_count s_singleton;
@@ -1779,7 +1779,7 @@ protected:
class Create_func_rpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_rpad s_singleton;
@@ -1792,7 +1792,7 @@ protected:
class Create_func_rtrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_rtrim s_singleton;
@@ -1805,7 +1805,7 @@ protected:
class Create_func_sec_to_time : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sec_to_time s_singleton;
@@ -1818,7 +1818,7 @@ protected:
class Create_func_sha : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sha s_singleton;
@@ -1831,7 +1831,7 @@ protected:
class Create_func_sign : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sign s_singleton;
@@ -1844,7 +1844,7 @@ protected:
class Create_func_sin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sin s_singleton;
@@ -1857,7 +1857,7 @@ protected:
class Create_func_sleep : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sleep s_singleton;
@@ -1870,7 +1870,7 @@ protected:
class Create_func_soundex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_soundex s_singleton;
@@ -1883,7 +1883,7 @@ protected:
class Create_func_space : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_space s_singleton;
@@ -1896,7 +1896,7 @@ protected:
class Create_func_sqrt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sqrt s_singleton;
@@ -1910,7 +1910,7 @@ protected:
class Create_func_srid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_srid s_singleton;
@@ -1925,7 +1925,7 @@ protected:
class Create_func_startpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_startpoint s_singleton;
@@ -1939,7 +1939,7 @@ protected:
class Create_func_str_to_date : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_str_to_date s_singleton;
@@ -1952,7 +1952,7 @@ protected:
class Create_func_strcmp : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_strcmp s_singleton;
@@ -1965,7 +1965,7 @@ protected:
class Create_func_substr_index : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_substr_index s_singleton;
@@ -1978,7 +1978,7 @@ protected:
class Create_func_subtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_subtime s_singleton;
@@ -1991,7 +1991,7 @@ protected:
class Create_func_tan : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_tan s_singleton;
@@ -2004,7 +2004,7 @@ protected:
class Create_func_time_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_time_format s_singleton;
@@ -2017,7 +2017,7 @@ protected:
class Create_func_time_to_sec : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_time_to_sec s_singleton;
@@ -2030,7 +2030,7 @@ protected:
class Create_func_timediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_timediff s_singleton;
@@ -2043,7 +2043,7 @@ protected:
class Create_func_to_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_to_days s_singleton;
@@ -2057,7 +2057,7 @@ protected:
class Create_func_touches : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_touches s_singleton;
@@ -2071,7 +2071,7 @@ protected:
class Create_func_ucase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ucase s_singleton;
@@ -2084,7 +2084,7 @@ protected:
class Create_func_uncompress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompress s_singleton;
@@ -2097,7 +2097,7 @@ protected:
class Create_func_uncompressed_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompressed_length s_singleton;
@@ -2110,7 +2110,7 @@ protected:
class Create_func_unhex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_unhex s_singleton;
@@ -2136,7 +2136,7 @@ protected:
class Create_func_uuid : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid s_singleton;
@@ -2149,7 +2149,7 @@ protected:
class Create_func_uuid_short : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid_short s_singleton;
@@ -2162,7 +2162,7 @@ protected:
class Create_func_version : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_version s_singleton;
@@ -2175,7 +2175,7 @@ protected:
class Create_func_weekday : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekday s_singleton;
@@ -2188,7 +2188,7 @@ protected:
class Create_func_weekofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekofyear s_singleton;
@@ -2202,7 +2202,7 @@ protected:
class Create_func_within : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_within s_singleton;
@@ -2217,7 +2217,7 @@ protected:
class Create_func_x : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_x s_singleton;
@@ -2231,7 +2231,7 @@ protected:
class Create_func_xml_extractvalue : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_xml_extractvalue s_singleton;
@@ -2244,7 +2244,7 @@ protected:
class Create_func_xml_update : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_xml_update s_singleton;
@@ -2258,7 +2258,7 @@ protected:
class Create_func_y : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_y s_singleton;
@@ -2353,7 +2353,7 @@ Create_qfunc::create(THD *thd, LEX_STRIN
if (thd->lex->copy_db_to(&db.str, &db.length))
return NULL;
- return create(thd, db, name, false, item_list);
+ return create_with_db(thd, db, name, false, item_list);
}
@@ -2470,8 +2470,8 @@ Create_udf_func::create(THD *thd, udf_fu
Create_sp_func Create_sp_func::s_singleton;
Item*
-Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list)
+Create_sp_func::create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list)
{
int arg_count= 0;
Item *func= NULL;
@@ -2538,7 +2538,7 @@ Create_func_arg0::create(THD *thd, LEX_S
return NULL;
}
- return create(thd);
+ return create_builder(thd);
}
@@ -2564,7 +2564,7 @@ Create_func_arg1::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1);
+ return create_1_arg(thd, param_1);
}
@@ -2592,7 +2592,7 @@ Create_func_arg2::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2);
+ return create_2_arg(thd, param_1, param_2);
}
@@ -2622,14 +2622,14 @@ Create_func_arg3::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2, param_3);
+ return create_3_arg(thd, param_1, param_2, param_3);
}
Create_func_abs Create_func_abs::s_singleton;
Item*
-Create_func_abs::create(THD *thd, Item *arg1)
+Create_func_abs::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_abs(arg1);
}
@@ -2638,7 +2638,7 @@ Create_func_abs::create(THD *thd, Item *
Create_func_acos Create_func_acos::s_singleton;
Item*
-Create_func_acos::create(THD *thd, Item *arg1)
+Create_func_acos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_acos(arg1);
}
@@ -2647,7 +2647,7 @@ Create_func_acos::create(THD *thd, Item
Create_func_addtime Create_func_addtime::s_singleton;
Item*
-Create_func_addtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_addtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 0);
}
@@ -2656,7 +2656,7 @@ Create_func_addtime::create(THD *thd, It
Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton;
Item*
-Create_func_aes_encrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_encrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_encrypt(arg1, arg2);
}
@@ -2665,7 +2665,7 @@ Create_func_aes_encrypt::create(THD *thd
Create_func_aes_decrypt Create_func_aes_decrypt::s_singleton;
Item*
-Create_func_aes_decrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_decrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_decrypt(arg1, arg2);
}
@@ -2675,7 +2675,7 @@ Create_func_aes_decrypt::create(THD *thd
Create_func_area Create_func_area::s_singleton;
Item*
-Create_func_area::create(THD *thd, Item *arg1)
+Create_func_area::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_area(arg1);
}
@@ -2686,7 +2686,7 @@ Create_func_area::create(THD *thd, Item
Create_func_as_wkb Create_func_as_wkb::s_singleton;
Item*
-Create_func_as_wkb::create(THD *thd, Item *arg1)
+Create_func_as_wkb::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkb(arg1);
}
@@ -2697,7 +2697,7 @@ Create_func_as_wkb::create(THD *thd, Ite
Create_func_as_wkt Create_func_as_wkt::s_singleton;
Item*
-Create_func_as_wkt::create(THD *thd, Item *arg1)
+Create_func_as_wkt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkt(arg1);
}
@@ -2707,7 +2707,7 @@ Create_func_as_wkt::create(THD *thd, Ite
Create_func_asin Create_func_asin::s_singleton;
Item*
-Create_func_asin::create(THD *thd, Item *arg1)
+Create_func_asin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_asin(arg1);
}
@@ -2753,7 +2753,7 @@ Create_func_atan::create_native(THD *thd
Create_func_benchmark Create_func_benchmark::s_singleton;
Item*
-Create_func_benchmark::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_benchmark::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_benchmark(arg1, arg2);
@@ -2763,7 +2763,7 @@ Create_func_benchmark::create(THD *thd,
Create_func_bin Create_func_bin::s_singleton;
Item*
-Create_func_bin::create(THD *thd, Item *arg1)
+Create_func_bin::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i2= new (thd->mem_root) Item_int((int32) 2,1);
@@ -2774,7 +2774,7 @@ Create_func_bin::create(THD *thd, Item *
Create_func_bit_count Create_func_bit_count::s_singleton;
Item*
-Create_func_bit_count::create(THD *thd, Item *arg1)
+Create_func_bit_count::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_count(arg1);
}
@@ -2783,7 +2783,7 @@ Create_func_bit_count::create(THD *thd,
Create_func_bit_length Create_func_bit_length::s_singleton;
Item*
-Create_func_bit_length::create(THD *thd, Item *arg1)
+Create_func_bit_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_length(arg1);
}
@@ -2792,7 +2792,7 @@ Create_func_bit_length::create(THD *thd,
Create_func_ceiling Create_func_ceiling::s_singleton;
Item*
-Create_func_ceiling::create(THD *thd, Item *arg1)
+Create_func_ceiling::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ceiling(arg1);
}
@@ -2802,7 +2802,7 @@ Create_func_ceiling::create(THD *thd, It
Create_func_centroid Create_func_centroid::s_singleton;
Item*
-Create_func_centroid::create(THD *thd, Item *arg1)
+Create_func_centroid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_centroid(arg1);
}
@@ -2812,7 +2812,7 @@ Create_func_centroid::create(THD *thd, I
Create_func_char_length Create_func_char_length::s_singleton;
Item*
-Create_func_char_length::create(THD *thd, Item *arg1)
+Create_func_char_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_char_length(arg1);
}
@@ -2821,7 +2821,7 @@ Create_func_char_length::create(THD *thd
Create_func_coercibility Create_func_coercibility::s_singleton;
Item*
-Create_func_coercibility::create(THD *thd, Item *arg1)
+Create_func_coercibility::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_coercibility(arg1);
}
@@ -2873,7 +2873,7 @@ Create_func_concat_ws::create_native(THD
Create_func_compress Create_func_compress::s_singleton;
Item*
-Create_func_compress::create(THD *thd, Item *arg1)
+Create_func_compress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_compress(arg1);
}
@@ -2882,7 +2882,7 @@ Create_func_compress::create(THD *thd, I
Create_func_connection_id Create_func_connection_id::s_singleton;
Item*
-Create_func_connection_id::create(THD *thd)
+Create_func_connection_id::create_builder(THD *thd)
{
thd->lex->safe_to_cache_query= 0;
return new (thd->mem_root) Item_func_connection_id();
@@ -2893,7 +2893,7 @@ Create_func_connection_id::create(THD *t
Create_func_contains Create_func_contains::s_singleton;
Item*
-Create_func_contains::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_contains::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CONTAINS_FUNC);
@@ -2904,7 +2904,7 @@ Create_func_contains::create(THD *thd, I
Create_func_conv Create_func_conv::s_singleton;
Item*
-Create_func_conv::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_conv::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_conv(arg1, arg2, arg3);
}
@@ -2913,7 +2913,7 @@ Create_func_conv::create(THD *thd, Item
Create_func_convert_tz Create_func_convert_tz::s_singleton;
Item*
-Create_func_convert_tz::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_convert_tz::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_convert_tz(arg1, arg2, arg3);
}
@@ -2922,7 +2922,7 @@ Create_func_convert_tz::create(THD *thd,
Create_func_cos Create_func_cos::s_singleton;
Item*
-Create_func_cos::create(THD *thd, Item *arg1)
+Create_func_cos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_cos(arg1);
}
@@ -2931,7 +2931,7 @@ Create_func_cos::create(THD *thd, Item *
Create_func_cot Create_func_cot::s_singleton;
Item*
-Create_func_cot::create(THD *thd, Item *arg1)
+Create_func_cot::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "1", 1, 1);
Item *i2= new (thd->mem_root) Item_func_tan(arg1);
@@ -2942,7 +2942,7 @@ Create_func_cot::create(THD *thd, Item *
Create_func_crc32 Create_func_crc32::s_singleton;
Item*
-Create_func_crc32::create(THD *thd, Item *arg1)
+Create_func_crc32::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_crc32(arg1);
}
@@ -2952,7 +2952,7 @@ Create_func_crc32::create(THD *thd, Item
Create_func_crosses Create_func_crosses::s_singleton;
Item*
-Create_func_crosses::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_crosses::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CROSSES_FUNC);
@@ -2963,7 +2963,7 @@ Create_func_crosses::create(THD *thd, It
Create_func_date_format Create_func_date_format::s_singleton;
Item*
-Create_func_date_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_date_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 0);
}
@@ -2972,7 +2972,7 @@ Create_func_date_format::create(THD *thd
Create_func_datediff Create_func_datediff::s_singleton;
Item*
-Create_func_datediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_datediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
Item *i1= new (thd->mem_root) Item_func_to_days(arg1);
Item *i2= new (thd->mem_root) Item_func_to_days(arg2);
@@ -2984,7 +2984,7 @@ Create_func_datediff::create(THD *thd, I
Create_func_dayname Create_func_dayname::s_singleton;
Item*
-Create_func_dayname::create(THD *thd, Item *arg1)
+Create_func_dayname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayname(arg1);
}
@@ -2993,7 +2993,7 @@ Create_func_dayname::create(THD *thd, It
Create_func_dayofmonth Create_func_dayofmonth::s_singleton;
Item*
-Create_func_dayofmonth::create(THD *thd, Item *arg1)
+Create_func_dayofmonth::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofmonth(arg1);
}
@@ -3002,7 +3002,7 @@ Create_func_dayofmonth::create(THD *thd,
Create_func_dayofweek Create_func_dayofweek::s_singleton;
Item*
-Create_func_dayofweek::create(THD *thd, Item *arg1)
+Create_func_dayofweek::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 1);
}
@@ -3011,7 +3011,7 @@ Create_func_dayofweek::create(THD *thd,
Create_func_dayofyear Create_func_dayofyear::s_singleton;
Item*
-Create_func_dayofyear::create(THD *thd, Item *arg1)
+Create_func_dayofyear::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofyear(arg1);
}
@@ -3020,7 +3020,7 @@ Create_func_dayofyear::create(THD *thd,
Create_func_decode Create_func_decode::s_singleton;
Item*
-Create_func_decode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_decode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_decode(arg1, arg2);
}
@@ -3029,7 +3029,7 @@ Create_func_decode::create(THD *thd, Ite
Create_func_degrees Create_func_degrees::s_singleton;
Item*
-Create_func_degrees::create(THD *thd, Item *arg1)
+Create_func_degrees::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "degrees", arg1,
180/M_PI, 0.0);
@@ -3114,7 +3114,7 @@ Create_func_des_encrypt::create_native(T
Create_func_dimension Create_func_dimension::s_singleton;
Item*
-Create_func_dimension::create(THD *thd, Item *arg1)
+Create_func_dimension::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dimension(arg1);
}
@@ -3125,7 +3125,7 @@ Create_func_dimension::create(THD *thd,
Create_func_disjoint Create_func_disjoint::s_singleton;
Item*
-Create_func_disjoint::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_disjoint::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_DISJOINT_FUNC);
@@ -3157,7 +3157,7 @@ Create_func_elt::create_native(THD *thd,
Create_func_encode Create_func_encode::s_singleton;
Item*
-Create_func_encode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_encode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_encode(arg1, arg2);
}
@@ -3205,7 +3205,7 @@ Create_func_encrypt::create_native(THD *
Create_func_endpoint Create_func_endpoint::s_singleton;
Item*
-Create_func_endpoint::create(THD *thd, Item *arg1)
+Create_func_endpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_ENDPOINT);
@@ -3217,7 +3217,7 @@ Create_func_endpoint::create(THD *thd, I
Create_func_envelope Create_func_envelope::s_singleton;
Item*
-Create_func_envelope::create(THD *thd, Item *arg1)
+Create_func_envelope::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_envelope(arg1);
}
@@ -3228,7 +3228,7 @@ Create_func_envelope::create(THD *thd, I
Create_func_equals Create_func_equals::s_singleton;
Item*
-Create_func_equals::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_equals::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_EQUALS_FUNC);
@@ -3239,7 +3239,7 @@ Create_func_equals::create(THD *thd, Ite
Create_func_exp Create_func_exp::s_singleton;
Item*
-Create_func_exp::create(THD *thd, Item *arg1)
+Create_func_exp::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_exp(arg1);
}
@@ -3302,7 +3302,7 @@ Create_func_export_set::create_native(TH
Create_func_exteriorring Create_func_exteriorring::s_singleton;
Item*
-Create_func_exteriorring::create(THD *thd, Item *arg1)
+Create_func_exteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_EXTERIORRING);
@@ -3334,7 +3334,7 @@ Create_func_field::create_native(THD *th
Create_func_find_in_set Create_func_find_in_set::s_singleton;
Item*
-Create_func_find_in_set::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_find_in_set::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_find_in_set(arg1, arg2);
}
@@ -3343,7 +3343,7 @@ Create_func_find_in_set::create(THD *thd
Create_func_floor Create_func_floor::s_singleton;
Item*
-Create_func_floor::create(THD *thd, Item *arg1)
+Create_func_floor::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_floor(arg1);
}
@@ -3352,7 +3352,7 @@ Create_func_floor::create(THD *thd, Item
Create_func_format Create_func_format::s_singleton;
Item*
-Create_func_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_format(arg1, arg2);
}
@@ -3361,7 +3361,7 @@ Create_func_format::create(THD *thd, Ite
Create_func_found_rows Create_func_found_rows::s_singleton;
Item*
-Create_func_found_rows::create(THD *thd)
+Create_func_found_rows::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -3372,7 +3372,7 @@ Create_func_found_rows::create(THD *thd)
Create_func_from_days Create_func_from_days::s_singleton;
Item*
-Create_func_from_days::create(THD *thd, Item *arg1)
+Create_func_from_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_from_days(arg1);
}
@@ -3500,7 +3500,7 @@ Create_func_geometry_from_wkb::create_na
Create_func_geometry_type Create_func_geometry_type::s_singleton;
Item*
-Create_func_geometry_type::create(THD *thd, Item *arg1)
+Create_func_geometry_type::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_geometry_type(arg1);
}
@@ -3511,7 +3511,7 @@ Create_func_geometry_type::create(THD *t
Create_func_geometryn Create_func_geometryn::s_singleton;
Item*
-Create_func_geometryn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_geometryn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_GEOMETRYN);
@@ -3522,7 +3522,7 @@ Create_func_geometryn::create(THD *thd,
Create_func_get_lock Create_func_get_lock::s_singleton;
Item*
-Create_func_get_lock::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_get_lock::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3534,7 +3534,7 @@ Create_func_get_lock::create(THD *thd, I
Create_func_glength Create_func_glength::s_singleton;
Item*
-Create_func_glength::create(THD *thd, Item *arg1)
+Create_func_glength::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_glength(arg1);
}
@@ -3565,7 +3565,7 @@ Create_func_greatest::create_native(THD
Create_func_hex Create_func_hex::s_singleton;
Item*
-Create_func_hex::create(THD *thd, Item *arg1)
+Create_func_hex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_hex(arg1);
}
@@ -3574,7 +3574,7 @@ Create_func_hex::create(THD *thd, Item *
Create_func_ifnull Create_func_ifnull::s_singleton;
Item*
-Create_func_ifnull::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_ifnull::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_ifnull(arg1, arg2);
}
@@ -3583,7 +3583,7 @@ Create_func_ifnull::create(THD *thd, Ite
Create_func_inet_ntoa Create_func_inet_ntoa::s_singleton;
Item*
-Create_func_inet_ntoa::create(THD *thd, Item *arg1)
+Create_func_inet_ntoa::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_ntoa(arg1);
}
@@ -3592,7 +3592,7 @@ Create_func_inet_ntoa::create(THD *thd,
Create_func_inet_aton Create_func_inet_aton::s_singleton;
Item*
-Create_func_inet_aton::create(THD *thd, Item *arg1)
+Create_func_inet_aton::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_aton(arg1);
}
@@ -3601,7 +3601,7 @@ Create_func_inet_aton::create(THD *thd,
Create_func_instr Create_func_instr::s_singleton;
Item*
-Create_func_instr::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_instr::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_locate(arg1, arg2);
}
@@ -3611,7 +3611,7 @@ Create_func_instr::create(THD *thd, Item
Create_func_interiorringn Create_func_interiorringn::s_singleton;
Item*
-Create_func_interiorringn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_interiorringn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_INTERIORRINGN);
@@ -3623,7 +3623,7 @@ Create_func_interiorringn::create(THD *t
Create_func_intersects Create_func_intersects::s_singleton;
Item*
-Create_func_intersects::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_intersects::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_INTERSECTS_FUNC);
@@ -3634,7 +3634,7 @@ Create_func_intersects::create(THD *thd,
Create_func_is_free_lock Create_func_is_free_lock::s_singleton;
Item*
-Create_func_is_free_lock::create(THD *thd, Item *arg1)
+Create_func_is_free_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3645,7 +3645,7 @@ Create_func_is_free_lock::create(THD *th
Create_func_is_used_lock Create_func_is_used_lock::s_singleton;
Item*
-Create_func_is_used_lock::create(THD *thd, Item *arg1)
+Create_func_is_used_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3657,7 +3657,7 @@ Create_func_is_used_lock::create(THD *th
Create_func_isclosed Create_func_isclosed::s_singleton;
Item*
-Create_func_isclosed::create(THD *thd, Item *arg1)
+Create_func_isclosed::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isclosed(arg1);
}
@@ -3668,7 +3668,7 @@ Create_func_isclosed::create(THD *thd, I
Create_func_isempty Create_func_isempty::s_singleton;
Item*
-Create_func_isempty::create(THD *thd, Item *arg1)
+Create_func_isempty::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isempty(arg1);
}
@@ -3678,7 +3678,7 @@ Create_func_isempty::create(THD *thd, It
Create_func_isnull Create_func_isnull::s_singleton;
Item*
-Create_func_isnull::create(THD *thd, Item *arg1)
+Create_func_isnull::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isnull(arg1);
}
@@ -3688,7 +3688,7 @@ Create_func_isnull::create(THD *thd, Ite
Create_func_issimple Create_func_issimple::s_singleton;
Item*
-Create_func_issimple::create(THD *thd, Item *arg1)
+Create_func_issimple::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_issimple(arg1);
}
@@ -3698,7 +3698,7 @@ Create_func_issimple::create(THD *thd, I
Create_func_last_day Create_func_last_day::s_singleton;
Item*
-Create_func_last_day::create(THD *thd, Item *arg1)
+Create_func_last_day::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_last_day(arg1);
}
@@ -3744,7 +3744,7 @@ Create_func_last_insert_id::create_nativ
Create_func_lcase Create_func_lcase::s_singleton;
Item*
-Create_func_lcase::create(THD *thd, Item *arg1)
+Create_func_lcase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_lcase(arg1);
}
@@ -3774,7 +3774,7 @@ Create_func_least::create_native(THD *th
Create_func_length Create_func_length::s_singleton;
Item*
-Create_func_length::create(THD *thd, Item *arg1)
+Create_func_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_length(arg1);
}
@@ -3783,7 +3783,7 @@ Create_func_length::create(THD *thd, Ite
Create_func_ln Create_func_ln::s_singleton;
Item*
-Create_func_ln::create(THD *thd, Item *arg1)
+Create_func_ln::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ln(arg1);
}
@@ -3792,7 +3792,7 @@ Create_func_ln::create(THD *thd, Item *a
Create_func_load_file Create_func_load_file::s_singleton;
Item*
-Create_func_load_file::create(THD *thd, Item *arg1)
+Create_func_load_file::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3881,7 +3881,7 @@ Create_func_log::create_native(THD *thd,
Create_func_log10 Create_func_log10::s_singleton;
Item*
-Create_func_log10::create(THD *thd, Item *arg1)
+Create_func_log10::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log10(arg1);
}
@@ -3890,7 +3890,7 @@ Create_func_log10::create(THD *thd, Item
Create_func_log2 Create_func_log2::s_singleton;
Item*
-Create_func_log2::create(THD *thd, Item *arg1)
+Create_func_log2::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log2(arg1);
}
@@ -3899,7 +3899,7 @@ Create_func_log2::create(THD *thd, Item
Create_func_lpad Create_func_lpad::s_singleton;
Item*
-Create_func_lpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_lpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_lpad(arg1, arg2, arg3);
}
@@ -3908,7 +3908,7 @@ Create_func_lpad::create(THD *thd, Item
Create_func_ltrim Create_func_ltrim::s_singleton;
Item*
-Create_func_ltrim::create(THD *thd, Item *arg1)
+Create_func_ltrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ltrim(arg1);
}
@@ -3917,7 +3917,7 @@ Create_func_ltrim::create(THD *thd, Item
Create_func_makedate Create_func_makedate::s_singleton;
Item*
-Create_func_makedate::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_makedate::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_makedate(arg1, arg2);
}
@@ -3926,7 +3926,7 @@ Create_func_makedate::create(THD *thd, I
Create_func_maketime Create_func_maketime::s_singleton;
Item*
-Create_func_maketime::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_maketime::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_maketime(arg1, arg2, arg3);
}
@@ -4001,7 +4001,7 @@ Create_func_master_pos_wait::create_nati
Create_func_md5 Create_func_md5::s_singleton;
Item*
-Create_func_md5::create(THD *thd, Item *arg1)
+Create_func_md5::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_md5(arg1);
}
@@ -4010,7 +4010,7 @@ Create_func_md5::create(THD *thd, Item *
Create_func_monthname Create_func_monthname::s_singleton;
Item*
-Create_func_monthname::create(THD *thd, Item *arg1)
+Create_func_monthname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_monthname(arg1);
}
@@ -4019,7 +4019,7 @@ Create_func_monthname::create(THD *thd,
Create_func_name_const Create_func_name_const::s_singleton;
Item*
-Create_func_name_const::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_name_const::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_name_const(arg1, arg2);
}
@@ -4028,7 +4028,7 @@ Create_func_name_const::create(THD *thd,
Create_func_nullif Create_func_nullif::s_singleton;
Item*
-Create_func_nullif::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_nullif::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_nullif(arg1, arg2);
}
@@ -4038,7 +4038,7 @@ Create_func_nullif::create(THD *thd, Ite
Create_func_numgeometries Create_func_numgeometries::s_singleton;
Item*
-Create_func_numgeometries::create(THD *thd, Item *arg1)
+Create_func_numgeometries::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numgeometries(arg1);
}
@@ -4049,7 +4049,7 @@ Create_func_numgeometries::create(THD *t
Create_func_numinteriorring Create_func_numinteriorring::s_singleton;
Item*
-Create_func_numinteriorring::create(THD *thd, Item *arg1)
+Create_func_numinteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numinteriorring(arg1);
}
@@ -4060,7 +4060,7 @@ Create_func_numinteriorring::create(THD
Create_func_numpoints Create_func_numpoints::s_singleton;
Item*
-Create_func_numpoints::create(THD *thd, Item *arg1)
+Create_func_numpoints::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numpoints(arg1);
}
@@ -4070,7 +4070,7 @@ Create_func_numpoints::create(THD *thd,
Create_func_oct Create_func_oct::s_singleton;
Item*
-Create_func_oct::create(THD *thd, Item *arg1)
+Create_func_oct::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i8= new (thd->mem_root) Item_int((int32) 8,1);
@@ -4081,7 +4081,7 @@ Create_func_oct::create(THD *thd, Item *
Create_func_ord Create_func_ord::s_singleton;
Item*
-Create_func_ord::create(THD *thd, Item *arg1)
+Create_func_ord::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ord(arg1);
}
@@ -4091,7 +4091,7 @@ Create_func_ord::create(THD *thd, Item *
Create_func_overlaps Create_func_overlaps::s_singleton;
Item*
-Create_func_overlaps::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_overlaps::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_OVERLAPS_FUNC);
@@ -4102,7 +4102,7 @@ Create_func_overlaps::create(THD *thd, I
Create_func_period_add Create_func_period_add::s_singleton;
Item*
-Create_func_period_add::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_add::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_add(arg1, arg2);
}
@@ -4111,7 +4111,7 @@ Create_func_period_add::create(THD *thd,
Create_func_period_diff Create_func_period_diff::s_singleton;
Item*
-Create_func_period_diff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_diff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_diff(arg1, arg2);
}
@@ -4120,7 +4120,7 @@ Create_func_period_diff::create(THD *thd
Create_func_pi Create_func_pi::s_singleton;
Item*
-Create_func_pi::create(THD *thd)
+Create_func_pi::create_builder(THD *thd)
{
return new (thd->mem_root) Item_static_float_func("pi()", M_PI, 6, 8);
}
@@ -4130,7 +4130,7 @@ Create_func_pi::create(THD *thd)
Create_func_pointn Create_func_pointn::s_singleton;
Item*
-Create_func_pointn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pointn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_POINTN);
@@ -4141,7 +4141,7 @@ Create_func_pointn::create(THD *thd, Ite
Create_func_pow Create_func_pow::s_singleton;
Item*
-Create_func_pow::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pow::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_pow(arg1, arg2);
}
@@ -4150,7 +4150,7 @@ Create_func_pow::create(THD *thd, Item *
Create_func_quote Create_func_quote::s_singleton;
Item*
-Create_func_quote::create(THD *thd, Item *arg1)
+Create_func_quote::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_quote(arg1);
}
@@ -4159,7 +4159,7 @@ Create_func_quote::create(THD *thd, Item
Create_func_radians Create_func_radians::s_singleton;
Item*
-Create_func_radians::create(THD *thd, Item *arg1)
+Create_func_radians::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "radians", arg1,
M_PI/180, 0.0);
@@ -4216,7 +4216,7 @@ Create_func_rand::create_native(THD *thd
Create_func_release_lock Create_func_release_lock::s_singleton;
Item*
-Create_func_release_lock::create(THD *thd, Item *arg1)
+Create_func_release_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4227,7 +4227,7 @@ Create_func_release_lock::create(THD *th
Create_func_reverse Create_func_reverse::s_singleton;
Item*
-Create_func_reverse::create(THD *thd, Item *arg1)
+Create_func_reverse::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_reverse(arg1);
}
@@ -4274,7 +4274,7 @@ Create_func_round::create_native(THD *th
Create_func_row_count Create_func_row_count::s_singleton;
Item*
-Create_func_row_count::create(THD *thd)
+Create_func_row_count::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4285,7 +4285,7 @@ Create_func_row_count::create(THD *thd)
Create_func_rpad Create_func_rpad::s_singleton;
Item*
-Create_func_rpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_rpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_rpad(arg1, arg2, arg3);
}
@@ -4294,7 +4294,7 @@ Create_func_rpad::create(THD *thd, Item
Create_func_rtrim Create_func_rtrim::s_singleton;
Item*
-Create_func_rtrim::create(THD *thd, Item *arg1)
+Create_func_rtrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_rtrim(arg1);
}
@@ -4303,7 +4303,7 @@ Create_func_rtrim::create(THD *thd, Item
Create_func_sec_to_time Create_func_sec_to_time::s_singleton;
Item*
-Create_func_sec_to_time::create(THD *thd, Item *arg1)
+Create_func_sec_to_time::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sec_to_time(arg1);
}
@@ -4312,7 +4312,7 @@ Create_func_sec_to_time::create(THD *thd
Create_func_sha Create_func_sha::s_singleton;
Item*
-Create_func_sha::create(THD *thd, Item *arg1)
+Create_func_sha::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sha(arg1);
}
@@ -4321,7 +4321,7 @@ Create_func_sha::create(THD *thd, Item *
Create_func_sign Create_func_sign::s_singleton;
Item*
-Create_func_sign::create(THD *thd, Item *arg1)
+Create_func_sign::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sign(arg1);
}
@@ -4330,7 +4330,7 @@ Create_func_sign::create(THD *thd, Item
Create_func_sin Create_func_sin::s_singleton;
Item*
-Create_func_sin::create(THD *thd, Item *arg1)
+Create_func_sin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sin(arg1);
}
@@ -4339,7 +4339,7 @@ Create_func_sin::create(THD *thd, Item *
Create_func_sleep Create_func_sleep::s_singleton;
Item*
-Create_func_sleep::create(THD *thd, Item *arg1)
+Create_func_sleep::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4350,7 +4350,7 @@ Create_func_sleep::create(THD *thd, Item
Create_func_soundex Create_func_soundex::s_singleton;
Item*
-Create_func_soundex::create(THD *thd, Item *arg1)
+Create_func_soundex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_soundex(arg1);
}
@@ -4359,7 +4359,7 @@ Create_func_soundex::create(THD *thd, It
Create_func_space Create_func_space::s_singleton;
Item*
-Create_func_space::create(THD *thd, Item *arg1)
+Create_func_space::create_1_arg(THD *thd, Item *arg1)
{
/**
TODO: Fix Bug#23637
@@ -4387,7 +4387,7 @@ Create_func_space::create(THD *thd, Item
Create_func_sqrt Create_func_sqrt::s_singleton;
Item*
-Create_func_sqrt::create(THD *thd, Item *arg1)
+Create_func_sqrt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sqrt(arg1);
}
@@ -4397,7 +4397,7 @@ Create_func_sqrt::create(THD *thd, Item
Create_func_srid Create_func_srid::s_singleton;
Item*
-Create_func_srid::create(THD *thd, Item *arg1)
+Create_func_srid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_srid(arg1);
}
@@ -4408,7 +4408,7 @@ Create_func_srid::create(THD *thd, Item
Create_func_startpoint Create_func_startpoint::s_singleton;
Item*
-Create_func_startpoint::create(THD *thd, Item *arg1)
+Create_func_startpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_STARTPOINT);
@@ -4419,7 +4419,7 @@ Create_func_startpoint::create(THD *thd,
Create_func_str_to_date Create_func_str_to_date::s_singleton;
Item*
-Create_func_str_to_date::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_str_to_date::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_str_to_date(arg1, arg2);
}
@@ -4428,7 +4428,7 @@ Create_func_str_to_date::create(THD *thd
Create_func_strcmp Create_func_strcmp::s_singleton;
Item*
-Create_func_strcmp::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_strcmp::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_strcmp(arg1, arg2);
}
@@ -4437,7 +4437,7 @@ Create_func_strcmp::create(THD *thd, Ite
Create_func_substr_index Create_func_substr_index::s_singleton;
Item*
-Create_func_substr_index::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_substr_index::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_substr_index(arg1, arg2, arg3);
}
@@ -4446,7 +4446,7 @@ Create_func_substr_index::create(THD *th
Create_func_subtime Create_func_subtime::s_singleton;
Item*
-Create_func_subtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_subtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 1);
}
@@ -4455,7 +4455,7 @@ Create_func_subtime::create(THD *thd, It
Create_func_tan Create_func_tan::s_singleton;
Item*
-Create_func_tan::create(THD *thd, Item *arg1)
+Create_func_tan::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_tan(arg1);
}
@@ -4464,7 +4464,7 @@ Create_func_tan::create(THD *thd, Item *
Create_func_time_format Create_func_time_format::s_singleton;
Item*
-Create_func_time_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_time_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 1);
}
@@ -4473,7 +4473,7 @@ Create_func_time_format::create(THD *thd
Create_func_time_to_sec Create_func_time_to_sec::s_singleton;
Item*
-Create_func_time_to_sec::create(THD *thd, Item *arg1)
+Create_func_time_to_sec::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_time_to_sec(arg1);
}
@@ -4482,7 +4482,7 @@ Create_func_time_to_sec::create(THD *thd
Create_func_timediff Create_func_timediff::s_singleton;
Item*
-Create_func_timediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_timediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_timediff(arg1, arg2);
}
@@ -4491,7 +4491,7 @@ Create_func_timediff::create(THD *thd, I
Create_func_to_days Create_func_to_days::s_singleton;
Item*
-Create_func_to_days::create(THD *thd, Item *arg1)
+Create_func_to_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_to_days(arg1);
}
@@ -4501,7 +4501,7 @@ Create_func_to_days::create(THD *thd, It
Create_func_touches Create_func_touches::s_singleton;
Item*
-Create_func_touches::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_touches::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_TOUCHES_FUNC);
@@ -4512,7 +4512,7 @@ Create_func_touches::create(THD *thd, It
Create_func_ucase Create_func_ucase::s_singleton;
Item*
-Create_func_ucase::create(THD *thd, Item *arg1)
+Create_func_ucase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ucase(arg1);
}
@@ -4521,7 +4521,7 @@ Create_func_ucase::create(THD *thd, Item
Create_func_uncompress Create_func_uncompress::s_singleton;
Item*
-Create_func_uncompress::create(THD *thd, Item *arg1)
+Create_func_uncompress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompress(arg1);
}
@@ -4530,7 +4530,7 @@ Create_func_uncompress::create(THD *thd,
Create_func_uncompressed_length Create_func_uncompressed_length::s_singleton;
Item*
-Create_func_uncompressed_length::create(THD *thd, Item *arg1)
+Create_func_uncompressed_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompressed_length(arg1);
}
@@ -4539,7 +4539,7 @@ Create_func_uncompressed_length::create(
Create_func_unhex Create_func_unhex::s_singleton;
Item*
-Create_func_unhex::create(THD *thd, Item *arg1)
+Create_func_unhex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_unhex(arg1);
}
@@ -4584,7 +4584,7 @@ Create_func_unix_timestamp::create_nativ
Create_func_uuid Create_func_uuid::s_singleton;
Item*
-Create_func_uuid::create(THD *thd)
+Create_func_uuid::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4595,7 +4595,7 @@ Create_func_uuid::create(THD *thd)
Create_func_uuid_short Create_func_uuid_short::s_singleton;
Item*
-Create_func_uuid_short::create(THD *thd)
+Create_func_uuid_short::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4606,7 +4606,7 @@ Create_func_uuid_short::create(THD *thd)
Create_func_version Create_func_version::s_singleton;
Item*
-Create_func_version::create(THD *thd)
+Create_func_version::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
return new (thd->mem_root) Item_static_string_func("version()",
@@ -4620,7 +4620,7 @@ Create_func_version::create(THD *thd)
Create_func_weekday Create_func_weekday::s_singleton;
Item*
-Create_func_weekday::create(THD *thd, Item *arg1)
+Create_func_weekday::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 0);
}
@@ -4629,7 +4629,7 @@ Create_func_weekday::create(THD *thd, It
Create_func_weekofyear Create_func_weekofyear::s_singleton;
Item*
-Create_func_weekofyear::create(THD *thd, Item *arg1)
+Create_func_weekofyear::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "0", 3, 1);
return new (thd->mem_root) Item_func_week(arg1, i1);
@@ -4640,7 +4640,7 @@ Create_func_weekofyear::create(THD *thd,
Create_func_within Create_func_within::s_singleton;
Item*
-Create_func_within::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_within::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_WITHIN_FUNC);
@@ -4652,7 +4652,7 @@ Create_func_within::create(THD *thd, Ite
Create_func_x Create_func_x::s_singleton;
Item*
-Create_func_x::create(THD *thd, Item *arg1)
+Create_func_x::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_x(arg1);
}
@@ -4662,7 +4662,7 @@ Create_func_x::create(THD *thd, Item *ar
Create_func_xml_extractvalue Create_func_xml_extractvalue::s_singleton;
Item*
-Create_func_xml_extractvalue::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_xml_extractvalue::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_xml_extractvalue(arg1, arg2);
}
@@ -4671,7 +4671,7 @@ Create_func_xml_extractvalue::create(THD
Create_func_xml_update Create_func_xml_update::s_singleton;
Item*
-Create_func_xml_update::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_xml_update::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_xml_update(arg1, arg2, arg3);
}
@@ -4681,7 +4681,7 @@ Create_func_xml_update::create(THD *thd,
Create_func_y Create_func_y::s_singleton;
Item*
-Create_func_y::create(THD *thd, Item *arg1)
+Create_func_y::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_y(arg1);
}
=== modified file 'sql/item_create.h'
--- a/sql/item_create.h 2007-08-15 13:43:08 +0000
+++ b/sql/item_create.h 2010-03-28 18:10:00 +0000
@@ -91,8 +91,9 @@ public:
@param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call
*/
- virtual Item* create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list) = 0;
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name,
+ List<Item> *item_list) = 0;
protected:
/** Constructor. */
=== modified file 'sql/item_sum.cc'
--- a/sql/item_sum.cc 2010-01-15 15:27:55 +0000
+++ b/sql/item_sum.cc 2010-03-28 18:10:00 +0000
@@ -642,7 +642,7 @@ Item_sum_hybrid::fix_fields(THD *thd, It
default:
DBUG_ASSERT(0);
};
- setup(args[0], NULL);
+ setup_item(args[0], NULL);
/* MIN/MAX can return NULL for empty set indepedent of the used column */
maybe_null= 1;
unsigned_flag=item->unsigned_flag;
@@ -676,7 +676,7 @@ Item_sum_hybrid::fix_fields(THD *thd, It
of the original MIN/MAX object and it is saved in this object's cache.
*/
-void Item_sum_hybrid::setup(Item *item, Item *value_arg)
+void Item_sum_hybrid::setup_item(Item *item, Item *value_arg)
{
value= Item_cache::get_cache(item);
value->setup(item);
@@ -1646,7 +1646,7 @@ void Item_sum_hybrid::no_rows_in_result(
Item *Item_sum_min::copy_or_same(THD* thd)
{
Item_sum_min *item= new (thd->mem_root) Item_sum_min(thd, this);
- item->setup(args[0], value);
+ item->setup_item(args[0], value);
return item;
}
@@ -1669,7 +1669,7 @@ bool Item_sum_min::add()
Item *Item_sum_max::copy_or_same(THD* thd)
{
Item_sum_max *item= new (thd->mem_root) Item_sum_max(thd, this);
- item->setup(args[0], value);
+ item->setup_item(args[0], value);
return item;
}
=== modified file 'sql/item_sum.h'
--- a/sql/item_sum.h 2010-02-01 06:14:12 +0000
+++ b/sql/item_sum.h 2010-04-01 09:04:26 +0000
@@ -870,7 +870,7 @@ protected:
was_values(item->was_values)
{ }
bool fix_fields(THD *, Item **);
- void setup(Item *item, Item *value_arg);
+ void setup_item(Item *item, Item *value_arg);
void clear();
double val_real();
longlong val_int();
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-03-15 11:51:23 +0000
+++ b/sql/log.cc 2010-04-01 09:04:26 +0000
@@ -5424,7 +5424,7 @@ int TC_LOG_MMAP::open(const char *opt_na
pg->state=POOL;
pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST);
pthread_cond_init (&pg->cond, 0);
- pg->start=(my_xid *)(data + i*tc_log_page_size);
+ pg->ptr= pg->start=(my_xid *)(data + i*tc_log_page_size);
pg->size=pg->free=tc_log_page_size/sizeof(my_xid);
pg->end=pg->start + pg->size;
}
@@ -5659,7 +5659,15 @@ int TC_LOG_MMAP::sync()
/* marking 'syncing' slot free */
pthread_mutex_lock(&LOCK_sync);
syncing=0;
- pthread_cond_signal(&active->cond); // wake up a new syncer
+ /*
+ we check the "active" pointer without LOCK_active. Still, it's safe -
+ "active" can change from NULL to not NULL any time, but it
+ will take LOCK_sync before waiting on active->cond. That is, it can never
+ miss a signal.
+ And "active" can change to NULL only after LOCK_sync, so this is safe too.
+ */
+ if (active)
+ pthread_cond_signal(&active->cond); // wake up a new syncer
pthread_mutex_unlock(&LOCK_sync);
return err;
}
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-29 15:13:53 +0000
+++ b/sql/mysqld.cc 2010-04-01 09:04:26 +0000
@@ -8371,6 +8371,8 @@ mysqld_get_one_option(int optid,
case (int) OPT_INIT_RPL_ROLE:
{
int role;
+ LINT_INIT(role);
+
if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role))
{
rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
@@ -8427,6 +8429,8 @@ mysqld_get_one_option(int optid,
case OPT_BINLOG_FORMAT:
{
int id;
+ LINT_INIT(id);
+
if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id))
{
global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
@@ -8677,6 +8681,8 @@ mysqld_get_one_option(int optid,
else
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type))
delay_key_write_options= (uint) type-1;
}
@@ -8688,6 +8694,8 @@ mysqld_get_one_option(int optid,
case OPT_TX_ISOLATION:
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type))
global_system_variables.tx_isolation= (type-1);
break;
@@ -8775,6 +8783,7 @@ mysqld_get_one_option(int optid,
ulong method_conv;
int method;
LINT_INIT(method_conv);
+ LINT_INIT(method);
myisam_stats_method_str= argument;
if (!find_opt_type(argument, &myisam_stats_method_typelib,
@@ -8837,6 +8846,7 @@ mysqld_get_one_option(int optid,
case OPT_THREAD_HANDLING:
{
int id;
+ LINT_INIT(id);
if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id))
global_system_variables.thread_handling= id - 1;
opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];
=== modified file 'sql/net_serv.cc'
--- a/sql/net_serv.cc 2010-02-23 12:04:58 +0000
+++ b/sql/net_serv.cc 2010-03-29 19:07:45 +0000
@@ -279,7 +279,7 @@ static int net_data_is_ready(my_socket s
@param clear_buffer if <> 0, then clear all data from comm buff
*/
-void net_clear(NET *net, my_bool clear_buffer)
+void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
size_t count;
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2010-03-15 11:51:23 +0000
+++ b/sql/set_var.cc 2010-04-01 09:04:26 +0000
@@ -1266,16 +1266,16 @@ uchar *sys_var_set::value_ptr(THD *thd,
void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
{
- slave_exec_mode_options= 0;
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ slave_exec_mode_options= (ULL(1) << SLAVE_EXEC_MODE_STRICT);
}
bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
{
bool rc= sys_var_set::check(thd, var);
if (!rc &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ test_all_bits(var->save_result.ulong_value,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
rc= true;
my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
@@ -1297,15 +1297,16 @@ void fix_slave_exec_mode(enum_var_type t
DBUG_ENTER("fix_slave_exec_mode");
compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT
> SLAVE_EXEC_MODE_LAST_BIT - 1);
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ if (test_all_bits(slave_exec_mode_options,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
sql_print_error("Ambiguous slave modes combination."
" STRICT will be used");
- bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT);
+ slave_exec_mode_options&= ~(ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT);
}
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ if (!(slave_exec_mode_options & (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT)))
+ slave_exec_mode_options|= (ULL(1)<< SLAVE_EXEC_MODE_STRICT);
DBUG_VOID_RETURN;
}
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sp_head.cc 2010-04-01 09:04:26 +0000
@@ -2089,6 +2089,8 @@ sp_head::reset_lex(THD *thd)
sublex->dec= NULL;
sublex->interval_list.empty();
sublex->type= 0;
+ sublex->uint_geom_type= 0;
+ sublex->vcol_info= 0;
DBUG_RETURN(FALSE);
}
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-03-31 18:37:45 +0000
+++ b/sql/sql_acl.cc 2010-04-01 09:04:26 +0000
@@ -536,6 +536,9 @@ static my_bool acl_load(THD *thd, TABLE_
while (!(read_record_info.read_record(&read_record_info)))
{
ACL_USER user;
+ char *password;
+ uint password_len;
+
bzero(&user, sizeof(user));
update_hostname(&user.host, get_field(&mem, table->field[0]));
user.user= get_field(&mem, table->field[1]);
@@ -548,8 +551,8 @@ static my_bool acl_load(THD *thd, TABLE_
continue;
}
- char *password= get_field(thd->mem_root, table->field[2]);
- uint password_len= password ? strlen(password) : 0;
+ password= get_field(&mem, table->field[2]);
+ password_len= password ? strlen(password) : 0;
user.auth_string.str= password ? password : const_cast<char*>("");
user.auth_string.length= password_len;
set_user_salt(&user, password, password_len);
@@ -7826,15 +7829,15 @@ static int do_auth_once(THD *thd, LEX_ST
bool unlock_plugin= false;
plugin_ref plugin;
+#ifdef EMBEDDED_LIBRARY
+ plugin= native_password_plugin;
+#else
if (auth_plugin_name->str == native_password_plugin_name.str)
plugin= native_password_plugin;
- else
-#ifndef EMBEDDED_LIBRARY
- if (auth_plugin_name->str == old_password_plugin_name.str)
+ else if (auth_plugin_name->str == old_password_plugin_name.str)
plugin= old_password_plugin;
- else
- if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
- MYSQL_AUTHENTICATION_PLUGIN)))
+ else if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
+ MYSQL_AUTHENTICATION_PLUGIN)))
unlock_plugin= true;
#endif
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-29 15:13:53 +0000
+++ b/sql/sql_class.h 2010-04-01 09:04:26 +0000
@@ -63,6 +63,7 @@ public:
bool report_error(THD *thd);
bool is_invalidated() const { return m_invalidated; }
void reset_reprepare_observer() { m_invalidated= FALSE; }
+ Reprepare_observer() {} /* Remove gcc warning */
private:
bool m_invalidated;
};
@@ -1117,6 +1118,7 @@ public:
/* Ignore error */
return TRUE;
}
+ Dummy_error_handler() {} /* Remove gcc warning */
};
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_table.cc 2010-04-01 09:04:26 +0000
@@ -5704,6 +5704,10 @@ compare_tables(TABLE *table,
*/
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
uint db_options= 0; /* not used */
+
+ /* Set default value for return value (to ensure it's always set) */
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+
/* Create the prepared information. */
if (mysql_prepare_create_table(thd, create_info,
&tmp_alter_info,
@@ -5762,7 +5766,6 @@ compare_tables(TABLE *table,
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
{
DBUG_PRINT("info", ("Basic checks -> ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5792,7 +5795,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("NULL behaviour difference in field '%s' -> "
"ALTER_TABLE_DATA_CHANGED", new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5828,7 +5830,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED",
new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
// Clear indexed marker
@@ -5963,7 +5964,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("check_if_incompatible_data() -> "
"ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_view.cc 2010-03-30 12:36:49 +0000
@@ -1034,10 +1034,12 @@ bool mysql_make_view(THD *thd, File_pars
bool parse_status;
bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables);
-
DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
+ LINT_INIT(parse_status);
+ LINT_INIT(view_select);
+
if (table->view)
{
/*
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-03-29 15:13:53 +0000
+++ b/sql/sql_yacc.yy 2010-04-01 09:04:26 +0000
@@ -2342,6 +2342,7 @@ sp_init_param:
lex->interval_list.empty();
lex->uint_geom_type= 0;
+ lex->vcol_info= 0;
}
;
@@ -8190,7 +8191,7 @@ function_call_generic:
builder= find_qualified_function_builder(thd);
DBUG_ASSERT(builder);
- item= builder->create(thd, $1, $3, true, $5);
+ item= builder->create_with_db(thd, $1, $3, true, $5);
if (! ($$= item))
{
=== modified file 'storage/example/ha_example.h'
--- a/storage/example/ha_example.h 2007-08-13 13:11:25 +0000
+++ b/storage/example/ha_example.h 2010-03-28 18:10:00 +0000
@@ -155,7 +155,8 @@ public:
/** @brief
This method will never be called if you do not implement indexes.
*/
- virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
+ virtual double read_time(uint index, uint ranges, ha_rows rows)
+ { return (double) rows / 20.0+1; }
/*
Everything below are methods that we implement in ha_example.cc.
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2010-03-30 12:35:15 +0000
+++ b/storage/maria/ma_loghandler.c 2010-04-01 09:04:26 +0000
@@ -1274,6 +1274,8 @@ static my_bool translog_set_lsn_for_file
for (file= from_file; file <= to_file; file++)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT(info.max_lsn);
+
File fd= open_logfile_by_number_no_cache(file);
LINT_INIT_STRUCT(info);
if ((fd < 0) ||
@@ -3968,6 +3970,7 @@ my_bool translog_init_with_table(const c
{
LOGHANDLER_FILE_INFO info;
LINT_INIT_STRUCT(info);
+
/*
Accessing &log_descriptor.open_files without mutex is safe
because it is initialization
=== modified file 'storage/maria/ma_search.c'
--- a/storage/maria/ma_search.c 2010-03-15 11:51:23 +0000
+++ b/storage/maria/ma_search.c 2010-04-01 09:04:26 +0000
@@ -76,8 +76,8 @@ int _ma_search(register MARIA_HA *info,
bmove512(info->keyread_buff, page_buff, info->s->block_size);
/* Save position for a possible read next / previous */
- info->int_keypos= info->keyread_buff + (ulonglong) info->int_keypos;
- info->int_maxpos= info->keyread_buff + (ulonglong) info->int_maxpos;
+ info->int_keypos= info->keyread_buff + info->keypos_offset;
+ info->int_maxpos= info->keyread_buff + info->maxpos_offset;
info->int_keytree_version= key->keyinfo->version;
info->last_search_keypage= info->last_keypage;
info->page_changed= 0;
@@ -214,8 +214,8 @@ static int _ma_search_no_save(register M
info->cur_row.trid= _ma_trid_from_key(&info->last_key);
/* Store offset to key */
- info->int_keypos= (uchar*) (keypos - page.buff);
- info->int_maxpos= (uchar*) (maxpos - page.buff);
+ info->keypos_offset= (uint) (keypos - page.buff);
+ info->maxpos_offset= (uint) (maxpos - page.buff);
info->int_nod_flag= nod_flag;
info->last_keypage= pos;
*res_page_link= page_link;
=== modified file 'storage/maria/maria_def.h'
--- a/storage/maria/maria_def.h 2010-03-09 19:22:24 +0000
+++ b/storage/maria/maria_def.h 2010-03-28 18:10:00 +0000
@@ -506,8 +506,10 @@ struct st_maria_handler
uchar *first_mbr_key; /* Searhed spatial key */
uchar *rec_buff; /* Temp buffer for recordpack */
uchar *blob_buff; /* Temp buffer for blobs */
- uchar *int_keypos, /* Save position for next/previous */
- *int_maxpos; /* -""- */
+ uchar *int_keypos; /* Save position for next/previous */
+ uchar *int_maxpos; /* -""- */
+ uint keypos_offset; /* Tmp storage for offset int_keypos */
+ uint maxpos_offset; /* Tmp storage for offset int_maxpos */
uchar *update_field_data; /* Used by update in rows-in-block */
uint int_nod_flag; /* -""- */
uint32 int_keytree_version; /* -""- */
=== modified file 'storage/myisam/ft_stopwords.c'
--- a/storage/myisam/ft_stopwords.c 2010-03-10 10:32:14 +0000
+++ b/storage/myisam/ft_stopwords.c 2010-03-28 18:10:00 +0000
@@ -44,9 +44,10 @@ static void FT_STOPWORD_free(FT_STOPWORD
static int ft_add_stopword(const char *w)
{
FT_STOPWORD sw;
- return !w ||
- (((sw.len= (uint) strlen(sw.pos=(const uchar *)w)) >= ft_min_word_len) &&
- (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL));
+ return (!w ||
+ (((sw.len= (uint) strlen((char*) (sw.pos=(const uchar *)w))) >=
+ ft_min_word_len) &&
+ (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL)));
}
int ft_init_stopwords()
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2010-03-04 08:03:07 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-03-30 12:36:49 +0000
@@ -382,7 +382,7 @@ static MI_INFO *myisammrg_attach_childre
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
}
DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d",
- my_errno ? NULL : (long) myisam, my_errno));
+ my_errno ? 0L : (long) myisam, my_errno));
err:
DBUG_RETURN(my_errno ? NULL : myisam);
=== modified file 'storage/myisammrg/myrg_open.c'
--- a/storage/myisammrg/myrg_open.c 2009-09-23 13:21:29 +0000
+++ b/storage/myisammrg/myrg_open.c 2010-03-30 12:36:49 +0000
@@ -239,6 +239,7 @@ MYRG_INFO *myrg_parent_open(const char *
rc= 1;
errpos= 0;
bzero((char*) &file_cache, sizeof(file_cache));
+ LINT_INIT(m_info);
/* Open MERGE meta file. */
if ((fd= my_open(fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT,
=== modified file 'storage/xtradb/include/page0page.h'
--- a/storage/xtradb/include/page0page.h 2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/page0page.h 2010-03-28 18:10:00 +0000
@@ -517,7 +517,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec); /*!< in: pointer to record */
+ const rec_t* rec); /*!< in: pointer to record */
/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
=== modified file 'storage/xtradb/include/page0page.ic'
--- a/storage/xtradb/include/page0page.ic 2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/page0page.ic 2010-03-28 18:10:00 +0000
@@ -731,7 +731,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec) /*!< in: pointer to record */
+ const rec_t* rec) /*!< in: pointer to record */
{
return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
}
=== modified file 'storage/xtradb/include/ut0lst.h'
--- a/storage/xtradb/include/ut0lst.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0lst.h 2010-03-30 12:36:49 +0000
@@ -158,7 +158,7 @@ Inserts a NODE2 after NODE1 in a list.
/** Invalidate the pointers in a list node.
@param NAME list name
@param N pointer to the node that was removed */
-# define UT_LIST_REMOVE_CLEAR(NAME, N) while (0)
+# define UT_LIST_REMOVE_CLEAR(NAME, N) {} while (0)
#endif
/*******************************************************************//**
=== modified file 'strings/ctype-ucs2.c'
--- a/strings/ctype-ucs2.c 2010-03-15 11:51:23 +0000
+++ b/strings/ctype-ucs2.c 2010-04-01 09:04:26 +0000
@@ -203,7 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@@ -317,7 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_I
const char *s, const char *t, size_t len)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const char *se=s+len;
const char *te=t+len;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@@ -1384,7 +1384,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
=== modified file 'strings/ctype-utf8.c'
--- a/strings/ctype-utf8.c 2010-01-06 19:20:16 +0000
+++ b/strings/ctype-utf8.c 2010-04-01 09:04:26 +0000
@@ -2308,7 +2308,7 @@ static int my_strnncoll_utf8(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc), t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@@ -2378,7 +2378,7 @@ static int my_strnncollsp_utf8(CHARSET_I
my_bool diff_if_only_endspace_difference)
{
int s_res, t_res, res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se= s+slen, *te= t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
=== modified file 'strings/my_vsnprintf.c'
--- a/strings/my_vsnprintf.c 2010-03-03 14:44:14 +0000
+++ b/strings/my_vsnprintf.c 2010-04-01 09:04:26 +0000
@@ -400,16 +400,18 @@ start:
case 's':
{
char *par= args_arr[print_arr[i].arg_idx].str_arg;
- width= (print_arr[i].flags & WIDTH_ARG) ?
- args_arr[print_arr[i].width].longlong_arg : print_arr[i].width;
+ width= ((print_arr[i].flags & WIDTH_ARG) ?
+ (uint) args_arr[print_arr[i].width].longlong_arg :
+ (uint) print_arr[i].width);
to= process_str_arg(cs, to, end, width, par, print_arr[i].flags);
break;
}
case 'b':
{
char *par = args_arr[print_arr[i].arg_idx].str_arg;
- width= (print_arr[i].flags & WIDTH_ARG) ?
- args_arr[print_arr[i].width].longlong_arg : print_arr[i].width;
+ width= ((print_arr[i].flags & WIDTH_ARG) ?
+ (uint) args_arr[print_arr[i].width].longlong_arg :
+ (uint) print_arr[i].width);
to= process_bin_arg(to, end, width, par);
break;
}
@@ -428,8 +430,9 @@ start:
{
/* Integer parameter */
longlong larg;
- length= (print_arr[i].flags & LENGTH_ARG) ?
- args_arr[print_arr[i].length].longlong_arg : print_arr[i].length;
+ length= ((print_arr[i].flags & LENGTH_ARG) ?
+ args_arr[print_arr[i].length].longlong_arg :
+ (longlong) print_arr[i].length);
if (args_arr[print_arr[i].arg_idx].have_longlong)
larg = args_arr[print_arr[i].arg_idx].longlong_arg;
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-03-10 10:32:14 +0000
+++ b/support-files/compiler_warnings.supp 2010-03-31 19:12:21 +0000
@@ -39,6 +39,7 @@ sync/sync0rw\.c: unused parameter
sync/sync0sync\.c: unused parameter
sync/sync0sync\.c: unused variable
ut/ut0ut\.c: ignoring return value of
+srv/srv0srv\.c: value computed is not used
#
# bdb is not critical to keep up to date
@@ -53,6 +54,12 @@ db_vrfy.c : .*comparison is always false
# readline is not maintained by us
#
.*/cmd-line-utils/readline/.* : .*
+readline\.c : unused parameter
+term\.c : unused parameter
+vi\.c : unused parameter
+common\.c : unused parameter
+term\.c : *.*
+
#
# Ignore some warnings in libevent, which is not maintained by us.
@@ -66,6 +73,16 @@ db_vrfy.c : .*comparison is always false
/usr/share/aclocal/audiofile.m4 : .*
#
+# Ignore strict-aliasing warnings (for now)
+#
+.*: break strict-aliasing rules
+
+#
+# Ignore not important declaration warnings
+#
+.*: only defines private constructors and has no friends
+
+#
# Ignore all conversion warnings on windows 64
# (Is safe as we are not yet supporting strings >= 2G)
#
@@ -100,6 +117,11 @@ db_vrfy.c : .*comparison is always false
storage/maria/ma_pagecache.c: .*'info_check_pin' defined but not used
#
+# Pbxt
+#
+xaction_xt\.cc: may be used uninitialized in this function
+
+#
# I think these are due to mix of C and C++.
#
storage/pbxt/ : typedef.*was ignored in this declaration
@@ -112,6 +134,7 @@ include/runtime.hpp: .*pure_error.*
.*/extra/yassl/taocrypt/src/blowfish\.cpp: array subscript is above array bounds
.*/extra/yassl/taocrypt/src/file\.cpp: ignoring return value
.*/extra/yassl/taocrypt/src/integer\.cpp: control reaches end of non-void function
+mySTL/algorithm\.hpp: is used uninitialized in this function
#
# Groff warnings on OpenSUSE.
@@ -123,18 +146,18 @@ include/runtime.hpp: .*pure_error.*
#
listener.cc : .*conversion from 'SOCKET' to 'int'.*
net_serv.cc : .*conversion from 'SOCKET' to 'int'.*
-set_var.cc: right-hand operand of comma has no effect : 1000-1400
-
# allow a little moving space for the warning below
-mi_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
-ma_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
+mi_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
+ma_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
#
# Wrong compiler warnings
#
.* : .*no matching operator delete found; memory will not be freed if initialization throws an exception.*
-ctype-simple.c : .*unary minus operator applied to unsigned type, result still unsigned.*
+ctype-simple\.c : .*unary minus operator applied to unsigned type, result still unsigned.*
# Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478
-regexec\.c : .*passing argument 3 of.*matcher.* discards qualifiers from pointer target type.*
+regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type
+libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000
+storage/xtradb/dict/dict0dict\.c: passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
=== modified file 'unittest/mysys/waiting_threads-t.c'
--- a/unittest/mysys/waiting_threads-t.c 2010-01-28 14:49:14 +0000
+++ b/unittest/mysys/waiting_threads-t.c 2010-03-30 12:36:49 +0000
@@ -258,7 +258,7 @@ void do_tests()
#define test_kill_strategy(X) \
diag("kill strategy: " #X); \
DBUG_EXECUTE("reset_file", \
- { rewind(DBUG_FILE); (void) ftruncate(fileno(DBUG_FILE), 0); }); \
+ { rewind(DBUG_FILE); my_chsize(fileno(DBUG_FILE), 0, 0, MYF(MY_WME)); }); \
DBUG_PRINT("info", ("kill strategy: " #X)); \
kill_strategy=X; \
do_one_test();
1
0

[Maria-developers] Updated (by Guest): Table elimination (17)
by worklog-noreply@askmonty.org 01 Apr '10
by worklog-noreply@askmonty.org 01 Apr '10
01 Apr '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Table elimination
CREATION DATE..: Sun, 10 May 2009, 19:57
SUPERVISOR.....: Monty
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-Sprint
TASK ID........: 17 (http://askmonty.org/worklog/?tid=17)
VERSION........: Server-9.x
STATUS.........: Assigned
PRIORITY.......: 60
WORKED HOURS...: 1
ESTIMATE.......: 3 (hours remain)
ORIG. ESTIMATE.: 3
PROGRESS NOTES:
-=-=(Guest - Thu, 01 Apr 2010, 01:56)=-=-
New attachment: '16_bitMICRO-PROCESSOR.htm'
-=-=(Guest - Wed, 24 Mar 2010, 05:58)=-=-
Status updated.
--- /tmp/wklog.17.old.13223 2010-03-24 05:58:26.000000000 +0000
+++ /tmp/wklog.17.new.13223 2010-03-24 05:58:26.000000000 +0000
@@ -1 +1 @@
-In-Progress
+Assigned
-=-=(Guest - Wed, 24 Mar 2010, 05:58)=-=-
Privacy level updated.
--- /tmp/wklog.17.old.13223 2010-03-24 05:58:26.000000000 +0000
+++ /tmp/wklog.17.new.13223 2010-03-24 05:58:26.000000000 +0000
@@ -1 +1 @@
-n
+y
-=-=(Guest - Wed, 28 Oct 2009, 02:01)=-=-
Version updated.
--- /tmp/wklog.17.old.24041 2009-10-28 02:01:58.000000000 +0200
+++ /tmp/wklog.17.new.24041 2009-10-28 02:01:58.000000000 +0200
@@ -1 +1 @@
-9.x
+Server-9.x
-=-=(Guest - Sun, 16 Aug 2009, 16:16)=-=-
Category updated.
--- /tmp/wklog.17.old.24882 2009-08-16 16:16:49.000000000 +0300
+++ /tmp/wklog.17.new.24882 2009-08-16 16:16:49.000000000 +0300
@@ -1 +1 @@
-Client-BackLog
+Server-Sprint
-=-=(Guest - Sun, 16 Aug 2009, 16:16)=-=-
Version updated.
--- /tmp/wklog.17.old.24882 2009-08-16 16:16:49.000000000 +0300
+++ /tmp/wklog.17.new.24882 2009-08-16 16:16:49.000000000 +0300
@@ -1 +1 @@
-Server-5.1
+9.x
-=-=(Guest - Wed, 29 Jul 2009, 21:41)=-=-
Low Level Design modified.
--- /tmp/wklog.17.old.26011 2009-07-29 21:41:04.000000000 +0300
+++ /tmp/wklog.17.new.26011 2009-07-29 21:41:04.000000000 +0300
@@ -2,163 +2,146 @@
~maria-captains/maria/maria-5.1-table-elimination tree.
<contents>
-1. Conditions for removal
-1.1 Quick check if there are candidates
-2. Removal operation properties
-3. Removal operation
-4. User interface
-5. Tests and benchmarks
-6. Todo, issues to resolve
-6.1 To resolve
-6.2 Resolved
-7. Additional issues
+1. Elimination criteria
+2. No outside references check
+2.1 Quick check if there are tables with no outside references
+3. One-match check
+3.1 Functional dependency source #1: Potential eq_ref access
+3.2 Functional dependency source #2: col2=func(col1)
+3.3 Functional dependency source #3: One or zero records in the table
+3.4 Functional dependency check implementation
+3.4.1 Equality collection: Option1
+3.4.2 Equality collection: Option2
+3.4.3 Functional dependency propagation - option 1
+3.4.4 Functional dependency propagation - option 2
+4. Removal operation properties
+5. Removal operation
+6. User interface
+6.1 @@optimizer_switch flag
+6.2 EXPLAIN [EXTENDED]
+7. Miscellaneous adjustments
+7.1 Fix used_tables() of aggregate functions
+7.2 Make subquery predicates collect their outer references
+8. Other concerns
+8.1 Relationship with outer->inner joins converter
+8.2 Relationship with prepared statements
+8.3 Relationship with constant table detection
+9. Tests and benchmarks
</contents>
It's not really about elimination of tables, it's about elimination of inner
sides of outer joins.
-1. Conditions for removal
--------------------------
-We can eliminate an inner side of outer join if:
-1. For each record combination of outer tables, it will always produce
- exactly one record.
-2. There are no references to columns of the inner tables anywhere else in
+1. Elimination criteria
+=======================
+We can eliminate inner side of an outer join nest if:
+
+1. There are no references to columns of the inner tables anywhere else in
the query.
+2. For each record combination of outer tables, it will always produce
+ exactly one matching record combination.
+
+Most of effort in this WL entry is checking these two conditions.
-#1 means that every table inside the outer join nest is:
- - is a constant table:
- = because it can be accessed via eq_ref(const) access, or
- = it is a zero-rows or one-row MyISAM-like table [MARK1]
- - has an eq_ref access method candidate.
-
-#2 means that WHERE clause, ON clauses of embedding outer joins, ORDER BY,
- GROUP BY and HAVING do not refer to the inner tables of the outer join
- nest.
-
-1.1 Quick check if there are candidates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Before we start to enumerate join nests, here is a quick way to check if
-there *can be* something to be removed:
+2. No outside references check
+==============================
+Criterion #1 means that the WHERE clause, ON clauses of embedding/subsequent
+outer joins, ORDER BY, GROUP BY and HAVING must have no references to inner
+tables of the outer join nest we're trying to remove.
+
+For multi-table UPDATE/DELETE we also must not remove tables that we're
+updating/deleting from or tables that are used in UPDATE's SET clause.
+
+2.1 Quick check if there are tables with no outside references
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Before we start searching for outer join nests that could be eliminated,
+we'll do a quick and cheap check if there possibly could be something that
+could be eliminated:
- if ((tables used in select_list |
+ if (there are outer joins &&
+ (tables used in select_list |
tables used in group/order by UNION |
- tables used in where) != bitmap_of_all_tables)
+ tables used in where) != bitmap_of_all_join_tables)
{
attempt table elimination;
}
-2. Removal operation properties
--------------------------------
-* There is always one way to remove (no choice to remove either this or that)
-* It is always better to remove as much tables as possible (at least within
- our cost model).
-Thus, no need for any cost calculations/etc. It's an unconditional rewrite.
-3. Removal operation
---------------------
-* Remove the outer join nest's nested join structure (i.e. get the
- outer join's TABLE_LIST object $OJ and remove it from $OJ->embedding,
- $OJ->embedding->nested_join. Update table_map's of all ancestor nested
- joins). [MARK2]
+3. One-match check
+==================
+We can eliminate inner side of outer join if it will always generate exactly
+one matching record combination.
-* Move the tables and their JOIN_TABs to front like it is done with const
- tables, with exception that if eliminated outer join nest was within
- another outer join nest, that shouldn't prevent us from moving away the
- eliminated tables.
+By definition of OUTER JOIN, a NULL-complemented record combination will be
+generated when the inner side of outer join has not produced any matches.
-* Update join->table_count and all-join-tables bitmap.
+What remains to be checked is that there is no possiblity that inner side of
+the outer join could produce more than one matching record combination.
-* That's it. Nothing else?
+We'll refer to one-match property as "functional dependency":
-4. User interface
------------------
-* We'll add an @@optimizer switch flag for table elimination. Tentative
- name: 'table_elimination'.
- (Note ^^ utility of the above questioned ^, as table elimination can never
- be worse than no elimination. We're leaning towards not adding the flag)
-
-* EXPLAIN will not show the removed tables at all. This will allow to check
- if tables were removed, and also will behave nicely with anchor model and
- VIEWs: stuff that user doesn't care about just won't be there.
+- A outer join nest is functionally dependent [wrt outer tables] if it will
+ produce one matching record combination per each record combination of
+ outer tables
-5. Tests and benchmarks
------------------------
-Create a benchmark in sql-bench which checks if the DBMS has table
-elimination.
-[According to Monty] Run
- - queries that would use elimination
- - queries that are very similar to one above (so that they would have same
- QEP, execution cost, etc) but cannot use table elimination.
-then compare run times and make a conclusion about whether dbms supports table
-elimination.
+- A table is functionally dependent wrt certain set of dependency tables, if
+ record combination of dependency tables uniquely identifies zero or one
+ matching record in the table
-6. Todo, issues to resolve
---------------------------
+- Definitions of functional dependency of keys (=column tuples) and columns are
+ apparent.
-6.1 To resolve
-~~~~~~~~~~~~~~
-- Relationship with prepared statements.
- On one hand, it's natural to desire to make table elimination a
- once-per-statement operation, like outer->inner join conversion. We'll have
- to limit the applicability by removing [MARK1] as that can change during
- lifetime of the statement.
-
- The other option is to do table elimination every time. This will require to
- rework operation [MARK2] to be undoable.
-
- I'm leaning towards doing the former. With anchor modeling, it is unlikely
- that we'll meet outer joins which have N inner tables of which some are 1-row
- MyISAM tables that do not have primary key.
-
-6.2 Resolved
-~~~~~~~~~~~~
-* outer->inner join conversion is not a problem for table elimination.
- We make outer->inner conversions based on predicates in WHERE. If the WHERE
- referred to an inner table (requirement for OJ->IJ conversion) then table
- elimination would not be applicable anyway.
-
-* For Multi-table UPDATEs/DELETEs, need to also analyze the SET clause:
- - affected tables must not be eliminated
- - tables that are used on the right side of the SET x=y assignments must
- not be eliminated either.
+Our goal is to prove that the entire join nest is functionally-dependent.
-* Aggregate functions used to report that they depend on all tables, that is,
+Join nest is functionally dependent (on the otside tables) if each of its
+elements (those can be either base tables or join nests) is functionally
+dependent.
- item_agg_func->used_tables() == (1ULL << join->tables) - 1
+Functional dependency is transitive: if table A is f-dependent on the outer
+tables and table B is f.dependent on {A, outer_tables} then B is functionally
+dependent on the outer tables.
+
+Subsequent sections list cases when we can declare a table to be
+functionally-dependent.
+
+3.1 Functional dependency source #1: Potential eq_ref access
+------------------------------------------------------------
+This is the most practically-important case. Taking the example from the HLD
+of this WL entry:
+
+ select
+ A.colA
+ from
+ tableA A
+ left outer join
+ tableB B
+ on
+ B.id = A.id;
- always. Fixed it, now aggregate function reports it depends on
- tables that its arguments depend on. In particular, COUNT(*) reports
- that it depends on no tables (item_count_star->used_tables()==0).
- One consequence of that is that "item->used_tables()==0" is not
- equivalent to "item->const_item()==true" anymore (not sure if it's
- "anymore" or this has been already happening).
-
-* EXPLAIN EXTENDED warning text was generated after the JOIN object has
- been discarded. This didn't allow to use information about join plan
- when printing the warning. Fixed this by keeping the JOIN objects until
- we've printed the warning (have also an intent to remove the const
- tables from the join output).
-
-7. Additional issues
---------------------
-* We remove ON clauses within outer join nests. If these clauses contain
- subqueries, they probably should be gone from EXPLAIN output also?
- Yes. Current approach: when removing an outer join nest, walk the ON clause
- and mark subselects as eliminated. Then let EXPLAIN code check if the
- SELECT was eliminated before the printing (EXPLAIN is generated by doing
- a recursive descent, so the check will also cause children of eliminated
- selects not to be printed)
-
-* Table elimination is performed after constant table detection (but before
- the range analysis). Constant tables are technically different from
- eliminated ones (e.g. the former are shown in EXPLAIN and the latter aren't).
- Considering we've already done the join_read_const_table() call, is there any
- real difference between constant table and eliminated one? If there is, should
- we mark const tables also as eliminated?
- from user/EXPLAIN point of view: no. constant table is the one that we read
- one record from. eliminated table is the one that we don't acccess at all.
+and generalizing it: a table TBL is functionally-dependent if the ON
+expression allows to construct a potential eq_ref access to table TBL that
+uses only outer or functionally-dependent tables.
+
+In other words: table TBL will have one match if the ON expression can be
+converted into this form
+
+ TBL.unique_key=func(one_match_tables) AND .. remainder ...
+
+(with appropriate extension for multi-part keys), where
+
+ one_match_tables= {
+ tables that are not on the inner side of the outer join in question, and
+ functionally dependent tables
+ }
+
+Note that this will cover constant tables, except those that are constant because
+they have 0/1 record or are partitioned and have no used partitions.
+
+
+3.2 Functional dependency source #2: col2=func(col1)
+----------------------------------------------------
+This comes from the second example in the HLS:
-* What is described above will not be able to eliminate this outer join
create unique index idx on tableB (id, fromDate);
...
left outer join
@@ -169,32 +152,331 @@
B.fromDate = (select max(sub.fromDate)
from tableB sub where sub.id = A.id);
- This is because condition "B.fromDate= func(tableB)" cannot be used.
- Reason#1: update_ref_and_keys() does not consider such conditions to
- be of any use (and indeed they are not usable for ref access)
- so they are not put into KEYUSE array.
- Reason#2: even if they were put there, we would need to be able to tell
- between predicates like
- B.fromDate= func(B.id) // guarantees only one matching row as
- // B.id is already bound by B.id=A.id
- // hence B.fromDate becomes bound too.
- and
- "B.fromDate= func(B.*)" // Can potentially have many matching
- // records.
- We need to
- - Have update_ref_and_keys() create KEYUSE elements for such equalities
- - Have eliminate_tables() and friends make a more accurate check.
- The right check is to check whether all parts of a unique key are bound.
- If we have keypartX to be bound, then t.keypartY=func(keypartX) makes
- keypartY to be bound.
- The difficulty here is that correlated subquery predicate cannot tell what
- columns it depends on (it only remembers tables).
- Traversing the predicate is expensive and complicated.
- We're leaning towards making each subquery predicate have a List<Item> with
- items that
- - are in the current select
- - and it depends on.
- This list will be useful in certain other subquery optimizations as well,
- it is cheap to collect it in fix_fields() phase, so it will be collected
- for every subquery predicate.
+Here it is apparent that tableB can be eliminated. It is not possible to
+construct eq_ref access to tableB, though, because for the second part of the
+primary key (fromDate column) we only got a condition in this form:
+
+ B.fromDate= func(tableB)
+
+(we write "func(tableB)" because ref optimizer can only determine which tables
+the right part of the equality depends on).
+
+In general case, equality like this doesn't guarantee functional dependency.
+For example, if func() == { return fromDate;}, i.e the ON expression is
+
+ ... ON B.id = A.id and B.fromDate = B.fromDate
+
+then that would allow table B to have multiple matches per record of table A.
+
+In order to be able to distinguish between these two cases, we'll need to go
+down to column level:
+
+- A table is functionally dependent if it has a unique key that's functionally
+ dependent
+
+- A unique key is functionally dependent when all of its columns are
+ functionally dependent
+
+- A table column is functionally dependent if the ON clause allows to extract
+ an AND-part in this form:
+
+ tbl.column = f(functionally-dependent columns or columns of outer tables)
+
+3.3 Functional dependency source #3: One or zero records in the table
+---------------------------------------------------------------------
+A table with one or zero records cannot generate more than one matching
+record. This source is of lesser importance as one/zero-record tables are only
+MyISAM tables.
+
+3.4 Functional dependency check implementation
+----------------------------------------------
+As shown above, we need something similar to KEYUSE structures, but not
+exactly that (we need things that current ref optimizer considers unusable and
+don't need things that it considers usable).
+
+3.4.1 Equality collection: Option1
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We could
+- extend KEYUSE structures to store all kinds of equalities we need
+- change update_ref_and_keys() and co. to collect equalities both for ref
+ access and for table elimination
+ = [possibly] Improve [eq_]ref access to be able to use equalities in
+ form keypart2=func(keypart1)
+- process the KEYUSE array both by table elimination and by ref access
+ optimizer.
+
++ This requires less effort.
+- Code will have to be changed all over sql_select.cc
+- update_ref_and_keys() and co. already do several unrelated things. Hooking
+ up table elimination will make it even worse.
+
+3.4.2 Equality collection: Option2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Alternatively, we could process the WHERE clause totally on our own.
++ Table elimination is standalone and easy to detach module.
+- Some code duplication with update_ref_and_keys() and co.
+
+Having got the equalities, we'll to propagate functional dependency property
+to unique keys, tables and, ultimately, join nests.
+
+3.4.3 Functional dependency propagation - option 1
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Borrow the approach used in constant table detection code:
+
+ do
+ {
+ converted= FALSE;
+ for each table T in join nest
+ {
+ if (check_if_functionally_dependent(T))
+ converted= TRUE;
+ }
+ } while (converted == TRUE);
+
+ check_if_functionally_dependent(T)
+ {
+ if (T has eq_ref access based on func_dep_tables)
+ return TRUE;
+
+ Apply the same do-while loop-based approach to available equalities
+ T.column1=func(other columns)
+ to spread the set of functionally-dependent columns. The goal is to get
+ all columns of a certain unique key to be bound.
+ }
+
+
+3.4.4 Functional dependency propagation - option 2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Analyze the ON expression(s) and build a list of
+
+ tbl.field = expr(...)
+
+equalities. tbl here is a table that belongs to a join nest that could
+potentially be eliminated.
+
+besides those, add to the list
+ - An element for each unique key in the table that needs to be eliminated
+ - An element for each table that needs to be eliminated
+ - An element for each join nest that can be eliminated (i.e. has no
+ references from outside).
+
+Then, setup "reverse dependencies": each element should have pointers to
+elements that are functionally dependent on it:
+
+- "tbl.field=expr(...)" equality is functionally dependent on all fields that
+ are used in "expr(...)" (here we take into account only fields that belong
+ to tables that can potentially be eliminated).
+- a unique key is dependent on all of its components
+- a table is dependent on all of its unique keys
+- a join nest is dependent on all tables that it contains
+
+These pointers are stored in form of one bitmap, such that:
+
+ "X depends on Y" == test( bitmap[(X's number)*n_objects + (Y's number)] )
+
+Each object also stores a number of dependencies it needs to be satisfied
+before it itself is satisfied:
+
+- "tbl.field=expr(...)" needs all its underlying fields (if a field is
+ referenced many times it is counted only once)
+
+- a unique key needs all of its key parts
+
+- a table needs only one of its unique keys
+
+- a join nest needs all of its tables
+
+(TODO: so what do we do when we've marked a table as constant? We'll need to
+update the "field=expr(....)" elements that use fields of that table. And the
+problem is that we won't know how much to decrement from the counters of those
+elements.
+
+Solution#1: switch to table_map() based approach.
+Solution#2: introduce separate elements for each involved field.
+ field will depend on its table,
+ "field=expr" will depend on fields.
+)
+
+Besides the above, let each element have a pointer to another element, so that
+we can have a linked list of elements.
+
+After the above structures have been created, we start the main algorithm.
+
+The first step is to create a list of functionally-dependent elements. We walk
+across array of dependencies and mark those elements that are already bound
+(i.e. their dependencies are satisfied). At the moment those immediately-bound
+are only "field=expr" dependencies that don't refer to any columns that are
+not bound.
+
+The second step is the loop
+
+ while (bound_list is not empty)
+ {
+ Take the first bound element F off the list.
+ Use the bitmap to find out what other elements depended on it
+ for each such element E
+ {
+ if (E becomes bound after F is bound)
+ add E to the list;
+ }
+ }
+
+The last step is to walk through elements that represent the join nests. Those
+that are bound can be eliminated.
+
+4. Removal operation properties
+===============================
+* There is always one way to remove (no choice to remove either this or that)
+* It is always better to remove as much tables as possible (at least within
+ our cost model).
+Thus, no need for any cost calculations/etc. It's an unconditional rewrite.
+
+
+5. Removal operation
+====================
+(This depends a lot on whether we make table elimination a one-off rewrite or
+conditional)
+
+At the moment table elimination is re-done for each join re-execution, hence
+the removal operation is designed not to modify any statement's permanent
+members.
+
+* Remove the outer join nest's nested join structure (i.e. get the
+ outer join's TABLE_LIST object $OJ and remove it from $OJ->embedding,
+ $OJ->embedding->nested_join. Update table_map's of all ancestor nested
+ joins). [MARK2]
+
+* Move the tables and their JOIN_TABs to the front of join order, like it is
+ done with const tables, with exception that if eliminated outer join nest
+ was within another outer join nest, that shouldn't prevent us from moving
+ away the eliminated tables.
+
+* Update join->table_count and all-join-tables bitmap.
+ ^ TODO: not true anymore ^
+
+* That's it. Nothing else?
+
+6. User interface
+=================
+
+6.1 @@optimizer_switch flag
+---------------------------
+Argument againist adding the flag:
+* It is always better to perform table elimination than not to do it.
+
+Arguments for the flag:
+* It is always theoretically possible that the new code will cause unintended
+ slowdowns.
+* Having the flag is useful for QA and comparative benchmarking.
+
+Decision so far: add the flag under #ifdef. Make the flag be present in debug
+builds.
+
+6.2 EXPLAIN [EXTENDED]
+----------------------
+There are two possible options:
+1. Show eliminated tables, like we do with const tables.
+2. Do not show eliminated tables.
+
+We chose option 2, because:
+- the table is not accessed at all (besides locking it)
+- it is more natural for anchor model user - when he's querying an anchor-
+ and attributes view, he doesn't care about the unused attributes.
+
+EXPLAIN EXTENDED+SHOW WARNINGS won't show the removed table either.
+
+NOTE: Before this WL, the warning text was generated after all JOIN objects
+have been destroyed. This didn't allow to use information about join plan
+when printing the warning. We've fixed this by keeping the JOIN objects until
+the warning text has been generated.
+
+Table elimination removes inner sides of outer join, and logically the ON
+clause is also removed. If this clause has any subqueries, they will be
+also removed from EXPLAIN output.
+
+An exception to the above is that if we eliminate a derived table, it will
+still be shown in EXPLAIN output. This comes from the fact that the FROM
+subqueries are evaluated before table elimination is invoked.
+TODO: Is the above ok or still remove parts of FROM subqueries?
+
+7. Miscellaneous adjustments
+============================
+
+7.1 Fix used_tables() of aggregate functions
+--------------------------------------------
+Aggregate functions used to report that they depend on all tables, that is,
+
+ item_agg_func->used_tables() == (1ULL << join->tables) - 1
+
+always. Fixed it, now aggregate function reports that it depends on the
+tables that its arguments depend on. In particular, COUNT(*) reports that it
+depends on no tables (item_count_star->used_tables()==0). One consequence of
+that is that "item->used_tables()==0" is not equivalent to
+"item->const_item()==true" anymore (not sure if it's "anymore" or this has
+been already so for some items).
+
+7.2 Make subquery predicates collect their outer references
+-----------------------------------------------------------
+Per-column functional dependency analysis requires us to take a
+
+ tbl.field = func(...)
+
+equality and tell which columns of which tables are referred from func(...)
+expression. For scalar expressions, this is accomplished by Item::walk()-based
+traversal. It should be reasonably cheap (the only practical Item that can be
+expensive to traverse seems to be a special case of "col IN (const1,const2,
+...)". check if we traverse the long list for such items).
+
+For correlated subqueries, traversal can be expensive, it is cheaper to make
+each subquery item have a list of its outer references. The list can be
+collected at fix_fields() stage with very little extra cost, and then it could
+be used for other optimizations.
+
+
+8. Other concerns
+=================
+
+8.1 Relationship with outer->inner joins converter
+--------------------------------------------------
+One could suspect that outer->inner join conversion could get in the way
+of table elimination by changing outer joins (which could be eliminated)
+to inner (which we will not try to eliminate).
+This concern is not valid: we make outer->inner conversions based on
+predicates in WHERE. If the WHERE referred to an inner table (this is a
+requirement for the conversion) then table elimination would not be
+applicable anyway.
+
+8.2 Relationship with prepared statements
+-----------------------------------------
+On one hand, it's natural to desire to make table elimination a
+once-per-statement operation, like outer->inner join conversion. We'll have
+to limit the applicability by removing [MARK1] as that can change during
+lifetime of the statement.
+
+The other option is to do table elimination every time. This will require to
+rework operation [MARK2] to be undoable.
+
+
+8.3 Relationship with constant table detection
+----------------------------------------------
+Table elimination is performed after constant table detection (but before
+the range analysis). Constant tables are technically different from
+eliminated ones (e.g. the former are shown in EXPLAIN and the latter aren't).
+Considering we've already done the join_read_const_table() call, is there any
+real difference between constant table and eliminated one? If there is, should
+we mark const tables also as eliminated?
+from user/EXPLAIN point of view: no. constant table is the one that we read
+one record from. eliminated table is the one that we don't acccess at all.
+TODO
+
+9. Tests and benchmarks
+=======================
+Create a benchmark in sql-bench which checks if the DBMS has table
+elimination.
+[According to Monty] Run
+ - query Q1 that would use elimination
+ - query Q2 that is very similar to Q1 (so that they would have same
+ QEP, execution cost, etc) but cannot use table elimination.
+then compare run times and make a conclusion about whether the used dbms
+supports table elimination.
-=-=(Guest - Thu, 23 Jul 2009, 20:07)=-=-
Dependency created: 29 now depends on 17
-=-=(Monty - Thu, 23 Jul 2009, 09:19)=-=-
Version updated.
--- /tmp/wklog.17.old.24090 2009-07-23 09:19:32.000000000 +0300
+++ /tmp/wklog.17.new.24090 2009-07-23 09:19:32.000000000 +0300
@@ -1 +1 @@
-Server-9.x
+Server-5.1
-=-=(Guest - Mon, 20 Jul 2009, 14:28)=-=-
deukje weg
Worked 1 hour and estimate 3 hours remain (original estimate increased by 4 hours).
------------------------------------------------------------
-=-=(View All Progress Notes, 32 total)=-=-
http://askmonty.org/worklog/index.pl?tid=17&nolimit=1
DESCRIPTION:
Eliminate not needed tables from SELECT queries..
This will speed up some views and automatically generated queries.
Example:
CREATE TABLE B (id int primary key);
select
A.colA
from
tableA A
left outer join
tableB B
on
B.id = A.id;
In this case we can remove table B and the join from the query.
HIGH-LEVEL SPECIFICATION:
Here is an extended explanation of table elimination.
Table elimination is a feature found in some modern query optimizers, of
which Microsoft SQL Server 2005/2008 seems to have the most advanced
implementation. Oracle 11g has also been confirmed to use table
elimination but not to the same extent.
Basically, what table elimination does, is to remove tables from the
execution plan when it is unnecessary to include them. This can, of
course, only happen if the right circumstances arise. Let us for example
look at the following query:
select
A.colA
from
tableA A
left outer join
tableB B
on
B.id = A.id;
When using A as the left table we ensure that the query will return at
least as many rows as there are in that table. For rows where the join
condition (B.id = A.id) is not met the selected column (A.colA) will
still contain it's original value. The not seen B.* row would contain all NULL:s.
However, the result set could actually contain more rows than what is
found in tableA if there are duplicates of the column B.id in tableB. If
A contains a row [1, "val1"] and B the rows [1, "other1a"],[1, "other1b"]
then two rows will match in the join condition. The only way to know
what the result will look like is to actually touch both tables during
execution.
Instead, let's say that tableB contains rows that make it possible to
place a unique constraint on the column B.id, for example and often the
case a primary key. In this situation we know that we will get exactly
as many rows as there are in tableA, since joining with tableB cannot
introduce any duplicates. If further, as in the example query, we do not
select any columns from tableB, touching that table during execution is
unnecessary. We can remove the whole join operation from the execution
plan.
Both SQL Server 2005/2008 and Oracle 11g will deploy table elimination
in the case described above. Let us look at a more advanced query, where
Oracle fails.
select
A.colA
from
tableA A
left outer join
tableB B
on
B.id = A.id
and
B.fromDate = (
select
max(sub.fromDate)
from
tableB sub
where
sub.id = A.id
);
In this example we have added another join condition, which ensures
that we only pick the matching row from tableB having the latest
fromDate. In this case tableB will contain duplicates of the column
B.id, so in order to ensure uniqueness the primary key has to contain
the fromDate column as well. In other words the primary key of tableB
is (B.id, B.fromDate).
Furthermore, since the subselect ensures that we only pick the latest
B.fromDate for a given B.id we know that at most one row will match
the join condition. We will again have the situation where joining
with tableB cannot affect the number of rows in the result set. Since
we do not select any columns from tableB, the whole join operation can
be eliminated from the execution plan.
SQL Server 2005/2008 will deploy table elimination in this situation as
well. We have not found a way to make Oracle 11g use it for this type of
query. Queries like these arise in two situations. Either when you have
denormalized model consisting of a fact table with several related
dimension tables, or when you have a highly normalized model where each
attribute is stored in its own table. The example with the subselect is
common whenever you store historized/versioned data.
LOW-LEVEL DESIGN:
The code (currently in development) is at lp:
~maria-captains/maria/maria-5.1-table-elimination tree.
<contents>
1. Elimination criteria
2. No outside references check
2.1 Quick check if there are tables with no outside references
3. One-match check
3.1 Functional dependency source #1: Potential eq_ref access
3.2 Functional dependency source #2: col2=func(col1)
3.3 Functional dependency source #3: One or zero records in the table
3.4 Functional dependency check implementation
3.4.1 Equality collection: Option1
3.4.2 Equality collection: Option2
3.4.3 Functional dependency propagation - option 1
3.4.4 Functional dependency propagation - option 2
4. Removal operation properties
5. Removal operation
6. User interface
6.1 @@optimizer_switch flag
6.2 EXPLAIN [EXTENDED]
7. Miscellaneous adjustments
7.1 Fix used_tables() of aggregate functions
7.2 Make subquery predicates collect their outer references
8. Other concerns
8.1 Relationship with outer->inner joins converter
8.2 Relationship with prepared statements
8.3 Relationship with constant table detection
9. Tests and benchmarks
</contents>
It's not really about elimination of tables, it's about elimination of inner
sides of outer joins.
1. Elimination criteria
=======================
We can eliminate inner side of an outer join nest if:
1. There are no references to columns of the inner tables anywhere else in
the query.
2. For each record combination of outer tables, it will always produce
exactly one matching record combination.
Most of effort in this WL entry is checking these two conditions.
2. No outside references check
==============================
Criterion #1 means that the WHERE clause, ON clauses of embedding/subsequent
outer joins, ORDER BY, GROUP BY and HAVING must have no references to inner
tables of the outer join nest we're trying to remove.
For multi-table UPDATE/DELETE we also must not remove tables that we're
updating/deleting from or tables that are used in UPDATE's SET clause.
2.1 Quick check if there are tables with no outside references
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before we start searching for outer join nests that could be eliminated,
we'll do a quick and cheap check if there possibly could be something that
could be eliminated:
if (there are outer joins &&
(tables used in select_list |
tables used in group/order by UNION |
tables used in where) != bitmap_of_all_join_tables)
{
attempt table elimination;
}
3. One-match check
==================
We can eliminate inner side of outer join if it will always generate exactly
one matching record combination.
By definition of OUTER JOIN, a NULL-complemented record combination will be
generated when the inner side of outer join has not produced any matches.
What remains to be checked is that there is no possiblity that inner side of
the outer join could produce more than one matching record combination.
We'll refer to one-match property as "functional dependency":
- A outer join nest is functionally dependent [wrt outer tables] if it will
produce one matching record combination per each record combination of
outer tables
- A table is functionally dependent wrt certain set of dependency tables, if
record combination of dependency tables uniquely identifies zero or one
matching record in the table
- Definitions of functional dependency of keys (=column tuples) and columns are
apparent.
Our goal is to prove that the entire join nest is functionally-dependent.
Join nest is functionally dependent (on the otside tables) if each of its
elements (those can be either base tables or join nests) is functionally
dependent.
Functional dependency is transitive: if table A is f-dependent on the outer
tables and table B is f.dependent on {A, outer_tables} then B is functionally
dependent on the outer tables.
Subsequent sections list cases when we can declare a table to be
functionally-dependent.
3.1 Functional dependency source #1: Potential eq_ref access
------------------------------------------------------------
This is the most practically-important case. Taking the example from the HLD
of this WL entry:
select
A.colA
from
tableA A
left outer join
tableB B
on
B.id = A.id;
and generalizing it: a table TBL is functionally-dependent if the ON
expression allows to construct a potential eq_ref access to table TBL that
uses only outer or functionally-dependent tables.
In other words: table TBL will have one match if the ON expression can be
converted into this form
TBL.unique_key=func(one_match_tables) AND .. remainder ...
(with appropriate extension for multi-part keys), where
one_match_tables= {
tables that are not on the inner side of the outer join in question, and
functionally dependent tables
}
Note that this will cover constant tables, except those that are constant because
they have 0/1 record or are partitioned and have no used partitions.
3.2 Functional dependency source #2: col2=func(col1)
----------------------------------------------------
This comes from the second example in the HLS:
create unique index idx on tableB (id, fromDate);
...
left outer join
tableB B
on
B.id = A.id
and
B.fromDate = (select max(sub.fromDate)
from tableB sub where sub.id = A.id);
Here it is apparent that tableB can be eliminated. It is not possible to
construct eq_ref access to tableB, though, because for the second part of the
primary key (fromDate column) we only got a condition in this form:
B.fromDate= func(tableB)
(we write "func(tableB)" because ref optimizer can only determine which tables
the right part of the equality depends on).
In general case, equality like this doesn't guarantee functional dependency.
For example, if func() == { return fromDate;}, i.e the ON expression is
... ON B.id = A.id and B.fromDate = B.fromDate
then that would allow table B to have multiple matches per record of table A.
In order to be able to distinguish between these two cases, we'll need to go
down to column level:
- A table is functionally dependent if it has a unique key that's functionally
dependent
- A unique key is functionally dependent when all of its columns are
functionally dependent
- A table column is functionally dependent if the ON clause allows to extract
an AND-part in this form:
tbl.column = f(functionally-dependent columns or columns of outer tables)
3.3 Functional dependency source #3: One or zero records in the table
---------------------------------------------------------------------
A table with one or zero records cannot generate more than one matching
record. This source is of lesser importance as one/zero-record tables are only
MyISAM tables.
3.4 Functional dependency check implementation
----------------------------------------------
As shown above, we need something similar to KEYUSE structures, but not
exactly that (we need things that current ref optimizer considers unusable and
don't need things that it considers usable).
3.4.1 Equality collection: Option1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We could
- extend KEYUSE structures to store all kinds of equalities we need
- change update_ref_and_keys() and co. to collect equalities both for ref
access and for table elimination
= [possibly] Improve [eq_]ref access to be able to use equalities in
form keypart2=func(keypart1)
- process the KEYUSE array both by table elimination and by ref access
optimizer.
+ This requires less effort.
- Code will have to be changed all over sql_select.cc
- update_ref_and_keys() and co. already do several unrelated things. Hooking
up table elimination will make it even worse.
3.4.2 Equality collection: Option2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Alternatively, we could process the WHERE clause totally on our own.
+ Table elimination is standalone and easy to detach module.
- Some code duplication with update_ref_and_keys() and co.
Having got the equalities, we'll to propagate functional dependency property
to unique keys, tables and, ultimately, join nests.
3.4.3 Functional dependency propagation - option 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Borrow the approach used in constant table detection code:
do
{
converted= FALSE;
for each table T in join nest
{
if (check_if_functionally_dependent(T))
converted= TRUE;
}
} while (converted == TRUE);
check_if_functionally_dependent(T)
{
if (T has eq_ref access based on func_dep_tables)
return TRUE;
Apply the same do-while loop-based approach to available equalities
T.column1=func(other columns)
to spread the set of functionally-dependent columns. The goal is to get
all columns of a certain unique key to be bound.
}
3.4.4 Functional dependency propagation - option 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Analyze the ON expression(s) and build a list of
tbl.field = expr(...)
equalities. tbl here is a table that belongs to a join nest that could
potentially be eliminated.
besides those, add to the list
- An element for each unique key in the table that needs to be eliminated
- An element for each table that needs to be eliminated
- An element for each join nest that can be eliminated (i.e. has no
references from outside).
Then, setup "reverse dependencies": each element should have pointers to
elements that are functionally dependent on it:
- "tbl.field=expr(...)" equality is functionally dependent on all fields that
are used in "expr(...)" (here we take into account only fields that belong
to tables that can potentially be eliminated).
- a unique key is dependent on all of its components
- a table is dependent on all of its unique keys
- a join nest is dependent on all tables that it contains
These pointers are stored in form of one bitmap, such that:
"X depends on Y" == test( bitmap[(X's number)*n_objects + (Y's number)] )
Each object also stores a number of dependencies it needs to be satisfied
before it itself is satisfied:
- "tbl.field=expr(...)" needs all its underlying fields (if a field is
referenced many times it is counted only once)
- a unique key needs all of its key parts
- a table needs only one of its unique keys
- a join nest needs all of its tables
(TODO: so what do we do when we've marked a table as constant? We'll need to
update the "field=expr(....)" elements that use fields of that table. And the
problem is that we won't know how much to decrement from the counters of those
elements.
Solution#1: switch to table_map() based approach.
Solution#2: introduce separate elements for each involved field.
field will depend on its table,
"field=expr" will depend on fields.
)
Besides the above, let each element have a pointer to another element, so that
we can have a linked list of elements.
After the above structures have been created, we start the main algorithm.
The first step is to create a list of functionally-dependent elements. We walk
across array of dependencies and mark those elements that are already bound
(i.e. their dependencies are satisfied). At the moment those immediately-bound
are only "field=expr" dependencies that don't refer to any columns that are
not bound.
The second step is the loop
while (bound_list is not empty)
{
Take the first bound element F off the list.
Use the bitmap to find out what other elements depended on it
for each such element E
{
if (E becomes bound after F is bound)
add E to the list;
}
}
The last step is to walk through elements that represent the join nests. Those
that are bound can be eliminated.
4. Removal operation properties
===============================
* There is always one way to remove (no choice to remove either this or that)
* It is always better to remove as much tables as possible (at least within
our cost model).
Thus, no need for any cost calculations/etc. It's an unconditional rewrite.
5. Removal operation
====================
(This depends a lot on whether we make table elimination a one-off rewrite or
conditional)
At the moment table elimination is re-done for each join re-execution, hence
the removal operation is designed not to modify any statement's permanent
members.
* Remove the outer join nest's nested join structure (i.e. get the
outer join's TABLE_LIST object $OJ and remove it from $OJ->embedding,
$OJ->embedding->nested_join. Update table_map's of all ancestor nested
joins). [MARK2]
* Move the tables and their JOIN_TABs to the front of join order, like it is
done with const tables, with exception that if eliminated outer join nest
was within another outer join nest, that shouldn't prevent us from moving
away the eliminated tables.
* Update join->table_count and all-join-tables bitmap.
^ TODO: not true anymore ^
* That's it. Nothing else?
6. User interface
=================
6.1 @@optimizer_switch flag
---------------------------
Argument againist adding the flag:
* It is always better to perform table elimination than not to do it.
Arguments for the flag:
* It is always theoretically possible that the new code will cause unintended
slowdowns.
* Having the flag is useful for QA and comparative benchmarking.
Decision so far: add the flag under #ifdef. Make the flag be present in debug
builds.
6.2 EXPLAIN [EXTENDED]
----------------------
There are two possible options:
1. Show eliminated tables, like we do with const tables.
2. Do not show eliminated tables.
We chose option 2, because:
- the table is not accessed at all (besides locking it)
- it is more natural for anchor model user - when he's querying an anchor-
and attributes view, he doesn't care about the unused attributes.
EXPLAIN EXTENDED+SHOW WARNINGS won't show the removed table either.
NOTE: Before this WL, the warning text was generated after all JOIN objects
have been destroyed. This didn't allow to use information about join plan
when printing the warning. We've fixed this by keeping the JOIN objects until
the warning text has been generated.
Table elimination removes inner sides of outer join, and logically the ON
clause is also removed. If this clause has any subqueries, they will be
also removed from EXPLAIN output.
An exception to the above is that if we eliminate a derived table, it will
still be shown in EXPLAIN output. This comes from the fact that the FROM
subqueries are evaluated before table elimination is invoked.
TODO: Is the above ok or still remove parts of FROM subqueries?
7. Miscellaneous adjustments
============================
7.1 Fix used_tables() of aggregate functions
--------------------------------------------
Aggregate functions used to report that they depend on all tables, that is,
item_agg_func->used_tables() == (1ULL << join->tables) - 1
always. Fixed it, now aggregate function reports that it depends on the
tables that its arguments depend on. In particular, COUNT(*) reports that it
depends on no tables (item_count_star->used_tables()==0). One consequence of
that is that "item->used_tables()==0" is not equivalent to
"item->const_item()==true" anymore (not sure if it's "anymore" or this has
been already so for some items).
7.2 Make subquery predicates collect their outer references
-----------------------------------------------------------
Per-column functional dependency analysis requires us to take a
tbl.field = func(...)
equality and tell which columns of which tables are referred from func(...)
expression. For scalar expressions, this is accomplished by Item::walk()-based
traversal. It should be reasonably cheap (the only practical Item that can be
expensive to traverse seems to be a special case of "col IN (const1,const2,
...)". check if we traverse the long list for such items).
For correlated subqueries, traversal can be expensive, it is cheaper to make
each subquery item have a list of its outer references. The list can be
collected at fix_fields() stage with very little extra cost, and then it could
be used for other optimizations.
8. Other concerns
=================
8.1 Relationship with outer->inner joins converter
--------------------------------------------------
One could suspect that outer->inner join conversion could get in the way
of table elimination by changing outer joins (which could be eliminated)
to inner (which we will not try to eliminate).
This concern is not valid: we make outer->inner conversions based on
predicates in WHERE. If the WHERE referred to an inner table (this is a
requirement for the conversion) then table elimination would not be
applicable anyway.
8.2 Relationship with prepared statements
-----------------------------------------
On one hand, it's natural to desire to make table elimination a
once-per-statement operation, like outer->inner join conversion. We'll have
to limit the applicability by removing [MARK1] as that can change during
lifetime of the statement.
The other option is to do table elimination every time. This will require to
rework operation [MARK2] to be undoable.
8.3 Relationship with constant table detection
----------------------------------------------
Table elimination is performed after constant table detection (but before
the range analysis). Constant tables are technically different from
eliminated ones (e.g. the former are shown in EXPLAIN and the latter aren't).
Considering we've already done the join_read_const_table() call, is there any
real difference between constant table and eliminated one? If there is, should
we mark const tables also as eliminated?
from user/EXPLAIN point of view: no. constant table is the one that we read
one record from. eliminated table is the one that we don't acccess at all.
TODO
9. Tests and benchmarks
=======================
Create a benchmark in sql-bench which checks if the DBMS has table
elimination.
[According to Monty] Run
- query Q1 that would use elimination
- query Q2 that is very similar to Q1 (so that they would have same
QEP, execution cost, etc) but cannot use table elimination.
then compare run times and make a conclusion about whether the used dbms
supports table elimination.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2746)
by Igor Babaev 01 Apr '10
by Igor Babaev 01 Apr '10
01 Apr '10
#At lp:maria/5.2 based on revid:igor@askmonty.org-20100331231003-9gvmv2y8384kbqfa
2746 Igor Babaev 2010-03-31
Made the results of the key_cache test to be platform independent.
modified:
mysql-test/r/key_cache.result
mysql-test/t/key_cache.test
=== modified file 'mysql-test/r/key_cache.result'
--- a/mysql-test/r/key_cache.result 2010-03-31 18:45:41 +0000
+++ b/mysql-test/r/key_cache.result 2010-03-31 23:37:28 +0000
@@ -388,7 +388,7 @@ i int, a char(10), key k1(i), key k2(a))
select @@key_cache_partitions;
@@key_cache_partitions
0
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default NULL NULL 2097152 1024 0 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
@@ -416,18 +416,18 @@ Key_read_requests 22
Key_reads 0
Key_write_requests 26
Key_writes 6
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default NULL NULL 2097152 1024 4 # 0 22 0 26 6
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
delete from t2 where a='zzzz';
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default NULL NULL 2097152 1024 4 # 0 29 0 32 9
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
delete from t1;
delete from t2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default NULL NULL 2097152 1024 4 # 0 29 0 32 9
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
@@ -435,10 +435,8 @@ set global key_cache_partitions=2;
select @@key_cache_partitions;
@@key_cache_partitions
2
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 1048576 1024 0 # 0 0 0 0 0
-default 2 2 1048576 1024 0 # 0 0 0 0 0
default 2 NULL 2097152 1024 0 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
@@ -465,27 +463,22 @@ Key_read_requests 22
Key_reads 0
Key_write_requests 26
Key_writes 6
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 1048576 1024 # # 0 10 0 13 4
-default 2 2 1048576 1024 # # 0 12 0 13 2
-default 2 NULL 2097152 1024 # # 0 22 0 26 6
-small NULL NULL 1048576 1024 # # 0 1 0 2 1
+default 2 NULL 2097152 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
delete from t1;
delete from t2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 1048576 1024 # # 0 10 0 13 4
-default 2 2 1048576 1024 # # 0 12 0 13 2
-default 2 NULL 2097152 1024 # # 0 22 0 26 6
-small NULL NULL 1048576 1024 # # 0 1 0 2 1
+default 2 NULL 2097152 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
set global key_cache_partitions=1;
select @@key_cache_partitions;
@@key_cache_partitions
1
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 1 1 2097152 1024 0 # 0 0 0 0 0
default 1 NULL 2097152 1024 0 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
@@ -512,23 +505,20 @@ Key_read_requests 22
Key_reads 0
Key_write_requests 26
Key_writes 6
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 1 1 2097152 1024 4 # 0 22 0 26 6
default 1 NULL 2097152 1024 4 # 0 22 0 26 6
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
delete from t1;
delete from t2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 1 1 2097152 1024 4 # 0 22 0 26 6
default 1 NULL 2097152 1024 4 # 0 22 0 26 6
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
flush tables;
flush status;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 1 1 2097152 1024 4 # 0 0 0 0 0
default 1 NULL 2097152 1024 4 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 0 0 0 0
set global key_buffer_size=32*1024;
@@ -539,10 +529,8 @@ set global key_cache_partitions=2;
select @@key_cache_partitions;
@@key_cache_partitions
2
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 0 # 0 0 0 0 0
-default 2 2 16384 1024 0 # 0 0 0 0 0
default 2 NULL 32768 1024 0 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 0 0 0 0
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
@@ -560,10 +548,8 @@ p i a
4 3 zzzz
update t1 set p=3 where p=1;
update t2 set i=2 where i=1;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 1 # 0 12 0 13 2
-default 2 2 16384 1024 3 # 0 10 0 13 4
default 2 NULL 32768 1024 4 # 0 22 0 26 6
small NULL NULL 1048576 1024 1 # 0 0 0 0 0
insert into t1(a) select a from t1;
@@ -582,10 +568,8 @@ insert into t2(i,a) select i,a from t2;
insert into t2(i,a) select i,a from t2;
insert into t2(i,a) select i,a from t2;
insert into t2(i,a) select i,a from t2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 1951 # 1976 43
-default 2 2 16384 1024 # # 0 4782 # 1708 60
default 2 NULL 32768 1024 # # 0 6733 # 3684 103
small NULL NULL 1048576 1024 # # 0 0 # 0 0
select * from t1 where p between 1010 and 1020 ;
@@ -603,20 +587,16 @@ p i a
1018 2 pppp
1019 2 yyyy
1020 3 zzzz
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 1954 # 1976 43
-default 2 2 16384 1024 # # 0 4796 # 1708 60
default 2 NULL 32768 1024 # # 0 6750 # 3684 103
small NULL NULL 1048576 1024 # # 0 0 # 0 0
flush tables;
flush status;
update t1 set a='zzzz' where a='qqqq';
update t2 set i=1 where i=2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 940 10 939 10
-default 2 2 16384 1024 # # 0 2136 8 613 8
default 2 NULL 32768 1024 # # 0 3076 18 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=256*1024;
@@ -627,29 +607,14 @@ set global keycache1.key_cache_partition
select @@keycache1.key_cache_partitions;
@@keycache1.key_cache_partitions
7
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 940 10 939 10
-default 2 2 16384 1024 # # 0 2136 8 613 8
default 2 NULL 32768 1024 # # 0 3076 18 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 37449 2048 # # 0 0 0 0 0
-keycache1 7 2 37449 2048 # # 0 0 0 0 0
-keycache1 7 3 37449 2048 # # 0 0 0 0 0
-keycache1 7 4 37449 2048 # # 0 0 0 0 0
-keycache1 7 5 37449 2048 # # 0 0 0 0 0
-keycache1 7 6 37449 2048 # # 0 0 0 0 0
-keycache1 7 7 37449 2048 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 0 0 0 0
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache1 7 1 37449 2048 0 # 0 0 0 0 0
-keycache1 7 2 37449 2048 0 # 0 0 0 0 0
-keycache1 7 3 37449 2048 0 # 0 0 0 0 0
-keycache1 7 4 37449 2048 0 # 0 0 0 0 0
-keycache1 7 5 37449 2048 0 # 0 0 0 0 0
-keycache1 7 6 37449 2048 0 # 0 0 0 0 0
-keycache1 7 7 37449 2048 0 # 0 0 0 0 0
keycache1 7 NULL 262143 2048 0 # 0 0 0 0 0
cache index t1 key (`primary`) in keycache1;
Table Op Msg_type Msg_text
@@ -682,61 +647,35 @@ id select_type table type possible_keys
select count(*) from t1, t2 where t1.p = t2.i;
count(*)
256
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 37449 2048 # # 0 2 1 0 0
-keycache1 7 2 37449 2048 # # 0 7 1 0 0
-keycache1 7 3 37449 2048 # # 0 0 0 0 0
-keycache1 7 4 37449 2048 # # 0 5 1 0 0
-keycache1 7 5 37449 2048 # # 0 0 0 0 0
-keycache1 7 6 37449 2048 # # 0 0 0 0 0
-keycache1 7 7 37449 2048 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 14 3 0 0
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache1 7 1 37449 2048 1 # 0 2 1 0 0
-keycache1 7 2 37449 2048 1 # 0 7 1 0 0
-keycache1 7 3 37449 2048 0 # 0 0 0 0 0
-keycache1 7 4 37449 2048 1 # 0 5 1 0 0
-keycache1 7 5 37449 2048 0 # 0 0 0 0 0
-keycache1 7 6 37449 2048 0 # 0 0 0 0 0
-keycache1 7 7 37449 2048 0 # 0 0 0 0 0
keycache1 7 NULL 262143 2048 3 # 0 14 3 0 0
cache index t2 in keycache1;
Table Op Msg_type Msg_text
test.t2 assign_to_keycache status OK
update t2 set p=p+3000, i=2 where a='qqqq';
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache1 7 1 37449 2048 3 # 0 44 3 43 2
-keycache1 7 2 37449 2048 4 # 0 61 4 51 1
-keycache1 7 3 37449 2048 4 # 0 177 4 176 3
-keycache1 7 4 37449 2048 4 # 0 122 4 119 3
-keycache1 7 5 37449 2048 4 # 0 840 4 335 4
-keycache1 7 6 37449 2048 3 # 0 627 3 133 3
-keycache1 7 7 37449 2048 3 # 0 211 3 214 3
keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19
set global keycache2.key_buffer_size=1024*1024;
cache index t2 in keycache2;
Table Op Msg_type Msg_text
test.t2 assign_to_keycache status OK
insert into t2 values (2000, 3, 'yyyy');
-select * from information_schema.key_caches where key_cache_name like "keycache2";
+select * from information_schema.key_caches where key_cache_name like "keycache2"
+ and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
keycache2 NULL NULL 1048576 1024 0 # 0 0 0 0 0
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache1 7 1 37449 2048 3 # 0 44 3 43 2
-keycache1 7 2 37449 2048 4 # 0 61 4 51 1
-keycache1 7 3 37449 2048 4 # 0 177 4 176 3
-keycache1 7 4 37449 2048 4 # 0 122 4 119 3
-keycache1 7 5 37449 2048 4 # 0 840 4 335 4
-keycache1 7 6 37449 2048 3 # 0 627 3 133 3
-keycache1 7 7 37449 2048 3 # 0 211 3 214 3
keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19
keycache2 NULL NULL 1048576 1024 0 # 0 0 0 0 0
cache index t2 in keycache1;
@@ -774,127 +713,77 @@ id select_type table type possible_keys
select a from t2 where a='yyyy' and i=3 ;
a
yyyy
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 37449 2048 # # 0 85 6 68 3
-keycache1 7 2 37449 2048 # # 0 122 6 102 2
-keycache1 7 3 37449 2048 # # 0 271 8 254 6
-keycache1 7 4 37449 2048 # # 0 179 6 170 4
-keycache1 7 5 37449 2048 # # 0 1445 7 416 6
-keycache1 7 6 37449 2048 # # 0 863 6 345 5
-keycache1 7 7 37449 2048 # # 0 236 4 239 4
keycache1 7 NULL 262143 2048 # # 0 3201 43 1594 30
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=2*1024;
insert into t2 values (7000, 3, 'yyyy');
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 37449 2048 # # 0 1 1 1 1
-keycache1 7 2 37449 2048 # # 0 1 1 0 0
-keycache1 7 3 37449 2048 # # 0 0 0 0 0
-keycache1 7 4 37449 2048 # # 0 1 1 1 1
-keycache1 7 5 37449 2048 # # 0 1 1 0 0
-keycache1 7 6 37449 2048 # # 0 2 2 1 1
-keycache1 7 7 37449 2048 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 6 6 3 3
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=8*1024;
insert into t2 values (8000, 3, 'yyyy');
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 3 1 87381 8192 # # 0 1 1 1 1
-keycache1 3 2 87381 8192 # # 0 3 2 1 1
-keycache1 3 3 87381 8192 # # 0 2 2 1 1
keycache1 3 NULL 262143 8192 # # 0 6 5 3 3
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=64*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=2*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 3 1 21845 2048 # # 0 0 0 0 0
-keycache1 3 2 21845 2048 # # 0 0 0 0 0
-keycache1 3 3 21845 2048 # # 0 0 0 0 0
keycache1 3 NULL 65535 2048 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=8*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=0;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=8*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=0;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=128*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 1 1 131072 8192 # # 0 0 0 0 0
keycache1 1 NULL 131072 8192 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 18724 1024 # # 0 0 0 0 0
-keycache1 7 2 18724 1024 # # 0 0 0 0 0
-keycache1 7 3 18724 1024 # # 0 0 0 0 0
-keycache1 7 4 18724 1024 # # 0 0 0 0 0
-keycache1 7 5 18724 1024 # # 0 0 0 0 0
-keycache1 7 6 18724 1024 # # 0 0 0 0 0
-keycache1 7 7 18724 1024 # # 0 0 0 0 0
keycache1 7 NULL 131068 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
drop table t1,t2;
=== modified file 'mysql-test/t/key_cache.test'
--- a/mysql-test/t/key_cache.test 2010-03-31 18:45:41 +0000
+++ b/mysql-test/t/key_cache.test 2010-03-31 23:37:28 +0000
@@ -272,7 +272,7 @@ create table t2 (
select @@key_cache_partitions;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
@@ -285,16 +285,16 @@ update t2 set i=2 where i=1;
--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
show status like 'key_%';
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
delete from t2 where a='zzzz';
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
delete from t1;
delete from t2;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
# For the key cache with 2 partitions execute the same sequence of
# statements as for the simple cache above.
@@ -304,7 +304,7 @@ select * from information_schema.key_cac
set global key_cache_partitions=2;
select @@key_cache_partitions;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
@@ -316,20 +316,20 @@ update t2 set i=2 where i=1;
--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
show status like 'key_%';
---replace_column 6 # 7 #
-select * from information_schema.key_caches;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
delete from t1;
delete from t2;
---replace_column 6 # 7 #
-select * from information_schema.key_caches;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
# Check that we can work with one partition with the same results
set global key_cache_partitions=1;
select @@key_cache_partitions;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
@@ -342,16 +342,16 @@ update t2 set i=2 where i=1;
--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
show status like 'key_%';
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
delete from t1;
delete from t2;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
flush tables; flush status;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
# Switch back to 2 partitions
@@ -360,7 +360,7 @@ select @@key_buffer_size;
set global key_cache_partitions=2;
select @@key_cache_partitions;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
@@ -371,7 +371,7 @@ update t1 set p=3 where p=1;
update t2 set i=2 where i=1;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
# Add more rows to tables t1 and t2
@@ -394,18 +394,18 @@ insert into t2(i,a) select i,a from t2;
insert into t2(i,a) select i,a from t2;
--replace_column 6 # 7 # 10 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
select * from t1 where p between 1010 and 1020 ;
select * from t2 where p between 1010 and 1020 ;
--replace_column 6 # 7 # 10 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
flush tables; flush status;
update t1 set a='zzzz' where a='qqqq';
update t2 set i=1 where i=2;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
# Now test how we can work with 7 partitions
@@ -415,9 +415,10 @@ set global keycache1.key_cache_partition
select @@keycache1.key_cache_partitions;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
cache index t1 key (`primary`) in keycache1;
@@ -429,22 +430,26 @@ explain select count(*) from t1, t2 wher
select count(*) from t1, t2 where t1.p = t2.i;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
cache index t2 in keycache1;
update t2 set p=p+3000, i=2 where a='qqqq';
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
set global keycache2.key_buffer_size=1024*1024;
cache index t2 in keycache2;
insert into t2 values (2000, 3, 'yyyy');
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "keycache2";
+select * from information_schema.key_caches where key_cache_name like "keycache2"
+ and partition_number is null;
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
cache index t2 in keycache1;
update t2 set p=p+5000 where a='zzzz';
@@ -456,49 +461,49 @@ select i from t2 where a='yyyy' and i=3;
explain select a from t2 where a='yyyy' and i=3;
select a from t2 where a='yyyy' and i=3 ;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=2*1024;
insert into t2 values (7000, 3, 'yyyy');
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=8*1024;
insert into t2 values (8000, 3, 'yyyy');
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_buffer_size=64*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=2*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=8*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_buffer_size=0;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=8*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_buffer_size=0;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_buffer_size=128*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
drop table t1,t2;
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2745)
by Igor Babaev 01 Apr '10
by Igor Babaev 01 Apr '10
01 Apr '10
#At lp:maria/5.2 based on revid:igor@askmonty.org-20100331184541-cigkg2yokjzve1mk
2745 Igor Babaev 2010-03-31 [merge]
Merge with the latest changes og 5.2.
removed:
include/mysql/plugin.h.pp
added:
include/mysql/client_plugin.h
include/mysql/client_plugin.h.pp
include/mysql/plugin_auth.h
include/mysql/plugin_auth.h.pp
include/mysql/plugin_auth_common.h
plugin/auth/
plugin/auth/Makefile.am
plugin/auth/auth_socket.c
plugin/auth/dialog.c
plugin/auth/plug.in
sql-common/client_plugin.c
modified:
.bzrignore
Makefile.am
client/CMakeLists.txt
client/Makefile.am
client/client_priv.h
client/mysql.cc
client/mysqltest.cc
config/ac-macros/plugins.m4
configure.in
include/Makefile.am
include/errmsg.h
include/m_ctype.h
include/my_global.h
include/my_no_pthread.h
include/my_sys.h
include/mysql.h
include/mysql.h.pp
include/mysql/plugin.h
include/mysql_com.h
include/sql_common.h
libmysql/CMakeLists.txt
libmysql/Makefile.shared
libmysql/client_settings.h
libmysql/errmsg.c
libmysql/libmysql.c
libmysqld/Makefile.am
libmysqld/embedded_priv.h
libmysqld/lib_sql.cc
libmysqld/libmysqld.c
mysql-test/mysql-test-run.pl
mysql-test/r/change_user.result
mysql-test/r/grant.result
mysql-test/r/grant2.result
mysql-test/r/ps.result
mysql-test/r/sp_notembedded.result
mysql-test/r/system_mysql_db.result
mysql-test/suite/funcs_1/r/is_columns_mysql.result
mysql-test/suite/funcs_1/r/is_user_privileges.result
mysql-test/suite/pbxt/r/grant.result
mysql-test/suite/rpl/r/rpl_ignore_table.result
mysql-test/suite/rpl/r/rpl_stm_000001.result
mysql-test/t/change_user.test
mysql-test/valgrind.supp
mysys/Makefile.am
scripts/mysql_system_tables.sql
scripts/mysql_system_tables_data.sql
scripts/mysql_system_tables_fix.sql
server-tools/instance-manager/Makefile.am
server-tools/instance-manager/user_map.cc
sql-common/Makefile.am
sql-common/client.c
sql/CMakeLists.txt
sql/Makefile.am
sql/client_settings.h
sql/ha_ndbcluster.cc
sql/ha_ndbcluster_binlog.cc
sql/lex.h
sql/mysql_priv.h
sql/mysqld.cc
sql/password.c
sql/protocol.cc
sql/protocol.h
sql/sql_acl.cc
sql/sql_acl.h
sql/sql_builtin.cc.in
sql/sql_class.cc
sql/sql_class.h
sql/sql_connect.cc
sql/sql_insert.cc
sql/sql_lex.h
sql/sql_parse.cc
sql/sql_plugin.cc
sql/sql_yacc.yy
sql/structs.h
sql/table.cc
storage/maria/ma_loghandler.c
storage/pbxt/src/ha_pbxt.cc
tests/mysql_client_test.c
=== modified file '.bzrignore'
--- a/.bzrignore 2010-02-01 06:14:12 +0000
+++ b/.bzrignore 2010-03-29 15:13:53 +0000
@@ -1931,3 +1931,6 @@ client/rpl_filter.cc
client/rpl_filter.h
client/sql_list.cc
client/sql_list.h
+libmysqld/client_plugin.c
+sql/client_plugin.c
+*.dgcov
=== modified file 'Makefile.am'
--- a/Makefile.am 2010-03-03 14:44:14 +0000
+++ b/Makefile.am 2010-03-29 15:13:53 +0000
@@ -140,14 +140,14 @@ smoke:
test-full: test test-nr test-ps
test-force:
- $(MAKE) force=--force test
+ $(MAKE) -k force=--force test
test-force-full:
- $(MAKE) force=--force test-full
+ $(MAKE) -k force=--force test-full
#used by autopush.pl to run memory based tests
test-force-mem:
- $(MAKE) force=--force mem=--mem test
+ $(MAKE) -k force=--force mem=--mem test
test-bt:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@@ -261,7 +261,7 @@ test-fast-prepare:
$(MAKE) subset=--ps-protocol test-fast
test-full-qa:
- $(MAKE) force=--force test-pr \
+ $(MAKE) -k force=--force test-pr \
test-binlog-statement test-ext test-fast-view \
test-fast-cursor test-unit
@@ -271,12 +271,13 @@ test-full-qa:
# after which TEST_PREPROCESSOR_HEADER will be used.
#
-API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \
- $(top_srcdir)/include/mysql.h
-
-TEST_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \
- $(top_srcdir)/sql/mysql_priv.h \
- $(top_srcdir)/include/mysql.h
+API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql.h \
+ $(top_srcdir)/include/mysql/client_plugin.h \
+ $(top_srcdir)/include/mysql/plugin_auth.h
+
+TEST_PREPROCESSOR_HEADER = $(API_PREPROCESSOR_HEADER) \
+ $(top_srcdir)/sql/mysql_priv.h
+
#
# Rules for checking that the abi/api has not changed.
=== modified file 'client/CMakeLists.txt'
--- a/client/CMakeLists.txt 2009-09-04 05:54:16 +0000
+++ b/client/CMakeLists.txt 2010-03-29 15:13:53 +0000
@@ -83,3 +83,5 @@ IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("echo" "asInvoker")
ENDIF(EMBED_MANIFESTS)
+ADD_DEFINITIONS(-DHAVE_DLOPEN)
+
=== modified file 'client/Makefile.am'
--- a/client/Makefile.am 2009-12-08 21:47:54 +0000
+++ b/client/Makefile.am 2010-03-29 15:13:53 +0000
@@ -100,8 +100,8 @@ mysql_upgrade_SOURCES= mysql_up
# Fix for mit-threads
DEFS = -DMYSQL_CLIENT_NO_THREADS \
- -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \
- -DMYSQL_DATADIR="\"$(localstatedir)\""
+ -DDEFAULT_MYSQL_HOME='"$(prefix)"' \
+ -DMYSQL_DATADIR='"$(localstatedir)"'
sql_src=log_event.h mysql_priv.h rpl_constants.h \
rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \
=== modified file 'client/client_priv.h'
--- a/client/client_priv.h 2010-03-15 11:51:23 +0000
+++ b/client/client_priv.h 2010-03-29 15:13:53 +0000
@@ -93,5 +93,7 @@ enum options_client
OPT_FIRST_SLAVE,
OPT_ALL,
OPT_REWRITE_DB,
- OPT_MAX_CLIENT_OPTION
+ OPT_PLUGIN_DIR,
+ OPT_DEFAULT_PLUGIN,
+ OPT_MAX_CLIENT_OPTION /* should be always the last */
};
=== modified file 'client/mysql.cc'
--- a/client/mysql.cc 2010-03-04 08:03:07 +0000
+++ b/client/mysql.cc 2010-03-29 15:13:53 +0000
@@ -167,6 +167,7 @@ static int wait_time = 5;
static STATUS status;
static ulong select_limit,max_join_size,opt_connect_timeout=0;
static char mysql_charsets_dir[FN_REFLEN+1];
+static char *opt_plugin_dir= 0, *opt_default_auth;
static const char *xmlmeta[] = {
"&", "&",
"<", "<",
@@ -1542,6 +1543,13 @@ static struct my_option my_long_options[
{"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
(uchar**) &show_warnings, (uchar**) &show_warnings, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_PLUGIN_DIR,
+ "Default authentication client-side plugin to use.",
+ (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -4238,6 +4246,56 @@ char *get_arg(char *line, my_bool get_ne
}
+/**
+ An example of mysql_authentication_dialog_ask callback.
+
+ The C function with the name "mysql_authentication_dialog_ask", if exists,
+ will be used by the "dialog" client authentication plugin when user
+ input is needed. This function should be of mysql_authentication_dialog_ask_t
+ type. If the function does not exists, a built-in implementation will be
+ used.
+
+ @param mysql mysql
+ @param type type of the input
+ 1 - normal string input
+ 2 - password string
+ @param prompt prompt
+ @param buf a buffer to store the use input
+ @param buf_len the length of the buffer
+
+ @retval a pointer to the user input string.
+ It may be equal to 'buf' or to 'mysql->password'.
+ In all other cases it is assumed to be an allocated
+ string, and the "dialog" plugin will free() it.
+*/
+
+extern "C" char *mysql_authentication_dialog_ask(MYSQL *mysql, int type,
+ const char *prompt,
+ char *buf, int buf_len)
+{
+ char *s=buf;
+
+ fputs("[mariadb] ", stdout);
+ fputs(prompt, stdout);
+ fputs(" ", stdout);
+
+ if (type == 2) /* password */
+ {
+ s= get_tty_password("");
+ strnmov(buf, s, buf_len);
+ buf[buf_len-1]= 0;
+ my_free(s, MYF(0));
+ }
+ else
+ {
+ fgets(buf, buf_len-1, stdin);
+ if (buf[0] && (s= strend(buf))[-1] == '\n')
+ s[-1]= 0;
+ }
+
+ return buf;
+}
+
static int
sql_real_connect(char *host,char *database,char *user,char *password,
uint silent)
@@ -4283,6 +4341,13 @@ sql_real_connect(char *host,char *databa
}
if (default_charset_used)
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
if (!mysql_real_connect(&mysql, host, user, password,
database, opt_mysql_port, opt_mysql_unix_port,
connect_flag | CLIENT_MULTI_STATEMENTS))
=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc 2010-01-28 14:49:14 +0000
+++ b/client/mysqltest.cc 2010-02-19 08:08:05 +0000
@@ -36,6 +36,7 @@
#include "client_priv.h"
#include <mysql_version.h>
#include <mysqld_error.h>
+#include <sql_common.h>
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
@@ -3610,13 +3611,15 @@ void do_change_user(struct st_command *c
}
if (!ds_user.length)
+ {
dynstr_set(&ds_user, mysql->user);
- if (!ds_passwd.length)
- dynstr_set(&ds_passwd, mysql->passwd);
+ if (!ds_passwd.length)
+ dynstr_set(&ds_passwd, mysql->passwd);
- if (!ds_db.length)
- dynstr_set(&ds_db, mysql->db);
+ if (!ds_db.length)
+ dynstr_set(&ds_db, mysql->db);
+ }
DBUG_PRINT("info",("connection: '%s' user: '%s' password: '%s' database: '%s'",
cur_con->name, ds_user.str, ds_passwd.str, ds_db.str));
=== modified file 'config/ac-macros/plugins.m4'
--- a/config/ac-macros/plugins.m4 2009-12-22 10:33:20 +0000
+++ b/config/ac-macros/plugins.m4 2010-03-29 15:14:28 +0000
@@ -38,6 +38,7 @@ AC_DEFUN([_MYSQL_PLUGIN],[
_MYSQL_PLUGAPPEND([__mysql_plugin_list__],[$1])
m4_define([MYSQL_PLUGIN_NAME_]AS_TR_CPP([$1]), [$3])
m4_define([MYSQL_PLUGIN_DESC_]AS_TR_CPP([$1]), [$4])
+ m4_ifdef([_AC_ENABLE_IF], [_AC_ENABLE_IF([with],[plugin-$1])])
_MYSQL_PLUGAPPEND_META([$1], $5)
ifelse(m4_bregexp(__mysql_include__,[/plug\.in$]),-1,[],[
MYSQL_PLUGIN_DIRECTORY([$1],
=== modified file 'configure.in'
--- a/configure.in 2010-03-18 12:08:39 +0000
+++ b/configure.in 2010-03-29 15:13:53 +0000
@@ -1605,9 +1605,8 @@ case "$with_mysqld_ldflags " in
;;
*)
- # Check for dlopen, needed for user definable functions
+ # Check for dlopen, needed for user definable functions and plugins
# This must be checked after threads on AIX
- # We only need this for mysqld, not for the clients.
my_save_LIBS="$LIBS"
LIBS=""
=== modified file 'include/Makefile.am'
--- a/include/Makefile.am 2010-03-03 14:44:14 +0000
+++ b/include/Makefile.am 2010-03-29 15:13:53 +0000
@@ -24,6 +24,8 @@ pkginclude_HEADERS = $(HEADERS_ABI) my_d
my_xml.h mysql_embed.h mysql/services.h \
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
my_pthread.h my_no_pthread.h \
+ mysql/plugin_auth.h mysql/client_plugin.h \
+ mysql/plugin_auth_common.h \
decimal.h errmsg.h my_global.h my_net.h \
my_getopt.h sslopt-longopts.h my_dir.h \
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
@@ -42,7 +44,7 @@ noinst_HEADERS = config-win.h config-net
atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \
atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \
wqueue.h waiting_threads.h
-EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp
+EXTRA_DIST = mysql.h.pp mysql/plugin_auth.h.pp mysql/client_plugin.h.pp
# Remove built files and the symlinked directories
CLEANFILES = $(BUILT_SOURCES) readline openssl
=== modified file 'include/errmsg.h'
--- a/include/errmsg.h 2008-05-20 16:36:26 +0000
+++ b/include/errmsg.h 2010-03-29 15:13:53 +0000
@@ -97,6 +97,7 @@ extern const char *client_errors[]; /* E
#define CR_SERVER_LOST_EXTENDED 2055
#define CR_STMT_CLOSED 2056
#define CR_NEW_STMT_METADATA 2057
-#define CR_ERROR_LAST /*Copy last error nr:*/ 2057
+#define CR_AUTH_PLUGIN_CANNOT_LOAD 2058
+#define CR_ERROR_LAST /*Copy last error nr:*/ 2058
/* Add error numbers before CR_ERROR_LAST and change it accordingly. */
=== modified file 'include/m_ctype.h'
--- a/include/m_ctype.h 2010-01-06 19:20:16 +0000
+++ b/include/m_ctype.h 2010-03-31 18:37:45 +0000
@@ -291,7 +291,7 @@ struct charset_info_st
const uint16 *const *sort_order_big;
const uint16 *tab_to_uni;
MY_UNI_IDX *tab_from_uni;
- const MY_UNICASE_INFO *const *caseinfo;
+ MY_UNICASE_INFO *const *caseinfo;
const uchar *state_map;
const uchar *ident_map;
uint strxfrm_multiply;
=== modified file 'include/my_global.h'
--- a/include/my_global.h 2010-03-10 10:32:14 +0000
+++ b/include/my_global.h 2010-03-29 15:13:53 +0000
@@ -578,6 +578,14 @@ int __void__;
#define IF_VALGRIND(A,B) (B)
#endif
+#ifdef _WIN32
+#define SO_EXT ".dll"
+#elif defined(__APPLE__)
+#define SO_EXT ".dylib"
+#else
+#define SO_EXT ".so"
+#endif
+
/*
Suppress uninitialized variable warning without generating code.
@@ -1522,10 +1530,12 @@ do { doubleget_union _tmp; \
#endif
#ifndef HAVE_DLERROR
-#define dlerror() ""
+#define dlerror() "No support for dynamic loading (static build?)"
+#define dlopen(A,B) 0
+#define dlsym(A,B) 0
+#define dlclose(A) 0
#endif
-
#ifndef __NETWARE__
/*
* Include standard definitions of operator new and delete.
=== modified file 'include/my_no_pthread.h'
--- a/include/my_no_pthread.h 2009-12-12 18:11:25 +0000
+++ b/include/my_no_pthread.h 2010-03-29 15:13:53 +0000
@@ -46,6 +46,7 @@
#define rw_wrlock(A)
#define rw_unlock(A)
#define rwlock_destroy(A)
+#define safe_mutex_assert_owner(mp)
typedef int my_pthread_once_t;
#define MY_PTHREAD_ONCE_INIT 0
=== modified file 'include/my_sys.h'
--- a/include/my_sys.h 2010-03-15 11:51:23 +0000
+++ b/include/my_sys.h 2010-03-29 15:13:53 +0000
@@ -210,7 +210,7 @@ extern void my_large_free(uchar * ptr, m
#define my_alloca(SZ) alloca((size_t) (SZ))
#define my_afree(PTR) {}
#else
-#define my_alloca(SZ) my_malloc(SZ,MYF(0))
+#define my_alloca(SZ) my_malloc(SZ,MYF(MY_FAE))
#define my_afree(PTR) my_free(PTR,MYF(MY_WME))
#endif /* HAVE_ALLOCA */
@@ -870,6 +870,10 @@ extern void set_prealloc_root(MEM_ROOT *
extern void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
size_t prealloc_size);
extern char *strdup_root(MEM_ROOT *root,const char *str);
+static inline char *safe_strdup_root(MEM_ROOT *root, const char *str)
+{
+ return str ? strdup_root(root, str) : 0;
+}
extern char *strmake_root(MEM_ROOT *root,const char *str,size_t len);
extern void *memdup_root(MEM_ROOT *root,const void *str, size_t len);
extern int get_defaults_options(int argc, char **argv,
=== modified file 'include/mysql.h'
--- a/include/mysql.h 2010-02-01 06:14:12 +0000
+++ b/include/mysql.h 2010-03-29 15:13:53 +0000
@@ -167,9 +167,15 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH
};
+/**
+ @todo remove the "extension", move st_mysql_options completely
+ out of mysql.h
+*/
+struct st_mysql_options_extention;
+
struct st_mysql_options {
unsigned int connect_timeout, read_timeout, write_timeout;
unsigned int port, protocol;
@@ -217,7 +223,7 @@ struct st_mysql_options {
void (*local_infile_end)(void *);
int (*local_infile_error)(void *, char *, unsigned int);
void *local_infile_userdata;
- void *extension;
+ struct st_mysql_options_extention *extension;
};
enum mysql_status
@@ -752,38 +758,6 @@ enum enum_stmt_attr_type
};
-typedef struct st_mysql_methods
-{
- my_bool (*read_query_result)(MYSQL *mysql);
- my_bool (*advanced_command)(MYSQL *mysql,
- enum enum_server_command command,
- const unsigned char *header,
- unsigned long header_length,
- const unsigned char *arg,
- unsigned long arg_length,
- my_bool skip_check,
- MYSQL_STMT *stmt);
- MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
- unsigned int fields);
- MYSQL_RES * (*use_result)(MYSQL *mysql);
- void (*fetch_lengths)(unsigned long *to,
- MYSQL_ROW column, unsigned int field_count);
- void (*flush_use_result)(MYSQL *mysql);
-#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)
- MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
- my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
- int (*stmt_execute)(MYSQL_STMT *stmt);
- int (*read_binary_rows)(MYSQL_STMT *stmt);
- int (*unbuffered_fetch)(MYSQL *mysql, char **row);
- void (*free_embedded_thd)(MYSQL *mysql);
- const char *(*read_statistics)(MYSQL *mysql);
- my_bool (*next_result)(MYSQL *mysql);
- int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
- int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
-#endif
-} MYSQL_METHODS;
-
-
MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql);
int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
unsigned long length);
@@ -846,18 +820,6 @@ int STDCALL mysql_drop_db(MYSQL *mysql,
#endif
#define HAVE_MYSQL_REAL_CONNECT
-/*
- The following functions are mainly exported because of mysqlbinlog;
- They are not for general usage
-*/
-
-#define simple_command(mysql, command, arg, length, skip_check) \
- (*(mysql)->methods->advanced_command)(mysql, command, 0, \
- 0, arg, length, skip_check, NULL)
-#define stmt_command(mysql, command, arg, length, stmt) \
- (*(mysql)->methods->advanced_command)(mysql, command, 0, \
- 0, arg, length, 1, stmt)
-
#ifdef __NETWARE__
#pragma pack(pop) /* restore alignment */
#endif
=== modified file 'include/mysql.h.pp'
--- a/include/mysql.h.pp 2010-03-15 11:51:23 +0000
+++ b/include/mysql.h.pp 2010-03-29 15:13:53 +0000
@@ -128,13 +128,13 @@ void create_random_string(char *to, unsi
void hash_password(unsigned long *to, const char *password, unsigned int password_len);
void make_scrambled_password_323(char *to, const char *password);
void scramble_323(char *to, const char *message, const char *password);
-my_bool check_scramble_323(const char *, const char *message,
+my_bool check_scramble_323(const unsigned char *reply, const char *message,
unsigned long *salt);
void get_salt_from_password_323(unsigned long *res, const char *password);
void make_password_from_salt_323(char *to, const unsigned long *salt);
void make_scrambled_password(char *to, const char *password);
void scramble(char *to, const char *message, const char *password);
-my_bool check_scramble(const char *reply, const char *message,
+my_bool check_scramble(const unsigned char *reply, const char *message,
const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password);
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
@@ -258,8 +258,9 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH
};
+struct st_mysql_options_extention;
struct st_mysql_options {
unsigned int connect_timeout, read_timeout, write_timeout;
unsigned int port, protocol;
@@ -289,7 +290,7 @@ struct st_mysql_options {
void (*local_infile_end)(void *);
int (*local_infile_error)(void *, char *, unsigned int);
void *local_infile_userdata;
- void *extension;
+ struct st_mysql_options_extention *extension;
};
enum mysql_status
{
@@ -601,34 +602,6 @@ enum enum_stmt_attr_type
STMT_ATTR_CURSOR_TYPE,
STMT_ATTR_PREFETCH_ROWS
};
-typedef struct st_mysql_methods
-{
- my_bool (*read_query_result)(MYSQL *mysql);
- my_bool (*advanced_command)(MYSQL *mysql,
- enum enum_server_command command,
- const unsigned char *header,
- unsigned long header_length,
- const unsigned char *arg,
- unsigned long arg_length,
- my_bool skip_check,
- MYSQL_STMT *stmt);
- MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
- unsigned int fields);
- MYSQL_RES * (*use_result)(MYSQL *mysql);
- void (*fetch_lengths)(unsigned long *to,
- MYSQL_ROW column, unsigned int field_count);
- void (*flush_use_result)(MYSQL *mysql);
- MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
- my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
- int (*stmt_execute)(MYSQL_STMT *stmt);
- int (*read_binary_rows)(MYSQL_STMT *stmt);
- int (*unbuffered_fetch)(MYSQL *mysql, char **row);
- void (*free_embedded_thd)(MYSQL *mysql);
- const char *(*read_statistics)(MYSQL *mysql);
- my_bool (*next_result)(MYSQL *mysql);
- int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
- int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
-} MYSQL_METHODS;
MYSQL_STMT * mysql_stmt_init(MYSQL *mysql);
int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
unsigned long length);
=== added file 'include/mysql/client_plugin.h'
--- a/include/mysql/client_plugin.h 1970-01-01 00:00:00 +0000
+++ b/include/mysql/client_plugin.h 2010-03-29 15:13:53 +0000
@@ -0,0 +1,164 @@
+#ifndef MYSQL_CLIENT_PLUGIN_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ MySQL Client Plugin API
+
+ This file defines the API for plugins that work on the client side
+*/
+#define MYSQL_CLIENT_PLUGIN_INCLUDED
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* known plugin types */
+#define MYSQL_CLIENT_reserved1 0
+#define MYSQL_CLIENT_reserved2 1
+#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2
+
+#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100
+
+#define MYSQL_CLIENT_MAX_PLUGINS 3
+
+#define mysql_declare_client_plugin(X) \
+ struct st_mysql_client_plugin_ ## X \
+ _mysql_client_plugin_declaration_ = { \
+ MYSQL_CLIENT_ ## X ## _PLUGIN, \
+ MYSQL_CLIENT_ ## X ## _PLUGIN_INTERFACE_VERSION,
+#define mysql_end_client_plugin }
+
+/* generic plugin header structure */
+#define MYSQL_CLIENT_PLUGIN_HEADER \
+ int type; \
+ unsigned int interface_version; \
+ const char *name; \
+ const char *author; \
+ const char *desc; \
+ unsigned int version[3]; \
+ int (*init)(char *, size_t, int, va_list); \
+ int (*deinit)();
+
+struct st_mysql_client_plugin
+{
+ MYSQL_CLIENT_PLUGIN_HEADER
+};
+
+struct st_mysql;
+
+/******** authentication plugin specific declarations *********/
+#include <mysql/plugin_auth_common.h>
+
+struct st_mysql_client_plugin_AUTHENTICATION
+{
+ MYSQL_CLIENT_PLUGIN_HEADER
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
+};
+
+/**
+ type of the mysql_authentication_dialog_ask function
+
+ @param mysql mysql
+ @param type type of the input
+ 1 - ordinary string input
+ 2 - password string
+ @param prompt prompt
+ @param buf a buffer to store the use input
+ @param buf_len the length of the buffer
+
+ @retval a pointer to the user input string.
+ It may be equal to 'buf' or to 'mysql->password'.
+ In all other cases it is assumed to be an allocated
+ string, and the "dialog" plugin will free() it.
+*/
+typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql,
+ int type, const char *prompt, char *buf, int buf_len);
+/******** using plugins ************/
+
+/**
+ loads a plugin and initializes it
+
+ @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used,
+ and last_errno/last_error, for error reporting
+ @param name a name of the plugin to load
+ @param type type of plugin that should be loaded, -1 to disable type check
+ @param argc number of arguments to pass to the plugin initialization
+ function
+ @param ... arguments for the plugin initialization function
+
+ @retval
+ a pointer to the loaded plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_load_plugin(struct st_mysql *mysql, const char *name, int type,
+ int argc, ...);
+
+/**
+ loads a plugin and initializes it, taking va_list as an argument
+
+ This is the same as mysql_load_plugin, but take va_list instead of
+ a list of arguments.
+
+ @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used,
+ and last_errno/last_error, for error reporting
+ @param name a name of the plugin to load
+ @param type type of plugin that should be loaded, -1 to disable type check
+ @param argc number of arguments to pass to the plugin initialization
+ function
+ @param args arguments for the plugin initialization function
+
+ @retval
+ a pointer to the loaded plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type,
+ int argc, va_list args);
+
+/**
+ finds an already loaded plugin by name, or loads it, if necessary
+
+ @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used,
+ and last_errno/last_error, for error reporting
+ @param name a name of the plugin to load
+ @param type type of plugin that should be loaded
+
+ @retval
+ a pointer to the plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_client_find_plugin(struct st_mysql *mysql, const char *name, int type);
+
+/**
+ adds a plugin structure to the list of loaded plugins
+
+ This is useful if an application has the necessary functionality
+ (for example, a special load data handler) statically linked into
+ the application binary. It can use this function to register the plugin
+ directly, avoiding the need to factor it out into a shared object.
+
+ @param mysql MYSQL structure. It is only used for error reporting
+ @param plugin an st_mysql_client_plugin structure to register
+
+ @retval
+ a pointer to the plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_client_register_plugin(struct st_mysql *mysql,
+ struct st_mysql_client_plugin *plugin);
+
+#endif
+
=== added file 'include/mysql/client_plugin.h.pp'
--- a/include/mysql/client_plugin.h.pp 1970-01-01 00:00:00 +0000
+++ b/include/mysql/client_plugin.h.pp 2010-03-29 15:13:53 +0000
@@ -0,0 +1,41 @@
+#include <stdarg.h>
+#include <stdlib.h>
+struct st_mysql_client_plugin
+{
+ int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; int (*init)(char *, size_t, int, va_list); int (*deinit)();
+};
+struct st_mysql;
+#include <mysql/plugin_auth_common.h>
+typedef struct st_plugin_vio_info
+{
+ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
+ MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
+ int socket;
+} MYSQL_PLUGIN_VIO_INFO;
+typedef struct st_plugin_vio
+{
+ int (*read_packet)(struct st_plugin_vio *vio,
+ unsigned char **buf);
+ int (*write_packet)(struct st_plugin_vio *vio,
+ const unsigned char *packet,
+ int packet_len);
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+} MYSQL_PLUGIN_VIO;
+struct st_mysql_client_plugin_AUTHENTICATION
+{
+ int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; int (*init)(char *, size_t, int, va_list); int (*deinit)();
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
+};
+typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql,
+ int type, const char *prompt, char *buf, int buf_len);
+struct st_mysql_client_plugin *
+mysql_load_plugin(struct st_mysql *mysql, const char *name, int type,
+ int argc, ...);
+struct st_mysql_client_plugin *
+mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type,
+ int argc, va_list args);
+struct st_mysql_client_plugin *
+mysql_client_find_plugin(struct st_mysql *mysql, const char *name, int type);
+struct st_mysql_client_plugin *
+mysql_client_register_plugin(struct st_mysql *mysql,
+ struct st_mysql_client_plugin *plugin);
=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h 2010-03-03 14:44:14 +0000
+++ b/include/mysql/plugin.h 2010-03-29 15:13:53 +0000
@@ -67,7 +67,10 @@ typedef struct st_mysql_xid MYSQL_XID;
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
-#define MYSQL_MAX_PLUGIN_TYPE_NUM 5 /* The number of plugin types */
+#define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */
+#define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */
+#define MYSQL_AUTHENTICATION_PLUGIN 7 /* The authentication plugin type */
+#define MYSQL_MAX_PLUGIN_TYPE_NUM 8 /* The number of plugin types */
/* We use the following strings to define licenses for plugins */
#define PLUGIN_LICENSE_PROPRIETARY 0
=== removed file 'include/mysql/plugin.h.pp'
--- a/include/mysql/plugin.h.pp 2010-03-03 14:44:14 +0000
+++ b/include/mysql/plugin.h.pp 1970-01-01 00:00:00 +0000
@@ -1,163 +0,0 @@
-#include <mysql/services.h>
-#include <mysql/service_my_snprintf.h>
-#include <stdarg.h>
-#include <stdlib.h>
-extern struct my_snprintf_service_st {
- size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
- size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
-} *my_snprintf_service;
-size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
-size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
-#include <mysql/service_thd_alloc.h>
-#include <stdlib.h>
-struct st_mysql_lex_string
-{
- char *str;
- size_t length;
-};
-typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
-extern struct thd_alloc_service_st {
- void *(*thd_alloc_func)(void*, unsigned int);
- void *(*thd_calloc_func)(void*, unsigned int);
- char *(*thd_strdup_func)(void*, const char *);
- char *(*thd_strmake_func)(void*, const char *, unsigned int);
- void *(*thd_memdup_func)(void*, const void*, unsigned int);
- MYSQL_LEX_STRING *(*thd_make_lex_string_func)(void*, MYSQL_LEX_STRING *,
- const char *, unsigned int, int);
-} *thd_alloc_service;
-void *thd_alloc(void* thd, unsigned int size);
-void *thd_calloc(void* thd, unsigned int size);
-char *thd_strdup(void* thd, const char *str);
-char *thd_strmake(void* thd, const char *str, unsigned int size);
-void *thd_memdup(void* thd, const void* str, unsigned int size);
-MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
- const char *str, unsigned int size,
- int allocate_lex_string);
-struct st_mysql_xid {
- long formatID;
- long gtrid_length;
- long bqual_length;
- char data[128];
-};
-typedef struct st_mysql_xid MYSQL_XID;
-enum enum_mysql_show_type
-{
- SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
- SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
- SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
- SHOW_always_last
-};
-struct st_mysql_show_var {
- const char *name;
- char *value;
- enum enum_mysql_show_type type;
-};
-typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, char *);
-struct st_mysql_sys_var;
-struct st_mysql_value;
-typedef int (*mysql_var_check_func)(void* thd,
- struct st_mysql_sys_var *var,
- void *save, struct st_mysql_value *value);
-typedef void (*mysql_var_update_func)(void* thd,
- struct st_mysql_sys_var *var,
- void *var_ptr, const void *save);
-struct st_mysql_plugin
-{
- int type;
- void *info;
- const char *name;
- const char *author;
- const char *descr;
- int license;
- int (*init)(void *);
- int (*deinit)(void *);
- unsigned int version;
- struct st_mysql_show_var *status_vars;
- struct st_mysql_sys_var **system_vars;
- void * __reserved1;
-};
-enum enum_ftparser_mode
-{
- MYSQL_FTPARSER_SIMPLE_MODE= 0,
- MYSQL_FTPARSER_WITH_STOPWORDS= 1,
- MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
-};
-enum enum_ft_token_type
-{
- FT_TOKEN_EOF= 0,
- FT_TOKEN_WORD= 1,
- FT_TOKEN_LEFT_PAREN= 2,
- FT_TOKEN_RIGHT_PAREN= 3,
- FT_TOKEN_STOPWORD= 4
-};
-typedef struct st_mysql_ftparser_boolean_info
-{
- enum enum_ft_token_type type;
- int yesno;
- int weight_adjust;
- char wasign;
- char trunc;
- char prev;
- char *quot;
-} MYSQL_FTPARSER_BOOLEAN_INFO;
-typedef int mysql_ft_size_t;
-typedef struct st_mysql_ftparser_param
-{
- int (*mysql_parse)(struct st_mysql_ftparser_param *,
- const unsigned char *doc, mysql_ft_size_t doc_len);
- int (*mysql_add_word)(struct st_mysql_ftparser_param *,
- const unsigned char *word, mysql_ft_size_t word_len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
- void *ftparser_state;
- void *mysql_ftparam;
- const struct charset_info_st *cs;
- const unsigned char *doc;
- mysql_ft_size_t length;
- unsigned int flags;
- enum enum_ftparser_mode mode;
-} MYSQL_FTPARSER_PARAM;
-struct st_mysql_ftparser
-{
- int interface_version;
- int (*parse)(MYSQL_FTPARSER_PARAM *param);
- int (*init)(MYSQL_FTPARSER_PARAM *param);
- int (*deinit)(MYSQL_FTPARSER_PARAM *param);
-};
-struct st_mysql_storage_engine
-{
- int interface_version;
-};
-struct handlerton;
-struct st_mysql_daemon
-{
- int interface_version;
-};
-struct st_mysql_information_schema
-{
- int interface_version;
-};
-struct st_mysql_value
-{
- int (*value_type)(struct st_mysql_value *);
- const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
- int (*val_real)(struct st_mysql_value *, double *realbuf);
- int (*val_int)(struct st_mysql_value *, long long *intbuf);
-};
-int thd_in_lock_tables(const void* thd);
-int thd_tablespace_op(const void* thd);
-long long thd_test_options(const void* thd, long long test_options);
-int thd_sql_command(const void* thd);
-void **thd_ha_data(const void* thd, const struct handlerton *hton);
-int thd_tx_isolation(const void* thd);
-char *thd_security_context(void* thd, char *buffer, unsigned int length,
- unsigned int max_query_len);
-void thd_inc_row_count(void* thd);
-const char *set_thd_proc_info(void*, const char * info, const char *func,
- const char *file, const unsigned int line);
-int mysql_tmpfile(const char *prefix);
-int thd_killed(const void* thd);
-unsigned long thd_get_thread_id(const void* thd);
-void thd_get_xid(const void* thd, MYSQL_XID *xid);
-void mysql_query_cache_invalidate4(void* thd,
- const char *key, unsigned int key_length,
- int using_trx);
=== added file 'include/mysql/plugin_auth.h'
--- a/include/mysql/plugin_auth.h 1970-01-01 00:00:00 +0000
+++ b/include/mysql/plugin_auth.h 2010-03-29 15:13:53 +0000
@@ -0,0 +1,83 @@
+#ifndef MYSQL_PLUGIN_AUTH_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ Authentication Plugin API.
+
+ This file defines the API for server authentication plugins.
+*/
+
+#define MYSQL_PLUGIN_AUTH_INCLUDED
+
+#include <mysql/plugin.h>
+
+#define MYSQL_AUTHENTICATION_INTERFACE_VERSION 0x0100
+
+#include <mysql/plugin_auth_common.h>
+
+/**
+ Provides server plugin access to authentication information
+*/
+typedef struct st_mysql_server_auth_info
+{
+ /**
+ User name as sent by the client and shown in USER().
+ NULL if the client packet with the user name was not received yet.
+ */
+ const char *user_name;
+ /**
+ A corresponding column value from the mysql.user table for the
+ matching account name
+ */
+ const char *auth_string;
+
+ /**
+ Matching account name as found in the mysql.user table.
+ A plugin can override it with another name that will be
+ used by MySQL for authorization, and shown in CURRENT_USER()
+ */
+ char authenticated_as[MYSQL_USERNAME_LENGTH+1];
+ /**
+ This only affects the "Authentication failed. Password used: %s"
+ error message. If set, %s will be YES, otherwise - NO.
+ Set it as appropriate or ignore at will.
+ */
+ int password_used;
+} MYSQL_SERVER_AUTH_INFO;
+
+/**
+ Server authentication plugin descriptor
+*/
+struct st_mysql_auth
+{
+ int interface_version; /**< version plugin uses */
+ /**
+ A plugin that a client must use for authentication with this server
+ plugin. Can be NULL to mean "any plugin".
+ */
+ const char *client_auth_plugin;
+ /**
+ Function provided by the plugin which should perform authentication (using
+ the vio functions if necessary) and return 0 if successful. The plugin can
+ also fill the info.authenticated_as field if a different username should be
+ used for authorization.
+ */
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);
+};
+#endif
+
=== added file 'include/mysql/plugin_auth.h.pp'
--- a/include/mysql/plugin_auth.h.pp 1970-01-01 00:00:00 +0000
+++ b/include/mysql/plugin_auth.h.pp 2010-03-29 15:13:53 +0000
@@ -0,0 +1,193 @@
+#include <mysql/plugin.h>
+#include <mysql/services.h>
+#include <mysql/service_my_snprintf.h>
+#include <stdarg.h>
+#include <stdlib.h>
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+#include <mysql/service_thd_alloc.h>
+#include <stdlib.h>
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(void*, unsigned int);
+ void *(*thd_calloc_func)(void*, unsigned int);
+ char *(*thd_strdup_func)(void*, const char *);
+ char *(*thd_strmake_func)(void*, const char *, unsigned int);
+ void *(*thd_memdup_func)(void*, const void*, unsigned int);
+ MYSQL_LEX_STRING *(*thd_make_lex_string_func)(void*, MYSQL_LEX_STRING *,
+ const char *, unsigned int, int);
+} *thd_alloc_service;
+void *thd_alloc(void* thd, unsigned int size);
+void *thd_calloc(void* thd, unsigned int size);
+char *thd_strdup(void* thd, const char *str);
+char *thd_strmake(void* thd, const char *str, unsigned int size);
+void *thd_memdup(void* thd, const void* str, unsigned int size);
+MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
+ const char *str, unsigned int size,
+ int allocate_lex_string);
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[128];
+};
+typedef struct st_mysql_xid MYSQL_XID;
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
+ SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_always_last
+};
+struct st_mysql_show_var {
+ const char *name;
+ char *value;
+ enum enum_mysql_show_type type;
+};
+typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, char *);
+struct st_mysql_sys_var;
+struct st_mysql_value;
+typedef int (*mysql_var_check_func)(void* thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+typedef void (*mysql_var_update_func)(void* thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+struct st_mysql_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1;
+};
+enum enum_ftparser_mode
+{
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef int mysql_ft_size_t;
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const unsigned char *doc, mysql_ft_size_t doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const unsigned char *word, mysql_ft_size_t word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const unsigned char *doc;
+ mysql_ft_size_t length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+struct handlerton;
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+};
+int thd_in_lock_tables(const void* thd);
+int thd_tablespace_op(const void* thd);
+long long thd_test_options(const void* thd, long long test_options);
+int thd_sql_command(const void* thd);
+void **thd_ha_data(const void* thd, const struct handlerton *hton);
+int thd_tx_isolation(const void* thd);
+char *thd_security_context(void* thd, char *buffer, unsigned int length,
+ unsigned int max_query_len);
+void thd_inc_row_count(void* thd);
+const char *set_thd_proc_info(void*, const char * info, const char *func,
+ const char *file, const unsigned int line);
+int mysql_tmpfile(const char *prefix);
+int thd_killed(const void* thd);
+unsigned long thd_get_thread_id(const void* thd);
+void thd_get_xid(const void* thd, MYSQL_XID *xid);
+void mysql_query_cache_invalidate4(void* thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+#include <mysql/plugin_auth_common.h>
+typedef struct st_plugin_vio_info
+{
+ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
+ MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
+ int socket;
+} MYSQL_PLUGIN_VIO_INFO;
+typedef struct st_plugin_vio
+{
+ int (*read_packet)(struct st_plugin_vio *vio,
+ unsigned char **buf);
+ int (*write_packet)(struct st_plugin_vio *vio,
+ const unsigned char *packet,
+ int packet_len);
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+} MYSQL_PLUGIN_VIO;
+typedef struct st_mysql_server_auth_info
+{
+ const char *user_name;
+ const char *auth_string;
+ char authenticated_as[48 +1];
+ int password_used;
+} MYSQL_SERVER_AUTH_INFO;
+struct st_mysql_auth
+{
+ int interface_version;
+ const char *client_auth_plugin;
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);
+};
=== added file 'include/mysql/plugin_auth_common.h'
--- a/include/mysql/plugin_auth_common.h 1970-01-01 00:00:00 +0000
+++ b/include/mysql/plugin_auth_common.h 2010-03-29 15:13:53 +0000
@@ -0,0 +1,105 @@
+#ifndef MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ This file defines constants and data structures that are the same for
+ both client- and server-side authentication plugins.
+*/
+#define MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
+
+/** the max allowed length for a user name */
+#define MYSQL_USERNAME_LENGTH 48
+
+/**
+ return values of the plugin authenticate_user() method.
+*/
+
+/**
+ Authentication failed. Additionally, all other CR_xxx values
+ (libmysql error code) can be used too.
+
+ The client plugin may set the error code and the error message directly
+ in the MYSQL structure and return CR_ERROR. If a CR_xxx specific error
+ code was returned, an error message in the MYSQL structure will be
+ overwritten. If CR_ERROR is returned without setting the error in MYSQL,
+ CR_UNKNOWN_ERROR will be user.
+*/
+#define CR_ERROR 0
+/**
+ Authentication (client part) was successful. It does not mean that the
+ authentication as a whole was successful, usually it only means
+ that the client was able to send the user name and the password to the
+ server. If CR_OK is returned, the libmysql reads the next packet expecting
+ it to be one of OK, ERROR, or CHANGE_PLUGIN packets.
+*/
+#define CR_OK -1
+/**
+ Authentication was successful.
+ It means that the client has done its part successfully and also that
+ a plugin has read the last packet (one of OK, ERROR, CHANGE_PLUGIN).
+ In this case, libmysql will not read a packet from the server,
+ but it will use the data at mysql->net.read_pos.
+
+ A plugin may return this value if the number of roundtrips in the
+ authentication protocol is not known in advance, and the client plugin
+ needs to read one packet more to determine if the authentication is finished
+ or not.
+*/
+#define CR_OK_HANDSHAKE_COMPLETE -2
+
+typedef struct st_plugin_vio_info
+{
+ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
+ MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
+ int socket; /**< it's set, if the protocol is SOCKET or TCP */
+#ifdef _WIN32
+ HANDLE handle; /**< it's set, if the protocol is PIPE or MEMORY */
+#endif
+} MYSQL_PLUGIN_VIO_INFO;
+
+/**
+ Provides plugin access to communication channel
+*/
+typedef struct st_plugin_vio
+{
+ /**
+ Plugin provides a pointer reference and this function sets it to the
+ contents of any incoming packet. Returns the packet length, or -1 if
+ the plugin should terminate.
+ */
+ int (*read_packet)(struct st_plugin_vio *vio,
+ unsigned char **buf);
+
+ /**
+ Plugin provides a buffer with data and the length and this
+ function sends it as a packet. Returns 0 on success, 1 on failure.
+ */
+ int (*write_packet)(struct st_plugin_vio *vio,
+ const unsigned char *packet,
+ int packet_len);
+
+ /**
+ Fills in a st_plugin_vio_info structure, providing the information
+ about the connection.
+ */
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+
+} MYSQL_PLUGIN_VIO;
+
+#endif
+
=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h 2010-03-15 11:51:23 +0000
+++ b/include/mysql_com.h 2010-03-29 15:13:53 +0000
@@ -152,9 +152,17 @@ enum enum_server_command
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */
+#define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */
+
#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
#define CLIENT_REMEMBER_OPTIONS (1UL << 31)
+#ifdef HAVE_COMPRESS
+#define CAN_CLIENT_COMPRESS CLIENT_COMPRESS
+#else
+#define CAN_CLIENT_COMPRESS 0
+#endif
+
/* Gather all possible capabilites (flags) supported by the server */
#define CLIENT_ALL_FLAGS (CLIENT_LONG_PASSWORD | \
CLIENT_FOUND_ROWS | \
@@ -175,7 +183,8 @@ enum enum_server_command
CLIENT_MULTI_STATEMENTS | \
CLIENT_MULTI_RESULTS | \
CLIENT_SSL_VERIFY_SERVER_CERT | \
- CLIENT_REMEMBER_OPTIONS)
+ CLIENT_REMEMBER_OPTIONS | \
+ CLIENT_PLUGIN_AUTH)
/*
Switch off the flags that are optional and depending on build flags
@@ -488,14 +497,14 @@ void create_random_string(char *to, unsi
void hash_password(unsigned long *to, const char *password, unsigned int password_len);
void make_scrambled_password_323(char *to, const char *password);
void scramble_323(char *to, const char *message, const char *password);
-my_bool check_scramble_323(const char *, const char *message,
+my_bool check_scramble_323(const unsigned char *reply, const char *message,
unsigned long *salt);
void get_salt_from_password_323(unsigned long *res, const char *password);
void make_password_from_salt_323(char *to, const unsigned long *salt);
void make_scrambled_password(char *to, const char *password);
void scramble(char *to, const char *message, const char *password);
-my_bool check_scramble(const char *reply, const char *message,
+my_bool check_scramble(const unsigned char *reply, const char *message,
const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password);
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
=== modified file 'include/sql_common.h'
--- a/include/sql_common.h 2008-02-27 09:00:59 +0000
+++ b/include/sql_common.h 2010-03-29 15:13:53 +0000
@@ -1,3 +1,4 @@
+#ifndef SQL_COMMON_INCLUDED
/* Copyright (C) 2003-2004, 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -13,14 +14,60 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#define SQL_COMMON_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <mysql.h>
extern const char *unknown_sqlstate;
extern const char *cant_connect_sqlstate;
extern const char *not_error_sqlstate;
-#ifdef __cplusplus
-extern "C" {
+struct st_mysql_options_extention {
+ char *plugin_dir;
+ char *default_auth;
+};
+
+typedef struct st_mysql_methods
+{
+ my_bool (*read_query_result)(MYSQL *mysql);
+ my_bool (*advanced_command)(MYSQL *mysql,
+ enum enum_server_command command,
+ const unsigned char *header,
+ unsigned long header_length,
+ const unsigned char *arg,
+ unsigned long arg_length,
+ my_bool skip_check,
+ MYSQL_STMT *stmt);
+ MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
+ unsigned int fields);
+ MYSQL_RES * (*use_result)(MYSQL *mysql);
+ void (*fetch_lengths)(unsigned long *to,
+ MYSQL_ROW column, unsigned int field_count);
+ void (*flush_use_result)(MYSQL *mysql);
+ int (*read_change_user_result)(MYSQL *mysql);
+#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)
+ MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
+ my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
+ int (*stmt_execute)(MYSQL_STMT *stmt);
+ int (*read_binary_rows)(MYSQL_STMT *stmt);
+ int (*unbuffered_fetch)(MYSQL *mysql, char **row);
+ void (*free_embedded_thd)(MYSQL *mysql);
+ const char *(*read_statistics)(MYSQL *mysql);
+ my_bool (*next_result)(MYSQL *mysql);
+ int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
#endif
+} MYSQL_METHODS;
+
+#define simple_command(mysql, command, arg, length, skip_check) \
+ (*(mysql)->methods->advanced_command)(mysql, command, 0, \
+ 0, arg, length, skip_check, NULL)
+#define stmt_command(mysql, command, arg, length, stmt) \
+ (*(mysql)->methods->advanced_command)(mysql, command, 0, \
+ 0, arg, length, 1, stmt)
extern CHARSET_INFO *default_client_charset_info;
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
@@ -42,9 +89,23 @@ void set_stmt_errmsg(MYSQL_STMT *stmt, N
void set_stmt_error(MYSQL_STMT *stmt, int errcode, const char *sqlstate,
const char *err);
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate);
+void set_mysql_extended_error(MYSQL *mysql, int errcode, const char *sqlstate,
+ const char *format, ...);
+
+/* client side of the pluggable authentication */
+struct st_plugin_vio_info;
+void mpvio_info(Vio *vio, struct st_plugin_vio_info *info);
+int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
+ char *data_plugin, const char *db);
+int mysql_client_plugin_init();
+void mysql_client_plugin_deinit();
+struct st_mysql_client_plugin;
+extern struct st_mysql_client_plugin *mysql_client_builtins[];
+
#ifdef __cplusplus
}
#endif
#define protocol_41(A) ((A)->server_capabilities & CLIENT_PROTOCOL_41)
+#endif
=== modified file 'libmysql/CMakeLists.txt'
--- a/libmysql/CMakeLists.txt 2009-09-15 10:46:35 +0000
+++ b/libmysql/CMakeLists.txt 2010-03-29 15:13:53 +0000
@@ -98,7 +98,7 @@ SET(CLIENT_SOURCES ../mysys/array.c ..
../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c
../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c
../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c ../mysys/mf_qsort.c
- ../mysys/my_getsystime.c ../mysys/my_sync.c ${LIB_SOURCES})
+ ../mysys/my_getsystime.c ../mysys/my_sync.c ../sql-common/client_plugin.c ${LIB_SOURCES})
# Need to set USE_TLS for building the DLL, since __declspec(thread)
# approach to thread local storage does not work properly in DLLs.
@@ -125,6 +125,7 @@ IF(WIN32)
ENDIF(WIN32)
ADD_DEPENDENCIES(libmysql GenError)
TARGET_LINK_LIBRARIES(libmysql wsock32)
+ADD_DEFINITIONS(-DHAVE_DLOPEN)
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("myTest" "asInvoker")
=== modified file 'libmysql/Makefile.shared'
--- a/libmysql/Makefile.shared 2009-09-15 10:46:35 +0000
+++ b/libmysql/Makefile.shared 2010-03-29 15:13:53 +0000
@@ -23,6 +23,7 @@
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
+pkgplugindir = $(pkglibdir)/plugin
## We'll use CLIENT_EXTRA_LDFLAGS for threaded and non-threaded
## until someone complains that they need separate options.
LDADD = @CLIENT_EXTRA_LDFLAGS@ $(target)
@@ -71,26 +72,27 @@ mysysobjects1 = my_init.lo my_static.lo
my_getopt.lo my_gethostbyname.lo my_port.lo \
my_rename.lo my_chsize.lo my_sync.lo my_getsystime.lo
sqlobjects = net.lo
-sql_cmn_objects = pack.lo client.lo my_time.lo
+sql_cmn_objects = pack.lo client.lo my_time.lo client_plugin.lo
# Not needed in the minimum library
mysysobjects2 = my_lib.lo mf_qsort.lo
mysysobjects = $(mysysobjects1) $(mysysobjects2)
target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
$(sql_cmn_objects) $(vio_objects) $(sqlobjects)
-target_ldflags = -version-info @SHARED_LIB_VERSION@ @LD_VERSION_SCRIPT@
+target_ldflags = -version-info @SHARED_LIB_VERSION@ @LD_VERSION_SCRIPT@ @LIBDL@
vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
BUILT_SOURCES = link_sources
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
$(target) $(BUILT_SOURCES)
-DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
+DEFS = -DDEFAULT_CHARSET_HOME='"$(MYSQLBASEdir)"' \
+ -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \
-DDEFAULT_HOME_ENV=MYSQL_HOME \
+ -DPLUGINDIR='"$(pkgplugindir)"' \
-DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \
- -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \
- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" $(target_defs)
+ -DDEFAULT_SYSCONFDIR='"$(sysconfdir)"' \
+ -DSHAREDIR='"$(MYSQLSHAREdir)"' $(target_defs)
if HAVE_YASSL
yassl_las = $(top_builddir)/extra/yassl/src/libyassl.la \
=== modified file 'libmysql/client_settings.h'
--- a/libmysql/client_settings.h 2007-09-29 19:31:08 +0000
+++ b/libmysql/client_settings.h 2010-03-29 15:13:53 +0000
@@ -18,7 +18,8 @@ extern char * mysql_unix_port;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \
CLIENT_TRANSACTIONS | \
- CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION)
+ CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | \
+ CLIENT_PLUGIN_AUTH)
sig_handler my_pipe_sig_handler(int sig);
void read_user_name(char *name);
@@ -57,7 +58,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt);
int cli_read_binary_rows(MYSQL_STMT *stmt);
int cli_unbuffered_fetch(MYSQL *mysql, char **row);
const char * cli_read_statistics(MYSQL *mysql);
-int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd);
+int cli_read_change_user_result(MYSQL *mysql);
#ifdef EMBEDDED_LIBRARY
int init_embedded_server(int argc, char **argv, char **groups);
=== modified file 'libmysql/errmsg.c'
--- a/libmysql/errmsg.c 2008-05-20 16:36:26 +0000
+++ b/libmysql/errmsg.c 2010-03-29 15:13:53 +0000
@@ -85,6 +85,7 @@ const char *client_errors[]=
"Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
+ "Authentication plugin '%s' cannot be loaded: %s",
""
};
@@ -151,6 +152,7 @@ const char *client_errors[]=
"Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
+ "Authentication plugin '%s' cannot be loaded: %s",
""
};
@@ -215,6 +217,7 @@ const char *client_errors[]=
"Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
+ "Authentication plugin '%s' cannot be loaded: %s",
""
};
#endif
=== modified file 'libmysql/libmysql.c'
--- a/libmysql/libmysql.c 2010-03-04 08:03:07 +0000
+++ b/libmysql/libmysql.c 2010-03-29 15:13:53 +0000
@@ -126,12 +126,13 @@ int STDCALL mysql_server_init(int argc _
if (my_init()) /* Will init threads */
return 1;
init_client_errs();
+ if (mysql_client_plugin_init())
+ return 1;
if (!mysql_port)
{
mysql_port = MYSQL_PORT;
#ifndef MSDOS
{
- struct servent *serv_ptr;
char *env;
/*
@@ -145,6 +146,7 @@ int STDCALL mysql_server_init(int argc _
*/
#if MYSQL_PORT_DEFAULT == 0
+ struct servent *serv_ptr;
if ((serv_ptr = getservbyname("mysql", "tcp")))
mysql_port = (uint) ntohs((ushort) serv_ptr->s_port);
#endif
@@ -198,6 +200,8 @@ void STDCALL mysql_server_end()
if (!mysql_client_init)
return;
+ mysql_client_plugin_deinit();
+
#ifdef EMBEDDED_LIBRARY
end_embedded_server();
#endif
@@ -662,44 +666,14 @@ mysql_connect(MYSQL *mysql,const char *h
Change user and database
**************************************************************************/
-int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
-{
- NET *net= &mysql->net;
- ulong pkt_length;
-
- pkt_length= cli_safe_read(mysql);
-
- if (pkt_length == packet_error)
- return 1;
-
- if (pkt_length == 1 && net->read_pos[0] == 254 &&
- mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- /*
- By sending this very specific reply server asks us to send scrambled
- password in old format. The reply contains scramble_323.
- */
- scramble_323(buff, mysql->scramble, passwd);
- if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
- net_flush(net))
- {
- set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
- return 1;
- }
- /* Read what server thinks about out new auth message report */
- if (cli_safe_read(mysql) == packet_error)
- return 1;
- }
- return 0;
-}
-
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db)
{
- char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2];
- char *end= buff;
int rc;
CHARSET_INFO *saved_cs= mysql->charset;
+ char *saved_user= mysql->user;
+ char *saved_passwd= mysql->passwd;
+ char *saved_db= mysql->db;
DBUG_ENTER("mysql_change_user");
@@ -713,49 +687,11 @@ my_bool STDCALL mysql_change_user(MYSQL
/* Use an empty string instead of NULL. */
- if (!user)
- user="";
- if (!passwd)
- passwd="";
-
- /*
- Store user into the buffer.
- Advance position as strmake returns a pointer to the closing NUL.
- */
- end= strmake(end, user, USERNAME_LENGTH) + 1;
-
- /* write scrambled password according to server capabilities */
- if (passwd[0])
- {
- if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- *end++= SCRAMBLE_LENGTH;
- scramble(end, mysql->scramble, passwd);
- end+= SCRAMBLE_LENGTH;
- }
- else
- {
- scramble_323(end, mysql->scramble, passwd);
- end+= SCRAMBLE_LENGTH_323 + 1;
- }
- }
- else
- *end++= '\0'; /* empty password */
- /* Add database if needed */
- end= strmake(end, db ? db : "", NAME_LEN) + 1;
-
- /* Add character set number. */
-
- if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- int2store(end, (ushort) mysql->charset->number);
- end+= 2;
- }
-
- /* Write authentication package */
- simple_command(mysql,COM_CHANGE_USER, (uchar*) buff, (ulong) (end-buff), 1);
+ mysql->user= (char*)(user ? user : "");
+ mysql->passwd= (char*)(passwd ? passwd : "");
+ mysql->db= 0;
- rc= (*mysql->methods->read_change_user_result)(mysql, buff, passwd);
+ rc= run_plugin_auth(mysql, 0, 0, 0, db);
/*
The server will close all statements no matter was the attempt
@@ -765,18 +701,21 @@ my_bool STDCALL mysql_change_user(MYSQL
if (rc == 0)
{
/* Free old connect information */
- my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(saved_user, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(saved_passwd, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(saved_db, MYF(MY_ALLOW_ZERO_PTR));
/* alloc new connect information */
- mysql->user= my_strdup(user,MYF(MY_WME));
- mysql->passwd=my_strdup(passwd,MYF(MY_WME));
- mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
+ mysql->user= my_strdup(mysql->user, MYF(MY_WME));
+ mysql->passwd= my_strdup(mysql->passwd, MYF(MY_WME));
+ mysql->db= db ? my_strdup(db, MYF(MY_WME)) : 0;
}
else
{
mysql->charset= saved_cs;
+ mysql->user= saved_user;
+ mysql->passwd= saved_passwd;
+ mysql->db= saved_db;
}
DBUG_RETURN(rc);
=== modified file 'libmysqld/Makefile.am'
--- a/libmysqld/Makefile.am 2009-12-03 11:19:05 +0000
+++ b/libmysqld/Makefile.am 2010-03-29 15:13:53 +0000
@@ -25,10 +25,10 @@ pkgplugindir = $(pkglibdir)/plugin
EXTRA_DIST = libmysqld.def CMakeLists.txt
DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
- -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
- -DPLUGINDIR="\"$(pkgplugindir)\""
+ -DDEFAULT_MYSQL_HOME='"$(MYSQLBASEdir)"' \
+ -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \
+ -DSHAREDIR='"$(MYSQLSHAREdir)"' \
+ -DPLUGINDIR='"$(pkgplugindir)"'
INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \
-I$(top_builddir)/sql -I$(top_srcdir)/sql \
-I$(top_srcdir)/sql/examples \
@@ -41,7 +41,7 @@ pkglib_LIBRARIES = libmysqld.a
SUBDIRS = . examples
libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \
- my_time.c
+ my_time.c client_plugin.c
noinst_HEADERS = embedded_priv.h emb_qcache.h
=== modified file 'libmysqld/embedded_priv.h'
--- a/libmysqld/embedded_priv.h 2006-12-31 00:32:21 +0000
+++ b/libmysqld/embedded_priv.h 2010-03-29 15:13:53 +0000
@@ -15,6 +15,8 @@
/* Prototypes for the embedded version of MySQL */
+#include <sql_common.h>
+
C_MODE_START
void lib_connection_phase(NET *net, int phase);
void init_embedded_mysql(MYSQL *mysql, int client_flag);
=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc 2010-03-04 08:03:07 +0000
+++ b/libmysqld/lib_sql.cc 2010-03-29 15:13:53 +0000
@@ -35,7 +35,6 @@ C_MODE_START
#include <mysql.h>
#undef ER
#include "errmsg.h"
-#include <sql_common.h>
#include "embedded_priv.h"
extern unsigned int mysql_server_last_errno;
@@ -413,11 +412,10 @@ static MYSQL_RES * emb_store_result(MYSQ
return mysql_store_result(mysql);
}
-int emb_read_change_user_result(MYSQL *mysql,
- char *buff __attribute__((unused)),
- const char *passwd __attribute__((unused)))
+int emb_read_change_user_result(MYSQL *mysql)
{
- return mysql_errno(mysql);
+ mysql->net.read_pos= (uchar*)""; // fake an OK packet
+ return mysql_errno(mysql) ? packet_error : 1 /* length of the OK packet */;
}
MYSQL_METHODS embedded_methods=
@@ -428,6 +426,7 @@ MYSQL_METHODS embedded_methods=
emb_store_result,
emb_fetch_lengths,
emb_flush_use_result,
+ emb_read_change_user_result,
emb_list_fields,
emb_read_prepare_result,
emb_stmt_execute,
@@ -436,7 +435,6 @@ MYSQL_METHODS embedded_methods=
emb_free_embedded_thd,
emb_read_statistics,
emb_read_query_result,
- emb_read_change_user_result,
emb_read_rows_from_cursor
};
@@ -584,6 +582,7 @@ void init_embedded_mysql(MYSQL *mysql, i
THD *thd = (THD *)mysql->thd;
thd->mysql= mysql;
mysql->server_version= server_version;
+ mysql->client_flag= client_flag;
init_alloc_root(&mysql->field_alloc, 8192, 0);
}
@@ -648,14 +647,19 @@ err:
int check_embedded_connection(MYSQL *mysql, const char *db)
{
int result;
+ LEX_STRING db_str = { (char*)db, db ? strlen(db) : 0 };
THD *thd= (THD*)mysql->thd;
thd_init_client_charset(thd, mysql->charset->number);
thd->update_charset();
Security_context *sctx= thd->security_ctx;
sctx->host_or_ip= sctx->host= (char*) my_localhost;
strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1);
- sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0));
- result= check_user(thd, COM_CONNECT, NULL, 0, db, true);
+ strmake(sctx->priv_user, mysql->user, USERNAME_LENGTH-1);
+ sctx->user= my_strdup(mysql->user, MYF(0));
+ sctx->master_access= GLOBAL_ACLS; // Full rights
+ /* Change database if necessary */
+ if (!(result= (db && db[0] && mysql_change_db(thd, &db_str, FALSE))))
+ my_ok(thd);
net_end_statement(thd);
emb_read_query_result(mysql);
return result;
@@ -664,14 +668,15 @@ int check_embedded_connection(MYSQL *mys
#else
int check_embedded_connection(MYSQL *mysql, const char *db)
{
+ /*
+ we emulate a COM_CHANGE_USER user here,
+ it's easier than to emulate the complete 3-way handshake
+ */
+ char buf[USERNAME_LENGTH + SCRAMBLE_LENGTH + 1 + 2*NAME_LEN + 2], *end;
+ NET *net= &mysql->net;
THD *thd= (THD*)mysql->thd;
Security_context *sctx= thd->security_ctx;
- int result;
- char scramble_buff[SCRAMBLE_LENGTH];
- int passwd_len;
- thd_init_client_charset(thd, mysql->charset->number);
- thd->update_charset();
if (mysql->options.client_ip)
{
sctx->host= my_strdup(mysql->options.client_ip, MYF(0));
@@ -682,36 +687,44 @@ int check_embedded_connection(MYSQL *mys
sctx->host_or_ip= sctx->host;
if (acl_check_host(sctx->host, sctx->ip))
- {
- result= ER_HOST_NOT_PRIVILEGED;
goto err;
- }
- sctx->user= my_strdup(mysql->user, MYF(0));
+ /* construct a COM_CHANGE_USER packet */
+ end= strmake(buf, mysql->user, USERNAME_LENGTH) + 1;
+
+ memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
+ thd->scramble[SCRAMBLE_LENGTH]= 0;
+
if (mysql->passwd && mysql->passwd[0])
{
- memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
- thd->scramble[SCRAMBLE_LENGTH]= 0;
- scramble(scramble_buff, thd->scramble, mysql->passwd);
- passwd_len= SCRAMBLE_LENGTH;
+ *end++= SCRAMBLE_LENGTH;
+ scramble(end, thd->scramble, mysql->passwd);
+ end+= SCRAMBLE_LENGTH;
}
else
- passwd_len= 0;
+ *end++= 0;
- if((result= check_user(thd, COM_CONNECT,
- scramble_buff, passwd_len, db, true)))
- goto err;
+ end= strmake(end, db ? db : "", NAME_LEN) + 1;
- return 0;
-err:
+ int2store(end, (ushort) mysql->charset->number);
+ end+= 2;
+
+ /* acl_authenticate() takes the data from thd->net->read_pos */
+ thd->net.read_pos= (uchar*)buf;
+
+ if (acl_authenticate(thd, 0, end - buf))
{
- NET *net= &mysql->net;
- strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1);
- memcpy(net->sqlstate,
- mysql_errno_to_sqlstate(thd->main_da.sql_errno()),
- sizeof(net->sqlstate)-1);
+ x_free(thd->security_ctx->user);
+ goto err;
}
- return result;
+ return 0;
+
+err:
+ strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1);
+ memcpy(net->sqlstate,
+ mysql_errno_to_sqlstate(thd->main_da.sql_errno()),
+ sizeof(net->sqlstate)-1);
+ return 1;
}
#endif
=== modified file 'libmysqld/libmysqld.c'
--- a/libmysqld/libmysqld.c 2009-09-25 11:39:05 +0000
+++ b/libmysqld/libmysqld.c 2010-03-29 15:13:53 +0000
@@ -18,7 +18,6 @@
#include <mysql_embed.h>
#include <mysqld_error.h>
#include <my_pthread.h>
-#include "embedded_priv.h"
#include <my_sys.h>
#include <mysys_err.h>
#include <m_string.h>
@@ -28,6 +27,7 @@
#include <sys/stat.h>
#include <signal.h>
#include <time.h>
+#include "embedded_priv.h"
#include "client_settings.h"
#ifdef HAVE_PWD_H
#include <pwd.h>
@@ -81,9 +81,9 @@ static my_bool is_NT(void)
** Shut down connection
**************************************************************************/
-static void end_server(MYSQL *mysql)
+void embedded_end_server(MYSQL *mysql)
{
- DBUG_ENTER("end_server");
+ DBUG_ENTER("embedded_end_server");
free_old_query(mysql);
DBUG_VOID_RETURN;
}
@@ -169,7 +169,11 @@ mysql_real_connect(MYSQL *mysql,const ch
client_flag|=CLIENT_CAPABILITIES;
if (client_flag & CLIENT_MULTI_STATEMENTS)
client_flag|= CLIENT_MULTI_RESULTS;
- client_flag&= ~CLIENT_COMPRESS;
+ /*
+ no compression in embedded as we don't send any data,
+ and no pluggable auth, as we cannot do a client-server dialog
+ */
+ client_flag&= ~(CLIENT_COMPRESS | CLIENT_PLUGIN_AUTH);
if (db)
client_flag|=CLIENT_CONNECT_WITH_DB;
@@ -216,7 +220,7 @@ error:
{
/* Free alloced memory */
my_bool free_me=mysql->free_me;
- end_server(mysql);
+ embedded_end_server(mysql);
mysql->free_me=0;
mysql_close(mysql);
mysql->free_me=free_me;
=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl 2010-03-17 02:32:31 +0000
+++ b/mysql-test/mysql-test-run.pl 2010-02-19 08:10:05 +0000
@@ -1272,21 +1272,18 @@ sub command_line_setup {
if ($opt_gdb)
{
- mtr_warning("Silently converting --gdb to --client-gdb in embedded mode");
$opt_client_gdb= $opt_gdb;
$opt_gdb= undef;
}
if ($opt_ddd)
{
- mtr_warning("Silently converting --ddd to --client-ddd in embedded mode");
$opt_client_ddd= $opt_ddd;
$opt_ddd= undef;
}
if ($opt_debugger)
{
- mtr_warning("Silently converting --debugger to --client-debugger in embedded mode");
$opt_client_debugger= $opt_debugger;
$opt_debugger= undef;
}
@@ -5341,20 +5338,12 @@ sub gdb_arguments {
if ( $type eq "client" )
{
# write init file for client
- mtr_tofile($gdb_init_file,
- "set args $str\n" .
- "break main\n");
+ mtr_tofile($gdb_init_file, "set args $str\n");
}
else
{
# write init file for mysqld
- mtr_tofile($gdb_init_file,
- "set args $str\n" .
- "break mysql_parse\n" .
- "commands 1\n" .
- "disable 1\n" .
- "end\n" .
- "run");
+ mtr_tofile($gdb_init_file, "set args $str\n");
}
if ( $opt_manual_gdb )
@@ -5405,20 +5394,12 @@ sub ddd_arguments {
if ( $type eq "client" )
{
# write init file for client
- mtr_tofile($gdb_init_file,
- "set args $str\n" .
- "break main\n");
+ mtr_tofile($gdb_init_file, "set args $str\n");
}
else
{
# write init file for mysqld
- mtr_tofile($gdb_init_file,
- "file $$exe\n" .
- "set args $str\n" .
- "break mysql_parse\n" .
- "commands 1\n" .
- "disable 1\n" .
- "end");
+ mtr_tofile($gdb_init_file, "file $$exe\nset args $str\n");
}
if ( $opt_manual_ddd )
=== modified file 'mysql-test/r/change_user.result'
--- a/mysql-test/r/change_user.result 2009-02-12 14:08:56 +0000
+++ b/mysql-test/r/change_user.result 2010-03-29 15:13:53 +0000
@@ -1,3 +1,36 @@
+grant select on test.* to test_nopw;
+grant select on test.* to test_oldpw identified by password "09301740536db389";
+grant select on test.* to test_newpw identified by "newpw";
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<root@localhost> <root@localhost> test
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_nopw@localhost> <test_nopw@%> NULL
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_oldpw@localhost> <test_oldpw@%> NULL
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_newpw@localhost> <test_newpw@%> NULL
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<root@localhost> <root@localhost> NULL
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_nopw@localhost> <test_nopw@%> test
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_oldpw@localhost> <test_oldpw@%> test
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_newpw@localhost> <test_newpw@%> test
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<root@localhost> <root@localhost> test
+drop user test_nopw;
+drop user test_oldpw;
+drop user test_newpw;
Bug#20023
SELECT @@session.sql_big_selects;
@@session.sql_big_selects
=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result 2010-01-29 10:42:31 +0000
+++ b/mysql-test/r/grant.result 2010-03-29 15:13:53 +0000
@@ -13,8 +13,8 @@ GRANT USAGE ON *.* TO 'mysqltest_1'@'loc
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
grant delete on mysqltest.* to mysqltest_1@localhost;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
@@ -44,15 +44,15 @@ delete from mysql.user where user='mysql
flush privileges;
grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10
grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30
@@ -164,6 +164,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
insert into mysql.db (host, db, user, select_priv) values
('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y');
alter table mysql.db order by db asc;
=== modified file 'mysql-test/r/grant2.result'
--- a/mysql-test/r/grant2.result 2009-10-30 05:06:10 +0000
+++ b/mysql-test/r/grant2.result 2010-03-29 15:13:53 +0000
@@ -287,6 +287,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
create user mysqltest_A@'%';
rename user mysqltest_B@'%' to mysqltest_C@'%';
drop user mysqltest_C@'%';
@@ -354,6 +355,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
INSERT INTO mysql.db (host, db, user, select_priv) VALUES
('%','TESTDB','mysqltest_1','Y');
FLUSH PRIVILEGES;
=== modified file 'mysql-test/r/ps.result'
--- a/mysql-test/r/ps.result 2009-12-26 11:25:56 +0000
+++ b/mysql-test/r/ps.result 2010-03-29 15:13:53 +0000
@@ -1194,13 +1194,13 @@ SET @aux= "SELECT COUNT(*)
prepare my_stmt from @aux;
execute my_stmt;
COUNT(*)
-39
+41
execute my_stmt;
COUNT(*)
-39
+41
execute my_stmt;
COUNT(*)
-39
+41
deallocate prepare my_stmt;
drop procedure if exists p1|
drop table if exists t1|
=== modified file 'mysql-test/r/sp_notembedded.result'
--- a/mysql-test/r/sp_notembedded.result 2010-01-11 13:15:28 +0000
+++ b/mysql-test/r/sp_notembedded.result 2010-03-29 15:13:53 +0000
@@ -191,6 +191,8 @@ max_updates, max_connections, max_user_c
VALUES('%', 'mysqltest_1', password(''), 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'N',
'N', 'N', 'N', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', 'Y', 'Y', 'N', '',
'', '', '', '0', '0', '0', '0');
+Warnings:
+Warning 1364 Field 'auth_string' doesn't have a default value
FLUSH PRIVILEGES;
CREATE PROCEDURE p1(i INT) BEGIN END;
DROP PROCEDURE p1;
=== modified file 'mysql-test/r/system_mysql_db.result'
--- a/mysql-test/r/system_mysql_db.result 2009-10-27 10:09:36 +0000
+++ b/mysql-test/r/system_mysql_db.result 2010-03-29 15:13:53 +0000
@@ -118,6 +118,8 @@ user CREATE TABLE `user` (
`max_updates` int(11) unsigned NOT NULL DEFAULT '0',
`max_connections` int(11) unsigned NOT NULL DEFAULT '0',
`max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
+ `plugin` char(60) CHARACTER SET latin1 NOT NULL DEFAULT '',
+ `auth_string` text COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'
show create table func;
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2009-10-28 09:23:02 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2010-03-29 15:13:53 +0000
@@ -178,6 +178,7 @@ NULL mysql time_zone_transition_type Tim
NULL mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references
NULL mysql user Alter_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user Alter_routine_priv 28 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user auth_string 41 NULL NO text 65535 65535 NULL NULL utf8 utf8_bin text select,insert,update,references
NULL mysql user Create_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user Create_routine_priv 27 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user Create_tmp_table_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
@@ -198,6 +199,7 @@ NULL mysql user max_questions 36 0 NO in
NULL mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references
NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references
NULL mysql user Password 3 NO char 41 41 NULL NULL latin1 latin1_bin char(41) select,insert,update,references
+NULL mysql user plugin 40 NO char 60 60 NULL NULL latin1 latin1_swedish_ci char(60) select,insert,update,references
NULL mysql user Process_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user References_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user Reload_priv 10 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
@@ -233,6 +235,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COL
1.0000 char latin1 latin1_bin
1.0000 char latin1 latin1_swedish_ci
1.0000 varchar latin1 latin1_swedish_ci
+1.0000 text utf8 utf8_bin
1.0000 mediumtext utf8 utf8_general_ci
1.0000 text utf8 utf8_general_ci
SELECT DISTINCT
@@ -497,3 +500,5 @@ NULL mysql user max_questions int NULL N
NULL mysql user max_updates int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_connections int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_user_connections int NULL NULL NULL NULL int(11) unsigned
+1.0000 mysql user plugin char 60 60 latin1 latin1_swedish_ci char(60)
+1.0000 mysql user auth_string text 65535 65535 utf8 utf8_bin text
=== modified file 'mysql-test/suite/funcs_1/r/is_user_privileges.result'
--- a/mysql-test/suite/funcs_1/r/is_user_privileges.result 2008-03-07 19:18:14 +0000
+++ b/mysql-test/suite/funcs_1/r/is_user_privileges.result 2010-03-29 15:13:53 +0000
@@ -76,10 +76,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
#
# Add GRANT OPTION db_datadict.* to testuser1;
GRANT UPDATE ON db_datadict.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
@@ -93,10 +93,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Establish connection testuser1 (user=testuser1)
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
@@ -105,10 +105,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser1'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
SHOW GRANTS;
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
@@ -130,10 +130,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
#
# Here <SELECT YES> is shown correctly for testuser1;
@@ -147,10 +147,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Switch to connection testuser1
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
@@ -159,10 +159,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser1'@'localhost' NULL SELECT YES
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
SHOW GRANTS;
Grants for testuser1@localhost
GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION
@@ -207,10 +207,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Switch to connection testuser1
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
@@ -253,10 +253,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Switch to connection testuser1
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
@@ -265,10 +265,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser1'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
SHOW GRANTS;
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
@@ -284,10 +284,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser1'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
SHOW GRANTS;
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
@@ -309,10 +309,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Switch to connection testuser1
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
=== modified file 'mysql-test/suite/pbxt/r/grant.result'
--- a/mysql-test/suite/pbxt/r/grant.result 2009-11-24 10:19:08 +0000
+++ b/mysql-test/suite/pbxt/r/grant.result 2010-03-29 15:13:53 +0000
@@ -11,8 +11,8 @@ GRANT USAGE ON *.* TO 'mysqltest_1'@'loc
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
grant delete on mysqltest.* to mysqltest_1@localhost;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
@@ -42,15 +42,15 @@ delete from mysql.user where user='mysql
flush privileges;
grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10
grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30
@@ -162,6 +162,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
insert into mysql.db (host, db, user, select_priv) values
('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y');
alter table mysql.db order by db asc;
=== modified file 'mysql-test/suite/rpl/r/rpl_ignore_table.result'
--- a/mysql-test/suite/rpl/r/rpl_ignore_table.result 2008-11-13 19:19:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_ignore_table.result 2010-03-29 15:13:53 +0000
@@ -34,6 +34,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
GRANT SELECT ON *.* TO mysqltest6@localhost;
GRANT INSERT ON *.* TO mysqltest6@localhost;
GRANT INSERT ON test.* TO mysqltest6@localhost;
=== modified file 'mysql-test/suite/rpl/r/rpl_stm_000001.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_000001.result 2009-11-18 14:50:31 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_000001.result 2010-03-29 15:13:53 +0000
@@ -66,6 +66,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
select select_priv,user from mysql.user where user = _binary'blafasel2';
select_priv user
N blafasel2
=== modified file 'mysql-test/t/change_user.test'
--- a/mysql-test/t/change_user.test 2009-10-28 07:52:34 +0000
+++ b/mysql-test/t/change_user.test 2010-03-29 15:13:53 +0000
@@ -1,4 +1,50 @@
#
+# functional change user tests
+#
+
+grant select on test.* to test_nopw;
+grant select on test.* to test_oldpw identified by password "09301740536db389";
+grant select on test.* to test_newpw identified by "newpw";
+
+#
+# massaging the data for tests to pass in the embedded server,
+# that has authentication completely disabled.
+#
+
+--replace_result <@> <test_nopw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+
+change_user test_nopw;
+--replace_result <@> <test_nopw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user test_oldpw, oldpw;
+--replace_result <@> <test_oldpw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user test_newpw, newpw;
+--replace_result <@> <test_newpw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user root;
+--replace_result <@> <root@localhost> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+
+change_user test_nopw,,test;
+--replace_result <@> <test_nopw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user test_oldpw,oldpw,test;
+--replace_result <@> <test_oldpw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user test_newpw,newpw,test;
+--replace_result <@> <test_newpw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user root,,test;
+--replace_result <@> <root@localhost> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+
+drop user test_nopw;
+drop user test_oldpw;
+drop user test_newpw;
+
+#
# Bug#20023 mysql_change_user() resets the value of SQL_BIG_SELECTS
# The replace's are here to fix things for 32 bit systems
#
=== modified file 'mysql-test/valgrind.supp'
--- a/mysql-test/valgrind.supp 2010-03-10 09:11:02 +0000
+++ b/mysql-test/valgrind.supp 2010-02-19 08:12:25 +0000
@@ -1000,6 +1000,27 @@
fun:nptl_pthread_exit_hack_handler
}
+{
+ Invalid read within nptl_pthread_exit_hack_handler
+ Memcheck:Addr8
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+}
+
#
# Pthread doesn't free all thread specific memory before program exists
#
=== modified file 'mysys/Makefile.am'
--- a/mysys/Makefile.am 2009-12-03 11:19:05 +0000
+++ b/mysys/Makefile.am 2010-03-29 15:13:53 +0000
@@ -74,13 +74,13 @@ libmysys_a_LIBADD = @THREAD_LOBJECTS@
# testhash_DEPENDENCIES= $(LIBRARIES)
# test_charset_DEPENDENCIES= $(LIBRARIES)
# charset2html_DEPENDENCIES= $(LIBRARIES)
-DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \
- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
- -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
+DEFS = -DDEFAULT_BASEDIR='"$(prefix)"' \
+ -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \
+ -DDEFAULT_CHARSET_HOME='"$(MYSQLBASEdir)"' \
+ -DSHAREDIR'="$(MYSQLSHAREdir)"' \
-DDEFAULT_HOME_ENV=MYSQL_HOME \
-DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \
- -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \
+ -DDEFAULT_SYSCONFDIR='"$(sysconfdir)"' \
@DEFS@
libmysys_a_DEPENDENCIES= @THREAD_LOBJECTS@
=== added directory 'plugin/auth'
=== added file 'plugin/auth/Makefile.am'
--- a/plugin/auth/Makefile.am 1970-01-01 00:00:00 +0000
+++ b/plugin/auth/Makefile.am 2010-03-29 15:13:53 +0000
@@ -0,0 +1,15 @@
+pkgplugindir=$(pkglibdir)/plugin
+
+AM_LDFLAGS=-module -rpath $(pkgplugindir)
+AM_CPPFLAGS=-DMYSQL_DYNAMIC_PLUGIN -I$(top_srcdir)/include
+
+pkgplugin_LTLIBRARIES= dialog.la
+dialog_la_SOURCES= dialog.c
+
+if HAVE_PEERCRED
+pkgplugin_LTLIBRARIES+= auth_socket.la
+auth_socket_la_SOURCES= auth_socket.c
+endif
+
+EXTRA_DIST= plug.in
+
=== added file 'plugin/auth/auth_socket.c'
--- a/plugin/auth/auth_socket.c 1970-01-01 00:00:00 +0000
+++ b/plugin/auth/auth_socket.c 2010-03-29 15:13:53 +0000
@@ -0,0 +1,102 @@
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ socket_peercred authentication plugin.
+
+ Authentication is successful if the connection is done via a unix socket and
+ the owner of the client process matches the user name that was used when
+ connecting to mysqld.
+*/
+#define _GNU_SOURCE /* for struct ucred */
+
+#include <mysql/plugin_auth.h>
+#include <sys/socket.h>
+#include <pwd.h>
+#include <string.h>
+
+/**
+ perform the unix socket based authentication
+
+ This authentication callback performs a unix socket based authentication -
+ it gets the uid of the client process and considers the user authenticated
+ if it uses username of this uid. That is - if the user is already
+ authenticated to the OS (if she is logged in) - she can use MySQL as herself
+*/
+
+static int socket_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
+{
+ unsigned char *pkt;
+ MYSQL_PLUGIN_VIO_INFO vio_info;
+ struct ucred cred;
+ socklen_t cred_len= sizeof(cred);
+ struct passwd pwd_buf, *pwd;
+ char buf[1024];
+
+ /* no user name yet ? read the client handshake packet with the user name */
+ if (info->user_name == 0)
+ {
+ if (vio->read_packet(vio, &pkt) < 0)
+ return CR_ERROR;
+ }
+
+ info->password_used = 0;
+
+ vio->info(vio, &vio_info);
+ if (vio_info.protocol != MYSQL_VIO_SOCKET)
+ return CR_ERROR;
+
+ /* get the UID of the client process */
+ if (getsockopt(vio_info.socket, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len))
+ return CR_ERROR;
+
+ if (cred_len != sizeof(cred))
+ return CR_ERROR;
+
+ /* and find the username for this uid */
+ getpwuid_r(cred.uid, &pwd_buf, buf, sizeof(buf), &pwd);
+ if (pwd == NULL)
+ return CR_ERROR;
+
+ /* now it's simple as that */
+ return strcmp(pwd->pw_name, info->user_name) ? CR_ERROR : CR_OK;
+}
+
+static struct st_mysql_auth socket_auth_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ 0,
+ socket_auth
+};
+
+mysql_declare_plugin(socket_auth)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &socket_auth_handler,
+ "socket_peercred",
+ "Sergei Golubchik",
+ "Unix Socket based authentication",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ NULL
+}
+mysql_declare_plugin_end;
+
=== added file 'plugin/auth/dialog.c'
--- a/plugin/auth/dialog.c 1970-01-01 00:00:00 +0000
+++ b/plugin/auth/dialog.c 2010-03-31 18:37:45 +0000
@@ -0,0 +1,308 @@
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ dialog client authentication plugin with examples
+
+ dialog is a general purpose client authentication plugin, it simply
+ asks the user the question, as provided by the server and reports
+ the answer back to the server. No encryption is involved,
+ the answers are sent in clear text.
+
+ Two examples are provided: two_questions server plugin, that asks
+ the password and an "Are you sure?" question with a reply "yes, of course".
+ It demonstrates the usage of "password" (input is hidden) and "ordinary"
+ (input can be echoed) questions, and how to mark the last question,
+ to avoid an extra roundtrip.
+
+ And three_attempts plugin that gives the user three attempts to enter
+ a correct password. It shows the situation when a number of questions
+ is not known in advance.
+*/
+#define _GNU_SOURCE /* for RTLD_DEFAULT */
+
+#include <mysql/plugin_auth.h>
+#include <mysql/client_plugin.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/**
+ first byte of the question string is the question "type".
+ It can be a "ordinary" or a "password" question.
+ The last bit set marks a last question in the authentication exchange.
+*/
+#define ORDINARY_QUESTION "\2"
+#define LAST_QUESTION "\3"
+#define PASSWORD_QUESTION "\4"
+#define LAST_PASSWORD "\5"
+
+typedef unsigned char uchar;
+
+/********************* SERVER SIDE ****************************************/
+
+/**
+ dialog demo with two questions, one password and one ordinary.
+*/
+
+static int two_questions(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
+{
+ unsigned char *pkt;
+ int pkt_len;
+
+ /* send a password question */
+ if (vio->write_packet(vio,
+ (const uchar*) (PASSWORD_QUESTION "Password, please:"),
+ 18))
+ return CR_ERROR;
+
+ /* read the answer */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ info->password_used = 1;
+
+ /* fail if the password is wrong */
+ if (strcmp((char*) pkt, info->auth_string))
+ return CR_ERROR;
+
+ /* send the last, ordinary, question */
+ if (vio->write_packet(vio,
+ (const uchar*) (LAST_QUESTION "Are you sure ?"), 15))
+ return CR_ERROR;
+
+ /* read the answer */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ /* check the reply */
+ return strcmp((char*) pkt, "yes, of course") ? CR_ERROR : CR_OK;
+}
+
+static struct st_mysql_auth two_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ "dialog", /* requires dialog client plugin */
+ two_questions
+};
+
+
+/**
+ dialog demo where the number of questions is not known in advance
+*/
+
+static int three_attempts(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
+{
+ unsigned char *pkt;
+ int pkt_len, i;
+
+ for (i= 0; i < 3; i++)
+ {
+ /* send the prompt */
+ if (vio->write_packet(vio,
+ (const uchar*) (PASSWORD_QUESTION "Password, please:"), 18))
+ return CR_ERROR;
+
+ /* read the password */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ info->password_used = 1;
+
+ /*
+ finish, if the password is correct.
+ note, that we did not mark the prompt packet as "last"
+ */
+ if (strcmp((char*) pkt, info->auth_string) == 0)
+ return CR_OK;
+ }
+
+ return CR_ERROR;
+}
+
+static struct st_mysql_auth three_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ "dialog", /* requires dialog client plugin */
+ three_attempts
+};
+
+mysql_declare_plugin(dialog)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &two_handler,
+ "two_questions",
+ "Sergei Golubchik",
+ "Dialog plugin demo 1",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ NULL
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &three_handler,
+ "three_attempts",
+ "Sergei Golubchik",
+ "Dialog plugin demo 2",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ NULL
+}
+mysql_declare_plugin_end;
+
+/********************* CLIENT SIDE ***************************************/
+/*
+ This plugin performs a dialog with the user, asking questions and
+ reading answers. Depending on the client it may be desirable to do it
+ using GUI, or console, with or without curses, or read answers
+ from a smardcard, for example.
+
+ To support all this variety, the dialog plugin has a callback function
+ "authentication_dialog_ask". If the client has a function of this name
+ dialog plugin will use it for communication with the user. Otherwise
+ a default gets() based implementation will be used.
+*/
+#include <mysql.h>
+#include <dlfcn.h>
+
+static mysql_authentication_dialog_ask_t ask;
+
+static char *builtin_ask(MYSQL *mysql __attribute__((unused)),
+ int type __attribute__((unused)),
+ const char *prompt,
+ char *buf, int buf_len __attribute__((unused)))
+{
+ fputs(prompt, stdout);
+ fputc(' ', stdout);
+ if (gets(buf) == 0)
+ return 0;
+
+ return buf;
+}
+
+
+/**
+ The main function of the dialog plugin.
+
+ Read the prompt, ask the question, send the reply, repeat until
+ the server is satisfied.
+
+ @note
+ 1. this plugin shows how a client authentication plugin
+ may read a MySQL protocol OK packet internally - which is important
+ where a number of packets is not known in advance.
+ 2. the first byte of the prompt is special. it is not
+ shown to the user, but signals whether it is the last question
+ (prompt[0] & 1 == 1) or not last (prompt[0] & 1 == 0),
+ and whether the input is a password (not echoed).
+ 3. the prompt is expected to be sent zero-terminated
+*/
+
+static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ unsigned char *pkt, cmd= 0;
+ int pkt_len, res;
+ char reply_buf[1024], *reply;
+
+ do
+ {
+ /* read the prompt */
+ pkt_len= vio->read_packet(vio, &pkt);
+ if (pkt_len < 0)
+ return CR_ERROR;
+
+ if (pkt == 0)
+ {
+ /*
+ in mysql_change_user() the client sends the first packet, so
+ the first vio->read_packet() does nothing (pkt == 0).
+
+ We send the "password", assuming the client knows what its doing.
+ (in other words, the dialog plugin should be only set as a default
+ authentication plugin on the client if the first question
+ asks for a password - which will be sent in clear text, by the way)
+ */
+ reply= mysql->passwd;
+ }
+ else
+ {
+ cmd= *pkt++;
+
+ /* is it MySQL protocol packet ? */
+ if (cmd == 0 || cmd == 254)
+ return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */
+
+ /*
+ asking for a password with an empty prompt means mysql->password
+ otherwise we ask the user and read the reply
+ */
+ if ((cmd >> 1) == 2 && *pkt == 0)
+ reply= mysql->passwd;
+ else
+ reply= ask(mysql, cmd >> 1, (char*) pkt, reply_buf, sizeof(reply_buf));
+ if (!reply)
+ return CR_ERROR;
+ }
+ /* send the reply to the server */
+ res= vio->write_packet(vio, (uchar*) reply, strlen(reply)+1);
+
+ if (reply != mysql->passwd && reply != reply_buf)
+ free(reply);
+
+ if (res)
+ return CR_ERROR;
+
+ /* repeat unless it was the last question */
+ } while ((cmd & 1) != 1);
+
+ /* the job of reading the ok/error packet is left to the server */
+ return CR_OK;
+}
+
+
+/**
+ initialization function of the dialog plugin
+
+ Pick up the client's authentication_dialog_ask() function, if exists,
+ or fall back to the default implementation.
+*/
+
+static int init_dialog()
+{
+ void *sym= dlsym(RTLD_DEFAULT, "mysql_authentication_dialog_ask");
+ ask= sym ? (mysql_authentication_dialog_ask_t)sym : builtin_ask;
+ return 0;
+}
+
+mysql_declare_client_plugin(AUTHENTICATION)
+ "dialog",
+ "Sergei Golubchik",
+ "Dialog Client Authentication Plugin",
+ {0,1,0},
+ init_dialog,
+ NULL,
+ perform_dialog
+mysql_end_client_plugin;
+
=== added file 'plugin/auth/plug.in'
--- a/plugin/auth/plug.in 1970-01-01 00:00:00 +0000
+++ b/plugin/auth/plug.in 2010-03-29 15:13:53 +0000
@@ -0,0 +1,15 @@
+MYSQL_PLUGIN(auth, [Collection of Authentication Plugins],
+ [Collection of Authentication Plugins])
+MYSQL_PLUGIN_DYNAMIC(auth, [dialog.la])
+MYSQL_PLUGIN_ACTIONS(auth,[
+AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([[
+#define _GNU_SOURCE
+#include <sys/socket.h>
+]],[[
+ struct ucred cred;
+ getsockopt(0, SOL_SOCKET, SO_PEERCRED, &cred, 0);
+]])],have_peercred=yes)
+AM_CONDITIONAL(HAVE_PEERCRED, test x$have_peercred = xyes)
+])
+AM_CONDITIONAL(HAVE_PEERCRED, false)
=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql 2009-10-27 10:09:36 +0000
+++ b/scripts/mysql_system_tables.sql 2010-03-29 15:13:53 +0000
@@ -13,7 +13,7 @@ set @had_db_table= @@warning_count != 0;
CREATE TABLE IF NOT EXISTS host ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT
NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges';
-CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_rout
ine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
+CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_rout
ine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) unsigned DEFAULT 0 NOT NULL, plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, auth_string TEXT NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
-- Remember for later if user table already existed
set @had_user_table= @@warning_count != 0;
=== modified file 'scripts/mysql_system_tables_data.sql'
--- a/scripts/mysql_system_tables_data.sql 2008-10-03 15:54:22 +0000
+++ b/scripts/mysql_system_tables_data.sql 2010-03-29 15:13:53 +0000
@@ -21,9 +21,9 @@ DROP TABLE tmp_db;
-- from local machine if "users" table didn't exist before
CREATE TEMPORARY TABLE tmp_user LIKE user;
set @current_hostname= @@hostname;
-INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
-REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0 FROM dual WHERE LOWER( @current_hostname) != 'localhost';
-REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
+INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','');
+REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','' FROM dual WHERE LOWER( @current_hostname) != 'localhost';
+REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','');
INSERT INTO tmp_user (host,user) VALUES ('localhost','');
INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE LOWER(@current_hostname ) != 'localhost';
INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0;
=== modified file 'scripts/mysql_system_tables_fix.sql'
--- a/scripts/mysql_system_tables_fix.sql 2009-12-03 16:15:47 +0000
+++ b/scripts/mysql_system_tables_fix.sql 2010-03-29 15:13:53 +0000
@@ -571,6 +571,9 @@ ALTER TABLE tables_priv MODIFY Table_pri
UPDATE user SET Trigger_priv=Super_priv WHERE @hadTriggerPriv = 0;
+ALTER TABLE user ADD plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, ADD auth_string TEXT NOT NULL;
+ALTER TABLE user MODIFY plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL;
+
# Activate the new, possible modified privilege tables
# This should not be needed, but gives us some extra testing that the above
# changes was correct
=== modified file 'server-tools/instance-manager/Makefile.am'
--- a/server-tools/instance-manager/Makefile.am 2007-02-18 12:45:28 +0000
+++ b/server-tools/instance-manager/Makefile.am 2010-03-29 15:13:53 +0000
@@ -46,7 +46,8 @@ libnet_a_LIBADD= $(top_builddir)/sql/pas
$(top_builddir)/sql/pack.$(OBJEXT) \
$(top_builddir)/sql/sql_state.$(OBJEXT) \
$(top_builddir)/sql/mini_client_errors.$(OBJEXT)\
- $(top_builddir)/sql/client.$(OBJEXT)
+ $(top_builddir)/sql/client.$(OBJEXT) \
+ $(top_builddir)/sql/client_plugin.$(OBJEXT)
CLEANFILES= net_serv.cc client_settings.h
@@ -91,7 +92,7 @@ mysqlmanager_LDADD= @CLIENT_EXTRA_LDFLAG
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/strings/libmystrings.a \
$(top_builddir)/dbug/libdbug.a \
- @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@
+ @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@ @LIBDL@
EXTRA_DIST = WindowsService.cpp WindowsService.h IMService.cpp \
IMService.h CMakeLists.txt
=== modified file 'server-tools/instance-manager/user_map.cc'
--- a/server-tools/instance-manager/user_map.cc 2009-12-18 19:14:09 +0000
+++ b/server-tools/instance-manager/user_map.cc 2010-03-29 15:13:53 +0000
@@ -368,7 +368,7 @@ int User_map::authenticate(const LEX_STR
const char *scramble) const
{
const User *user= find_user(user_name);
- return user ? check_scramble(scrambled_password, scramble, user->salt) : 2;
+ return user ? check_scramble((uchar*)scrambled_password, scramble, user->salt) : 2;
}
=== modified file 'sql-common/Makefile.am'
--- a/sql-common/Makefile.am 2006-12-31 00:02:27 +0000
+++ b/sql-common/Makefile.am 2010-03-29 15:13:53 +0000
@@ -14,7 +14,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to create Makefile.in
-EXTRA_DIST = client.c pack.c my_time.c my_user.c
+EXTRA_DIST = client.c pack.c my_time.c my_user.c client_plugin.c
# Don't update the files from bitkeeper
%::SCCS/s.%
=== modified file 'sql-common/client.c'
--- a/sql-common/client.c 2010-02-01 06:14:12 +0000
+++ b/sql-common/client.c 2010-03-29 15:13:53 +0000
@@ -107,6 +107,10 @@ my_bool net_flush(NET *net);
#include "client_settings.h"
#include <sql_common.h>
+#include <mysql/client_plugin.h>
+
+#define native_password_plugin_name "mysql_native_password"
+#define old_password_plugin_name "mysql_old_password"
uint mysql_port=0;
char *mysql_unix_port= 0;
@@ -332,7 +336,7 @@ void net_clear_error(NET *net)
@param ... variable number of arguments
*/
-static void set_mysql_extended_error(MYSQL *mysql, int errcode,
+void set_mysql_extended_error(MYSQL *mysql, int errcode,
const char *sqlstate,
const char *format, ...)
{
@@ -1002,9 +1006,20 @@ static const char *default_options[]=
"replication-probe", "enable-reads-from-master", "repl-parse-query",
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
"multi-results", "multi-statements", "multi-queries", "secure-auth",
- "report-data-truncation",
+ "report-data-truncation", "plugin-dir", "default-auth",
NullS
};
+enum option_id {
+ OPT_port=1, OPT_socket, OPT_compress, OPT_password, OPT_pipe, OPT_timeout, OPT_user,
+ OPT_init_command, OPT_host, OPT_database, OPT_debug, OPT_return_found_rows,
+ OPT_ssl_key, OPT_ssl_cert, OPT_ssl_ca, OPT_ssl_capath,
+ OPT_character_sets_dir, OPT_default_character_set, OPT_interactive_timeout,
+ OPT_connect_timeout, OPT_local_infile, OPT_disable_local_infile,
+ OPT_replication_probe, OPT_enable_reads_from_master, OPT_repl_parse_query,
+ OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name,
+ OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth,
+ OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth,
+};
static TYPELIB option_types={array_elements(default_options)-1,
"options",default_options, NULL};
@@ -1035,6 +1050,15 @@ static int add_init_command(struct st_my
return 0;
}
+#define extension_set_string(OPTS, X, STR) \
+ if ((OPTS)->extension) \
+ my_free((OPTS)->extension->X, MYF(MY_ALLOW_ZERO_PTR)); \
+ else \
+ (OPTS)->extension= (struct st_mysql_options_extention *) \
+ my_malloc(sizeof(struct st_mysql_options_extention), \
+ MYF(MY_WME | MY_ZEROFILL)); \
+ (OPTS)->extension->X= my_strdup((STR), MYF(MY_WME));
+
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group)
{
@@ -1067,134 +1091,134 @@ void mysql_read_default_options(struct s
for (end= *option ; *(end= strcend(end,'_')) ; )
*end= '-';
switch (find_type(*option+2,&option_types,2)) {
- case 1: /* port */
+ case OPT_port:
if (opt_arg)
options->port=atoi(opt_arg);
break;
- case 2: /* socket */
+ case OPT_socket:
if (opt_arg)
{
my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 3: /* compress */
+ case OPT_compress:
options->compress=1;
options->client_flag|= CLIENT_COMPRESS;
break;
- case 4: /* password */
+ case OPT_password:
if (opt_arg)
{
my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
options->password=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 5:
+ case OPT_pipe:
options->protocol = MYSQL_PROTOCOL_PIPE;
- case 20: /* connect_timeout */
- case 6: /* timeout */
+ case OPT_connect_timeout:
+ case OPT_timeout:
if (opt_arg)
options->connect_timeout=atoi(opt_arg);
break;
- case 7: /* user */
+ case OPT_user:
if (opt_arg)
{
my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
options->user=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 8: /* init-command */
+ case OPT_init_command:
add_init_command(options,opt_arg);
break;
- case 9: /* host */
+ case OPT_host:
if (opt_arg)
{
my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
options->host=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 10: /* database */
+ case OPT_database:
if (opt_arg)
{
my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
options->db=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 11: /* debug */
+ case OPT_debug:
#ifdef MYSQL_CLIENT
mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace");
break;
#endif
- case 12: /* return-found-rows */
+ case OPT_return_found_rows:
options->client_flag|=CLIENT_FOUND_ROWS;
break;
#ifdef HAVE_OPENSSL
- case 13: /* ssl_key */
+ case OPT_ssl_key:
my_free(options->ssl_key, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_key = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 14: /* ssl_cert */
+ case OPT_ssl_cert:
my_free(options->ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_cert = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 15: /* ssl_ca */
+ case OPT_ssl_ca:
my_free(options->ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_ca = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 16: /* ssl_capath */
+ case OPT_ssl_capath:
my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 26: /* ssl_cipher */
+ case OPT_ssl_cipher:
my_free(options->ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME));
break;
#else
- case 13: /* Ignore SSL options */
- case 14:
- case 15:
- case 16:
- case 26:
+ case OPT_ssl_key:
+ case OPT_ssl_cert:
+ case OPT_ssl_ca:
+ case OPT_ssl_capath:
+ case OPT_ssl_cipher:
break;
#endif /* HAVE_OPENSSL */
- case 17: /* charset-lib */
+ case OPT_character_sets_dir:
my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 18:
+ case OPT_default_character_set:
my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 19: /* Interactive-timeout */
+ case OPT_interactive_timeout:
options->client_flag|= CLIENT_INTERACTIVE;
break;
- case 21:
+ case OPT_local_infile:
if (!opt_arg || atoi(opt_arg) != 0)
options->client_flag|= CLIENT_LOCAL_FILES;
else
options->client_flag&= ~CLIENT_LOCAL_FILES;
break;
- case 22:
+ case OPT_disable_local_infile:
options->client_flag&= ~CLIENT_LOCAL_FILES;
break;
- case 23: /* replication probe */
+ case OPT_replication_probe:
#ifndef TO_BE_DELETED
options->rpl_probe= 1;
#endif
break;
- case 24: /* enable-reads-from-master */
+ case OPT_enable_reads_from_master:
options->no_master_reads= 0;
break;
- case 25: /* repl-parse-query */
+ case OPT_repl_parse_query:
#ifndef TO_BE_DELETED
options->rpl_parse= 1;
#endif
break;
- case 27:
+ case OPT_max_allowed_packet:
if (opt_arg)
options->max_allowed_packet= atoi(opt_arg);
break;
- case 28: /* protocol */
+ case OPT_protocol:
if ((options->protocol= find_type(opt_arg,
&sql_protocol_typelib,0)) <= 0)
{
@@ -1202,26 +1226,32 @@ void mysql_read_default_options(struct s
exit(1);
}
break;
- case 29: /* shared_memory_base_name */
+ case OPT_shared_memory_base_name:
#ifdef HAVE_SMEM
if (options->shared_memory_base_name != def_shared_memory_base_name)
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
#endif
break;
- case 30:
+ case OPT_multi_results:
options->client_flag|= CLIENT_MULTI_RESULTS;
break;
- case 31:
- case 32:
+ case OPT_multi_statements:
+ case OPT_multi_queries:
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
break;
- case 33: /* secure-auth */
+ case OPT_secure_auth:
options->secure_auth= TRUE;
break;
- case 34: /* report-data-truncation */
+ case OPT_report_data_truncation:
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
break;
+ case OPT_plugin_dir:
+ extension_set_string(options, plugin_dir, opt_arg);
+ break;
+ case OPT_default_auth:
+ extension_set_string(options, default_auth, opt_arg);
+ break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
}
@@ -1765,6 +1795,11 @@ static int ssl_verify_server_cert(Vio *v
static my_bool cli_read_query_result(MYSQL *mysql);
static MYSQL_RES *cli_use_result(MYSQL *mysql);
+int cli_read_change_user_result(MYSQL *mysql)
+{
+ return cli_safe_read(mysql);
+}
+
static MYSQL_METHODS client_methods=
{
cli_read_query_result, /* read_query_result */
@@ -1772,7 +1807,8 @@ static MYSQL_METHODS client_methods=
cli_read_rows, /* read_rows */
cli_use_result, /* use_result */
cli_fetch_lengths, /* fetch_lengths */
- cli_flush_use_result /* flush_use_result */
+ cli_flush_use_result, /* flush_use_result */
+ cli_read_change_user_result /* read_change_user_result */
#ifndef MYSQL_SERVER
,cli_list_fields, /* list_fields */
cli_read_prepare_result, /* read_prepare_result */
@@ -1782,7 +1818,6 @@ static MYSQL_METHODS client_methods=
NULL, /* free_embedded_thd */
cli_read_statistics, /* read_statistics */
cli_read_query_result, /* next_result */
- cli_read_change_user_result, /* read_change_user_result */
cli_read_binary_rows /* read_rows_from_cursor */
#endif
};
@@ -1856,6 +1891,646 @@ int mysql_init_character_set(MYSQL *mysq
}
C_MODE_END
+/*********** client side authentication support **************************/
+
+typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
+static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, int);
+static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
+static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
+
+static auth_plugin_t native_password_client_plugin=
+{
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
+ native_password_plugin_name,
+ "R.J.Silk, Sergei Golubchik",
+ "Native MySQL authentication",
+ {1, 0, 0},
+ NULL,
+ NULL,
+ native_password_auth_client
+};
+
+static auth_plugin_t old_password_client_plugin=
+{
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
+ old_password_plugin_name,
+ "R.J.Silk, Sergei Golubchik",
+ "Old MySQL-3.23 authentication",
+ {1, 0, 0},
+ NULL,
+ NULL,
+ old_password_auth_client
+};
+
+struct st_mysql_client_plugin *mysql_client_builtins[]=
+{
+ (struct st_mysql_client_plugin *)&native_password_client_plugin,
+ (struct st_mysql_client_plugin *)&old_password_client_plugin,
+ 0
+};
+
+
+
+/* this is a "superset" of MYSQL_PLUGIN_VIO, in C++ I use inheritance */
+typedef struct {
+ int (*read_packet)(struct st_plugin_vio *vio, uchar **buf);
+ int (*write_packet)(struct st_plugin_vio *vio, const uchar *pkt, int pkt_len);
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+ /* -= end of MYSQL_PLUGIN_VIO =- */
+ MYSQL *mysql;
+ auth_plugin_t *plugin; /**< what plugin we're under */
+ const char *db;
+ struct {
+ uchar *pkt; /**< pointer into NET::buff */
+ uint pkt_len;
+ } cached_server_reply;
+ uint packets_read, packets_written; /**< counters for send/received packets */
+ my_bool mysql_change_user; /**< if it's mysql_change_user() */
+ int last_read_packet_len; /**< the length of the last *read* packet */
+} MCPVIO_EXT;
+
+/**
+ sends a COM_CHANGE_USER command with a caller provided payload
+
+ Packet format:
+
+ Bytes Content
+ ----- ----
+ n user name - \0-terminated string
+ n password
+ 3.23 scramble - \0-terminated string (9 bytes)
+ otherwise - length (1 byte) coded
+ n database name - \0-terminated string
+ 2 character set number (if the server >= 4.1.x)
+ n client auth plugin name - \0-terminated string,
+ (if the server supports plugin auth)
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+static int send_change_user_packet(MCPVIO_EXT *mpvio,
+ const uchar *data, int data_len)
+{
+ MYSQL *mysql= mpvio->mysql;
+ char *buff, *end;
+ int res= 1;
+
+ buff= my_alloca(USERNAME_LENGTH + data_len + 1 + NAME_LEN + 2 + NAME_LEN);
+
+ end= strmake(buff, mysql->user, USERNAME_LENGTH) + 1;
+
+ if (!data_len)
+ *end++= 0;
+ else
+ {
+ if (mysql->client_flag & CLIENT_SECURE_CONNECTION)
+ {
+ DBUG_ASSERT(data_len <= 255);
+ if (data_len > 255)
+ {
+ set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
+ goto error;
+ }
+ *end++= data_len;
+ }
+ else
+ {
+ DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1);
+ DBUG_ASSERT(data[SCRAMBLE_LENGTH_323] == 0);
+ }
+ memcpy(end, data, data_len);
+ end+= data_len;
+ }
+ end= strmake(end, mpvio->db ? mpvio->db : "", NAME_LEN) + 1;
+
+ if (mysql->server_capabilities & CLIENT_PROTOCOL_41)
+ {
+ int2store(end, (ushort) mysql->charset->number);
+ end+= 2;
+ }
+
+ if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
+ end= strmake(end, mpvio->plugin->name, NAME_LEN) + 1;
+
+ res= simple_command(mysql, COM_CHANGE_USER,
+ (uchar*)buff, (ulong)(end-buff), 1);
+
+error:
+ my_afree(buff);
+ return res;
+}
+
+
+/**
+ sends a client authentication packet (second packet in the 3-way handshake)
+
+ Packet format (when the server is 4.0 or earlier):
+
+ Bytes Content
+ ----- ----
+ 2 client capabilities
+ 3 max packet size
+ n user name, \0-terminated
+ 9 scramble_323, \0-terminated
+
+ Packet format (when the server is 4.1 or newer):
+
+ Bytes Content
+ ----- ----
+ 4 client capabilities
+ 4 max packet size
+ 1 charset number
+ 23 reserved (always 0)
+ n user name, \0-terminated
+ n plugin auth data (e.g. scramble), length (1 byte) coded
+ n database name, \0-terminated
+ (if CLIENT_CONNECT_WITH_DB is set in the capabilities)
+ n client auth plugin name - \0-terminated string,
+ (if CLIENT_PLUGIN_AUTH is set in the capabilities)
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+static int send_client_reply_packet(MCPVIO_EXT *mpvio,
+ const uchar *data, int data_len)
+{
+ MYSQL *mysql= mpvio->mysql;
+ NET *net= &mysql->net;
+ char *buff, *end;
+
+ /* see end= buff+32 below, fixed size of the packet is 32 bytes */
+ buff= my_alloca(33 + USERNAME_LENGTH + data_len + NAME_LEN + NAME_LEN);
+
+ mysql->client_flag|= mysql->options.client_flag;
+ mysql->client_flag|= CLIENT_CAPABILITIES;
+
+ if (mysql->client_flag & CLIENT_MULTI_STATEMENTS)
+ mysql->client_flag|= CLIENT_MULTI_RESULTS;
+
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
+ if (mysql->options.ssl_key || mysql->options.ssl_cert ||
+ mysql->options.ssl_ca || mysql->options.ssl_capath ||
+ mysql->options.ssl_cipher)
+ mysql->options.use_ssl= 1;
+ if (mysql->options.use_ssl)
+ mysql->client_flag|= CLIENT_SSL;
+#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY*/
+ if (mpvio->db)
+ mysql->client_flag|= CLIENT_CONNECT_WITH_DB;
+
+ /* Remove options that server doesn't support */
+ mysql->client_flag= mysql->client_flag &
+ (~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)
+ | mysql->server_capabilities);
+
+#ifndef HAVE_COMPRESS
+ mysql->client_flag&= ~CLIENT_COMPRESS;
+#endif
+
+ if (mysql->client_flag & CLIENT_PROTOCOL_41)
+ {
+ /* 4.1 server and 4.1 client has a 32 byte option flag */
+ int4store(buff,mysql->client_flag);
+ int4store(buff+4, net->max_packet_size);
+ buff[8]= (char) mysql->charset->number;
+ bzero(buff+9, 32-9);
+ end= buff+32;
+ }
+ else
+ {
+ int2store(buff, mysql->client_flag);
+ int3store(buff+2, net->max_packet_size);
+ end= buff+5;
+ }
+#ifdef HAVE_OPENSSL
+ if (mysql->client_flag & CLIENT_SSL)
+ {
+ /* Do the SSL layering. */
+ struct st_mysql_options *options= &mysql->options;
+ struct st_VioSSLFd *ssl_fd;
+ char error_string[1024];
+
+ /*
+ Send mysql->client_flag, max_packet_size - unencrypted otherwise
+ the server does not know we want to do SSL
+ */
+ if (my_net_write(net, (uchar*)buff, (size_t) (end-buff)) || net_flush(net))
+ {
+ set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "sending connection information to server",
+ errno);
+ goto error;
+ }
+
+ /* Create the VioSSLConnectorFd - init SSL and load certs */
+ if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key,
+ options->ssl_cert,
+ options->ssl_ca,
+ options->ssl_capath,
+ options->ssl_cipher)))
+ {
+ set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+ goto error;
+ }
+ mysql->connector_fd= (void*)ssl_fd;
+
+ /* Connect to the server */
+ DBUG_PRINT("info", ("IO layer change in progress..."));
+ if (sslconnect(ssl_fd, net->vio,
+ (long) (mysql->options.connect_timeout),
+ error_string))
+ {
+ set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR,
+ unknown_sqlstate, "SSL error: %s",
+ error_string[0] ? error_string :
+ ER(CR_SSL_CONNECTION_ERROR));
+ goto error;
+ }
+ DBUG_PRINT("info", ("IO layer change done!"));
+
+ /* Verify server cert */
+ if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
+ ssl_verify_server_cert(net->vio, mysql->host))
+ {
+ set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+ goto error;
+ }
+ }
+#endif /* HAVE_OPENSSL */
+
+ DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
+ mysql->server_version, mysql->server_capabilities,
+ mysql->server_status, mysql->client_flag));
+
+ compile_time_assert(MYSQL_USERNAME_LENGTH == USERNAME_LENGTH);
+
+ /* This needs to be changed as it's not useful with big packets */
+ if (mysql->user[0])
+ strmake(end, mysql->user, USERNAME_LENGTH);
+ else
+ read_user_name(end);
+
+ /* We have to handle different version of handshake here */
+ DBUG_PRINT("info",("user: %s",end));
+ end= strend(end) + 1;
+ if (data_len)
+ {
+ if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
+ {
+ *end++= data_len;
+ memcpy(end, data, data_len);
+ end+= data_len;
+ }
+ else
+ {
+ DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1); /* incl. \0 at the end */
+ memcpy(end, data, data_len);
+ end+= data_len;
+ }
+ }
+ else
+ *end++= 0;
+
+ /* Add database if needed */
+ if (mpvio->db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
+ {
+ end= strmake(end, mpvio->db, NAME_LEN) + 1;
+ mysql->db= my_strdup(mpvio->db, MYF(MY_WME));
+ }
+
+ if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
+ end= strmake(end, mpvio->plugin->name, NAME_LEN) + 1;
+
+ /* Write authentication package */
+ if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
+ {
+ set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "sending authentication information",
+ errno);
+ goto error;
+ }
+ my_afree(buff);
+ return 0;
+
+error:
+ my_afree(buff);
+ return 1;
+}
+
+
+/**
+ vio->read_packet() callback method for client authentication plugins
+
+ This function is called by a client authentication plugin, when it wants
+ to read data from the server.
+*/
+
+static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf)
+{
+ MCPVIO_EXT *mpvio= (MCPVIO_EXT*)mpv;
+ MYSQL *mysql= mpvio->mysql;
+ ulong pkt_len;
+
+ /* there are cached data left, feed it to a plugin */
+ if (mpvio->cached_server_reply.pkt)
+ {
+ *buf= mpvio->cached_server_reply.pkt;
+ mpvio->cached_server_reply.pkt= 0;
+ mpvio->packets_read++;
+ return mpvio->cached_server_reply.pkt_len;
+ }
+
+ if (mpvio->packets_read == 0)
+ {
+ /*
+ the server handshake packet came from the wrong plugin,
+ or it's mysql_change_user(). Either way, there is no data
+ for a plugin to read. send a dummy packet to the server
+ to initiate a dialog.
+ */
+ if (client_mpvio_write_packet(mpv, 0, 0))
+ return (int)packet_error;
+ }
+
+ /* otherwise read the data */
+ pkt_len= (*mysql->methods->read_change_user_result)(mysql);
+ mpvio->last_read_packet_len= pkt_len;
+ *buf= mysql->net.read_pos;
+
+ /* was it a request to change plugins ? */
+ if (**buf == 254)
+ return (int)packet_error; /* if yes, this plugin shan't continue */
+
+ /*
+ the server sends \1\255 or \1\254 instead of just \255 or \254 -
+ for us to not confuse it with an error or "change plugin" packets.
+ We remove this escaping \1 here.
+
+ See also server_mpvio_write_packet() where the escaping is done.
+ */
+ if (pkt_len && **buf == 1)
+ {
+ (*buf)++;
+ pkt_len--;
+ }
+ mpvio->packets_read++;
+ return pkt_len;
+}
+
+
+/**
+ vio->write_packet() callback method for client authentication plugins
+
+ This function is called by a client authentication plugin, when it wants
+ to send data to the server.
+
+ It transparently wraps the data into a change user or authentication
+ handshake packet, if neccessary.
+*/
+
+static int client_mpvio_write_packet(struct st_plugin_vio *mpv,
+ const uchar *pkt, int pkt_len)
+{
+ int res;
+ MCPVIO_EXT *mpvio= (MCPVIO_EXT*)mpv;
+
+ if (mpvio->packets_written == 0)
+ {
+ if (mpvio->mysql_change_user)
+ res= send_change_user_packet(mpvio, pkt, pkt_len);
+ else
+ res= send_client_reply_packet(mpvio, pkt, pkt_len);
+ }
+ else
+ {
+ NET *net= &mpvio->mysql->net;
+ if (mpvio->mysql->thd)
+ res= 1; /* no chit-chat in embedded */
+ else
+ res= my_net_write(net, pkt, pkt_len) || net_flush(net);
+ if (res)
+ set_mysql_extended_error(mpvio->mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "sending authentication information",
+ errno);
+ }
+ mpvio->packets_written++;
+ return res;
+}
+
+
+/**
+ fills MYSQL_PLUGIN_VIO_INFO structure with the information about the
+ connection
+*/
+
+void mpvio_info(Vio *vio, MYSQL_PLUGIN_VIO_INFO *info)
+{
+ bzero(info, sizeof(*info));
+ switch (vio->type) {
+ case VIO_TYPE_TCPIP:
+ info->protocol= MYSQL_VIO_TCP;
+ info->socket= vio->sd;
+ return;
+ case VIO_TYPE_SOCKET:
+ info->protocol= MYSQL_VIO_SOCKET;
+ info->socket= vio->sd;
+ return;
+ case VIO_TYPE_SSL:
+ {
+ struct sockaddr addr;
+ socklen_t addrlen= sizeof(addr);
+ if (getsockname(vio->sd, &addr, &addrlen))
+ return;
+ info->protocol= addr.sa_family == AF_UNIX ?
+ MYSQL_VIO_SOCKET : MYSQL_VIO_TCP;
+ info->socket= vio->sd;
+ return;
+ }
+#ifdef _WIN32
+ case VIO_TYPE_NAMEDPIPE:
+ info->protocol= MYSQL_VIO_PIPE;
+ info->handle= vio->hPipe;
+ return;
+ case VIO_TYPE_SHARED_MEMORY:
+ info->protocol= MYSQL_VIO_MEMORY;
+ info->handle= vio->handle_client_file_map; /* or what ? */
+ return;
+#endif
+ default: DBUG_ASSERT(0);
+ }
+}
+
+
+static void client_mpvio_info(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_PLUGIN_VIO_INFO *info)
+{
+ MCPVIO_EXT *mpvio= (MCPVIO_EXT*)vio;
+ mpvio_info(mpvio->mysql->net.vio, info);
+}
+
+
+/**
+ Client side of the plugin driver authentication.
+
+ @note this is used by both the mysql_real_connect and mysql_change_user
+
+ @param mysql mysql
+ @param data pointer to the plugin auth data (scramble) in the
+ handshake packet
+ @param data_len the length of the data
+ @param data_plugin a plugin that data were prepared for
+ or 0 if it's mysql_change_user()
+ @param db initial db to use, can be 0
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
+ char *data_plugin, const char *db)
+{
+ const char *auth_plugin_name;
+ auth_plugin_t *auth_plugin;
+ MCPVIO_EXT mpvio;
+ ulong pkt_length;
+ int res;
+
+ /* determine the default/initial plugin to use */
+ if (mysql->options.extension && mysql->options.extension->default_auth &&
+ mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
+ {
+ auth_plugin_name= mysql->options.extension->default_auth;
+ if (!(auth_plugin= (auth_plugin_t*) mysql_client_find_plugin(mysql,
+ auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
+ return 1; /* oops, not found */
+ }
+ else
+ {
+ auth_plugin= mysql->server_capabilities & CLIENT_PROTOCOL_41 ?
+ &native_password_client_plugin : &old_password_client_plugin;
+ auth_plugin_name= auth_plugin->name;
+ }
+
+ mysql->net.last_errno= 0; /* just in case */
+
+ if (data_plugin && strcmp(data_plugin, auth_plugin_name))
+ {
+ /* data was prepared for a different plugin, don't show it to this one */
+ data= 0;
+ data_len= 0;
+ }
+
+ mpvio.mysql_change_user= data_plugin == 0;
+ mpvio.cached_server_reply.pkt= (uchar*)data;
+ mpvio.cached_server_reply.pkt_len= data_len;
+ mpvio.read_packet= client_mpvio_read_packet;
+ mpvio.write_packet= client_mpvio_write_packet;
+ mpvio.info= client_mpvio_info;
+ mpvio.mysql= mysql;
+ mpvio.packets_read= mpvio.packets_written= 0;
+ mpvio.db= db;
+ mpvio.plugin= auth_plugin;
+
+ res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql);
+
+ compile_time_assert(CR_OK == -1);
+ compile_time_assert(CR_ERROR == 0);
+ if (res > CR_OK && mysql->net.read_pos[0] != 254)
+ {
+ /*
+ the plugin returned an error. write it down in mysql,
+ unless the error code is CR_ERROR and mysql->net.last_errno
+ is already set (the plugin has done it)
+ */
+ if (res > CR_ERROR)
+ set_mysql_error(mysql, res, unknown_sqlstate);
+ else
+ if (!mysql->net.last_errno)
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+ return 1;
+ }
+
+ /* read the OK packet (or use the cached value in mysql->net.read_pos */
+ if (res == CR_OK)
+ pkt_length= (*mysql->methods->read_change_user_result)(mysql);
+ else /* res == CR_OK_HANDSHAKE_COMPLETE */
+ pkt_length= mpvio.last_read_packet_len;
+
+ if (pkt_length == packet_error)
+ {
+ if (mysql->net.last_errno == CR_SERVER_LOST)
+ set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "reading authorization packet",
+ errno);
+ return 1;
+ }
+
+ if (mysql->net.read_pos[0] == 254)
+ {
+ /* The server asked to use a different authentication plugin */
+ if (pkt_length == 1)
+ {
+ /* old "use short scramble" packet */
+ auth_plugin_name= old_password_plugin_name;
+ mpvio.cached_server_reply.pkt= (uchar*)mysql->scramble;
+ mpvio.cached_server_reply.pkt_len= SCRAMBLE_LENGTH + 1;
+ }
+ else
+ {
+ /* new "use different plugin" packet */
+ uint len;
+ auth_plugin_name= (char*)mysql->net.read_pos + 1;
+ len= strlen(auth_plugin_name); /* safe as my_net_read always appends \0 */
+ mpvio.cached_server_reply.pkt_len= pkt_length - len - 2;
+ mpvio.cached_server_reply.pkt= mysql->net.read_pos + len + 2;
+ }
+
+ if (!(auth_plugin= (auth_plugin_t *) mysql_client_find_plugin(mysql,
+ auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
+ return 1;
+
+ mpvio.plugin= auth_plugin;
+ res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql);
+
+ if (res > CR_OK)
+ {
+ if (res > CR_ERROR)
+ set_mysql_error(mysql, res, unknown_sqlstate);
+ else
+ if (!mysql->net.last_errno)
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+ return 1;
+ }
+
+ if (res != CR_OK_HANDSHAKE_COMPLETE)
+ {
+ /* Read what server thinks about out new auth message report */
+ if (cli_safe_read(mysql) == packet_error)
+ {
+ if (mysql->net.last_errno == CR_SERVER_LOST)
+ set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "reading final connect information",
+ errno);
+ return 1;
+ }
+ }
+ }
+ /*
+ net->read_pos[0] should always be 0 here if the server implements
+ the protocol correctly
+ */
+ return mysql->net.read_pos[0] != 0;
+}
+
MYSQL * STDCALL
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
@@ -1863,8 +2538,9 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
uint port, const char *unix_socket,ulong client_flag)
{
char buff[NAME_LEN+USERNAME_LENGTH+100];
- char error_string[1024];
- char *end,*host_info= NULL;
+ int scramble_data_len, pkt_scramble_len;
+ char *end, *host_info=0, *server_version_end, *pkt_end;
+ char *scramble_data, *scramble_plugin;
my_socket sock;
in_addr_t ip_addr;
struct sockaddr_in sock_addr;
@@ -2180,8 +2856,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
errno);
goto error;
}
+ pkt_end= (char*)net->read_pos + pkt_length;
/* Check if version of protocol matches current one */
-
mysql->protocol_version= net->read_pos[0];
DBUG_DUMP("packet",(uchar*) net->read_pos,10);
DBUG_PRINT("info",("mysql protocol version %d, server=%d",
@@ -2193,31 +2869,29 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
PROTOCOL_VERSION);
goto error;
}
- end=strend((char*) net->read_pos+1);
+ server_version_end= end= strend((char*) net->read_pos+1);
mysql->thread_id=uint4korr(end+1);
end+=5;
/*
- Scramble is split into two parts because old clients does not understand
+ Scramble is split into two parts because old clients do not understand
long scrambles; here goes the first part.
*/
- strmake(mysql->scramble, end, SCRAMBLE_LENGTH_323);
- end+= SCRAMBLE_LENGTH_323+1;
+ scramble_data= end;
+ scramble_data_len= SCRAMBLE_LENGTH_323 + 1;
+ scramble_plugin= old_password_plugin_name;
+ end+= scramble_data_len;
- if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
+ if (pkt_end >= end + 1)
mysql->server_capabilities=uint2korr(end);
- if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
+ if (pkt_end >= end + 18)
{
/* New protocol with 16 bytes to describe server characteristics */
mysql->server_language=end[2];
mysql->server_status=uint2korr(end+3);
+ mysql->server_capabilities|= uint2korr(end+5) << 16;
+ pkt_scramble_len= end[7];
}
end+= 18;
- if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
- (char *) net->read_pos))
- strmake(mysql->scramble+SCRAMBLE_LENGTH_323, end,
- SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
- else
- mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
if (mysql->options.secure_auth && passwd[0] &&
!(mysql->server_capabilities & CLIENT_SECURE_CONNECTION))
@@ -2236,7 +2910,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
&mysql->unix_socket,unix_socket ?
(uint) strlen(unix_socket)+1 : (uint) 1,
&mysql->server_version,
- (uint) (end - (char*) net->read_pos),
+ (uint) (server_version_end - (char*) net->read_pos + 1),
NullS) ||
!(mysql->user=my_strdup(user,MYF(0))) ||
!(mysql->passwd=my_strdup(passwd,MYF(0))))
@@ -2253,203 +2927,47 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
strmov(mysql->server_version,(char*) net->read_pos+1);
mysql->port=port;
- /*
- Part 2: format and send client info to the server for access check
- */
-
- client_flag|=mysql->options.client_flag;
- client_flag|=CLIENT_CAPABILITIES;
- if (client_flag & CLIENT_MULTI_STATEMENTS)
- client_flag|= CLIENT_MULTI_RESULTS;
-
-#ifdef HAVE_OPENSSL
- if (mysql->options.ssl_key || mysql->options.ssl_cert ||
- mysql->options.ssl_ca || mysql->options.ssl_capath ||
- mysql->options.ssl_cipher)
- mysql->options.use_ssl= 1;
- if (mysql->options.use_ssl)
- client_flag|=CLIENT_SSL;
-#endif /* HAVE_OPENSSL */
- if (db)
- client_flag|=CLIENT_CONNECT_WITH_DB;
-
- /* Remove options that server doesn't support */
- client_flag= ((client_flag &
- ~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
- (client_flag & mysql->server_capabilities));
-#ifndef HAVE_COMPRESS
- client_flag&= ~CLIENT_COMPRESS;
-#endif
-
- if (client_flag & CLIENT_PROTOCOL_41)
- {
- /* 4.1 server and 4.1 client has a 32 byte option flag */
- int4store(buff,client_flag);
- int4store(buff+4, net->max_packet_size);
- buff[8]= (char) mysql->charset->number;
- bzero(buff+9, 32-9);
- end= buff+32;
- }
- else
- {
- int2store(buff,client_flag);
- int3store(buff+2,net->max_packet_size);
- end= buff+5;
- }
- mysql->client_flag=client_flag;
-
-#ifdef HAVE_OPENSSL
- if (client_flag & CLIENT_SSL)
+ if (pkt_end >= end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1)
{
- /* Do the SSL layering. */
- struct st_mysql_options *options= &mysql->options;
- struct st_VioSSLFd *ssl_fd;
-
/*
- Send client_flag, max_packet_size - unencrypted otherwise
- the server does not know we want to do SSL
+ move the first scramble part - directly in the NET buffer -
+ to get a full continuous scramble. We've read all the header,
+ and can overwrite it now.
*/
- if (my_net_write(net, (uchar*) buff, (uint) (end-buff)) || net_flush(net))
- {
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "sending connection information to server",
- errno);
- goto error;
- }
-
- /* Create the VioSSLConnectorFd - init SSL and load certs */
- if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key,
- options->ssl_cert,
- options->ssl_ca,
- options->ssl_capath,
- options->ssl_cipher)))
- {
- set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
- goto error;
- }
- mysql->connector_fd= (void*)ssl_fd;
-
- /* Connect to the server */
- DBUG_PRINT("info", ("IO layer change in progress..."));
- if (sslconnect(ssl_fd, mysql->net.vio,
- (long) (mysql->options.connect_timeout),
- error_string))
- {
- set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR,
- unknown_sqlstate,
- "SSL error: %s",
- error_string[0] ? error_string :
- ER(CR_SSL_CONNECTION_ERROR));
- goto error;
- }
- DBUG_PRINT("info", ("IO layer change done!"));
-
- /* Verify server cert */
- if ((client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
- ssl_verify_server_cert(mysql->net.vio, mysql->host))
- {
- set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
- goto error;
- }
-
- }
-#endif /* HAVE_OPENSSL */
-
- DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
- mysql->server_version,mysql->server_capabilities,
- mysql->server_status, client_flag));
- /* This needs to be changed as it's not useful with big packets */
- if (user && user[0])
- strmake(end,user,USERNAME_LENGTH); /* Max user name */
- else
- read_user_name((char*) end);
-
- /* We have to handle different version of handshake here */
-#ifdef _CUSTOMCONFIG_
-#include "_cust_libmysql.h"
-#endif
- DBUG_PRINT("info",("user: %s",end));
- end= strend(end) + 1;
- if (passwd[0])
- {
- if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- *end++= SCRAMBLE_LENGTH;
- scramble(end, mysql->scramble, passwd);
- end+= SCRAMBLE_LENGTH;
+ memmove(end - SCRAMBLE_LENGTH_323, scramble_data,
+ SCRAMBLE_LENGTH_323);
+ scramble_data= end - SCRAMBLE_LENGTH_323;
+ if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
+ {
+ scramble_data_len= pkt_scramble_len;
+ scramble_plugin= scramble_data + scramble_data_len;
+ if (scramble_data + scramble_data_len > pkt_end)
+ scramble_data_len= pkt_end - scramble_data;
}
else
{
- scramble_323(end, mysql->scramble, passwd);
- end+= SCRAMBLE_LENGTH_323 + 1;
+ scramble_data_len= pkt_end - scramble_data;
+ scramble_plugin= native_password_plugin_name;
}
}
else
- *end++= '\0'; /* empty password */
+ mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
+
+ mysql->client_flag= client_flag;
- /* Add database if needed */
- if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
- {
- end= strmake(end, db, NAME_LEN) + 1;
- mysql->db= my_strdup(db,MYF(MY_WME));
- db= 0;
- }
- /* Write authentication package */
- if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
- {
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "sending authentication information",
- errno);
- goto error;
- }
-
/*
- Part 3: Authorization data's been sent. Now server can reply with
- OK-packet, or re-request scrambled password.
+ Part 2: invoke the plugin to send the authentication data to the server
*/
- if ((pkt_length=cli_safe_read(mysql)) == packet_error)
- {
- if (mysql->net.last_errno == CR_SERVER_LOST)
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "reading authorization packet",
- errno);
+ if (run_plugin_auth(mysql, scramble_data, scramble_data_len,
+ scramble_plugin, db))
goto error;
- }
- if (pkt_length == 1 && net->read_pos[0] == 254 &&
- mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- /*
- By sending this very specific reply server asks us to send scrambled
- password in old format.
- */
- scramble_323(buff, mysql->scramble, passwd);
- if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
- net_flush(net))
- {
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "sending password information",
- errno);
- goto error;
- }
- /* Read what server thinks about out new auth message report */
- if (cli_safe_read(mysql) == packet_error)
- {
- if (mysql->net.last_errno == CR_SERVER_LOST)
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "reading final connect information",
- errno);
- goto error;
- }
- }
+ /*
+ Part 3: authenticated, finish the initialization of the connection
+ */
- if (client_flag & CLIENT_COMPRESS) /* We will use compression */
+ if (mysql->client_flag & CLIENT_COMPRESS) /* We will use compression */
net->compress=1;
#ifdef CHECK_LICENSE
@@ -2457,7 +2975,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
goto error;
#endif
- if (db && mysql_select_db(mysql, db))
+ if (db && !mysql->db && mysql_select_db(mysql, db))
{
if (mysql->net.last_errno == CR_SERVER_LOST)
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
@@ -2510,7 +3028,7 @@ error:
/* Free alloced memory */
end_server(mysql);
mysql_close_free(mysql);
- if (!(((ulong) client_flag) & CLIENT_REMEMBER_OPTIONS))
+ if (!(client_flag & CLIENT_REMEMBER_OPTIONS))
mysql_close_free_options(mysql);
}
DBUG_RETURN(0);
@@ -2655,6 +3173,12 @@ static void mysql_close_free_options(MYS
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif /* HAVE_SMEM */
+ if (mysql->options.extension)
+ {
+ my_free(mysql->options.extension->plugin_dir,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.extension->default_auth,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.extension,MYF(0));
+ }
bzero((char*) &mysql->options,sizeof(mysql->options));
DBUG_VOID_RETURN;
}
@@ -3185,6 +3709,12 @@ mysql_options(MYSQL *mysql,enum mysql_op
else
mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
break;
+ case MYSQL_PLUGIN_DIR:
+ extension_set_string(&mysql->options, plugin_dir, arg);
+ break;
+ case MYSQL_DEFAULT_AUTH:
+ extension_set_string(&mysql->options, default_auth, arg);
+ break;
default:
DBUG_RETURN(1);
}
@@ -3293,3 +3823,99 @@ int STDCALL mysql_set_character_set(MYSQ
}
+/**
+ client authentication plugin that does native MySQL authentication
+ using a 20-byte (4.1+) scramble
+*/
+
+static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ int pkt_len;
+ uchar *pkt;
+
+ if (((MCPVIO_EXT *)vio)->mysql_change_user)
+ {
+ /*
+ in mysql_change_user() the client sends the first packet.
+ we use the old scramble.
+ */
+ pkt= (uchar*)mysql->scramble;
+ pkt_len= SCRAMBLE_LENGTH + 1;
+ }
+ else
+ {
+ /* read the scramble */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ if (pkt_len != SCRAMBLE_LENGTH + 1)
+ return CR_SERVER_HANDSHAKE_ERR;
+
+ /* save it in MYSQL */
+ memcpy(mysql->scramble, pkt, SCRAMBLE_LENGTH);
+ mysql->scramble[SCRAMBLE_LENGTH] = 0;
+ }
+
+ if (mysql->passwd[0])
+ {
+ char scrambled[SCRAMBLE_LENGTH + 1];
+ scramble(scrambled, (char*)pkt, mysql->passwd);
+ if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH))
+ return CR_ERROR;
+ }
+ else
+ if (vio->write_packet(vio, 0, 0)) /* no password */
+ return CR_ERROR;
+
+ return CR_OK;
+}
+
+
+/**
+ client authentication plugin that does old MySQL authentication
+ using an 8-byte (4.0-) scramble
+*/
+
+static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ uchar *pkt;
+ int pkt_len;
+
+ if (((MCPVIO_EXT *)vio)->mysql_change_user)
+ {
+ /*
+ in mysql_change_user() the client sends the first packet.
+ we use the old scramble.
+ */
+ pkt= (uchar*)mysql->scramble;
+ pkt_len= SCRAMBLE_LENGTH_323 + 1;
+ }
+ else
+ {
+ /* read the scramble */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ if (pkt_len != SCRAMBLE_LENGTH_323 + 1 &&
+ pkt_len != SCRAMBLE_LENGTH + 1)
+ return CR_SERVER_HANDSHAKE_ERR;
+
+ /* save it in MYSQL */
+ memcpy(mysql->scramble, pkt, pkt_len);
+ mysql->scramble[pkt_len] = 0;
+ }
+
+ if (mysql->passwd[0])
+ {
+ char scrambled[SCRAMBLE_LENGTH_323 + 1];
+ scramble_323(scrambled, (char*)pkt, mysql->passwd);
+ if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH_323 + 1))
+ return CR_ERROR;
+ }
+ else
+ if (vio->write_packet(vio, 0, 0)) /* no password */
+ return CR_ERROR;
+
+ return CR_OK;
+}
+
=== added file 'sql-common/client_plugin.c'
--- a/sql-common/client_plugin.c 1970-01-01 00:00:00 +0000
+++ b/sql-common/client_plugin.c 2010-03-29 15:13:53 +0000
@@ -0,0 +1,436 @@
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ Support code for the client side (libmysql) plugins
+
+ Client plugins are somewhat different from server plugins, they are simpler.
+
+ They do not need to be installed or in any way explicitly loaded on the
+ client, they are loaded automatically on demand.
+ One client plugin per shared object, soname *must* match the plugin name.
+
+ There is no reference counting and no unloading either.
+*/
+
+#include <my_global.h>
+#include "mysql.h"
+#include <my_sys.h>
+#include <m_string.h>
+#ifdef THREAD
+#include <my_pthread.h>
+#else
+#include <my_no_pthread.h>
+#endif
+
+#include <sql_common.h>
+#include "errmsg.h"
+#include <mysql/client_plugin.h>
+
+struct st_client_plugin_int {
+ struct st_client_plugin_int *next;
+ void *dlhandle;
+ struct st_mysql_client_plugin *plugin;
+};
+
+static my_bool initialized= 0;
+static MEM_ROOT mem_root;
+
+static const char *plugin_declarations_sym= "_mysql_client_plugin_declaration_";
+static uint plugin_version[MYSQL_CLIENT_MAX_PLUGINS]=
+{
+ 0, /* these two are taken by Connector/C */
+ 0, /* these two are taken by Connector/C */
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION
+};
+
+/*
+ Loaded plugins are stored in a linked list.
+ The list is append-only, the elements are added to the head (like in a stack).
+ The elements are added under a mutex, but the list can be read and traversed
+ without any mutex because once an element is added to the list, it stays
+ there. The main purpose of a mutex is to prevent two threads from
+ loading the same plugin twice in parallel.
+*/
+struct st_client_plugin_int *plugin_list[MYSQL_CLIENT_MAX_PLUGINS];
+#ifdef THREAD
+static pthread_mutex_t LOCK_load_client_plugin;
+#endif
+
+static int is_not_initialized(MYSQL *mysql, const char *name)
+{
+ if (initialized)
+ return 0;
+
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
+ unknown_sqlstate, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
+ name, "not initialized");
+ return 1;
+}
+
+
+/**
+ finds a plugin in the list
+
+ @param name plugin name to search for
+ @param type plugin type
+
+ @note this does NOT necessarily need a mutex, take care!
+
+ @retval a pointer to a found plugin or 0
+*/
+
+static struct st_mysql_client_plugin *find_plugin(const char *name, int type)
+{
+ struct st_client_plugin_int *p;
+
+ DBUG_ASSERT(initialized);
+ DBUG_ASSERT(type >= 0 && type < MYSQL_CLIENT_MAX_PLUGINS);
+ if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS)
+ return 0;
+
+ for (p= plugin_list[type]; p; p= p->next)
+ {
+ if (strcmp(p->plugin->name, name) == 0)
+ return p->plugin;
+ }
+ return NULL;
+}
+
+
+/**
+ verifies the plugin and adds it to the list
+
+ @param mysql MYSQL structure (for error reporting)
+ @param plugin plugin to install
+ @param dlhandle a handle to the shared object (returned by dlopen)
+ or 0 if the plugin was not dynamically loaded
+ @param argc number of arguments in the 'va_list args'
+ @param args arguments passed to the plugin initialization function
+
+ @retval a pointer to an installed plugin or 0
+*/
+
+static struct st_mysql_client_plugin *
+add_plugin(MYSQL *mysql, struct st_mysql_client_plugin *plugin, void *dlhandle,
+ int argc, va_list args)
+{
+ const char *errmsg;
+ struct st_client_plugin_int plugin_int, *p;
+ char errbuf[1024];
+
+ DBUG_ASSERT(initialized);
+
+ plugin_int.plugin= plugin;
+ plugin_int.dlhandle= dlhandle;
+
+ if (plugin->type >= MYSQL_CLIENT_MAX_PLUGINS)
+ {
+ errmsg= "Unknown client plugin type";
+ goto err1;
+ }
+
+ if (plugin->interface_version < plugin_version[plugin->type] ||
+ (plugin->interface_version >> 8) >
+ (plugin_version[plugin->type] >> 8))
+ {
+ errmsg= "Incompatible client plugin interface";
+ goto err1;
+ }
+
+ /* Call the plugin initialization function, if any */
+ if (plugin->init && plugin->init(errbuf, sizeof(errbuf), argc, args))
+ {
+ errmsg= errbuf;
+ goto err1;
+ }
+
+ p= (struct st_client_plugin_int *)
+ memdup_root(&mem_root, &plugin_int, sizeof(plugin_int));
+
+ if (!p)
+ {
+ errmsg= "Out of memory";
+ goto err2;
+ }
+
+ safe_mutex_assert_owner(&LOCK_load_client_plugin);
+
+ p->next= plugin_list[plugin->type];
+ plugin_list[plugin->type]= p;
+
+ return plugin;
+
+err2:
+ if (plugin->deinit)
+ plugin->deinit();
+err1:
+ if (dlhandle)
+ dlclose(dlhandle);
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate,
+ ER(CR_AUTH_PLUGIN_CANNOT_LOAD), plugin->name,
+ errmsg);
+ return NULL;
+}
+
+
+/**
+ Loads plugins which are specified in the environment variable
+ LIBMYSQL_PLUGINS.
+
+ Multiple plugins must be separated by semicolon. This function doesn't
+ return or log an error.
+
+ The function is be called by mysql_client_plugin_init
+
+ @todo
+ Support extended syntax, passing parameters to plugins, for example
+ LIBMYSQL_PLUGINS="plugin1(param1,param2);plugin2;..."
+ or
+ LIBMYSQL_PLUGINS="plugin1=int:param1,str:param2;plugin2;..."
+*/
+
+static void load_env_plugins(MYSQL *mysql)
+{
+ char *plugs, *free_env, *s= getenv("LIBMYSQL_PLUGINS");
+
+ /* no plugins to load */
+ if (!s)
+ return;
+
+ free_env= plugs= my_strdup(s, MYF(MY_WME));
+
+ do {
+ if ((s= strchr(plugs, ';')))
+ *s= '\0';
+ mysql_load_plugin(mysql, plugs, -1, 0);
+ plugs= s + 1;
+ } while (s);
+
+ my_free(free_env, MYF(0));
+}
+
+/********** extern functions to be used by libmysql *********************/
+
+/**
+ Initializes the client plugin layer.
+
+ This function must be called before any other client plugin function.
+
+ @retval 0 successful
+ @retval != 0 error occured
+*/
+
+int mysql_client_plugin_init()
+{
+ MYSQL mysql;
+ struct st_mysql_client_plugin **builtin;
+
+ if (initialized)
+ return 0;
+
+ bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */
+
+ pthread_mutex_init(&LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW);
+ init_alloc_root(&mem_root, 128, 128);
+
+ bzero(&plugin_list, sizeof(plugin_list));
+
+ initialized= 1;
+
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ for (builtin= mysql_client_builtins; *builtin; builtin++)
+ add_plugin(&mysql, *builtin, 0, 0, 0);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+
+ load_env_plugins(&mysql);
+
+ return 0;
+}
+
+
+/**
+ Deinitializes the client plugin layer.
+
+ Unloades all client plugins and frees any associated resources.
+*/
+
+void mysql_client_plugin_deinit()
+{
+ int i;
+ struct st_client_plugin_int *p;
+
+ if (!initialized)
+ return;
+
+ for (i=0; i < MYSQL_CLIENT_MAX_PLUGINS; i++)
+ for (p= plugin_list[i]; p; p= p->next)
+ {
+ if (p->plugin->deinit)
+ p->plugin->deinit();
+ if (p->dlhandle)
+ dlclose(p->dlhandle);
+ }
+
+ bzero(&plugin_list, sizeof(plugin_list));
+ initialized= 0;
+ free_root(&mem_root, MYF(0));
+ pthread_mutex_destroy(&LOCK_load_client_plugin);
+}
+
+/************* public facing functions, for client consumption *********/
+
+/* see <mysql/client_plugin.h> for a full description */
+struct st_mysql_client_plugin *
+mysql_client_register_plugin(MYSQL *mysql,
+ struct st_mysql_client_plugin *plugin)
+{
+ if (is_not_initialized(mysql, plugin->name))
+ return NULL;
+
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ /* make sure the plugin wasn't loaded meanwhile */
+ if (find_plugin(plugin->name, plugin->type))
+ {
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
+ unknown_sqlstate, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
+ plugin->name, "it is already loaded");
+ plugin= NULL;
+ }
+ else
+ plugin= add_plugin(mysql, plugin, 0, 0, 0);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+ return plugin;
+}
+
+
+/* see <mysql/client_plugin.h> for a full description */
+struct st_mysql_client_plugin *
+mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
+ int argc, va_list args)
+{
+ const char *errmsg;
+ char dlpath[FN_REFLEN+1];
+ void *sym, *dlhandle;
+ struct st_mysql_client_plugin *plugin;
+
+ if (is_not_initialized(mysql, name))
+ return NULL;
+
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ /* make sure the plugin wasn't loaded meanwhile */
+ if (type >= 0 && find_plugin(name, type))
+ {
+ errmsg= "it is already loaded";
+ goto err;
+ }
+
+ /* Compile dll path */
+ strxnmov(dlpath, sizeof(dlpath) - 1,
+ mysql->options.extension && mysql->options.extension->plugin_dir ?
+ mysql->options.extension->plugin_dir : PLUGINDIR, "/",
+ name, SO_EXT, NullS);
+
+ /* Open new dll handle */
+ if (!(dlhandle= dlopen(dlpath, RTLD_NOW)))
+ {
+ errmsg= dlerror();
+ goto err;
+ }
+
+ if (!(sym= dlsym(dlhandle, plugin_declarations_sym)))
+ {
+ errmsg= "not a plugin";
+ dlclose(dlhandle);
+ goto err;
+ }
+
+ plugin= (struct st_mysql_client_plugin*)sym;
+
+ if (type >=0 && type != plugin->type)
+ {
+ errmsg= "type mismatch";
+ goto err;
+ }
+
+ if (strcmp(name, plugin->name))
+ {
+ errmsg= "name mismatch";
+ goto err;
+ }
+
+ if (type < 0 && find_plugin(name, plugin->type))
+ {
+ errmsg= "it is already loaded";
+ goto err;
+ }
+
+ plugin= add_plugin(mysql, plugin, dlhandle, argc, args);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+
+ return plugin;
+
+err:
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate,
+ ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, errmsg);
+ return NULL;
+}
+
+
+/* see <mysql/client_plugin.h> for a full description */
+struct st_mysql_client_plugin *
+mysql_load_plugin(MYSQL *mysql, const char *name, int type, int argc, ...)
+{
+ struct st_mysql_client_plugin *p;
+ va_list args;
+ va_start(args, argc);
+ p= mysql_load_plugin_v(mysql, name, type, argc, args);
+ va_end(args);
+ return p;
+}
+
+
+/* see <mysql/client_plugin.h> for a full description */
+struct st_mysql_client_plugin *
+mysql_client_find_plugin(MYSQL *mysql, const char *name, int type)
+{
+ struct st_mysql_client_plugin *p;
+
+ if (is_not_initialized(mysql, name))
+ return NULL;
+
+ if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS)
+ {
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate,
+ ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name,
+ "invalid type");
+ }
+
+ if ((p= find_plugin(name, type)))
+ return p;
+
+ /* not found, load it */
+ return mysql_load_plugin(mysql, name, type, 0);
+}
+
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2010-03-03 14:44:14 +0000
+++ b/sql/CMakeLists.txt 2010-03-29 15:13:53 +0000
@@ -54,7 +54,7 @@ SET (SQL_SOURCE
log_event.cc rpl_record.cc rpl_reporting.cc
log_event_old.cc rpl_record_old.cc
message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c
- mysqld.cc net_serv.cc
+ mysqld.cc net_serv.cc ../sql-common/client_plugin.c
nt_servc.cc nt_servc.h opt_range.cc opt_range.h opt_sum.cc
../sql-common/pack.c parse_file.cc password.c procedure.cc
protocol.cc records.cc repl_failsafe.cc rpl_filter.cc set_var.cc
=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am 2010-03-03 14:44:14 +0000
+++ b/sql/Makefile.am 2010-03-29 15:13:53 +0000
@@ -126,7 +126,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.
sql_servers.cc event_parse_data.cc \
opt_table_elimination.cc
-nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
+nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c client_plugin.c
libndb_la_CPPFLAGS= @ndbcluster_includes@
libndb_la_SOURCES= ha_ndbcluster.cc \
@@ -140,10 +140,10 @@ mysql_tzinfo_to_sql_SOURCES = tztime.cc
mysql_tzinfo_to_sql_CXXFLAGS= -DTZINFO2SQL
DEFS = -DMYSQL_SERVER \
- -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
- -DPLUGINDIR="\"$(pkgplugindir)\"" \
+ -DDEFAULT_MYSQL_HOME='"$(MYSQLBASEdir)"' \
+ -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \
+ -DSHAREDIR='"$(MYSQLSHAREdir)"' \
+ -DPLUGINDIR='"$(pkgplugindir)"' \
-DHAVE_EVENT_SCHEDULER \
@DEFS@
@@ -167,6 +167,8 @@ link_sources:
@LN_CP_F@ $(top_srcdir)/sql-common/pack.c pack.c
rm -f client.c
@LN_CP_F@ $(top_srcdir)/sql-common/client.c client.c
+ rm -f client_plugin.c
+ @LN_CP_F@ $(top_srcdir)/sql-common/client_plugin.c client_plugin.c
rm -f my_time.c
@LN_CP_F@ $(top_srcdir)/sql-common/my_time.c my_time.c
rm -f my_user.c
=== modified file 'sql/client_settings.h'
--- a/sql/client_settings.h 2009-08-13 20:07:20 +0000
+++ b/sql/client_settings.h 2010-03-29 15:13:53 +0000
@@ -15,6 +15,7 @@
#include <thr_alarm.h>
+#include <sql_common.h>
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \
CLIENT_SECURE_CONNECTION | CLIENT_TRANSACTIONS | \
@@ -31,7 +32,8 @@
#undef HAVE_SMEM
#undef _CUSTOMCONFIG_
-#define mysql_server_init(a,b,c) 0
+#define mysql_server_init(a,b,c) mysql_client_plugin_init()
+#define mysql_server_end() mysql_client_plugin_deinit()
#ifdef HAVE_REPLICATION
C_MODE_START
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2010-01-06 21:27:53 +0000
+++ b/sql/ha_ndbcluster.cc 2010-03-29 15:13:53 +0000
@@ -9185,7 +9185,7 @@ pthread_handler_t ndb_util_thread_func(v
thd->client_capabilities = 0;
my_net_init(&thd->net, 0);
thd->main_security_ctx.master_access= ~0;
- thd->main_security_ctx.priv_user = 0;
+ thd->main_security_ctx.priv_user[0] = 0;
CHARSET_INFO *charset_connection;
charset_connection= get_charset_by_csname("utf8",
=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc 2009-12-03 11:19:05 +0000
+++ b/sql/ha_ndbcluster_binlog.cc 2010-03-29 15:13:53 +0000
@@ -3681,7 +3681,7 @@ pthread_handler_t ndb_binlog_thread_func
thd->client_capabilities= 0;
my_net_init(&thd->net, 0);
thd->main_security_ctx.master_access= ~0;
- thd->main_security_ctx.priv_user= 0;
+ thd->main_security_ctx.priv_user[0]= 0;
/*
Set up ndb binlog
=== modified file 'sql/lex.h'
--- a/sql/lex.h 2009-11-12 04:31:28 +0000
+++ b/sql/lex.h 2010-03-29 15:13:53 +0000
@@ -590,6 +590,7 @@ static SYMBOL symbols[] = {
{ "VARCHARACTER", SYM(VARCHAR)},
{ "VARIABLES", SYM(VARIABLES)},
{ "VARYING", SYM(VARYING)},
+ { "VIA", SYM(VIA_SYM)},
{ "VIEW", SYM(VIEW_SYM)},
{ "VIRTUAL", SYM(VIRTUAL_SYM)},
{ "WAIT", SYM(WAIT_SYM)},
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2010-03-15 11:51:23 +0000
+++ b/sql/mysql_priv.h 2010-03-29 15:13:53 +0000
@@ -1067,9 +1067,6 @@ int write_bin_log(THD *thd, bool clear_e
char const *query, ulong query_length);
/* sql_connect.cc */
-int check_user(THD *thd, enum enum_server_command command,
- const char *passwd, uint passwd_len, const char *db,
- bool check_count);
pthread_handler_t handle_one_connection(void *arg);
bool init_new_connection_handler_thread();
void reset_mqh(LEX_USER *lu, bool get_them);
@@ -1082,6 +1079,9 @@ bool login_connection(THD *thd);
void end_connection(THD *thd);
void prepare_new_connection_state(THD* thd);
void update_global_user_stats(THD* thd, bool create_user, time_t now);
+int get_or_create_user_conn(THD *thd, const char *user,
+ const char *host, USER_RESOURCES *mqh);
+int check_for_max_user_connections(THD *thd, USER_CONN *uc);
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-29 21:16:12 +0000
+++ b/sql/mysqld.cc 2010-03-31 23:10:03 +0000
@@ -22,6 +22,7 @@
#include "rpl_mi.h"
#include "sql_repl.h"
#include "rpl_filter.h"
+#include "client_settings.h"
#include "repl_failsafe.h"
#include <my_stacktrace.h>
#include "mysqld_suffix.h"
@@ -1394,6 +1395,7 @@ void clean_up(bool print_message)
if (print_message && errmesg && server_start_time)
sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
thread_scheduler.end();
+ mysql_library_end();
finish_client_errs();
my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST),
MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
@@ -3489,6 +3491,7 @@ static int init_common_variables(const c
if (init_errmessage()) /* Read error messages from file */
return 1;
init_client_errs();
+ mysql_library_init(never,never,never); /* for replication */
lex_init();
if (item_create_init())
return 1;
=== modified file 'sql/password.c'
--- a/sql/password.c 2009-09-07 20:50:10 +0000
+++ b/sql/password.c 2010-03-29 15:13:53 +0000
@@ -193,13 +193,13 @@ void scramble_323(char *to, const char *
*/
my_bool
-check_scramble_323(const char *scrambled, const char *message,
+check_scramble_323(const unsigned char *scrambled, const char *message,
ulong *hash_pass)
{
struct my_rnd_struct rand_st;
ulong hash_message[2];
- char buff[16],*to,extra; /* Big enough for check */
- const char *pos;
+ uchar buff[16],*to,extra; /* Big enough for check */
+ const uchar *pos;
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
my_rnd_init(&rand_st,hash_pass[0] ^ hash_message[0],
@@ -214,7 +214,7 @@ check_scramble_323(const char *scrambled
to=buff;
while (*scrambled)
{
- if (*scrambled++ != (char) (*to++ ^ extra))
+ if (*scrambled++ != (uchar) (*to++ ^ extra))
return 1; /* Wrong password */
}
return 0;
@@ -481,7 +481,7 @@ scramble(char *to, const char *message,
*/
my_bool
-check_scramble(const char *scramble_arg, const char *message,
+check_scramble(const uchar *scramble_arg, const char *message,
const uint8 *hash_stage2)
{
SHA1_CONTEXT sha1_context;
@@ -494,7 +494,7 @@ check_scramble(const char *scramble_arg,
mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
mysql_sha1_result(&sha1_context, buf);
/* encrypt scramble */
- my_crypt((char *) buf, buf, (const uchar *) scramble_arg, SCRAMBLE_LENGTH);
+ my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH);
/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
mysql_sha1_reset(&sha1_context);
mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
=== modified file 'sql/protocol.cc'
--- a/sql/protocol.cc 2009-12-03 11:19:05 +0000
+++ b/sql/protocol.cc 2010-03-29 15:13:53 +0000
@@ -341,24 +341,6 @@ static bool write_eof_packet(THD *thd, N
}
/**
- Please client to send scrambled_password in old format.
-
- @param thd thread handle
-
- @retval
- 0 ok
- @retval
- !0 error
-*/
-
-bool send_old_password_request(THD *thd)
-{
- NET *net= &thd->net;
- return my_net_write(net, eof_buff, 1) || net_flush(net);
-}
-
-
-/**
@param thd Thread handler
@param sql_errno The error code to send
@param err A pointer to the error message
=== modified file 'sql/protocol.h'
--- a/sql/protocol.h 2009-12-03 11:19:05 +0000
+++ b/sql/protocol.h 2010-03-29 15:13:53 +0000
@@ -177,7 +177,6 @@ public:
void send_warning(THD *thd, uint sql_errno, const char *err=0);
bool net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
void net_end_statement(THD *thd);
-bool send_old_password_request(THD *thd);
uchar *net_store_data(uchar *to,const uchar *from, size_t length);
uchar *net_store_data(uchar *to,int32 from);
uchar *net_store_data(uchar *to,longlong from);
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_acl.cc 2010-03-31 18:37:45 +0000
@@ -30,6 +30,8 @@
#include <stdarg.h>
#include "sp_head.h"
#include "sp.h"
+#include <sql_common.h>
+#include <mysql/plugin_auth.h>
static const
TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
@@ -148,6 +150,87 @@ TABLE_FIELD_TYPE mysql_db_table_fields[M
const TABLE_FIELD_DEF
mysql_db_table_def= {MYSQL_DB_FIELD_COUNT, mysql_db_table_fields};
+static LEX_STRING native_password_plugin_name= {
+ C_STRING_WITH_LEN("mysql_native_password")
+};
+
+static LEX_STRING old_password_plugin_name= {
+ C_STRING_WITH_LEN("mysql_old_password")
+};
+
+/// @todo make it configurable
+LEX_STRING *default_auth_plugin_name= &native_password_plugin_name;
+
+static plugin_ref native_password_plugin;
+#ifndef EMBEDDED_LIBRARY
+static plugin_ref old_password_plugin;
+#endif
+
+/* Classes */
+
+struct acl_host_and_ip
+{
+ char *hostname;
+ long ip,ip_mask; // Used with masked ip:s
+};
+
+class ACL_ACCESS {
+public:
+ ulong sort;
+ ulong access;
+};
+
+/* ACL_HOST is used if no host is specified */
+
+class ACL_HOST :public ACL_ACCESS
+{
+public:
+ acl_host_and_ip host;
+ char *db;
+};
+
+class ACL_USER :public ACL_ACCESS
+{
+public:
+ acl_host_and_ip host;
+ uint hostname_length;
+ USER_RESOURCES user_resource;
+ char *user;
+ uint8 salt[SCRAMBLE_LENGTH+1]; // scrambled password in binary form
+ uint8 salt_len; // 0 - no password, 4 - 3.20, 8 - 4.0, 20 - 4.1.1
+ enum SSL_type ssl_type;
+ const char *ssl_cipher, *x509_issuer, *x509_subject;
+ LEX_STRING plugin;
+ LEX_STRING auth_string;
+
+ ACL_USER *copy(MEM_ROOT *root)
+ {
+ ACL_USER *dst= (ACL_USER *)alloc_root(root, sizeof(ACL_USER));
+ if (!dst)
+ return 0;
+ *dst= *this;
+ dst->user= safe_strdup_root(root, user);
+ dst->ssl_cipher= safe_strdup_root(root, ssl_cipher);
+ dst->x509_issuer= safe_strdup_root(root, x509_issuer);
+ dst->x509_subject= safe_strdup_root(root, x509_subject);
+ if (plugin.str == native_password_plugin_name.str ||
+ plugin.str == old_password_plugin_name.str)
+ dst->plugin= plugin;
+ else
+ dst->plugin.str= strmake_root(root, plugin.str, plugin.length);
+ dst->auth_string.str = safe_strdup_root(root, auth_string.str);
+ dst->host.hostname= safe_strdup_root(root, host.hostname);
+ return dst;
+ }
+};
+
+class ACL_DB :public ACL_ACCESS
+{
+public:
+ acl_host_and_ip host;
+ char *user,*db;
+};
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#define FIRST_NON_YN_FIELD 26
@@ -171,6 +254,24 @@ static uchar* acl_entry_get_key(acl_entr
#define IP_ADDR_STRLEN (3+1+3+1+3+1+3)
#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1)
+#if defined(HAVE_OPENSSL)
+/*
+ Without SSL the handshake consists of one packet. This packet
+ has both client capabilites and scrambled password.
+ With SSL the handshake might consist of two packets. If the first
+ packet (client capabilities) has CLIENT_SSL flag set, we have to
+ switch to SSL and read the second packet. The scrambled password
+ is in the second packet and client_capabilites field will be ignored.
+ Maybe it is better to accept flags other than CLIENT_SSL from the
+ second packet?
+*/
+#define SSL_HANDSHAKE_SIZE 2
+#define NORMAL_HANDSHAKE_SIZE 6
+#define MIN_HANDSHAKE_SIZE 2
+#else
+#define MIN_HANDSHAKE_SIZE 6
+#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
+
static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs;
static MEM_ROOT mem, memex;
static bool initialized=0;
@@ -265,6 +366,19 @@ my_bool acl_init(bool dont_read_acl_tabl
(hash_get_key) acl_entry_get_key,
(hash_free_key) free,
&my_charset_utf8_bin);
+
+ /*
+ cache built-in native authentication plugins,
+ to avoid hash searches and a global mutex lock on every connect
+ */
+ native_password_plugin= my_plugin_lock_by_name(0,
+ &native_password_plugin_name, MYSQL_AUTHENTICATION_PLUGIN);
+ old_password_plugin= my_plugin_lock_by_name(0,
+ &old_password_plugin_name, MYSQL_AUTHENTICATION_PLUGIN);
+
+ if (!native_password_plugin || !old_password_plugin)
+ DBUG_RETURN(1);
+
if (dont_read_acl_tables)
{
DBUG_RETURN(0); /* purecov: tested */
@@ -422,6 +536,7 @@ static my_bool acl_load(THD *thd, TABLE_
while (!(read_record_info.read_record(&read_record_info)))
{
ACL_USER user;
+ bzero(&user, sizeof(user));
update_hostname(&user.host, get_field(&mem, table->field[0]));
user.user= get_field(&mem, table->field[1]);
if (check_no_resolve && hostname_requires_resolving(user.host.hostname))
@@ -433,27 +548,34 @@ static my_bool acl_load(THD *thd, TABLE_
continue;
}
- const char *password= get_field(thd->mem_root, table->field[2]);
+ char *password= get_field(thd->mem_root, table->field[2]);
uint password_len= password ? strlen(password) : 0;
+ user.auth_string.str= password ? password : const_cast<char*>("");
+ user.auth_string.length= password_len;
set_user_salt(&user, password, password_len);
- if (user.salt_len == 0 && password_len != 0)
- {
- switch (password_len) {
- case 45: /* 4.1: to be removed */
- sql_print_warning("Found 4.1 style password for user '%s@%s'. "
- "Ignoring user. "
- "You should change password for this user.",
- user.user ? user.user : "",
- user.host.hostname ? user.host.hostname : "");
- break;
- default:
- sql_print_warning("Found invalid password for user: '%s@%s'; "
- "Ignoring user", user.user ? user.user : "",
- user.host.hostname ? user.host.hostname : "");
- break;
- }
+
+ switch (password_len) {
+ case 0: /* no password */
+ case SCRAMBLED_PASSWORD_CHAR_LENGTH:
+ user.plugin= native_password_plugin_name;
+ break;
+ case SCRAMBLED_PASSWORD_CHAR_LENGTH_323:
+ user.plugin= old_password_plugin_name;
+ break;
+ case 45: /* 4.1: to be removed */
+ sql_print_warning("Found 4.1.0 style password for user '%s@%s'. "
+ "Ignoring user. "
+ "You should change password for this user.",
+ user.user ? user.user : "",
+ user.host.hostname ? user.host.hostname : "");
+ continue;
+ default:
+ sql_print_warning("Found invalid password for user: '%s@%s'; "
+ "Ignoring user", user.user ? user.user : "",
+ user.host.hostname ? user.host.hostname : "");
+ continue;
}
- else // password is correct
+
{
uint next_field;
user.access= get_access(table,3,&next_field) & GLOBAL_ACLS;
@@ -530,13 +652,43 @@ static my_bool acl_load(THD *thd, TABLE_
ptr= get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
}
- else
- user.user_resource.user_conn= 0;
+
+ if (table->s->fields >= 41)
+ {
+ /* We may have plugin & auth_String fields */
+ char *tmpstr= get_field(&mem, table->field[next_field++]);
+ if (tmpstr)
+ {
+ if (user.auth_string.length)
+ {
+ sql_print_warning("'user' entry '%s@%s' has both a password "
+ "and an authentication plugin specified. The "
+ "password will be ignored.",
+ user.user ? user.user : "",
+ user.host.hostname ? user.host.hostname : "");
+ }
+ if (my_strcasecmp(system_charset_info, tmpstr,
+ native_password_plugin_name.str) == 0)
+ user.plugin= native_password_plugin_name;
+ else
+ if (my_strcasecmp(system_charset_info, tmpstr,
+ old_password_plugin_name.str) == 0)
+ user.plugin= old_password_plugin_name;
+ else
+ {
+ user.plugin.str= tmpstr;
+ user.plugin.length= strlen(tmpstr);
+ }
+ user.auth_string.str= get_field(&mem, table->field[next_field++]);
+ if (!user.auth_string.str)
+ user.auth_string.str= const_cast<char*>("");
+ user.auth_string.length= strlen(user.auth_string.str);
+ }
+ }
}
else
{
user.ssl_type=SSL_TYPE_NONE;
- bzero((char *)&(user.user_resource),sizeof(user.user_resource));
#ifndef TO_BE_REMOVED
if (table->s->fields <= 13)
{ // Without grant
@@ -639,6 +791,8 @@ void acl_free(bool end)
delete_dynamic(&acl_dbs);
delete_dynamic(&acl_wild_hosts);
hash_free(&acl_check_hosts);
+ plugin_unlock(0, native_password_plugin);
+ plugin_unlock(0, old_password_plugin);
if (!end)
acl_cache->clear(1); /* purecov: inspected */
else
@@ -841,246 +995,10 @@ static int acl_compare(ACL_ACCESS *a,ACL
/*
- Seek ACL entry for a user, check password, SSL cypher, and if
- everything is OK, update THD user data and USER_RESOURCES struct.
-
- IMPLEMENTATION
- This function does not check if the user has any sensible privileges:
- only user's existence and validity is checked.
- Note, that entire operation is protected by acl_cache_lock.
+ Gets user credentials without authentication and resource limit checks.
SYNOPSIS
acl_getroot()
- thd thread handle. If all checks are OK,
- thd->security_ctx->priv_user/master_access are updated.
- thd->security_ctx->host/ip/user are used for checks.
- mqh user resources; on success mqh is reset, else
- unchanged
- passwd scrambled & crypted password, received from client
- (to check): thd->scramble or thd->scramble_323 is
- used to decrypt passwd, so they must contain
- original random string,
- passwd_len length of passwd, must be one of 0, 8,
- SCRAMBLE_LENGTH_323, SCRAMBLE_LENGTH
- 'thd' and 'mqh' are updated on success; other params are IN.
-
- RETURN VALUE
- 0 success: thd->priv_user, thd->priv_host, thd->master_access, mqh are
- updated
- 1 user not found or authentication failure
- 2 user found, has long (4.1.1) salt, but passwd is in old (3.23) format.
- -1 user found, has short (3.23) salt, but passwd is in new (4.1.1) format.
-*/
-
-int acl_getroot(THD *thd, USER_RESOURCES *mqh,
- const char *passwd, uint passwd_len)
-{
- ulong user_access= NO_ACCESS;
- int res= 1;
- ACL_USER *acl_user= 0;
- Security_context *sctx= thd->security_ctx;
- DBUG_ENTER("acl_getroot");
-
- if (!initialized)
- {
- /*
- here if mysqld's been started with --skip-grant-tables option.
- */
- sctx->skip_grants();
- bzero((char*) mqh, sizeof(*mqh));
- DBUG_RETURN(0);
- }
-
- VOID(pthread_mutex_lock(&acl_cache->lock));
-
- /*
- Find acl entry in user database. Note, that find_acl_user is not the same,
- because it doesn't take into account the case when user is not empty,
- but acl_user->user is empty
- */
-
- for (uint i=0 ; i < acl_users.elements ; i++)
- {
- ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
- if (!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user))
- {
- if (compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip))
- {
- /* check password: it should be empty or valid */
- if (passwd_len == acl_user_tmp->salt_len)
- {
- if (acl_user_tmp->salt_len == 0 ||
- (acl_user_tmp->salt_len == SCRAMBLE_LENGTH ?
- check_scramble(passwd, thd->scramble, acl_user_tmp->salt) :
- check_scramble_323(passwd, thd->scramble,
- (ulong *) acl_user_tmp->salt)) == 0)
- {
- acl_user= acl_user_tmp;
- res= 0;
- }
- }
- else if (passwd_len == SCRAMBLE_LENGTH &&
- acl_user_tmp->salt_len == SCRAMBLE_LENGTH_323)
- res= -1;
- else if (passwd_len == SCRAMBLE_LENGTH_323 &&
- acl_user_tmp->salt_len == SCRAMBLE_LENGTH)
- res= 2;
- /* linear search complete: */
- break;
- }
- }
- }
- /*
- This was moved to separate tree because of heavy HAVE_OPENSSL case.
- If acl_user is not null, res is 0.
- */
-
- if (acl_user)
- {
- /* OK. User found and password checked continue validation */
-#ifdef HAVE_OPENSSL
- Vio *vio=thd->net.vio;
- SSL *ssl= (SSL*) vio->ssl_arg;
- X509 *cert;
-#endif
-
- /*
- At this point we know that user is allowed to connect
- from given host by given username/password pair. Now
- we check if SSL is required, if user is using SSL and
- if X509 certificate attributes are OK
- */
- switch (acl_user->ssl_type) {
- case SSL_TYPE_NOT_SPECIFIED: // Impossible
- case SSL_TYPE_NONE: // SSL is not required
- user_access= acl_user->access;
- break;
-#ifdef HAVE_OPENSSL
- case SSL_TYPE_ANY: // Any kind of SSL is ok
- if (vio_type(vio) == VIO_TYPE_SSL)
- user_access= acl_user->access;
- break;
- case SSL_TYPE_X509: /* Client should have any valid certificate. */
- /*
- Connections with non-valid certificates are dropped already
- in sslaccept() anyway, so we do not check validity here.
-
- We need to check for absence of SSL because without SSL
- we should reject connection.
- */
- if (vio_type(vio) == VIO_TYPE_SSL &&
- SSL_get_verify_result(ssl) == X509_V_OK &&
- (cert= SSL_get_peer_certificate(ssl)))
- {
- user_access= acl_user->access;
- X509_free(cert);
- }
- break;
- case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */
- /*
- We do not check for absence of SSL because without SSL it does
- not pass all checks here anyway.
- If cipher name is specified, we compare it to actual cipher in
- use.
- */
- if (vio_type(vio) != VIO_TYPE_SSL ||
- SSL_get_verify_result(ssl) != X509_V_OK)
- break;
- if (acl_user->ssl_cipher)
- {
- DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'",
- acl_user->ssl_cipher,SSL_get_cipher(ssl)));
- if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(ssl)))
- user_access= acl_user->access;
- else
- {
- if (global_system_variables.log_warnings)
- sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'",
- acl_user->ssl_cipher,
- SSL_get_cipher(ssl));
- break;
- }
- }
- /* Prepare certificate (if exists) */
- DBUG_PRINT("info",("checkpoint 1"));
- if (!(cert= SSL_get_peer_certificate(ssl)))
- {
- user_access=NO_ACCESS;
- break;
- }
- DBUG_PRINT("info",("checkpoint 2"));
- /* If X509 issuer is specified, we check it... */
- if (acl_user->x509_issuer)
- {
- DBUG_PRINT("info",("checkpoint 3"));
- char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
- DBUG_PRINT("info",("comparing issuers: '%s' and '%s'",
- acl_user->x509_issuer, ptr));
- if (strcmp(acl_user->x509_issuer, ptr))
- {
- if (global_system_variables.log_warnings)
- sql_print_information("X509 issuer mismatch: should be '%s' "
- "but is '%s'", acl_user->x509_issuer, ptr);
- free(ptr);
- X509_free(cert);
- user_access=NO_ACCESS;
- break;
- }
- user_access= acl_user->access;
- free(ptr);
- }
- DBUG_PRINT("info",("checkpoint 4"));
- /* X509 subject is specified, we check it .. */
- if (acl_user->x509_subject)
- {
- char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
- DBUG_PRINT("info",("comparing subjects: '%s' and '%s'",
- acl_user->x509_subject, ptr));
- if (strcmp(acl_user->x509_subject,ptr))
- {
- if (global_system_variables.log_warnings)
- sql_print_information("X509 subject mismatch: should be '%s' but is '%s'",
- acl_user->x509_subject, ptr);
- free(ptr);
- X509_free(cert);
- user_access=NO_ACCESS;
- break;
- }
- user_access= acl_user->access;
- free(ptr);
- }
- /* Deallocate the X509 certificate. */
- X509_free(cert);
- break;
-#else /* HAVE_OPENSSL */
- default:
- /*
- If we don't have SSL but SSL is required for this user the
- authentication should fail.
- */
- break;
-#endif /* HAVE_OPENSSL */
- }
- sctx->master_access= user_access;
- sctx->priv_user= acl_user->user ? sctx->user : (char *) "";
- *mqh= acl_user->user_resource;
-
- if (acl_user->host.hostname)
- strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1);
- else
- *sctx->priv_host= 0;
- }
- VOID(pthread_mutex_unlock(&acl_cache->lock));
- DBUG_RETURN(res);
-}
-
-
-/*
- This is like acl_getroot() above, but it doesn't check password,
- and we don't care about the user resources.
-
- SYNOPSIS
- acl_getroot_no_password()
sctx Context which should be initialized
user user name
host host name
@@ -1092,13 +1010,13 @@ int acl_getroot(THD *thd, USER_RESOURCES
TRUE Error
*/
-bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
- char *ip, char *db)
+bool acl_getroot(Security_context *sctx, char *user, char *host,
+ char *ip, char *db)
{
int res= 1;
uint i;
ACL_USER *acl_user= 0;
- DBUG_ENTER("acl_getroot_no_password");
+ DBUG_ENTER("acl_getroot");
DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', db: '%s'",
(host ? host : "(NULL)"), (ip ? ip : "(NULL)"),
@@ -1121,8 +1039,7 @@ bool acl_getroot_no_password(Security_co
sctx->master_access= 0;
sctx->db_access= 0;
- sctx->priv_user= (char *) "";
- *sctx->priv_host= 0;
+ *sctx->priv_user= *sctx->priv_host= 0;
/*
Find acl entry in user database.
@@ -1164,7 +1081,11 @@ bool acl_getroot_no_password(Security_co
}
}
sctx->master_access= acl_user->access;
- sctx->priv_user= acl_user->user ? user : (char *) "";
+
+ if (acl_user->user)
+ strmake(sctx->priv_user, user, USERNAME_LENGTH);
+ else
+ *sctx->priv_user= 0;
if (acl_user->host.hostname)
strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1);
@@ -1190,7 +1111,9 @@ static void acl_update_user(const char *
const char *x509_issuer,
const char *x509_subject,
USER_RESOURCES *mqh,
- ulong privileges)
+ ulong privileges,
+ const LEX_STRING *plugin,
+ const LEX_STRING *auth)
{
safe_mutex_assert_owner(&acl_cache->lock);
@@ -1204,6 +1127,14 @@ static void acl_update_user(const char *
(acl_user->host.hostname &&
!my_strcasecmp(system_charset_info, host, acl_user->host.hostname)))
{
+ if (plugin->str[0])
+ {
+ acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length);
+ acl_user->plugin.length= plugin->length;
+ acl_user->auth_string.str= auth->str ?
+ strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
+ acl_user->auth_string.length= auth->length;
+ }
acl_user->access=privileges;
if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
acl_user->user_resource.questions=mqh->questions;
@@ -1240,7 +1171,9 @@ static void acl_insert_user(const char *
const char *x509_issuer,
const char *x509_subject,
USER_RESOURCES *mqh,
- ulong privileges)
+ ulong privileges,
+ const LEX_STRING *plugin,
+ const LEX_STRING *auth)
{
ACL_USER acl_user;
@@ -1248,6 +1181,22 @@ static void acl_insert_user(const char *
acl_user.user=*user ? strdup_root(&mem,user) : 0;
update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0);
+ if (plugin->str[0])
+ {
+ acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length);
+ acl_user.plugin.length= plugin->length;
+ acl_user.auth_string.str= auth->str ?
+ strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
+ acl_user.auth_string.length= auth->length;
+ }
+ else
+ {
+ acl_user.plugin= password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 ?
+ old_password_plugin_name : native_password_plugin_name;
+ acl_user.auth_string.str= strmake_root(&mem, password, password_len);
+ acl_user.auth_string.length= password_len;
+ }
+
acl_user.access=privileges;
acl_user.user_resource = *mqh;
acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user);
@@ -1966,6 +1915,15 @@ static int replace_user_table(THD *thd,
thd->security_ctx->user, thd->security_ctx->host_or_ip);
goto end;
}
+ else if (combo.plugin.str[0])
+ {
+ if (!plugin_is_ready(&combo.plugin, MYSQL_AUTHENTICATION_PLUGIN))
+ {
+ my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), combo.plugin.str);
+ goto end;
+ }
+ }
+
old_row_exists = 0;
restore_record(table,s->default_values);
table->field[0]->store(combo.host.str,combo.host.length,
@@ -1979,7 +1937,7 @@ static int replace_user_table(THD *thd,
{
old_row_exists = 1;
store_record(table,record[1]); // Save copy for update
- if (combo.password.str) // If password given
+ if (combo.password.str) // If password given
table->field[2]->store(password, password_len, system_charset_info);
else if (!rights && !revoke_grant &&
lex->ssl_type == SSL_TYPE_NOT_SPECIFIED &&
@@ -2060,7 +2018,17 @@ static int replace_user_table(THD *thd,
(mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS))
table->field[next_field+3]->store((longlong) mqh.user_conn, TRUE);
mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour;
+
+ next_field+=4;
+ if (table->s->fields >= 41 && combo.plugin.str[0])
+ {
+ table->field[next_field]->store(combo.plugin.str, combo.plugin.length,
+ system_charset_info);
+ table->field[next_field+1]->store(combo.auth.str, combo.auth.length,
+ system_charset_info);
+ }
}
+
if (old_row_exists)
{
/*
@@ -2104,7 +2072,9 @@ end:
lex->x509_issuer,
lex->x509_subject,
&lex->mqh,
- rights);
+ rights,
+ &combo.plugin,
+ &combo.auth);
else
acl_insert_user(combo.user.str, combo.host.str, password, password_len,
lex->ssl_type,
@@ -2112,7 +2082,9 @@ end:
lex->x509_issuer,
lex->x509_subject,
&lex->mqh,
- rights);
+ rights,
+ &combo.plugin,
+ &combo.auth);
}
DBUG_RETURN(error);
}
@@ -4445,14 +4417,14 @@ bool check_routine_level_acl(THD *thd, c
ulong get_table_grant(THD *thd, TABLE_LIST *table)
{
ulong privilege;
- Security_context *sctx= thd->security_ctx;
- const char *db = table->db ? table->db : thd->db;
GRANT_TABLE *grant_table;
rw_rdlock(&LOCK_grant);
#ifdef EMBEDDED_LIBRARY
grant_table= NULL;
#else
+ Security_context *sctx= thd->security_ctx;
+ const char *db = table->db ? table->db : thd->db;
grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user,
table->table_name, 0);
#endif
@@ -6328,38 +6300,44 @@ bool sp_grant_privileges(THD *thd, const
tables->db= (char*)sp_db;
tables->table_name= tables->alias= (char*)sp_name;
- combo->host.length= strlen(combo->host.str);
- combo->user.length= strlen(combo->user.str);
- combo->host.str= thd->strmake(combo->host.str,combo->host.length);
- combo->user.str= thd->strmake(combo->user.str,combo->user.length);
+ thd->make_lex_string(&combo->user,
+ combo->user.str, strlen(combo->user.str), 0);
+ thd->make_lex_string(&combo->host,
+ combo->host.str, strlen(combo->host.str), 0);
+ combo->password= empty_lex_str;
+ combo->plugin= empty_lex_str;
+ combo->auth= empty_lex_str;
- if(au && au->salt_len)
+ if(au)
{
- if (au->salt_len == SCRAMBLE_LENGTH)
- {
- make_password_from_salt(passwd_buff, au->salt);
- combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
- }
- else if (au->salt_len == SCRAMBLE_LENGTH_323)
+ if (au->salt_len)
{
- make_password_from_salt_323(passwd_buff, (ulong *) au->salt);
- combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
+ if (au->salt_len == SCRAMBLE_LENGTH)
+ {
+ make_password_from_salt(passwd_buff, au->salt);
+ combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
+ }
+ else if (au->salt_len == SCRAMBLE_LENGTH_323)
+ {
+ make_password_from_salt_323(passwd_buff, (ulong *) au->salt);
+ combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
+ }
+ else
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_PASSWD_LENGTH,
+ ER(ER_PASSWD_LENGTH), SCRAMBLED_PASSWORD_CHAR_LENGTH);
+ return TRUE;
+ }
+ combo->password.str= passwd_buff;
}
- else
+
+ if (au->plugin.str != native_password_plugin_name.str &&
+ au->plugin.str != old_password_plugin_name.str)
{
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_PASSWD_LENGTH,
- ER(ER_PASSWD_LENGTH),
- SCRAMBLED_PASSWORD_CHAR_LENGTH);
- return TRUE;
+ combo->plugin= au->plugin;
+ combo->auth= au->auth_string;
}
- combo->password.str= passwd_buff;
- }
- else
- {
- combo->password.str= (char*)"";
- combo->password.length= 0;
}
if (user_list.push_back(combo))
@@ -6853,3 +6831,1429 @@ bool check_routine_level_acl(THD *thd, c
}
#endif
+
+/****************************************************************************
+ AUTHENTICATION CODE
+ including initial connect handshake, invoking appropriate plugins,
+ client-server plugin negotiation, COM_CHANGE_USER, and native
+ MySQL authentication plugins.
+****************************************************************************/
+
+/* few defines to have less ifdef's in the code below */
+#ifdef EMBEDDED_LIBRARY
+#undef HAVE_OPENSSL
+#ifdef NO_EMBEDDED_ACCESS_CHECKS
+#define initialized 0
+#define decrease_user_connections(X) /* nothing */
+#define check_for_max_user_connections(X,Y) 0
+#endif
+#endif
+#ifndef HAVE_OPENSSL
+#define ssl_acceptor_fd 0
+#define sslaccept(A,B,C,D) 1
+#define NORMAL_HANDSHAKE_SIZE 6
+#endif
+
+/**
+ The internal version of what plugins know as MYSQL_PLUGIN_VIO,
+ basically the context of the authentication session
+*/
+struct MPVIO_EXT : public MYSQL_PLUGIN_VIO
+{
+ MYSQL_SERVER_AUTH_INFO auth_info;
+ THD *thd;
+ ACL_USER *acl_user; ///< a copy, independent from acl_users array
+ plugin_ref plugin; ///< what plugin we're under
+ LEX_STRING db; ///< db name from the handshake packet
+ /** when restarting a plugin this caches the last client reply */
+ struct {
+ char *plugin, *pkt; ///< pointers into NET::buff
+ uint pkt_len;
+ } cached_client_reply;
+ /** this caches the first plugin packet for restart request on the client */
+ struct {
+ char *pkt;
+ uint pkt_len;
+ } cached_server_packet;
+ int packets_read, packets_written; ///< counters for send/received packets
+ uint connect_errors; ///< if there were connect errors for this host
+ /** when plugin returns a failure this tells us what really happened */
+ enum { SUCCESS, FAILURE, RESTART } status;
+};
+
+
+/**
+ a helper function to report an access denied error in all the proper places
+*/
+
+static void login_failed_error(THD *thd, bool passwd_used)
+{
+ my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
+ passwd_used ? ER(ER_YES) : ER(ER_NO));
+ general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
+ passwd_used ? ER(ER_YES) : ER(ER_NO));
+ status_var_increment(thd->status_var.access_denied_errors);
+ /*
+ Log access denied messages to the error log when log-warnings = 2
+ so that the overhead of the general query log is not required to track
+ failed connections.
+ */
+ if (global_system_variables.log_warnings > 1)
+ {
+ sql_print_warning(ER(ER_ACCESS_DENIED_ERROR),
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
+ passwd_used ? ER(ER_YES) : ER(ER_NO));
+ }
+}
+
+
+/**
+ sends a server handshake initialization packet, the very first packet
+ after the connection was established
+
+ Packet format:
+
+ Bytes Content
+ ----- ----
+ 1 protocol version (always 10)
+ n server version string, \0-terminated
+ 4 thread id
+ 8 first 8 bytes of the plugin provided data (scramble)
+ 1 \0 byte, terminating the first part of a scramble
+ 2 server capabilities (two lower bytes)
+ 1 server character set
+ 2 server status
+ 2 server capabilities (two upper bytes)
+ 1 length of the scramble
+ 10 reserved, always 0
+ n rest of the plugin provided data (at least 12 bytes)
+ 1 \0 byte, terminating the second part of a scramble
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
+ const char *data, uint data_len)
+{
+ DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
+ DBUG_ASSERT(data_len <= 255);
+
+ THD *thd= mpvio->thd;
+ char *buff= (char *)my_alloca(1 + SERVER_VERSION_LENGTH + 1 + data_len + 64);
+ char scramble_buf[SCRAMBLE_LENGTH];
+ char *end= buff;
+
+ *end++= protocol_version;
+
+ thd->client_capabilities= CLIENT_BASIC_FLAGS;
+
+ if (data_len)
+ {
+ mpvio->cached_server_packet.pkt= (char*)thd->memdup(data, data_len);
+ mpvio->cached_server_packet.pkt_len= data_len;
+ }
+
+ if (data_len < SCRAMBLE_LENGTH)
+ {
+ if (data_len)
+ { /*
+ the first packet *must* have at least 20 bytes of a scramble.
+ if a plugin provided less, we pad it to 20 with zeros
+ */
+ memcpy(scramble_buf, data, data_len);
+ bzero(scramble_buf+data_len, SCRAMBLE_LENGTH-data_len);
+ data= scramble_buf;
+ }
+ else
+ {
+ /*
+ if the default plugin does not provide the data for the scramble at
+ all, we generate a scramble internally anyway, just in case the
+ user account (that will be known only later) uses a
+ native_password_plugin (which needs a scramble). If we don't send a
+ scramble now - wasting 20 bytes in the packet -
+ native_password_plugin will have to send it in a separate packet,
+ adding one more round trip.
+ */
+ create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+ data= thd->scramble;
+ }
+ data_len= SCRAMBLE_LENGTH;
+ }
+
+ if (opt_using_transactions)
+ thd->client_capabilities|= CLIENT_TRANSACTIONS;
+
+ thd->client_capabilities|= CAN_CLIENT_COMPRESS;
+
+ if (ssl_acceptor_fd)
+ {
+ thd->client_capabilities |= CLIENT_SSL;
+ thd->client_capabilities |= CLIENT_SSL_VERIFY_SERVER_CERT;
+ }
+
+ end= strnmov(end, server_version, SERVER_VERSION_LENGTH) + 1;
+ int4store((uchar*) end, mpvio->thd->thread_id);
+ end+= 4;
+
+ /*
+ Old clients does not understand long scrambles, but can ignore packet
+ tail: that's why first part of the scramble is placed here, and second
+ part at the end of packet.
+ */
+ end= (char*)memcpy(end, data, SCRAMBLE_LENGTH_323);
+ end+= SCRAMBLE_LENGTH_323;
+ *end++= 0;
+
+ int2store(end, thd->client_capabilities);
+ /* write server characteristics: up to 16 bytes allowed */
+ end[2]=(char) default_charset_info->number;
+ int2store(end+3, mpvio->thd->server_status);
+ int2store(end+5, thd->client_capabilities >> 16);
+ end[7]= data_len;
+ bzero(end+8, 10);
+ end+= 18;
+ /* write scramble tail */
+ end= (char*)memcpy(end, data + SCRAMBLE_LENGTH_323,
+ data_len - SCRAMBLE_LENGTH_323);
+ end+= data_len - SCRAMBLE_LENGTH_323;
+ end= strmake(end, plugin_name(mpvio->plugin)->str,
+ plugin_name(mpvio->plugin)->length);
+
+ int res= my_net_write(&mpvio->thd->net, (uchar*) buff, (size_t) (end-buff)) ||
+ net_flush(&mpvio->thd->net);
+ my_afree(buff);
+ return res;
+}
+
+static bool secure_auth(THD *thd)
+{
+ if (!opt_secure_auth)
+ return 0;
+
+ /*
+ If the server is running in secure auth mode, short scrambles are
+ forbidden. Extra juggling to report the same error as the old code.
+ */
+ if (thd->client_capabilities & CLIENT_PROTOCOL_41)
+ {
+ my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
+ thd->security_ctx->user,
+ thd->security_ctx->host_or_ip);
+ general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
+ thd->security_ctx->user,
+ thd->security_ctx->host_or_ip);
+ }
+ else
+ {
+ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
+ general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ }
+ return 1;
+}
+
+/**
+ sends a "change plugin" packet, requesting a client to restart authentication
+ using a different authentication plugin
+
+ Packet format:
+
+ Bytes Content
+ ----- ----
+ 1 byte with the value 254
+ n client plugin to use, \0-terminated
+ n plugin provided data
+
+ In a special case of switching from native_password_plugin to
+ old_password_plugin, the packet contains only one - the first - byte,
+ plugin name is omitted, plugin data aren't needed as the scramble was
+ already sent. This one-byte packet is identical to the "use the short
+ scramble" packet in the protocol before plugins were introduced.
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
+ const uchar *data, uint data_len)
+{
+ DBUG_ASSERT(mpvio->packets_written == 1);
+ DBUG_ASSERT(mpvio->packets_read == 1);
+ NET *net= &mpvio->thd->net;
+ static uchar switch_plugin_request_buf[]= { 254 };
+
+
+ mpvio->status= MPVIO_EXT::FAILURE; // the status is no longer RESTART
+
+ const char *client_auth_plugin=
+ ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
+
+ DBUG_ASSERT(client_auth_plugin);
+
+ /*
+ we send an old "short 4.0 scramble request", if we need to request a
+ client to use 4.0 auth plugin (short scramble) and the scramble was
+ already sent to the client
+
+ below, cached_client_reply.plugin is the plugin name that client has used,
+ client_auth_plugin is derived from mysql.user table, for the given
+ user account, it's the plugin that the client need to use to login.
+ */
+ bool switch_from_long_to_short_scramble=
+ native_password_plugin_name.str == mpvio->cached_client_reply.plugin &&
+ client_auth_plugin == old_password_plugin_name.str;
+
+ if (switch_from_long_to_short_scramble)
+ return secure_auth(mpvio->thd) ||
+ my_net_write(net, switch_plugin_request_buf, 1) ||
+ net_flush(net);
+
+ /*
+ We never request a client to switch from a short to long scramble.
+ Plugin-aware clients can do that, but traditionally it meant to
+ ask an old 4.0 client to use the new 4.1 authentication protocol.
+ */
+ bool switch_from_short_to_long_scramble=
+ old_password_plugin_name.str == mpvio->cached_client_reply.plugin &&
+ client_auth_plugin == native_password_plugin_name.str;
+
+ if (switch_from_short_to_long_scramble)
+ {
+ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
+ general_log_print(mpvio->thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ return 1;
+ }
+
+ return net_write_command(net, switch_plugin_request_buf[0],
+ (uchar*)client_auth_plugin,
+ strlen(client_auth_plugin)+1,
+ (uchar*)data, data_len);
+}
+
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+/**
+ Finds acl entry in user database for authentication purposes.
+
+ Finds a user and copies it into mpvio. Reports an authentication
+ failure if a user is not found.
+
+ @note find_acl_user is not the same, because it doesn't take into
+ account the case when user is not empty, but acl_user->user is empty
+
+ @retval 0 found
+ @retval 1 not found
+*/
+
+static bool find_mpvio_user(MPVIO_EXT *mpvio, Security_context *sctx)
+{
+ DBUG_ASSERT(mpvio->acl_user == 0);
+
+ pthread_mutex_lock(&acl_cache->lock);
+ for (uint i=0 ; i < acl_users.elements ; i++)
+ {
+ ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
+ if ((!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user)) &&
+ compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip))
+ {
+ mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&acl_cache->lock);
+
+ if (!mpvio->acl_user)
+ {
+ login_failed_error(mpvio->thd, 0);
+ return 1;
+ }
+
+ /* user account requires non-default plugin and the client is too old */
+ if (mpvio->acl_user->plugin.str != native_password_plugin_name.str &&
+ mpvio->acl_user->plugin.str != old_password_plugin_name.str &&
+ !(mpvio->thd->client_capabilities & CLIENT_PLUGIN_AUTH))
+ {
+ DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ native_password_plugin_name.str));
+ DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ old_password_plugin_name.str));
+ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
+ general_log_print(mpvio->thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ return 1;
+ }
+
+ mpvio->auth_info.user_name= sctx->user;
+ mpvio->auth_info.auth_string= mpvio->acl_user->auth_string.str;
+ strmake(mpvio->auth_info.authenticated_as, mpvio->acl_user->user ?
+ mpvio->acl_user->user : "", USERNAME_LENGTH);
+
+ return 0;
+}
+#endif
+
+
+/* the packet format is described in send_change_user_packet() */
+static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
+{
+ THD *thd= mpvio->thd;
+ NET *net= &thd->net;
+ Security_context *sctx= thd->security_ctx;
+
+ char *user= (char*) net->read_pos;
+ char *end= user + packet_length;
+ /* Safe because there is always a trailing \0 at the end of the packet */
+ char *passwd= strend(user)+1;
+ uint user_len= passwd - user - 1;
+ char *db= passwd;
+ char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
+ char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
+ uint dummy_errors;
+
+ if (passwd >= end)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ return 1;
+ }
+
+ /*
+ Old clients send null-terminated string as password; new clients send
+ the size (1 byte) + string (not null-terminated). Hence in case of empty
+ password both send '\0'.
+
+ This strlen() can't be easily deleted without changing protocol.
+
+ Cast *passwd to an unsigned char, so that it doesn't extend the sign for
+ *passwd > 127 and become 2**32-127+ after casting to uint.
+ */
+ uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ (uchar)(*passwd++) : strlen(passwd));
+
+ db+= passwd_len + 1;
+ /*
+ Database name is always NUL-terminated, so in case of empty database
+ the packet must contain at least the trailing '\0'.
+ */
+ if (db >= end)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ return 1;
+ }
+
+ uint db_len= strlen(db);
+
+ char *ptr= db + db_len + 1;
+
+ if (ptr+1 < end)
+ {
+ uint cs_number= uint2korr(ptr);
+ thd_init_client_charset(thd, cs_number);
+ thd->update_charset();
+ }
+
+ /* Convert database and user names to utf8 */
+ db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info,
+ db, db_len, thd->charset(), &dummy_errors);
+
+ user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
+ system_charset_info, user, user_len,
+ thd->charset(), &dummy_errors);
+
+ if (!(sctx->user= my_strndup(user_buff, user_len, MYF(MY_WME))))
+ return 1;
+
+ /* Clear variables that are allocated */
+ thd->user_connect= 0;
+ strmake(sctx->priv_user, sctx->user, USERNAME_LENGTH);
+
+ if (thd->make_lex_string(&mpvio->db, db_buff, db_len, 0) == 0)
+ return 1; /* The error is set by make_lex_string(). */
+
+ /*
+ Clear thd->db as it points to something, that will be freed when
+ connection is closed. We don't want to accidentally free a wrong
+ pointer if connect failed.
+ */
+ thd->reset_db(NULL, 0);
+
+ if (!initialized)
+ {
+ // if mysqld's been started with --skip-grant-tables option
+ mpvio->status= MPVIO_EXT::SUCCESS;
+ return 0;
+ }
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ if (find_mpvio_user(mpvio, sctx))
+ return 1;
+
+ char *client_plugin;
+ if (thd->client_capabilities & CLIENT_PLUGIN_AUTH)
+ {
+ client_plugin= ptr + 2;
+ if (client_plugin >= end)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ return 1;
+ }
+ }
+ else
+ {
+ if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
+ client_plugin= native_password_plugin_name.str;
+ else
+ {
+ client_plugin= old_password_plugin_name.str;
+ /*
+ For a passwordless accounts we use native_password_plugin.
+ But when an old 4.0 client connects to it, we change it to
+ old_password_plugin, otherwise MySQL will think that server
+ and client plugins don't match.
+ */
+ if (mpvio->acl_user->auth_string.length == 0)
+ mpvio->acl_user->plugin= old_password_plugin_name;
+ }
+ }
+
+ /* remember the data part of the packet, to present it to plugin in read_packet() */
+ mpvio->cached_client_reply.pkt= passwd;
+ mpvio->cached_client_reply.pkt_len= passwd_len;
+ mpvio->cached_client_reply.plugin= client_plugin;
+ mpvio->status= MPVIO_EXT::RESTART;
+#endif
+
+ return 0;
+}
+
+
+/* the packet format is described in send_client_reply_packet() */
+static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
+ uchar **buff, ulong pkt_len)
+{
+#ifndef EMBEDDED_LIBRARY
+ THD *thd= mpvio->thd;
+ NET *net= &thd->net;
+ char *end;
+
+ DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
+
+ if (pkt_len < MIN_HANDSHAKE_SIZE)
+ return packet_error;
+
+ if (mpvio->connect_errors)
+ reset_host_errors(&net->vio->remote.sin_addr);
+
+ ulong client_capabilities= uint2korr(net->read_pos);
+ if (client_capabilities & CLIENT_PROTOCOL_41)
+ {
+ client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
+ thd->max_client_packet_length= uint4korr(net->read_pos+4);
+ DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
+ thd_init_client_charset(thd, (uint) net->read_pos[8]);
+ thd->update_charset();
+ end= (char*) net->read_pos+32;
+ }
+ else
+ {
+ thd->max_client_packet_length= uint3korr(net->read_pos+2);
+ end= (char*) net->read_pos+5;
+ }
+
+ /* Disable those bits which are not supported by the client. */
+ thd->client_capabilities&= client_capabilities;
+
+ if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
+ thd->variables.sql_mode|= MODE_IGNORE_SPACE;
+
+ DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
+ if (thd->client_capabilities & CLIENT_SSL)
+ {
+ char error_string[1024] __attribute__((unused));
+
+ /* Do the SSL layering. */
+ if (!ssl_acceptor_fd)
+ return packet_error;
+
+ DBUG_PRINT("info", ("IO layer change in progress..."));
+ if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, error_string))
+ {
+ DBUG_PRINT("error", ("Failed to accept new SSL connection"));
+ return packet_error;
+ }
+
+ DBUG_PRINT("info", ("Reading user information over SSL layer"));
+ pkt_len= my_net_read(net);
+ if (pkt_len == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE)
+ {
+ DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
+ pkt_len));
+ return packet_error;
+ }
+ }
+
+ if (end >= (char*) net->read_pos+ pkt_len +2)
+ return packet_error;
+
+ if (thd->client_capabilities & CLIENT_INTERACTIVE)
+ thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
+ if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
+ opt_using_transactions)
+ net->return_status= &thd->server_status;
+
+ char *user= end;
+ char *passwd= strend(user)+1;
+ uint user_len= passwd - user - 1, db_len;
+ char *db= passwd;
+ char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
+ char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
+ uint dummy_errors;
+
+ /*
+ Old clients send null-terminated string as password; new clients send
+ the size (1 byte) + string (not null-terminated). Hence in case of empty
+ password both send '\0'.
+
+ This strlen() can't be easily deleted without changing protocol.
+
+ Cast *passwd to an unsigned char, so that it doesn't extend the sign for
+ *passwd > 127 and become 2**32-127+ after casting to uint.
+ */
+ uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ (uchar)(*passwd++) : strlen(passwd);
+
+ if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
+ {
+ db= db + passwd_len + 1;
+ /* strlen() can't be easily deleted without changing protocol */
+ db_len= strlen(db);
+ }
+ else
+ {
+ db= 0;
+ db_len= 0;
+ }
+
+ if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
+ return packet_error;
+
+ char *client_plugin= passwd + passwd_len + (db ? db_len + 1 : 0);
+
+ /* Since 4.1 all database names are stored in utf8 */
+ if (db)
+ {
+ db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info,
+ db, db_len, thd->charset(), &dummy_errors);
+ db= db_buff;
+ }
+
+ user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
+ system_charset_info, user, user_len,
+ thd->charset(), &dummy_errors);
+ user= user_buff;
+
+ /* If username starts and ends in "'", chop them off */
+ if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
+ {
+ user++;
+ user_len-= 2;
+ }
+
+ Security_context *sctx= thd->security_ctx;
+
+ if (thd->make_lex_string(&mpvio->db, db, db_len, 0) == 0)
+ return packet_error; /* The error is set by make_lex_string(). */
+ if (sctx->user)
+ x_free(sctx->user);
+ if (!(sctx->user= my_strndup(user, user_len, MYF(MY_WME))))
+ return packet_error; /* The error is set by my_strdup(). */
+
+ /*
+ Clear thd->db as it points to something, that will be freed when
+ connection is closed. We don't want to accidentally free a wrong
+ pointer if connect failed.
+ */
+ thd->reset_db(NULL, 0);
+
+ if (!initialized)
+ {
+ // if mysqld's been started with --skip-grant-tables option
+ mpvio->status= MPVIO_EXT::SUCCESS;
+ return packet_error;
+ }
+
+ if (find_mpvio_user(mpvio, sctx))
+ return packet_error;
+
+ if (thd->client_capabilities & CLIENT_PLUGIN_AUTH)
+ {
+ if ((client_plugin + strlen(client_plugin)) >
+ (char *)net->read_pos + pkt_len)
+ return packet_error;
+ }
+ else
+ {
+ if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
+ client_plugin= native_password_plugin_name.str;
+ else
+ {
+ client_plugin= old_password_plugin_name.str;
+ /*
+ For a passwordless accounts we use native_password_plugin.
+ But when an old 4.0 client connects to it, we change it to
+ old_password_plugin, otherwise MySQL will think that server
+ and client plugins don't match.
+ */
+ if (mpvio->acl_user->auth_string.length == 0)
+ mpvio->acl_user->plugin= old_password_plugin_name;
+ }
+ }
+
+ /*
+ if the acl_user needs a different plugin to authenticate
+ (specified in GRANT ... AUTHENTICATED VIA plugin_name ..)
+ we need to restart the authentication in the server.
+ But perhaps the client has already used the correct plugin -
+ in that case the authentication on the client may not need to be
+ restarted and a server auth plugin will read the data that the client
+ has just send. Cache them to return in the next server_mpvio_read_packet().
+ */
+ if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ plugin_name(mpvio->plugin)->str) != 0)
+ {
+ mpvio->cached_client_reply.pkt= passwd;
+ mpvio->cached_client_reply.pkt_len= passwd_len;
+ mpvio->cached_client_reply.plugin= client_plugin;
+ mpvio->status= MPVIO_EXT::RESTART;
+ return packet_error;
+ }
+
+ /*
+ ok, we don't need to restart the authentication on the server.
+ but if the client used the wrong plugin, we need to restart
+ the authentication on the client. Do it here, the server plugin
+ doesn't need to know.
+ */
+ const char *client_auth_plugin=
+ ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
+
+ if (client_auth_plugin &&
+ my_strcasecmp(system_charset_info, client_plugin, client_auth_plugin))
+ {
+ mpvio->cached_client_reply.plugin= client_plugin;
+ if (send_plugin_request_packet(mpvio,
+ (uchar*)mpvio->cached_server_packet.pkt,
+ mpvio->cached_server_packet.pkt_len))
+ return packet_error;
+
+ passwd_len= my_net_read(&mpvio->thd->net);
+ passwd = (char*)mpvio->thd->net.read_pos;
+ }
+
+ *buff= (uchar*)passwd;
+ return passwd_len;
+#else
+ return 0;
+#endif
+}
+
+
+/**
+ vio->write_packet() callback method for server authentication plugins
+
+ This function is called by a server authentication plugin, when it wants
+ to send data to the client.
+
+ It transparently wraps the data into a handshake packet,
+ and handles plugin negotiation with the client. If necessary,
+ it escapes the plugin data, if it starts with a mysql protocol packet byte.
+*/
+
+static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param,
+ const uchar *packet, int packet_len)
+{
+ MPVIO_EXT *mpvio= (MPVIO_EXT*)param;
+ int res;
+
+ /* reset cached_client_reply */
+ mpvio->cached_client_reply.pkt= 0;
+ /* for the 1st packet we wrap plugin data into the handshake packet */
+ if (mpvio->packets_written == 0)
+ res= send_server_handshake_packet(mpvio, (char*)packet, packet_len);
+ else if (mpvio->status == MPVIO_EXT::RESTART)
+ res= send_plugin_request_packet(mpvio, packet, packet_len);
+ else if (packet_len > 0 && (*packet == 1 || *packet == 255 || *packet == 254))
+ {
+ /*
+ we cannot allow plugin data packet to start from 255 or 254 -
+ as the client will treat it as an error or "change plugin" packet.
+ We'll escape these bytes with \1. Consequently, we
+ have to escape \1 byte too.
+ */
+ res= net_write_command(&mpvio->thd->net, 1, (uchar*)"", 0,
+ packet, packet_len);
+ }
+ else
+ {
+ res= my_net_write(&mpvio->thd->net, packet, packet_len) ||
+ net_flush(&mpvio->thd->net);
+ }
+ mpvio->packets_written++;
+ return res;
+}
+
+
+/**
+ vio->read_packet() callback method for server authentication plugins
+
+ This function is called by a server authentication plugin, when it wants
+ to read data from the client.
+
+ It transparently extracts the client plugin data, if embedded into
+ a client authentication handshake packet, and handles plugin negotiation
+ with the client, if necessary.
+*/
+
+static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf)
+{
+ MPVIO_EXT *mpvio= (MPVIO_EXT*)param;
+ ulong pkt_len;
+
+ if (mpvio->packets_written == 0)
+ {
+ /*
+ plugin wants to read the data without sending anything first.
+ send an empty packet to force a server handshake packet to be sent
+ */
+ if (server_mpvio_write_packet(mpvio, 0, 0))
+ pkt_len= packet_error;
+ else
+ pkt_len= my_net_read(&mpvio->thd->net);
+ }
+ else
+ if (mpvio->cached_client_reply.pkt)
+ {
+ DBUG_ASSERT(mpvio->status == MPVIO_EXT::RESTART);
+ DBUG_ASSERT(mpvio->packets_read > 0);
+ /*
+ if the have the data cached from the last server_mpvio_read_packet
+ (which can be the case if it's a restarted authentication)
+ and a client has used the correct plugin, then we can return the
+ cached data straight away and avoid one round trip.
+ */
+ const char *client_auth_plugin=
+ ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
+ if (client_auth_plugin == 0 ||
+ my_strcasecmp(system_charset_info, mpvio->cached_client_reply.plugin,
+ client_auth_plugin) == 0)
+ {
+ mpvio->status= MPVIO_EXT::FAILURE;
+ *buf= (uchar*)mpvio->cached_client_reply.pkt;
+ mpvio->cached_client_reply.pkt= 0;
+ mpvio->packets_read++;
+ return (int)mpvio->cached_client_reply.pkt_len;
+ }
+ /*
+ But if the client has used the wrong plugin, the cached data are
+ useless. Furthermore, we have to send a "change plugin" request
+ to the client.
+ */
+ if (server_mpvio_write_packet(mpvio, 0, 0))
+ pkt_len= packet_error;
+ else
+ pkt_len= my_net_read(&mpvio->thd->net);
+ }
+ else
+ pkt_len= my_net_read(&mpvio->thd->net);
+
+ if (pkt_len == packet_error)
+ goto err;
+
+ mpvio->packets_read++;
+
+ /*
+ the 1st packet has the plugin data wrapped into the client authentication
+ handshake packet
+ */
+ if (mpvio->packets_read == 1)
+ {
+ pkt_len= parse_client_handshake_packet(mpvio, buf, pkt_len);
+ if (pkt_len == packet_error)
+ goto err;
+ }
+ else
+ *buf = mpvio->thd->net.read_pos;
+
+ return (int)pkt_len;
+
+err:
+ if (mpvio->status == MPVIO_EXT::FAILURE && !mpvio->thd->is_error())
+ {
+ inc_host_errors(&mpvio->thd->net.vio->remote.sin_addr);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0),
+ mpvio->thd->security_ctx->host_or_ip);
+ }
+ return -1;
+}
+
+
+/**
+ fills MYSQL_PLUGIN_VIO_INFO structure with the information about the
+ connection
+*/
+
+static void server_mpvio_info(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_PLUGIN_VIO_INFO *info)
+{
+ MPVIO_EXT *mpvio= (MPVIO_EXT*)vio;
+ mpvio_info(mpvio->thd->net.vio, info);
+}
+
+
+static bool acl_check_ssl(THD *thd, ACL_USER *acl_user)
+{
+#if defined(HAVE_OPENSSL)
+ Vio *vio=thd->net.vio;
+ SSL *ssl= (SSL*) vio->ssl_arg;
+ X509 *cert;
+#endif
+
+ /*
+ At this point we know that user is allowed to connect
+ from given host by given username/password pair. Now
+ we check if SSL is required, if user is using SSL and
+ if X509 certificate attributes are OK
+ */
+ switch (acl_user->ssl_type) {
+ case SSL_TYPE_NOT_SPECIFIED: // Impossible
+ case SSL_TYPE_NONE: // SSL is not required
+ return 0;
+#if defined(HAVE_OPENSSL)
+ case SSL_TYPE_ANY: // Any kind of SSL is ok
+ return vio_type(vio) != VIO_TYPE_SSL;
+ case SSL_TYPE_X509: /* Client should have any valid certificate. */
+ /*
+ Connections with non-valid certificates are dropped already
+ in sslaccept() anyway, so we do not check validity here.
+
+ We need to check for absence of SSL because without SSL
+ we should reject connection.
+ */
+ if (vio_type(vio) == VIO_TYPE_SSL &&
+ SSL_get_verify_result(ssl) == X509_V_OK &&
+ (cert= SSL_get_peer_certificate(ssl)))
+ {
+ X509_free(cert);
+ return 0;
+ }
+ return 1;
+ case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */
+ /* If a cipher name is specified, we compare it to actual cipher in use. */
+ if (vio_type(vio) != VIO_TYPE_SSL ||
+ SSL_get_verify_result(ssl) != X509_V_OK)
+ return 1;
+ if (acl_user->ssl_cipher)
+ {
+ DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'",
+ acl_user->ssl_cipher,SSL_get_cipher(ssl)));
+ if (strcmp(acl_user->ssl_cipher,SSL_get_cipher(ssl)))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'",
+ acl_user->ssl_cipher, SSL_get_cipher(ssl));
+ return 1;
+ }
+ }
+ /* Prepare certificate (if exists) */
+ if (!(cert= SSL_get_peer_certificate(ssl)))
+ return 1;
+ /* If X509 issuer is specified, we check it... */
+ if (acl_user->x509_issuer)
+ {
+ char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
+ DBUG_PRINT("info",("comparing issuers: '%s' and '%s'",
+ acl_user->x509_issuer, ptr));
+ if (strcmp(acl_user->x509_issuer, ptr))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_information("X509 issuer mismatch: should be '%s' "
+ "but is '%s'", acl_user->x509_issuer, ptr);
+ free(ptr);
+ X509_free(cert);
+ return 1;
+ }
+ free(ptr);
+ }
+ /* X509 subject is specified, we check it .. */
+ if (acl_user->x509_subject)
+ {
+ char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
+ DBUG_PRINT("info",("comparing subjects: '%s' and '%s'",
+ acl_user->x509_subject, ptr));
+ if (strcmp(acl_user->x509_subject,ptr))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_information("X509 subject mismatch: should be '%s' but is '%s'",
+ acl_user->x509_subject, ptr);
+ free(ptr);
+ X509_free(cert);
+ return 1;
+ }
+ free(ptr);
+ }
+ X509_free(cert);
+ return 0;
+#else /* HAVE_OPENSSL */
+ default:
+ /*
+ If we don't have SSL but SSL is required for this user the
+ authentication should fail.
+ */
+ return 1;
+#endif /* HAVE_OPENSSL */
+ }
+ return 1;
+}
+
+static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name,
+ MPVIO_EXT *mpvio)
+{
+ int res= CR_OK, old_status= MPVIO_EXT::FAILURE;
+ bool unlock_plugin= false;
+ plugin_ref plugin;
+
+ if (auth_plugin_name->str == native_password_plugin_name.str)
+ plugin= native_password_plugin;
+ else
+#ifndef EMBEDDED_LIBRARY
+ if (auth_plugin_name->str == old_password_plugin_name.str)
+ plugin= old_password_plugin;
+ else
+ if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
+ MYSQL_AUTHENTICATION_PLUGIN)))
+ unlock_plugin= true;
+#endif
+
+ mpvio->plugin= plugin;
+ old_status= mpvio->status;
+
+ if (plugin)
+ {
+ st_mysql_auth *auth= (st_mysql_auth*)plugin_decl(plugin)->info;
+ res= auth->authenticate_user(mpvio, &mpvio->auth_info);
+
+ if (unlock_plugin)
+ plugin_unlock(thd, plugin);
+ }
+ else
+ {
+ /* Server cannot load the required plugin. */
+ my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name->str);
+ res= CR_ERROR;
+ }
+
+ /*
+ If the status was MPVIO_EXT::RESTART before the authenticate_user() call
+ it can never be MPVIO_EXT::RESTART after the call, because any call
+ to write_packet() or read_packet() will reset the status.
+
+ But (!) if a plugin never called a read_packet() or write_packet(), the
+ status will stay unchanged. We'll fix it, by resetting the status here.
+ */
+ if (old_status == MPVIO_EXT::RESTART && mpvio->status == MPVIO_EXT::RESTART)
+ mpvio->status= MPVIO_EXT::FAILURE; // reset to the default
+
+ return res;
+}
+
+/**
+ Perform the handshake, authorize the client and update thd sctx variables.
+
+ @param thd thread handle
+ @param connect_errors number of previous failed connect attemps
+ from this host
+ @param com_change_user_pkt_len size of the COM_CHANGE_USER packet
+ (without the first, command, byte) or 0
+ if it's not a COM_CHANGE_USER (that is, if
+ it's a new connection)
+
+ @retval 0 success, thd is updated.
+ @retval 1 error
+*/
+
+bool acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len)
+{
+ int res= CR_OK;
+ MPVIO_EXT mpvio;
+ LEX_STRING *auth_plugin_name= default_auth_plugin_name;
+ enum enum_server_command command= com_change_user_pkt_len ? COM_CHANGE_USER
+ : COM_CONNECT;
+ DBUG_ENTER("acl_authenticate");
+
+ compile_time_assert(MYSQL_USERNAME_LENGTH == USERNAME_LENGTH);
+
+ bzero(&mpvio, sizeof(mpvio));
+ mpvio.read_packet= server_mpvio_read_packet;
+ mpvio.write_packet= server_mpvio_write_packet;
+ mpvio.info= server_mpvio_info;
+ mpvio.thd= thd;
+ mpvio.connect_errors= connect_errors;
+ mpvio.status= MPVIO_EXT::FAILURE;
+
+ if (command == COM_CHANGE_USER)
+ {
+ mpvio.packets_written++; // pretend that a server handshake packet was sent
+ mpvio.packets_read++; // take COM_CHANGE_USER packet into account
+
+ if (parse_com_change_user_packet(&mpvio, com_change_user_pkt_len))
+ DBUG_RETURN(1);
+
+ DBUG_ASSERT(mpvio.status == MPVIO_EXT::RESTART ||
+ mpvio.status == MPVIO_EXT::SUCCESS);
+ }
+ else
+ {
+ /* mark the thd as having no scramble yet */
+ thd->scramble[SCRAMBLE_LENGTH]= 1;
+
+ /*
+ perform the first authentication attempt, with the default plugin.
+ This sends the server handshake packet, reads the client reply
+ with a user name, and performs the authentication if everyone has used
+ the correct plugin.
+ */
+ res= do_auth_once(thd, auth_plugin_name, &mpvio);
+ }
+
+ /*
+ retry the authentication, if - after receiving the user name -
+ we found that we need to switch to a non-default plugin
+ */
+ if (mpvio.status == MPVIO_EXT::RESTART)
+ {
+ DBUG_ASSERT(mpvio.acl_user);
+ DBUG_ASSERT(command == COM_CHANGE_USER ||
+ my_strcasecmp(system_charset_info, auth_plugin_name->str,
+ mpvio.acl_user->plugin.str));
+ auth_plugin_name= &mpvio.acl_user->plugin;
+ res= do_auth_once(thd, auth_plugin_name, &mpvio);
+ }
+
+ Security_context *sctx= thd->security_ctx;
+ ACL_USER *acl_user= mpvio.acl_user;
+
+ thd->password= mpvio.auth_info.password_used; // remember for error messages
+
+ /*
+ Log the command here so that the user can check the log
+ for the tried logins and also to detect break-in attempts.
+
+ if sctx->user is unset it's protocol failure, bad packet.
+ */
+ if (sctx->user)
+ {
+ if (strcmp(sctx->priv_user, sctx->user))
+ {
+ general_log_print(thd, command, "%s@%s as %s on %s",
+ sctx->user, sctx->host_or_ip,
+ sctx->priv_user[0] ? sctx->priv_user : "anonymous",
+ mpvio.db.str ? mpvio.db.str : (char*) "");
+ }
+ else
+ general_log_print(thd, command, (char*) "%s@%s on %s",
+ sctx->user, sctx->host_or_ip,
+ mpvio.db.str ? mpvio.db.str : (char*) "");
+ }
+
+ if (res > CR_OK && mpvio.status != MPVIO_EXT::SUCCESS)
+ {
+ DBUG_ASSERT(mpvio.status == MPVIO_EXT::FAILURE);
+
+ if (!thd->is_error())
+ login_failed_error(thd, thd->password);
+ DBUG_RETURN(1);
+ }
+
+ if (initialized) // if not --skip-grant-tables
+ {
+ sctx->master_access= acl_user->access;
+ strmake(sctx->priv_user, mpvio.auth_info.authenticated_as, USERNAME_LENGTH);
+ if (acl_user->host.hostname)
+ strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
+ else
+ *sctx->priv_host= 0;
+
+ /*
+ OK. Let's check the SSL. Historically it was checked after the password,
+ as an additional layer, not instead of the password
+ (in which case it would've been a plugin too).
+ */
+ if (acl_check_ssl(thd, acl_user))
+ {
+ login_failed_error(thd, thd->password);
+ DBUG_RETURN(1);
+ }
+
+ /* Don't allow the user to connect if he has done too many queries */
+ if ((acl_user->user_resource.questions || acl_user->user_resource.updates ||
+ acl_user->user_resource.conn_per_hour ||
+ acl_user->user_resource.user_conn || max_user_connections) &&
+ get_or_create_user_conn(thd,
+ (opt_old_style_user_limits ? sctx->user : sctx->priv_user),
+ (opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host),
+ &acl_user->user_resource))
+ DBUG_RETURN(1); // The error is set by get_or_create_user_conn()
+ }
+ else
+ sctx->skip_grants();
+
+ if (thd->user_connect &&
+ (thd->user_connect->user_resources.conn_per_hour ||
+ thd->user_connect->user_resources.user_conn ||
+ max_user_connections) &&
+ check_for_max_user_connections(thd, thd->user_connect))
+ {
+ status_var_increment(denied_connections);
+ DBUG_RETURN(1); // The error is set in check_for_max_user_connections()
+ }
+
+ DBUG_PRINT("info",
+ ("Capabilities: %lu packet_length: %ld Host: '%s' "
+ "Login user: '%s' Priv_user: '%s' Using password: %s "
+ "Access: %lu db: '%s'",
+ thd->client_capabilities, thd->max_client_packet_length,
+ sctx->host_or_ip, sctx->user, sctx->priv_user,
+ thd->password ? "yes": "no",
+ sctx->master_access, mpvio.db.str));
+
+ if (command == COM_CONNECT &&
+ !(thd->main_security_ctx.master_access & SUPER_ACL))
+ {
+ pthread_mutex_lock(&LOCK_connection_count);
+ bool count_ok= (*thd->scheduler->connection_count <=
+ *thd->scheduler->max_connections);
+ VOID(pthread_mutex_unlock(&LOCK_connection_count));
+ if (!count_ok)
+ { // too many connections
+ my_error(ER_CON_COUNT_ERROR, MYF(0));
+ DBUG_RETURN(1);
+ }
+ }
+
+ /*
+ This is the default access rights for the current database. It's
+ set to 0 here because we don't have an active database yet (and we
+ may not have an active database to set.
+ */
+ sctx->db_access=0;
+
+ /* Change a database if necessary */
+ if (mpvio.db.length)
+ {
+ if (mysql_change_db(thd, &mpvio.db, FALSE))
+ {
+ /* mysql_change_db() has pushed the error message. */
+ if (thd->user_connect)
+ {
+ status_var_increment(thd->status_var.access_denied_errors);
+ decrease_user_connections(thd->user_connect);
+ thd->user_connect= 0;
+ }
+ DBUG_RETURN(1);
+ }
+ }
+
+ thd->net.net_skip_rest_factor= 2; // skip at most 2*max_packet_size
+
+ if (res == CR_OK_HANDSHAKE_COMPLETE)
+ thd->main_da.disable_status();
+ else
+ my_ok(thd);
+
+ /* Ready to handle queries */
+ DBUG_RETURN(0);
+}
+
+
+/**
+ MySQL Server Password Authentication Plugin
+
+ In the MySQL authentication protocol:
+ 1. the server sends the random scramble to the client
+ 2. client sends the encrypted password back to the server
+ 3. the server checks the password.
+*/
+
+static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_SERVER_AUTH_INFO *info)
+{
+ uchar *pkt;
+ int pkt_len;
+ MPVIO_EXT *mpvio=(MPVIO_EXT*)vio;
+ THD *thd=mpvio->thd;
+
+ /* generate the scramble, or reuse the old one */
+ if (thd->scramble[SCRAMBLE_LENGTH])
+ create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+
+ /* send it to the client */
+ if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
+ return CR_ERROR;
+
+ /* reply and authenticate */
+
+ /*
+ <digression>
+ This is more complex than it looks.
+
+ The plugin (we) may be called right after the client was connected -
+ and will need to send a scramble, read reply, authenticate.
+
+ Or the plugin may be called after another plugin has sent a scramble,
+ and read the reply. If the client has used the correct client-plugin,
+ we won't need to read anything here from the client, the client
+ has already sent a reply with everything we need for authentication.
+
+ Or the plugin may be called after another plugin has sent a scramble,
+ and read the reply, but the client has used the wrong client-plugin.
+ We'll need to sent a "switch to another plugin" packet to the
+ client and read the reply. "Use the short scramble" packet is a special
+ case of "switch to another plugin" packet.
+
+ Or, perhaps, the plugin may be called after another plugin has
+ done the handshake but did not send a useful scramble. We'll need
+ to send a scramble (and perhaps a "switch to another plugin" packet)
+ and read the reply.
+
+ Besides, a client may be an old one, that doesn't understand plugins.
+ Or doesn't even understand 4.0 scramble.
+
+ And we want to keep the same protocol on the wire unless non-native
+ plugins are involved.
+
+ Anyway, it still looks simple from a plugin point of view:
+ "send the scramble, read the reply and authenticate".
+ All the magic is transparently handled by the server.
+ </digression>
+ */
+
+ /* read the reply with the encrypted password */
+ if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0)
+ return CR_ERROR;
+
+#ifdef NO_EMBEDDED_ACCESS_CHECKS
+ return CR_OK;
+#endif
+
+ if (pkt_len == 0) /* no password */
+ return info->auth_string[0] ? CR_ERROR : CR_OK;
+
+ info->password_used = 1;
+ if (pkt_len == SCRAMBLE_LENGTH)
+ return check_scramble(pkt, thd->scramble, mpvio->acl_user->salt) ?
+ CR_ERROR : CR_OK;
+
+ inc_host_errors(&mpvio->thd->net.vio->remote.sin_addr);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+ return CR_ERROR;
+}
+
+
+static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_SERVER_AUTH_INFO *info)
+{
+ uchar *pkt;
+ int pkt_len;
+ MPVIO_EXT *mpvio=(MPVIO_EXT*)vio;
+ THD *thd=mpvio->thd;
+
+ /* generate the scramble, or reuse the old one */
+ if (thd->scramble[SCRAMBLE_LENGTH])
+ create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+
+ /* send it to the client */
+ if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
+ return CR_ERROR;
+
+ /* read the reply and authenticate */
+ if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0)
+ return CR_ERROR;
+
+#ifdef NO_EMBEDDED_ACCESS_CHECKS
+ return CR_OK;
+#endif
+
+ /*
+ legacy: if switch_from_long_to_short_scramble,
+ the password is sent \0-terminated, the pkt_len is always 9 bytes.
+ We need to figure out the correct scramble length here.
+ */
+ if (pkt_len == SCRAMBLE_LENGTH_323+1)
+ pkt_len= strnlen((char*)pkt, pkt_len);
+
+ if (pkt_len == 0) /* no password */
+ return info->auth_string[0] ? CR_ERROR : CR_OK;
+
+ if (secure_auth(thd))
+ return CR_ERROR;
+
+ info->password_used = 1;
+
+ if (pkt_len == SCRAMBLE_LENGTH_323)
+ return check_scramble_323(pkt, thd->scramble,
+ (ulong *)mpvio->acl_user->salt) ? CR_ERROR : CR_OK;
+
+ inc_host_errors(&mpvio->thd->net.vio->remote.sin_addr);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+ return CR_ERROR;
+}
+
+static struct st_mysql_auth native_password_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ native_password_plugin_name.str,
+ native_password_authenticate
+};
+
+static struct st_mysql_auth old_password_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ old_password_plugin_name.str,
+ old_password_authenticate
+};
+
+mysql_declare_plugin(mysql_password)
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &native_password_handler, /* type descriptor */
+ native_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Native MySQL authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &old_password_handler, /* type descriptor */
+ old_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Old MySQL-4.0 authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+}
+mysql_declare_plugin_end;
+
=== modified file 'sql/sql_acl.h'
--- a/sql/sql_acl.h 2009-11-21 11:18:21 +0000
+++ b/sql/sql_acl.h 2010-03-29 15:13:53 +0000
@@ -161,53 +161,6 @@ enum mysql_db_table_field
extern const TABLE_FIELD_DEF mysql_db_table_def;
-/* Classes */
-
-struct acl_host_and_ip
-{
- char *hostname;
- long ip,ip_mask; // Used with masked ip:s
-};
-
-
-class ACL_ACCESS {
-public:
- ulong sort;
- ulong access;
-};
-
-
-/* ACL_HOST is used if no host is specified */
-
-class ACL_HOST :public ACL_ACCESS
-{
-public:
- acl_host_and_ip host;
- char *db;
-};
-
-
-class ACL_USER :public ACL_ACCESS
-{
-public:
- acl_host_and_ip host;
- uint hostname_length;
- USER_RESOURCES user_resource;
- char *user;
- uint8 salt[SCRAMBLE_LENGTH+1]; // scrambled password in binary form
- uint8 salt_len; // 0 - no password, 4 - 3.20, 8 - 3.23, 20 - 4.1.1
- enum SSL_type ssl_type;
- const char *ssl_cipher, *x509_issuer, *x509_subject;
-};
-
-
-class ACL_DB :public ACL_ACCESS
-{
-public:
- acl_host_and_ip host;
- char *user,*db;
-};
-
/* prototypes */
bool hostname_requires_resolving(const char *hostname);
@@ -216,10 +169,9 @@ my_bool acl_reload(THD *thd);
void acl_free(bool end=0);
ulong acl_get(const char *host, const char *ip,
const char *user, const char *db, my_bool db_is_pattern);
-int acl_getroot(THD *thd, USER_RESOURCES *mqh, const char *passwd,
- uint passwd_len);
-bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
- char *ip, char *db);
+bool acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len);
+bool acl_getroot(Security_context *sctx, char *user, char *host,
+ char *ip, char *db);
bool acl_check_host(const char *host, const char *ip);
int check_change_password(THD *thd, const char *host, const char *user,
char *password, uint password_len);
=== modified file 'sql/sql_builtin.cc.in'
--- a/sql/sql_builtin.cc.in 2009-11-29 23:08:56 +0000
+++ b/sql/sql_builtin.cc.in 2010-03-29 15:13:53 +0000
@@ -19,10 +19,10 @@
typedef struct st_mysql_plugin builtin_plugin[];
extern builtin_plugin
- builtin_binlog_plugin@mysql_plugin_defs@;
+ builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@;
struct st_mysql_plugin *mysqld_builtins[]=
{
- builtin_binlog_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
+ builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
};
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-03-16 12:38:35 +0000
+++ b/sql/sql_class.cc 2010-03-29 15:13:53 +0000
@@ -2984,9 +2984,9 @@ void THD::set_status_var_init()
void Security_context::init()
{
- host= user= priv_user= ip= 0;
+ host= user= ip= 0;
host_or_ip= "connecting host";
- priv_host[0]= '\0';
+ priv_user[0]= priv_host[0]= '\0';
master_access= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
db_access= NO_ACCESS;
@@ -3010,8 +3010,7 @@ void Security_context::skip_grants()
/* privileges for the user are unknown everything is allowed */
host_or_ip= (char *)"";
master_access= ~NO_ACCESS;
- priv_user= (char *)"";
- *priv_host= '\0';
+ *priv_user= *priv_host= '\0';
}
@@ -3053,7 +3052,7 @@ bool Security_context::set_user(char *us
of a statement under credentials of a different user, e.g.
definer of a procedure, we authenticate this user in a local
instance of Security_context by means of this method (and
- ultimately by means of acl_getroot_no_password), and make the
+ ultimately by means of acl_getroot), and make the
local instance active in the thread by re-setting
thd->security_ctx pointer.
@@ -3087,19 +3086,12 @@ change_security_context(THD *thd,
DBUG_ASSERT(definer_user->str && definer_host->str);
*backup= NULL;
- /*
- The current security context may have NULL members
- if we have just started the thread and not authenticated
- any user. This use case is currently in events worker thread.
- */
- needs_change= (thd->security_ctx->priv_user == NULL ||
- strcmp(definer_user->str, thd->security_ctx->priv_user) ||
- thd->security_ctx->priv_host == NULL ||
+ needs_change= (strcmp(definer_user->str, thd->security_ctx->priv_user) ||
my_strcasecmp(system_charset_info, definer_host->str,
thd->security_ctx->priv_host));
if (needs_change)
{
- if (acl_getroot_no_password(this, definer_user->str, definer_host->str,
+ if (acl_getroot(this, definer_user->str, definer_host->str,
definer_host->str, db->str))
{
my_error(ER_NO_SUCH_USER, MYF(0), definer_user->str,
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_class.h 2010-03-29 15:13:53 +0000
@@ -805,7 +805,8 @@ public:
priv_user - The user privilege we are using. May be "" for anonymous user.
ip - client IP
*/
- char *host, *user, *priv_user, *ip;
+ char *host, *user, *ip;
+ char priv_user[USERNAME_LENGTH];
/* The host privilege we are using */
char priv_host[MAX_HOSTNAME];
/* points to host if host is available, otherwise points to ip */
=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_connect.cc 2010-03-29 15:13:53 +0000
@@ -27,24 +27,6 @@ extern pthread_mutex_t LOCK_global_user_
extern pthread_mutex_t LOCK_global_table_stats;
extern pthread_mutex_t LOCK_global_index_stats;
-#ifdef HAVE_OPENSSL
-/*
- Without SSL the handshake consists of one packet. This packet
- has both client capabilites and scrambled password.
- With SSL the handshake might consist of two packets. If the first
- packet (client capabilities) has CLIENT_SSL flag set, we have to
- switch to SSL and read the second packet. The scrambled password
- is in the second packet and client_capabilites field will be ignored.
- Maybe it is better to accept flags other than CLIENT_SSL from the
- second packet?
-*/
-#define SSL_HANDSHAKE_SIZE 2
-#define NORMAL_HANDSHAKE_SIZE 6
-#define MIN_HANDSHAKE_SIZE 2
-#else
-#define MIN_HANDSHAKE_SIZE 6
-#endif /* HAVE_OPENSSL */
-
#ifdef __WIN__
extern void win_install_sigabrt_handler();
#endif
@@ -56,9 +38,9 @@ extern void win_install_sigabrt_handler(
#ifndef NO_EMBEDDED_ACCESS_CHECKS
static HASH hash_user_connections;
-static int get_or_create_user_conn(THD *thd, const char *user,
- const char *host,
- USER_RESOURCES *mqh)
+int get_or_create_user_conn(THD *thd, const char *user,
+ const char *host,
+ USER_RESOURCES *mqh)
{
int return_val= 0;
size_t temp_len, user_len;
@@ -124,7 +106,6 @@ end:
1 error
*/
-static
int check_for_max_user_connections(THD *thd, USER_CONN *uc)
{
int error=0;
@@ -276,240 +257,6 @@ end:
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-
-/**
- Check if user exist and password supplied is correct.
-
- @param thd thread handle, thd->security_ctx->{host,user,ip} are used
- @param command originator of the check: now check_user is called
- during connect and change user procedures; used for
- logging.
- @param passwd scrambled password received from client
- @param passwd_len length of scrambled password
- @param db database name to connect to, may be NULL
- @param check_count TRUE if establishing a new connection. In this case
- check that we have not exceeded the global
- max_connections limist
-
- @note Host, user and passwd may point to communication buffer.
- Current implementation does not depend on that, but future changes
- should be done with this in mind; 'thd' is INOUT, all other params
- are 'IN'.
-
- @retval 0 OK; thd->security_ctx->user/master_access/priv_user/db_access and
- thd->db are updated; OK is sent to the client.
- @retval 1 error, e.g. access denied or handshake error, not sent to
- the client. A message is pushed into the error stack.
-*/
-
-int
-check_user(THD *thd, enum enum_server_command command,
- const char *passwd, uint passwd_len, const char *db,
- bool check_count)
-{
- DBUG_ENTER("check_user");
- LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
-
- /*
- Clear thd->db as it points to something, that will be freed when
- connection is closed. We don't want to accidentally free a wrong
- pointer if connect failed. Also in case of 'CHANGE USER' failure,
- current database will be switched to 'no database selected'.
- */
- thd->reset_db(NULL, 0);
-
-#ifdef NO_EMBEDDED_ACCESS_CHECKS
- thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights
- /* Change database if necessary */
- if (db && db[0])
- {
- if (mysql_change_db(thd, &db_str, FALSE))
- DBUG_RETURN(1);
- }
- my_ok(thd);
- DBUG_RETURN(0);
-#else
-
- my_bool opt_secure_auth_local;
- pthread_mutex_lock(&LOCK_global_system_variables);
- opt_secure_auth_local= opt_secure_auth;
- pthread_mutex_unlock(&LOCK_global_system_variables);
-
- /*
- If the server is running in secure auth mode, short scrambles are
- forbidden.
- */
- if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323)
- {
- my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
- general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
- DBUG_RETURN(1);
- }
- if (passwd_len != 0 &&
- passwd_len != SCRAMBLE_LENGTH &&
- passwd_len != SCRAMBLE_LENGTH_323)
- {
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- DBUG_RETURN(1);
- }
-
- USER_RESOURCES ur;
- int res= acl_getroot(thd, &ur, passwd, passwd_len);
-#ifndef EMBEDDED_LIBRARY
- if (res == -1)
- {
- /*
- This happens when client (new) sends password scrambled with
- scramble(), but database holds old value (scrambled with
- scramble_323()). Here we please client to send scrambled_password
- in old format.
- */
- NET *net= &thd->net;
- if (opt_secure_auth_local)
- {
- my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip);
- general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip);
- DBUG_RETURN(1);
- }
- /* We have to read very specific packet size */
- if (send_old_password_request(thd) ||
- my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- DBUG_RETURN(1);
- }
- /* Final attempt to check the user based on reply */
- /* So as passwd is short, errcode is always >= 0 */
- res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323);
- }
-#endif /*EMBEDDED_LIBRARY*/
- /* here res is always >= 0 */
- if (res == 0)
- {
- if (!(thd->main_security_ctx.master_access &
- NO_ACCESS)) // authentication is OK
- {
- DBUG_PRINT("info",
- ("Capabilities: %lu packet_length: %ld Host: '%s' "
- "Login user: '%s' Priv_user: '%s' Using password: %s "
- "Access: %lu db: '%s'",
- thd->client_capabilities,
- thd->max_client_packet_length,
- thd->main_security_ctx.host_or_ip,
- thd->main_security_ctx.user,
- thd->main_security_ctx.priv_user,
- passwd_len ? "yes": "no",
- thd->main_security_ctx.master_access,
- (thd->db ? thd->db : "*none*")));
-
- if (check_count)
- {
- bool count_ok= 1;
-
- if (!(thd->main_security_ctx.master_access & SUPER_ACL))
- {
- pthread_mutex_lock(&LOCK_connection_count);
- count_ok= (*thd->scheduler->connection_count <=
- *thd->scheduler->max_connections);
- VOID(pthread_mutex_unlock(&LOCK_connection_count));
- }
- if (!count_ok)
- { // too many connections
- my_error(ER_CON_COUNT_ERROR, MYF(0));
- DBUG_RETURN(1);
- }
- }
-
- /*
- Log the command before authentication checks, so that the user can
- check the log for the tried login tried and also to detect
- break-in attempts.
- */
- general_log_print(thd, command,
- (thd->main_security_ctx.priv_user ==
- thd->main_security_ctx.user ?
- (char*) "%s@%s on %s" :
- (char*) "%s@%s as anonymous on %s"),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip,
- db ? db : (char*) "");
-
- /*
- This is the default access rights for the current database. It's
- set to 0 here because we don't have an active database yet (and we
- may not have an active database to set.
- */
- thd->main_security_ctx.db_access=0;
-
- /* Don't allow user to connect if he has done too many queries */
- if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
- max_user_connections) &&
- get_or_create_user_conn(thd,
- (opt_old_style_user_limits ? thd->main_security_ctx.user :
- thd->main_security_ctx.priv_user),
- (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
- thd->main_security_ctx.priv_host),
- &ur))
- {
- /* The error is set by get_or_create_user_conn(). */
- DBUG_RETURN(1);
- }
- if (thd->user_connect &&
- (thd->user_connect->user_resources.conn_per_hour ||
- thd->user_connect->user_resources.user_conn ||
- max_user_connections) &&
- check_for_max_user_connections(thd, thd->user_connect))
- {
- /* The error is set in check_for_max_user_connections(). */
- status_var_increment(denied_connections);
- DBUG_RETURN(1);
- }
-
- /* Change database if necessary */
- if (db && db[0])
- {
- if (mysql_change_db(thd, &db_str, FALSE))
- {
- /* mysql_change_db() has pushed the error message. */
- if (thd->user_connect)
- decrease_user_connections(thd->user_connect);
- status_var_increment(thd->status_var.access_denied_errors);
- DBUG_RETURN(1);
- }
- }
- my_ok(thd);
- thd->net.net_skip_rest_factor= 2; // skip at most 2*max_packet_size
- thd->password= test(passwd_len); // remember for error messages
- /* Ready to handle queries */
- DBUG_RETURN(0);
- }
- }
- else if (res == 2) // client gave short hash, server has long hash
- {
- my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
- general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
- DBUG_RETURN(1);
- }
- my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip,
- passwd_len ? ER(ER_YES) : ER(ER_NO));
- general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip,
- passwd_len ? ER(ER_YES) : ER(ER_NO));
- status_var_increment(thd->status_var.access_denied_errors);
-
- DBUG_RETURN(1);
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-}
-
-
/*
Check for maximum allowable user connections, if the mysqld server is
started with corresponding variable that is greater then 0.
@@ -1088,9 +835,8 @@ bool init_new_connection_handler_thread(
thd thread handle
RETURN
- 0 success, OK is sent to user, thd is updated.
- -1 error, which is sent to user
- > 0 error code (not sent to user)
+ 0 success, thd is updated.
+ 1 error
*/
#ifndef EMBEDDED_LIBRARY
@@ -1098,8 +844,6 @@ static int check_connection(THD *thd)
{
uint connect_errors= 0;
NET *net= &thd->net;
- ulong pkt_len= 0;
- char *end;
DBUG_PRINT("info",
("New connection received on %s", vio_description(net->vio)));
@@ -1161,200 +905,10 @@ static int check_connection(THD *thd)
}
vio_keepalive(net->vio, TRUE);
- ulong server_capabilites;
- {
- /* buff[] needs to big enough to hold the server_version variable */
- char buff[SERVER_VERSION_LENGTH + 1 + SCRAMBLE_LENGTH + 1 + 64];
- server_capabilites= CLIENT_BASIC_FLAGS;
-
- if (opt_using_transactions)
- server_capabilites|= CLIENT_TRANSACTIONS;
-#ifdef HAVE_COMPRESS
- server_capabilites|= CLIENT_COMPRESS;
-#endif /* HAVE_COMPRESS */
-#ifdef HAVE_OPENSSL
- if (ssl_acceptor_fd)
- {
- server_capabilites |= CLIENT_SSL; /* Wow, SSL is available! */
- server_capabilites |= CLIENT_SSL_VERIFY_SERVER_CERT;
- }
-#endif /* HAVE_OPENSSL */
-
- end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1;
- int4store((uchar*) end, thd->thread_id);
- end+= 4;
- /*
- So as check_connection is the only entry point to authorization
- procedure, scramble is set here. This gives us new scramble for
- each handshake.
- */
- create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
- /*
- Old clients does not understand long scrambles, but can ignore packet
- tail: that's why first part of the scramble is placed here, and second
- part at the end of packet.
- */
- end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1;
-
- int2store(end, server_capabilites);
- /* write server characteristics: up to 16 bytes allowed */
- end[2]=(char) default_charset_info->number;
- int2store(end+3, thd->server_status);
- bzero(end+5, 13);
- end+= 18;
- /* write scramble tail */
- end= strmake(end, thd->scramble + SCRAMBLE_LENGTH_323,
- SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323) + 1;
-
- /* At this point we write connection message and read reply */
- if (net_write_command(net, (uchar) protocol_version, (uchar*) "", 0,
- (uchar*) buff, (size_t) (end-buff)) ||
- (pkt_len= my_net_read(net)) == packet_error ||
- pkt_len < MIN_HANDSHAKE_SIZE)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0),
- thd->main_security_ctx.host_or_ip);
- return 1;
- }
- }
-#ifdef _CUSTOMCONFIG_
-#include "_cust_sql_parse.h"
-#endif
- if (connect_errors)
- reset_host_errors(&thd->remote.sin_addr);
if (thd->packet.alloc(thd->variables.net_buffer_length))
return 1; /* The error is set by alloc(). */
- thd->client_capabilities= uint2korr(net->read_pos);
- if (thd->client_capabilities & CLIENT_PROTOCOL_41)
- {
- thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
- thd->max_client_packet_length= uint4korr(net->read_pos+4);
- DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
- thd_init_client_charset(thd, (uint) net->read_pos[8]);
- thd->update_charset();
- end= (char*) net->read_pos+32;
- }
- else
- {
- thd->max_client_packet_length= uint3korr(net->read_pos+2);
- end= (char*) net->read_pos+5;
- }
- /*
- Disable those bits which are not supported by the server.
- This is a precautionary measure, if the client lies. See Bug#27944.
- */
- thd->client_capabilities&= server_capabilites;
-
- if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
- thd->variables.sql_mode|= MODE_IGNORE_SPACE;
-#ifdef HAVE_OPENSSL
- DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
- if (thd->client_capabilities & CLIENT_SSL)
- {
- char error_string[1024];
- /* Do the SSL layering. */
- if (!ssl_acceptor_fd)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
- DBUG_PRINT("info", ("IO layer change in progress..."));
- if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, error_string))
- {
- DBUG_PRINT("error", ("Failed to accept new SSL connection"));
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
- DBUG_PRINT("info", ("Reading user information over SSL layer"));
- if ((pkt_len= my_net_read(net)) == packet_error ||
- pkt_len < NORMAL_HANDSHAKE_SIZE)
- {
- DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
- pkt_len));
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
- }
-#endif /* HAVE_OPENSSL */
-
- if (end >= (char*) net->read_pos+ pkt_len +2)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
-
- if (thd->client_capabilities & CLIENT_INTERACTIVE)
- thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
- if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
- opt_using_transactions)
- net->return_status= &thd->server_status;
-
- char *user= end;
- char *passwd= strend(user)+1;
- uint user_len= passwd - user - 1;
- char *db= passwd;
- char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
- char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
- uint dummy_errors;
-
- /*
- Old clients send null-terminated string as password; new clients send
- the size (1 byte) + string (not null-terminated). Hence in case of empty
- password both send '\0'.
-
- This strlen() can't be easily deleted without changing protocol.
-
- Cast *passwd to an unsigned char, so that it doesn't extend the sign for
- *passwd > 127 and become 2**32-127+ after casting to uint.
- */
- uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
- (uchar)(*passwd++) : strlen(passwd);
- db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
- db + passwd_len + 1 : 0;
- /* strlen() can't be easily deleted without changing protocol */
- uint db_len= db ? strlen(db) : 0;
-
- if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
-
- /* Since 4.1 all database names are stored in utf8 */
- if (db)
- {
- db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
- system_charset_info,
- db, db_len,
- thd->charset(), &dummy_errors)]= 0;
- db= db_buff;
- }
-
- user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
- system_charset_info, user, user_len,
- thd->charset(), &dummy_errors)]= '\0';
- user= user_buff;
-
- /* If username starts and ends in "'", chop them off */
- if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
- {
- user[user_len-1]= 0;
- user++;
- user_len-= 2;
- }
-
- if (thd->main_security_ctx.user)
- x_free(thd->main_security_ctx.user);
- if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
- return 1; /* The error is set by my_strdup(). */
- return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
+ return acl_authenticate(thd, connect_errors, 0);
}
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_insert.cc 2010-03-29 15:13:53 +0000
@@ -1778,8 +1778,10 @@ public:
table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0),
group_count(0)
{
- thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user;
+ thd.security_ctx->user=(char*) delayed_user;
thd.security_ctx->host=(char*) my_localhost;
+ strmake(thd.security_ctx->priv_user, thd.security_ctx->user,
+ USERNAME_LENGTH);
thd.current_tablenr=0;
thd.version=refresh_version;
thd.command=COM_DELAYED_INSERT;
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_lex.h 2010-03-29 15:13:53 +0000
@@ -952,6 +952,8 @@ extern sys_var *trg_new_row_fake_var;
enum xa_option_words {XA_NONE, XA_JOIN, XA_RESUME, XA_ONE_PHASE,
XA_SUSPEND, XA_FOR_MIGRATE};
+extern const LEX_STRING null_lex_str;
+extern const LEX_STRING empty_lex_str;
/*
Class representing list of all tables used by statement.
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-03-16 12:38:35 +0000
+++ b/sql/sql_parse.cc 2010-03-29 15:13:53 +0000
@@ -444,9 +444,8 @@ static void handle_bootstrap_impl(THD *t
thd_proc_info(thd, 0);
thd->version=refresh_version;
- thd->security_ctx->priv_user=
- thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
- thd->security_ctx->priv_host[0]=0;
+ thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
+ thd->security_ctx->priv_user[0]= thd->security_ctx->priv_host[0]=0;
/*
Make the "client" handle multiple results. This is necessary
to enable stored procedures with SELECTs and Dynamic SQL
@@ -1093,96 +1092,34 @@ bool dispatch_command(enum enum_server_c
case COM_CHANGE_USER:
{
status_var_increment(thd->status_var.com_other);
- char *user= (char*) packet, *packet_end= packet + packet_length;
- /* Safe because there is always a trailing \0 at the end of the packet */
- char *passwd= strend(user)+1;
thd->change_user();
thd->clear_error(); // if errors from rollback
- /*
- Old clients send null-terminated string ('\0' for empty string) for
- password. New clients send the size (1 byte) + string (not null
- terminated, so also '\0' for empty string).
-
- Cast *passwd to an unsigned char, so that it doesn't extend the sign
- for *passwd > 127 and become 2**32-127 after casting to uint.
- */
- char db_buff[NAME_LEN+1]; // buffer to store db in utf8
- char *db= passwd;
- char *save_db;
- /*
- If there is no password supplied, the packet must contain '\0',
- in any type of handshake (4.1 or pre-4.1).
- */
- if (passwd >= packet_end)
- {
- my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
- break;
- }
- uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
- (uchar)(*passwd++) : strlen(passwd));
- uint dummy_errors, save_db_length, db_length;
- int res;
- Security_context save_security_ctx= *thd->security_ctx;
- USER_CONN *save_user_connect;
-
- db+= passwd_len + 1;
- /*
- Database name is always NUL-terminated, so in case of empty database
- the packet must contain at least the trailing '\0'.
- */
- if (db >= packet_end)
- {
- my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
- break;
- }
- db_length= strlen(db);
-
- char *ptr= db + db_length + 1;
- uint cs_number= 0;
-
- if (ptr < packet_end)
- {
- if (ptr + 2 > packet_end)
- {
- my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
- break;
- }
-
- cs_number= uint2korr(ptr);
- }
-
- /* Convert database name to utf8 */
- db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
- system_charset_info, db, db_length,
- thd->charset(), &dummy_errors)]= 0;
- db= db_buff;
-
- /* Save user and privileges */
- save_db_length= thd->db_length;
- save_db= thd->db;
- save_user_connect= thd->user_connect;
+ /* acl_authenticate() takes the data from net->read_pos */
+ net->read_pos= (uchar*)packet;
- if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
- {
- thd->security_ctx->user= save_security_ctx.user;
- my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
- break;
- }
-
- /* Clear variables that are allocated */
- thd->user_connect= 0;
- thd->security_ctx->priv_user= thd->security_ctx->user;
- res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
+ uint save_db_length= thd->db_length;
+ char *save_db= thd->db;
+ USER_CONN *save_user_connect= thd->user_connect;
+ Security_context save_security_ctx= *thd->security_ctx;
+ CHARSET_INFO *save_character_set_client=
+ thd->variables.character_set_client;
+ CHARSET_INFO *save_collation_connection=
+ thd->variables.collation_connection;
+ CHARSET_INFO *save_character_set_results=
+ thd->variables.character_set_results;
- if (res)
+ if (acl_authenticate(thd, 0, packet_length))
{
x_free(thd->security_ctx->user);
*thd->security_ctx= save_security_ctx;
thd->user_connect= save_user_connect;
- thd->db= save_db;
- thd->db_length= save_db_length;
+ thd->reset_db(save_db, save_db_length);
+ thd->variables.character_set_client= save_character_set_client;
+ thd->variables.collation_connection= save_collation_connection;
+ thd->variables.character_set_results= save_character_set_results;
+ thd->update_charset();
}
else
{
@@ -1193,12 +1130,6 @@ bool dispatch_command(enum enum_server_c
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
x_free(save_db);
x_free(save_security_ctx.user);
-
- if (cs_number)
- {
- thd_init_client_charset(thd, cs_number);
- thd->update_charset();
- }
}
break;
}
@@ -4348,8 +4279,8 @@ end_with_restore_list:
if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE))
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_PROC_AUTO_GRANT_FAIL,
- ER(ER_PROC_AUTO_GRANT_FAIL));
+ ER_PROC_AUTO_GRANT_FAIL, ER(ER_PROC_AUTO_GRANT_FAIL));
+ thd->clear_error();
}
/*
@@ -7727,8 +7658,9 @@ void get_default_definer(THD *thd, LEX_U
definer->host.str= (char *) sctx->priv_host;
definer->host.length= strlen(definer->host.str);
- definer->password.str= NULL;
- definer->password.length= 0;
+ definer->password= null_lex_str;
+ definer->plugin= empty_lex_str;
+ definer->auth= empty_lex_str;
}
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_plugin.cc 2010-03-29 15:13:53 +0000
@@ -16,6 +16,7 @@
#include "mysql_priv.h"
#include <my_pthread.h>
#include <my_getopt.h>
+#include <mysql/plugin_auth.h>
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
@@ -46,7 +47,10 @@ const LEX_STRING plugin_type_names[MYSQL
{ C_STRING_WITH_LEN("STORAGE ENGINE") },
{ C_STRING_WITH_LEN("FTPARSER") },
{ C_STRING_WITH_LEN("DAEMON") },
- { C_STRING_WITH_LEN("INFORMATION SCHEMA") }
+ { C_STRING_WITH_LEN("INFORMATION SCHEMA") },
+ { C_STRING_WITH_LEN("AUDIT") },
+ { C_STRING_WITH_LEN("REPLICATION") },
+ { C_STRING_WITH_LEN("AUTHENTICATION") }
};
extern int initialize_schema_table(st_plugin_int *plugin);
@@ -59,12 +63,12 @@ extern int finalize_schema_table(st_plug
*/
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
- 0,ha_initialize_handlerton,0,0,initialize_schema_table
+ 0,ha_initialize_handlerton,0,0,initialize_schema_table, 0, 0, 0
};
plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
- 0,ha_finalize_handlerton,0,0,finalize_schema_table
+ 0,ha_finalize_handlerton,0,0,finalize_schema_table, 0, 0, 0
};
#ifdef HAVE_DLOPEN
@@ -85,7 +89,10 @@ static int min_plugin_info_interface_ver
MYSQL_HANDLERTON_INTERFACE_VERSION,
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
- MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
+ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
+ 0xff00, /* audit plugins are supported in a later versions */
+ 0xff00, /* replication plugins are supported in a later versions */
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION
};
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
@@ -93,7 +100,10 @@ static int cur_plugin_info_interface_ver
MYSQL_HANDLERTON_INTERFACE_VERSION,
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
- MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
+ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
+ 0x0000, /* audit plugins are supported in a later versions */
+ 0x0000, /* replication plugins are supported in a later versions */
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION
};
/* support for Services */
@@ -1013,6 +1023,9 @@ void plugin_unlock_list(THD *thd, plugin
{
LEX *lex= thd ? thd->lex : 0;
DBUG_ENTER("plugin_unlock_list");
+ if (count == 0)
+ DBUG_VOID_RETURN;
+
DBUG_ASSERT(list);
pthread_mutex_lock(&LOCK_plugin);
while (count--)
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-03-15 11:51:23 +0000
+++ b/sql/sql_yacc.yy 2010-03-29 15:13:53 +0000
@@ -56,6 +56,7 @@
int yylex(void *yylval, void *yythd);
const LEX_STRING null_lex_str= {0,0};
+const LEX_STRING empty_lex_str= { (char*) "", 0 };
#define yyoverflow(A,B,C,D,E,F) \
{ \
@@ -1260,8 +1261,9 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token VARIANCE_SYM
%token VARYING /* SQL-2003-R */
%token VAR_SAMP_SYM
-%token VIRTUAL_SYM
+%token VIA_SYM
%token VIEW_SYM /* SQL-2003-N */
+%token VIRTUAL_SYM
%token WAIT_SYM
%token WARNINGS
%token WEEK_SYM
@@ -11673,6 +11675,9 @@ user:
$$->user = $1;
$$->host.str= (char *) "%";
$$->host.length= 1;
+ $$->password= null_lex_str;
+ $$->plugin= empty_lex_str;
+ $$->auth= empty_lex_str;
if (check_string_char_length(&$$->user, ER(ER_USERNAME),
USERNAME_CHAR_LENGTH,
@@ -11685,6 +11690,9 @@ user:
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
MYSQL_YYABORT;
$$->user = $1; $$->host=$3;
+ $$->password= null_lex_str;
+ $$->plugin= empty_lex_str;
+ $$->auth= empty_lex_str;
if (check_string_char_length(&$$->user, ER(ER_USERNAME),
USERNAME_CHAR_LENGTH,
@@ -12941,6 +12949,18 @@ grant_user:
}
| user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
{ $$= $1; $1->password= $5; }
+ | user IDENTIFIED_SYM VIA_SYM ident_or_text
+ {
+ $$= $1;
+ $1->plugin= $4;
+ $1->auth= empty_lex_str;
+ }
+ | user IDENTIFIED_SYM VIA_SYM ident_or_text USING TEXT_STRING_sys
+ {
+ $$= $1;
+ $1->plugin= $4;
+ $1->auth= $6;
+ }
| user
{ $$= $1; $1->password= null_lex_str; }
;
=== modified file 'sql/structs.h'
--- a/sql/structs.h 2010-02-01 06:14:12 +0000
+++ b/sql/structs.h 2010-03-29 15:13:53 +0000
@@ -178,7 +178,7 @@ extern const char *show_comp_option_name
typedef int *(*update_var)(THD *, struct st_mysql_show_var *);
typedef struct st_lex_user {
- LEX_STRING user, host, password;
+ LEX_STRING user, host, password, plugin, auth;
} LEX_USER;
/*
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2010-03-15 11:51:23 +0000
+++ b/sql/table.cc 2010-03-29 15:13:53 +0000
@@ -4163,11 +4163,8 @@ bool TABLE_LIST::prepare_view_securety_c
{
DBUG_PRINT("info", ("This table is suid view => load contest"));
DBUG_ASSERT(view && view_sctx);
- if (acl_getroot_no_password(view_sctx,
- definer.user.str,
- definer.host.str,
- definer.host.str,
- thd->db))
+ if (acl_getroot(view_sctx, definer.user.str, definer.host.str,
+ definer.host.str, thd->db))
{
if ((thd->lex->sql_command == SQLCOM_SHOW_CREATE) ||
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS))
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2010-03-15 11:51:23 +0000
+++ b/storage/maria/ma_loghandler.c 2010-03-30 12:35:15 +0000
@@ -1275,6 +1275,7 @@ static my_bool translog_set_lsn_for_file
{
LOGHANDLER_FILE_INFO info;
File fd= open_logfile_by_number_no_cache(file);
+ LINT_INIT_STRUCT(info);
if ((fd < 0) ||
((translog_read_file_header(&info, fd) ||
(cmp_translog_addr(lsn, info.max_lsn) > 0 &&
@@ -1457,8 +1458,8 @@ LSN translog_get_file_max_lsn_stored(uin
{
LOGHANDLER_FILE_INFO info;
- LINT_INIT_STRUCT(info);
File fd= open_logfile_by_number_no_cache(file);
+ LINT_INIT_STRUCT(info);
if ((fd < 0) ||
(translog_read_file_header(&info, fd) | my_close(fd, MYF(MY_WME))))
{
@@ -3966,6 +3967,7 @@ my_bool translog_init_with_table(const c
if (!old_log_was_recovered && old_flags == flags)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT_STRUCT(info);
/*
Accessing &log_descriptor.open_files without mutex is safe
because it is initialization
@@ -7934,6 +7936,7 @@ my_bool translog_flush(TRANSLOG_ADDRESS
DBUG_ASSERT(translog_status == TRANSLOG_OK ||
translog_status == TRANSLOG_READONLY);
LINT_INIT(sent_to_disk);
+ LINT_INIT(flush_interval);
pthread_mutex_lock(&log_descriptor.log_flush_lock);
DBUG_PRINT("info", ("Everything is flushed up to (%lu,0x%lx)",
@@ -8060,18 +8063,14 @@ retest:
/* keep values for soft sync() and forced sync() actual */
{
uint32 fileno= LSN_FILE_NO(lsn);
- my_atomic_rwlock_wrlock(&soft_sync_rwl);
- my_atomic_store32(&soft_sync_min, fileno);
- my_atomic_store32(&soft_sync_max, fileno);
- my_atomic_rwlock_wrunlock(&soft_sync_rwl);
+ soft_sync_min= fileno;
+ soft_sync_max= fileno;
}
}
else
{
- my_atomic_rwlock_wrlock(&soft_sync_rwl);
- my_atomic_store32(&soft_sync_max, LSN_FILE_NO(lsn));
- my_atomic_store32(&soft_need_sync, 1);
- my_atomic_rwlock_wrunlock(&soft_sync_rwl);
+ soft_sync_max= lsn;
+ soft_need_sync= 1;
}
DBUG_ASSERT(flush_horizon <= log_descriptor.horizon);
@@ -8464,9 +8463,7 @@ my_bool translog_purge(TRANSLOG_ADDRESS
translog_status == TRANSLOG_READONLY);
soft= soft_sync;
- my_atomic_rwlock_wrlock(&soft_sync_rwl);
- min_unsync= my_atomic_load32(&soft_sync_min);
- my_atomic_rwlock_wrunlock(&soft_sync_rwl);
+ min_unsync= soft_sync_min;
DBUG_PRINT("info", ("min_unsync: %lu", (ulong) min_unsync));
if (soft && min_unsync < last_need_file)
{
@@ -8748,9 +8745,7 @@ void translog_sync()
uint32 min;
DBUG_ENTER("ma_translog_sync");
- my_atomic_rwlock_rdlock(&soft_sync_rwl);
- min= my_atomic_load32(&soft_sync_min);
- my_atomic_rwlock_rdunlock(&soft_sync_rwl);
+ min= soft_sync_min;
if (!min)
min= max;
@@ -8796,13 +8791,11 @@ ma_soft_sync_background( void *arg __att
ulonglong prev_loop= my_micro_time();
ulonglong time, sleep;
uint32 min, max, sync_request;
- my_atomic_rwlock_rdlock(&soft_sync_rwl);
- min= my_atomic_load32(&soft_sync_min);
- max= my_atomic_load32(&soft_sync_max);
- sync_request= my_atomic_load32(&soft_need_sync);
- my_atomic_store32(&soft_sync_min, max);
- my_atomic_store32(&soft_need_sync, 0);
- my_atomic_rwlock_rdunlock(&soft_sync_rwl);
+ min= soft_sync_min;
+ max= soft_sync_max;
+ sync_request= soft_need_sync;
+ soft_sync_min= max;
+ soft_need_sync= 0;
sleep= group_commit_wait;
if (sync_request)
@@ -8834,15 +8827,13 @@ int translog_soft_sync_start(void)
DBUG_ENTER("translog_soft_sync_start");
/* check and init variables */
- my_atomic_rwlock_rdlock(&soft_sync_rwl);
- min= my_atomic_load32(&soft_sync_min);
- max= my_atomic_load32(&soft_sync_max);
+ min= soft_sync_min;
+ max= soft_sync_max;
if (!max)
- my_atomic_store32(&soft_sync_max, (max= get_current_logfile()->number));
+ soft_sync_max= max= get_current_logfile()->number;
if (!min)
- my_atomic_store32(&soft_sync_min, max);
- my_atomic_store32(&soft_need_sync, 1);
- my_atomic_rwlock_rdunlock(&soft_sync_rwl);
+ soft_sync_min= max;
+ soft_need_sync= 1;
if (!(res= ma_service_thread_control_init(&soft_sync_control)))
if (!(res= pthread_create(&th, NULL, ma_soft_sync_background, NULL)))
@@ -8985,6 +8976,7 @@ static void dump_header_page(uchar *buff
{
LOGHANDLER_FILE_INFO desc;
char strbuff[21];
+ LINT_INIT_STRUCT(desc);
translog_interpret_file_header(&desc, buff);
printf(" This can be header page:\n"
" Timestamp: %s\n"
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- a/storage/pbxt/src/ha_pbxt.cc 2010-03-03 14:44:14 +0000
+++ b/storage/pbxt/src/ha_pbxt.cc 2010-03-31 18:37:45 +0000
@@ -1215,8 +1215,6 @@ static int pbxt_init(void *p)
THD *thd = NULL;
#ifndef DRIZZLED
- extern myxt_mutex_t LOCK_plugin;
-
/* {MYSQL QUIRK}
* I have to release this lock for PBXT recovery to
* work, because it needs to open .frm files.
=== modified file 'tests/mysql_client_test.c'
--- a/tests/mysql_client_test.c 2010-01-11 13:15:28 +0000
+++ b/tests/mysql_client_test.c 2010-03-29 15:13:53 +0000
@@ -34,6 +34,7 @@
#include <m_string.h>
#include <mysqld_error.h>
#include <my_handler.h>
+#include <sql_common.h>
#define VER "2.1"
#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2745)
by Igor Babaev 01 Apr '10
by Igor Babaev 01 Apr '10
01 Apr '10
#At lp:maria/5.2 based on revid:igor@askmonty.org-20100331184541-cigkg2yokjzve1mk
2745 Igor Babaev 2010-03-31 [merge]
Merge the latest changes in 5.2.
Made the results for the key_cache test to be plaform independent.
removed:
include/mysql/plugin.h.pp
added:
include/mysql/client_plugin.h
include/mysql/client_plugin.h.pp
include/mysql/plugin_auth.h
include/mysql/plugin_auth.h.pp
include/mysql/plugin_auth_common.h
plugin/auth/
plugin/auth/Makefile.am
plugin/auth/auth_socket.c
plugin/auth/dialog.c
plugin/auth/plug.in
sql-common/client_plugin.c
modified:
.bzrignore
Makefile.am
client/CMakeLists.txt
client/Makefile.am
client/client_priv.h
client/mysql.cc
client/mysqltest.cc
config/ac-macros/plugins.m4
configure.in
include/Makefile.am
include/errmsg.h
include/m_ctype.h
include/my_global.h
include/my_no_pthread.h
include/my_sys.h
include/mysql.h
include/mysql.h.pp
include/mysql/plugin.h
include/mysql_com.h
include/sql_common.h
libmysql/CMakeLists.txt
libmysql/Makefile.shared
libmysql/client_settings.h
libmysql/errmsg.c
libmysql/libmysql.c
libmysqld/Makefile.am
libmysqld/embedded_priv.h
libmysqld/lib_sql.cc
libmysqld/libmysqld.c
mysql-test/mysql-test-run.pl
mysql-test/r/change_user.result
mysql-test/r/grant.result
mysql-test/r/grant2.result
mysql-test/r/key_cache.result
mysql-test/r/ps.result
mysql-test/r/sp_notembedded.result
mysql-test/r/system_mysql_db.result
mysql-test/suite/funcs_1/r/is_columns_mysql.result
mysql-test/suite/funcs_1/r/is_user_privileges.result
mysql-test/suite/pbxt/r/grant.result
mysql-test/suite/rpl/r/rpl_ignore_table.result
mysql-test/suite/rpl/r/rpl_stm_000001.result
mysql-test/t/change_user.test
mysql-test/t/key_cache.test
mysql-test/valgrind.supp
mysys/Makefile.am
scripts/mysql_system_tables.sql
scripts/mysql_system_tables_data.sql
scripts/mysql_system_tables_fix.sql
server-tools/instance-manager/Makefile.am
server-tools/instance-manager/user_map.cc
sql-common/Makefile.am
sql-common/client.c
sql/CMakeLists.txt
sql/Makefile.am
sql/client_settings.h
sql/ha_ndbcluster.cc
sql/ha_ndbcluster_binlog.cc
sql/lex.h
sql/mysql_priv.h
sql/mysqld.cc
sql/password.c
sql/protocol.cc
sql/protocol.h
sql/sql_acl.cc
sql/sql_acl.h
sql/sql_builtin.cc.in
sql/sql_class.cc
sql/sql_class.h
sql/sql_connect.cc
sql/sql_insert.cc
sql/sql_lex.h
sql/sql_parse.cc
sql/sql_plugin.cc
sql/sql_yacc.yy
sql/structs.h
sql/table.cc
storage/maria/ma_loghandler.c
storage/pbxt/src/ha_pbxt.cc
tests/mysql_client_test.c
=== modified file '.bzrignore'
--- a/.bzrignore 2010-02-01 06:14:12 +0000
+++ b/.bzrignore 2010-03-29 15:13:53 +0000
@@ -1931,3 +1931,6 @@ client/rpl_filter.cc
client/rpl_filter.h
client/sql_list.cc
client/sql_list.h
+libmysqld/client_plugin.c
+sql/client_plugin.c
+*.dgcov
=== modified file 'Makefile.am'
--- a/Makefile.am 2010-03-03 14:44:14 +0000
+++ b/Makefile.am 2010-03-29 15:13:53 +0000
@@ -140,14 +140,14 @@ smoke:
test-full: test test-nr test-ps
test-force:
- $(MAKE) force=--force test
+ $(MAKE) -k force=--force test
test-force-full:
- $(MAKE) force=--force test-full
+ $(MAKE) -k force=--force test-full
#used by autopush.pl to run memory based tests
test-force-mem:
- $(MAKE) force=--force mem=--mem test
+ $(MAKE) -k force=--force mem=--mem test
test-bt:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@@ -261,7 +261,7 @@ test-fast-prepare:
$(MAKE) subset=--ps-protocol test-fast
test-full-qa:
- $(MAKE) force=--force test-pr \
+ $(MAKE) -k force=--force test-pr \
test-binlog-statement test-ext test-fast-view \
test-fast-cursor test-unit
@@ -271,12 +271,13 @@ test-full-qa:
# after which TEST_PREPROCESSOR_HEADER will be used.
#
-API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \
- $(top_srcdir)/include/mysql.h
-
-TEST_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \
- $(top_srcdir)/sql/mysql_priv.h \
- $(top_srcdir)/include/mysql.h
+API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql.h \
+ $(top_srcdir)/include/mysql/client_plugin.h \
+ $(top_srcdir)/include/mysql/plugin_auth.h
+
+TEST_PREPROCESSOR_HEADER = $(API_PREPROCESSOR_HEADER) \
+ $(top_srcdir)/sql/mysql_priv.h
+
#
# Rules for checking that the abi/api has not changed.
=== modified file 'client/CMakeLists.txt'
--- a/client/CMakeLists.txt 2009-09-04 05:54:16 +0000
+++ b/client/CMakeLists.txt 2010-03-29 15:13:53 +0000
@@ -83,3 +83,5 @@ IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("echo" "asInvoker")
ENDIF(EMBED_MANIFESTS)
+ADD_DEFINITIONS(-DHAVE_DLOPEN)
+
=== modified file 'client/Makefile.am'
--- a/client/Makefile.am 2009-12-08 21:47:54 +0000
+++ b/client/Makefile.am 2010-03-29 15:13:53 +0000
@@ -100,8 +100,8 @@ mysql_upgrade_SOURCES= mysql_up
# Fix for mit-threads
DEFS = -DMYSQL_CLIENT_NO_THREADS \
- -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \
- -DMYSQL_DATADIR="\"$(localstatedir)\""
+ -DDEFAULT_MYSQL_HOME='"$(prefix)"' \
+ -DMYSQL_DATADIR='"$(localstatedir)"'
sql_src=log_event.h mysql_priv.h rpl_constants.h \
rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \
=== modified file 'client/client_priv.h'
--- a/client/client_priv.h 2010-03-15 11:51:23 +0000
+++ b/client/client_priv.h 2010-03-29 15:13:53 +0000
@@ -93,5 +93,7 @@ enum options_client
OPT_FIRST_SLAVE,
OPT_ALL,
OPT_REWRITE_DB,
- OPT_MAX_CLIENT_OPTION
+ OPT_PLUGIN_DIR,
+ OPT_DEFAULT_PLUGIN,
+ OPT_MAX_CLIENT_OPTION /* should be always the last */
};
=== modified file 'client/mysql.cc'
--- a/client/mysql.cc 2010-03-04 08:03:07 +0000
+++ b/client/mysql.cc 2010-03-29 15:13:53 +0000
@@ -167,6 +167,7 @@ static int wait_time = 5;
static STATUS status;
static ulong select_limit,max_join_size,opt_connect_timeout=0;
static char mysql_charsets_dir[FN_REFLEN+1];
+static char *opt_plugin_dir= 0, *opt_default_auth;
static const char *xmlmeta[] = {
"&", "&",
"<", "<",
@@ -1542,6 +1543,13 @@ static struct my_option my_long_options[
{"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
(uchar**) &show_warnings, (uchar**) &show_warnings, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_PLUGIN_DIR,
+ "Default authentication client-side plugin to use.",
+ (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -4238,6 +4246,56 @@ char *get_arg(char *line, my_bool get_ne
}
+/**
+ An example of mysql_authentication_dialog_ask callback.
+
+ The C function with the name "mysql_authentication_dialog_ask", if exists,
+ will be used by the "dialog" client authentication plugin when user
+ input is needed. This function should be of mysql_authentication_dialog_ask_t
+ type. If the function does not exists, a built-in implementation will be
+ used.
+
+ @param mysql mysql
+ @param type type of the input
+ 1 - normal string input
+ 2 - password string
+ @param prompt prompt
+ @param buf a buffer to store the use input
+ @param buf_len the length of the buffer
+
+ @retval a pointer to the user input string.
+ It may be equal to 'buf' or to 'mysql->password'.
+ In all other cases it is assumed to be an allocated
+ string, and the "dialog" plugin will free() it.
+*/
+
+extern "C" char *mysql_authentication_dialog_ask(MYSQL *mysql, int type,
+ const char *prompt,
+ char *buf, int buf_len)
+{
+ char *s=buf;
+
+ fputs("[mariadb] ", stdout);
+ fputs(prompt, stdout);
+ fputs(" ", stdout);
+
+ if (type == 2) /* password */
+ {
+ s= get_tty_password("");
+ strnmov(buf, s, buf_len);
+ buf[buf_len-1]= 0;
+ my_free(s, MYF(0));
+ }
+ else
+ {
+ fgets(buf, buf_len-1, stdin);
+ if (buf[0] && (s= strend(buf))[-1] == '\n')
+ s[-1]= 0;
+ }
+
+ return buf;
+}
+
static int
sql_real_connect(char *host,char *database,char *user,char *password,
uint silent)
@@ -4283,6 +4341,13 @@ sql_real_connect(char *host,char *databa
}
if (default_charset_used)
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
if (!mysql_real_connect(&mysql, host, user, password,
database, opt_mysql_port, opt_mysql_unix_port,
connect_flag | CLIENT_MULTI_STATEMENTS))
=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc 2010-01-28 14:49:14 +0000
+++ b/client/mysqltest.cc 2010-02-19 08:08:05 +0000
@@ -36,6 +36,7 @@
#include "client_priv.h"
#include <mysql_version.h>
#include <mysqld_error.h>
+#include <sql_common.h>
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
@@ -3610,13 +3611,15 @@ void do_change_user(struct st_command *c
}
if (!ds_user.length)
+ {
dynstr_set(&ds_user, mysql->user);
- if (!ds_passwd.length)
- dynstr_set(&ds_passwd, mysql->passwd);
+ if (!ds_passwd.length)
+ dynstr_set(&ds_passwd, mysql->passwd);
- if (!ds_db.length)
- dynstr_set(&ds_db, mysql->db);
+ if (!ds_db.length)
+ dynstr_set(&ds_db, mysql->db);
+ }
DBUG_PRINT("info",("connection: '%s' user: '%s' password: '%s' database: '%s'",
cur_con->name, ds_user.str, ds_passwd.str, ds_db.str));
=== modified file 'config/ac-macros/plugins.m4'
--- a/config/ac-macros/plugins.m4 2009-12-22 10:33:20 +0000
+++ b/config/ac-macros/plugins.m4 2010-03-29 15:14:28 +0000
@@ -38,6 +38,7 @@ AC_DEFUN([_MYSQL_PLUGIN],[
_MYSQL_PLUGAPPEND([__mysql_plugin_list__],[$1])
m4_define([MYSQL_PLUGIN_NAME_]AS_TR_CPP([$1]), [$3])
m4_define([MYSQL_PLUGIN_DESC_]AS_TR_CPP([$1]), [$4])
+ m4_ifdef([_AC_ENABLE_IF], [_AC_ENABLE_IF([with],[plugin-$1])])
_MYSQL_PLUGAPPEND_META([$1], $5)
ifelse(m4_bregexp(__mysql_include__,[/plug\.in$]),-1,[],[
MYSQL_PLUGIN_DIRECTORY([$1],
=== modified file 'configure.in'
--- a/configure.in 2010-03-18 12:08:39 +0000
+++ b/configure.in 2010-03-29 15:13:53 +0000
@@ -1605,9 +1605,8 @@ case "$with_mysqld_ldflags " in
;;
*)
- # Check for dlopen, needed for user definable functions
+ # Check for dlopen, needed for user definable functions and plugins
# This must be checked after threads on AIX
- # We only need this for mysqld, not for the clients.
my_save_LIBS="$LIBS"
LIBS=""
=== modified file 'include/Makefile.am'
--- a/include/Makefile.am 2010-03-03 14:44:14 +0000
+++ b/include/Makefile.am 2010-03-29 15:13:53 +0000
@@ -24,6 +24,8 @@ pkginclude_HEADERS = $(HEADERS_ABI) my_d
my_xml.h mysql_embed.h mysql/services.h \
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
my_pthread.h my_no_pthread.h \
+ mysql/plugin_auth.h mysql/client_plugin.h \
+ mysql/plugin_auth_common.h \
decimal.h errmsg.h my_global.h my_net.h \
my_getopt.h sslopt-longopts.h my_dir.h \
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
@@ -42,7 +44,7 @@ noinst_HEADERS = config-win.h config-net
atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \
atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \
wqueue.h waiting_threads.h
-EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp
+EXTRA_DIST = mysql.h.pp mysql/plugin_auth.h.pp mysql/client_plugin.h.pp
# Remove built files and the symlinked directories
CLEANFILES = $(BUILT_SOURCES) readline openssl
=== modified file 'include/errmsg.h'
--- a/include/errmsg.h 2008-05-20 16:36:26 +0000
+++ b/include/errmsg.h 2010-03-29 15:13:53 +0000
@@ -97,6 +97,7 @@ extern const char *client_errors[]; /* E
#define CR_SERVER_LOST_EXTENDED 2055
#define CR_STMT_CLOSED 2056
#define CR_NEW_STMT_METADATA 2057
-#define CR_ERROR_LAST /*Copy last error nr:*/ 2057
+#define CR_AUTH_PLUGIN_CANNOT_LOAD 2058
+#define CR_ERROR_LAST /*Copy last error nr:*/ 2058
/* Add error numbers before CR_ERROR_LAST and change it accordingly. */
=== modified file 'include/m_ctype.h'
--- a/include/m_ctype.h 2010-01-06 19:20:16 +0000
+++ b/include/m_ctype.h 2010-03-31 18:37:45 +0000
@@ -291,7 +291,7 @@ struct charset_info_st
const uint16 *const *sort_order_big;
const uint16 *tab_to_uni;
MY_UNI_IDX *tab_from_uni;
- const MY_UNICASE_INFO *const *caseinfo;
+ MY_UNICASE_INFO *const *caseinfo;
const uchar *state_map;
const uchar *ident_map;
uint strxfrm_multiply;
=== modified file 'include/my_global.h'
--- a/include/my_global.h 2010-03-10 10:32:14 +0000
+++ b/include/my_global.h 2010-03-29 15:13:53 +0000
@@ -578,6 +578,14 @@ int __void__;
#define IF_VALGRIND(A,B) (B)
#endif
+#ifdef _WIN32
+#define SO_EXT ".dll"
+#elif defined(__APPLE__)
+#define SO_EXT ".dylib"
+#else
+#define SO_EXT ".so"
+#endif
+
/*
Suppress uninitialized variable warning without generating code.
@@ -1522,10 +1530,12 @@ do { doubleget_union _tmp; \
#endif
#ifndef HAVE_DLERROR
-#define dlerror() ""
+#define dlerror() "No support for dynamic loading (static build?)"
+#define dlopen(A,B) 0
+#define dlsym(A,B) 0
+#define dlclose(A) 0
#endif
-
#ifndef __NETWARE__
/*
* Include standard definitions of operator new and delete.
=== modified file 'include/my_no_pthread.h'
--- a/include/my_no_pthread.h 2009-12-12 18:11:25 +0000
+++ b/include/my_no_pthread.h 2010-03-29 15:13:53 +0000
@@ -46,6 +46,7 @@
#define rw_wrlock(A)
#define rw_unlock(A)
#define rwlock_destroy(A)
+#define safe_mutex_assert_owner(mp)
typedef int my_pthread_once_t;
#define MY_PTHREAD_ONCE_INIT 0
=== modified file 'include/my_sys.h'
--- a/include/my_sys.h 2010-03-15 11:51:23 +0000
+++ b/include/my_sys.h 2010-03-29 15:13:53 +0000
@@ -210,7 +210,7 @@ extern void my_large_free(uchar * ptr, m
#define my_alloca(SZ) alloca((size_t) (SZ))
#define my_afree(PTR) {}
#else
-#define my_alloca(SZ) my_malloc(SZ,MYF(0))
+#define my_alloca(SZ) my_malloc(SZ,MYF(MY_FAE))
#define my_afree(PTR) my_free(PTR,MYF(MY_WME))
#endif /* HAVE_ALLOCA */
@@ -870,6 +870,10 @@ extern void set_prealloc_root(MEM_ROOT *
extern void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
size_t prealloc_size);
extern char *strdup_root(MEM_ROOT *root,const char *str);
+static inline char *safe_strdup_root(MEM_ROOT *root, const char *str)
+{
+ return str ? strdup_root(root, str) : 0;
+}
extern char *strmake_root(MEM_ROOT *root,const char *str,size_t len);
extern void *memdup_root(MEM_ROOT *root,const void *str, size_t len);
extern int get_defaults_options(int argc, char **argv,
=== modified file 'include/mysql.h'
--- a/include/mysql.h 2010-02-01 06:14:12 +0000
+++ b/include/mysql.h 2010-03-29 15:13:53 +0000
@@ -167,9 +167,15 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH
};
+/**
+ @todo remove the "extension", move st_mysql_options completely
+ out of mysql.h
+*/
+struct st_mysql_options_extention;
+
struct st_mysql_options {
unsigned int connect_timeout, read_timeout, write_timeout;
unsigned int port, protocol;
@@ -217,7 +223,7 @@ struct st_mysql_options {
void (*local_infile_end)(void *);
int (*local_infile_error)(void *, char *, unsigned int);
void *local_infile_userdata;
- void *extension;
+ struct st_mysql_options_extention *extension;
};
enum mysql_status
@@ -752,38 +758,6 @@ enum enum_stmt_attr_type
};
-typedef struct st_mysql_methods
-{
- my_bool (*read_query_result)(MYSQL *mysql);
- my_bool (*advanced_command)(MYSQL *mysql,
- enum enum_server_command command,
- const unsigned char *header,
- unsigned long header_length,
- const unsigned char *arg,
- unsigned long arg_length,
- my_bool skip_check,
- MYSQL_STMT *stmt);
- MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
- unsigned int fields);
- MYSQL_RES * (*use_result)(MYSQL *mysql);
- void (*fetch_lengths)(unsigned long *to,
- MYSQL_ROW column, unsigned int field_count);
- void (*flush_use_result)(MYSQL *mysql);
-#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)
- MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
- my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
- int (*stmt_execute)(MYSQL_STMT *stmt);
- int (*read_binary_rows)(MYSQL_STMT *stmt);
- int (*unbuffered_fetch)(MYSQL *mysql, char **row);
- void (*free_embedded_thd)(MYSQL *mysql);
- const char *(*read_statistics)(MYSQL *mysql);
- my_bool (*next_result)(MYSQL *mysql);
- int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
- int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
-#endif
-} MYSQL_METHODS;
-
-
MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql);
int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
unsigned long length);
@@ -846,18 +820,6 @@ int STDCALL mysql_drop_db(MYSQL *mysql,
#endif
#define HAVE_MYSQL_REAL_CONNECT
-/*
- The following functions are mainly exported because of mysqlbinlog;
- They are not for general usage
-*/
-
-#define simple_command(mysql, command, arg, length, skip_check) \
- (*(mysql)->methods->advanced_command)(mysql, command, 0, \
- 0, arg, length, skip_check, NULL)
-#define stmt_command(mysql, command, arg, length, stmt) \
- (*(mysql)->methods->advanced_command)(mysql, command, 0, \
- 0, arg, length, 1, stmt)
-
#ifdef __NETWARE__
#pragma pack(pop) /* restore alignment */
#endif
=== modified file 'include/mysql.h.pp'
--- a/include/mysql.h.pp 2010-03-15 11:51:23 +0000
+++ b/include/mysql.h.pp 2010-03-29 15:13:53 +0000
@@ -128,13 +128,13 @@ void create_random_string(char *to, unsi
void hash_password(unsigned long *to, const char *password, unsigned int password_len);
void make_scrambled_password_323(char *to, const char *password);
void scramble_323(char *to, const char *message, const char *password);
-my_bool check_scramble_323(const char *, const char *message,
+my_bool check_scramble_323(const unsigned char *reply, const char *message,
unsigned long *salt);
void get_salt_from_password_323(unsigned long *res, const char *password);
void make_password_from_salt_323(char *to, const unsigned long *salt);
void make_scrambled_password(char *to, const char *password);
void scramble(char *to, const char *message, const char *password);
-my_bool check_scramble(const char *reply, const char *message,
+my_bool check_scramble(const unsigned char *reply, const char *message,
const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password);
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
@@ -258,8 +258,9 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH
};
+struct st_mysql_options_extention;
struct st_mysql_options {
unsigned int connect_timeout, read_timeout, write_timeout;
unsigned int port, protocol;
@@ -289,7 +290,7 @@ struct st_mysql_options {
void (*local_infile_end)(void *);
int (*local_infile_error)(void *, char *, unsigned int);
void *local_infile_userdata;
- void *extension;
+ struct st_mysql_options_extention *extension;
};
enum mysql_status
{
@@ -601,34 +602,6 @@ enum enum_stmt_attr_type
STMT_ATTR_CURSOR_TYPE,
STMT_ATTR_PREFETCH_ROWS
};
-typedef struct st_mysql_methods
-{
- my_bool (*read_query_result)(MYSQL *mysql);
- my_bool (*advanced_command)(MYSQL *mysql,
- enum enum_server_command command,
- const unsigned char *header,
- unsigned long header_length,
- const unsigned char *arg,
- unsigned long arg_length,
- my_bool skip_check,
- MYSQL_STMT *stmt);
- MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
- unsigned int fields);
- MYSQL_RES * (*use_result)(MYSQL *mysql);
- void (*fetch_lengths)(unsigned long *to,
- MYSQL_ROW column, unsigned int field_count);
- void (*flush_use_result)(MYSQL *mysql);
- MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
- my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
- int (*stmt_execute)(MYSQL_STMT *stmt);
- int (*read_binary_rows)(MYSQL_STMT *stmt);
- int (*unbuffered_fetch)(MYSQL *mysql, char **row);
- void (*free_embedded_thd)(MYSQL *mysql);
- const char *(*read_statistics)(MYSQL *mysql);
- my_bool (*next_result)(MYSQL *mysql);
- int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
- int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
-} MYSQL_METHODS;
MYSQL_STMT * mysql_stmt_init(MYSQL *mysql);
int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
unsigned long length);
=== added file 'include/mysql/client_plugin.h'
--- a/include/mysql/client_plugin.h 1970-01-01 00:00:00 +0000
+++ b/include/mysql/client_plugin.h 2010-03-29 15:13:53 +0000
@@ -0,0 +1,164 @@
+#ifndef MYSQL_CLIENT_PLUGIN_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ MySQL Client Plugin API
+
+ This file defines the API for plugins that work on the client side
+*/
+#define MYSQL_CLIENT_PLUGIN_INCLUDED
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* known plugin types */
+#define MYSQL_CLIENT_reserved1 0
+#define MYSQL_CLIENT_reserved2 1
+#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2
+
+#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100
+
+#define MYSQL_CLIENT_MAX_PLUGINS 3
+
+#define mysql_declare_client_plugin(X) \
+ struct st_mysql_client_plugin_ ## X \
+ _mysql_client_plugin_declaration_ = { \
+ MYSQL_CLIENT_ ## X ## _PLUGIN, \
+ MYSQL_CLIENT_ ## X ## _PLUGIN_INTERFACE_VERSION,
+#define mysql_end_client_plugin }
+
+/* generic plugin header structure */
+#define MYSQL_CLIENT_PLUGIN_HEADER \
+ int type; \
+ unsigned int interface_version; \
+ const char *name; \
+ const char *author; \
+ const char *desc; \
+ unsigned int version[3]; \
+ int (*init)(char *, size_t, int, va_list); \
+ int (*deinit)();
+
+struct st_mysql_client_plugin
+{
+ MYSQL_CLIENT_PLUGIN_HEADER
+};
+
+struct st_mysql;
+
+/******** authentication plugin specific declarations *********/
+#include <mysql/plugin_auth_common.h>
+
+struct st_mysql_client_plugin_AUTHENTICATION
+{
+ MYSQL_CLIENT_PLUGIN_HEADER
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
+};
+
+/**
+ type of the mysql_authentication_dialog_ask function
+
+ @param mysql mysql
+ @param type type of the input
+ 1 - ordinary string input
+ 2 - password string
+ @param prompt prompt
+ @param buf a buffer to store the use input
+ @param buf_len the length of the buffer
+
+ @retval a pointer to the user input string.
+ It may be equal to 'buf' or to 'mysql->password'.
+ In all other cases it is assumed to be an allocated
+ string, and the "dialog" plugin will free() it.
+*/
+typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql,
+ int type, const char *prompt, char *buf, int buf_len);
+/******** using plugins ************/
+
+/**
+ loads a plugin and initializes it
+
+ @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used,
+ and last_errno/last_error, for error reporting
+ @param name a name of the plugin to load
+ @param type type of plugin that should be loaded, -1 to disable type check
+ @param argc number of arguments to pass to the plugin initialization
+ function
+ @param ... arguments for the plugin initialization function
+
+ @retval
+ a pointer to the loaded plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_load_plugin(struct st_mysql *mysql, const char *name, int type,
+ int argc, ...);
+
+/**
+ loads a plugin and initializes it, taking va_list as an argument
+
+ This is the same as mysql_load_plugin, but take va_list instead of
+ a list of arguments.
+
+ @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used,
+ and last_errno/last_error, for error reporting
+ @param name a name of the plugin to load
+ @param type type of plugin that should be loaded, -1 to disable type check
+ @param argc number of arguments to pass to the plugin initialization
+ function
+ @param args arguments for the plugin initialization function
+
+ @retval
+ a pointer to the loaded plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type,
+ int argc, va_list args);
+
+/**
+ finds an already loaded plugin by name, or loads it, if necessary
+
+ @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used,
+ and last_errno/last_error, for error reporting
+ @param name a name of the plugin to load
+ @param type type of plugin that should be loaded
+
+ @retval
+ a pointer to the plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_client_find_plugin(struct st_mysql *mysql, const char *name, int type);
+
+/**
+ adds a plugin structure to the list of loaded plugins
+
+ This is useful if an application has the necessary functionality
+ (for example, a special load data handler) statically linked into
+ the application binary. It can use this function to register the plugin
+ directly, avoiding the need to factor it out into a shared object.
+
+ @param mysql MYSQL structure. It is only used for error reporting
+ @param plugin an st_mysql_client_plugin structure to register
+
+ @retval
+ a pointer to the plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_client_register_plugin(struct st_mysql *mysql,
+ struct st_mysql_client_plugin *plugin);
+
+#endif
+
=== added file 'include/mysql/client_plugin.h.pp'
--- a/include/mysql/client_plugin.h.pp 1970-01-01 00:00:00 +0000
+++ b/include/mysql/client_plugin.h.pp 2010-03-29 15:13:53 +0000
@@ -0,0 +1,41 @@
+#include <stdarg.h>
+#include <stdlib.h>
+struct st_mysql_client_plugin
+{
+ int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; int (*init)(char *, size_t, int, va_list); int (*deinit)();
+};
+struct st_mysql;
+#include <mysql/plugin_auth_common.h>
+typedef struct st_plugin_vio_info
+{
+ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
+ MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
+ int socket;
+} MYSQL_PLUGIN_VIO_INFO;
+typedef struct st_plugin_vio
+{
+ int (*read_packet)(struct st_plugin_vio *vio,
+ unsigned char **buf);
+ int (*write_packet)(struct st_plugin_vio *vio,
+ const unsigned char *packet,
+ int packet_len);
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+} MYSQL_PLUGIN_VIO;
+struct st_mysql_client_plugin_AUTHENTICATION
+{
+ int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; int (*init)(char *, size_t, int, va_list); int (*deinit)();
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
+};
+typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql,
+ int type, const char *prompt, char *buf, int buf_len);
+struct st_mysql_client_plugin *
+mysql_load_plugin(struct st_mysql *mysql, const char *name, int type,
+ int argc, ...);
+struct st_mysql_client_plugin *
+mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type,
+ int argc, va_list args);
+struct st_mysql_client_plugin *
+mysql_client_find_plugin(struct st_mysql *mysql, const char *name, int type);
+struct st_mysql_client_plugin *
+mysql_client_register_plugin(struct st_mysql *mysql,
+ struct st_mysql_client_plugin *plugin);
=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h 2010-03-03 14:44:14 +0000
+++ b/include/mysql/plugin.h 2010-03-29 15:13:53 +0000
@@ -67,7 +67,10 @@ typedef struct st_mysql_xid MYSQL_XID;
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
-#define MYSQL_MAX_PLUGIN_TYPE_NUM 5 /* The number of plugin types */
+#define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */
+#define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */
+#define MYSQL_AUTHENTICATION_PLUGIN 7 /* The authentication plugin type */
+#define MYSQL_MAX_PLUGIN_TYPE_NUM 8 /* The number of plugin types */
/* We use the following strings to define licenses for plugins */
#define PLUGIN_LICENSE_PROPRIETARY 0
=== removed file 'include/mysql/plugin.h.pp'
--- a/include/mysql/plugin.h.pp 2010-03-03 14:44:14 +0000
+++ b/include/mysql/plugin.h.pp 1970-01-01 00:00:00 +0000
@@ -1,163 +0,0 @@
-#include <mysql/services.h>
-#include <mysql/service_my_snprintf.h>
-#include <stdarg.h>
-#include <stdlib.h>
-extern struct my_snprintf_service_st {
- size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
- size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
-} *my_snprintf_service;
-size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
-size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
-#include <mysql/service_thd_alloc.h>
-#include <stdlib.h>
-struct st_mysql_lex_string
-{
- char *str;
- size_t length;
-};
-typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
-extern struct thd_alloc_service_st {
- void *(*thd_alloc_func)(void*, unsigned int);
- void *(*thd_calloc_func)(void*, unsigned int);
- char *(*thd_strdup_func)(void*, const char *);
- char *(*thd_strmake_func)(void*, const char *, unsigned int);
- void *(*thd_memdup_func)(void*, const void*, unsigned int);
- MYSQL_LEX_STRING *(*thd_make_lex_string_func)(void*, MYSQL_LEX_STRING *,
- const char *, unsigned int, int);
-} *thd_alloc_service;
-void *thd_alloc(void* thd, unsigned int size);
-void *thd_calloc(void* thd, unsigned int size);
-char *thd_strdup(void* thd, const char *str);
-char *thd_strmake(void* thd, const char *str, unsigned int size);
-void *thd_memdup(void* thd, const void* str, unsigned int size);
-MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
- const char *str, unsigned int size,
- int allocate_lex_string);
-struct st_mysql_xid {
- long formatID;
- long gtrid_length;
- long bqual_length;
- char data[128];
-};
-typedef struct st_mysql_xid MYSQL_XID;
-enum enum_mysql_show_type
-{
- SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
- SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
- SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
- SHOW_always_last
-};
-struct st_mysql_show_var {
- const char *name;
- char *value;
- enum enum_mysql_show_type type;
-};
-typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, char *);
-struct st_mysql_sys_var;
-struct st_mysql_value;
-typedef int (*mysql_var_check_func)(void* thd,
- struct st_mysql_sys_var *var,
- void *save, struct st_mysql_value *value);
-typedef void (*mysql_var_update_func)(void* thd,
- struct st_mysql_sys_var *var,
- void *var_ptr, const void *save);
-struct st_mysql_plugin
-{
- int type;
- void *info;
- const char *name;
- const char *author;
- const char *descr;
- int license;
- int (*init)(void *);
- int (*deinit)(void *);
- unsigned int version;
- struct st_mysql_show_var *status_vars;
- struct st_mysql_sys_var **system_vars;
- void * __reserved1;
-};
-enum enum_ftparser_mode
-{
- MYSQL_FTPARSER_SIMPLE_MODE= 0,
- MYSQL_FTPARSER_WITH_STOPWORDS= 1,
- MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
-};
-enum enum_ft_token_type
-{
- FT_TOKEN_EOF= 0,
- FT_TOKEN_WORD= 1,
- FT_TOKEN_LEFT_PAREN= 2,
- FT_TOKEN_RIGHT_PAREN= 3,
- FT_TOKEN_STOPWORD= 4
-};
-typedef struct st_mysql_ftparser_boolean_info
-{
- enum enum_ft_token_type type;
- int yesno;
- int weight_adjust;
- char wasign;
- char trunc;
- char prev;
- char *quot;
-} MYSQL_FTPARSER_BOOLEAN_INFO;
-typedef int mysql_ft_size_t;
-typedef struct st_mysql_ftparser_param
-{
- int (*mysql_parse)(struct st_mysql_ftparser_param *,
- const unsigned char *doc, mysql_ft_size_t doc_len);
- int (*mysql_add_word)(struct st_mysql_ftparser_param *,
- const unsigned char *word, mysql_ft_size_t word_len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
- void *ftparser_state;
- void *mysql_ftparam;
- const struct charset_info_st *cs;
- const unsigned char *doc;
- mysql_ft_size_t length;
- unsigned int flags;
- enum enum_ftparser_mode mode;
-} MYSQL_FTPARSER_PARAM;
-struct st_mysql_ftparser
-{
- int interface_version;
- int (*parse)(MYSQL_FTPARSER_PARAM *param);
- int (*init)(MYSQL_FTPARSER_PARAM *param);
- int (*deinit)(MYSQL_FTPARSER_PARAM *param);
-};
-struct st_mysql_storage_engine
-{
- int interface_version;
-};
-struct handlerton;
-struct st_mysql_daemon
-{
- int interface_version;
-};
-struct st_mysql_information_schema
-{
- int interface_version;
-};
-struct st_mysql_value
-{
- int (*value_type)(struct st_mysql_value *);
- const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
- int (*val_real)(struct st_mysql_value *, double *realbuf);
- int (*val_int)(struct st_mysql_value *, long long *intbuf);
-};
-int thd_in_lock_tables(const void* thd);
-int thd_tablespace_op(const void* thd);
-long long thd_test_options(const void* thd, long long test_options);
-int thd_sql_command(const void* thd);
-void **thd_ha_data(const void* thd, const struct handlerton *hton);
-int thd_tx_isolation(const void* thd);
-char *thd_security_context(void* thd, char *buffer, unsigned int length,
- unsigned int max_query_len);
-void thd_inc_row_count(void* thd);
-const char *set_thd_proc_info(void*, const char * info, const char *func,
- const char *file, const unsigned int line);
-int mysql_tmpfile(const char *prefix);
-int thd_killed(const void* thd);
-unsigned long thd_get_thread_id(const void* thd);
-void thd_get_xid(const void* thd, MYSQL_XID *xid);
-void mysql_query_cache_invalidate4(void* thd,
- const char *key, unsigned int key_length,
- int using_trx);
=== added file 'include/mysql/plugin_auth.h'
--- a/include/mysql/plugin_auth.h 1970-01-01 00:00:00 +0000
+++ b/include/mysql/plugin_auth.h 2010-03-29 15:13:53 +0000
@@ -0,0 +1,83 @@
+#ifndef MYSQL_PLUGIN_AUTH_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ Authentication Plugin API.
+
+ This file defines the API for server authentication plugins.
+*/
+
+#define MYSQL_PLUGIN_AUTH_INCLUDED
+
+#include <mysql/plugin.h>
+
+#define MYSQL_AUTHENTICATION_INTERFACE_VERSION 0x0100
+
+#include <mysql/plugin_auth_common.h>
+
+/**
+ Provides server plugin access to authentication information
+*/
+typedef struct st_mysql_server_auth_info
+{
+ /**
+ User name as sent by the client and shown in USER().
+ NULL if the client packet with the user name was not received yet.
+ */
+ const char *user_name;
+ /**
+ A corresponding column value from the mysql.user table for the
+ matching account name
+ */
+ const char *auth_string;
+
+ /**
+ Matching account name as found in the mysql.user table.
+ A plugin can override it with another name that will be
+ used by MySQL for authorization, and shown in CURRENT_USER()
+ */
+ char authenticated_as[MYSQL_USERNAME_LENGTH+1];
+ /**
+ This only affects the "Authentication failed. Password used: %s"
+ error message. If set, %s will be YES, otherwise - NO.
+ Set it as appropriate or ignore at will.
+ */
+ int password_used;
+} MYSQL_SERVER_AUTH_INFO;
+
+/**
+ Server authentication plugin descriptor
+*/
+struct st_mysql_auth
+{
+ int interface_version; /**< version plugin uses */
+ /**
+ A plugin that a client must use for authentication with this server
+ plugin. Can be NULL to mean "any plugin".
+ */
+ const char *client_auth_plugin;
+ /**
+ Function provided by the plugin which should perform authentication (using
+ the vio functions if necessary) and return 0 if successful. The plugin can
+ also fill the info.authenticated_as field if a different username should be
+ used for authorization.
+ */
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);
+};
+#endif
+
=== added file 'include/mysql/plugin_auth.h.pp'
--- a/include/mysql/plugin_auth.h.pp 1970-01-01 00:00:00 +0000
+++ b/include/mysql/plugin_auth.h.pp 2010-03-29 15:13:53 +0000
@@ -0,0 +1,193 @@
+#include <mysql/plugin.h>
+#include <mysql/services.h>
+#include <mysql/service_my_snprintf.h>
+#include <stdarg.h>
+#include <stdlib.h>
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+#include <mysql/service_thd_alloc.h>
+#include <stdlib.h>
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(void*, unsigned int);
+ void *(*thd_calloc_func)(void*, unsigned int);
+ char *(*thd_strdup_func)(void*, const char *);
+ char *(*thd_strmake_func)(void*, const char *, unsigned int);
+ void *(*thd_memdup_func)(void*, const void*, unsigned int);
+ MYSQL_LEX_STRING *(*thd_make_lex_string_func)(void*, MYSQL_LEX_STRING *,
+ const char *, unsigned int, int);
+} *thd_alloc_service;
+void *thd_alloc(void* thd, unsigned int size);
+void *thd_calloc(void* thd, unsigned int size);
+char *thd_strdup(void* thd, const char *str);
+char *thd_strmake(void* thd, const char *str, unsigned int size);
+void *thd_memdup(void* thd, const void* str, unsigned int size);
+MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
+ const char *str, unsigned int size,
+ int allocate_lex_string);
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[128];
+};
+typedef struct st_mysql_xid MYSQL_XID;
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
+ SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_always_last
+};
+struct st_mysql_show_var {
+ const char *name;
+ char *value;
+ enum enum_mysql_show_type type;
+};
+typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, char *);
+struct st_mysql_sys_var;
+struct st_mysql_value;
+typedef int (*mysql_var_check_func)(void* thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+typedef void (*mysql_var_update_func)(void* thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+struct st_mysql_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1;
+};
+enum enum_ftparser_mode
+{
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef int mysql_ft_size_t;
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const unsigned char *doc, mysql_ft_size_t doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const unsigned char *word, mysql_ft_size_t word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const unsigned char *doc;
+ mysql_ft_size_t length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+struct handlerton;
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+};
+int thd_in_lock_tables(const void* thd);
+int thd_tablespace_op(const void* thd);
+long long thd_test_options(const void* thd, long long test_options);
+int thd_sql_command(const void* thd);
+void **thd_ha_data(const void* thd, const struct handlerton *hton);
+int thd_tx_isolation(const void* thd);
+char *thd_security_context(void* thd, char *buffer, unsigned int length,
+ unsigned int max_query_len);
+void thd_inc_row_count(void* thd);
+const char *set_thd_proc_info(void*, const char * info, const char *func,
+ const char *file, const unsigned int line);
+int mysql_tmpfile(const char *prefix);
+int thd_killed(const void* thd);
+unsigned long thd_get_thread_id(const void* thd);
+void thd_get_xid(const void* thd, MYSQL_XID *xid);
+void mysql_query_cache_invalidate4(void* thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+#include <mysql/plugin_auth_common.h>
+typedef struct st_plugin_vio_info
+{
+ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
+ MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
+ int socket;
+} MYSQL_PLUGIN_VIO_INFO;
+typedef struct st_plugin_vio
+{
+ int (*read_packet)(struct st_plugin_vio *vio,
+ unsigned char **buf);
+ int (*write_packet)(struct st_plugin_vio *vio,
+ const unsigned char *packet,
+ int packet_len);
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+} MYSQL_PLUGIN_VIO;
+typedef struct st_mysql_server_auth_info
+{
+ const char *user_name;
+ const char *auth_string;
+ char authenticated_as[48 +1];
+ int password_used;
+} MYSQL_SERVER_AUTH_INFO;
+struct st_mysql_auth
+{
+ int interface_version;
+ const char *client_auth_plugin;
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);
+};
=== added file 'include/mysql/plugin_auth_common.h'
--- a/include/mysql/plugin_auth_common.h 1970-01-01 00:00:00 +0000
+++ b/include/mysql/plugin_auth_common.h 2010-03-29 15:13:53 +0000
@@ -0,0 +1,105 @@
+#ifndef MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ This file defines constants and data structures that are the same for
+ both client- and server-side authentication plugins.
+*/
+#define MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
+
+/** the max allowed length for a user name */
+#define MYSQL_USERNAME_LENGTH 48
+
+/**
+ return values of the plugin authenticate_user() method.
+*/
+
+/**
+ Authentication failed. Additionally, all other CR_xxx values
+ (libmysql error code) can be used too.
+
+ The client plugin may set the error code and the error message directly
+ in the MYSQL structure and return CR_ERROR. If a CR_xxx specific error
+ code was returned, an error message in the MYSQL structure will be
+ overwritten. If CR_ERROR is returned without setting the error in MYSQL,
+ CR_UNKNOWN_ERROR will be user.
+*/
+#define CR_ERROR 0
+/**
+ Authentication (client part) was successful. It does not mean that the
+ authentication as a whole was successful, usually it only means
+ that the client was able to send the user name and the password to the
+ server. If CR_OK is returned, the libmysql reads the next packet expecting
+ it to be one of OK, ERROR, or CHANGE_PLUGIN packets.
+*/
+#define CR_OK -1
+/**
+ Authentication was successful.
+ It means that the client has done its part successfully and also that
+ a plugin has read the last packet (one of OK, ERROR, CHANGE_PLUGIN).
+ In this case, libmysql will not read a packet from the server,
+ but it will use the data at mysql->net.read_pos.
+
+ A plugin may return this value if the number of roundtrips in the
+ authentication protocol is not known in advance, and the client plugin
+ needs to read one packet more to determine if the authentication is finished
+ or not.
+*/
+#define CR_OK_HANDSHAKE_COMPLETE -2
+
+typedef struct st_plugin_vio_info
+{
+ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
+ MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
+ int socket; /**< it's set, if the protocol is SOCKET or TCP */
+#ifdef _WIN32
+ HANDLE handle; /**< it's set, if the protocol is PIPE or MEMORY */
+#endif
+} MYSQL_PLUGIN_VIO_INFO;
+
+/**
+ Provides plugin access to communication channel
+*/
+typedef struct st_plugin_vio
+{
+ /**
+ Plugin provides a pointer reference and this function sets it to the
+ contents of any incoming packet. Returns the packet length, or -1 if
+ the plugin should terminate.
+ */
+ int (*read_packet)(struct st_plugin_vio *vio,
+ unsigned char **buf);
+
+ /**
+ Plugin provides a buffer with data and the length and this
+ function sends it as a packet. Returns 0 on success, 1 on failure.
+ */
+ int (*write_packet)(struct st_plugin_vio *vio,
+ const unsigned char *packet,
+ int packet_len);
+
+ /**
+ Fills in a st_plugin_vio_info structure, providing the information
+ about the connection.
+ */
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+
+} MYSQL_PLUGIN_VIO;
+
+#endif
+
=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h 2010-03-15 11:51:23 +0000
+++ b/include/mysql_com.h 2010-03-29 15:13:53 +0000
@@ -152,9 +152,17 @@ enum enum_server_command
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */
+#define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */
+
#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
#define CLIENT_REMEMBER_OPTIONS (1UL << 31)
+#ifdef HAVE_COMPRESS
+#define CAN_CLIENT_COMPRESS CLIENT_COMPRESS
+#else
+#define CAN_CLIENT_COMPRESS 0
+#endif
+
/* Gather all possible capabilites (flags) supported by the server */
#define CLIENT_ALL_FLAGS (CLIENT_LONG_PASSWORD | \
CLIENT_FOUND_ROWS | \
@@ -175,7 +183,8 @@ enum enum_server_command
CLIENT_MULTI_STATEMENTS | \
CLIENT_MULTI_RESULTS | \
CLIENT_SSL_VERIFY_SERVER_CERT | \
- CLIENT_REMEMBER_OPTIONS)
+ CLIENT_REMEMBER_OPTIONS | \
+ CLIENT_PLUGIN_AUTH)
/*
Switch off the flags that are optional and depending on build flags
@@ -488,14 +497,14 @@ void create_random_string(char *to, unsi
void hash_password(unsigned long *to, const char *password, unsigned int password_len);
void make_scrambled_password_323(char *to, const char *password);
void scramble_323(char *to, const char *message, const char *password);
-my_bool check_scramble_323(const char *, const char *message,
+my_bool check_scramble_323(const unsigned char *reply, const char *message,
unsigned long *salt);
void get_salt_from_password_323(unsigned long *res, const char *password);
void make_password_from_salt_323(char *to, const unsigned long *salt);
void make_scrambled_password(char *to, const char *password);
void scramble(char *to, const char *message, const char *password);
-my_bool check_scramble(const char *reply, const char *message,
+my_bool check_scramble(const unsigned char *reply, const char *message,
const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password);
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
=== modified file 'include/sql_common.h'
--- a/include/sql_common.h 2008-02-27 09:00:59 +0000
+++ b/include/sql_common.h 2010-03-29 15:13:53 +0000
@@ -1,3 +1,4 @@
+#ifndef SQL_COMMON_INCLUDED
/* Copyright (C) 2003-2004, 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -13,14 +14,60 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#define SQL_COMMON_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <mysql.h>
extern const char *unknown_sqlstate;
extern const char *cant_connect_sqlstate;
extern const char *not_error_sqlstate;
-#ifdef __cplusplus
-extern "C" {
+struct st_mysql_options_extention {
+ char *plugin_dir;
+ char *default_auth;
+};
+
+typedef struct st_mysql_methods
+{
+ my_bool (*read_query_result)(MYSQL *mysql);
+ my_bool (*advanced_command)(MYSQL *mysql,
+ enum enum_server_command command,
+ const unsigned char *header,
+ unsigned long header_length,
+ const unsigned char *arg,
+ unsigned long arg_length,
+ my_bool skip_check,
+ MYSQL_STMT *stmt);
+ MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
+ unsigned int fields);
+ MYSQL_RES * (*use_result)(MYSQL *mysql);
+ void (*fetch_lengths)(unsigned long *to,
+ MYSQL_ROW column, unsigned int field_count);
+ void (*flush_use_result)(MYSQL *mysql);
+ int (*read_change_user_result)(MYSQL *mysql);
+#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)
+ MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
+ my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
+ int (*stmt_execute)(MYSQL_STMT *stmt);
+ int (*read_binary_rows)(MYSQL_STMT *stmt);
+ int (*unbuffered_fetch)(MYSQL *mysql, char **row);
+ void (*free_embedded_thd)(MYSQL *mysql);
+ const char *(*read_statistics)(MYSQL *mysql);
+ my_bool (*next_result)(MYSQL *mysql);
+ int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
#endif
+} MYSQL_METHODS;
+
+#define simple_command(mysql, command, arg, length, skip_check) \
+ (*(mysql)->methods->advanced_command)(mysql, command, 0, \
+ 0, arg, length, skip_check, NULL)
+#define stmt_command(mysql, command, arg, length, stmt) \
+ (*(mysql)->methods->advanced_command)(mysql, command, 0, \
+ 0, arg, length, 1, stmt)
extern CHARSET_INFO *default_client_charset_info;
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
@@ -42,9 +89,23 @@ void set_stmt_errmsg(MYSQL_STMT *stmt, N
void set_stmt_error(MYSQL_STMT *stmt, int errcode, const char *sqlstate,
const char *err);
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate);
+void set_mysql_extended_error(MYSQL *mysql, int errcode, const char *sqlstate,
+ const char *format, ...);
+
+/* client side of the pluggable authentication */
+struct st_plugin_vio_info;
+void mpvio_info(Vio *vio, struct st_plugin_vio_info *info);
+int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
+ char *data_plugin, const char *db);
+int mysql_client_plugin_init();
+void mysql_client_plugin_deinit();
+struct st_mysql_client_plugin;
+extern struct st_mysql_client_plugin *mysql_client_builtins[];
+
#ifdef __cplusplus
}
#endif
#define protocol_41(A) ((A)->server_capabilities & CLIENT_PROTOCOL_41)
+#endif
=== modified file 'libmysql/CMakeLists.txt'
--- a/libmysql/CMakeLists.txt 2009-09-15 10:46:35 +0000
+++ b/libmysql/CMakeLists.txt 2010-03-29 15:13:53 +0000
@@ -98,7 +98,7 @@ SET(CLIENT_SOURCES ../mysys/array.c ..
../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c
../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c
../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c ../mysys/mf_qsort.c
- ../mysys/my_getsystime.c ../mysys/my_sync.c ${LIB_SOURCES})
+ ../mysys/my_getsystime.c ../mysys/my_sync.c ../sql-common/client_plugin.c ${LIB_SOURCES})
# Need to set USE_TLS for building the DLL, since __declspec(thread)
# approach to thread local storage does not work properly in DLLs.
@@ -125,6 +125,7 @@ IF(WIN32)
ENDIF(WIN32)
ADD_DEPENDENCIES(libmysql GenError)
TARGET_LINK_LIBRARIES(libmysql wsock32)
+ADD_DEFINITIONS(-DHAVE_DLOPEN)
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("myTest" "asInvoker")
=== modified file 'libmysql/Makefile.shared'
--- a/libmysql/Makefile.shared 2009-09-15 10:46:35 +0000
+++ b/libmysql/Makefile.shared 2010-03-29 15:13:53 +0000
@@ -23,6 +23,7 @@
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
+pkgplugindir = $(pkglibdir)/plugin
## We'll use CLIENT_EXTRA_LDFLAGS for threaded and non-threaded
## until someone complains that they need separate options.
LDADD = @CLIENT_EXTRA_LDFLAGS@ $(target)
@@ -71,26 +72,27 @@ mysysobjects1 = my_init.lo my_static.lo
my_getopt.lo my_gethostbyname.lo my_port.lo \
my_rename.lo my_chsize.lo my_sync.lo my_getsystime.lo
sqlobjects = net.lo
-sql_cmn_objects = pack.lo client.lo my_time.lo
+sql_cmn_objects = pack.lo client.lo my_time.lo client_plugin.lo
# Not needed in the minimum library
mysysobjects2 = my_lib.lo mf_qsort.lo
mysysobjects = $(mysysobjects1) $(mysysobjects2)
target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
$(sql_cmn_objects) $(vio_objects) $(sqlobjects)
-target_ldflags = -version-info @SHARED_LIB_VERSION@ @LD_VERSION_SCRIPT@
+target_ldflags = -version-info @SHARED_LIB_VERSION@ @LD_VERSION_SCRIPT@ @LIBDL@
vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
BUILT_SOURCES = link_sources
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
$(target) $(BUILT_SOURCES)
-DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
+DEFS = -DDEFAULT_CHARSET_HOME='"$(MYSQLBASEdir)"' \
+ -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \
-DDEFAULT_HOME_ENV=MYSQL_HOME \
+ -DPLUGINDIR='"$(pkgplugindir)"' \
-DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \
- -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \
- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" $(target_defs)
+ -DDEFAULT_SYSCONFDIR='"$(sysconfdir)"' \
+ -DSHAREDIR='"$(MYSQLSHAREdir)"' $(target_defs)
if HAVE_YASSL
yassl_las = $(top_builddir)/extra/yassl/src/libyassl.la \
=== modified file 'libmysql/client_settings.h'
--- a/libmysql/client_settings.h 2007-09-29 19:31:08 +0000
+++ b/libmysql/client_settings.h 2010-03-29 15:13:53 +0000
@@ -18,7 +18,8 @@ extern char * mysql_unix_port;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \
CLIENT_TRANSACTIONS | \
- CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION)
+ CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | \
+ CLIENT_PLUGIN_AUTH)
sig_handler my_pipe_sig_handler(int sig);
void read_user_name(char *name);
@@ -57,7 +58,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt);
int cli_read_binary_rows(MYSQL_STMT *stmt);
int cli_unbuffered_fetch(MYSQL *mysql, char **row);
const char * cli_read_statistics(MYSQL *mysql);
-int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd);
+int cli_read_change_user_result(MYSQL *mysql);
#ifdef EMBEDDED_LIBRARY
int init_embedded_server(int argc, char **argv, char **groups);
=== modified file 'libmysql/errmsg.c'
--- a/libmysql/errmsg.c 2008-05-20 16:36:26 +0000
+++ b/libmysql/errmsg.c 2010-03-29 15:13:53 +0000
@@ -85,6 +85,7 @@ const char *client_errors[]=
"Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
+ "Authentication plugin '%s' cannot be loaded: %s",
""
};
@@ -151,6 +152,7 @@ const char *client_errors[]=
"Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
+ "Authentication plugin '%s' cannot be loaded: %s",
""
};
@@ -215,6 +217,7 @@ const char *client_errors[]=
"Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
+ "Authentication plugin '%s' cannot be loaded: %s",
""
};
#endif
=== modified file 'libmysql/libmysql.c'
--- a/libmysql/libmysql.c 2010-03-04 08:03:07 +0000
+++ b/libmysql/libmysql.c 2010-03-29 15:13:53 +0000
@@ -126,12 +126,13 @@ int STDCALL mysql_server_init(int argc _
if (my_init()) /* Will init threads */
return 1;
init_client_errs();
+ if (mysql_client_plugin_init())
+ return 1;
if (!mysql_port)
{
mysql_port = MYSQL_PORT;
#ifndef MSDOS
{
- struct servent *serv_ptr;
char *env;
/*
@@ -145,6 +146,7 @@ int STDCALL mysql_server_init(int argc _
*/
#if MYSQL_PORT_DEFAULT == 0
+ struct servent *serv_ptr;
if ((serv_ptr = getservbyname("mysql", "tcp")))
mysql_port = (uint) ntohs((ushort) serv_ptr->s_port);
#endif
@@ -198,6 +200,8 @@ void STDCALL mysql_server_end()
if (!mysql_client_init)
return;
+ mysql_client_plugin_deinit();
+
#ifdef EMBEDDED_LIBRARY
end_embedded_server();
#endif
@@ -662,44 +666,14 @@ mysql_connect(MYSQL *mysql,const char *h
Change user and database
**************************************************************************/
-int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
-{
- NET *net= &mysql->net;
- ulong pkt_length;
-
- pkt_length= cli_safe_read(mysql);
-
- if (pkt_length == packet_error)
- return 1;
-
- if (pkt_length == 1 && net->read_pos[0] == 254 &&
- mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- /*
- By sending this very specific reply server asks us to send scrambled
- password in old format. The reply contains scramble_323.
- */
- scramble_323(buff, mysql->scramble, passwd);
- if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
- net_flush(net))
- {
- set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
- return 1;
- }
- /* Read what server thinks about out new auth message report */
- if (cli_safe_read(mysql) == packet_error)
- return 1;
- }
- return 0;
-}
-
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db)
{
- char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2];
- char *end= buff;
int rc;
CHARSET_INFO *saved_cs= mysql->charset;
+ char *saved_user= mysql->user;
+ char *saved_passwd= mysql->passwd;
+ char *saved_db= mysql->db;
DBUG_ENTER("mysql_change_user");
@@ -713,49 +687,11 @@ my_bool STDCALL mysql_change_user(MYSQL
/* Use an empty string instead of NULL. */
- if (!user)
- user="";
- if (!passwd)
- passwd="";
-
- /*
- Store user into the buffer.
- Advance position as strmake returns a pointer to the closing NUL.
- */
- end= strmake(end, user, USERNAME_LENGTH) + 1;
-
- /* write scrambled password according to server capabilities */
- if (passwd[0])
- {
- if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- *end++= SCRAMBLE_LENGTH;
- scramble(end, mysql->scramble, passwd);
- end+= SCRAMBLE_LENGTH;
- }
- else
- {
- scramble_323(end, mysql->scramble, passwd);
- end+= SCRAMBLE_LENGTH_323 + 1;
- }
- }
- else
- *end++= '\0'; /* empty password */
- /* Add database if needed */
- end= strmake(end, db ? db : "", NAME_LEN) + 1;
-
- /* Add character set number. */
-
- if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- int2store(end, (ushort) mysql->charset->number);
- end+= 2;
- }
-
- /* Write authentication package */
- simple_command(mysql,COM_CHANGE_USER, (uchar*) buff, (ulong) (end-buff), 1);
+ mysql->user= (char*)(user ? user : "");
+ mysql->passwd= (char*)(passwd ? passwd : "");
+ mysql->db= 0;
- rc= (*mysql->methods->read_change_user_result)(mysql, buff, passwd);
+ rc= run_plugin_auth(mysql, 0, 0, 0, db);
/*
The server will close all statements no matter was the attempt
@@ -765,18 +701,21 @@ my_bool STDCALL mysql_change_user(MYSQL
if (rc == 0)
{
/* Free old connect information */
- my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(saved_user, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(saved_passwd, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(saved_db, MYF(MY_ALLOW_ZERO_PTR));
/* alloc new connect information */
- mysql->user= my_strdup(user,MYF(MY_WME));
- mysql->passwd=my_strdup(passwd,MYF(MY_WME));
- mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
+ mysql->user= my_strdup(mysql->user, MYF(MY_WME));
+ mysql->passwd= my_strdup(mysql->passwd, MYF(MY_WME));
+ mysql->db= db ? my_strdup(db, MYF(MY_WME)) : 0;
}
else
{
mysql->charset= saved_cs;
+ mysql->user= saved_user;
+ mysql->passwd= saved_passwd;
+ mysql->db= saved_db;
}
DBUG_RETURN(rc);
=== modified file 'libmysqld/Makefile.am'
--- a/libmysqld/Makefile.am 2009-12-03 11:19:05 +0000
+++ b/libmysqld/Makefile.am 2010-03-29 15:13:53 +0000
@@ -25,10 +25,10 @@ pkgplugindir = $(pkglibdir)/plugin
EXTRA_DIST = libmysqld.def CMakeLists.txt
DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
- -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
- -DPLUGINDIR="\"$(pkgplugindir)\""
+ -DDEFAULT_MYSQL_HOME='"$(MYSQLBASEdir)"' \
+ -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \
+ -DSHAREDIR='"$(MYSQLSHAREdir)"' \
+ -DPLUGINDIR='"$(pkgplugindir)"'
INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \
-I$(top_builddir)/sql -I$(top_srcdir)/sql \
-I$(top_srcdir)/sql/examples \
@@ -41,7 +41,7 @@ pkglib_LIBRARIES = libmysqld.a
SUBDIRS = . examples
libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \
- my_time.c
+ my_time.c client_plugin.c
noinst_HEADERS = embedded_priv.h emb_qcache.h
=== modified file 'libmysqld/embedded_priv.h'
--- a/libmysqld/embedded_priv.h 2006-12-31 00:32:21 +0000
+++ b/libmysqld/embedded_priv.h 2010-03-29 15:13:53 +0000
@@ -15,6 +15,8 @@
/* Prototypes for the embedded version of MySQL */
+#include <sql_common.h>
+
C_MODE_START
void lib_connection_phase(NET *net, int phase);
void init_embedded_mysql(MYSQL *mysql, int client_flag);
=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc 2010-03-04 08:03:07 +0000
+++ b/libmysqld/lib_sql.cc 2010-03-29 15:13:53 +0000
@@ -35,7 +35,6 @@ C_MODE_START
#include <mysql.h>
#undef ER
#include "errmsg.h"
-#include <sql_common.h>
#include "embedded_priv.h"
extern unsigned int mysql_server_last_errno;
@@ -413,11 +412,10 @@ static MYSQL_RES * emb_store_result(MYSQ
return mysql_store_result(mysql);
}
-int emb_read_change_user_result(MYSQL *mysql,
- char *buff __attribute__((unused)),
- const char *passwd __attribute__((unused)))
+int emb_read_change_user_result(MYSQL *mysql)
{
- return mysql_errno(mysql);
+ mysql->net.read_pos= (uchar*)""; // fake an OK packet
+ return mysql_errno(mysql) ? packet_error : 1 /* length of the OK packet */;
}
MYSQL_METHODS embedded_methods=
@@ -428,6 +426,7 @@ MYSQL_METHODS embedded_methods=
emb_store_result,
emb_fetch_lengths,
emb_flush_use_result,
+ emb_read_change_user_result,
emb_list_fields,
emb_read_prepare_result,
emb_stmt_execute,
@@ -436,7 +435,6 @@ MYSQL_METHODS embedded_methods=
emb_free_embedded_thd,
emb_read_statistics,
emb_read_query_result,
- emb_read_change_user_result,
emb_read_rows_from_cursor
};
@@ -584,6 +582,7 @@ void init_embedded_mysql(MYSQL *mysql, i
THD *thd = (THD *)mysql->thd;
thd->mysql= mysql;
mysql->server_version= server_version;
+ mysql->client_flag= client_flag;
init_alloc_root(&mysql->field_alloc, 8192, 0);
}
@@ -648,14 +647,19 @@ err:
int check_embedded_connection(MYSQL *mysql, const char *db)
{
int result;
+ LEX_STRING db_str = { (char*)db, db ? strlen(db) : 0 };
THD *thd= (THD*)mysql->thd;
thd_init_client_charset(thd, mysql->charset->number);
thd->update_charset();
Security_context *sctx= thd->security_ctx;
sctx->host_or_ip= sctx->host= (char*) my_localhost;
strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1);
- sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0));
- result= check_user(thd, COM_CONNECT, NULL, 0, db, true);
+ strmake(sctx->priv_user, mysql->user, USERNAME_LENGTH-1);
+ sctx->user= my_strdup(mysql->user, MYF(0));
+ sctx->master_access= GLOBAL_ACLS; // Full rights
+ /* Change database if necessary */
+ if (!(result= (db && db[0] && mysql_change_db(thd, &db_str, FALSE))))
+ my_ok(thd);
net_end_statement(thd);
emb_read_query_result(mysql);
return result;
@@ -664,14 +668,15 @@ int check_embedded_connection(MYSQL *mys
#else
int check_embedded_connection(MYSQL *mysql, const char *db)
{
+ /*
+ we emulate a COM_CHANGE_USER user here,
+ it's easier than to emulate the complete 3-way handshake
+ */
+ char buf[USERNAME_LENGTH + SCRAMBLE_LENGTH + 1 + 2*NAME_LEN + 2], *end;
+ NET *net= &mysql->net;
THD *thd= (THD*)mysql->thd;
Security_context *sctx= thd->security_ctx;
- int result;
- char scramble_buff[SCRAMBLE_LENGTH];
- int passwd_len;
- thd_init_client_charset(thd, mysql->charset->number);
- thd->update_charset();
if (mysql->options.client_ip)
{
sctx->host= my_strdup(mysql->options.client_ip, MYF(0));
@@ -682,36 +687,44 @@ int check_embedded_connection(MYSQL *mys
sctx->host_or_ip= sctx->host;
if (acl_check_host(sctx->host, sctx->ip))
- {
- result= ER_HOST_NOT_PRIVILEGED;
goto err;
- }
- sctx->user= my_strdup(mysql->user, MYF(0));
+ /* construct a COM_CHANGE_USER packet */
+ end= strmake(buf, mysql->user, USERNAME_LENGTH) + 1;
+
+ memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
+ thd->scramble[SCRAMBLE_LENGTH]= 0;
+
if (mysql->passwd && mysql->passwd[0])
{
- memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
- thd->scramble[SCRAMBLE_LENGTH]= 0;
- scramble(scramble_buff, thd->scramble, mysql->passwd);
- passwd_len= SCRAMBLE_LENGTH;
+ *end++= SCRAMBLE_LENGTH;
+ scramble(end, thd->scramble, mysql->passwd);
+ end+= SCRAMBLE_LENGTH;
}
else
- passwd_len= 0;
+ *end++= 0;
- if((result= check_user(thd, COM_CONNECT,
- scramble_buff, passwd_len, db, true)))
- goto err;
+ end= strmake(end, db ? db : "", NAME_LEN) + 1;
- return 0;
-err:
+ int2store(end, (ushort) mysql->charset->number);
+ end+= 2;
+
+ /* acl_authenticate() takes the data from thd->net->read_pos */
+ thd->net.read_pos= (uchar*)buf;
+
+ if (acl_authenticate(thd, 0, end - buf))
{
- NET *net= &mysql->net;
- strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1);
- memcpy(net->sqlstate,
- mysql_errno_to_sqlstate(thd->main_da.sql_errno()),
- sizeof(net->sqlstate)-1);
+ x_free(thd->security_ctx->user);
+ goto err;
}
- return result;
+ return 0;
+
+err:
+ strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1);
+ memcpy(net->sqlstate,
+ mysql_errno_to_sqlstate(thd->main_da.sql_errno()),
+ sizeof(net->sqlstate)-1);
+ return 1;
}
#endif
=== modified file 'libmysqld/libmysqld.c'
--- a/libmysqld/libmysqld.c 2009-09-25 11:39:05 +0000
+++ b/libmysqld/libmysqld.c 2010-03-29 15:13:53 +0000
@@ -18,7 +18,6 @@
#include <mysql_embed.h>
#include <mysqld_error.h>
#include <my_pthread.h>
-#include "embedded_priv.h"
#include <my_sys.h>
#include <mysys_err.h>
#include <m_string.h>
@@ -28,6 +27,7 @@
#include <sys/stat.h>
#include <signal.h>
#include <time.h>
+#include "embedded_priv.h"
#include "client_settings.h"
#ifdef HAVE_PWD_H
#include <pwd.h>
@@ -81,9 +81,9 @@ static my_bool is_NT(void)
** Shut down connection
**************************************************************************/
-static void end_server(MYSQL *mysql)
+void embedded_end_server(MYSQL *mysql)
{
- DBUG_ENTER("end_server");
+ DBUG_ENTER("embedded_end_server");
free_old_query(mysql);
DBUG_VOID_RETURN;
}
@@ -169,7 +169,11 @@ mysql_real_connect(MYSQL *mysql,const ch
client_flag|=CLIENT_CAPABILITIES;
if (client_flag & CLIENT_MULTI_STATEMENTS)
client_flag|= CLIENT_MULTI_RESULTS;
- client_flag&= ~CLIENT_COMPRESS;
+ /*
+ no compression in embedded as we don't send any data,
+ and no pluggable auth, as we cannot do a client-server dialog
+ */
+ client_flag&= ~(CLIENT_COMPRESS | CLIENT_PLUGIN_AUTH);
if (db)
client_flag|=CLIENT_CONNECT_WITH_DB;
@@ -216,7 +220,7 @@ error:
{
/* Free alloced memory */
my_bool free_me=mysql->free_me;
- end_server(mysql);
+ embedded_end_server(mysql);
mysql->free_me=0;
mysql_close(mysql);
mysql->free_me=free_me;
=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl 2010-03-17 02:32:31 +0000
+++ b/mysql-test/mysql-test-run.pl 2010-02-19 08:10:05 +0000
@@ -1272,21 +1272,18 @@ sub command_line_setup {
if ($opt_gdb)
{
- mtr_warning("Silently converting --gdb to --client-gdb in embedded mode");
$opt_client_gdb= $opt_gdb;
$opt_gdb= undef;
}
if ($opt_ddd)
{
- mtr_warning("Silently converting --ddd to --client-ddd in embedded mode");
$opt_client_ddd= $opt_ddd;
$opt_ddd= undef;
}
if ($opt_debugger)
{
- mtr_warning("Silently converting --debugger to --client-debugger in embedded mode");
$opt_client_debugger= $opt_debugger;
$opt_debugger= undef;
}
@@ -5341,20 +5338,12 @@ sub gdb_arguments {
if ( $type eq "client" )
{
# write init file for client
- mtr_tofile($gdb_init_file,
- "set args $str\n" .
- "break main\n");
+ mtr_tofile($gdb_init_file, "set args $str\n");
}
else
{
# write init file for mysqld
- mtr_tofile($gdb_init_file,
- "set args $str\n" .
- "break mysql_parse\n" .
- "commands 1\n" .
- "disable 1\n" .
- "end\n" .
- "run");
+ mtr_tofile($gdb_init_file, "set args $str\n");
}
if ( $opt_manual_gdb )
@@ -5405,20 +5394,12 @@ sub ddd_arguments {
if ( $type eq "client" )
{
# write init file for client
- mtr_tofile($gdb_init_file,
- "set args $str\n" .
- "break main\n");
+ mtr_tofile($gdb_init_file, "set args $str\n");
}
else
{
# write init file for mysqld
- mtr_tofile($gdb_init_file,
- "file $$exe\n" .
- "set args $str\n" .
- "break mysql_parse\n" .
- "commands 1\n" .
- "disable 1\n" .
- "end");
+ mtr_tofile($gdb_init_file, "file $$exe\nset args $str\n");
}
if ( $opt_manual_ddd )
=== modified file 'mysql-test/r/change_user.result'
--- a/mysql-test/r/change_user.result 2009-02-12 14:08:56 +0000
+++ b/mysql-test/r/change_user.result 2010-03-29 15:13:53 +0000
@@ -1,3 +1,36 @@
+grant select on test.* to test_nopw;
+grant select on test.* to test_oldpw identified by password "09301740536db389";
+grant select on test.* to test_newpw identified by "newpw";
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<root@localhost> <root@localhost> test
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_nopw@localhost> <test_nopw@%> NULL
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_oldpw@localhost> <test_oldpw@%> NULL
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_newpw@localhost> <test_newpw@%> NULL
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<root@localhost> <root@localhost> NULL
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_nopw@localhost> <test_nopw@%> test
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_oldpw@localhost> <test_oldpw@%> test
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<test_newpw@localhost> <test_newpw@%> test
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+concat('<', user(), '>') concat('<', current_user(), '>') database()
+<root@localhost> <root@localhost> test
+drop user test_nopw;
+drop user test_oldpw;
+drop user test_newpw;
Bug#20023
SELECT @@session.sql_big_selects;
@@session.sql_big_selects
=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result 2010-01-29 10:42:31 +0000
+++ b/mysql-test/r/grant.result 2010-03-29 15:13:53 +0000
@@ -13,8 +13,8 @@ GRANT USAGE ON *.* TO 'mysqltest_1'@'loc
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
grant delete on mysqltest.* to mysqltest_1@localhost;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
@@ -44,15 +44,15 @@ delete from mysql.user where user='mysql
flush privileges;
grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10
grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30
@@ -164,6 +164,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
insert into mysql.db (host, db, user, select_priv) values
('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y');
alter table mysql.db order by db asc;
=== modified file 'mysql-test/r/grant2.result'
--- a/mysql-test/r/grant2.result 2009-10-30 05:06:10 +0000
+++ b/mysql-test/r/grant2.result 2010-03-29 15:13:53 +0000
@@ -287,6 +287,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
create user mysqltest_A@'%';
rename user mysqltest_B@'%' to mysqltest_C@'%';
drop user mysqltest_C@'%';
@@ -354,6 +355,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
INSERT INTO mysql.db (host, db, user, select_priv) VALUES
('%','TESTDB','mysqltest_1','Y');
FLUSH PRIVILEGES;
=== modified file 'mysql-test/r/key_cache.result'
--- a/mysql-test/r/key_cache.result 2010-03-31 18:45:41 +0000
+++ b/mysql-test/r/key_cache.result 2010-03-31 23:03:57 +0000
@@ -388,7 +388,7 @@ i int, a char(10), key k1(i), key k2(a))
select @@key_cache_partitions;
@@key_cache_partitions
0
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default NULL NULL 2097152 1024 0 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
@@ -416,18 +416,18 @@ Key_read_requests 22
Key_reads 0
Key_write_requests 26
Key_writes 6
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default NULL NULL 2097152 1024 4 # 0 22 0 26 6
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
delete from t2 where a='zzzz';
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default NULL NULL 2097152 1024 4 # 0 29 0 32 9
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
delete from t1;
delete from t2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default NULL NULL 2097152 1024 4 # 0 29 0 32 9
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
@@ -435,10 +435,8 @@ set global key_cache_partitions=2;
select @@key_cache_partitions;
@@key_cache_partitions
2
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 1048576 1024 0 # 0 0 0 0 0
-default 2 2 1048576 1024 0 # 0 0 0 0 0
default 2 NULL 2097152 1024 0 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
@@ -465,27 +463,22 @@ Key_read_requests 22
Key_reads 0
Key_write_requests 26
Key_writes 6
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 1048576 1024 # # 0 10 0 13 4
-default 2 2 1048576 1024 # # 0 12 0 13 2
-default 2 NULL 2097152 1024 # # 0 22 0 26 6
-small NULL NULL 1048576 1024 # # 0 1 0 2 1
+default 2 NULL 2097152 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
delete from t1;
delete from t2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 1048576 1024 # # 0 10 0 13 4
-default 2 2 1048576 1024 # # 0 12 0 13 2
-default 2 NULL 2097152 1024 # # 0 22 0 26 6
-small NULL NULL 1048576 1024 # # 0 1 0 2 1
+default 2 NULL 2097152 1024 4 # 0 22 0 26 6
+small NULL NULL 1048576 1024 1 # 0 1 0 2 1
set global key_cache_partitions=1;
select @@key_cache_partitions;
@@key_cache_partitions
1
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 1 1 2097152 1024 0 # 0 0 0 0 0
default 1 NULL 2097152 1024 0 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
@@ -512,23 +505,20 @@ Key_read_requests 22
Key_reads 0
Key_write_requests 26
Key_writes 6
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 1 1 2097152 1024 4 # 0 22 0 26 6
default 1 NULL 2097152 1024 4 # 0 22 0 26 6
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
delete from t1;
delete from t2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 1 1 2097152 1024 4 # 0 22 0 26 6
default 1 NULL 2097152 1024 4 # 0 22 0 26 6
small NULL NULL 1048576 1024 1 # 0 1 0 2 1
flush tables;
flush status;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 1 1 2097152 1024 4 # 0 0 0 0 0
default 1 NULL 2097152 1024 4 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 0 0 0 0
set global key_buffer_size=32*1024;
@@ -539,10 +529,8 @@ set global key_cache_partitions=2;
select @@key_cache_partitions;
@@key_cache_partitions
2
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 0 # 0 0 0 0 0
-default 2 2 16384 1024 0 # 0 0 0 0 0
default 2 NULL 32768 1024 0 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 0 0 0 0
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
@@ -560,10 +548,8 @@ p i a
4 3 zzzz
update t1 set p=3 where p=1;
update t2 set i=2 where i=1;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 1 # 0 12 0 13 2
-default 2 2 16384 1024 3 # 0 10 0 13 4
default 2 NULL 32768 1024 4 # 0 22 0 26 6
small NULL NULL 1048576 1024 1 # 0 0 0 0 0
insert into t1(a) select a from t1;
@@ -582,10 +568,8 @@ insert into t2(i,a) select i,a from t2;
insert into t2(i,a) select i,a from t2;
insert into t2(i,a) select i,a from t2;
insert into t2(i,a) select i,a from t2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 1951 # 1976 43
-default 2 2 16384 1024 # # 0 4782 # 1708 60
default 2 NULL 32768 1024 # # 0 6733 # 3684 103
small NULL NULL 1048576 1024 # # 0 0 # 0 0
select * from t1 where p between 1010 and 1020 ;
@@ -603,20 +587,16 @@ p i a
1018 2 pppp
1019 2 yyyy
1020 3 zzzz
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 1954 # 1976 43
-default 2 2 16384 1024 # # 0 4796 # 1708 60
default 2 NULL 32768 1024 # # 0 6750 # 3684 103
small NULL NULL 1048576 1024 # # 0 0 # 0 0
flush tables;
flush status;
update t1 set a='zzzz' where a='qqqq';
update t2 set i=1 where i=2;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 940 10 939 10
-default 2 2 16384 1024 # # 0 2136 8 613 8
default 2 NULL 32768 1024 # # 0 3076 18 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=256*1024;
@@ -627,29 +607,14 @@ set global keycache1.key_cache_partition
select @@keycache1.key_cache_partitions;
@@keycache1.key_cache_partitions
7
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 940 10 939 10
-default 2 2 16384 1024 # # 0 2136 8 613 8
default 2 NULL 32768 1024 # # 0 3076 18 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 37449 2048 # # 0 0 0 0 0
-keycache1 7 2 37449 2048 # # 0 0 0 0 0
-keycache1 7 3 37449 2048 # # 0 0 0 0 0
-keycache1 7 4 37449 2048 # # 0 0 0 0 0
-keycache1 7 5 37449 2048 # # 0 0 0 0 0
-keycache1 7 6 37449 2048 # # 0 0 0 0 0
-keycache1 7 7 37449 2048 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 0 0 0 0
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache1 7 1 37449 2048 0 # 0 0 0 0 0
-keycache1 7 2 37449 2048 0 # 0 0 0 0 0
-keycache1 7 3 37449 2048 0 # 0 0 0 0 0
-keycache1 7 4 37449 2048 0 # 0 0 0 0 0
-keycache1 7 5 37449 2048 0 # 0 0 0 0 0
-keycache1 7 6 37449 2048 0 # 0 0 0 0 0
-keycache1 7 7 37449 2048 0 # 0 0 0 0 0
keycache1 7 NULL 262143 2048 0 # 0 0 0 0 0
cache index t1 key (`primary`) in keycache1;
Table Op Msg_type Msg_text
@@ -682,61 +647,35 @@ id select_type table type possible_keys
select count(*) from t1, t2 where t1.p = t2.i;
count(*)
256
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 37449 2048 # # 0 2 1 0 0
-keycache1 7 2 37449 2048 # # 0 7 1 0 0
-keycache1 7 3 37449 2048 # # 0 0 0 0 0
-keycache1 7 4 37449 2048 # # 0 5 1 0 0
-keycache1 7 5 37449 2048 # # 0 0 0 0 0
-keycache1 7 6 37449 2048 # # 0 0 0 0 0
-keycache1 7 7 37449 2048 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 14 3 0 0
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache1 7 1 37449 2048 1 # 0 2 1 0 0
-keycache1 7 2 37449 2048 1 # 0 7 1 0 0
-keycache1 7 3 37449 2048 0 # 0 0 0 0 0
-keycache1 7 4 37449 2048 1 # 0 5 1 0 0
-keycache1 7 5 37449 2048 0 # 0 0 0 0 0
-keycache1 7 6 37449 2048 0 # 0 0 0 0 0
-keycache1 7 7 37449 2048 0 # 0 0 0 0 0
keycache1 7 NULL 262143 2048 3 # 0 14 3 0 0
cache index t2 in keycache1;
Table Op Msg_type Msg_text
test.t2 assign_to_keycache status OK
update t2 set p=p+3000, i=2 where a='qqqq';
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache1 7 1 37449 2048 3 # 0 44 3 43 2
-keycache1 7 2 37449 2048 4 # 0 61 4 51 1
-keycache1 7 3 37449 2048 4 # 0 177 4 176 3
-keycache1 7 4 37449 2048 4 # 0 122 4 119 3
-keycache1 7 5 37449 2048 4 # 0 840 4 335 4
-keycache1 7 6 37449 2048 3 # 0 627 3 133 3
-keycache1 7 7 37449 2048 3 # 0 211 3 214 3
keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19
set global keycache2.key_buffer_size=1024*1024;
cache index t2 in keycache2;
Table Op Msg_type Msg_text
test.t2 assign_to_keycache status OK
insert into t2 values (2000, 3, 'yyyy');
-select * from information_schema.key_caches where key_cache_name like "keycache2";
+select * from information_schema.key_caches where key_cache_name like "keycache2"
+ and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
keycache2 NULL NULL 1048576 1024 0 # 0 0 0 0 0
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+and partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-keycache1 7 1 37449 2048 3 # 0 44 3 43 2
-keycache1 7 2 37449 2048 4 # 0 61 4 51 1
-keycache1 7 3 37449 2048 4 # 0 177 4 176 3
-keycache1 7 4 37449 2048 4 # 0 122 4 119 3
-keycache1 7 5 37449 2048 4 # 0 840 4 335 4
-keycache1 7 6 37449 2048 3 # 0 627 3 133 3
-keycache1 7 7 37449 2048 3 # 0 211 3 214 3
keycache1 7 NULL 262143 2048 25 # 0 2082 25 1071 19
keycache2 NULL NULL 1048576 1024 0 # 0 0 0 0 0
cache index t2 in keycache1;
@@ -774,127 +713,77 @@ id select_type table type possible_keys
select a from t2 where a='yyyy' and i=3 ;
a
yyyy
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 37449 2048 # # 0 85 6 68 3
-keycache1 7 2 37449 2048 # # 0 122 6 102 2
-keycache1 7 3 37449 2048 # # 0 271 8 254 6
-keycache1 7 4 37449 2048 # # 0 179 6 170 4
-keycache1 7 5 37449 2048 # # 0 1445 7 416 6
-keycache1 7 6 37449 2048 # # 0 863 6 345 5
-keycache1 7 7 37449 2048 # # 0 236 4 239 4
keycache1 7 NULL 262143 2048 # # 0 3201 43 1594 30
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=2*1024;
insert into t2 values (7000, 3, 'yyyy');
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 37449 2048 # # 0 1 1 1 1
-keycache1 7 2 37449 2048 # # 0 1 1 0 0
-keycache1 7 3 37449 2048 # # 0 0 0 0 0
-keycache1 7 4 37449 2048 # # 0 1 1 1 1
-keycache1 7 5 37449 2048 # # 0 1 1 0 0
-keycache1 7 6 37449 2048 # # 0 2 2 1 1
-keycache1 7 7 37449 2048 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 6 6 3 3
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=8*1024;
insert into t2 values (8000, 3, 'yyyy');
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 3 1 87381 8192 # # 0 1 1 1 1
-keycache1 3 2 87381 8192 # # 0 3 2 1 1
-keycache1 3 3 87381 8192 # # 0 2 2 1 1
keycache1 3 NULL 262143 8192 # # 0 6 5 3 3
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=64*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=2*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 3 1 21845 2048 # # 0 0 0 0 0
-keycache1 3 2 21845 2048 # # 0 0 0 0 0
-keycache1 3 3 21845 2048 # # 0 0 0 0 0
keycache1 3 NULL 65535 2048 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=8*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=0;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=8*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=0;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_buffer_size=128*1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 1 1 131072 8192 # # 0 0 0 0 0
keycache1 1 NULL 131072 8192 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
set global keycache1.key_cache_block_size=1024;
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 16384 1024 # # 0 966 12 939 10
-default 2 2 16384 1024 # # 0 2206 12 613 8
default 2 NULL 32768 1024 # # 0 3172 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
-keycache1 7 1 18724 1024 # # 0 0 0 0 0
-keycache1 7 2 18724 1024 # # 0 0 0 0 0
-keycache1 7 3 18724 1024 # # 0 0 0 0 0
-keycache1 7 4 18724 1024 # # 0 0 0 0 0
-keycache1 7 5 18724 1024 # # 0 0 0 0 0
-keycache1 7 6 18724 1024 # # 0 0 0 0 0
-keycache1 7 7 18724 1024 # # 0 0 0 0 0
keycache1 7 NULL 131068 1024 # # 0 0 0 0 0
keycache2 NULL NULL 1048576 1024 # # 0 0 0 0 0
drop table t1,t2;
=== modified file 'mysql-test/r/ps.result'
--- a/mysql-test/r/ps.result 2009-12-26 11:25:56 +0000
+++ b/mysql-test/r/ps.result 2010-03-29 15:13:53 +0000
@@ -1194,13 +1194,13 @@ SET @aux= "SELECT COUNT(*)
prepare my_stmt from @aux;
execute my_stmt;
COUNT(*)
-39
+41
execute my_stmt;
COUNT(*)
-39
+41
execute my_stmt;
COUNT(*)
-39
+41
deallocate prepare my_stmt;
drop procedure if exists p1|
drop table if exists t1|
=== modified file 'mysql-test/r/sp_notembedded.result'
--- a/mysql-test/r/sp_notembedded.result 2010-01-11 13:15:28 +0000
+++ b/mysql-test/r/sp_notembedded.result 2010-03-29 15:13:53 +0000
@@ -191,6 +191,8 @@ max_updates, max_connections, max_user_c
VALUES('%', 'mysqltest_1', password(''), 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'N',
'N', 'N', 'N', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', 'Y', 'Y', 'N', '',
'', '', '', '0', '0', '0', '0');
+Warnings:
+Warning 1364 Field 'auth_string' doesn't have a default value
FLUSH PRIVILEGES;
CREATE PROCEDURE p1(i INT) BEGIN END;
DROP PROCEDURE p1;
=== modified file 'mysql-test/r/system_mysql_db.result'
--- a/mysql-test/r/system_mysql_db.result 2009-10-27 10:09:36 +0000
+++ b/mysql-test/r/system_mysql_db.result 2010-03-29 15:13:53 +0000
@@ -118,6 +118,8 @@ user CREATE TABLE `user` (
`max_updates` int(11) unsigned NOT NULL DEFAULT '0',
`max_connections` int(11) unsigned NOT NULL DEFAULT '0',
`max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
+ `plugin` char(60) CHARACTER SET latin1 NOT NULL DEFAULT '',
+ `auth_string` text COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'
show create table func;
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2009-10-28 09:23:02 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result 2010-03-29 15:13:53 +0000
@@ -178,6 +178,7 @@ NULL mysql time_zone_transition_type Tim
NULL mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references
NULL mysql user Alter_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user Alter_routine_priv 28 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user auth_string 41 NULL NO text 65535 65535 NULL NULL utf8 utf8_bin text select,insert,update,references
NULL mysql user Create_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user Create_routine_priv 27 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user Create_tmp_table_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
@@ -198,6 +199,7 @@ NULL mysql user max_questions 36 0 NO in
NULL mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references
NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references
NULL mysql user Password 3 NO char 41 41 NULL NULL latin1 latin1_bin char(41) select,insert,update,references
+NULL mysql user plugin 40 NO char 60 60 NULL NULL latin1 latin1_swedish_ci char(60) select,insert,update,references
NULL mysql user Process_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user References_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql user Reload_priv 10 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
@@ -233,6 +235,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COL
1.0000 char latin1 latin1_bin
1.0000 char latin1 latin1_swedish_ci
1.0000 varchar latin1 latin1_swedish_ci
+1.0000 text utf8 utf8_bin
1.0000 mediumtext utf8 utf8_general_ci
1.0000 text utf8 utf8_general_ci
SELECT DISTINCT
@@ -497,3 +500,5 @@ NULL mysql user max_questions int NULL N
NULL mysql user max_updates int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_connections int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_user_connections int NULL NULL NULL NULL int(11) unsigned
+1.0000 mysql user plugin char 60 60 latin1 latin1_swedish_ci char(60)
+1.0000 mysql user auth_string text 65535 65535 utf8 utf8_bin text
=== modified file 'mysql-test/suite/funcs_1/r/is_user_privileges.result'
--- a/mysql-test/suite/funcs_1/r/is_user_privileges.result 2008-03-07 19:18:14 +0000
+++ b/mysql-test/suite/funcs_1/r/is_user_privileges.result 2010-03-29 15:13:53 +0000
@@ -76,10 +76,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
#
# Add GRANT OPTION db_datadict.* to testuser1;
GRANT UPDATE ON db_datadict.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
@@ -93,10 +93,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Establish connection testuser1 (user=testuser1)
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
@@ -105,10 +105,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser1'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
SHOW GRANTS;
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
@@ -130,10 +130,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
#
# Here <SELECT YES> is shown correctly for testuser1;
@@ -147,10 +147,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Switch to connection testuser1
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
@@ -159,10 +159,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser1'@'localhost' NULL SELECT YES
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 Y N N N N N N N N N Y N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
SHOW GRANTS;
Grants for testuser1@localhost
GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION
@@ -207,10 +207,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Switch to connection testuser1
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
@@ -253,10 +253,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Switch to connection testuser1
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
@@ -265,10 +265,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser1'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
SHOW GRANTS;
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
@@ -284,10 +284,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser1'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
SHOW GRANTS;
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
@@ -309,10 +309,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_
'testuser3'@'localhost' NULL USAGE NO
SELECT * FROM mysql.user
WHERE user LIKE 'testuser%' ORDER BY host, user;
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
-localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
+localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0
# Switch to connection testuser1
SELECT * FROM information_schema.user_privileges
WHERE grantee LIKE '''testuser%'''
=== modified file 'mysql-test/suite/pbxt/r/grant.result'
--- a/mysql-test/suite/pbxt/r/grant.result 2009-11-24 10:19:08 +0000
+++ b/mysql-test/suite/pbxt/r/grant.result 2010-03-29 15:13:53 +0000
@@ -11,8 +11,8 @@ GRANT USAGE ON *.* TO 'mysqltest_1'@'loc
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
grant delete on mysqltest.* to mysqltest_1@localhost;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
@@ -42,15 +42,15 @@ delete from mysql.user where user='mysql
flush privileges;
grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10
grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30;
select * from mysql.user where user="mysqltest_1";
-Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections
-localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin auth_string
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30
@@ -162,6 +162,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
insert into mysql.db (host, db, user, select_priv) values
('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y');
alter table mysql.db order by db asc;
=== modified file 'mysql-test/suite/rpl/r/rpl_ignore_table.result'
--- a/mysql-test/suite/rpl/r/rpl_ignore_table.result 2008-11-13 19:19:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_ignore_table.result 2010-03-29 15:13:53 +0000
@@ -34,6 +34,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
GRANT SELECT ON *.* TO mysqltest6@localhost;
GRANT INSERT ON *.* TO mysqltest6@localhost;
GRANT INSERT ON test.* TO mysqltest6@localhost;
=== modified file 'mysql-test/suite/rpl/r/rpl_stm_000001.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_000001.result 2009-11-18 14:50:31 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_000001.result 2010-03-29 15:13:53 +0000
@@ -66,6 +66,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
+Warning 1364 Field 'auth_string' doesn't have a default value
select select_priv,user from mysql.user where user = _binary'blafasel2';
select_priv user
N blafasel2
=== modified file 'mysql-test/t/change_user.test'
--- a/mysql-test/t/change_user.test 2009-10-28 07:52:34 +0000
+++ b/mysql-test/t/change_user.test 2010-03-29 15:13:53 +0000
@@ -1,4 +1,50 @@
#
+# functional change user tests
+#
+
+grant select on test.* to test_nopw;
+grant select on test.* to test_oldpw identified by password "09301740536db389";
+grant select on test.* to test_newpw identified by "newpw";
+
+#
+# massaging the data for tests to pass in the embedded server,
+# that has authentication completely disabled.
+#
+
+--replace_result <@> <test_nopw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+
+change_user test_nopw;
+--replace_result <@> <test_nopw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user test_oldpw, oldpw;
+--replace_result <@> <test_oldpw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user test_newpw, newpw;
+--replace_result <@> <test_newpw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user root;
+--replace_result <@> <root@localhost> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+
+change_user test_nopw,,test;
+--replace_result <@> <test_nopw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user test_oldpw,oldpw,test;
+--replace_result <@> <test_oldpw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user test_newpw,newpw,test;
+--replace_result <@> <test_newpw@%> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+change_user root,,test;
+--replace_result <@> <root@localhost> @> @localhost>
+select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
+
+drop user test_nopw;
+drop user test_oldpw;
+drop user test_newpw;
+
+#
# Bug#20023 mysql_change_user() resets the value of SQL_BIG_SELECTS
# The replace's are here to fix things for 32 bit systems
#
=== modified file 'mysql-test/t/key_cache.test'
--- a/mysql-test/t/key_cache.test 2010-03-31 18:45:41 +0000
+++ b/mysql-test/t/key_cache.test 2010-03-31 23:03:57 +0000
@@ -272,7 +272,7 @@ create table t2 (
select @@key_cache_partitions;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
@@ -285,16 +285,16 @@ update t2 set i=2 where i=1;
--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
show status like 'key_%';
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
delete from t2 where a='zzzz';
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
delete from t1;
delete from t2;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
# For the key cache with 2 partitions execute the same sequence of
# statements as for the simple cache above.
@@ -304,7 +304,7 @@ select * from information_schema.key_cac
set global key_cache_partitions=2;
select @@key_cache_partitions;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
@@ -316,20 +316,20 @@ update t2 set i=2 where i=1;
--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
show status like 'key_%';
---replace_column 6 # 7 #
-select * from information_schema.key_caches;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
delete from t1;
delete from t2;
---replace_column 6 # 7 #
-select * from information_schema.key_caches;
+--replace_column 7 #
+select * from information_schema.key_caches where partition_number is null;
# Check that we can work with one partition with the same results
set global key_cache_partitions=1;
select @@key_cache_partitions;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
@@ -342,16 +342,16 @@ update t2 set i=2 where i=1;
--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
show status like 'key_%';
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
delete from t1;
delete from t2;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
flush tables; flush status;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
# Switch back to 2 partitions
@@ -360,7 +360,7 @@ select @@key_buffer_size;
set global key_cache_partitions=2;
select @@key_cache_partitions;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
insert into t1 values (1, 'qqqq'), (2, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
@@ -371,7 +371,7 @@ update t1 set p=3 where p=1;
update t2 set i=2 where i=1;
--replace_column 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
# Add more rows to tables t1 and t2
@@ -394,18 +394,18 @@ insert into t2(i,a) select i,a from t2;
insert into t2(i,a) select i,a from t2;
--replace_column 6 # 7 # 10 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
select * from t1 where p between 1010 and 1020 ;
select * from t2 where p between 1010 and 1020 ;
--replace_column 6 # 7 # 10 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
flush tables; flush status;
update t1 set a='zzzz' where a='qqqq';
update t2 set i=1 where i=2;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
# Now test how we can work with 7 partitions
@@ -415,9 +415,10 @@ set global keycache1.key_cache_partition
select @@keycache1.key_cache_partitions;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
cache index t1 key (`primary`) in keycache1;
@@ -429,22 +430,26 @@ explain select count(*) from t1, t2 wher
select count(*) from t1, t2 where t1.p = t2.i;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
cache index t2 in keycache1;
update t2 set p=p+3000, i=2 where a='qqqq';
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
set global keycache2.key_buffer_size=1024*1024;
cache index t2 in keycache2;
insert into t2 values (2000, 3, 'yyyy');
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "keycache2";
+select * from information_schema.key_caches where key_cache_name like "keycache2"
+ and partition_number is null;
--replace_column 7 #
-select * from information_schema.key_caches where key_cache_name like "key%";
+select * from information_schema.key_caches where key_cache_name like "key%"
+ and partition_number is null;
cache index t2 in keycache1;
update t2 set p=p+5000 where a='zzzz';
@@ -456,49 +461,49 @@ select i from t2 where a='yyyy' and i=3;
explain select a from t2 where a='yyyy' and i=3;
select a from t2 where a='yyyy' and i=3 ;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=2*1024;
insert into t2 values (7000, 3, 'yyyy');
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=8*1024;
insert into t2 values (8000, 3, 'yyyy');
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_buffer_size=64*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=2*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=8*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_buffer_size=0;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=8*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_buffer_size=0;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_buffer_size=128*1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
set global keycache1.key_cache_block_size=1024;
--replace_column 6 # 7 #
-select * from information_schema.key_caches;
+select * from information_schema.key_caches where partition_number is null;
drop table t1,t2;
=== modified file 'mysql-test/valgrind.supp'
--- a/mysql-test/valgrind.supp 2010-03-10 09:11:02 +0000
+++ b/mysql-test/valgrind.supp 2010-02-19 08:12:25 +0000
@@ -1000,6 +1000,27 @@
fun:nptl_pthread_exit_hack_handler
}
+{
+ Invalid read within nptl_pthread_exit_hack_handler
+ Memcheck:Addr8
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+}
+
#
# Pthread doesn't free all thread specific memory before program exists
#
=== modified file 'mysys/Makefile.am'
--- a/mysys/Makefile.am 2009-12-03 11:19:05 +0000
+++ b/mysys/Makefile.am 2010-03-29 15:13:53 +0000
@@ -74,13 +74,13 @@ libmysys_a_LIBADD = @THREAD_LOBJECTS@
# testhash_DEPENDENCIES= $(LIBRARIES)
# test_charset_DEPENDENCIES= $(LIBRARIES)
# charset2html_DEPENDENCIES= $(LIBRARIES)
-DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \
- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
- -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
+DEFS = -DDEFAULT_BASEDIR='"$(prefix)"' \
+ -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \
+ -DDEFAULT_CHARSET_HOME='"$(MYSQLBASEdir)"' \
+ -DSHAREDIR'="$(MYSQLSHAREdir)"' \
-DDEFAULT_HOME_ENV=MYSQL_HOME \
-DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \
- -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \
+ -DDEFAULT_SYSCONFDIR='"$(sysconfdir)"' \
@DEFS@
libmysys_a_DEPENDENCIES= @THREAD_LOBJECTS@
=== added directory 'plugin/auth'
=== added file 'plugin/auth/Makefile.am'
--- a/plugin/auth/Makefile.am 1970-01-01 00:00:00 +0000
+++ b/plugin/auth/Makefile.am 2010-03-29 15:13:53 +0000
@@ -0,0 +1,15 @@
+pkgplugindir=$(pkglibdir)/plugin
+
+AM_LDFLAGS=-module -rpath $(pkgplugindir)
+AM_CPPFLAGS=-DMYSQL_DYNAMIC_PLUGIN -I$(top_srcdir)/include
+
+pkgplugin_LTLIBRARIES= dialog.la
+dialog_la_SOURCES= dialog.c
+
+if HAVE_PEERCRED
+pkgplugin_LTLIBRARIES+= auth_socket.la
+auth_socket_la_SOURCES= auth_socket.c
+endif
+
+EXTRA_DIST= plug.in
+
=== added file 'plugin/auth/auth_socket.c'
--- a/plugin/auth/auth_socket.c 1970-01-01 00:00:00 +0000
+++ b/plugin/auth/auth_socket.c 2010-03-29 15:13:53 +0000
@@ -0,0 +1,102 @@
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ socket_peercred authentication plugin.
+
+ Authentication is successful if the connection is done via a unix socket and
+ the owner of the client process matches the user name that was used when
+ connecting to mysqld.
+*/
+#define _GNU_SOURCE /* for struct ucred */
+
+#include <mysql/plugin_auth.h>
+#include <sys/socket.h>
+#include <pwd.h>
+#include <string.h>
+
+/**
+ perform the unix socket based authentication
+
+ This authentication callback performs a unix socket based authentication -
+ it gets the uid of the client process and considers the user authenticated
+ if it uses username of this uid. That is - if the user is already
+ authenticated to the OS (if she is logged in) - she can use MySQL as herself
+*/
+
+static int socket_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
+{
+ unsigned char *pkt;
+ MYSQL_PLUGIN_VIO_INFO vio_info;
+ struct ucred cred;
+ socklen_t cred_len= sizeof(cred);
+ struct passwd pwd_buf, *pwd;
+ char buf[1024];
+
+ /* no user name yet ? read the client handshake packet with the user name */
+ if (info->user_name == 0)
+ {
+ if (vio->read_packet(vio, &pkt) < 0)
+ return CR_ERROR;
+ }
+
+ info->password_used = 0;
+
+ vio->info(vio, &vio_info);
+ if (vio_info.protocol != MYSQL_VIO_SOCKET)
+ return CR_ERROR;
+
+ /* get the UID of the client process */
+ if (getsockopt(vio_info.socket, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len))
+ return CR_ERROR;
+
+ if (cred_len != sizeof(cred))
+ return CR_ERROR;
+
+ /* and find the username for this uid */
+ getpwuid_r(cred.uid, &pwd_buf, buf, sizeof(buf), &pwd);
+ if (pwd == NULL)
+ return CR_ERROR;
+
+ /* now it's simple as that */
+ return strcmp(pwd->pw_name, info->user_name) ? CR_ERROR : CR_OK;
+}
+
+static struct st_mysql_auth socket_auth_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ 0,
+ socket_auth
+};
+
+mysql_declare_plugin(socket_auth)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &socket_auth_handler,
+ "socket_peercred",
+ "Sergei Golubchik",
+ "Unix Socket based authentication",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ NULL
+}
+mysql_declare_plugin_end;
+
=== added file 'plugin/auth/dialog.c'
--- a/plugin/auth/dialog.c 1970-01-01 00:00:00 +0000
+++ b/plugin/auth/dialog.c 2010-03-31 18:37:45 +0000
@@ -0,0 +1,308 @@
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ dialog client authentication plugin with examples
+
+ dialog is a general purpose client authentication plugin, it simply
+ asks the user the question, as provided by the server and reports
+ the answer back to the server. No encryption is involved,
+ the answers are sent in clear text.
+
+ Two examples are provided: two_questions server plugin, that asks
+ the password and an "Are you sure?" question with a reply "yes, of course".
+ It demonstrates the usage of "password" (input is hidden) and "ordinary"
+ (input can be echoed) questions, and how to mark the last question,
+ to avoid an extra roundtrip.
+
+ And three_attempts plugin that gives the user three attempts to enter
+ a correct password. It shows the situation when a number of questions
+ is not known in advance.
+*/
+#define _GNU_SOURCE /* for RTLD_DEFAULT */
+
+#include <mysql/plugin_auth.h>
+#include <mysql/client_plugin.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/**
+ first byte of the question string is the question "type".
+ It can be a "ordinary" or a "password" question.
+ The last bit set marks a last question in the authentication exchange.
+*/
+#define ORDINARY_QUESTION "\2"
+#define LAST_QUESTION "\3"
+#define PASSWORD_QUESTION "\4"
+#define LAST_PASSWORD "\5"
+
+typedef unsigned char uchar;
+
+/********************* SERVER SIDE ****************************************/
+
+/**
+ dialog demo with two questions, one password and one ordinary.
+*/
+
+static int two_questions(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
+{
+ unsigned char *pkt;
+ int pkt_len;
+
+ /* send a password question */
+ if (vio->write_packet(vio,
+ (const uchar*) (PASSWORD_QUESTION "Password, please:"),
+ 18))
+ return CR_ERROR;
+
+ /* read the answer */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ info->password_used = 1;
+
+ /* fail if the password is wrong */
+ if (strcmp((char*) pkt, info->auth_string))
+ return CR_ERROR;
+
+ /* send the last, ordinary, question */
+ if (vio->write_packet(vio,
+ (const uchar*) (LAST_QUESTION "Are you sure ?"), 15))
+ return CR_ERROR;
+
+ /* read the answer */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ /* check the reply */
+ return strcmp((char*) pkt, "yes, of course") ? CR_ERROR : CR_OK;
+}
+
+static struct st_mysql_auth two_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ "dialog", /* requires dialog client plugin */
+ two_questions
+};
+
+
+/**
+ dialog demo where the number of questions is not known in advance
+*/
+
+static int three_attempts(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
+{
+ unsigned char *pkt;
+ int pkt_len, i;
+
+ for (i= 0; i < 3; i++)
+ {
+ /* send the prompt */
+ if (vio->write_packet(vio,
+ (const uchar*) (PASSWORD_QUESTION "Password, please:"), 18))
+ return CR_ERROR;
+
+ /* read the password */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ info->password_used = 1;
+
+ /*
+ finish, if the password is correct.
+ note, that we did not mark the prompt packet as "last"
+ */
+ if (strcmp((char*) pkt, info->auth_string) == 0)
+ return CR_OK;
+ }
+
+ return CR_ERROR;
+}
+
+static struct st_mysql_auth three_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ "dialog", /* requires dialog client plugin */
+ three_attempts
+};
+
+mysql_declare_plugin(dialog)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &two_handler,
+ "two_questions",
+ "Sergei Golubchik",
+ "Dialog plugin demo 1",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ NULL
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &three_handler,
+ "three_attempts",
+ "Sergei Golubchik",
+ "Dialog plugin demo 2",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ NULL
+}
+mysql_declare_plugin_end;
+
+/********************* CLIENT SIDE ***************************************/
+/*
+ This plugin performs a dialog with the user, asking questions and
+ reading answers. Depending on the client it may be desirable to do it
+ using GUI, or console, with or without curses, or read answers
+ from a smardcard, for example.
+
+ To support all this variety, the dialog plugin has a callback function
+ "authentication_dialog_ask". If the client has a function of this name
+ dialog plugin will use it for communication with the user. Otherwise
+ a default gets() based implementation will be used.
+*/
+#include <mysql.h>
+#include <dlfcn.h>
+
+static mysql_authentication_dialog_ask_t ask;
+
+static char *builtin_ask(MYSQL *mysql __attribute__((unused)),
+ int type __attribute__((unused)),
+ const char *prompt,
+ char *buf, int buf_len __attribute__((unused)))
+{
+ fputs(prompt, stdout);
+ fputc(' ', stdout);
+ if (gets(buf) == 0)
+ return 0;
+
+ return buf;
+}
+
+
+/**
+ The main function of the dialog plugin.
+
+ Read the prompt, ask the question, send the reply, repeat until
+ the server is satisfied.
+
+ @note
+ 1. this plugin shows how a client authentication plugin
+ may read a MySQL protocol OK packet internally - which is important
+ where a number of packets is not known in advance.
+ 2. the first byte of the prompt is special. it is not
+ shown to the user, but signals whether it is the last question
+ (prompt[0] & 1 == 1) or not last (prompt[0] & 1 == 0),
+ and whether the input is a password (not echoed).
+ 3. the prompt is expected to be sent zero-terminated
+*/
+
+static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ unsigned char *pkt, cmd= 0;
+ int pkt_len, res;
+ char reply_buf[1024], *reply;
+
+ do
+ {
+ /* read the prompt */
+ pkt_len= vio->read_packet(vio, &pkt);
+ if (pkt_len < 0)
+ return CR_ERROR;
+
+ if (pkt == 0)
+ {
+ /*
+ in mysql_change_user() the client sends the first packet, so
+ the first vio->read_packet() does nothing (pkt == 0).
+
+ We send the "password", assuming the client knows what its doing.
+ (in other words, the dialog plugin should be only set as a default
+ authentication plugin on the client if the first question
+ asks for a password - which will be sent in clear text, by the way)
+ */
+ reply= mysql->passwd;
+ }
+ else
+ {
+ cmd= *pkt++;
+
+ /* is it MySQL protocol packet ? */
+ if (cmd == 0 || cmd == 254)
+ return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */
+
+ /*
+ asking for a password with an empty prompt means mysql->password
+ otherwise we ask the user and read the reply
+ */
+ if ((cmd >> 1) == 2 && *pkt == 0)
+ reply= mysql->passwd;
+ else
+ reply= ask(mysql, cmd >> 1, (char*) pkt, reply_buf, sizeof(reply_buf));
+ if (!reply)
+ return CR_ERROR;
+ }
+ /* send the reply to the server */
+ res= vio->write_packet(vio, (uchar*) reply, strlen(reply)+1);
+
+ if (reply != mysql->passwd && reply != reply_buf)
+ free(reply);
+
+ if (res)
+ return CR_ERROR;
+
+ /* repeat unless it was the last question */
+ } while ((cmd & 1) != 1);
+
+ /* the job of reading the ok/error packet is left to the server */
+ return CR_OK;
+}
+
+
+/**
+ initialization function of the dialog plugin
+
+ Pick up the client's authentication_dialog_ask() function, if exists,
+ or fall back to the default implementation.
+*/
+
+static int init_dialog()
+{
+ void *sym= dlsym(RTLD_DEFAULT, "mysql_authentication_dialog_ask");
+ ask= sym ? (mysql_authentication_dialog_ask_t)sym : builtin_ask;
+ return 0;
+}
+
+mysql_declare_client_plugin(AUTHENTICATION)
+ "dialog",
+ "Sergei Golubchik",
+ "Dialog Client Authentication Plugin",
+ {0,1,0},
+ init_dialog,
+ NULL,
+ perform_dialog
+mysql_end_client_plugin;
+
=== added file 'plugin/auth/plug.in'
--- a/plugin/auth/plug.in 1970-01-01 00:00:00 +0000
+++ b/plugin/auth/plug.in 2010-03-29 15:13:53 +0000
@@ -0,0 +1,15 @@
+MYSQL_PLUGIN(auth, [Collection of Authentication Plugins],
+ [Collection of Authentication Plugins])
+MYSQL_PLUGIN_DYNAMIC(auth, [dialog.la])
+MYSQL_PLUGIN_ACTIONS(auth,[
+AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([[
+#define _GNU_SOURCE
+#include <sys/socket.h>
+]],[[
+ struct ucred cred;
+ getsockopt(0, SOL_SOCKET, SO_PEERCRED, &cred, 0);
+]])],have_peercred=yes)
+AM_CONDITIONAL(HAVE_PEERCRED, test x$have_peercred = xyes)
+])
+AM_CONDITIONAL(HAVE_PEERCRED, false)
=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql 2009-10-27 10:09:36 +0000
+++ b/scripts/mysql_system_tables.sql 2010-03-29 15:13:53 +0000
@@ -13,7 +13,7 @@ set @had_db_table= @@warning_count != 0;
CREATE TABLE IF NOT EXISTS host ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT
NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges';
-CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_rout
ine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
+CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_rout
ine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) unsigned DEFAULT 0 NOT NULL, plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, auth_string TEXT NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
-- Remember for later if user table already existed
set @had_user_table= @@warning_count != 0;
=== modified file 'scripts/mysql_system_tables_data.sql'
--- a/scripts/mysql_system_tables_data.sql 2008-10-03 15:54:22 +0000
+++ b/scripts/mysql_system_tables_data.sql 2010-03-29 15:13:53 +0000
@@ -21,9 +21,9 @@ DROP TABLE tmp_db;
-- from local machine if "users" table didn't exist before
CREATE TEMPORARY TABLE tmp_user LIKE user;
set @current_hostname= @@hostname;
-INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
-REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0 FROM dual WHERE LOWER( @current_hostname) != 'localhost';
-REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
+INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','');
+REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','' FROM dual WHERE LOWER( @current_hostname) != 'localhost';
+REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','');
INSERT INTO tmp_user (host,user) VALUES ('localhost','');
INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE LOWER(@current_hostname ) != 'localhost';
INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0;
=== modified file 'scripts/mysql_system_tables_fix.sql'
--- a/scripts/mysql_system_tables_fix.sql 2009-12-03 16:15:47 +0000
+++ b/scripts/mysql_system_tables_fix.sql 2010-03-29 15:13:53 +0000
@@ -571,6 +571,9 @@ ALTER TABLE tables_priv MODIFY Table_pri
UPDATE user SET Trigger_priv=Super_priv WHERE @hadTriggerPriv = 0;
+ALTER TABLE user ADD plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, ADD auth_string TEXT NOT NULL;
+ALTER TABLE user MODIFY plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL;
+
# Activate the new, possible modified privilege tables
# This should not be needed, but gives us some extra testing that the above
# changes was correct
=== modified file 'server-tools/instance-manager/Makefile.am'
--- a/server-tools/instance-manager/Makefile.am 2007-02-18 12:45:28 +0000
+++ b/server-tools/instance-manager/Makefile.am 2010-03-29 15:13:53 +0000
@@ -46,7 +46,8 @@ libnet_a_LIBADD= $(top_builddir)/sql/pas
$(top_builddir)/sql/pack.$(OBJEXT) \
$(top_builddir)/sql/sql_state.$(OBJEXT) \
$(top_builddir)/sql/mini_client_errors.$(OBJEXT)\
- $(top_builddir)/sql/client.$(OBJEXT)
+ $(top_builddir)/sql/client.$(OBJEXT) \
+ $(top_builddir)/sql/client_plugin.$(OBJEXT)
CLEANFILES= net_serv.cc client_settings.h
@@ -91,7 +92,7 @@ mysqlmanager_LDADD= @CLIENT_EXTRA_LDFLAG
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/strings/libmystrings.a \
$(top_builddir)/dbug/libdbug.a \
- @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@
+ @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@ @LIBDL@
EXTRA_DIST = WindowsService.cpp WindowsService.h IMService.cpp \
IMService.h CMakeLists.txt
=== modified file 'server-tools/instance-manager/user_map.cc'
--- a/server-tools/instance-manager/user_map.cc 2009-12-18 19:14:09 +0000
+++ b/server-tools/instance-manager/user_map.cc 2010-03-29 15:13:53 +0000
@@ -368,7 +368,7 @@ int User_map::authenticate(const LEX_STR
const char *scramble) const
{
const User *user= find_user(user_name);
- return user ? check_scramble(scrambled_password, scramble, user->salt) : 2;
+ return user ? check_scramble((uchar*)scrambled_password, scramble, user->salt) : 2;
}
=== modified file 'sql-common/Makefile.am'
--- a/sql-common/Makefile.am 2006-12-31 00:02:27 +0000
+++ b/sql-common/Makefile.am 2010-03-29 15:13:53 +0000
@@ -14,7 +14,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to create Makefile.in
-EXTRA_DIST = client.c pack.c my_time.c my_user.c
+EXTRA_DIST = client.c pack.c my_time.c my_user.c client_plugin.c
# Don't update the files from bitkeeper
%::SCCS/s.%
=== modified file 'sql-common/client.c'
--- a/sql-common/client.c 2010-02-01 06:14:12 +0000
+++ b/sql-common/client.c 2010-03-29 15:13:53 +0000
@@ -107,6 +107,10 @@ my_bool net_flush(NET *net);
#include "client_settings.h"
#include <sql_common.h>
+#include <mysql/client_plugin.h>
+
+#define native_password_plugin_name "mysql_native_password"
+#define old_password_plugin_name "mysql_old_password"
uint mysql_port=0;
char *mysql_unix_port= 0;
@@ -332,7 +336,7 @@ void net_clear_error(NET *net)
@param ... variable number of arguments
*/
-static void set_mysql_extended_error(MYSQL *mysql, int errcode,
+void set_mysql_extended_error(MYSQL *mysql, int errcode,
const char *sqlstate,
const char *format, ...)
{
@@ -1002,9 +1006,20 @@ static const char *default_options[]=
"replication-probe", "enable-reads-from-master", "repl-parse-query",
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
"multi-results", "multi-statements", "multi-queries", "secure-auth",
- "report-data-truncation",
+ "report-data-truncation", "plugin-dir", "default-auth",
NullS
};
+enum option_id {
+ OPT_port=1, OPT_socket, OPT_compress, OPT_password, OPT_pipe, OPT_timeout, OPT_user,
+ OPT_init_command, OPT_host, OPT_database, OPT_debug, OPT_return_found_rows,
+ OPT_ssl_key, OPT_ssl_cert, OPT_ssl_ca, OPT_ssl_capath,
+ OPT_character_sets_dir, OPT_default_character_set, OPT_interactive_timeout,
+ OPT_connect_timeout, OPT_local_infile, OPT_disable_local_infile,
+ OPT_replication_probe, OPT_enable_reads_from_master, OPT_repl_parse_query,
+ OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name,
+ OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth,
+ OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth,
+};
static TYPELIB option_types={array_elements(default_options)-1,
"options",default_options, NULL};
@@ -1035,6 +1050,15 @@ static int add_init_command(struct st_my
return 0;
}
+#define extension_set_string(OPTS, X, STR) \
+ if ((OPTS)->extension) \
+ my_free((OPTS)->extension->X, MYF(MY_ALLOW_ZERO_PTR)); \
+ else \
+ (OPTS)->extension= (struct st_mysql_options_extention *) \
+ my_malloc(sizeof(struct st_mysql_options_extention), \
+ MYF(MY_WME | MY_ZEROFILL)); \
+ (OPTS)->extension->X= my_strdup((STR), MYF(MY_WME));
+
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group)
{
@@ -1067,134 +1091,134 @@ void mysql_read_default_options(struct s
for (end= *option ; *(end= strcend(end,'_')) ; )
*end= '-';
switch (find_type(*option+2,&option_types,2)) {
- case 1: /* port */
+ case OPT_port:
if (opt_arg)
options->port=atoi(opt_arg);
break;
- case 2: /* socket */
+ case OPT_socket:
if (opt_arg)
{
my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 3: /* compress */
+ case OPT_compress:
options->compress=1;
options->client_flag|= CLIENT_COMPRESS;
break;
- case 4: /* password */
+ case OPT_password:
if (opt_arg)
{
my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
options->password=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 5:
+ case OPT_pipe:
options->protocol = MYSQL_PROTOCOL_PIPE;
- case 20: /* connect_timeout */
- case 6: /* timeout */
+ case OPT_connect_timeout:
+ case OPT_timeout:
if (opt_arg)
options->connect_timeout=atoi(opt_arg);
break;
- case 7: /* user */
+ case OPT_user:
if (opt_arg)
{
my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
options->user=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 8: /* init-command */
+ case OPT_init_command:
add_init_command(options,opt_arg);
break;
- case 9: /* host */
+ case OPT_host:
if (opt_arg)
{
my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
options->host=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 10: /* database */
+ case OPT_database:
if (opt_arg)
{
my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
options->db=my_strdup(opt_arg,MYF(MY_WME));
}
break;
- case 11: /* debug */
+ case OPT_debug:
#ifdef MYSQL_CLIENT
mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace");
break;
#endif
- case 12: /* return-found-rows */
+ case OPT_return_found_rows:
options->client_flag|=CLIENT_FOUND_ROWS;
break;
#ifdef HAVE_OPENSSL
- case 13: /* ssl_key */
+ case OPT_ssl_key:
my_free(options->ssl_key, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_key = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 14: /* ssl_cert */
+ case OPT_ssl_cert:
my_free(options->ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_cert = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 15: /* ssl_ca */
+ case OPT_ssl_ca:
my_free(options->ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_ca = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 16: /* ssl_capath */
+ case OPT_ssl_capath:
my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 26: /* ssl_cipher */
+ case OPT_ssl_cipher:
my_free(options->ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME));
break;
#else
- case 13: /* Ignore SSL options */
- case 14:
- case 15:
- case 16:
- case 26:
+ case OPT_ssl_key:
+ case OPT_ssl_cert:
+ case OPT_ssl_ca:
+ case OPT_ssl_capath:
+ case OPT_ssl_cipher:
break;
#endif /* HAVE_OPENSSL */
- case 17: /* charset-lib */
+ case OPT_character_sets_dir:
my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 18:
+ case OPT_default_character_set:
my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
break;
- case 19: /* Interactive-timeout */
+ case OPT_interactive_timeout:
options->client_flag|= CLIENT_INTERACTIVE;
break;
- case 21:
+ case OPT_local_infile:
if (!opt_arg || atoi(opt_arg) != 0)
options->client_flag|= CLIENT_LOCAL_FILES;
else
options->client_flag&= ~CLIENT_LOCAL_FILES;
break;
- case 22:
+ case OPT_disable_local_infile:
options->client_flag&= ~CLIENT_LOCAL_FILES;
break;
- case 23: /* replication probe */
+ case OPT_replication_probe:
#ifndef TO_BE_DELETED
options->rpl_probe= 1;
#endif
break;
- case 24: /* enable-reads-from-master */
+ case OPT_enable_reads_from_master:
options->no_master_reads= 0;
break;
- case 25: /* repl-parse-query */
+ case OPT_repl_parse_query:
#ifndef TO_BE_DELETED
options->rpl_parse= 1;
#endif
break;
- case 27:
+ case OPT_max_allowed_packet:
if (opt_arg)
options->max_allowed_packet= atoi(opt_arg);
break;
- case 28: /* protocol */
+ case OPT_protocol:
if ((options->protocol= find_type(opt_arg,
&sql_protocol_typelib,0)) <= 0)
{
@@ -1202,26 +1226,32 @@ void mysql_read_default_options(struct s
exit(1);
}
break;
- case 29: /* shared_memory_base_name */
+ case OPT_shared_memory_base_name:
#ifdef HAVE_SMEM
if (options->shared_memory_base_name != def_shared_memory_base_name)
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
#endif
break;
- case 30:
+ case OPT_multi_results:
options->client_flag|= CLIENT_MULTI_RESULTS;
break;
- case 31:
- case 32:
+ case OPT_multi_statements:
+ case OPT_multi_queries:
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
break;
- case 33: /* secure-auth */
+ case OPT_secure_auth:
options->secure_auth= TRUE;
break;
- case 34: /* report-data-truncation */
+ case OPT_report_data_truncation:
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
break;
+ case OPT_plugin_dir:
+ extension_set_string(options, plugin_dir, opt_arg);
+ break;
+ case OPT_default_auth:
+ extension_set_string(options, default_auth, opt_arg);
+ break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
}
@@ -1765,6 +1795,11 @@ static int ssl_verify_server_cert(Vio *v
static my_bool cli_read_query_result(MYSQL *mysql);
static MYSQL_RES *cli_use_result(MYSQL *mysql);
+int cli_read_change_user_result(MYSQL *mysql)
+{
+ return cli_safe_read(mysql);
+}
+
static MYSQL_METHODS client_methods=
{
cli_read_query_result, /* read_query_result */
@@ -1772,7 +1807,8 @@ static MYSQL_METHODS client_methods=
cli_read_rows, /* read_rows */
cli_use_result, /* use_result */
cli_fetch_lengths, /* fetch_lengths */
- cli_flush_use_result /* flush_use_result */
+ cli_flush_use_result, /* flush_use_result */
+ cli_read_change_user_result /* read_change_user_result */
#ifndef MYSQL_SERVER
,cli_list_fields, /* list_fields */
cli_read_prepare_result, /* read_prepare_result */
@@ -1782,7 +1818,6 @@ static MYSQL_METHODS client_methods=
NULL, /* free_embedded_thd */
cli_read_statistics, /* read_statistics */
cli_read_query_result, /* next_result */
- cli_read_change_user_result, /* read_change_user_result */
cli_read_binary_rows /* read_rows_from_cursor */
#endif
};
@@ -1856,6 +1891,646 @@ int mysql_init_character_set(MYSQL *mysq
}
C_MODE_END
+/*********** client side authentication support **************************/
+
+typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
+static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, int);
+static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
+static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
+
+static auth_plugin_t native_password_client_plugin=
+{
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
+ native_password_plugin_name,
+ "R.J.Silk, Sergei Golubchik",
+ "Native MySQL authentication",
+ {1, 0, 0},
+ NULL,
+ NULL,
+ native_password_auth_client
+};
+
+static auth_plugin_t old_password_client_plugin=
+{
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
+ old_password_plugin_name,
+ "R.J.Silk, Sergei Golubchik",
+ "Old MySQL-3.23 authentication",
+ {1, 0, 0},
+ NULL,
+ NULL,
+ old_password_auth_client
+};
+
+struct st_mysql_client_plugin *mysql_client_builtins[]=
+{
+ (struct st_mysql_client_plugin *)&native_password_client_plugin,
+ (struct st_mysql_client_plugin *)&old_password_client_plugin,
+ 0
+};
+
+
+
+/* this is a "superset" of MYSQL_PLUGIN_VIO, in C++ I use inheritance */
+typedef struct {
+ int (*read_packet)(struct st_plugin_vio *vio, uchar **buf);
+ int (*write_packet)(struct st_plugin_vio *vio, const uchar *pkt, int pkt_len);
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+ /* -= end of MYSQL_PLUGIN_VIO =- */
+ MYSQL *mysql;
+ auth_plugin_t *plugin; /**< what plugin we're under */
+ const char *db;
+ struct {
+ uchar *pkt; /**< pointer into NET::buff */
+ uint pkt_len;
+ } cached_server_reply;
+ uint packets_read, packets_written; /**< counters for send/received packets */
+ my_bool mysql_change_user; /**< if it's mysql_change_user() */
+ int last_read_packet_len; /**< the length of the last *read* packet */
+} MCPVIO_EXT;
+
+/**
+ sends a COM_CHANGE_USER command with a caller provided payload
+
+ Packet format:
+
+ Bytes Content
+ ----- ----
+ n user name - \0-terminated string
+ n password
+ 3.23 scramble - \0-terminated string (9 bytes)
+ otherwise - length (1 byte) coded
+ n database name - \0-terminated string
+ 2 character set number (if the server >= 4.1.x)
+ n client auth plugin name - \0-terminated string,
+ (if the server supports plugin auth)
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+static int send_change_user_packet(MCPVIO_EXT *mpvio,
+ const uchar *data, int data_len)
+{
+ MYSQL *mysql= mpvio->mysql;
+ char *buff, *end;
+ int res= 1;
+
+ buff= my_alloca(USERNAME_LENGTH + data_len + 1 + NAME_LEN + 2 + NAME_LEN);
+
+ end= strmake(buff, mysql->user, USERNAME_LENGTH) + 1;
+
+ if (!data_len)
+ *end++= 0;
+ else
+ {
+ if (mysql->client_flag & CLIENT_SECURE_CONNECTION)
+ {
+ DBUG_ASSERT(data_len <= 255);
+ if (data_len > 255)
+ {
+ set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
+ goto error;
+ }
+ *end++= data_len;
+ }
+ else
+ {
+ DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1);
+ DBUG_ASSERT(data[SCRAMBLE_LENGTH_323] == 0);
+ }
+ memcpy(end, data, data_len);
+ end+= data_len;
+ }
+ end= strmake(end, mpvio->db ? mpvio->db : "", NAME_LEN) + 1;
+
+ if (mysql->server_capabilities & CLIENT_PROTOCOL_41)
+ {
+ int2store(end, (ushort) mysql->charset->number);
+ end+= 2;
+ }
+
+ if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
+ end= strmake(end, mpvio->plugin->name, NAME_LEN) + 1;
+
+ res= simple_command(mysql, COM_CHANGE_USER,
+ (uchar*)buff, (ulong)(end-buff), 1);
+
+error:
+ my_afree(buff);
+ return res;
+}
+
+
+/**
+ sends a client authentication packet (second packet in the 3-way handshake)
+
+ Packet format (when the server is 4.0 or earlier):
+
+ Bytes Content
+ ----- ----
+ 2 client capabilities
+ 3 max packet size
+ n user name, \0-terminated
+ 9 scramble_323, \0-terminated
+
+ Packet format (when the server is 4.1 or newer):
+
+ Bytes Content
+ ----- ----
+ 4 client capabilities
+ 4 max packet size
+ 1 charset number
+ 23 reserved (always 0)
+ n user name, \0-terminated
+ n plugin auth data (e.g. scramble), length (1 byte) coded
+ n database name, \0-terminated
+ (if CLIENT_CONNECT_WITH_DB is set in the capabilities)
+ n client auth plugin name - \0-terminated string,
+ (if CLIENT_PLUGIN_AUTH is set in the capabilities)
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+static int send_client_reply_packet(MCPVIO_EXT *mpvio,
+ const uchar *data, int data_len)
+{
+ MYSQL *mysql= mpvio->mysql;
+ NET *net= &mysql->net;
+ char *buff, *end;
+
+ /* see end= buff+32 below, fixed size of the packet is 32 bytes */
+ buff= my_alloca(33 + USERNAME_LENGTH + data_len + NAME_LEN + NAME_LEN);
+
+ mysql->client_flag|= mysql->options.client_flag;
+ mysql->client_flag|= CLIENT_CAPABILITIES;
+
+ if (mysql->client_flag & CLIENT_MULTI_STATEMENTS)
+ mysql->client_flag|= CLIENT_MULTI_RESULTS;
+
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
+ if (mysql->options.ssl_key || mysql->options.ssl_cert ||
+ mysql->options.ssl_ca || mysql->options.ssl_capath ||
+ mysql->options.ssl_cipher)
+ mysql->options.use_ssl= 1;
+ if (mysql->options.use_ssl)
+ mysql->client_flag|= CLIENT_SSL;
+#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY*/
+ if (mpvio->db)
+ mysql->client_flag|= CLIENT_CONNECT_WITH_DB;
+
+ /* Remove options that server doesn't support */
+ mysql->client_flag= mysql->client_flag &
+ (~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)
+ | mysql->server_capabilities);
+
+#ifndef HAVE_COMPRESS
+ mysql->client_flag&= ~CLIENT_COMPRESS;
+#endif
+
+ if (mysql->client_flag & CLIENT_PROTOCOL_41)
+ {
+ /* 4.1 server and 4.1 client has a 32 byte option flag */
+ int4store(buff,mysql->client_flag);
+ int4store(buff+4, net->max_packet_size);
+ buff[8]= (char) mysql->charset->number;
+ bzero(buff+9, 32-9);
+ end= buff+32;
+ }
+ else
+ {
+ int2store(buff, mysql->client_flag);
+ int3store(buff+2, net->max_packet_size);
+ end= buff+5;
+ }
+#ifdef HAVE_OPENSSL
+ if (mysql->client_flag & CLIENT_SSL)
+ {
+ /* Do the SSL layering. */
+ struct st_mysql_options *options= &mysql->options;
+ struct st_VioSSLFd *ssl_fd;
+ char error_string[1024];
+
+ /*
+ Send mysql->client_flag, max_packet_size - unencrypted otherwise
+ the server does not know we want to do SSL
+ */
+ if (my_net_write(net, (uchar*)buff, (size_t) (end-buff)) || net_flush(net))
+ {
+ set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "sending connection information to server",
+ errno);
+ goto error;
+ }
+
+ /* Create the VioSSLConnectorFd - init SSL and load certs */
+ if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key,
+ options->ssl_cert,
+ options->ssl_ca,
+ options->ssl_capath,
+ options->ssl_cipher)))
+ {
+ set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+ goto error;
+ }
+ mysql->connector_fd= (void*)ssl_fd;
+
+ /* Connect to the server */
+ DBUG_PRINT("info", ("IO layer change in progress..."));
+ if (sslconnect(ssl_fd, net->vio,
+ (long) (mysql->options.connect_timeout),
+ error_string))
+ {
+ set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR,
+ unknown_sqlstate, "SSL error: %s",
+ error_string[0] ? error_string :
+ ER(CR_SSL_CONNECTION_ERROR));
+ goto error;
+ }
+ DBUG_PRINT("info", ("IO layer change done!"));
+
+ /* Verify server cert */
+ if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
+ ssl_verify_server_cert(net->vio, mysql->host))
+ {
+ set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+ goto error;
+ }
+ }
+#endif /* HAVE_OPENSSL */
+
+ DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
+ mysql->server_version, mysql->server_capabilities,
+ mysql->server_status, mysql->client_flag));
+
+ compile_time_assert(MYSQL_USERNAME_LENGTH == USERNAME_LENGTH);
+
+ /* This needs to be changed as it's not useful with big packets */
+ if (mysql->user[0])
+ strmake(end, mysql->user, USERNAME_LENGTH);
+ else
+ read_user_name(end);
+
+ /* We have to handle different version of handshake here */
+ DBUG_PRINT("info",("user: %s",end));
+ end= strend(end) + 1;
+ if (data_len)
+ {
+ if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
+ {
+ *end++= data_len;
+ memcpy(end, data, data_len);
+ end+= data_len;
+ }
+ else
+ {
+ DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1); /* incl. \0 at the end */
+ memcpy(end, data, data_len);
+ end+= data_len;
+ }
+ }
+ else
+ *end++= 0;
+
+ /* Add database if needed */
+ if (mpvio->db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
+ {
+ end= strmake(end, mpvio->db, NAME_LEN) + 1;
+ mysql->db= my_strdup(mpvio->db, MYF(MY_WME));
+ }
+
+ if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
+ end= strmake(end, mpvio->plugin->name, NAME_LEN) + 1;
+
+ /* Write authentication package */
+ if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
+ {
+ set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "sending authentication information",
+ errno);
+ goto error;
+ }
+ my_afree(buff);
+ return 0;
+
+error:
+ my_afree(buff);
+ return 1;
+}
+
+
+/**
+ vio->read_packet() callback method for client authentication plugins
+
+ This function is called by a client authentication plugin, when it wants
+ to read data from the server.
+*/
+
+static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf)
+{
+ MCPVIO_EXT *mpvio= (MCPVIO_EXT*)mpv;
+ MYSQL *mysql= mpvio->mysql;
+ ulong pkt_len;
+
+ /* there are cached data left, feed it to a plugin */
+ if (mpvio->cached_server_reply.pkt)
+ {
+ *buf= mpvio->cached_server_reply.pkt;
+ mpvio->cached_server_reply.pkt= 0;
+ mpvio->packets_read++;
+ return mpvio->cached_server_reply.pkt_len;
+ }
+
+ if (mpvio->packets_read == 0)
+ {
+ /*
+ the server handshake packet came from the wrong plugin,
+ or it's mysql_change_user(). Either way, there is no data
+ for a plugin to read. send a dummy packet to the server
+ to initiate a dialog.
+ */
+ if (client_mpvio_write_packet(mpv, 0, 0))
+ return (int)packet_error;
+ }
+
+ /* otherwise read the data */
+ pkt_len= (*mysql->methods->read_change_user_result)(mysql);
+ mpvio->last_read_packet_len= pkt_len;
+ *buf= mysql->net.read_pos;
+
+ /* was it a request to change plugins ? */
+ if (**buf == 254)
+ return (int)packet_error; /* if yes, this plugin shan't continue */
+
+ /*
+ the server sends \1\255 or \1\254 instead of just \255 or \254 -
+ for us to not confuse it with an error or "change plugin" packets.
+ We remove this escaping \1 here.
+
+ See also server_mpvio_write_packet() where the escaping is done.
+ */
+ if (pkt_len && **buf == 1)
+ {
+ (*buf)++;
+ pkt_len--;
+ }
+ mpvio->packets_read++;
+ return pkt_len;
+}
+
+
+/**
+ vio->write_packet() callback method for client authentication plugins
+
+ This function is called by a client authentication plugin, when it wants
+ to send data to the server.
+
+ It transparently wraps the data into a change user or authentication
+ handshake packet, if neccessary.
+*/
+
+static int client_mpvio_write_packet(struct st_plugin_vio *mpv,
+ const uchar *pkt, int pkt_len)
+{
+ int res;
+ MCPVIO_EXT *mpvio= (MCPVIO_EXT*)mpv;
+
+ if (mpvio->packets_written == 0)
+ {
+ if (mpvio->mysql_change_user)
+ res= send_change_user_packet(mpvio, pkt, pkt_len);
+ else
+ res= send_client_reply_packet(mpvio, pkt, pkt_len);
+ }
+ else
+ {
+ NET *net= &mpvio->mysql->net;
+ if (mpvio->mysql->thd)
+ res= 1; /* no chit-chat in embedded */
+ else
+ res= my_net_write(net, pkt, pkt_len) || net_flush(net);
+ if (res)
+ set_mysql_extended_error(mpvio->mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "sending authentication information",
+ errno);
+ }
+ mpvio->packets_written++;
+ return res;
+}
+
+
+/**
+ fills MYSQL_PLUGIN_VIO_INFO structure with the information about the
+ connection
+*/
+
+void mpvio_info(Vio *vio, MYSQL_PLUGIN_VIO_INFO *info)
+{
+ bzero(info, sizeof(*info));
+ switch (vio->type) {
+ case VIO_TYPE_TCPIP:
+ info->protocol= MYSQL_VIO_TCP;
+ info->socket= vio->sd;
+ return;
+ case VIO_TYPE_SOCKET:
+ info->protocol= MYSQL_VIO_SOCKET;
+ info->socket= vio->sd;
+ return;
+ case VIO_TYPE_SSL:
+ {
+ struct sockaddr addr;
+ socklen_t addrlen= sizeof(addr);
+ if (getsockname(vio->sd, &addr, &addrlen))
+ return;
+ info->protocol= addr.sa_family == AF_UNIX ?
+ MYSQL_VIO_SOCKET : MYSQL_VIO_TCP;
+ info->socket= vio->sd;
+ return;
+ }
+#ifdef _WIN32
+ case VIO_TYPE_NAMEDPIPE:
+ info->protocol= MYSQL_VIO_PIPE;
+ info->handle= vio->hPipe;
+ return;
+ case VIO_TYPE_SHARED_MEMORY:
+ info->protocol= MYSQL_VIO_MEMORY;
+ info->handle= vio->handle_client_file_map; /* or what ? */
+ return;
+#endif
+ default: DBUG_ASSERT(0);
+ }
+}
+
+
+static void client_mpvio_info(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_PLUGIN_VIO_INFO *info)
+{
+ MCPVIO_EXT *mpvio= (MCPVIO_EXT*)vio;
+ mpvio_info(mpvio->mysql->net.vio, info);
+}
+
+
+/**
+ Client side of the plugin driver authentication.
+
+ @note this is used by both the mysql_real_connect and mysql_change_user
+
+ @param mysql mysql
+ @param data pointer to the plugin auth data (scramble) in the
+ handshake packet
+ @param data_len the length of the data
+ @param data_plugin a plugin that data were prepared for
+ or 0 if it's mysql_change_user()
+ @param db initial db to use, can be 0
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
+ char *data_plugin, const char *db)
+{
+ const char *auth_plugin_name;
+ auth_plugin_t *auth_plugin;
+ MCPVIO_EXT mpvio;
+ ulong pkt_length;
+ int res;
+
+ /* determine the default/initial plugin to use */
+ if (mysql->options.extension && mysql->options.extension->default_auth &&
+ mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
+ {
+ auth_plugin_name= mysql->options.extension->default_auth;
+ if (!(auth_plugin= (auth_plugin_t*) mysql_client_find_plugin(mysql,
+ auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
+ return 1; /* oops, not found */
+ }
+ else
+ {
+ auth_plugin= mysql->server_capabilities & CLIENT_PROTOCOL_41 ?
+ &native_password_client_plugin : &old_password_client_plugin;
+ auth_plugin_name= auth_plugin->name;
+ }
+
+ mysql->net.last_errno= 0; /* just in case */
+
+ if (data_plugin && strcmp(data_plugin, auth_plugin_name))
+ {
+ /* data was prepared for a different plugin, don't show it to this one */
+ data= 0;
+ data_len= 0;
+ }
+
+ mpvio.mysql_change_user= data_plugin == 0;
+ mpvio.cached_server_reply.pkt= (uchar*)data;
+ mpvio.cached_server_reply.pkt_len= data_len;
+ mpvio.read_packet= client_mpvio_read_packet;
+ mpvio.write_packet= client_mpvio_write_packet;
+ mpvio.info= client_mpvio_info;
+ mpvio.mysql= mysql;
+ mpvio.packets_read= mpvio.packets_written= 0;
+ mpvio.db= db;
+ mpvio.plugin= auth_plugin;
+
+ res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql);
+
+ compile_time_assert(CR_OK == -1);
+ compile_time_assert(CR_ERROR == 0);
+ if (res > CR_OK && mysql->net.read_pos[0] != 254)
+ {
+ /*
+ the plugin returned an error. write it down in mysql,
+ unless the error code is CR_ERROR and mysql->net.last_errno
+ is already set (the plugin has done it)
+ */
+ if (res > CR_ERROR)
+ set_mysql_error(mysql, res, unknown_sqlstate);
+ else
+ if (!mysql->net.last_errno)
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+ return 1;
+ }
+
+ /* read the OK packet (or use the cached value in mysql->net.read_pos */
+ if (res == CR_OK)
+ pkt_length= (*mysql->methods->read_change_user_result)(mysql);
+ else /* res == CR_OK_HANDSHAKE_COMPLETE */
+ pkt_length= mpvio.last_read_packet_len;
+
+ if (pkt_length == packet_error)
+ {
+ if (mysql->net.last_errno == CR_SERVER_LOST)
+ set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "reading authorization packet",
+ errno);
+ return 1;
+ }
+
+ if (mysql->net.read_pos[0] == 254)
+ {
+ /* The server asked to use a different authentication plugin */
+ if (pkt_length == 1)
+ {
+ /* old "use short scramble" packet */
+ auth_plugin_name= old_password_plugin_name;
+ mpvio.cached_server_reply.pkt= (uchar*)mysql->scramble;
+ mpvio.cached_server_reply.pkt_len= SCRAMBLE_LENGTH + 1;
+ }
+ else
+ {
+ /* new "use different plugin" packet */
+ uint len;
+ auth_plugin_name= (char*)mysql->net.read_pos + 1;
+ len= strlen(auth_plugin_name); /* safe as my_net_read always appends \0 */
+ mpvio.cached_server_reply.pkt_len= pkt_length - len - 2;
+ mpvio.cached_server_reply.pkt= mysql->net.read_pos + len + 2;
+ }
+
+ if (!(auth_plugin= (auth_plugin_t *) mysql_client_find_plugin(mysql,
+ auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
+ return 1;
+
+ mpvio.plugin= auth_plugin;
+ res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql);
+
+ if (res > CR_OK)
+ {
+ if (res > CR_ERROR)
+ set_mysql_error(mysql, res, unknown_sqlstate);
+ else
+ if (!mysql->net.last_errno)
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+ return 1;
+ }
+
+ if (res != CR_OK_HANDSHAKE_COMPLETE)
+ {
+ /* Read what server thinks about out new auth message report */
+ if (cli_safe_read(mysql) == packet_error)
+ {
+ if (mysql->net.last_errno == CR_SERVER_LOST)
+ set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
+ ER(CR_SERVER_LOST_EXTENDED),
+ "reading final connect information",
+ errno);
+ return 1;
+ }
+ }
+ }
+ /*
+ net->read_pos[0] should always be 0 here if the server implements
+ the protocol correctly
+ */
+ return mysql->net.read_pos[0] != 0;
+}
+
MYSQL * STDCALL
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
@@ -1863,8 +2538,9 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
uint port, const char *unix_socket,ulong client_flag)
{
char buff[NAME_LEN+USERNAME_LENGTH+100];
- char error_string[1024];
- char *end,*host_info= NULL;
+ int scramble_data_len, pkt_scramble_len;
+ char *end, *host_info=0, *server_version_end, *pkt_end;
+ char *scramble_data, *scramble_plugin;
my_socket sock;
in_addr_t ip_addr;
struct sockaddr_in sock_addr;
@@ -2180,8 +2856,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
errno);
goto error;
}
+ pkt_end= (char*)net->read_pos + pkt_length;
/* Check if version of protocol matches current one */
-
mysql->protocol_version= net->read_pos[0];
DBUG_DUMP("packet",(uchar*) net->read_pos,10);
DBUG_PRINT("info",("mysql protocol version %d, server=%d",
@@ -2193,31 +2869,29 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
PROTOCOL_VERSION);
goto error;
}
- end=strend((char*) net->read_pos+1);
+ server_version_end= end= strend((char*) net->read_pos+1);
mysql->thread_id=uint4korr(end+1);
end+=5;
/*
- Scramble is split into two parts because old clients does not understand
+ Scramble is split into two parts because old clients do not understand
long scrambles; here goes the first part.
*/
- strmake(mysql->scramble, end, SCRAMBLE_LENGTH_323);
- end+= SCRAMBLE_LENGTH_323+1;
+ scramble_data= end;
+ scramble_data_len= SCRAMBLE_LENGTH_323 + 1;
+ scramble_plugin= old_password_plugin_name;
+ end+= scramble_data_len;
- if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
+ if (pkt_end >= end + 1)
mysql->server_capabilities=uint2korr(end);
- if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
+ if (pkt_end >= end + 18)
{
/* New protocol with 16 bytes to describe server characteristics */
mysql->server_language=end[2];
mysql->server_status=uint2korr(end+3);
+ mysql->server_capabilities|= uint2korr(end+5) << 16;
+ pkt_scramble_len= end[7];
}
end+= 18;
- if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
- (char *) net->read_pos))
- strmake(mysql->scramble+SCRAMBLE_LENGTH_323, end,
- SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
- else
- mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
if (mysql->options.secure_auth && passwd[0] &&
!(mysql->server_capabilities & CLIENT_SECURE_CONNECTION))
@@ -2236,7 +2910,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
&mysql->unix_socket,unix_socket ?
(uint) strlen(unix_socket)+1 : (uint) 1,
&mysql->server_version,
- (uint) (end - (char*) net->read_pos),
+ (uint) (server_version_end - (char*) net->read_pos + 1),
NullS) ||
!(mysql->user=my_strdup(user,MYF(0))) ||
!(mysql->passwd=my_strdup(passwd,MYF(0))))
@@ -2253,203 +2927,47 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
strmov(mysql->server_version,(char*) net->read_pos+1);
mysql->port=port;
- /*
- Part 2: format and send client info to the server for access check
- */
-
- client_flag|=mysql->options.client_flag;
- client_flag|=CLIENT_CAPABILITIES;
- if (client_flag & CLIENT_MULTI_STATEMENTS)
- client_flag|= CLIENT_MULTI_RESULTS;
-
-#ifdef HAVE_OPENSSL
- if (mysql->options.ssl_key || mysql->options.ssl_cert ||
- mysql->options.ssl_ca || mysql->options.ssl_capath ||
- mysql->options.ssl_cipher)
- mysql->options.use_ssl= 1;
- if (mysql->options.use_ssl)
- client_flag|=CLIENT_SSL;
-#endif /* HAVE_OPENSSL */
- if (db)
- client_flag|=CLIENT_CONNECT_WITH_DB;
-
- /* Remove options that server doesn't support */
- client_flag= ((client_flag &
- ~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
- (client_flag & mysql->server_capabilities));
-#ifndef HAVE_COMPRESS
- client_flag&= ~CLIENT_COMPRESS;
-#endif
-
- if (client_flag & CLIENT_PROTOCOL_41)
- {
- /* 4.1 server and 4.1 client has a 32 byte option flag */
- int4store(buff,client_flag);
- int4store(buff+4, net->max_packet_size);
- buff[8]= (char) mysql->charset->number;
- bzero(buff+9, 32-9);
- end= buff+32;
- }
- else
- {
- int2store(buff,client_flag);
- int3store(buff+2,net->max_packet_size);
- end= buff+5;
- }
- mysql->client_flag=client_flag;
-
-#ifdef HAVE_OPENSSL
- if (client_flag & CLIENT_SSL)
+ if (pkt_end >= end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1)
{
- /* Do the SSL layering. */
- struct st_mysql_options *options= &mysql->options;
- struct st_VioSSLFd *ssl_fd;
-
/*
- Send client_flag, max_packet_size - unencrypted otherwise
- the server does not know we want to do SSL
+ move the first scramble part - directly in the NET buffer -
+ to get a full continuous scramble. We've read all the header,
+ and can overwrite it now.
*/
- if (my_net_write(net, (uchar*) buff, (uint) (end-buff)) || net_flush(net))
- {
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "sending connection information to server",
- errno);
- goto error;
- }
-
- /* Create the VioSSLConnectorFd - init SSL and load certs */
- if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key,
- options->ssl_cert,
- options->ssl_ca,
- options->ssl_capath,
- options->ssl_cipher)))
- {
- set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
- goto error;
- }
- mysql->connector_fd= (void*)ssl_fd;
-
- /* Connect to the server */
- DBUG_PRINT("info", ("IO layer change in progress..."));
- if (sslconnect(ssl_fd, mysql->net.vio,
- (long) (mysql->options.connect_timeout),
- error_string))
- {
- set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR,
- unknown_sqlstate,
- "SSL error: %s",
- error_string[0] ? error_string :
- ER(CR_SSL_CONNECTION_ERROR));
- goto error;
- }
- DBUG_PRINT("info", ("IO layer change done!"));
-
- /* Verify server cert */
- if ((client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
- ssl_verify_server_cert(mysql->net.vio, mysql->host))
- {
- set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
- goto error;
- }
-
- }
-#endif /* HAVE_OPENSSL */
-
- DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
- mysql->server_version,mysql->server_capabilities,
- mysql->server_status, client_flag));
- /* This needs to be changed as it's not useful with big packets */
- if (user && user[0])
- strmake(end,user,USERNAME_LENGTH); /* Max user name */
- else
- read_user_name((char*) end);
-
- /* We have to handle different version of handshake here */
-#ifdef _CUSTOMCONFIG_
-#include "_cust_libmysql.h"
-#endif
- DBUG_PRINT("info",("user: %s",end));
- end= strend(end) + 1;
- if (passwd[0])
- {
- if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- *end++= SCRAMBLE_LENGTH;
- scramble(end, mysql->scramble, passwd);
- end+= SCRAMBLE_LENGTH;
+ memmove(end - SCRAMBLE_LENGTH_323, scramble_data,
+ SCRAMBLE_LENGTH_323);
+ scramble_data= end - SCRAMBLE_LENGTH_323;
+ if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
+ {
+ scramble_data_len= pkt_scramble_len;
+ scramble_plugin= scramble_data + scramble_data_len;
+ if (scramble_data + scramble_data_len > pkt_end)
+ scramble_data_len= pkt_end - scramble_data;
}
else
{
- scramble_323(end, mysql->scramble, passwd);
- end+= SCRAMBLE_LENGTH_323 + 1;
+ scramble_data_len= pkt_end - scramble_data;
+ scramble_plugin= native_password_plugin_name;
}
}
else
- *end++= '\0'; /* empty password */
+ mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
+
+ mysql->client_flag= client_flag;
- /* Add database if needed */
- if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
- {
- end= strmake(end, db, NAME_LEN) + 1;
- mysql->db= my_strdup(db,MYF(MY_WME));
- db= 0;
- }
- /* Write authentication package */
- if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
- {
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "sending authentication information",
- errno);
- goto error;
- }
-
/*
- Part 3: Authorization data's been sent. Now server can reply with
- OK-packet, or re-request scrambled password.
+ Part 2: invoke the plugin to send the authentication data to the server
*/
- if ((pkt_length=cli_safe_read(mysql)) == packet_error)
- {
- if (mysql->net.last_errno == CR_SERVER_LOST)
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "reading authorization packet",
- errno);
+ if (run_plugin_auth(mysql, scramble_data, scramble_data_len,
+ scramble_plugin, db))
goto error;
- }
- if (pkt_length == 1 && net->read_pos[0] == 254 &&
- mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
- {
- /*
- By sending this very specific reply server asks us to send scrambled
- password in old format.
- */
- scramble_323(buff, mysql->scramble, passwd);
- if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
- net_flush(net))
- {
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "sending password information",
- errno);
- goto error;
- }
- /* Read what server thinks about out new auth message report */
- if (cli_safe_read(mysql) == packet_error)
- {
- if (mysql->net.last_errno == CR_SERVER_LOST)
- set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
- ER(CR_SERVER_LOST_EXTENDED),
- "reading final connect information",
- errno);
- goto error;
- }
- }
+ /*
+ Part 3: authenticated, finish the initialization of the connection
+ */
- if (client_flag & CLIENT_COMPRESS) /* We will use compression */
+ if (mysql->client_flag & CLIENT_COMPRESS) /* We will use compression */
net->compress=1;
#ifdef CHECK_LICENSE
@@ -2457,7 +2975,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
goto error;
#endif
- if (db && mysql_select_db(mysql, db))
+ if (db && !mysql->db && mysql_select_db(mysql, db))
{
if (mysql->net.last_errno == CR_SERVER_LOST)
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
@@ -2510,7 +3028,7 @@ error:
/* Free alloced memory */
end_server(mysql);
mysql_close_free(mysql);
- if (!(((ulong) client_flag) & CLIENT_REMEMBER_OPTIONS))
+ if (!(client_flag & CLIENT_REMEMBER_OPTIONS))
mysql_close_free_options(mysql);
}
DBUG_RETURN(0);
@@ -2655,6 +3173,12 @@ static void mysql_close_free_options(MYS
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif /* HAVE_SMEM */
+ if (mysql->options.extension)
+ {
+ my_free(mysql->options.extension->plugin_dir,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.extension->default_auth,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.extension,MYF(0));
+ }
bzero((char*) &mysql->options,sizeof(mysql->options));
DBUG_VOID_RETURN;
}
@@ -3185,6 +3709,12 @@ mysql_options(MYSQL *mysql,enum mysql_op
else
mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
break;
+ case MYSQL_PLUGIN_DIR:
+ extension_set_string(&mysql->options, plugin_dir, arg);
+ break;
+ case MYSQL_DEFAULT_AUTH:
+ extension_set_string(&mysql->options, default_auth, arg);
+ break;
default:
DBUG_RETURN(1);
}
@@ -3293,3 +3823,99 @@ int STDCALL mysql_set_character_set(MYSQ
}
+/**
+ client authentication plugin that does native MySQL authentication
+ using a 20-byte (4.1+) scramble
+*/
+
+static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ int pkt_len;
+ uchar *pkt;
+
+ if (((MCPVIO_EXT *)vio)->mysql_change_user)
+ {
+ /*
+ in mysql_change_user() the client sends the first packet.
+ we use the old scramble.
+ */
+ pkt= (uchar*)mysql->scramble;
+ pkt_len= SCRAMBLE_LENGTH + 1;
+ }
+ else
+ {
+ /* read the scramble */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ if (pkt_len != SCRAMBLE_LENGTH + 1)
+ return CR_SERVER_HANDSHAKE_ERR;
+
+ /* save it in MYSQL */
+ memcpy(mysql->scramble, pkt, SCRAMBLE_LENGTH);
+ mysql->scramble[SCRAMBLE_LENGTH] = 0;
+ }
+
+ if (mysql->passwd[0])
+ {
+ char scrambled[SCRAMBLE_LENGTH + 1];
+ scramble(scrambled, (char*)pkt, mysql->passwd);
+ if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH))
+ return CR_ERROR;
+ }
+ else
+ if (vio->write_packet(vio, 0, 0)) /* no password */
+ return CR_ERROR;
+
+ return CR_OK;
+}
+
+
+/**
+ client authentication plugin that does old MySQL authentication
+ using an 8-byte (4.0-) scramble
+*/
+
+static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ uchar *pkt;
+ int pkt_len;
+
+ if (((MCPVIO_EXT *)vio)->mysql_change_user)
+ {
+ /*
+ in mysql_change_user() the client sends the first packet.
+ we use the old scramble.
+ */
+ pkt= (uchar*)mysql->scramble;
+ pkt_len= SCRAMBLE_LENGTH_323 + 1;
+ }
+ else
+ {
+ /* read the scramble */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ if (pkt_len != SCRAMBLE_LENGTH_323 + 1 &&
+ pkt_len != SCRAMBLE_LENGTH + 1)
+ return CR_SERVER_HANDSHAKE_ERR;
+
+ /* save it in MYSQL */
+ memcpy(mysql->scramble, pkt, pkt_len);
+ mysql->scramble[pkt_len] = 0;
+ }
+
+ if (mysql->passwd[0])
+ {
+ char scrambled[SCRAMBLE_LENGTH_323 + 1];
+ scramble_323(scrambled, (char*)pkt, mysql->passwd);
+ if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH_323 + 1))
+ return CR_ERROR;
+ }
+ else
+ if (vio->write_packet(vio, 0, 0)) /* no password */
+ return CR_ERROR;
+
+ return CR_OK;
+}
+
=== added file 'sql-common/client_plugin.c'
--- a/sql-common/client_plugin.c 1970-01-01 00:00:00 +0000
+++ b/sql-common/client_plugin.c 2010-03-29 15:13:53 +0000
@@ -0,0 +1,436 @@
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+
+ Support code for the client side (libmysql) plugins
+
+ Client plugins are somewhat different from server plugins, they are simpler.
+
+ They do not need to be installed or in any way explicitly loaded on the
+ client, they are loaded automatically on demand.
+ One client plugin per shared object, soname *must* match the plugin name.
+
+ There is no reference counting and no unloading either.
+*/
+
+#include <my_global.h>
+#include "mysql.h"
+#include <my_sys.h>
+#include <m_string.h>
+#ifdef THREAD
+#include <my_pthread.h>
+#else
+#include <my_no_pthread.h>
+#endif
+
+#include <sql_common.h>
+#include "errmsg.h"
+#include <mysql/client_plugin.h>
+
+struct st_client_plugin_int {
+ struct st_client_plugin_int *next;
+ void *dlhandle;
+ struct st_mysql_client_plugin *plugin;
+};
+
+static my_bool initialized= 0;
+static MEM_ROOT mem_root;
+
+static const char *plugin_declarations_sym= "_mysql_client_plugin_declaration_";
+static uint plugin_version[MYSQL_CLIENT_MAX_PLUGINS]=
+{
+ 0, /* these two are taken by Connector/C */
+ 0, /* these two are taken by Connector/C */
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION
+};
+
+/*
+ Loaded plugins are stored in a linked list.
+ The list is append-only, the elements are added to the head (like in a stack).
+ The elements are added under a mutex, but the list can be read and traversed
+ without any mutex because once an element is added to the list, it stays
+ there. The main purpose of a mutex is to prevent two threads from
+ loading the same plugin twice in parallel.
+*/
+struct st_client_plugin_int *plugin_list[MYSQL_CLIENT_MAX_PLUGINS];
+#ifdef THREAD
+static pthread_mutex_t LOCK_load_client_plugin;
+#endif
+
+static int is_not_initialized(MYSQL *mysql, const char *name)
+{
+ if (initialized)
+ return 0;
+
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
+ unknown_sqlstate, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
+ name, "not initialized");
+ return 1;
+}
+
+
+/**
+ finds a plugin in the list
+
+ @param name plugin name to search for
+ @param type plugin type
+
+ @note this does NOT necessarily need a mutex, take care!
+
+ @retval a pointer to a found plugin or 0
+*/
+
+static struct st_mysql_client_plugin *find_plugin(const char *name, int type)
+{
+ struct st_client_plugin_int *p;
+
+ DBUG_ASSERT(initialized);
+ DBUG_ASSERT(type >= 0 && type < MYSQL_CLIENT_MAX_PLUGINS);
+ if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS)
+ return 0;
+
+ for (p= plugin_list[type]; p; p= p->next)
+ {
+ if (strcmp(p->plugin->name, name) == 0)
+ return p->plugin;
+ }
+ return NULL;
+}
+
+
+/**
+ verifies the plugin and adds it to the list
+
+ @param mysql MYSQL structure (for error reporting)
+ @param plugin plugin to install
+ @param dlhandle a handle to the shared object (returned by dlopen)
+ or 0 if the plugin was not dynamically loaded
+ @param argc number of arguments in the 'va_list args'
+ @param args arguments passed to the plugin initialization function
+
+ @retval a pointer to an installed plugin or 0
+*/
+
+static struct st_mysql_client_plugin *
+add_plugin(MYSQL *mysql, struct st_mysql_client_plugin *plugin, void *dlhandle,
+ int argc, va_list args)
+{
+ const char *errmsg;
+ struct st_client_plugin_int plugin_int, *p;
+ char errbuf[1024];
+
+ DBUG_ASSERT(initialized);
+
+ plugin_int.plugin= plugin;
+ plugin_int.dlhandle= dlhandle;
+
+ if (plugin->type >= MYSQL_CLIENT_MAX_PLUGINS)
+ {
+ errmsg= "Unknown client plugin type";
+ goto err1;
+ }
+
+ if (plugin->interface_version < plugin_version[plugin->type] ||
+ (plugin->interface_version >> 8) >
+ (plugin_version[plugin->type] >> 8))
+ {
+ errmsg= "Incompatible client plugin interface";
+ goto err1;
+ }
+
+ /* Call the plugin initialization function, if any */
+ if (plugin->init && plugin->init(errbuf, sizeof(errbuf), argc, args))
+ {
+ errmsg= errbuf;
+ goto err1;
+ }
+
+ p= (struct st_client_plugin_int *)
+ memdup_root(&mem_root, &plugin_int, sizeof(plugin_int));
+
+ if (!p)
+ {
+ errmsg= "Out of memory";
+ goto err2;
+ }
+
+ safe_mutex_assert_owner(&LOCK_load_client_plugin);
+
+ p->next= plugin_list[plugin->type];
+ plugin_list[plugin->type]= p;
+
+ return plugin;
+
+err2:
+ if (plugin->deinit)
+ plugin->deinit();
+err1:
+ if (dlhandle)
+ dlclose(dlhandle);
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate,
+ ER(CR_AUTH_PLUGIN_CANNOT_LOAD), plugin->name,
+ errmsg);
+ return NULL;
+}
+
+
+/**
+ Loads plugins which are specified in the environment variable
+ LIBMYSQL_PLUGINS.
+
+ Multiple plugins must be separated by semicolon. This function doesn't
+ return or log an error.
+
+ The function is be called by mysql_client_plugin_init
+
+ @todo
+ Support extended syntax, passing parameters to plugins, for example
+ LIBMYSQL_PLUGINS="plugin1(param1,param2);plugin2;..."
+ or
+ LIBMYSQL_PLUGINS="plugin1=int:param1,str:param2;plugin2;..."
+*/
+
+static void load_env_plugins(MYSQL *mysql)
+{
+ char *plugs, *free_env, *s= getenv("LIBMYSQL_PLUGINS");
+
+ /* no plugins to load */
+ if (!s)
+ return;
+
+ free_env= plugs= my_strdup(s, MYF(MY_WME));
+
+ do {
+ if ((s= strchr(plugs, ';')))
+ *s= '\0';
+ mysql_load_plugin(mysql, plugs, -1, 0);
+ plugs= s + 1;
+ } while (s);
+
+ my_free(free_env, MYF(0));
+}
+
+/********** extern functions to be used by libmysql *********************/
+
+/**
+ Initializes the client plugin layer.
+
+ This function must be called before any other client plugin function.
+
+ @retval 0 successful
+ @retval != 0 error occured
+*/
+
+int mysql_client_plugin_init()
+{
+ MYSQL mysql;
+ struct st_mysql_client_plugin **builtin;
+
+ if (initialized)
+ return 0;
+
+ bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */
+
+ pthread_mutex_init(&LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW);
+ init_alloc_root(&mem_root, 128, 128);
+
+ bzero(&plugin_list, sizeof(plugin_list));
+
+ initialized= 1;
+
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ for (builtin= mysql_client_builtins; *builtin; builtin++)
+ add_plugin(&mysql, *builtin, 0, 0, 0);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+
+ load_env_plugins(&mysql);
+
+ return 0;
+}
+
+
+/**
+ Deinitializes the client plugin layer.
+
+ Unloades all client plugins and frees any associated resources.
+*/
+
+void mysql_client_plugin_deinit()
+{
+ int i;
+ struct st_client_plugin_int *p;
+
+ if (!initialized)
+ return;
+
+ for (i=0; i < MYSQL_CLIENT_MAX_PLUGINS; i++)
+ for (p= plugin_list[i]; p; p= p->next)
+ {
+ if (p->plugin->deinit)
+ p->plugin->deinit();
+ if (p->dlhandle)
+ dlclose(p->dlhandle);
+ }
+
+ bzero(&plugin_list, sizeof(plugin_list));
+ initialized= 0;
+ free_root(&mem_root, MYF(0));
+ pthread_mutex_destroy(&LOCK_load_client_plugin);
+}
+
+/************* public facing functions, for client consumption *********/
+
+/* see <mysql/client_plugin.h> for a full description */
+struct st_mysql_client_plugin *
+mysql_client_register_plugin(MYSQL *mysql,
+ struct st_mysql_client_plugin *plugin)
+{
+ if (is_not_initialized(mysql, plugin->name))
+ return NULL;
+
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ /* make sure the plugin wasn't loaded meanwhile */
+ if (find_plugin(plugin->name, plugin->type))
+ {
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
+ unknown_sqlstate, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
+ plugin->name, "it is already loaded");
+ plugin= NULL;
+ }
+ else
+ plugin= add_plugin(mysql, plugin, 0, 0, 0);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+ return plugin;
+}
+
+
+/* see <mysql/client_plugin.h> for a full description */
+struct st_mysql_client_plugin *
+mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
+ int argc, va_list args)
+{
+ const char *errmsg;
+ char dlpath[FN_REFLEN+1];
+ void *sym, *dlhandle;
+ struct st_mysql_client_plugin *plugin;
+
+ if (is_not_initialized(mysql, name))
+ return NULL;
+
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ /* make sure the plugin wasn't loaded meanwhile */
+ if (type >= 0 && find_plugin(name, type))
+ {
+ errmsg= "it is already loaded";
+ goto err;
+ }
+
+ /* Compile dll path */
+ strxnmov(dlpath, sizeof(dlpath) - 1,
+ mysql->options.extension && mysql->options.extension->plugin_dir ?
+ mysql->options.extension->plugin_dir : PLUGINDIR, "/",
+ name, SO_EXT, NullS);
+
+ /* Open new dll handle */
+ if (!(dlhandle= dlopen(dlpath, RTLD_NOW)))
+ {
+ errmsg= dlerror();
+ goto err;
+ }
+
+ if (!(sym= dlsym(dlhandle, plugin_declarations_sym)))
+ {
+ errmsg= "not a plugin";
+ dlclose(dlhandle);
+ goto err;
+ }
+
+ plugin= (struct st_mysql_client_plugin*)sym;
+
+ if (type >=0 && type != plugin->type)
+ {
+ errmsg= "type mismatch";
+ goto err;
+ }
+
+ if (strcmp(name, plugin->name))
+ {
+ errmsg= "name mismatch";
+ goto err;
+ }
+
+ if (type < 0 && find_plugin(name, plugin->type))
+ {
+ errmsg= "it is already loaded";
+ goto err;
+ }
+
+ plugin= add_plugin(mysql, plugin, dlhandle, argc, args);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+
+ return plugin;
+
+err:
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate,
+ ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, errmsg);
+ return NULL;
+}
+
+
+/* see <mysql/client_plugin.h> for a full description */
+struct st_mysql_client_plugin *
+mysql_load_plugin(MYSQL *mysql, const char *name, int type, int argc, ...)
+{
+ struct st_mysql_client_plugin *p;
+ va_list args;
+ va_start(args, argc);
+ p= mysql_load_plugin_v(mysql, name, type, argc, args);
+ va_end(args);
+ return p;
+}
+
+
+/* see <mysql/client_plugin.h> for a full description */
+struct st_mysql_client_plugin *
+mysql_client_find_plugin(MYSQL *mysql, const char *name, int type)
+{
+ struct st_mysql_client_plugin *p;
+
+ if (is_not_initialized(mysql, name))
+ return NULL;
+
+ if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS)
+ {
+ set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate,
+ ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name,
+ "invalid type");
+ }
+
+ if ((p= find_plugin(name, type)))
+ return p;
+
+ /* not found, load it */
+ return mysql_load_plugin(mysql, name, type, 0);
+}
+
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2010-03-03 14:44:14 +0000
+++ b/sql/CMakeLists.txt 2010-03-29 15:13:53 +0000
@@ -54,7 +54,7 @@ SET (SQL_SOURCE
log_event.cc rpl_record.cc rpl_reporting.cc
log_event_old.cc rpl_record_old.cc
message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c
- mysqld.cc net_serv.cc
+ mysqld.cc net_serv.cc ../sql-common/client_plugin.c
nt_servc.cc nt_servc.h opt_range.cc opt_range.h opt_sum.cc
../sql-common/pack.c parse_file.cc password.c procedure.cc
protocol.cc records.cc repl_failsafe.cc rpl_filter.cc set_var.cc
=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am 2010-03-03 14:44:14 +0000
+++ b/sql/Makefile.am 2010-03-29 15:13:53 +0000
@@ -126,7 +126,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.
sql_servers.cc event_parse_data.cc \
opt_table_elimination.cc
-nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
+nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c client_plugin.c
libndb_la_CPPFLAGS= @ndbcluster_includes@
libndb_la_SOURCES= ha_ndbcluster.cc \
@@ -140,10 +140,10 @@ mysql_tzinfo_to_sql_SOURCES = tztime.cc
mysql_tzinfo_to_sql_CXXFLAGS= -DTZINFO2SQL
DEFS = -DMYSQL_SERVER \
- -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
- -DPLUGINDIR="\"$(pkgplugindir)\"" \
+ -DDEFAULT_MYSQL_HOME='"$(MYSQLBASEdir)"' \
+ -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \
+ -DSHAREDIR='"$(MYSQLSHAREdir)"' \
+ -DPLUGINDIR='"$(pkgplugindir)"' \
-DHAVE_EVENT_SCHEDULER \
@DEFS@
@@ -167,6 +167,8 @@ link_sources:
@LN_CP_F@ $(top_srcdir)/sql-common/pack.c pack.c
rm -f client.c
@LN_CP_F@ $(top_srcdir)/sql-common/client.c client.c
+ rm -f client_plugin.c
+ @LN_CP_F@ $(top_srcdir)/sql-common/client_plugin.c client_plugin.c
rm -f my_time.c
@LN_CP_F@ $(top_srcdir)/sql-common/my_time.c my_time.c
rm -f my_user.c
=== modified file 'sql/client_settings.h'
--- a/sql/client_settings.h 2009-08-13 20:07:20 +0000
+++ b/sql/client_settings.h 2010-03-29 15:13:53 +0000
@@ -15,6 +15,7 @@
#include <thr_alarm.h>
+#include <sql_common.h>
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \
CLIENT_SECURE_CONNECTION | CLIENT_TRANSACTIONS | \
@@ -31,7 +32,8 @@
#undef HAVE_SMEM
#undef _CUSTOMCONFIG_
-#define mysql_server_init(a,b,c) 0
+#define mysql_server_init(a,b,c) mysql_client_plugin_init()
+#define mysql_server_end() mysql_client_plugin_deinit()
#ifdef HAVE_REPLICATION
C_MODE_START
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2010-01-06 21:27:53 +0000
+++ b/sql/ha_ndbcluster.cc 2010-03-29 15:13:53 +0000
@@ -9185,7 +9185,7 @@ pthread_handler_t ndb_util_thread_func(v
thd->client_capabilities = 0;
my_net_init(&thd->net, 0);
thd->main_security_ctx.master_access= ~0;
- thd->main_security_ctx.priv_user = 0;
+ thd->main_security_ctx.priv_user[0] = 0;
CHARSET_INFO *charset_connection;
charset_connection= get_charset_by_csname("utf8",
=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc 2009-12-03 11:19:05 +0000
+++ b/sql/ha_ndbcluster_binlog.cc 2010-03-29 15:13:53 +0000
@@ -3681,7 +3681,7 @@ pthread_handler_t ndb_binlog_thread_func
thd->client_capabilities= 0;
my_net_init(&thd->net, 0);
thd->main_security_ctx.master_access= ~0;
- thd->main_security_ctx.priv_user= 0;
+ thd->main_security_ctx.priv_user[0]= 0;
/*
Set up ndb binlog
=== modified file 'sql/lex.h'
--- a/sql/lex.h 2009-11-12 04:31:28 +0000
+++ b/sql/lex.h 2010-03-29 15:13:53 +0000
@@ -590,6 +590,7 @@ static SYMBOL symbols[] = {
{ "VARCHARACTER", SYM(VARCHAR)},
{ "VARIABLES", SYM(VARIABLES)},
{ "VARYING", SYM(VARYING)},
+ { "VIA", SYM(VIA_SYM)},
{ "VIEW", SYM(VIEW_SYM)},
{ "VIRTUAL", SYM(VIRTUAL_SYM)},
{ "WAIT", SYM(WAIT_SYM)},
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2010-03-15 11:51:23 +0000
+++ b/sql/mysql_priv.h 2010-03-29 15:13:53 +0000
@@ -1067,9 +1067,6 @@ int write_bin_log(THD *thd, bool clear_e
char const *query, ulong query_length);
/* sql_connect.cc */
-int check_user(THD *thd, enum enum_server_command command,
- const char *passwd, uint passwd_len, const char *db,
- bool check_count);
pthread_handler_t handle_one_connection(void *arg);
bool init_new_connection_handler_thread();
void reset_mqh(LEX_USER *lu, bool get_them);
@@ -1082,6 +1079,9 @@ bool login_connection(THD *thd);
void end_connection(THD *thd);
void prepare_new_connection_state(THD* thd);
void update_global_user_stats(THD* thd, bool create_user, time_t now);
+int get_or_create_user_conn(THD *thd, const char *user,
+ const char *host, USER_RESOURCES *mqh);
+int check_for_max_user_connections(THD *thd, USER_CONN *uc);
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-29 21:16:12 +0000
+++ b/sql/mysqld.cc 2010-03-31 23:03:57 +0000
@@ -22,6 +22,7 @@
#include "rpl_mi.h"
#include "sql_repl.h"
#include "rpl_filter.h"
+#include "client_settings.h"
#include "repl_failsafe.h"
#include <my_stacktrace.h>
#include "mysqld_suffix.h"
@@ -1394,6 +1395,7 @@ void clean_up(bool print_message)
if (print_message && errmesg && server_start_time)
sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
thread_scheduler.end();
+ mysql_library_end();
finish_client_errs();
my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST),
MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
@@ -3489,6 +3491,7 @@ static int init_common_variables(const c
if (init_errmessage()) /* Read error messages from file */
return 1;
init_client_errs();
+ mysql_library_init(never,never,never); /* for replication */
lex_init();
if (item_create_init())
return 1;
=== modified file 'sql/password.c'
--- a/sql/password.c 2009-09-07 20:50:10 +0000
+++ b/sql/password.c 2010-03-29 15:13:53 +0000
@@ -193,13 +193,13 @@ void scramble_323(char *to, const char *
*/
my_bool
-check_scramble_323(const char *scrambled, const char *message,
+check_scramble_323(const unsigned char *scrambled, const char *message,
ulong *hash_pass)
{
struct my_rnd_struct rand_st;
ulong hash_message[2];
- char buff[16],*to,extra; /* Big enough for check */
- const char *pos;
+ uchar buff[16],*to,extra; /* Big enough for check */
+ const uchar *pos;
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
my_rnd_init(&rand_st,hash_pass[0] ^ hash_message[0],
@@ -214,7 +214,7 @@ check_scramble_323(const char *scrambled
to=buff;
while (*scrambled)
{
- if (*scrambled++ != (char) (*to++ ^ extra))
+ if (*scrambled++ != (uchar) (*to++ ^ extra))
return 1; /* Wrong password */
}
return 0;
@@ -481,7 +481,7 @@ scramble(char *to, const char *message,
*/
my_bool
-check_scramble(const char *scramble_arg, const char *message,
+check_scramble(const uchar *scramble_arg, const char *message,
const uint8 *hash_stage2)
{
SHA1_CONTEXT sha1_context;
@@ -494,7 +494,7 @@ check_scramble(const char *scramble_arg,
mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
mysql_sha1_result(&sha1_context, buf);
/* encrypt scramble */
- my_crypt((char *) buf, buf, (const uchar *) scramble_arg, SCRAMBLE_LENGTH);
+ my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH);
/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
mysql_sha1_reset(&sha1_context);
mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
=== modified file 'sql/protocol.cc'
--- a/sql/protocol.cc 2009-12-03 11:19:05 +0000
+++ b/sql/protocol.cc 2010-03-29 15:13:53 +0000
@@ -341,24 +341,6 @@ static bool write_eof_packet(THD *thd, N
}
/**
- Please client to send scrambled_password in old format.
-
- @param thd thread handle
-
- @retval
- 0 ok
- @retval
- !0 error
-*/
-
-bool send_old_password_request(THD *thd)
-{
- NET *net= &thd->net;
- return my_net_write(net, eof_buff, 1) || net_flush(net);
-}
-
-
-/**
@param thd Thread handler
@param sql_errno The error code to send
@param err A pointer to the error message
=== modified file 'sql/protocol.h'
--- a/sql/protocol.h 2009-12-03 11:19:05 +0000
+++ b/sql/protocol.h 2010-03-29 15:13:53 +0000
@@ -177,7 +177,6 @@ public:
void send_warning(THD *thd, uint sql_errno, const char *err=0);
bool net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
void net_end_statement(THD *thd);
-bool send_old_password_request(THD *thd);
uchar *net_store_data(uchar *to,const uchar *from, size_t length);
uchar *net_store_data(uchar *to,int32 from);
uchar *net_store_data(uchar *to,longlong from);
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_acl.cc 2010-03-31 18:37:45 +0000
@@ -30,6 +30,8 @@
#include <stdarg.h>
#include "sp_head.h"
#include "sp.h"
+#include <sql_common.h>
+#include <mysql/plugin_auth.h>
static const
TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
@@ -148,6 +150,87 @@ TABLE_FIELD_TYPE mysql_db_table_fields[M
const TABLE_FIELD_DEF
mysql_db_table_def= {MYSQL_DB_FIELD_COUNT, mysql_db_table_fields};
+static LEX_STRING native_password_plugin_name= {
+ C_STRING_WITH_LEN("mysql_native_password")
+};
+
+static LEX_STRING old_password_plugin_name= {
+ C_STRING_WITH_LEN("mysql_old_password")
+};
+
+/// @todo make it configurable
+LEX_STRING *default_auth_plugin_name= &native_password_plugin_name;
+
+static plugin_ref native_password_plugin;
+#ifndef EMBEDDED_LIBRARY
+static plugin_ref old_password_plugin;
+#endif
+
+/* Classes */
+
+struct acl_host_and_ip
+{
+ char *hostname;
+ long ip,ip_mask; // Used with masked ip:s
+};
+
+class ACL_ACCESS {
+public:
+ ulong sort;
+ ulong access;
+};
+
+/* ACL_HOST is used if no host is specified */
+
+class ACL_HOST :public ACL_ACCESS
+{
+public:
+ acl_host_and_ip host;
+ char *db;
+};
+
+class ACL_USER :public ACL_ACCESS
+{
+public:
+ acl_host_and_ip host;
+ uint hostname_length;
+ USER_RESOURCES user_resource;
+ char *user;
+ uint8 salt[SCRAMBLE_LENGTH+1]; // scrambled password in binary form
+ uint8 salt_len; // 0 - no password, 4 - 3.20, 8 - 4.0, 20 - 4.1.1
+ enum SSL_type ssl_type;
+ const char *ssl_cipher, *x509_issuer, *x509_subject;
+ LEX_STRING plugin;
+ LEX_STRING auth_string;
+
+ ACL_USER *copy(MEM_ROOT *root)
+ {
+ ACL_USER *dst= (ACL_USER *)alloc_root(root, sizeof(ACL_USER));
+ if (!dst)
+ return 0;
+ *dst= *this;
+ dst->user= safe_strdup_root(root, user);
+ dst->ssl_cipher= safe_strdup_root(root, ssl_cipher);
+ dst->x509_issuer= safe_strdup_root(root, x509_issuer);
+ dst->x509_subject= safe_strdup_root(root, x509_subject);
+ if (plugin.str == native_password_plugin_name.str ||
+ plugin.str == old_password_plugin_name.str)
+ dst->plugin= plugin;
+ else
+ dst->plugin.str= strmake_root(root, plugin.str, plugin.length);
+ dst->auth_string.str = safe_strdup_root(root, auth_string.str);
+ dst->host.hostname= safe_strdup_root(root, host.hostname);
+ return dst;
+ }
+};
+
+class ACL_DB :public ACL_ACCESS
+{
+public:
+ acl_host_and_ip host;
+ char *user,*db;
+};
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#define FIRST_NON_YN_FIELD 26
@@ -171,6 +254,24 @@ static uchar* acl_entry_get_key(acl_entr
#define IP_ADDR_STRLEN (3+1+3+1+3+1+3)
#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1)
+#if defined(HAVE_OPENSSL)
+/*
+ Without SSL the handshake consists of one packet. This packet
+ has both client capabilites and scrambled password.
+ With SSL the handshake might consist of two packets. If the first
+ packet (client capabilities) has CLIENT_SSL flag set, we have to
+ switch to SSL and read the second packet. The scrambled password
+ is in the second packet and client_capabilites field will be ignored.
+ Maybe it is better to accept flags other than CLIENT_SSL from the
+ second packet?
+*/
+#define SSL_HANDSHAKE_SIZE 2
+#define NORMAL_HANDSHAKE_SIZE 6
+#define MIN_HANDSHAKE_SIZE 2
+#else
+#define MIN_HANDSHAKE_SIZE 6
+#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
+
static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs;
static MEM_ROOT mem, memex;
static bool initialized=0;
@@ -265,6 +366,19 @@ my_bool acl_init(bool dont_read_acl_tabl
(hash_get_key) acl_entry_get_key,
(hash_free_key) free,
&my_charset_utf8_bin);
+
+ /*
+ cache built-in native authentication plugins,
+ to avoid hash searches and a global mutex lock on every connect
+ */
+ native_password_plugin= my_plugin_lock_by_name(0,
+ &native_password_plugin_name, MYSQL_AUTHENTICATION_PLUGIN);
+ old_password_plugin= my_plugin_lock_by_name(0,
+ &old_password_plugin_name, MYSQL_AUTHENTICATION_PLUGIN);
+
+ if (!native_password_plugin || !old_password_plugin)
+ DBUG_RETURN(1);
+
if (dont_read_acl_tables)
{
DBUG_RETURN(0); /* purecov: tested */
@@ -422,6 +536,7 @@ static my_bool acl_load(THD *thd, TABLE_
while (!(read_record_info.read_record(&read_record_info)))
{
ACL_USER user;
+ bzero(&user, sizeof(user));
update_hostname(&user.host, get_field(&mem, table->field[0]));
user.user= get_field(&mem, table->field[1]);
if (check_no_resolve && hostname_requires_resolving(user.host.hostname))
@@ -433,27 +548,34 @@ static my_bool acl_load(THD *thd, TABLE_
continue;
}
- const char *password= get_field(thd->mem_root, table->field[2]);
+ char *password= get_field(thd->mem_root, table->field[2]);
uint password_len= password ? strlen(password) : 0;
+ user.auth_string.str= password ? password : const_cast<char*>("");
+ user.auth_string.length= password_len;
set_user_salt(&user, password, password_len);
- if (user.salt_len == 0 && password_len != 0)
- {
- switch (password_len) {
- case 45: /* 4.1: to be removed */
- sql_print_warning("Found 4.1 style password for user '%s@%s'. "
- "Ignoring user. "
- "You should change password for this user.",
- user.user ? user.user : "",
- user.host.hostname ? user.host.hostname : "");
- break;
- default:
- sql_print_warning("Found invalid password for user: '%s@%s'; "
- "Ignoring user", user.user ? user.user : "",
- user.host.hostname ? user.host.hostname : "");
- break;
- }
+
+ switch (password_len) {
+ case 0: /* no password */
+ case SCRAMBLED_PASSWORD_CHAR_LENGTH:
+ user.plugin= native_password_plugin_name;
+ break;
+ case SCRAMBLED_PASSWORD_CHAR_LENGTH_323:
+ user.plugin= old_password_plugin_name;
+ break;
+ case 45: /* 4.1: to be removed */
+ sql_print_warning("Found 4.1.0 style password for user '%s@%s'. "
+ "Ignoring user. "
+ "You should change password for this user.",
+ user.user ? user.user : "",
+ user.host.hostname ? user.host.hostname : "");
+ continue;
+ default:
+ sql_print_warning("Found invalid password for user: '%s@%s'; "
+ "Ignoring user", user.user ? user.user : "",
+ user.host.hostname ? user.host.hostname : "");
+ continue;
}
- else // password is correct
+
{
uint next_field;
user.access= get_access(table,3,&next_field) & GLOBAL_ACLS;
@@ -530,13 +652,43 @@ static my_bool acl_load(THD *thd, TABLE_
ptr= get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
}
- else
- user.user_resource.user_conn= 0;
+
+ if (table->s->fields >= 41)
+ {
+ /* We may have plugin & auth_String fields */
+ char *tmpstr= get_field(&mem, table->field[next_field++]);
+ if (tmpstr)
+ {
+ if (user.auth_string.length)
+ {
+ sql_print_warning("'user' entry '%s@%s' has both a password "
+ "and an authentication plugin specified. The "
+ "password will be ignored.",
+ user.user ? user.user : "",
+ user.host.hostname ? user.host.hostname : "");
+ }
+ if (my_strcasecmp(system_charset_info, tmpstr,
+ native_password_plugin_name.str) == 0)
+ user.plugin= native_password_plugin_name;
+ else
+ if (my_strcasecmp(system_charset_info, tmpstr,
+ old_password_plugin_name.str) == 0)
+ user.plugin= old_password_plugin_name;
+ else
+ {
+ user.plugin.str= tmpstr;
+ user.plugin.length= strlen(tmpstr);
+ }
+ user.auth_string.str= get_field(&mem, table->field[next_field++]);
+ if (!user.auth_string.str)
+ user.auth_string.str= const_cast<char*>("");
+ user.auth_string.length= strlen(user.auth_string.str);
+ }
+ }
}
else
{
user.ssl_type=SSL_TYPE_NONE;
- bzero((char *)&(user.user_resource),sizeof(user.user_resource));
#ifndef TO_BE_REMOVED
if (table->s->fields <= 13)
{ // Without grant
@@ -639,6 +791,8 @@ void acl_free(bool end)
delete_dynamic(&acl_dbs);
delete_dynamic(&acl_wild_hosts);
hash_free(&acl_check_hosts);
+ plugin_unlock(0, native_password_plugin);
+ plugin_unlock(0, old_password_plugin);
if (!end)
acl_cache->clear(1); /* purecov: inspected */
else
@@ -841,246 +995,10 @@ static int acl_compare(ACL_ACCESS *a,ACL
/*
- Seek ACL entry for a user, check password, SSL cypher, and if
- everything is OK, update THD user data and USER_RESOURCES struct.
-
- IMPLEMENTATION
- This function does not check if the user has any sensible privileges:
- only user's existence and validity is checked.
- Note, that entire operation is protected by acl_cache_lock.
+ Gets user credentials without authentication and resource limit checks.
SYNOPSIS
acl_getroot()
- thd thread handle. If all checks are OK,
- thd->security_ctx->priv_user/master_access are updated.
- thd->security_ctx->host/ip/user are used for checks.
- mqh user resources; on success mqh is reset, else
- unchanged
- passwd scrambled & crypted password, received from client
- (to check): thd->scramble or thd->scramble_323 is
- used to decrypt passwd, so they must contain
- original random string,
- passwd_len length of passwd, must be one of 0, 8,
- SCRAMBLE_LENGTH_323, SCRAMBLE_LENGTH
- 'thd' and 'mqh' are updated on success; other params are IN.
-
- RETURN VALUE
- 0 success: thd->priv_user, thd->priv_host, thd->master_access, mqh are
- updated
- 1 user not found or authentication failure
- 2 user found, has long (4.1.1) salt, but passwd is in old (3.23) format.
- -1 user found, has short (3.23) salt, but passwd is in new (4.1.1) format.
-*/
-
-int acl_getroot(THD *thd, USER_RESOURCES *mqh,
- const char *passwd, uint passwd_len)
-{
- ulong user_access= NO_ACCESS;
- int res= 1;
- ACL_USER *acl_user= 0;
- Security_context *sctx= thd->security_ctx;
- DBUG_ENTER("acl_getroot");
-
- if (!initialized)
- {
- /*
- here if mysqld's been started with --skip-grant-tables option.
- */
- sctx->skip_grants();
- bzero((char*) mqh, sizeof(*mqh));
- DBUG_RETURN(0);
- }
-
- VOID(pthread_mutex_lock(&acl_cache->lock));
-
- /*
- Find acl entry in user database. Note, that find_acl_user is not the same,
- because it doesn't take into account the case when user is not empty,
- but acl_user->user is empty
- */
-
- for (uint i=0 ; i < acl_users.elements ; i++)
- {
- ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
- if (!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user))
- {
- if (compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip))
- {
- /* check password: it should be empty or valid */
- if (passwd_len == acl_user_tmp->salt_len)
- {
- if (acl_user_tmp->salt_len == 0 ||
- (acl_user_tmp->salt_len == SCRAMBLE_LENGTH ?
- check_scramble(passwd, thd->scramble, acl_user_tmp->salt) :
- check_scramble_323(passwd, thd->scramble,
- (ulong *) acl_user_tmp->salt)) == 0)
- {
- acl_user= acl_user_tmp;
- res= 0;
- }
- }
- else if (passwd_len == SCRAMBLE_LENGTH &&
- acl_user_tmp->salt_len == SCRAMBLE_LENGTH_323)
- res= -1;
- else if (passwd_len == SCRAMBLE_LENGTH_323 &&
- acl_user_tmp->salt_len == SCRAMBLE_LENGTH)
- res= 2;
- /* linear search complete: */
- break;
- }
- }
- }
- /*
- This was moved to separate tree because of heavy HAVE_OPENSSL case.
- If acl_user is not null, res is 0.
- */
-
- if (acl_user)
- {
- /* OK. User found and password checked continue validation */
-#ifdef HAVE_OPENSSL
- Vio *vio=thd->net.vio;
- SSL *ssl= (SSL*) vio->ssl_arg;
- X509 *cert;
-#endif
-
- /*
- At this point we know that user is allowed to connect
- from given host by given username/password pair. Now
- we check if SSL is required, if user is using SSL and
- if X509 certificate attributes are OK
- */
- switch (acl_user->ssl_type) {
- case SSL_TYPE_NOT_SPECIFIED: // Impossible
- case SSL_TYPE_NONE: // SSL is not required
- user_access= acl_user->access;
- break;
-#ifdef HAVE_OPENSSL
- case SSL_TYPE_ANY: // Any kind of SSL is ok
- if (vio_type(vio) == VIO_TYPE_SSL)
- user_access= acl_user->access;
- break;
- case SSL_TYPE_X509: /* Client should have any valid certificate. */
- /*
- Connections with non-valid certificates are dropped already
- in sslaccept() anyway, so we do not check validity here.
-
- We need to check for absence of SSL because without SSL
- we should reject connection.
- */
- if (vio_type(vio) == VIO_TYPE_SSL &&
- SSL_get_verify_result(ssl) == X509_V_OK &&
- (cert= SSL_get_peer_certificate(ssl)))
- {
- user_access= acl_user->access;
- X509_free(cert);
- }
- break;
- case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */
- /*
- We do not check for absence of SSL because without SSL it does
- not pass all checks here anyway.
- If cipher name is specified, we compare it to actual cipher in
- use.
- */
- if (vio_type(vio) != VIO_TYPE_SSL ||
- SSL_get_verify_result(ssl) != X509_V_OK)
- break;
- if (acl_user->ssl_cipher)
- {
- DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'",
- acl_user->ssl_cipher,SSL_get_cipher(ssl)));
- if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(ssl)))
- user_access= acl_user->access;
- else
- {
- if (global_system_variables.log_warnings)
- sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'",
- acl_user->ssl_cipher,
- SSL_get_cipher(ssl));
- break;
- }
- }
- /* Prepare certificate (if exists) */
- DBUG_PRINT("info",("checkpoint 1"));
- if (!(cert= SSL_get_peer_certificate(ssl)))
- {
- user_access=NO_ACCESS;
- break;
- }
- DBUG_PRINT("info",("checkpoint 2"));
- /* If X509 issuer is specified, we check it... */
- if (acl_user->x509_issuer)
- {
- DBUG_PRINT("info",("checkpoint 3"));
- char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
- DBUG_PRINT("info",("comparing issuers: '%s' and '%s'",
- acl_user->x509_issuer, ptr));
- if (strcmp(acl_user->x509_issuer, ptr))
- {
- if (global_system_variables.log_warnings)
- sql_print_information("X509 issuer mismatch: should be '%s' "
- "but is '%s'", acl_user->x509_issuer, ptr);
- free(ptr);
- X509_free(cert);
- user_access=NO_ACCESS;
- break;
- }
- user_access= acl_user->access;
- free(ptr);
- }
- DBUG_PRINT("info",("checkpoint 4"));
- /* X509 subject is specified, we check it .. */
- if (acl_user->x509_subject)
- {
- char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
- DBUG_PRINT("info",("comparing subjects: '%s' and '%s'",
- acl_user->x509_subject, ptr));
- if (strcmp(acl_user->x509_subject,ptr))
- {
- if (global_system_variables.log_warnings)
- sql_print_information("X509 subject mismatch: should be '%s' but is '%s'",
- acl_user->x509_subject, ptr);
- free(ptr);
- X509_free(cert);
- user_access=NO_ACCESS;
- break;
- }
- user_access= acl_user->access;
- free(ptr);
- }
- /* Deallocate the X509 certificate. */
- X509_free(cert);
- break;
-#else /* HAVE_OPENSSL */
- default:
- /*
- If we don't have SSL but SSL is required for this user the
- authentication should fail.
- */
- break;
-#endif /* HAVE_OPENSSL */
- }
- sctx->master_access= user_access;
- sctx->priv_user= acl_user->user ? sctx->user : (char *) "";
- *mqh= acl_user->user_resource;
-
- if (acl_user->host.hostname)
- strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1);
- else
- *sctx->priv_host= 0;
- }
- VOID(pthread_mutex_unlock(&acl_cache->lock));
- DBUG_RETURN(res);
-}
-
-
-/*
- This is like acl_getroot() above, but it doesn't check password,
- and we don't care about the user resources.
-
- SYNOPSIS
- acl_getroot_no_password()
sctx Context which should be initialized
user user name
host host name
@@ -1092,13 +1010,13 @@ int acl_getroot(THD *thd, USER_RESOURCES
TRUE Error
*/
-bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
- char *ip, char *db)
+bool acl_getroot(Security_context *sctx, char *user, char *host,
+ char *ip, char *db)
{
int res= 1;
uint i;
ACL_USER *acl_user= 0;
- DBUG_ENTER("acl_getroot_no_password");
+ DBUG_ENTER("acl_getroot");
DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', db: '%s'",
(host ? host : "(NULL)"), (ip ? ip : "(NULL)"),
@@ -1121,8 +1039,7 @@ bool acl_getroot_no_password(Security_co
sctx->master_access= 0;
sctx->db_access= 0;
- sctx->priv_user= (char *) "";
- *sctx->priv_host= 0;
+ *sctx->priv_user= *sctx->priv_host= 0;
/*
Find acl entry in user database.
@@ -1164,7 +1081,11 @@ bool acl_getroot_no_password(Security_co
}
}
sctx->master_access= acl_user->access;
- sctx->priv_user= acl_user->user ? user : (char *) "";
+
+ if (acl_user->user)
+ strmake(sctx->priv_user, user, USERNAME_LENGTH);
+ else
+ *sctx->priv_user= 0;
if (acl_user->host.hostname)
strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1);
@@ -1190,7 +1111,9 @@ static void acl_update_user(const char *
const char *x509_issuer,
const char *x509_subject,
USER_RESOURCES *mqh,
- ulong privileges)
+ ulong privileges,
+ const LEX_STRING *plugin,
+ const LEX_STRING *auth)
{
safe_mutex_assert_owner(&acl_cache->lock);
@@ -1204,6 +1127,14 @@ static void acl_update_user(const char *
(acl_user->host.hostname &&
!my_strcasecmp(system_charset_info, host, acl_user->host.hostname)))
{
+ if (plugin->str[0])
+ {
+ acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length);
+ acl_user->plugin.length= plugin->length;
+ acl_user->auth_string.str= auth->str ?
+ strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
+ acl_user->auth_string.length= auth->length;
+ }
acl_user->access=privileges;
if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
acl_user->user_resource.questions=mqh->questions;
@@ -1240,7 +1171,9 @@ static void acl_insert_user(const char *
const char *x509_issuer,
const char *x509_subject,
USER_RESOURCES *mqh,
- ulong privileges)
+ ulong privileges,
+ const LEX_STRING *plugin,
+ const LEX_STRING *auth)
{
ACL_USER acl_user;
@@ -1248,6 +1181,22 @@ static void acl_insert_user(const char *
acl_user.user=*user ? strdup_root(&mem,user) : 0;
update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0);
+ if (plugin->str[0])
+ {
+ acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length);
+ acl_user.plugin.length= plugin->length;
+ acl_user.auth_string.str= auth->str ?
+ strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
+ acl_user.auth_string.length= auth->length;
+ }
+ else
+ {
+ acl_user.plugin= password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 ?
+ old_password_plugin_name : native_password_plugin_name;
+ acl_user.auth_string.str= strmake_root(&mem, password, password_len);
+ acl_user.auth_string.length= password_len;
+ }
+
acl_user.access=privileges;
acl_user.user_resource = *mqh;
acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user);
@@ -1966,6 +1915,15 @@ static int replace_user_table(THD *thd,
thd->security_ctx->user, thd->security_ctx->host_or_ip);
goto end;
}
+ else if (combo.plugin.str[0])
+ {
+ if (!plugin_is_ready(&combo.plugin, MYSQL_AUTHENTICATION_PLUGIN))
+ {
+ my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), combo.plugin.str);
+ goto end;
+ }
+ }
+
old_row_exists = 0;
restore_record(table,s->default_values);
table->field[0]->store(combo.host.str,combo.host.length,
@@ -1979,7 +1937,7 @@ static int replace_user_table(THD *thd,
{
old_row_exists = 1;
store_record(table,record[1]); // Save copy for update
- if (combo.password.str) // If password given
+ if (combo.password.str) // If password given
table->field[2]->store(password, password_len, system_charset_info);
else if (!rights && !revoke_grant &&
lex->ssl_type == SSL_TYPE_NOT_SPECIFIED &&
@@ -2060,7 +2018,17 @@ static int replace_user_table(THD *thd,
(mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS))
table->field[next_field+3]->store((longlong) mqh.user_conn, TRUE);
mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour;
+
+ next_field+=4;
+ if (table->s->fields >= 41 && combo.plugin.str[0])
+ {
+ table->field[next_field]->store(combo.plugin.str, combo.plugin.length,
+ system_charset_info);
+ table->field[next_field+1]->store(combo.auth.str, combo.auth.length,
+ system_charset_info);
+ }
}
+
if (old_row_exists)
{
/*
@@ -2104,7 +2072,9 @@ end:
lex->x509_issuer,
lex->x509_subject,
&lex->mqh,
- rights);
+ rights,
+ &combo.plugin,
+ &combo.auth);
else
acl_insert_user(combo.user.str, combo.host.str, password, password_len,
lex->ssl_type,
@@ -2112,7 +2082,9 @@ end:
lex->x509_issuer,
lex->x509_subject,
&lex->mqh,
- rights);
+ rights,
+ &combo.plugin,
+ &combo.auth);
}
DBUG_RETURN(error);
}
@@ -4445,14 +4417,14 @@ bool check_routine_level_acl(THD *thd, c
ulong get_table_grant(THD *thd, TABLE_LIST *table)
{
ulong privilege;
- Security_context *sctx= thd->security_ctx;
- const char *db = table->db ? table->db : thd->db;
GRANT_TABLE *grant_table;
rw_rdlock(&LOCK_grant);
#ifdef EMBEDDED_LIBRARY
grant_table= NULL;
#else
+ Security_context *sctx= thd->security_ctx;
+ const char *db = table->db ? table->db : thd->db;
grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user,
table->table_name, 0);
#endif
@@ -6328,38 +6300,44 @@ bool sp_grant_privileges(THD *thd, const
tables->db= (char*)sp_db;
tables->table_name= tables->alias= (char*)sp_name;
- combo->host.length= strlen(combo->host.str);
- combo->user.length= strlen(combo->user.str);
- combo->host.str= thd->strmake(combo->host.str,combo->host.length);
- combo->user.str= thd->strmake(combo->user.str,combo->user.length);
+ thd->make_lex_string(&combo->user,
+ combo->user.str, strlen(combo->user.str), 0);
+ thd->make_lex_string(&combo->host,
+ combo->host.str, strlen(combo->host.str), 0);
+ combo->password= empty_lex_str;
+ combo->plugin= empty_lex_str;
+ combo->auth= empty_lex_str;
- if(au && au->salt_len)
+ if(au)
{
- if (au->salt_len == SCRAMBLE_LENGTH)
- {
- make_password_from_salt(passwd_buff, au->salt);
- combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
- }
- else if (au->salt_len == SCRAMBLE_LENGTH_323)
+ if (au->salt_len)
{
- make_password_from_salt_323(passwd_buff, (ulong *) au->salt);
- combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
+ if (au->salt_len == SCRAMBLE_LENGTH)
+ {
+ make_password_from_salt(passwd_buff, au->salt);
+ combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
+ }
+ else if (au->salt_len == SCRAMBLE_LENGTH_323)
+ {
+ make_password_from_salt_323(passwd_buff, (ulong *) au->salt);
+ combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
+ }
+ else
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_PASSWD_LENGTH,
+ ER(ER_PASSWD_LENGTH), SCRAMBLED_PASSWORD_CHAR_LENGTH);
+ return TRUE;
+ }
+ combo->password.str= passwd_buff;
}
- else
+
+ if (au->plugin.str != native_password_plugin_name.str &&
+ au->plugin.str != old_password_plugin_name.str)
{
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_PASSWD_LENGTH,
- ER(ER_PASSWD_LENGTH),
- SCRAMBLED_PASSWORD_CHAR_LENGTH);
- return TRUE;
+ combo->plugin= au->plugin;
+ combo->auth= au->auth_string;
}
- combo->password.str= passwd_buff;
- }
- else
- {
- combo->password.str= (char*)"";
- combo->password.length= 0;
}
if (user_list.push_back(combo))
@@ -6853,3 +6831,1429 @@ bool check_routine_level_acl(THD *thd, c
}
#endif
+
+/****************************************************************************
+ AUTHENTICATION CODE
+ including initial connect handshake, invoking appropriate plugins,
+ client-server plugin negotiation, COM_CHANGE_USER, and native
+ MySQL authentication plugins.
+****************************************************************************/
+
+/* few defines to have less ifdef's in the code below */
+#ifdef EMBEDDED_LIBRARY
+#undef HAVE_OPENSSL
+#ifdef NO_EMBEDDED_ACCESS_CHECKS
+#define initialized 0
+#define decrease_user_connections(X) /* nothing */
+#define check_for_max_user_connections(X,Y) 0
+#endif
+#endif
+#ifndef HAVE_OPENSSL
+#define ssl_acceptor_fd 0
+#define sslaccept(A,B,C,D) 1
+#define NORMAL_HANDSHAKE_SIZE 6
+#endif
+
+/**
+ The internal version of what plugins know as MYSQL_PLUGIN_VIO,
+ basically the context of the authentication session
+*/
+struct MPVIO_EXT : public MYSQL_PLUGIN_VIO
+{
+ MYSQL_SERVER_AUTH_INFO auth_info;
+ THD *thd;
+ ACL_USER *acl_user; ///< a copy, independent from acl_users array
+ plugin_ref plugin; ///< what plugin we're under
+ LEX_STRING db; ///< db name from the handshake packet
+ /** when restarting a plugin this caches the last client reply */
+ struct {
+ char *plugin, *pkt; ///< pointers into NET::buff
+ uint pkt_len;
+ } cached_client_reply;
+ /** this caches the first plugin packet for restart request on the client */
+ struct {
+ char *pkt;
+ uint pkt_len;
+ } cached_server_packet;
+ int packets_read, packets_written; ///< counters for send/received packets
+ uint connect_errors; ///< if there were connect errors for this host
+ /** when plugin returns a failure this tells us what really happened */
+ enum { SUCCESS, FAILURE, RESTART } status;
+};
+
+
+/**
+ a helper function to report an access denied error in all the proper places
+*/
+
+static void login_failed_error(THD *thd, bool passwd_used)
+{
+ my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
+ passwd_used ? ER(ER_YES) : ER(ER_NO));
+ general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
+ passwd_used ? ER(ER_YES) : ER(ER_NO));
+ status_var_increment(thd->status_var.access_denied_errors);
+ /*
+ Log access denied messages to the error log when log-warnings = 2
+ so that the overhead of the general query log is not required to track
+ failed connections.
+ */
+ if (global_system_variables.log_warnings > 1)
+ {
+ sql_print_warning(ER(ER_ACCESS_DENIED_ERROR),
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
+ passwd_used ? ER(ER_YES) : ER(ER_NO));
+ }
+}
+
+
+/**
+ sends a server handshake initialization packet, the very first packet
+ after the connection was established
+
+ Packet format:
+
+ Bytes Content
+ ----- ----
+ 1 protocol version (always 10)
+ n server version string, \0-terminated
+ 4 thread id
+ 8 first 8 bytes of the plugin provided data (scramble)
+ 1 \0 byte, terminating the first part of a scramble
+ 2 server capabilities (two lower bytes)
+ 1 server character set
+ 2 server status
+ 2 server capabilities (two upper bytes)
+ 1 length of the scramble
+ 10 reserved, always 0
+ n rest of the plugin provided data (at least 12 bytes)
+ 1 \0 byte, terminating the second part of a scramble
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
+ const char *data, uint data_len)
+{
+ DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
+ DBUG_ASSERT(data_len <= 255);
+
+ THD *thd= mpvio->thd;
+ char *buff= (char *)my_alloca(1 + SERVER_VERSION_LENGTH + 1 + data_len + 64);
+ char scramble_buf[SCRAMBLE_LENGTH];
+ char *end= buff;
+
+ *end++= protocol_version;
+
+ thd->client_capabilities= CLIENT_BASIC_FLAGS;
+
+ if (data_len)
+ {
+ mpvio->cached_server_packet.pkt= (char*)thd->memdup(data, data_len);
+ mpvio->cached_server_packet.pkt_len= data_len;
+ }
+
+ if (data_len < SCRAMBLE_LENGTH)
+ {
+ if (data_len)
+ { /*
+ the first packet *must* have at least 20 bytes of a scramble.
+ if a plugin provided less, we pad it to 20 with zeros
+ */
+ memcpy(scramble_buf, data, data_len);
+ bzero(scramble_buf+data_len, SCRAMBLE_LENGTH-data_len);
+ data= scramble_buf;
+ }
+ else
+ {
+ /*
+ if the default plugin does not provide the data for the scramble at
+ all, we generate a scramble internally anyway, just in case the
+ user account (that will be known only later) uses a
+ native_password_plugin (which needs a scramble). If we don't send a
+ scramble now - wasting 20 bytes in the packet -
+ native_password_plugin will have to send it in a separate packet,
+ adding one more round trip.
+ */
+ create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+ data= thd->scramble;
+ }
+ data_len= SCRAMBLE_LENGTH;
+ }
+
+ if (opt_using_transactions)
+ thd->client_capabilities|= CLIENT_TRANSACTIONS;
+
+ thd->client_capabilities|= CAN_CLIENT_COMPRESS;
+
+ if (ssl_acceptor_fd)
+ {
+ thd->client_capabilities |= CLIENT_SSL;
+ thd->client_capabilities |= CLIENT_SSL_VERIFY_SERVER_CERT;
+ }
+
+ end= strnmov(end, server_version, SERVER_VERSION_LENGTH) + 1;
+ int4store((uchar*) end, mpvio->thd->thread_id);
+ end+= 4;
+
+ /*
+ Old clients does not understand long scrambles, but can ignore packet
+ tail: that's why first part of the scramble is placed here, and second
+ part at the end of packet.
+ */
+ end= (char*)memcpy(end, data, SCRAMBLE_LENGTH_323);
+ end+= SCRAMBLE_LENGTH_323;
+ *end++= 0;
+
+ int2store(end, thd->client_capabilities);
+ /* write server characteristics: up to 16 bytes allowed */
+ end[2]=(char) default_charset_info->number;
+ int2store(end+3, mpvio->thd->server_status);
+ int2store(end+5, thd->client_capabilities >> 16);
+ end[7]= data_len;
+ bzero(end+8, 10);
+ end+= 18;
+ /* write scramble tail */
+ end= (char*)memcpy(end, data + SCRAMBLE_LENGTH_323,
+ data_len - SCRAMBLE_LENGTH_323);
+ end+= data_len - SCRAMBLE_LENGTH_323;
+ end= strmake(end, plugin_name(mpvio->plugin)->str,
+ plugin_name(mpvio->plugin)->length);
+
+ int res= my_net_write(&mpvio->thd->net, (uchar*) buff, (size_t) (end-buff)) ||
+ net_flush(&mpvio->thd->net);
+ my_afree(buff);
+ return res;
+}
+
+static bool secure_auth(THD *thd)
+{
+ if (!opt_secure_auth)
+ return 0;
+
+ /*
+ If the server is running in secure auth mode, short scrambles are
+ forbidden. Extra juggling to report the same error as the old code.
+ */
+ if (thd->client_capabilities & CLIENT_PROTOCOL_41)
+ {
+ my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
+ thd->security_ctx->user,
+ thd->security_ctx->host_or_ip);
+ general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
+ thd->security_ctx->user,
+ thd->security_ctx->host_or_ip);
+ }
+ else
+ {
+ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
+ general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ }
+ return 1;
+}
+
+/**
+ sends a "change plugin" packet, requesting a client to restart authentication
+ using a different authentication plugin
+
+ Packet format:
+
+ Bytes Content
+ ----- ----
+ 1 byte with the value 254
+ n client plugin to use, \0-terminated
+ n plugin provided data
+
+ In a special case of switching from native_password_plugin to
+ old_password_plugin, the packet contains only one - the first - byte,
+ plugin name is omitted, plugin data aren't needed as the scramble was
+ already sent. This one-byte packet is identical to the "use the short
+ scramble" packet in the protocol before plugins were introduced.
+
+ @retval 0 ok
+ @retval 1 error
+*/
+
+static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
+ const uchar *data, uint data_len)
+{
+ DBUG_ASSERT(mpvio->packets_written == 1);
+ DBUG_ASSERT(mpvio->packets_read == 1);
+ NET *net= &mpvio->thd->net;
+ static uchar switch_plugin_request_buf[]= { 254 };
+
+
+ mpvio->status= MPVIO_EXT::FAILURE; // the status is no longer RESTART
+
+ const char *client_auth_plugin=
+ ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
+
+ DBUG_ASSERT(client_auth_plugin);
+
+ /*
+ we send an old "short 4.0 scramble request", if we need to request a
+ client to use 4.0 auth plugin (short scramble) and the scramble was
+ already sent to the client
+
+ below, cached_client_reply.plugin is the plugin name that client has used,
+ client_auth_plugin is derived from mysql.user table, for the given
+ user account, it's the plugin that the client need to use to login.
+ */
+ bool switch_from_long_to_short_scramble=
+ native_password_plugin_name.str == mpvio->cached_client_reply.plugin &&
+ client_auth_plugin == old_password_plugin_name.str;
+
+ if (switch_from_long_to_short_scramble)
+ return secure_auth(mpvio->thd) ||
+ my_net_write(net, switch_plugin_request_buf, 1) ||
+ net_flush(net);
+
+ /*
+ We never request a client to switch from a short to long scramble.
+ Plugin-aware clients can do that, but traditionally it meant to
+ ask an old 4.0 client to use the new 4.1 authentication protocol.
+ */
+ bool switch_from_short_to_long_scramble=
+ old_password_plugin_name.str == mpvio->cached_client_reply.plugin &&
+ client_auth_plugin == native_password_plugin_name.str;
+
+ if (switch_from_short_to_long_scramble)
+ {
+ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
+ general_log_print(mpvio->thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ return 1;
+ }
+
+ return net_write_command(net, switch_plugin_request_buf[0],
+ (uchar*)client_auth_plugin,
+ strlen(client_auth_plugin)+1,
+ (uchar*)data, data_len);
+}
+
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+/**
+ Finds acl entry in user database for authentication purposes.
+
+ Finds a user and copies it into mpvio. Reports an authentication
+ failure if a user is not found.
+
+ @note find_acl_user is not the same, because it doesn't take into
+ account the case when user is not empty, but acl_user->user is empty
+
+ @retval 0 found
+ @retval 1 not found
+*/
+
+static bool find_mpvio_user(MPVIO_EXT *mpvio, Security_context *sctx)
+{
+ DBUG_ASSERT(mpvio->acl_user == 0);
+
+ pthread_mutex_lock(&acl_cache->lock);
+ for (uint i=0 ; i < acl_users.elements ; i++)
+ {
+ ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
+ if ((!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user)) &&
+ compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip))
+ {
+ mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&acl_cache->lock);
+
+ if (!mpvio->acl_user)
+ {
+ login_failed_error(mpvio->thd, 0);
+ return 1;
+ }
+
+ /* user account requires non-default plugin and the client is too old */
+ if (mpvio->acl_user->plugin.str != native_password_plugin_name.str &&
+ mpvio->acl_user->plugin.str != old_password_plugin_name.str &&
+ !(mpvio->thd->client_capabilities & CLIENT_PLUGIN_AUTH))
+ {
+ DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ native_password_plugin_name.str));
+ DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ old_password_plugin_name.str));
+ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
+ general_log_print(mpvio->thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ return 1;
+ }
+
+ mpvio->auth_info.user_name= sctx->user;
+ mpvio->auth_info.auth_string= mpvio->acl_user->auth_string.str;
+ strmake(mpvio->auth_info.authenticated_as, mpvio->acl_user->user ?
+ mpvio->acl_user->user : "", USERNAME_LENGTH);
+
+ return 0;
+}
+#endif
+
+
+/* the packet format is described in send_change_user_packet() */
+static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
+{
+ THD *thd= mpvio->thd;
+ NET *net= &thd->net;
+ Security_context *sctx= thd->security_ctx;
+
+ char *user= (char*) net->read_pos;
+ char *end= user + packet_length;
+ /* Safe because there is always a trailing \0 at the end of the packet */
+ char *passwd= strend(user)+1;
+ uint user_len= passwd - user - 1;
+ char *db= passwd;
+ char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
+ char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
+ uint dummy_errors;
+
+ if (passwd >= end)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ return 1;
+ }
+
+ /*
+ Old clients send null-terminated string as password; new clients send
+ the size (1 byte) + string (not null-terminated). Hence in case of empty
+ password both send '\0'.
+
+ This strlen() can't be easily deleted without changing protocol.
+
+ Cast *passwd to an unsigned char, so that it doesn't extend the sign for
+ *passwd > 127 and become 2**32-127+ after casting to uint.
+ */
+ uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ (uchar)(*passwd++) : strlen(passwd));
+
+ db+= passwd_len + 1;
+ /*
+ Database name is always NUL-terminated, so in case of empty database
+ the packet must contain at least the trailing '\0'.
+ */
+ if (db >= end)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ return 1;
+ }
+
+ uint db_len= strlen(db);
+
+ char *ptr= db + db_len + 1;
+
+ if (ptr+1 < end)
+ {
+ uint cs_number= uint2korr(ptr);
+ thd_init_client_charset(thd, cs_number);
+ thd->update_charset();
+ }
+
+ /* Convert database and user names to utf8 */
+ db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info,
+ db, db_len, thd->charset(), &dummy_errors);
+
+ user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
+ system_charset_info, user, user_len,
+ thd->charset(), &dummy_errors);
+
+ if (!(sctx->user= my_strndup(user_buff, user_len, MYF(MY_WME))))
+ return 1;
+
+ /* Clear variables that are allocated */
+ thd->user_connect= 0;
+ strmake(sctx->priv_user, sctx->user, USERNAME_LENGTH);
+
+ if (thd->make_lex_string(&mpvio->db, db_buff, db_len, 0) == 0)
+ return 1; /* The error is set by make_lex_string(). */
+
+ /*
+ Clear thd->db as it points to something, that will be freed when
+ connection is closed. We don't want to accidentally free a wrong
+ pointer if connect failed.
+ */
+ thd->reset_db(NULL, 0);
+
+ if (!initialized)
+ {
+ // if mysqld's been started with --skip-grant-tables option
+ mpvio->status= MPVIO_EXT::SUCCESS;
+ return 0;
+ }
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ if (find_mpvio_user(mpvio, sctx))
+ return 1;
+
+ char *client_plugin;
+ if (thd->client_capabilities & CLIENT_PLUGIN_AUTH)
+ {
+ client_plugin= ptr + 2;
+ if (client_plugin >= end)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ return 1;
+ }
+ }
+ else
+ {
+ if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
+ client_plugin= native_password_plugin_name.str;
+ else
+ {
+ client_plugin= old_password_plugin_name.str;
+ /*
+ For a passwordless accounts we use native_password_plugin.
+ But when an old 4.0 client connects to it, we change it to
+ old_password_plugin, otherwise MySQL will think that server
+ and client plugins don't match.
+ */
+ if (mpvio->acl_user->auth_string.length == 0)
+ mpvio->acl_user->plugin= old_password_plugin_name;
+ }
+ }
+
+ /* remember the data part of the packet, to present it to plugin in read_packet() */
+ mpvio->cached_client_reply.pkt= passwd;
+ mpvio->cached_client_reply.pkt_len= passwd_len;
+ mpvio->cached_client_reply.plugin= client_plugin;
+ mpvio->status= MPVIO_EXT::RESTART;
+#endif
+
+ return 0;
+}
+
+
+/* the packet format is described in send_client_reply_packet() */
+static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
+ uchar **buff, ulong pkt_len)
+{
+#ifndef EMBEDDED_LIBRARY
+ THD *thd= mpvio->thd;
+ NET *net= &thd->net;
+ char *end;
+
+ DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
+
+ if (pkt_len < MIN_HANDSHAKE_SIZE)
+ return packet_error;
+
+ if (mpvio->connect_errors)
+ reset_host_errors(&net->vio->remote.sin_addr);
+
+ ulong client_capabilities= uint2korr(net->read_pos);
+ if (client_capabilities & CLIENT_PROTOCOL_41)
+ {
+ client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
+ thd->max_client_packet_length= uint4korr(net->read_pos+4);
+ DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
+ thd_init_client_charset(thd, (uint) net->read_pos[8]);
+ thd->update_charset();
+ end= (char*) net->read_pos+32;
+ }
+ else
+ {
+ thd->max_client_packet_length= uint3korr(net->read_pos+2);
+ end= (char*) net->read_pos+5;
+ }
+
+ /* Disable those bits which are not supported by the client. */
+ thd->client_capabilities&= client_capabilities;
+
+ if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
+ thd->variables.sql_mode|= MODE_IGNORE_SPACE;
+
+ DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
+ if (thd->client_capabilities & CLIENT_SSL)
+ {
+ char error_string[1024] __attribute__((unused));
+
+ /* Do the SSL layering. */
+ if (!ssl_acceptor_fd)
+ return packet_error;
+
+ DBUG_PRINT("info", ("IO layer change in progress..."));
+ if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, error_string))
+ {
+ DBUG_PRINT("error", ("Failed to accept new SSL connection"));
+ return packet_error;
+ }
+
+ DBUG_PRINT("info", ("Reading user information over SSL layer"));
+ pkt_len= my_net_read(net);
+ if (pkt_len == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE)
+ {
+ DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
+ pkt_len));
+ return packet_error;
+ }
+ }
+
+ if (end >= (char*) net->read_pos+ pkt_len +2)
+ return packet_error;
+
+ if (thd->client_capabilities & CLIENT_INTERACTIVE)
+ thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
+ if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
+ opt_using_transactions)
+ net->return_status= &thd->server_status;
+
+ char *user= end;
+ char *passwd= strend(user)+1;
+ uint user_len= passwd - user - 1, db_len;
+ char *db= passwd;
+ char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
+ char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
+ uint dummy_errors;
+
+ /*
+ Old clients send null-terminated string as password; new clients send
+ the size (1 byte) + string (not null-terminated). Hence in case of empty
+ password both send '\0'.
+
+ This strlen() can't be easily deleted without changing protocol.
+
+ Cast *passwd to an unsigned char, so that it doesn't extend the sign for
+ *passwd > 127 and become 2**32-127+ after casting to uint.
+ */
+ uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ (uchar)(*passwd++) : strlen(passwd);
+
+ if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
+ {
+ db= db + passwd_len + 1;
+ /* strlen() can't be easily deleted without changing protocol */
+ db_len= strlen(db);
+ }
+ else
+ {
+ db= 0;
+ db_len= 0;
+ }
+
+ if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
+ return packet_error;
+
+ char *client_plugin= passwd + passwd_len + (db ? db_len + 1 : 0);
+
+ /* Since 4.1 all database names are stored in utf8 */
+ if (db)
+ {
+ db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info,
+ db, db_len, thd->charset(), &dummy_errors);
+ db= db_buff;
+ }
+
+ user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
+ system_charset_info, user, user_len,
+ thd->charset(), &dummy_errors);
+ user= user_buff;
+
+ /* If username starts and ends in "'", chop them off */
+ if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
+ {
+ user++;
+ user_len-= 2;
+ }
+
+ Security_context *sctx= thd->security_ctx;
+
+ if (thd->make_lex_string(&mpvio->db, db, db_len, 0) == 0)
+ return packet_error; /* The error is set by make_lex_string(). */
+ if (sctx->user)
+ x_free(sctx->user);
+ if (!(sctx->user= my_strndup(user, user_len, MYF(MY_WME))))
+ return packet_error; /* The error is set by my_strdup(). */
+
+ /*
+ Clear thd->db as it points to something, that will be freed when
+ connection is closed. We don't want to accidentally free a wrong
+ pointer if connect failed.
+ */
+ thd->reset_db(NULL, 0);
+
+ if (!initialized)
+ {
+ // if mysqld's been started with --skip-grant-tables option
+ mpvio->status= MPVIO_EXT::SUCCESS;
+ return packet_error;
+ }
+
+ if (find_mpvio_user(mpvio, sctx))
+ return packet_error;
+
+ if (thd->client_capabilities & CLIENT_PLUGIN_AUTH)
+ {
+ if ((client_plugin + strlen(client_plugin)) >
+ (char *)net->read_pos + pkt_len)
+ return packet_error;
+ }
+ else
+ {
+ if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
+ client_plugin= native_password_plugin_name.str;
+ else
+ {
+ client_plugin= old_password_plugin_name.str;
+ /*
+ For a passwordless accounts we use native_password_plugin.
+ But when an old 4.0 client connects to it, we change it to
+ old_password_plugin, otherwise MySQL will think that server
+ and client plugins don't match.
+ */
+ if (mpvio->acl_user->auth_string.length == 0)
+ mpvio->acl_user->plugin= old_password_plugin_name;
+ }
+ }
+
+ /*
+ if the acl_user needs a different plugin to authenticate
+ (specified in GRANT ... AUTHENTICATED VIA plugin_name ..)
+ we need to restart the authentication in the server.
+ But perhaps the client has already used the correct plugin -
+ in that case the authentication on the client may not need to be
+ restarted and a server auth plugin will read the data that the client
+ has just send. Cache them to return in the next server_mpvio_read_packet().
+ */
+ if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ plugin_name(mpvio->plugin)->str) != 0)
+ {
+ mpvio->cached_client_reply.pkt= passwd;
+ mpvio->cached_client_reply.pkt_len= passwd_len;
+ mpvio->cached_client_reply.plugin= client_plugin;
+ mpvio->status= MPVIO_EXT::RESTART;
+ return packet_error;
+ }
+
+ /*
+ ok, we don't need to restart the authentication on the server.
+ but if the client used the wrong plugin, we need to restart
+ the authentication on the client. Do it here, the server plugin
+ doesn't need to know.
+ */
+ const char *client_auth_plugin=
+ ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
+
+ if (client_auth_plugin &&
+ my_strcasecmp(system_charset_info, client_plugin, client_auth_plugin))
+ {
+ mpvio->cached_client_reply.plugin= client_plugin;
+ if (send_plugin_request_packet(mpvio,
+ (uchar*)mpvio->cached_server_packet.pkt,
+ mpvio->cached_server_packet.pkt_len))
+ return packet_error;
+
+ passwd_len= my_net_read(&mpvio->thd->net);
+ passwd = (char*)mpvio->thd->net.read_pos;
+ }
+
+ *buff= (uchar*)passwd;
+ return passwd_len;
+#else
+ return 0;
+#endif
+}
+
+
+/**
+ vio->write_packet() callback method for server authentication plugins
+
+ This function is called by a server authentication plugin, when it wants
+ to send data to the client.
+
+ It transparently wraps the data into a handshake packet,
+ and handles plugin negotiation with the client. If necessary,
+ it escapes the plugin data, if it starts with a mysql protocol packet byte.
+*/
+
+static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param,
+ const uchar *packet, int packet_len)
+{
+ MPVIO_EXT *mpvio= (MPVIO_EXT*)param;
+ int res;
+
+ /* reset cached_client_reply */
+ mpvio->cached_client_reply.pkt= 0;
+ /* for the 1st packet we wrap plugin data into the handshake packet */
+ if (mpvio->packets_written == 0)
+ res= send_server_handshake_packet(mpvio, (char*)packet, packet_len);
+ else if (mpvio->status == MPVIO_EXT::RESTART)
+ res= send_plugin_request_packet(mpvio, packet, packet_len);
+ else if (packet_len > 0 && (*packet == 1 || *packet == 255 || *packet == 254))
+ {
+ /*
+ we cannot allow plugin data packet to start from 255 or 254 -
+ as the client will treat it as an error or "change plugin" packet.
+ We'll escape these bytes with \1. Consequently, we
+ have to escape \1 byte too.
+ */
+ res= net_write_command(&mpvio->thd->net, 1, (uchar*)"", 0,
+ packet, packet_len);
+ }
+ else
+ {
+ res= my_net_write(&mpvio->thd->net, packet, packet_len) ||
+ net_flush(&mpvio->thd->net);
+ }
+ mpvio->packets_written++;
+ return res;
+}
+
+
+/**
+ vio->read_packet() callback method for server authentication plugins
+
+ This function is called by a server authentication plugin, when it wants
+ to read data from the client.
+
+ It transparently extracts the client plugin data, if embedded into
+ a client authentication handshake packet, and handles plugin negotiation
+ with the client, if necessary.
+*/
+
+static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf)
+{
+ MPVIO_EXT *mpvio= (MPVIO_EXT*)param;
+ ulong pkt_len;
+
+ if (mpvio->packets_written == 0)
+ {
+ /*
+ plugin wants to read the data without sending anything first.
+ send an empty packet to force a server handshake packet to be sent
+ */
+ if (server_mpvio_write_packet(mpvio, 0, 0))
+ pkt_len= packet_error;
+ else
+ pkt_len= my_net_read(&mpvio->thd->net);
+ }
+ else
+ if (mpvio->cached_client_reply.pkt)
+ {
+ DBUG_ASSERT(mpvio->status == MPVIO_EXT::RESTART);
+ DBUG_ASSERT(mpvio->packets_read > 0);
+ /*
+ if the have the data cached from the last server_mpvio_read_packet
+ (which can be the case if it's a restarted authentication)
+ and a client has used the correct plugin, then we can return the
+ cached data straight away and avoid one round trip.
+ */
+ const char *client_auth_plugin=
+ ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
+ if (client_auth_plugin == 0 ||
+ my_strcasecmp(system_charset_info, mpvio->cached_client_reply.plugin,
+ client_auth_plugin) == 0)
+ {
+ mpvio->status= MPVIO_EXT::FAILURE;
+ *buf= (uchar*)mpvio->cached_client_reply.pkt;
+ mpvio->cached_client_reply.pkt= 0;
+ mpvio->packets_read++;
+ return (int)mpvio->cached_client_reply.pkt_len;
+ }
+ /*
+ But if the client has used the wrong plugin, the cached data are
+ useless. Furthermore, we have to send a "change plugin" request
+ to the client.
+ */
+ if (server_mpvio_write_packet(mpvio, 0, 0))
+ pkt_len= packet_error;
+ else
+ pkt_len= my_net_read(&mpvio->thd->net);
+ }
+ else
+ pkt_len= my_net_read(&mpvio->thd->net);
+
+ if (pkt_len == packet_error)
+ goto err;
+
+ mpvio->packets_read++;
+
+ /*
+ the 1st packet has the plugin data wrapped into the client authentication
+ handshake packet
+ */
+ if (mpvio->packets_read == 1)
+ {
+ pkt_len= parse_client_handshake_packet(mpvio, buf, pkt_len);
+ if (pkt_len == packet_error)
+ goto err;
+ }
+ else
+ *buf = mpvio->thd->net.read_pos;
+
+ return (int)pkt_len;
+
+err:
+ if (mpvio->status == MPVIO_EXT::FAILURE && !mpvio->thd->is_error())
+ {
+ inc_host_errors(&mpvio->thd->net.vio->remote.sin_addr);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0),
+ mpvio->thd->security_ctx->host_or_ip);
+ }
+ return -1;
+}
+
+
+/**
+ fills MYSQL_PLUGIN_VIO_INFO structure with the information about the
+ connection
+*/
+
+static void server_mpvio_info(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_PLUGIN_VIO_INFO *info)
+{
+ MPVIO_EXT *mpvio= (MPVIO_EXT*)vio;
+ mpvio_info(mpvio->thd->net.vio, info);
+}
+
+
+static bool acl_check_ssl(THD *thd, ACL_USER *acl_user)
+{
+#if defined(HAVE_OPENSSL)
+ Vio *vio=thd->net.vio;
+ SSL *ssl= (SSL*) vio->ssl_arg;
+ X509 *cert;
+#endif
+
+ /*
+ At this point we know that user is allowed to connect
+ from given host by given username/password pair. Now
+ we check if SSL is required, if user is using SSL and
+ if X509 certificate attributes are OK
+ */
+ switch (acl_user->ssl_type) {
+ case SSL_TYPE_NOT_SPECIFIED: // Impossible
+ case SSL_TYPE_NONE: // SSL is not required
+ return 0;
+#if defined(HAVE_OPENSSL)
+ case SSL_TYPE_ANY: // Any kind of SSL is ok
+ return vio_type(vio) != VIO_TYPE_SSL;
+ case SSL_TYPE_X509: /* Client should have any valid certificate. */
+ /*
+ Connections with non-valid certificates are dropped already
+ in sslaccept() anyway, so we do not check validity here.
+
+ We need to check for absence of SSL because without SSL
+ we should reject connection.
+ */
+ if (vio_type(vio) == VIO_TYPE_SSL &&
+ SSL_get_verify_result(ssl) == X509_V_OK &&
+ (cert= SSL_get_peer_certificate(ssl)))
+ {
+ X509_free(cert);
+ return 0;
+ }
+ return 1;
+ case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */
+ /* If a cipher name is specified, we compare it to actual cipher in use. */
+ if (vio_type(vio) != VIO_TYPE_SSL ||
+ SSL_get_verify_result(ssl) != X509_V_OK)
+ return 1;
+ if (acl_user->ssl_cipher)
+ {
+ DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'",
+ acl_user->ssl_cipher,SSL_get_cipher(ssl)));
+ if (strcmp(acl_user->ssl_cipher,SSL_get_cipher(ssl)))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'",
+ acl_user->ssl_cipher, SSL_get_cipher(ssl));
+ return 1;
+ }
+ }
+ /* Prepare certificate (if exists) */
+ if (!(cert= SSL_get_peer_certificate(ssl)))
+ return 1;
+ /* If X509 issuer is specified, we check it... */
+ if (acl_user->x509_issuer)
+ {
+ char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
+ DBUG_PRINT("info",("comparing issuers: '%s' and '%s'",
+ acl_user->x509_issuer, ptr));
+ if (strcmp(acl_user->x509_issuer, ptr))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_information("X509 issuer mismatch: should be '%s' "
+ "but is '%s'", acl_user->x509_issuer, ptr);
+ free(ptr);
+ X509_free(cert);
+ return 1;
+ }
+ free(ptr);
+ }
+ /* X509 subject is specified, we check it .. */
+ if (acl_user->x509_subject)
+ {
+ char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
+ DBUG_PRINT("info",("comparing subjects: '%s' and '%s'",
+ acl_user->x509_subject, ptr));
+ if (strcmp(acl_user->x509_subject,ptr))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_information("X509 subject mismatch: should be '%s' but is '%s'",
+ acl_user->x509_subject, ptr);
+ free(ptr);
+ X509_free(cert);
+ return 1;
+ }
+ free(ptr);
+ }
+ X509_free(cert);
+ return 0;
+#else /* HAVE_OPENSSL */
+ default:
+ /*
+ If we don't have SSL but SSL is required for this user the
+ authentication should fail.
+ */
+ return 1;
+#endif /* HAVE_OPENSSL */
+ }
+ return 1;
+}
+
+static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name,
+ MPVIO_EXT *mpvio)
+{
+ int res= CR_OK, old_status= MPVIO_EXT::FAILURE;
+ bool unlock_plugin= false;
+ plugin_ref plugin;
+
+ if (auth_plugin_name->str == native_password_plugin_name.str)
+ plugin= native_password_plugin;
+ else
+#ifndef EMBEDDED_LIBRARY
+ if (auth_plugin_name->str == old_password_plugin_name.str)
+ plugin= old_password_plugin;
+ else
+ if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
+ MYSQL_AUTHENTICATION_PLUGIN)))
+ unlock_plugin= true;
+#endif
+
+ mpvio->plugin= plugin;
+ old_status= mpvio->status;
+
+ if (plugin)
+ {
+ st_mysql_auth *auth= (st_mysql_auth*)plugin_decl(plugin)->info;
+ res= auth->authenticate_user(mpvio, &mpvio->auth_info);
+
+ if (unlock_plugin)
+ plugin_unlock(thd, plugin);
+ }
+ else
+ {
+ /* Server cannot load the required plugin. */
+ my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name->str);
+ res= CR_ERROR;
+ }
+
+ /*
+ If the status was MPVIO_EXT::RESTART before the authenticate_user() call
+ it can never be MPVIO_EXT::RESTART after the call, because any call
+ to write_packet() or read_packet() will reset the status.
+
+ But (!) if a plugin never called a read_packet() or write_packet(), the
+ status will stay unchanged. We'll fix it, by resetting the status here.
+ */
+ if (old_status == MPVIO_EXT::RESTART && mpvio->status == MPVIO_EXT::RESTART)
+ mpvio->status= MPVIO_EXT::FAILURE; // reset to the default
+
+ return res;
+}
+
+/**
+ Perform the handshake, authorize the client and update thd sctx variables.
+
+ @param thd thread handle
+ @param connect_errors number of previous failed connect attemps
+ from this host
+ @param com_change_user_pkt_len size of the COM_CHANGE_USER packet
+ (without the first, command, byte) or 0
+ if it's not a COM_CHANGE_USER (that is, if
+ it's a new connection)
+
+ @retval 0 success, thd is updated.
+ @retval 1 error
+*/
+
+bool acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len)
+{
+ int res= CR_OK;
+ MPVIO_EXT mpvio;
+ LEX_STRING *auth_plugin_name= default_auth_plugin_name;
+ enum enum_server_command command= com_change_user_pkt_len ? COM_CHANGE_USER
+ : COM_CONNECT;
+ DBUG_ENTER("acl_authenticate");
+
+ compile_time_assert(MYSQL_USERNAME_LENGTH == USERNAME_LENGTH);
+
+ bzero(&mpvio, sizeof(mpvio));
+ mpvio.read_packet= server_mpvio_read_packet;
+ mpvio.write_packet= server_mpvio_write_packet;
+ mpvio.info= server_mpvio_info;
+ mpvio.thd= thd;
+ mpvio.connect_errors= connect_errors;
+ mpvio.status= MPVIO_EXT::FAILURE;
+
+ if (command == COM_CHANGE_USER)
+ {
+ mpvio.packets_written++; // pretend that a server handshake packet was sent
+ mpvio.packets_read++; // take COM_CHANGE_USER packet into account
+
+ if (parse_com_change_user_packet(&mpvio, com_change_user_pkt_len))
+ DBUG_RETURN(1);
+
+ DBUG_ASSERT(mpvio.status == MPVIO_EXT::RESTART ||
+ mpvio.status == MPVIO_EXT::SUCCESS);
+ }
+ else
+ {
+ /* mark the thd as having no scramble yet */
+ thd->scramble[SCRAMBLE_LENGTH]= 1;
+
+ /*
+ perform the first authentication attempt, with the default plugin.
+ This sends the server handshake packet, reads the client reply
+ with a user name, and performs the authentication if everyone has used
+ the correct plugin.
+ */
+ res= do_auth_once(thd, auth_plugin_name, &mpvio);
+ }
+
+ /*
+ retry the authentication, if - after receiving the user name -
+ we found that we need to switch to a non-default plugin
+ */
+ if (mpvio.status == MPVIO_EXT::RESTART)
+ {
+ DBUG_ASSERT(mpvio.acl_user);
+ DBUG_ASSERT(command == COM_CHANGE_USER ||
+ my_strcasecmp(system_charset_info, auth_plugin_name->str,
+ mpvio.acl_user->plugin.str));
+ auth_plugin_name= &mpvio.acl_user->plugin;
+ res= do_auth_once(thd, auth_plugin_name, &mpvio);
+ }
+
+ Security_context *sctx= thd->security_ctx;
+ ACL_USER *acl_user= mpvio.acl_user;
+
+ thd->password= mpvio.auth_info.password_used; // remember for error messages
+
+ /*
+ Log the command here so that the user can check the log
+ for the tried logins and also to detect break-in attempts.
+
+ if sctx->user is unset it's protocol failure, bad packet.
+ */
+ if (sctx->user)
+ {
+ if (strcmp(sctx->priv_user, sctx->user))
+ {
+ general_log_print(thd, command, "%s@%s as %s on %s",
+ sctx->user, sctx->host_or_ip,
+ sctx->priv_user[0] ? sctx->priv_user : "anonymous",
+ mpvio.db.str ? mpvio.db.str : (char*) "");
+ }
+ else
+ general_log_print(thd, command, (char*) "%s@%s on %s",
+ sctx->user, sctx->host_or_ip,
+ mpvio.db.str ? mpvio.db.str : (char*) "");
+ }
+
+ if (res > CR_OK && mpvio.status != MPVIO_EXT::SUCCESS)
+ {
+ DBUG_ASSERT(mpvio.status == MPVIO_EXT::FAILURE);
+
+ if (!thd->is_error())
+ login_failed_error(thd, thd->password);
+ DBUG_RETURN(1);
+ }
+
+ if (initialized) // if not --skip-grant-tables
+ {
+ sctx->master_access= acl_user->access;
+ strmake(sctx->priv_user, mpvio.auth_info.authenticated_as, USERNAME_LENGTH);
+ if (acl_user->host.hostname)
+ strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
+ else
+ *sctx->priv_host= 0;
+
+ /*
+ OK. Let's check the SSL. Historically it was checked after the password,
+ as an additional layer, not instead of the password
+ (in which case it would've been a plugin too).
+ */
+ if (acl_check_ssl(thd, acl_user))
+ {
+ login_failed_error(thd, thd->password);
+ DBUG_RETURN(1);
+ }
+
+ /* Don't allow the user to connect if he has done too many queries */
+ if ((acl_user->user_resource.questions || acl_user->user_resource.updates ||
+ acl_user->user_resource.conn_per_hour ||
+ acl_user->user_resource.user_conn || max_user_connections) &&
+ get_or_create_user_conn(thd,
+ (opt_old_style_user_limits ? sctx->user : sctx->priv_user),
+ (opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host),
+ &acl_user->user_resource))
+ DBUG_RETURN(1); // The error is set by get_or_create_user_conn()
+ }
+ else
+ sctx->skip_grants();
+
+ if (thd->user_connect &&
+ (thd->user_connect->user_resources.conn_per_hour ||
+ thd->user_connect->user_resources.user_conn ||
+ max_user_connections) &&
+ check_for_max_user_connections(thd, thd->user_connect))
+ {
+ status_var_increment(denied_connections);
+ DBUG_RETURN(1); // The error is set in check_for_max_user_connections()
+ }
+
+ DBUG_PRINT("info",
+ ("Capabilities: %lu packet_length: %ld Host: '%s' "
+ "Login user: '%s' Priv_user: '%s' Using password: %s "
+ "Access: %lu db: '%s'",
+ thd->client_capabilities, thd->max_client_packet_length,
+ sctx->host_or_ip, sctx->user, sctx->priv_user,
+ thd->password ? "yes": "no",
+ sctx->master_access, mpvio.db.str));
+
+ if (command == COM_CONNECT &&
+ !(thd->main_security_ctx.master_access & SUPER_ACL))
+ {
+ pthread_mutex_lock(&LOCK_connection_count);
+ bool count_ok= (*thd->scheduler->connection_count <=
+ *thd->scheduler->max_connections);
+ VOID(pthread_mutex_unlock(&LOCK_connection_count));
+ if (!count_ok)
+ { // too many connections
+ my_error(ER_CON_COUNT_ERROR, MYF(0));
+ DBUG_RETURN(1);
+ }
+ }
+
+ /*
+ This is the default access rights for the current database. It's
+ set to 0 here because we don't have an active database yet (and we
+ may not have an active database to set.
+ */
+ sctx->db_access=0;
+
+ /* Change a database if necessary */
+ if (mpvio.db.length)
+ {
+ if (mysql_change_db(thd, &mpvio.db, FALSE))
+ {
+ /* mysql_change_db() has pushed the error message. */
+ if (thd->user_connect)
+ {
+ status_var_increment(thd->status_var.access_denied_errors);
+ decrease_user_connections(thd->user_connect);
+ thd->user_connect= 0;
+ }
+ DBUG_RETURN(1);
+ }
+ }
+
+ thd->net.net_skip_rest_factor= 2; // skip at most 2*max_packet_size
+
+ if (res == CR_OK_HANDSHAKE_COMPLETE)
+ thd->main_da.disable_status();
+ else
+ my_ok(thd);
+
+ /* Ready to handle queries */
+ DBUG_RETURN(0);
+}
+
+
+/**
+ MySQL Server Password Authentication Plugin
+
+ In the MySQL authentication protocol:
+ 1. the server sends the random scramble to the client
+ 2. client sends the encrypted password back to the server
+ 3. the server checks the password.
+*/
+
+static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_SERVER_AUTH_INFO *info)
+{
+ uchar *pkt;
+ int pkt_len;
+ MPVIO_EXT *mpvio=(MPVIO_EXT*)vio;
+ THD *thd=mpvio->thd;
+
+ /* generate the scramble, or reuse the old one */
+ if (thd->scramble[SCRAMBLE_LENGTH])
+ create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+
+ /* send it to the client */
+ if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
+ return CR_ERROR;
+
+ /* reply and authenticate */
+
+ /*
+ <digression>
+ This is more complex than it looks.
+
+ The plugin (we) may be called right after the client was connected -
+ and will need to send a scramble, read reply, authenticate.
+
+ Or the plugin may be called after another plugin has sent a scramble,
+ and read the reply. If the client has used the correct client-plugin,
+ we won't need to read anything here from the client, the client
+ has already sent a reply with everything we need for authentication.
+
+ Or the plugin may be called after another plugin has sent a scramble,
+ and read the reply, but the client has used the wrong client-plugin.
+ We'll need to sent a "switch to another plugin" packet to the
+ client and read the reply. "Use the short scramble" packet is a special
+ case of "switch to another plugin" packet.
+
+ Or, perhaps, the plugin may be called after another plugin has
+ done the handshake but did not send a useful scramble. We'll need
+ to send a scramble (and perhaps a "switch to another plugin" packet)
+ and read the reply.
+
+ Besides, a client may be an old one, that doesn't understand plugins.
+ Or doesn't even understand 4.0 scramble.
+
+ And we want to keep the same protocol on the wire unless non-native
+ plugins are involved.
+
+ Anyway, it still looks simple from a plugin point of view:
+ "send the scramble, read the reply and authenticate".
+ All the magic is transparently handled by the server.
+ </digression>
+ */
+
+ /* read the reply with the encrypted password */
+ if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0)
+ return CR_ERROR;
+
+#ifdef NO_EMBEDDED_ACCESS_CHECKS
+ return CR_OK;
+#endif
+
+ if (pkt_len == 0) /* no password */
+ return info->auth_string[0] ? CR_ERROR : CR_OK;
+
+ info->password_used = 1;
+ if (pkt_len == SCRAMBLE_LENGTH)
+ return check_scramble(pkt, thd->scramble, mpvio->acl_user->salt) ?
+ CR_ERROR : CR_OK;
+
+ inc_host_errors(&mpvio->thd->net.vio->remote.sin_addr);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+ return CR_ERROR;
+}
+
+
+static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_SERVER_AUTH_INFO *info)
+{
+ uchar *pkt;
+ int pkt_len;
+ MPVIO_EXT *mpvio=(MPVIO_EXT*)vio;
+ THD *thd=mpvio->thd;
+
+ /* generate the scramble, or reuse the old one */
+ if (thd->scramble[SCRAMBLE_LENGTH])
+ create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+
+ /* send it to the client */
+ if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
+ return CR_ERROR;
+
+ /* read the reply and authenticate */
+ if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0)
+ return CR_ERROR;
+
+#ifdef NO_EMBEDDED_ACCESS_CHECKS
+ return CR_OK;
+#endif
+
+ /*
+ legacy: if switch_from_long_to_short_scramble,
+ the password is sent \0-terminated, the pkt_len is always 9 bytes.
+ We need to figure out the correct scramble length here.
+ */
+ if (pkt_len == SCRAMBLE_LENGTH_323+1)
+ pkt_len= strnlen((char*)pkt, pkt_len);
+
+ if (pkt_len == 0) /* no password */
+ return info->auth_string[0] ? CR_ERROR : CR_OK;
+
+ if (secure_auth(thd))
+ return CR_ERROR;
+
+ info->password_used = 1;
+
+ if (pkt_len == SCRAMBLE_LENGTH_323)
+ return check_scramble_323(pkt, thd->scramble,
+ (ulong *)mpvio->acl_user->salt) ? CR_ERROR : CR_OK;
+
+ inc_host_errors(&mpvio->thd->net.vio->remote.sin_addr);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+ return CR_ERROR;
+}
+
+static struct st_mysql_auth native_password_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ native_password_plugin_name.str,
+ native_password_authenticate
+};
+
+static struct st_mysql_auth old_password_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ old_password_plugin_name.str,
+ old_password_authenticate
+};
+
+mysql_declare_plugin(mysql_password)
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &native_password_handler, /* type descriptor */
+ native_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Native MySQL authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
+ &old_password_handler, /* type descriptor */
+ old_password_plugin_name.str, /* Name */
+ "R.J.Silk, Sergei Golubchik", /* Author */
+ "Old MySQL-4.0 authentication", /* Description */
+ PLUGIN_LICENSE_GPL, /* License */
+ NULL, /* Init function */
+ NULL, /* Deinit function */
+ 0x0100, /* Version (1.0) */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+}
+mysql_declare_plugin_end;
+
=== modified file 'sql/sql_acl.h'
--- a/sql/sql_acl.h 2009-11-21 11:18:21 +0000
+++ b/sql/sql_acl.h 2010-03-29 15:13:53 +0000
@@ -161,53 +161,6 @@ enum mysql_db_table_field
extern const TABLE_FIELD_DEF mysql_db_table_def;
-/* Classes */
-
-struct acl_host_and_ip
-{
- char *hostname;
- long ip,ip_mask; // Used with masked ip:s
-};
-
-
-class ACL_ACCESS {
-public:
- ulong sort;
- ulong access;
-};
-
-
-/* ACL_HOST is used if no host is specified */
-
-class ACL_HOST :public ACL_ACCESS
-{
-public:
- acl_host_and_ip host;
- char *db;
-};
-
-
-class ACL_USER :public ACL_ACCESS
-{
-public:
- acl_host_and_ip host;
- uint hostname_length;
- USER_RESOURCES user_resource;
- char *user;
- uint8 salt[SCRAMBLE_LENGTH+1]; // scrambled password in binary form
- uint8 salt_len; // 0 - no password, 4 - 3.20, 8 - 3.23, 20 - 4.1.1
- enum SSL_type ssl_type;
- const char *ssl_cipher, *x509_issuer, *x509_subject;
-};
-
-
-class ACL_DB :public ACL_ACCESS
-{
-public:
- acl_host_and_ip host;
- char *user,*db;
-};
-
/* prototypes */
bool hostname_requires_resolving(const char *hostname);
@@ -216,10 +169,9 @@ my_bool acl_reload(THD *thd);
void acl_free(bool end=0);
ulong acl_get(const char *host, const char *ip,
const char *user, const char *db, my_bool db_is_pattern);
-int acl_getroot(THD *thd, USER_RESOURCES *mqh, const char *passwd,
- uint passwd_len);
-bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
- char *ip, char *db);
+bool acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len);
+bool acl_getroot(Security_context *sctx, char *user, char *host,
+ char *ip, char *db);
bool acl_check_host(const char *host, const char *ip);
int check_change_password(THD *thd, const char *host, const char *user,
char *password, uint password_len);
=== modified file 'sql/sql_builtin.cc.in'
--- a/sql/sql_builtin.cc.in 2009-11-29 23:08:56 +0000
+++ b/sql/sql_builtin.cc.in 2010-03-29 15:13:53 +0000
@@ -19,10 +19,10 @@
typedef struct st_mysql_plugin builtin_plugin[];
extern builtin_plugin
- builtin_binlog_plugin@mysql_plugin_defs@;
+ builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@;
struct st_mysql_plugin *mysqld_builtins[]=
{
- builtin_binlog_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
+ builtin_binlog_plugin, builtin_mysql_password_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
};
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-03-16 12:38:35 +0000
+++ b/sql/sql_class.cc 2010-03-29 15:13:53 +0000
@@ -2984,9 +2984,9 @@ void THD::set_status_var_init()
void Security_context::init()
{
- host= user= priv_user= ip= 0;
+ host= user= ip= 0;
host_or_ip= "connecting host";
- priv_host[0]= '\0';
+ priv_user[0]= priv_host[0]= '\0';
master_access= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
db_access= NO_ACCESS;
@@ -3010,8 +3010,7 @@ void Security_context::skip_grants()
/* privileges for the user are unknown everything is allowed */
host_or_ip= (char *)"";
master_access= ~NO_ACCESS;
- priv_user= (char *)"";
- *priv_host= '\0';
+ *priv_user= *priv_host= '\0';
}
@@ -3053,7 +3052,7 @@ bool Security_context::set_user(char *us
of a statement under credentials of a different user, e.g.
definer of a procedure, we authenticate this user in a local
instance of Security_context by means of this method (and
- ultimately by means of acl_getroot_no_password), and make the
+ ultimately by means of acl_getroot), and make the
local instance active in the thread by re-setting
thd->security_ctx pointer.
@@ -3087,19 +3086,12 @@ change_security_context(THD *thd,
DBUG_ASSERT(definer_user->str && definer_host->str);
*backup= NULL;
- /*
- The current security context may have NULL members
- if we have just started the thread and not authenticated
- any user. This use case is currently in events worker thread.
- */
- needs_change= (thd->security_ctx->priv_user == NULL ||
- strcmp(definer_user->str, thd->security_ctx->priv_user) ||
- thd->security_ctx->priv_host == NULL ||
+ needs_change= (strcmp(definer_user->str, thd->security_ctx->priv_user) ||
my_strcasecmp(system_charset_info, definer_host->str,
thd->security_ctx->priv_host));
if (needs_change)
{
- if (acl_getroot_no_password(this, definer_user->str, definer_host->str,
+ if (acl_getroot(this, definer_user->str, definer_host->str,
definer_host->str, db->str))
{
my_error(ER_NO_SUCH_USER, MYF(0), definer_user->str,
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_class.h 2010-03-29 15:13:53 +0000
@@ -805,7 +805,8 @@ public:
priv_user - The user privilege we are using. May be "" for anonymous user.
ip - client IP
*/
- char *host, *user, *priv_user, *ip;
+ char *host, *user, *ip;
+ char priv_user[USERNAME_LENGTH];
/* The host privilege we are using */
char priv_host[MAX_HOSTNAME];
/* points to host if host is available, otherwise points to ip */
=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_connect.cc 2010-03-29 15:13:53 +0000
@@ -27,24 +27,6 @@ extern pthread_mutex_t LOCK_global_user_
extern pthread_mutex_t LOCK_global_table_stats;
extern pthread_mutex_t LOCK_global_index_stats;
-#ifdef HAVE_OPENSSL
-/*
- Without SSL the handshake consists of one packet. This packet
- has both client capabilites and scrambled password.
- With SSL the handshake might consist of two packets. If the first
- packet (client capabilities) has CLIENT_SSL flag set, we have to
- switch to SSL and read the second packet. The scrambled password
- is in the second packet and client_capabilites field will be ignored.
- Maybe it is better to accept flags other than CLIENT_SSL from the
- second packet?
-*/
-#define SSL_HANDSHAKE_SIZE 2
-#define NORMAL_HANDSHAKE_SIZE 6
-#define MIN_HANDSHAKE_SIZE 2
-#else
-#define MIN_HANDSHAKE_SIZE 6
-#endif /* HAVE_OPENSSL */
-
#ifdef __WIN__
extern void win_install_sigabrt_handler();
#endif
@@ -56,9 +38,9 @@ extern void win_install_sigabrt_handler(
#ifndef NO_EMBEDDED_ACCESS_CHECKS
static HASH hash_user_connections;
-static int get_or_create_user_conn(THD *thd, const char *user,
- const char *host,
- USER_RESOURCES *mqh)
+int get_or_create_user_conn(THD *thd, const char *user,
+ const char *host,
+ USER_RESOURCES *mqh)
{
int return_val= 0;
size_t temp_len, user_len;
@@ -124,7 +106,6 @@ end:
1 error
*/
-static
int check_for_max_user_connections(THD *thd, USER_CONN *uc)
{
int error=0;
@@ -276,240 +257,6 @@ end:
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-
-/**
- Check if user exist and password supplied is correct.
-
- @param thd thread handle, thd->security_ctx->{host,user,ip} are used
- @param command originator of the check: now check_user is called
- during connect and change user procedures; used for
- logging.
- @param passwd scrambled password received from client
- @param passwd_len length of scrambled password
- @param db database name to connect to, may be NULL
- @param check_count TRUE if establishing a new connection. In this case
- check that we have not exceeded the global
- max_connections limist
-
- @note Host, user and passwd may point to communication buffer.
- Current implementation does not depend on that, but future changes
- should be done with this in mind; 'thd' is INOUT, all other params
- are 'IN'.
-
- @retval 0 OK; thd->security_ctx->user/master_access/priv_user/db_access and
- thd->db are updated; OK is sent to the client.
- @retval 1 error, e.g. access denied or handshake error, not sent to
- the client. A message is pushed into the error stack.
-*/
-
-int
-check_user(THD *thd, enum enum_server_command command,
- const char *passwd, uint passwd_len, const char *db,
- bool check_count)
-{
- DBUG_ENTER("check_user");
- LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
-
- /*
- Clear thd->db as it points to something, that will be freed when
- connection is closed. We don't want to accidentally free a wrong
- pointer if connect failed. Also in case of 'CHANGE USER' failure,
- current database will be switched to 'no database selected'.
- */
- thd->reset_db(NULL, 0);
-
-#ifdef NO_EMBEDDED_ACCESS_CHECKS
- thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights
- /* Change database if necessary */
- if (db && db[0])
- {
- if (mysql_change_db(thd, &db_str, FALSE))
- DBUG_RETURN(1);
- }
- my_ok(thd);
- DBUG_RETURN(0);
-#else
-
- my_bool opt_secure_auth_local;
- pthread_mutex_lock(&LOCK_global_system_variables);
- opt_secure_auth_local= opt_secure_auth;
- pthread_mutex_unlock(&LOCK_global_system_variables);
-
- /*
- If the server is running in secure auth mode, short scrambles are
- forbidden.
- */
- if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323)
- {
- my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
- general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
- DBUG_RETURN(1);
- }
- if (passwd_len != 0 &&
- passwd_len != SCRAMBLE_LENGTH &&
- passwd_len != SCRAMBLE_LENGTH_323)
- {
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- DBUG_RETURN(1);
- }
-
- USER_RESOURCES ur;
- int res= acl_getroot(thd, &ur, passwd, passwd_len);
-#ifndef EMBEDDED_LIBRARY
- if (res == -1)
- {
- /*
- This happens when client (new) sends password scrambled with
- scramble(), but database holds old value (scrambled with
- scramble_323()). Here we please client to send scrambled_password
- in old format.
- */
- NET *net= &thd->net;
- if (opt_secure_auth_local)
- {
- my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip);
- general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip);
- DBUG_RETURN(1);
- }
- /* We have to read very specific packet size */
- if (send_old_password_request(thd) ||
- my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- DBUG_RETURN(1);
- }
- /* Final attempt to check the user based on reply */
- /* So as passwd is short, errcode is always >= 0 */
- res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323);
- }
-#endif /*EMBEDDED_LIBRARY*/
- /* here res is always >= 0 */
- if (res == 0)
- {
- if (!(thd->main_security_ctx.master_access &
- NO_ACCESS)) // authentication is OK
- {
- DBUG_PRINT("info",
- ("Capabilities: %lu packet_length: %ld Host: '%s' "
- "Login user: '%s' Priv_user: '%s' Using password: %s "
- "Access: %lu db: '%s'",
- thd->client_capabilities,
- thd->max_client_packet_length,
- thd->main_security_ctx.host_or_ip,
- thd->main_security_ctx.user,
- thd->main_security_ctx.priv_user,
- passwd_len ? "yes": "no",
- thd->main_security_ctx.master_access,
- (thd->db ? thd->db : "*none*")));
-
- if (check_count)
- {
- bool count_ok= 1;
-
- if (!(thd->main_security_ctx.master_access & SUPER_ACL))
- {
- pthread_mutex_lock(&LOCK_connection_count);
- count_ok= (*thd->scheduler->connection_count <=
- *thd->scheduler->max_connections);
- VOID(pthread_mutex_unlock(&LOCK_connection_count));
- }
- if (!count_ok)
- { // too many connections
- my_error(ER_CON_COUNT_ERROR, MYF(0));
- DBUG_RETURN(1);
- }
- }
-
- /*
- Log the command before authentication checks, so that the user can
- check the log for the tried login tried and also to detect
- break-in attempts.
- */
- general_log_print(thd, command,
- (thd->main_security_ctx.priv_user ==
- thd->main_security_ctx.user ?
- (char*) "%s@%s on %s" :
- (char*) "%s@%s as anonymous on %s"),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip,
- db ? db : (char*) "");
-
- /*
- This is the default access rights for the current database. It's
- set to 0 here because we don't have an active database yet (and we
- may not have an active database to set.
- */
- thd->main_security_ctx.db_access=0;
-
- /* Don't allow user to connect if he has done too many queries */
- if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
- max_user_connections) &&
- get_or_create_user_conn(thd,
- (opt_old_style_user_limits ? thd->main_security_ctx.user :
- thd->main_security_ctx.priv_user),
- (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
- thd->main_security_ctx.priv_host),
- &ur))
- {
- /* The error is set by get_or_create_user_conn(). */
- DBUG_RETURN(1);
- }
- if (thd->user_connect &&
- (thd->user_connect->user_resources.conn_per_hour ||
- thd->user_connect->user_resources.user_conn ||
- max_user_connections) &&
- check_for_max_user_connections(thd, thd->user_connect))
- {
- /* The error is set in check_for_max_user_connections(). */
- status_var_increment(denied_connections);
- DBUG_RETURN(1);
- }
-
- /* Change database if necessary */
- if (db && db[0])
- {
- if (mysql_change_db(thd, &db_str, FALSE))
- {
- /* mysql_change_db() has pushed the error message. */
- if (thd->user_connect)
- decrease_user_connections(thd->user_connect);
- status_var_increment(thd->status_var.access_denied_errors);
- DBUG_RETURN(1);
- }
- }
- my_ok(thd);
- thd->net.net_skip_rest_factor= 2; // skip at most 2*max_packet_size
- thd->password= test(passwd_len); // remember for error messages
- /* Ready to handle queries */
- DBUG_RETURN(0);
- }
- }
- else if (res == 2) // client gave short hash, server has long hash
- {
- my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
- general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
- DBUG_RETURN(1);
- }
- my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip,
- passwd_len ? ER(ER_YES) : ER(ER_NO));
- general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip,
- passwd_len ? ER(ER_YES) : ER(ER_NO));
- status_var_increment(thd->status_var.access_denied_errors);
-
- DBUG_RETURN(1);
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-}
-
-
/*
Check for maximum allowable user connections, if the mysqld server is
started with corresponding variable that is greater then 0.
@@ -1088,9 +835,8 @@ bool init_new_connection_handler_thread(
thd thread handle
RETURN
- 0 success, OK is sent to user, thd is updated.
- -1 error, which is sent to user
- > 0 error code (not sent to user)
+ 0 success, thd is updated.
+ 1 error
*/
#ifndef EMBEDDED_LIBRARY
@@ -1098,8 +844,6 @@ static int check_connection(THD *thd)
{
uint connect_errors= 0;
NET *net= &thd->net;
- ulong pkt_len= 0;
- char *end;
DBUG_PRINT("info",
("New connection received on %s", vio_description(net->vio)));
@@ -1161,200 +905,10 @@ static int check_connection(THD *thd)
}
vio_keepalive(net->vio, TRUE);
- ulong server_capabilites;
- {
- /* buff[] needs to big enough to hold the server_version variable */
- char buff[SERVER_VERSION_LENGTH + 1 + SCRAMBLE_LENGTH + 1 + 64];
- server_capabilites= CLIENT_BASIC_FLAGS;
-
- if (opt_using_transactions)
- server_capabilites|= CLIENT_TRANSACTIONS;
-#ifdef HAVE_COMPRESS
- server_capabilites|= CLIENT_COMPRESS;
-#endif /* HAVE_COMPRESS */
-#ifdef HAVE_OPENSSL
- if (ssl_acceptor_fd)
- {
- server_capabilites |= CLIENT_SSL; /* Wow, SSL is available! */
- server_capabilites |= CLIENT_SSL_VERIFY_SERVER_CERT;
- }
-#endif /* HAVE_OPENSSL */
-
- end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1;
- int4store((uchar*) end, thd->thread_id);
- end+= 4;
- /*
- So as check_connection is the only entry point to authorization
- procedure, scramble is set here. This gives us new scramble for
- each handshake.
- */
- create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
- /*
- Old clients does not understand long scrambles, but can ignore packet
- tail: that's why first part of the scramble is placed here, and second
- part at the end of packet.
- */
- end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1;
-
- int2store(end, server_capabilites);
- /* write server characteristics: up to 16 bytes allowed */
- end[2]=(char) default_charset_info->number;
- int2store(end+3, thd->server_status);
- bzero(end+5, 13);
- end+= 18;
- /* write scramble tail */
- end= strmake(end, thd->scramble + SCRAMBLE_LENGTH_323,
- SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323) + 1;
-
- /* At this point we write connection message and read reply */
- if (net_write_command(net, (uchar) protocol_version, (uchar*) "", 0,
- (uchar*) buff, (size_t) (end-buff)) ||
- (pkt_len= my_net_read(net)) == packet_error ||
- pkt_len < MIN_HANDSHAKE_SIZE)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0),
- thd->main_security_ctx.host_or_ip);
- return 1;
- }
- }
-#ifdef _CUSTOMCONFIG_
-#include "_cust_sql_parse.h"
-#endif
- if (connect_errors)
- reset_host_errors(&thd->remote.sin_addr);
if (thd->packet.alloc(thd->variables.net_buffer_length))
return 1; /* The error is set by alloc(). */
- thd->client_capabilities= uint2korr(net->read_pos);
- if (thd->client_capabilities & CLIENT_PROTOCOL_41)
- {
- thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
- thd->max_client_packet_length= uint4korr(net->read_pos+4);
- DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
- thd_init_client_charset(thd, (uint) net->read_pos[8]);
- thd->update_charset();
- end= (char*) net->read_pos+32;
- }
- else
- {
- thd->max_client_packet_length= uint3korr(net->read_pos+2);
- end= (char*) net->read_pos+5;
- }
- /*
- Disable those bits which are not supported by the server.
- This is a precautionary measure, if the client lies. See Bug#27944.
- */
- thd->client_capabilities&= server_capabilites;
-
- if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
- thd->variables.sql_mode|= MODE_IGNORE_SPACE;
-#ifdef HAVE_OPENSSL
- DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
- if (thd->client_capabilities & CLIENT_SSL)
- {
- char error_string[1024];
- /* Do the SSL layering. */
- if (!ssl_acceptor_fd)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
- DBUG_PRINT("info", ("IO layer change in progress..."));
- if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, error_string))
- {
- DBUG_PRINT("error", ("Failed to accept new SSL connection"));
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
- DBUG_PRINT("info", ("Reading user information over SSL layer"));
- if ((pkt_len= my_net_read(net)) == packet_error ||
- pkt_len < NORMAL_HANDSHAKE_SIZE)
- {
- DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
- pkt_len));
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
- }
-#endif /* HAVE_OPENSSL */
-
- if (end >= (char*) net->read_pos+ pkt_len +2)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
-
- if (thd->client_capabilities & CLIENT_INTERACTIVE)
- thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
- if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
- opt_using_transactions)
- net->return_status= &thd->server_status;
-
- char *user= end;
- char *passwd= strend(user)+1;
- uint user_len= passwd - user - 1;
- char *db= passwd;
- char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
- char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
- uint dummy_errors;
-
- /*
- Old clients send null-terminated string as password; new clients send
- the size (1 byte) + string (not null-terminated). Hence in case of empty
- password both send '\0'.
-
- This strlen() can't be easily deleted without changing protocol.
-
- Cast *passwd to an unsigned char, so that it doesn't extend the sign for
- *passwd > 127 and become 2**32-127+ after casting to uint.
- */
- uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
- (uchar)(*passwd++) : strlen(passwd);
- db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
- db + passwd_len + 1 : 0;
- /* strlen() can't be easily deleted without changing protocol */
- uint db_len= db ? strlen(db) : 0;
-
- if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
- return 1;
- }
-
- /* Since 4.1 all database names are stored in utf8 */
- if (db)
- {
- db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
- system_charset_info,
- db, db_len,
- thd->charset(), &dummy_errors)]= 0;
- db= db_buff;
- }
-
- user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
- system_charset_info, user, user_len,
- thd->charset(), &dummy_errors)]= '\0';
- user= user_buff;
-
- /* If username starts and ends in "'", chop them off */
- if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
- {
- user[user_len-1]= 0;
- user++;
- user_len-= 2;
- }
-
- if (thd->main_security_ctx.user)
- x_free(thd->main_security_ctx.user);
- if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
- return 1; /* The error is set by my_strdup(). */
- return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
+ return acl_authenticate(thd, connect_errors, 0);
}
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_insert.cc 2010-03-29 15:13:53 +0000
@@ -1778,8 +1778,10 @@ public:
table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0),
group_count(0)
{
- thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user;
+ thd.security_ctx->user=(char*) delayed_user;
thd.security_ctx->host=(char*) my_localhost;
+ strmake(thd.security_ctx->priv_user, thd.security_ctx->user,
+ USERNAME_LENGTH);
thd.current_tablenr=0;
thd.version=refresh_version;
thd.command=COM_DELAYED_INSERT;
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2010-03-15 11:51:23 +0000
+++ b/sql/sql_lex.h 2010-03-29 15:13:53 +0000
@@ -952,6 +952,8 @@ extern sys_var *trg_new_row_fake_var;
enum xa_option_words {XA_NONE, XA_JOIN, XA_RESUME, XA_ONE_PHASE,
XA_SUSPEND, XA_FOR_MIGRATE};
+extern const LEX_STRING null_lex_str;
+extern const LEX_STRING empty_lex_str;
/*
Class representing list of all tables used by statement.
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-03-16 12:38:35 +0000
+++ b/sql/sql_parse.cc 2010-03-29 15:13:53 +0000
@@ -444,9 +444,8 @@ static void handle_bootstrap_impl(THD *t
thd_proc_info(thd, 0);
thd->version=refresh_version;
- thd->security_ctx->priv_user=
- thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
- thd->security_ctx->priv_host[0]=0;
+ thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
+ thd->security_ctx->priv_user[0]= thd->security_ctx->priv_host[0]=0;
/*
Make the "client" handle multiple results. This is necessary
to enable stored procedures with SELECTs and Dynamic SQL
@@ -1093,96 +1092,34 @@ bool dispatch_command(enum enum_server_c
case COM_CHANGE_USER:
{
status_var_increment(thd->status_var.com_other);
- char *user= (char*) packet, *packet_end= packet + packet_length;
- /* Safe because there is always a trailing \0 at the end of the packet */
- char *passwd= strend(user)+1;
thd->change_user();
thd->clear_error(); // if errors from rollback
- /*
- Old clients send null-terminated string ('\0' for empty string) for
- password. New clients send the size (1 byte) + string (not null
- terminated, so also '\0' for empty string).
-
- Cast *passwd to an unsigned char, so that it doesn't extend the sign
- for *passwd > 127 and become 2**32-127 after casting to uint.
- */
- char db_buff[NAME_LEN+1]; // buffer to store db in utf8
- char *db= passwd;
- char *save_db;
- /*
- If there is no password supplied, the packet must contain '\0',
- in any type of handshake (4.1 or pre-4.1).
- */
- if (passwd >= packet_end)
- {
- my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
- break;
- }
- uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
- (uchar)(*passwd++) : strlen(passwd));
- uint dummy_errors, save_db_length, db_length;
- int res;
- Security_context save_security_ctx= *thd->security_ctx;
- USER_CONN *save_user_connect;
-
- db+= passwd_len + 1;
- /*
- Database name is always NUL-terminated, so in case of empty database
- the packet must contain at least the trailing '\0'.
- */
- if (db >= packet_end)
- {
- my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
- break;
- }
- db_length= strlen(db);
-
- char *ptr= db + db_length + 1;
- uint cs_number= 0;
-
- if (ptr < packet_end)
- {
- if (ptr + 2 > packet_end)
- {
- my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
- break;
- }
-
- cs_number= uint2korr(ptr);
- }
-
- /* Convert database name to utf8 */
- db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
- system_charset_info, db, db_length,
- thd->charset(), &dummy_errors)]= 0;
- db= db_buff;
-
- /* Save user and privileges */
- save_db_length= thd->db_length;
- save_db= thd->db;
- save_user_connect= thd->user_connect;
+ /* acl_authenticate() takes the data from net->read_pos */
+ net->read_pos= (uchar*)packet;
- if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
- {
- thd->security_ctx->user= save_security_ctx.user;
- my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
- break;
- }
-
- /* Clear variables that are allocated */
- thd->user_connect= 0;
- thd->security_ctx->priv_user= thd->security_ctx->user;
- res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
+ uint save_db_length= thd->db_length;
+ char *save_db= thd->db;
+ USER_CONN *save_user_connect= thd->user_connect;
+ Security_context save_security_ctx= *thd->security_ctx;
+ CHARSET_INFO *save_character_set_client=
+ thd->variables.character_set_client;
+ CHARSET_INFO *save_collation_connection=
+ thd->variables.collation_connection;
+ CHARSET_INFO *save_character_set_results=
+ thd->variables.character_set_results;
- if (res)
+ if (acl_authenticate(thd, 0, packet_length))
{
x_free(thd->security_ctx->user);
*thd->security_ctx= save_security_ctx;
thd->user_connect= save_user_connect;
- thd->db= save_db;
- thd->db_length= save_db_length;
+ thd->reset_db(save_db, save_db_length);
+ thd->variables.character_set_client= save_character_set_client;
+ thd->variables.collation_connection= save_collation_connection;
+ thd->variables.character_set_results= save_character_set_results;
+ thd->update_charset();
}
else
{
@@ -1193,12 +1130,6 @@ bool dispatch_command(enum enum_server_c
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
x_free(save_db);
x_free(save_security_ctx.user);
-
- if (cs_number)
- {
- thd_init_client_charset(thd, cs_number);
- thd->update_charset();
- }
}
break;
}
@@ -4348,8 +4279,8 @@ end_with_restore_list:
if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE))
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_PROC_AUTO_GRANT_FAIL,
- ER(ER_PROC_AUTO_GRANT_FAIL));
+ ER_PROC_AUTO_GRANT_FAIL, ER(ER_PROC_AUTO_GRANT_FAIL));
+ thd->clear_error();
}
/*
@@ -7727,8 +7658,9 @@ void get_default_definer(THD *thd, LEX_U
definer->host.str= (char *) sctx->priv_host;
definer->host.length= strlen(definer->host.str);
- definer->password.str= NULL;
- definer->password.length= 0;
+ definer->password= null_lex_str;
+ definer->plugin= empty_lex_str;
+ definer->auth= empty_lex_str;
}
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_plugin.cc 2010-03-29 15:13:53 +0000
@@ -16,6 +16,7 @@
#include "mysql_priv.h"
#include <my_pthread.h>
#include <my_getopt.h>
+#include <mysql/plugin_auth.h>
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
@@ -46,7 +47,10 @@ const LEX_STRING plugin_type_names[MYSQL
{ C_STRING_WITH_LEN("STORAGE ENGINE") },
{ C_STRING_WITH_LEN("FTPARSER") },
{ C_STRING_WITH_LEN("DAEMON") },
- { C_STRING_WITH_LEN("INFORMATION SCHEMA") }
+ { C_STRING_WITH_LEN("INFORMATION SCHEMA") },
+ { C_STRING_WITH_LEN("AUDIT") },
+ { C_STRING_WITH_LEN("REPLICATION") },
+ { C_STRING_WITH_LEN("AUTHENTICATION") }
};
extern int initialize_schema_table(st_plugin_int *plugin);
@@ -59,12 +63,12 @@ extern int finalize_schema_table(st_plug
*/
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
- 0,ha_initialize_handlerton,0,0,initialize_schema_table
+ 0,ha_initialize_handlerton,0,0,initialize_schema_table, 0, 0, 0
};
plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
- 0,ha_finalize_handlerton,0,0,finalize_schema_table
+ 0,ha_finalize_handlerton,0,0,finalize_schema_table, 0, 0, 0
};
#ifdef HAVE_DLOPEN
@@ -85,7 +89,10 @@ static int min_plugin_info_interface_ver
MYSQL_HANDLERTON_INTERFACE_VERSION,
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
- MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
+ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
+ 0xff00, /* audit plugins are supported in a later versions */
+ 0xff00, /* replication plugins are supported in a later versions */
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION
};
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
@@ -93,7 +100,10 @@ static int cur_plugin_info_interface_ver
MYSQL_HANDLERTON_INTERFACE_VERSION,
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
- MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
+ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
+ 0x0000, /* audit plugins are supported in a later versions */
+ 0x0000, /* replication plugins are supported in a later versions */
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION
};
/* support for Services */
@@ -1013,6 +1023,9 @@ void plugin_unlock_list(THD *thd, plugin
{
LEX *lex= thd ? thd->lex : 0;
DBUG_ENTER("plugin_unlock_list");
+ if (count == 0)
+ DBUG_VOID_RETURN;
+
DBUG_ASSERT(list);
pthread_mutex_lock(&LOCK_plugin);
while (count--)
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-03-15 11:51:23 +0000
+++ b/sql/sql_yacc.yy 2010-03-29 15:13:53 +0000
@@ -56,6 +56,7 @@
int yylex(void *yylval, void *yythd);
const LEX_STRING null_lex_str= {0,0};
+const LEX_STRING empty_lex_str= { (char*) "", 0 };
#define yyoverflow(A,B,C,D,E,F) \
{ \
@@ -1260,8 +1261,9 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token VARIANCE_SYM
%token VARYING /* SQL-2003-R */
%token VAR_SAMP_SYM
-%token VIRTUAL_SYM
+%token VIA_SYM
%token VIEW_SYM /* SQL-2003-N */
+%token VIRTUAL_SYM
%token WAIT_SYM
%token WARNINGS
%token WEEK_SYM
@@ -11673,6 +11675,9 @@ user:
$$->user = $1;
$$->host.str= (char *) "%";
$$->host.length= 1;
+ $$->password= null_lex_str;
+ $$->plugin= empty_lex_str;
+ $$->auth= empty_lex_str;
if (check_string_char_length(&$$->user, ER(ER_USERNAME),
USERNAME_CHAR_LENGTH,
@@ -11685,6 +11690,9 @@ user:
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
MYSQL_YYABORT;
$$->user = $1; $$->host=$3;
+ $$->password= null_lex_str;
+ $$->plugin= empty_lex_str;
+ $$->auth= empty_lex_str;
if (check_string_char_length(&$$->user, ER(ER_USERNAME),
USERNAME_CHAR_LENGTH,
@@ -12941,6 +12949,18 @@ grant_user:
}
| user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
{ $$= $1; $1->password= $5; }
+ | user IDENTIFIED_SYM VIA_SYM ident_or_text
+ {
+ $$= $1;
+ $1->plugin= $4;
+ $1->auth= empty_lex_str;
+ }
+ | user IDENTIFIED_SYM VIA_SYM ident_or_text USING TEXT_STRING_sys
+ {
+ $$= $1;
+ $1->plugin= $4;
+ $1->auth= $6;
+ }
| user
{ $$= $1; $1->password= null_lex_str; }
;
=== modified file 'sql/structs.h'
--- a/sql/structs.h 2010-02-01 06:14:12 +0000
+++ b/sql/structs.h 2010-03-29 15:13:53 +0000
@@ -178,7 +178,7 @@ extern const char *show_comp_option_name
typedef int *(*update_var)(THD *, struct st_mysql_show_var *);
typedef struct st_lex_user {
- LEX_STRING user, host, password;
+ LEX_STRING user, host, password, plugin, auth;
} LEX_USER;
/*
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2010-03-15 11:51:23 +0000
+++ b/sql/table.cc 2010-03-29 15:13:53 +0000
@@ -4163,11 +4163,8 @@ bool TABLE_LIST::prepare_view_securety_c
{
DBUG_PRINT("info", ("This table is suid view => load contest"));
DBUG_ASSERT(view && view_sctx);
- if (acl_getroot_no_password(view_sctx,
- definer.user.str,
- definer.host.str,
- definer.host.str,
- thd->db))
+ if (acl_getroot(view_sctx, definer.user.str, definer.host.str,
+ definer.host.str, thd->db))
{
if ((thd->lex->sql_command == SQLCOM_SHOW_CREATE) ||
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS))
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2010-03-15 11:51:23 +0000
+++ b/storage/maria/ma_loghandler.c 2010-03-30 12:35:15 +0000
@@ -1275,6 +1275,7 @@ static my_bool translog_set_lsn_for_file
{
LOGHANDLER_FILE_INFO info;
File fd= open_logfile_by_number_no_cache(file);
+ LINT_INIT_STRUCT(info);
if ((fd < 0) ||
((translog_read_file_header(&info, fd) ||
(cmp_translog_addr(lsn, info.max_lsn) > 0 &&
@@ -1457,8 +1458,8 @@ LSN translog_get_file_max_lsn_stored(uin
{
LOGHANDLER_FILE_INFO info;
- LINT_INIT_STRUCT(info);
File fd= open_logfile_by_number_no_cache(file);
+ LINT_INIT_STRUCT(info);
if ((fd < 0) ||
(translog_read_file_header(&info, fd) | my_close(fd, MYF(MY_WME))))
{
@@ -3966,6 +3967,7 @@ my_bool translog_init_with_table(const c
if (!old_log_was_recovered && old_flags == flags)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT_STRUCT(info);
/*
Accessing &log_descriptor.open_files without mutex is safe
because it is initialization
@@ -7934,6 +7936,7 @@ my_bool translog_flush(TRANSLOG_ADDRESS
DBUG_ASSERT(translog_status == TRANSLOG_OK ||
translog_status == TRANSLOG_READONLY);
LINT_INIT(sent_to_disk);
+ LINT_INIT(flush_interval);
pthread_mutex_lock(&log_descriptor.log_flush_lock);
DBUG_PRINT("info", ("Everything is flushed up to (%lu,0x%lx)",
@@ -8060,18 +8063,14 @@ retest:
/* keep values for soft sync() and forced sync() actual */
{
uint32 fileno= LSN_FILE_NO(lsn);
- my_atomic_rwlock_wrlock(&soft_sync_rwl);
- my_atomic_store32(&soft_sync_min, fileno);
- my_atomic_store32(&soft_sync_max, fileno);
- my_atomic_rwlock_wrunlock(&soft_sync_rwl);
+ soft_sync_min= fileno;
+ soft_sync_max= fileno;
}
}
else
{
- my_atomic_rwlock_wrlock(&soft_sync_rwl);
- my_atomic_store32(&soft_sync_max, LSN_FILE_NO(lsn));
- my_atomic_store32(&soft_need_sync, 1);
- my_atomic_rwlock_wrunlock(&soft_sync_rwl);
+ soft_sync_max= lsn;
+ soft_need_sync= 1;
}
DBUG_ASSERT(flush_horizon <= log_descriptor.horizon);
@@ -8464,9 +8463,7 @@ my_bool translog_purge(TRANSLOG_ADDRESS
translog_status == TRANSLOG_READONLY);
soft= soft_sync;
- my_atomic_rwlock_wrlock(&soft_sync_rwl);
- min_unsync= my_atomic_load32(&soft_sync_min);
- my_atomic_rwlock_wrunlock(&soft_sync_rwl);
+ min_unsync= soft_sync_min;
DBUG_PRINT("info", ("min_unsync: %lu", (ulong) min_unsync));
if (soft && min_unsync < last_need_file)
{
@@ -8748,9 +8745,7 @@ void translog_sync()
uint32 min;
DBUG_ENTER("ma_translog_sync");
- my_atomic_rwlock_rdlock(&soft_sync_rwl);
- min= my_atomic_load32(&soft_sync_min);
- my_atomic_rwlock_rdunlock(&soft_sync_rwl);
+ min= soft_sync_min;
if (!min)
min= max;
@@ -8796,13 +8791,11 @@ ma_soft_sync_background( void *arg __att
ulonglong prev_loop= my_micro_time();
ulonglong time, sleep;
uint32 min, max, sync_request;
- my_atomic_rwlock_rdlock(&soft_sync_rwl);
- min= my_atomic_load32(&soft_sync_min);
- max= my_atomic_load32(&soft_sync_max);
- sync_request= my_atomic_load32(&soft_need_sync);
- my_atomic_store32(&soft_sync_min, max);
- my_atomic_store32(&soft_need_sync, 0);
- my_atomic_rwlock_rdunlock(&soft_sync_rwl);
+ min= soft_sync_min;
+ max= soft_sync_max;
+ sync_request= soft_need_sync;
+ soft_sync_min= max;
+ soft_need_sync= 0;
sleep= group_commit_wait;
if (sync_request)
@@ -8834,15 +8827,13 @@ int translog_soft_sync_start(void)
DBUG_ENTER("translog_soft_sync_start");
/* check and init variables */
- my_atomic_rwlock_rdlock(&soft_sync_rwl);
- min= my_atomic_load32(&soft_sync_min);
- max= my_atomic_load32(&soft_sync_max);
+ min= soft_sync_min;
+ max= soft_sync_max;
if (!max)
- my_atomic_store32(&soft_sync_max, (max= get_current_logfile()->number));
+ soft_sync_max= max= get_current_logfile()->number;
if (!min)
- my_atomic_store32(&soft_sync_min, max);
- my_atomic_store32(&soft_need_sync, 1);
- my_atomic_rwlock_rdunlock(&soft_sync_rwl);
+ soft_sync_min= max;
+ soft_need_sync= 1;
if (!(res= ma_service_thread_control_init(&soft_sync_control)))
if (!(res= pthread_create(&th, NULL, ma_soft_sync_background, NULL)))
@@ -8985,6 +8976,7 @@ static void dump_header_page(uchar *buff
{
LOGHANDLER_FILE_INFO desc;
char strbuff[21];
+ LINT_INIT_STRUCT(desc);
translog_interpret_file_header(&desc, buff);
printf(" This can be header page:\n"
" Timestamp: %s\n"
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- a/storage/pbxt/src/ha_pbxt.cc 2010-03-03 14:44:14 +0000
+++ b/storage/pbxt/src/ha_pbxt.cc 2010-03-31 18:37:45 +0000
@@ -1215,8 +1215,6 @@ static int pbxt_init(void *p)
THD *thd = NULL;
#ifndef DRIZZLED
- extern myxt_mutex_t LOCK_plugin;
-
/* {MYSQL QUIRK}
* I have to release this lock for PBXT recovery to
* work, because it needs to open .frm files.
=== modified file 'tests/mysql_client_test.c'
--- a/tests/mysql_client_test.c 2010-01-11 13:15:28 +0000
+++ b/tests/mysql_client_test.c 2010-03-29 15:13:53 +0000
@@ -34,6 +34,7 @@
#include <m_string.h>
#include <mysqld_error.h>
#include <my_handler.h>
+#include <sql_common.h>
#define VER "2.1"
#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */
1
0

01 Apr '10
Arjen Lentz <arjen(a)openquery.com> writes:
>> On 31 Mar 2010, at 05:14, Arjen Lentz wrote:
>>> I think we need something like
>>> %attr(644, root, root) %{_libdir}/mysql/plugin
Ok, I got it sorted out (it wasn't quite like this, but should be ok now).
> So my preference would be to make it a built-in/regular as it will
> make adopton and subsequent use much easier.
Understand, unfortunately I am out of cycles to look into changing this (I
think it requires some (probably simple) changes in at least plug.in and
mysql-test-run.pl). But I personally have no strong opinion one way or the
other.
Anyway, the good news is I seem to have got everything sorted out. It's
running in Buildbot now, and first few builds look correct on both .deb and
.rpm.
https://buildbot.askmonty.org/buildbot/grid?branch=mariadb-5.2-knielsen
Arjen, I'll try to remember to put the packages up somewhere in case you want
to check them out.
So if everything looks ok to you, I will ask Serg to do second review, and
hopefully things will be sorted!
I'll push here once Launchpad gets back up:
lp:~knielsen/maria/5.2-oqgraph
- Kristian.
3
3

[Maria-developers] [Branch ~maria-captains/maria/5.1] Rev 2838: Added missing space from last push
by noreply@launchpad.net 31 Mar '10
by noreply@launchpad.net 31 Mar '10
31 Mar '10
------------------------------------------------------------
revno: 2838
committer: Michael Widenius <monty(a)askmonty.org>
branch nick: maria-5.1
timestamp: Wed 2010-03-31 23:50:54 +0300
message:
Added missing space from last push
Fixed compiler warnings
modified:
mysys/my_gethostbyname.c
storage/xtradb/handler/i_s.cc
storage/xtradb/log/log0recv.c
--
lp:maria
https://code.launchpad.net/~maria-captains/maria/5.1
Your team Maria developers is subscribed to branch lp:maria.
To unsubscribe from this branch go to https://code.launchpad.net/~maria-captains/maria/5.1/+edit-subscription
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2838)
by Michael Widenius 31 Mar '10
by Michael Widenius 31 Mar '10
31 Mar '10
#At lp:maria based on revid:monty@askmonty.org-20100331191221-xg8yj34ld36r2mhe
2838 Michael Widenius 2010-03-31
Added missing space from last push
Fixed compiler warnings
modified:
mysys/my_gethostbyname.c
storage/xtradb/handler/i_s.cc
storage/xtradb/log/log0recv.c
per-file messages:
mysys/my_gethostbyname.c
Added missing space from last push
storage/xtradb/handler/i_s.cc
Removed not used variable
storage/xtradb/log/log0recv.c
Removed not used variable
=== modified file 'mysys/my_gethostbyname.c'
--- a/mysys/my_gethostbyname.c 2010-03-30 12:36:49 +0000
+++ b/mysys/my_gethostbyname.c 2010-03-31 20:50:54 +0000
@@ -95,7 +95,7 @@ struct hostent *
my_gethostbyname_r(const char *name,
struct hostent *result __attribute__((unused)),
char *buffer __attribute__((unused)),
- int buflen__attribute__((unused)),
+ int buflen __attribute__((unused)),
int *h_errnop)
{
struct hostent *hp;
=== modified file 'storage/xtradb/handler/i_s.cc'
--- a/storage/xtradb/handler/i_s.cc 2010-01-28 11:35:10 +0000
+++ b/storage/xtradb/handler/i_s.cc 2010-03-31 20:50:54 +0000
@@ -2988,7 +2988,6 @@ i_s_innodb_admin_command_fill(
COND* cond)
{
TABLE* i_s_table = (TABLE *) tables->table;
- CHARSET_INFO *cs= system_charset_info;
char** query_str;
char* ptr;
char quote = '\0';
=== modified file 'storage/xtradb/log/log0recv.c'
--- a/storage/xtradb/log/log0recv.c 2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/log/log0recv.c 2010-03-31 20:50:54 +0000
@@ -3280,7 +3280,6 @@ recv_recovery_from_checkpoint_finish(voi
#endif /* UNIV_DEBUG */
if (recv_needed_recovery && srv_recovery_stats) {
- FILE* file = stderr;
ulint i;
fprintf(stderr,
1
0

[Maria-developers] [Branch ~maria-captains/maria/5.1] Rev 2837: Fixed compiler warnings
by noreply@launchpad.net 31 Mar '10
by noreply@launchpad.net 31 Mar '10
31 Mar '10
------------------------------------------------------------
revno: 2837
committer: Michael Widenius <monty(a)askmonty.org>
branch nick: maria-5.1
timestamp: Wed 2010-03-31 22:12:21 +0300
message:
Fixed compiler warnings
Fixed random failure in test system
modified:
BUILD/compile-solaris-sparc
cmd-line-utils/libedit/filecomplete.c
mysql-test/suite/rpl/r/rpl_optimize.result
mysql-test/suite/rpl/t/rpl_optimize.test
support-files/compiler_warnings.supp
--
lp:maria
https://code.launchpad.net/~maria-captains/maria/5.1
Your team Maria developers is subscribed to branch lp:maria.
To unsubscribe from this branch go to https://code.launchpad.net/~maria-captains/maria/5.1/+edit-subscription
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2837)
by Michael Widenius 31 Mar '10
by Michael Widenius 31 Mar '10
31 Mar '10
#At lp:maria based on revid:monty@askmonty.org-20100330123649-z64q052mcmpe049v
2837 Michael Widenius 2010-03-31
Fixed compiler warnings
Fixed random failure in test system
modified:
BUILD/compile-solaris-sparc
cmd-line-utils/libedit/filecomplete.c
mysql-test/suite/rpl/r/rpl_optimize.result
mysql-test/suite/rpl/t/rpl_optimize.test
support-files/compiler_warnings.supp
per-file messages:
BUILD/compile-solaris-sparc
Addex EXTRA_FLAGS to configure line (to get rid of warnings for not initialzed variables on buildbot)
cmd-line-utils/libedit/filecomplete.c
Remove not used variables
mysql-test/suite/rpl/r/rpl_optimize.result
Updated result
mysql-test/suite/rpl/t/rpl_optimize.test
Use sync_salve_with_master to ensure cleanup on slave
support-files/compiler_warnings.supp
Added suppression of libedit files
=== modified file 'BUILD/compile-solaris-sparc'
--- a/BUILD/compile-solaris-sparc 2008-09-30 20:57:48 +0000
+++ b/BUILD/compile-solaris-sparc 2010-03-31 19:12:21 +0000
@@ -9,6 +9,6 @@ PATH=$PATH:/usr/ccs/bin:/usr/local/bin
path=`dirname $0`
. "$path/autorun.sh"
-CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" LIBS="-lmtmalloc" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa $EXTRA_FLAGS $EXTRA_CFLAGS" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g $EXTRA_FLAGS $EXTRA_CXXFLAGS" LIBS="-lmtmalloc" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
make -j 4
=== modified file 'cmd-line-utils/libedit/filecomplete.c'
--- a/cmd-line-utils/libedit/filecomplete.c 2009-04-30 11:53:30 +0000
+++ b/cmd-line-utils/libedit/filecomplete.c 2010-03-31 19:12:21 +0000
@@ -95,10 +95,9 @@ static char break_chars[] = { ' ', '\t',
char *
fn_tilde_expand(const char *txt)
{
- struct passwd pwres, *pass;
+ struct passwd *pass;
char *temp;
size_t len = 0;
- char pwbuf[1024];
if (txt[0] != '~')
return (strdup(txt));
=== modified file 'mysql-test/suite/rpl/r/rpl_optimize.result'
--- a/mysql-test/suite/rpl/r/rpl_optimize.result 2010-01-13 09:00:03 +0000
+++ b/mysql-test/suite/rpl/r/rpl_optimize.result 2010-03-31 19:12:21 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+drop tables if exists t1;
CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
create table t1 (a int not null auto_increment primary key, b int, key(b));
INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
=== modified file 'mysql-test/suite/rpl/t/rpl_optimize.test'
--- a/mysql-test/suite/rpl/t/rpl_optimize.test 2010-03-04 08:03:07 +0000
+++ b/mysql-test/suite/rpl/t/rpl_optimize.test 2010-03-31 19:12:21 +0000
@@ -15,6 +15,10 @@
-- source include/not_staging.inc
-- source include/master-slave.inc
+--disable_warnings
+drop tables if exists t1;
+--enable_warnings
+
CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
create table t1 (a int not null auto_increment primary key, b int, key(b));
@@ -51,10 +55,9 @@ sync_with_master; # won't work if slave
connection master; # cleanup
drop table t1;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
# If the machine is so fast that slave syncs before OPTIMIZE
-# starts, this test wil demonstrate nothing but will pass.
+# starts, this test will demonstrate nothing but will pass.
# End of 4.1 tests
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-03-30 12:36:49 +0000
+++ b/support-files/compiler_warnings.supp 2010-03-31 19:12:21 +0000
@@ -54,6 +54,12 @@ db_vrfy.c : .*comparison is always false
# readline is not maintained by us
#
.*/cmd-line-utils/readline/.* : .*
+readline\.c : unused parameter
+term\.c : unused parameter
+vi\.c : unused parameter
+common\.c : unused parameter
+term\.c : *.*
+
#
# Ignore some warnings in libevent, which is not maintained by us.
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2744)
by Igor Babaev 31 Mar '10
by Igor Babaev 31 Mar '10
31 Mar '10
#At lp:maria/5.2 based on revid:igor@askmonty.org-20100329211612-d7f7utiqasfk0ups
2744 Igor Babaev 2010-03-31
Adjusted results
modified:
mysql-test/r/key_cache.result
mysql-test/suite/pbxt/r/mysqlshow.result
mysql-test/t/key_cache.test
=== modified file 'mysql-test/r/key_cache.result'
--- a/mysql-test/r/key_cache.result 2010-02-16 16:41:11 +0000
+++ b/mysql-test/r/key_cache.result 2010-03-31 18:45:41 +0000
@@ -467,18 +467,18 @@ Key_write_requests 26
Key_writes 6
select * from information_schema.key_caches;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 1048576 1024 3 # 0 10 0 13 4
-default 2 2 1048576 1024 1 # 0 12 0 13 2
-default 2 NULL 2097152 1024 4 # 0 22 0 26 6
-small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+default 2 1 1048576 1024 # # 0 10 0 13 4
+default 2 2 1048576 1024 # # 0 12 0 13 2
+default 2 NULL 2097152 1024 # # 0 22 0 26 6
+small NULL NULL 1048576 1024 # # 0 1 0 2 1
delete from t1;
delete from t2;
select * from information_schema.key_caches;
KEY_CACHE_NAME PARTITIONS PARTITION_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
-default 2 1 1048576 1024 3 # 0 10 0 13 4
-default 2 2 1048576 1024 1 # 0 12 0 13 2
-default 2 NULL 2097152 1024 4 # 0 22 0 26 6
-small NULL NULL 1048576 1024 1 # 0 1 0 2 1
+default 2 1 1048576 1024 # # 0 10 0 13 4
+default 2 2 1048576 1024 # # 0 12 0 13 2
+default 2 NULL 2097152 1024 # # 0 22 0 26 6
+small NULL NULL 1048576 1024 # # 0 1 0 2 1
set global key_cache_partitions=1;
select @@key_cache_partitions;
@@key_cache_partitions
=== modified file 'mysql-test/suite/pbxt/r/mysqlshow.result'
--- a/mysql-test/suite/pbxt/r/mysqlshow.result 2010-02-01 06:14:12 +0000
+++ b/mysql-test/suite/pbxt/r/mysqlshow.result 2010-03-31 18:45:41 +0000
@@ -91,6 +91,7 @@ Database: information_schema
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| INDEX_STATISTICS |
+| KEY_CACHES |
| KEY_COLUMN_USAGE |
| PARTITIONS |
| PLUGINS |
@@ -144,6 +145,7 @@ Database: INFORMATION_SCHEMA
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| INDEX_STATISTICS |
+| KEY_CACHES |
| KEY_COLUMN_USAGE |
| PARTITIONS |
| PLUGINS |
=== modified file 'mysql-test/t/key_cache.test'
--- a/mysql-test/t/key_cache.test 2010-02-16 16:41:11 +0000
+++ b/mysql-test/t/key_cache.test 2010-03-31 18:45:41 +0000
@@ -316,12 +316,12 @@ update t2 set i=2 where i=1;
--replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED
show status like 'key_%';
---replace_column 7 #
+--replace_column 6 # 7 #
select * from information_schema.key_caches;
delete from t1;
delete from t2;
---replace_column 7 #
+--replace_column 6 # 7 #
select * from information_schema.key_caches;
# Check that we can work with one partition with the same results
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (monty:2761)
by Michael Widenius 31 Mar '10
by Michael Widenius 31 Mar '10
31 Mar '10
#At lp:maria/5.2 based on revid:sanja@askmonty.org-20100330123515-4p8q03xccl3d6k59
2761 Michael Widenius 2010-03-31
Fixed some compiler warnings
modified:
include/m_ctype.h
plugin/auth/dialog.c
sql/sql_acl.cc
storage/pbxt/src/ha_pbxt.cc
per-file messages:
include/m_ctype.h
MY_UNICASE_INFO already includes 'const'
plugin/auth/dialog.c
Fixed parameters to have correct signed/unsigned type
sql/sql_acl.cc
old_password_plugin is not used for EMBEDDED_LIBRARY
storage/pbxt/src/ha_pbxt.cc
Remove not used variable
=== modified file 'include/m_ctype.h'
--- a/include/m_ctype.h 2010-01-06 19:20:16 +0000
+++ b/include/m_ctype.h 2010-03-31 18:37:45 +0000
@@ -291,7 +291,7 @@ struct charset_info_st
const uint16 *const *sort_order_big;
const uint16 *tab_to_uni;
MY_UNI_IDX *tab_from_uni;
- const MY_UNICASE_INFO *const *caseinfo;
+ MY_UNICASE_INFO *const *caseinfo;
const uchar *state_map;
const uchar *ident_map;
uint strxfrm_multiply;
=== modified file 'plugin/auth/dialog.c'
--- a/plugin/auth/dialog.c 2010-03-29 15:13:53 +0000
+++ b/plugin/auth/dialog.c 2010-03-31 18:37:45 +0000
@@ -51,6 +51,8 @@
#define PASSWORD_QUESTION "\4"
#define LAST_PASSWORD "\5"
+typedef unsigned char uchar;
+
/********************* SERVER SIDE ****************************************/
/**
@@ -63,7 +65,9 @@ static int two_questions(MYSQL_PLUGIN_VI
int pkt_len;
/* send a password question */
- if (vio->write_packet(vio, PASSWORD_QUESTION "Password, please:", 18))
+ if (vio->write_packet(vio,
+ (const uchar*) (PASSWORD_QUESTION "Password, please:"),
+ 18))
return CR_ERROR;
/* read the answer */
@@ -73,11 +77,12 @@ static int two_questions(MYSQL_PLUGIN_VI
info->password_used = 1;
/* fail if the password is wrong */
- if (strcmp(pkt, info->auth_string))
+ if (strcmp((char*) pkt, info->auth_string))
return CR_ERROR;
/* send the last, ordinary, question */
- if (vio->write_packet(vio, LAST_QUESTION "Are you sure ?", 15))
+ if (vio->write_packet(vio,
+ (const uchar*) (LAST_QUESTION "Are you sure ?"), 15))
return CR_ERROR;
/* read the answer */
@@ -85,7 +90,7 @@ static int two_questions(MYSQL_PLUGIN_VI
return CR_ERROR;
/* check the reply */
- return strcmp(pkt, "yes, of course") ? CR_ERROR : CR_OK;
+ return strcmp((char*) pkt, "yes, of course") ? CR_ERROR : CR_OK;
}
static struct st_mysql_auth two_handler=
@@ -108,7 +113,8 @@ static int three_attempts(MYSQL_PLUGIN_V
for (i= 0; i < 3; i++)
{
/* send the prompt */
- if (vio->write_packet(vio, PASSWORD_QUESTION "Password, please:", 18))
+ if (vio->write_packet(vio,
+ (const uchar*) (PASSWORD_QUESTION "Password, please:"), 18))
return CR_ERROR;
/* read the password */
@@ -121,7 +127,7 @@ static int three_attempts(MYSQL_PLUGIN_V
finish, if the password is correct.
note, that we did not mark the prompt packet as "last"
*/
- if (strcmp(pkt, info->auth_string) == 0)
+ if (strcmp((char*) pkt, info->auth_string) == 0)
return CR_OK;
}
@@ -255,12 +261,12 @@ static int perform_dialog(MYSQL_PLUGIN_V
if ((cmd >> 1) == 2 && *pkt == 0)
reply= mysql->passwd;
else
- reply= ask(mysql, cmd >> 1, pkt, reply_buf, sizeof(reply_buf));
+ reply= ask(mysql, cmd >> 1, (char*) pkt, reply_buf, sizeof(reply_buf));
if (!reply)
return CR_ERROR;
}
/* send the reply to the server */
- res= vio->write_packet(vio, reply, strlen(reply)+1);
+ res= vio->write_packet(vio, (uchar*) reply, strlen(reply)+1);
if (reply != mysql->passwd && reply != reply_buf)
free(reply);
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-03-29 15:13:53 +0000
+++ b/sql/sql_acl.cc 2010-03-31 18:37:45 +0000
@@ -161,7 +161,10 @@ static LEX_STRING old_password_plugin_na
/// @todo make it configurable
LEX_STRING *default_auth_plugin_name= &native_password_plugin_name;
-static plugin_ref native_password_plugin, old_password_plugin;
+static plugin_ref native_password_plugin;
+#ifndef EMBEDDED_LIBRARY
+static plugin_ref old_password_plugin;
+#endif
/* Classes */
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- a/storage/pbxt/src/ha_pbxt.cc 2010-03-03 14:44:14 +0000
+++ b/storage/pbxt/src/ha_pbxt.cc 2010-03-31 18:37:45 +0000
@@ -1215,8 +1215,6 @@ static int pbxt_init(void *p)
THD *thd = NULL;
#ifndef DRIZZLED
- extern myxt_mutex_t LOCK_plugin;
-
/* {MYSQL QUIRK}
* I have to release this lock for PBXT recovery to
* work, because it needs to open .frm files.
1
0

[Maria-developers] Rev 31: Merge. in file:///Users/hakan/work/monty_program/mariadb-tools/
by Hakan Kuecuekyilmaz 31 Mar '10
by Hakan Kuecuekyilmaz 31 Mar '10
31 Mar '10
At file:///Users/hakan/work/monty_program/mariadb-tools/
------------------------------------------------------------
revno: 31 [merge]
revision-id: hakan(a)askmonty.org-20100331181744-71hyuyjjlijrsl68
parent: hakan(a)askmonty.org-20100331181651-pxx2ep0u5658d6q1
parent: knielsen@hasky-20100329172857-9qy2lqbl892ikh89
committer: Hakan Kuecuekyilmaz <hakan(a)askmonty.org>
branch nick: mariadb-tools
timestamp: Wed 2010-03-31 20:17:44 +0200
message:
Merge.
modified:
buildbot/maria-master.cfg mariamaster.cfg-20091218103450-cvifjz3i70oerkej-1
=== modified file 'buildbot/maria-master.cfg'
--- a/buildbot/maria-master.cfg 2010-02-23 07:48:54 +0000
+++ b/buildbot/maria-master.cfg 2010-03-29 17:28:57 +0000
@@ -114,7 +114,8 @@
"lp:~maria-captains/maria/5.2-dsmrr" : "5.2-dsmrr",
"lp:~maria-captains/maria/5.3" : "5.3",
"lp:~maria-captains/maria/5.3-sj-subqueries" : "5.3-sj-subqueries",
- "lp:~maria-captains/maria/5.3-subqueries" : "5.3-subqueries"
+ "lp:~maria-captains/maria/5.3-subqueries" : "5.3-subqueries",
+ "lp:~maria-captains/maria/maria-5.2-wl85" : "maria-5.2-wl85"
}
mailSource = mail.BzrLaunchpadEmailMaildirSource("/var/lib/buildbot/Maildir",
branchMap=myBranchMap)
@@ -155,11 +156,11 @@
"mariadb-5.1-monty", "mariadb-5.2-monty",
"mariadb-5.1-knielsen","5.1-release", "5.1-merge",
"maria-5.1-wl24", "maria-5.1-vcol","maria-5.1-wl36","mysql-5.1-mwl36",
- "5.1.39-oqgraph", "5.2-dsmrr", "5.3", "5.3-sj-subqueries", "5.3-subqueries"
+ "5.1.39-oqgraph", "5.2-dsmrr", "5.3", "5.3-sj-subqueries", "5.3-subqueries",
+ "maria-5.2-wl85"
],
treeStableTimer=60, # 1 sec for bzr
- builderNames=["centos5-debug", "hardy-x86-rtai", "hardy-amd64-makedist",
- "hardy-amd64-dbg",
+ builderNames=["centos5-debug", "hardy-amd64-makedist",
# "lenny-amd64-dbg", "adutko-alpha",
"debian5-i386-fulltest",
"jaunty-x86-valgrind", "jaunty-amd64-rel",
@@ -170,6 +171,19 @@
"sol10-amd64-dbg", "sol10-sparc32-forte", "sol10-sparc64-forte",
"sol-sparc-32"]))
+# A scheduler for less powerful hosts, only run on most important branches.
+c['schedulers'].append(AnyBranchScheduler(
+ name="mariadb-light",
+ branches=["5.1", "5.2",
+ "mariadb-5.1-knielsen",
+ "5.1-release", "5.1-merge",
+ "5.2-release", "5.2-merge",
+ "5.3-release", "5.3-merge",
+ ],
+ treeStableTimer=60, # 1 sec for bzr
+ builderNames=["hardy-x86-rtai", "hardy-amd64-dbg",
+ ]))
+
c['schedulers'].append(Triggerable(
name="tarbuild-sched",
builderNames=["win32-tarball", "win32-make-noinstall-zip", "centos5-amd64-minimal"]))
@@ -298,7 +312,7 @@
f1.addStep(getMTR(
test_type="nm",
test_info="Valgrind run, no --ps-protocol",
- command=["sh", "-c", "cd mysql-test && exec perl mysql-test-run.pl --mem --parallel=3 --valgrind --force --retry=3 --skip-ndb"]))
+ command=["sh", "-c", "cd mysql-test && exec perl mysql-test-run.pl --mem --parallel=3 --valgrind --valgrind-option=--show-reachable=yes --valgrind-option=--gen-suppressions=all --force --retry=3 --skip-ndb"]))
bld_valgrind = {'name': "hardy-amd64-valgrind",
'slavename': "valgrind",
@@ -428,7 +442,8 @@
f_rel_1_32 = factory.BuildFactory()
f_rel_1_32.addStep(bzr_checkout)
-f_rel_1_32.addStep(getCompileStep(["BUILD/compile-pentium-max"]))
+f_rel_1_32.addStep(getCompileStep(["BUILD/compile-pentium-max"],
+ env={"AM_MAKEFLAGS": "-j1", "EXTRA_FLAGS": "-DFORCE_INIT_OF_VARS"}))
# --testcase-timeout as this host is really slow at some tests.
f_rel_1_32.addStep(getMTR(
test_type="nm",
@@ -482,6 +497,7 @@
'slavename': "archivist-cnc",
'builddir': "archivist-cnc",
'factory': f_rel_1_32,
+ "env": { "AM_MAKEFLAGS": "-j1" },
"category": "experimental",
}
@@ -489,6 +505,7 @@
'slavename': "archivist-amd64",
'builddir': "archivist-amd64",
'factory': f_dbg_2_64,
+ "env": { "AM_MAKEFLAGS": "-j1" },
"category": "main",
}
@@ -514,7 +531,7 @@
command=["sh", "-c", WithProperties("rm -Rf %(distname)s && tar zxf %(distname)s.tar.gz")]))
f_minimal.addStep(getCompileStep(
["sh", "-c", WithProperties("cd %(distname)s && ./configure --without-uca --without-query-cache --without-geomery --without-readline --without-libedit --without-embedded-server --without-plugin-example --without-plugin-innobase --without-plugin-federated --without-plugin-pbxt --without-plugin-partition --without-plugin-daemon_example --without-plugin-ftexample --without-plugin-archive --without-plugin-blackhole --without-plugin-ibmdb2i --without-plugin-ndbcluster && make -j3")],
- subdir="%(distname)s"))
+ subdir="%(distname)s/"))
f_minimal.addStep(getMTR(
test_type="nm",
test_info="Normal run, no --ps-protocol",
@@ -1134,8 +1151,9 @@
bld_kvm_deb_lucid_x86 = getDebBuilder("kvm-deb-lucid-x86", "vm-lucid-i386", "2239", "qemu32,-nx")
bld_kvm_deb_debian5_amd64 = getDebBuilder("kvm-deb-debian5-amd64", "vm-debian5-amd64", "2234", "qemu64")
bld_kvm_deb_debian5_x86 = getDebBuilder("kvm-deb-debian5-x86", "vm-debian5-i386", "2226", "qemu32,-nx")
-bld_kvm_deb_debian4_amd64 = getDebBuilder("kvm-deb-debian4-amd64", "vm-debian4-amd64", "2240", "qemu64", kvmargs=["--netdev=e1000", "--kvm=-cdrom", "--kvm=/kvm/debian-40r8-amd64-netinst.iso"])
-bld_kvm_deb_debian4_x86 = getDebBuilder("kvm-deb-debian4-x86", "vm-debian4-i386", "2241", "qemu32,-nx", kvmargs=["--netdev=e1000", "--kvm=-cdrom", "--kvm=/kvm/debian-40r8-i386-netinst.iso"])
+# Some serious kvm/kernel problem on debian4, need aggressive retry
+bld_kvm_deb_debian4_amd64 = getDebBuilder("kvm-deb-debian4-amd64", "vm-debian4-amd64", "2240", "qemu64", kvmargs=["--netdev=e1000", "--kvm-retries=20", "--kvm=-cdrom", "--kvm=/kvm/debian-40r8-amd64-netinst.iso"])
+bld_kvm_deb_debian4_x86 = getDebBuilder("kvm-deb-debian4-x86", "vm-debian4-i386", "2241", "qemu32,-nx", kvmargs=["--netdev=e1000", "--kvm-retries=20", "--kvm=-cdrom", "--kvm=/kvm/debian-40r8-i386-netinst.iso"])
def getBintarBuilder(name, kvm_image, port, cpu):
@@ -1221,7 +1239,7 @@
description="untarring", descriptionDone="untar",
command=["sh", "-c", WithProperties("rm -Rf %(distdirname)s && tar zxf %(distname)s")]))
f_sol_64_bintar.addStep(getCompileStep(["sh", "-c", WithProperties("cd %(distdirname)s && BUILD/compile-solaris-amd64-debug")],
- subdir="%(distdirname)s"))
+ subdir="%(distdirname)s/"))
f_sol_64_bintar.addStep(ShellCommand(
description="packaging", descriptionDone="package",
command=["sh", "-c", WithProperties("""
1
0

[Maria-developers] Rev 30: Added necessary options for mysql client calls. in file:///Users/hakan/work/monty_program/mariadb-tools/
by Hakan Kuecuekyilmaz 31 Mar '10
by Hakan Kuecuekyilmaz 31 Mar '10
31 Mar '10
At file:///Users/hakan/work/monty_program/mariadb-tools/
------------------------------------------------------------
revno: 30
revision-id: hakan(a)askmonty.org-20100331181651-pxx2ep0u5658d6q1
parent: hakan(a)askmonty.org-20100329105306-6hthpbelo9xop3kw
committer: Hakan Kuecuekyilmaz <hakan(a)askmonty.org>
branch nick: mariadb-tools
timestamp: Wed 2010-03-31 20:16:51 +0200
message:
Added necessary options for mysql client calls.
=== modified file 'sysbench/run-sysbench-myisam.sh'
--- a/sysbench/run-sysbench-myisam.sh 2010-03-29 10:53:06 +0000
+++ b/sysbench/run-sysbench-myisam.sh 2010-03-31 18:16:51 +0000
@@ -70,6 +70,7 @@
# Variables.
#
MY_SOCKET="/tmp/mysql.sock"
+MYSQL_OPTIONS="-uroot --socket=$MY_SOCKET"
MYSQLADMIN_OPTIONS="--no-defaults -uroot --socket=$MY_SOCKET"
MYSQLD_OPTIONS="--no-defaults \
--datadir=$DATA_DIR \
@@ -334,10 +335,11 @@
start_mysqld
sync
+ echo ""
echo "[$(date "+%Y-%m-%d %H:%M:%S")] Starting warm up of $WARM_UP_TIME seconds."
$SYSBENCH $SYSBENCH_OPTIONS_WARM_UP run
sync
- echo 'FLUSH STATUS' | $MYSQL -uroot
+ echo 'FLUSH STATUS' | $MYSQL $MYSQL_OPTIONS
echo "[$(date "+%Y-%m-%d %H:%M:%S")] Finnished warm up."
echo "[$(date "+%Y-%m-%d %H:%M:%S")] Starting actual sysbench run."
@@ -345,7 +347,7 @@
grep "write requests:" ${THIS_RESULT_DIR}/result${k}.txt | awk '{ print $4 }' | sed -e 's/(//' >> ${THIS_RESULT_DIR}/results.txt
- echo 'SELECT * FROM INFORMATION_SCHEMA.KEY_CACHES' | $MYSQL -uroot > ${THIS_RESULT_DIR}/key_cache_stats${k}.txt
+ echo 'SELECT * FROM INFORMATION_SCHEMA.KEY_CACHES' | $MYSQL $MYSQL_OPTIONS > ${THIS_RESULT_DIR}/key_cache_stats${k}.txt
k=$(($k + 1))
done
=== modified file 'sysbench/run-sysbench.sh'
--- a/sysbench/run-sysbench.sh 2010-03-25 01:42:05 +0000
+++ b/sysbench/run-sysbench.sh 2010-03-31 18:16:51 +0000
@@ -327,6 +327,7 @@
start_mysqld
sync
+ echo ""
echo "[$(date "+%Y-%m-%d %H:%M:%S")] Starting warm up of $WARM_UP_TIME seconds."
$SYSBENCH $SYSBENCH_OPTIONS_WARM_UP run
sync
1
0

[Maria-developers] Updated (by Knielsen): Merge OQGraph into MariaDB (112)
by worklog-noreply@askmonty.org 31 Mar '10
by worklog-noreply@askmonty.org 31 Mar '10
31 Mar '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Merge OQGraph into MariaDB
CREATION DATE..: Mon, 29 Mar 2010, 18:00
SUPERVISOR.....: Knielsen
IMPLEMENTOR....: Knielsen
COPIES TO......:
CATEGORY.......: Server-Sprint
TASK ID........: 112 (http://askmonty.org/worklog/?tid=112)
VERSION........: Server-5.2
STATUS.........: Code-Review
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 15 (hours remain)
ORIG. ESTIMATE.: 15
PROGRESS NOTES:
-=-=(Knielsen - Wed, 31 Mar 2010, 13:38)=-=-
Status updated.
--- /tmp/wklog.112.old.12166 2010-03-31 13:38:25.000000000 +0000
+++ /tmp/wklog.112.new.12166 2010-03-31 13:38:25.000000000 +0000
@@ -1 +1 @@
-Assigned
+Code-Review
-=-=(Knielsen - Wed, 31 Mar 2010, 13:38)=-=-
High-Level Specification modified.
--- /tmp/wklog.112.old.12070 2010-03-31 13:38:08.000000000 +0000
+++ /tmp/wklog.112.new.12070 2010-03-31 13:38:08.000000000 +0000
@@ -15,3 +15,5 @@
Fix OQGraph plug.in to detect boost version >= 1.40.0, and only enable OQGraph
if such boost is found.
+Update the packaging in ourdelta/bakery to include the oqgraph_engine.so and
+link with g++ rather than gcc.
-=-=(Knielsen - Mon, 29 Mar 2010, 21:46)=-=-
High-Level Specification modified.
--- /tmp/wklog.112.old.31142 2010-03-29 21:46:11.000000000 +0000
+++ /tmp/wklog.112.new.31142 2010-03-29 21:46:11.000000000 +0000
@@ -1,28 +1,17 @@
Tasks:
-Find the latest version of OQGraph to base this on (there should be a
-Launchpad branch somewhere, match it up with what is in the OQGraph patch for
-MySQL 5.0 in the ourdelta stuff).
-
-Extract the correct version of Boost from the MySQL 5.0 ourdelta patch. This
-is a patched version of Boost fixing a bug that is supposedly fatal for
-OQGraph (details are not known at the time of writing).
+Base work on the Launchpad branch lp:~knielsen/maria/mariadb-5.1-oqgraph
-Document in OQGraph README the need for boost of a specific version, and point
-to where it can be obtained. Also include the patch for boost if the correct
-base version of boost to do this against can be determined.
+OQGraph requires Boost >= 1.40.0 (earlier versions have a bug that affects
+OQGraph).
-Install the patched boost in /usr/local/ on the build machines (release builds
-and selected Buildbot slaves).
+Document in OQGraph README the need for boost of a specific version, and point
+to where it can be obtained.
-Fix OQGraph plug.in to detect correct version of OQGraph that makes the build
-not break. Check which version in Ubuntu starts working (I think it was
-Jaunty), and require at least that version.
-
-Setup some repository or source tarball of the patched boost
-somewhere. Preferably a Launchpad branch or similar (if upstream project can
-be found).
+Install the patched boost in /usr/local/include/boost on the build machines
+(release builds and selected Buildbot slaves). G++ seems to by default look in
+/usr/local/include, so that is sufficient to find it.
-Setup in plug.in or /configure.in appropriate --with-boost=xxx. Or in a pinch,
-we can make do with CFLAGS=-Ixxx, or even default look in /usr/local/.
+Fix OQGraph plug.in to detect boost version >= 1.40.0, and only enable OQGraph
+if such boost is found.
-=-=(Knielsen - Mon, 29 Mar 2010, 18:09)=-=-
High-Level Specification modified.
--- /tmp/wklog.112.old.23061 2010-03-29 18:09:27.000000000 +0000
+++ /tmp/wklog.112.new.23061 2010-03-29 18:09:27.000000000 +0000
@@ -1 +1,28 @@
+Tasks:
+
+Find the latest version of OQGraph to base this on (there should be a
+Launchpad branch somewhere, match it up with what is in the OQGraph patch for
+MySQL 5.0 in the ourdelta stuff).
+
+Extract the correct version of Boost from the MySQL 5.0 ourdelta patch. This
+is a patched version of Boost fixing a bug that is supposedly fatal for
+OQGraph (details are not known at the time of writing).
+
+Document in OQGraph README the need for boost of a specific version, and point
+to where it can be obtained. Also include the patch for boost if the correct
+base version of boost to do this against can be determined.
+
+Install the patched boost in /usr/local/ on the build machines (release builds
+and selected Buildbot slaves).
+
+Fix OQGraph plug.in to detect correct version of OQGraph that makes the build
+not break. Check which version in Ubuntu starts working (I think it was
+Jaunty), and require at least that version.
+
+Setup some repository or source tarball of the patched boost
+somewhere. Preferably a Launchpad branch or similar (if upstream project can
+be found).
+
+Setup in plug.in or /configure.in appropriate --with-boost=xxx. Or in a pinch,
+we can make do with CFLAGS=-Ixxx, or even default look in /usr/local/.
DESCRIPTION:
Get the OQGraph storage engine merged into MariaDB, fixing the remaining
problems blocking the merge.
HIGH-LEVEL SPECIFICATION:
Tasks:
Base work on the Launchpad branch lp:~knielsen/maria/mariadb-5.1-oqgraph
OQGraph requires Boost >= 1.40.0 (earlier versions have a bug that affects
OQGraph).
Document in OQGraph README the need for boost of a specific version, and point
to where it can be obtained.
Install the patched boost in /usr/local/include/boost on the build machines
(release builds and selected Buildbot slaves). G++ seems to by default look in
/usr/local/include, so that is sufficient to find it.
Fix OQGraph plug.in to detect boost version >= 1.40.0, and only enable OQGraph
if such boost is found.
Update the packaging in ourdelta/bakery to include the oqgraph_engine.so and
link with g++ rather than gcc.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

[Maria-developers] Updated (by Knielsen): Merge OQGraph into MariaDB (112)
by worklog-noreply@askmonty.org 31 Mar '10
by worklog-noreply@askmonty.org 31 Mar '10
31 Mar '10
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Merge OQGraph into MariaDB
CREATION DATE..: Mon, 29 Mar 2010, 18:00
SUPERVISOR.....: Knielsen
IMPLEMENTOR....: Knielsen
COPIES TO......:
CATEGORY.......: Server-Sprint
TASK ID........: 112 (http://askmonty.org/worklog/?tid=112)
VERSION........: Server-5.2
STATUS.........: Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 15 (hours remain)
ORIG. ESTIMATE.: 15
PROGRESS NOTES:
-=-=(Knielsen - Wed, 31 Mar 2010, 13:38)=-=-
High-Level Specification modified.
--- /tmp/wklog.112.old.12070 2010-03-31 13:38:08.000000000 +0000
+++ /tmp/wklog.112.new.12070 2010-03-31 13:38:08.000000000 +0000
@@ -15,3 +15,5 @@
Fix OQGraph plug.in to detect boost version >= 1.40.0, and only enable OQGraph
if such boost is found.
+Update the packaging in ourdelta/bakery to include the oqgraph_engine.so and
+link with g++ rather than gcc.
-=-=(Knielsen - Mon, 29 Mar 2010, 21:46)=-=-
High-Level Specification modified.
--- /tmp/wklog.112.old.31142 2010-03-29 21:46:11.000000000 +0000
+++ /tmp/wklog.112.new.31142 2010-03-29 21:46:11.000000000 +0000
@@ -1,28 +1,17 @@
Tasks:
-Find the latest version of OQGraph to base this on (there should be a
-Launchpad branch somewhere, match it up with what is in the OQGraph patch for
-MySQL 5.0 in the ourdelta stuff).
-
-Extract the correct version of Boost from the MySQL 5.0 ourdelta patch. This
-is a patched version of Boost fixing a bug that is supposedly fatal for
-OQGraph (details are not known at the time of writing).
+Base work on the Launchpad branch lp:~knielsen/maria/mariadb-5.1-oqgraph
-Document in OQGraph README the need for boost of a specific version, and point
-to where it can be obtained. Also include the patch for boost if the correct
-base version of boost to do this against can be determined.
+OQGraph requires Boost >= 1.40.0 (earlier versions have a bug that affects
+OQGraph).
-Install the patched boost in /usr/local/ on the build machines (release builds
-and selected Buildbot slaves).
+Document in OQGraph README the need for boost of a specific version, and point
+to where it can be obtained.
-Fix OQGraph plug.in to detect correct version of OQGraph that makes the build
-not break. Check which version in Ubuntu starts working (I think it was
-Jaunty), and require at least that version.
-
-Setup some repository or source tarball of the patched boost
-somewhere. Preferably a Launchpad branch or similar (if upstream project can
-be found).
+Install the patched boost in /usr/local/include/boost on the build machines
+(release builds and selected Buildbot slaves). G++ seems to by default look in
+/usr/local/include, so that is sufficient to find it.
-Setup in plug.in or /configure.in appropriate --with-boost=xxx. Or in a pinch,
-we can make do with CFLAGS=-Ixxx, or even default look in /usr/local/.
+Fix OQGraph plug.in to detect boost version >= 1.40.0, and only enable OQGraph
+if such boost is found.
-=-=(Knielsen - Mon, 29 Mar 2010, 18:09)=-=-
High-Level Specification modified.
--- /tmp/wklog.112.old.23061 2010-03-29 18:09:27.000000000 +0000
+++ /tmp/wklog.112.new.23061 2010-03-29 18:09:27.000000000 +0000
@@ -1 +1,28 @@
+Tasks:
+
+Find the latest version of OQGraph to base this on (there should be a
+Launchpad branch somewhere, match it up with what is in the OQGraph patch for
+MySQL 5.0 in the ourdelta stuff).
+
+Extract the correct version of Boost from the MySQL 5.0 ourdelta patch. This
+is a patched version of Boost fixing a bug that is supposedly fatal for
+OQGraph (details are not known at the time of writing).
+
+Document in OQGraph README the need for boost of a specific version, and point
+to where it can be obtained. Also include the patch for boost if the correct
+base version of boost to do this against can be determined.
+
+Install the patched boost in /usr/local/ on the build machines (release builds
+and selected Buildbot slaves).
+
+Fix OQGraph plug.in to detect correct version of OQGraph that makes the build
+not break. Check which version in Ubuntu starts working (I think it was
+Jaunty), and require at least that version.
+
+Setup some repository or source tarball of the patched boost
+somewhere. Preferably a Launchpad branch or similar (if upstream project can
+be found).
+
+Setup in plug.in or /configure.in appropriate --with-boost=xxx. Or in a pinch,
+we can make do with CFLAGS=-Ixxx, or even default look in /usr/local/.
DESCRIPTION:
Get the OQGraph storage engine merged into MariaDB, fixing the remaining
problems blocking the merge.
HIGH-LEVEL SPECIFICATION:
Tasks:
Base work on the Launchpad branch lp:~knielsen/maria/mariadb-5.1-oqgraph
OQGraph requires Boost >= 1.40.0 (earlier versions have a bug that affects
OQGraph).
Document in OQGraph README the need for boost of a specific version, and point
to where it can be obtained.
Install the patched boost in /usr/local/include/boost on the build machines
(release builds and selected Buildbot slaves). G++ seems to by default look in
/usr/local/include, so that is sufficient to find it.
Fix OQGraph plug.in to detect boost version >= 1.40.0, and only enable OQGraph
if such boost is found.
Update the packaging in ourdelta/bakery to include the oqgraph_engine.so and
link with g++ rather than gcc.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0

Re: [Maria-developers] [Bug 544173] [NEW] Server crash for multi-engine transaction with binlog disabled
by Sergei Golubchik 31 Mar '10
by Sergei Golubchik 31 Mar '10
31 Mar '10
Hi, Paul!
On Mar 31, Paul McCullagh wrote:
> On Mar 25, 2010, at 10:24 PM, Sergei Golubchik wrote:
>> Hi, MARK!
>>
>> On Mar 25, MARK CALLAGHAN wrote:
>>> On Wed, Mar 24, 2010 at 5:28 PM, Arjen Lentz <arjen(a)openquery.com> wrote:
>>>> This test is as important as the above crash, because multi-engine
>>>> transactions are something people will be using and thus relying on
>>>> correctly working
>>>
>>> I won't use this. We have enough problems when limited to one
>>> storage engine. All of those should be fixed first. If I want to use
>>> PBXT (and I do) then I will stop using InnoDB (and I might).
>>>
>>> When will we have cross-engine deadlock detection?
>>
>> When storage engines will start using a central server-wide deadlock
>> detector (that exists).
>
> Interesting... I did not know that this existed.
>
> Any idea of the performance? As we have seen from Mark's blog, it can
> be critical.
I've written it for Maria engine, but as a server global (not Maria
engine specific) detector detector. It could be used by other server
components.
Because it's not really used yet (besides stress unit tests), I couldn't
compare the performance with anything or come up with any meaningful
performance numbers.
It has no global mutexes, every node of a global wait-for graph has an
individual lock, so any number of threads may modify different parts of
the wait-for graph without waiting for each other.
It's not a lock manager, but only a deadlock detector - in a sense it's
"wait manager", an engine (or any other server subsystem) only needs to
use it before starting to wait on anything, in a simplified view
it's a replacement for pthread_cond_wait.
Regards,
Sergei
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (knielsen:2762)
by knielsen@knielsen-hq.org 31 Mar '10
by knielsen@knielsen-hq.org 31 Mar '10
31 Mar '10
#At lp:maria/5.2
2762 knielsen(a)knielsen-hq.org 2010-03-31
Fix type in merge, breaking `make dist` for oqgraph.
modified:
mysql-test/Makefile.am
=== modified file 'mysql-test/Makefile.am'
--- a/mysql-test/Makefile.am 2010-03-31 08:17:03 +0000
+++ b/mysql-test/Makefile.am 2010-03-31 09:43:19 +0000
@@ -103,7 +103,7 @@ TEST_DIRS = t r include std_data std_dat
suite/parts suite/parts/t suite/parts/r suite/parts/inc \
suite/pbxt/t suite/pbxt/r \
suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \
- suite/vcol suite/vcol/t suite/vcol/r suite/vcol/inc
+ suite/vcol suite/vcol/t suite/vcol/r suite/vcol/inc \
suite/oqgraph suite/oqgraph/t suite/oqgraph/r suite/oqgraph/include
# Used by dist-hook and install-data-local to copy all
1
0

[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (knielsen:2761)
by knielsen@knielsen-hq.org 31 Mar '10
by knielsen@knielsen-hq.org 31 Mar '10
31 Mar '10
#At lp:maria/5.2
2761 knielsen(a)knielsen-hq.org 2010-03-31 [merge]
Merge OQGraph into MariaDB 5.2.
(and in the process, fix compile-bintar to link C++ with g++ rather than gcc).
added:
mysql-test/suite/oqgraph/
mysql-test/suite/oqgraph/include/
mysql-test/suite/oqgraph/include/have_oqgraph_engine.inc
mysql-test/suite/oqgraph/r/
mysql-test/suite/oqgraph/r/basic.result
mysql-test/suite/oqgraph/t/
mysql-test/suite/oqgraph/t/basic-master.opt
mysql-test/suite/oqgraph/t/basic.test
mysql-test/suite/pbxt/r/pbxt_xa.result
mysql-test/suite/pbxt/t/pbxt_xa.test
mysql-test/suite/pbxt/t/suite.opt
storage/oqgraph/
storage/oqgraph/CMakeFiles.txt
storage/oqgraph/Makefile.am
storage/oqgraph/README
storage/oqgraph/graphcore-graph.h
storage/oqgraph/graphcore-types.h
storage/oqgraph/graphcore.cc
storage/oqgraph/graphcore.h
storage/oqgraph/graphstore.c
storage/oqgraph/graphstore.h
storage/oqgraph/ha_oqgraph.cc
storage/oqgraph/ha_oqgraph.h
storage/oqgraph/oqgraph_config.h.in
storage/oqgraph/oqgraph_probes.d
storage/oqgraph/plug.in
modified:
BUILD/SETUP.sh
BUILD/compile-bintar
extra/comp_err.c
extra/libevent/kqueue.c
mysql-test/Makefile.am
mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test
mysql-test/include/default_mysqld.cnf
mysql-test/lib/My/SafeProcess/safe_process.cc
mysql-test/lib/mtr_cases.pm
mysql-test/lib/v1/mysql-test-run.pl
mysql-test/mysql-test-run.pl
mysql-test/suite/parts/t/rpl_partition.test
mysql-test/suite/rpl/r/rpl_do_grant.result
mysql-test/suite/rpl/t/rpl_do_grant.test
mysql-test/suite/rpl/t/rpl_name_const.test
mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
mysql-test/suite/rpl/t/rpl_row_trig003.test
mysql-test/t/bug47671-master.opt
mysql-test/t/ctype_latin1_de-master.opt
mysql-test/t/ctype_ucs2_def-master.opt
mysys/mf_keycache.c
mysys/my_gethostbyname.c
sql/handler.cc
sql/item.cc
sql/item.h
sql/item_cmpfunc.cc
sql/item_create.cc
sql/item_create.h
sql/item_sum.cc
sql/item_sum.h
sql/log.cc
sql/mysqld.cc
sql/net_serv.cc
sql/set_var.cc
sql/sql_class.h
sql/sql_table.cc
sql/sql_view.cc
sql/sql_yacc.yy
storage/example/ha_example.h
storage/maria/ma_loghandler.c
storage/maria/ma_search.c
storage/maria/maria_def.h
storage/myisam/ft_stopwords.c
storage/myisammrg/ha_myisammrg.cc
storage/myisammrg/myrg_open.c
storage/xtradb/include/page0page.h
storage/xtradb/include/page0page.ic
storage/xtradb/include/ut0lst.h
strings/ctype-ucs2.c
strings/ctype-utf8.c
support-files/compiler_warnings.supp
unittest/mysys/waiting_threads-t.c
=== modified file 'BUILD/SETUP.sh'
--- a/BUILD/SETUP.sh 2010-01-07 12:02:18 +0000
+++ b/BUILD/SETUP.sh 2010-03-30 16:16:57 +0000
@@ -204,7 +204,7 @@ if test -z "$CC" ; then
fi
if test -z "$CXX" ; then
- CXX=gcc
+ CXX=g++
fi
# If ccache (a compiler cache which reduces build time)
=== modified file 'BUILD/compile-bintar'
--- a/BUILD/compile-bintar 2010-01-07 12:02:18 +0000
+++ b/BUILD/compile-bintar 2010-03-31 08:17:03 +0000
@@ -32,8 +32,7 @@
# .so files at runtime (either system stuff like NSS, or server
# plugins).
#
-# We link libgcc statically (and avoid linking libstdc++ at all by
-# CXX=gcc), to avoid reduce nasty library version dependencies.
+# We link libgcc statically to avoid reduce nasty library version dependencies.
test -f Makefile && make distclean
@@ -52,13 +51,12 @@ get_cpuopt
get_make_parallel_flag
# Use gcc rather than g++ to avoid linking libstdc++.so (which we don't need).
-COMP="gcc -static-libgcc"
FLAGS="-O2 -fno-omit-frame-pointer -g -pipe -Wall $CPUOPT"
# Don't press on in case of error.
set -e
-CC="$COMP" CXX="$COMP" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \
+CC="gcc -static-libgcc" CXX="g++ -static-libgcc" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \
./configure \
--prefix=/usr/local/mysql \
--exec-prefix=/usr/local/mysql \
=== modified file 'extra/comp_err.c'
--- a/extra/comp_err.c 2009-11-20 10:11:31 +0000
+++ b/extra/comp_err.c 2010-03-30 12:36:49 +0000
@@ -660,7 +660,7 @@ static ha_checksum checksum_format_speci
case 'u':
case 'x':
case 's':
- chksum= my_checksum(chksum, start, (uint) (p + 1 - start));
+ chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start));
start= 0; /* Not in format specifier anymore */
break;
=== modified file 'extra/libevent/kqueue.c'
--- a/extra/libevent/kqueue.c 2009-03-12 22:27:35 +0000
+++ b/extra/libevent/kqueue.c 2010-03-30 12:36:49 +0000
@@ -144,7 +144,7 @@ kq_init(struct event_base *base)
*/
if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
- kqueueop->events[0].ident != -1 ||
+ ((int) kqueueop->events[0].ident) != -1 ||
kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue; not using.", __func__);
free(kqueueop->changes);
=== modified file 'mysql-test/Makefile.am'
--- a/mysql-test/Makefile.am 2010-03-18 12:08:39 +0000
+++ b/mysql-test/Makefile.am 2010-03-31 08:17:03 +0000
@@ -104,6 +104,7 @@ TEST_DIRS = t r include std_data std_dat
suite/pbxt/t suite/pbxt/r \
suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \
suite/vcol suite/vcol/t suite/vcol/r suite/vcol/inc
+ suite/oqgraph suite/oqgraph/t suite/oqgraph/r suite/oqgraph/include
# Used by dist-hook and install-data-local to copy all
# test files into either dist or install directory
=== modified file 'mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test'
--- a/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-01-22 09:38:21 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-03-28 18:10:00 +0000
@@ -157,3 +157,4 @@ INSERT INTO t1 VALUES (1);
DROP TEMPORARY TABLE t1;
+--sync_slave_with_master
=== modified file 'mysql-test/include/default_mysqld.cnf'
--- a/mysql-test/include/default_mysqld.cnf 2008-04-08 14:51:26 +0000
+++ b/mysql-test/include/default_mysqld.cnf 2010-03-28 18:10:00 +0000
@@ -2,7 +2,7 @@
[mysqld]
open-files-limit= 1024
local-infile
-default-character-set= latin1
+character-set-server= latin1
# Increase default connect_timeout to avoid intermittent
# disconnects when test servers are put under load see BUG#28359
=== modified file 'mysql-test/lib/My/SafeProcess/safe_process.cc'
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc 2009-07-08 12:31:22 +0000
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc 2010-03-28 18:10:00 +0000
@@ -159,7 +159,7 @@ int main(int argc, char* const argv[] )
signal(SIGCHLD, handle_signal);
signal(SIGABRT, handle_abort);
- sprintf(safe_process_name, "safe_process[%d]", own_pid);
+ sprintf(safe_process_name, "safe_process[%d]", (int) own_pid);
message("Started");
=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm 2010-01-15 15:27:55 +0000
+++ b/mysql-test/lib/mtr_cases.pm 2010-03-30 16:16:57 +0000
@@ -681,6 +681,8 @@ sub optimize_cases {
if ( $default_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
if ( $default_engine =~ /^innodb/i );
+ $tinfo->{'pbxt_test'}= 1
+ if ( $default_engine =~ /^pbxt/i );
}
}
@@ -778,6 +780,8 @@ sub collect_one_test_case {
my $disabled= shift;
my $suite_opts= shift;
+ my $local_default_storage_engine= $default_storage_engine;
+
#print "collect_one_test_case\n";
#print " suitedir: $suitedir\n";
#print " testdir: $testdir\n";
@@ -932,15 +936,26 @@ sub collect_one_test_case {
tags_from_test_file($tinfo,"$testdir/${tname}.test");
- if ( defined $default_storage_engine )
+ # Get default storage engine from suite.opt file
+
+ if (defined $suite_opts &&
+ "@$suite_opts" =~ "default-storage-engine=\s*([^\s]*)")
+ {
+ $local_default_storage_engine= $1;
+ }
+
+ if ( defined $local_default_storage_engine )
{
# Different default engine is used
# tag test to require that engine
$tinfo->{'ndb_test'}= 1
- if ( $default_storage_engine =~ /^ndb/i );
+ if ( $local_default_storage_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
- if ( $default_storage_engine =~ /^innodb/i );
+ if ( $local_default_storage_engine =~ /^innodb/i );
+
+ $tinfo->{'pbxt_test'}= 1
+ if ( $local_default_storage_engine =~ /^pbxt/i );
}
@@ -1103,6 +1118,28 @@ sub collect_one_test_case {
$tinfo->{template_path}= $config;
}
+ if ( $tinfo->{'pbxt_test'} )
+ {
+ # This is a test that needs pbxt
+ if ( $::mysqld_variables{'pbxt'} eq "OFF" ||
+ ! exists $::mysqld_variables{'pbxt'} )
+ {
+ # Engine is not supported, skip it
+ $tinfo->{'skip'}= 1;
+ return $tinfo;
+ }
+ }
+ else
+ {
+ # Only disable engine if it's on by default (to avoid warnings about
+ # not existing loose options
+ if ( $::mysqld_variables{'pbxt'} eq "ON")
+ {
+ push(@{$tinfo->{'master_opt'}}, "--loose-skip-pbxt");
+ push(@{$tinfo->{'slave_opt'}}, "--loose-skip-pbxt");
+ }
+ }
+
if ( $tinfo->{'example_plugin_test'} )
{
if ( !$ENV{'EXAMPLE_PLUGIN'} )
@@ -1113,6 +1150,16 @@ sub collect_one_test_case {
}
}
+ if ( $tinfo->{'oqgraph_test'} )
+ {
+ if ( !$ENV{'OQGRAPH_PLUGIN'} )
+ {
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "Test requires the OQGraph storage engine";
+ return $tinfo;
+ }
+ }
+
# Set extra config file to use
if (defined $defaults_extra_file) {
@@ -1156,6 +1203,7 @@ my @tags=
["include/have_log_bin.inc", "need_binlog", 1],
["include/have_innodb.inc", "innodb_test", 1],
+ ["include/have_pbxt.inc", "pbxt_test", 1],
["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1],
["include/have_ndb.inc", "ndb_test", 1],
@@ -1167,6 +1215,7 @@ my @tags=
["include/not_embedded.inc", "not_embedded", 1],
["include/not_valgrind.inc", "not_valgrind", 1],
["include/have_example_plugin.inc", "example_plugin_test", 1],
+ ["include/have_oqgraph_engine.inc", "oqgraph_test", 1],
["include/have_ssl.inc", "need_ssl", 1],
);
=== modified file 'mysql-test/lib/v1/mysql-test-run.pl'
--- a/mysql-test/lib/v1/mysql-test-run.pl 2010-03-04 08:03:07 +0000
+++ b/mysql-test/lib/v1/mysql-test-run.pl 2010-03-28 18:10:00 +0000
@@ -3965,7 +3965,7 @@ sub mysqld_arguments ($$$$) {
}
}
- mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
+ mtr_add_arg($args, "%s--character-set-server-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl 2010-02-19 08:10:05 +0000
+++ b/mysql-test/mysql-test-run.pl 2010-03-31 08:17:03 +0000
@@ -126,7 +126,7 @@ my $path_config_file; # The ge
# executables will be used by the test suite.
our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
-my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,vcol";
+my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,vcol,oqgraph";
my $opt_suites;
our $opt_verbose= 0; # Verbose output, enable with --verbose
@@ -1909,6 +1909,33 @@ sub detect_plugins {
$ENV{'HA_EXAMPLE_SO'}="'".$plugin_filename."'";
$ENV{'EXAMPLE_PLUGIN_LOAD'}="--plugin_load=EXAMPLE=".$plugin_filename;
}
+
+ # --------------------------------------------------------------------------
+ # Add the path where mysqld will find graph_engine.so
+ # --------------------------------------------------------------------------
+ if ($mysql_version_id >= 50100 && !(IS_WINDOWS && $opt_embedded_server)) {
+ my $plugin_filename;
+ if (IS_WINDOWS)
+ {
+ $plugin_filename = "oqgraph_engine.dll";
+ }
+ else
+ {
+ $plugin_filename = "oqgraph_engine.so";
+ }
+ my $lib_oqgraph_plugin=
+ mtr_file_exists(vs_config_dirs('storage/oqgraph',$plugin_filename),
+ "$basedir/storage/oqgraph/.libs/".$plugin_filename,
+ "$basedir/lib/mariadb/plugin/".$plugin_filename,
+ "$basedir/lib/mysql/plugin/".$plugin_filename);
+ $ENV{'OQGRAPH_PLUGIN'}=
+ ($lib_oqgraph_plugin ? basename($lib_oqgraph_plugin) : "");
+ $ENV{'OQGRAPH_PLUGIN_OPT'}= "--plugin-dir=".
+ ($lib_oqgraph_plugin ? dirname($lib_oqgraph_plugin) : "");
+
+ $ENV{'GRAPH_ENGINE_SO'}="'".$plugin_filename."'";
+ $ENV{'OQGRAPH_PLUGIN_LOAD'}="--plugin_load=;OQGRAPH=".$plugin_filename.";";
+ }
}
#
=== added directory 'mysql-test/suite/oqgraph'
=== added directory 'mysql-test/suite/oqgraph/include'
=== added file 'mysql-test/suite/oqgraph/include/have_oqgraph_engine.inc'
--- a/mysql-test/suite/oqgraph/include/have_oqgraph_engine.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/oqgraph/include/have_oqgraph_engine.inc 2010-01-04 08:27:50 +0000
@@ -0,0 +1,4 @@
+disable_query_log;
+--require r/true.require
+select (PLUGIN_LIBRARY LIKE 'oqgraph_engine%') as `TRUE` from information_schema.plugins where PLUGIN_NAME='OQGRAPH';
+enable_query_log;
=== added directory 'mysql-test/suite/oqgraph/r'
=== added file 'mysql-test/suite/oqgraph/r/basic.result'
--- a/mysql-test/suite/oqgraph/r/basic.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/oqgraph/r/basic.result 2010-01-04 08:27:50 +0000
@@ -0,0 +1,63 @@
+drop table if exists graph;
+Warnings:
+Note 1051 Unknown table 'graph'
+CREATE TABLE graph (
+latch SMALLINT UNSIGNED NULL,
+origid BIGINT UNSIGNED NULL,
+destid BIGINT UNSIGNED NULL,
+weight DOUBLE NULL,
+seq BIGINT UNSIGNED NULL,
+linkid BIGINT UNSIGNED NULL,
+KEY (latch, origid, destid) USING HASH,
+KEY (latch, destid, origid) USING HASH
+) ENGINE=OQGRAPH;
+delete from graph;
+insert into graph(origid, destid) values (1,2), (2,1);
+insert into graph(origid, destid) values (1,3), (3,1);
+insert into graph(origid, destid) values (3,4), (4,3);
+insert into graph(origid, destid) values (3,5), (5,3);
+insert into graph(origid, destid) values (5,6), (6,5);
+select * from graph where latch = 2 and origid = 1 and weight = 1;
+latch origid destid weight seq linkid
+2 1 NULL 1 3 3
+2 1 NULL 1 2 2
+select * from graph where latch = 2 and origid = 1 and weight = 2;
+latch origid destid weight seq linkid
+2 1 NULL 2 5 5
+2 1 NULL 2 4 4
+select * from graph
+where latch = 2 and origid = 1 and (weight = 1 or weight = 2);
+latch origid destid weight seq linkid
+2 1 NULL 2 5 5
+2 1 NULL 2 4 4
+2 1 NULL 1 3 3
+2 1 NULL 1 2 2
+select * from graph where latch=1 and origid=1 and destid=6;
+latch origid destid weight seq linkid
+1 1 6 NULL 0 1
+1 1 6 1 1 3
+1 1 6 1 2 5
+1 1 6 1 3 6
+select * from graph where latch=1 and origid=1 and destid=4;
+latch origid destid weight seq linkid
+1 1 4 NULL 0 1
+1 1 4 1 1 3
+1 1 4 1 2 4
+select * from graph where latch=1 and origid=4 and destid=1;
+latch origid destid weight seq linkid
+1 4 1 NULL 0 4
+1 4 1 1 1 3
+1 4 1 1 2 1
+insert into graph (origid,destid) values (4,6);
+delete from graph where origid=5;
+delete from graph where origid=3 and destid=5;
+select * from graph where latch=1 and origid=1 and destid=6;
+latch origid destid weight seq linkid
+1 1 6 NULL 0 1
+1 1 6 1 1 3
+1 1 6 1 2 4
+1 1 6 1 3 6
+select * from graph where latch=1 and origid=6 and destid=1;
+latch origid destid weight seq linkid
+truncate table graph;
+drop table graph;
=== added directory 'mysql-test/suite/oqgraph/t'
=== added file 'mysql-test/suite/oqgraph/t/basic-master.opt'
--- a/mysql-test/suite/oqgraph/t/basic-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/oqgraph/t/basic-master.opt 2010-01-04 08:27:50 +0000
@@ -0,0 +1,2 @@
+$OQGRAPH_PLUGIN_OPT
+$OQGRAPH_PLUGIN_LOAD
=== added file 'mysql-test/suite/oqgraph/t/basic.test'
--- a/mysql-test/suite/oqgraph/t/basic.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/oqgraph/t/basic.test 2010-01-04 08:27:50 +0000
@@ -0,0 +1,45 @@
+-- source suite/oqgraph/include/have_oqgraph_engine.inc
+
+drop table if exists graph;
+
+CREATE TABLE graph (
+ latch SMALLINT UNSIGNED NULL,
+ origid BIGINT UNSIGNED NULL,
+ destid BIGINT UNSIGNED NULL,
+ weight DOUBLE NULL,
+ seq BIGINT UNSIGNED NULL,
+ linkid BIGINT UNSIGNED NULL,
+ KEY (latch, origid, destid) USING HASH,
+ KEY (latch, destid, origid) USING HASH
+ ) ENGINE=OQGRAPH;
+
+delete from graph;
+
+insert into graph(origid, destid) values (1,2), (2,1);
+insert into graph(origid, destid) values (1,3), (3,1);
+insert into graph(origid, destid) values (3,4), (4,3);
+insert into graph(origid, destid) values (3,5), (5,3);
+insert into graph(origid, destid) values (5,6), (6,5);
+
+select * from graph where latch = 2 and origid = 1 and weight = 1;
+
+select * from graph where latch = 2 and origid = 1 and weight = 2;
+
+select * from graph
+where latch = 2 and origid = 1 and (weight = 1 or weight = 2);
+
+select * from graph where latch=1 and origid=1 and destid=6;
+select * from graph where latch=1 and origid=1 and destid=4;
+select * from graph where latch=1 and origid=4 and destid=1;
+
+insert into graph (origid,destid) values (4,6);
+
+delete from graph where origid=5;
+delete from graph where origid=3 and destid=5;
+
+select * from graph where latch=1 and origid=1 and destid=6;
+select * from graph where latch=1 and origid=6 and destid=1;
+
+truncate table graph;
+
+drop table graph;
=== modified file 'mysql-test/suite/parts/t/rpl_partition.test'
--- a/mysql-test/suite/parts/t/rpl_partition.test 2009-02-01 12:00:48 +0000
+++ b/mysql-test/suite/parts/t/rpl_partition.test 2010-03-29 19:07:45 +0000
@@ -1,6 +1,7 @@
--source include/have_partition.inc
--source include/have_innodb.inc
--source include/master-slave.inc
+--source include/big_test.inc
--vertical_results
=== added file 'mysql-test/suite/pbxt/r/pbxt_xa.result'
--- a/mysql-test/suite/pbxt/r/pbxt_xa.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/r/pbxt_xa.result 2010-03-24 22:12:39 +0000
@@ -0,0 +1,18 @@
+drop table if exists t1, t2;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+SELECT @@log_bin;
+@@log_bin
+0
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+a
+1
+select * from t2;
+b
+2
+drop table t1, t2;
+drop database pbxt;
=== added file 'mysql-test/suite/pbxt/t/pbxt_xa.test'
--- a/mysql-test/suite/pbxt/t/pbxt_xa.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/pbxt_xa.test 2010-03-24 22:12:39 +0000
@@ -0,0 +1,23 @@
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+#
+# bug lp:544173, xa crash with two 2pc-capable storage engines without binlog
+#
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+# verify that binlog is off
+SELECT @@log_bin;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+select * from t2;
+drop table t1, t2;
+drop database pbxt;
+
=== added file 'mysql-test/suite/pbxt/t/suite.opt'
--- a/mysql-test/suite/pbxt/t/suite.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/suite.opt 2010-03-30 12:36:49 +0000
@@ -0,0 +1 @@
+--default-storage-engine=pbxt
=== modified file 'mysql-test/suite/rpl/r/rpl_do_grant.result'
--- a/mysql-test/suite/rpl/r/rpl_do_grant.result 2010-03-16 12:38:35 +0000
+++ b/mysql-test/suite/rpl/r/rpl_do_grant.result 2010-03-31 08:17:03 +0000
@@ -165,10 +165,9 @@ USE test;
DROP FUNCTION bug42217_db.upgrade_del_func;
DROP FUNCTION bug42217_db.upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
-USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+stop slave;
+DROP USER 'create_rout_db'@'localhost';
######## BUG#49119 #######
### i) test case from the 'how to repeat section'
stop slave;
=== modified file 'mysql-test/suite/rpl/t/rpl_do_grant.test'
--- a/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-03-16 12:38:35 +0000
+++ b/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-03-31 08:17:03 +0000
@@ -209,12 +209,18 @@ USE test;
DROP FUNCTION bug42217_db.upgrade_del_func;
DROP FUNCTION bug42217_db.upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+
+sync_slave_with_master;
+
+# Drop the user that was already dropped on the slave
connection slave;
-USE mtr;
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+--disable_warnings
+stop slave;
+connection master;
+DROP USER 'create_rout_db'@'localhost';
+--enable_warnings
# BUG#49119: Master crashes when executing 'REVOKE ... ON
# {PROCEDURE|FUNCTION} FROM ...'
=== modified file 'mysql-test/suite/rpl/t/rpl_name_const.test'
--- a/mysql-test/suite/rpl/t/rpl_name_const.test 2009-04-08 23:42:51 +0000
+++ b/mysql-test/suite/rpl/t/rpl_name_const.test 2010-03-28 18:10:00 +0000
@@ -45,3 +45,4 @@ select * from t1 order by id;
connection master;
drop table t1;
drop procedure test_procedure;
+--sync_slave_with_master
=== modified file 'mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test'
--- a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2007-12-12 10:14:59 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2010-03-28 18:10:00 +0000
@@ -53,6 +53,7 @@ UPDATE t1 SET a=99 WHERE a = 0;
SHOW BINLOG EVENTS;
DROP TABLE t1;
+--sync_slave_with_master
# BUG#17620: Replicate (Row Based) Fails when Query Cache enabled on
# slave
=== modified file 'mysql-test/suite/rpl/t/rpl_row_trig003.test'
--- a/mysql-test/suite/rpl/t/rpl_row_trig003.test 2007-12-06 15:27:10 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_trig003.test 2010-03-29 19:07:45 +0000
@@ -149,6 +149,8 @@ DROP TABLE IF EXISTS test.t2;
DROP TABLE IF EXISTS test.t3;
--enable_warnings
+sync_slave_with_master;
+
diff_files $MYSQLTEST_VARDIR/tmp/trg003_master.sql $MYSQLTEST_VARDIR/tmp/trg003_slave.sql;
# End of 5.0 test case
=== modified file 'mysql-test/t/bug47671-master.opt'
--- a/mysql-test/t/bug47671-master.opt 2009-11-25 06:55:49 +0000
+++ b/mysql-test/t/bug47671-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-character-set=utf8 --skip-character-set-client-handshake
+--character-set-server=utf8 --skip-character-set-client-handshake
=== modified file 'mysql-test/t/ctype_latin1_de-master.opt'
--- a/mysql-test/t/ctype_latin1_de-master.opt 2003-05-21 23:57:27 +0000
+++ b/mysql-test/t/ctype_latin1_de-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-character-set=latin1 --default-collation=latin1_german2_ci
+--character-set-server=latin1 --default-collation=latin1_german2_ci
=== modified file 'mysql-test/t/ctype_ucs2_def-master.opt'
--- a/mysql-test/t/ctype_ucs2_def-master.opt 2007-02-19 11:04:38 +0000
+++ b/mysql-test/t/ctype_ucs2_def-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-collation=ucs2_unicode_ci --default-character-set=ucs2,latin1
+--default-collation=ucs2_unicode_ci --character-set-server=ucs2,latin1
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2009-12-03 11:19:05 +0000
+++ b/mysys/mf_keycache.c 2010-03-30 12:36:49 +0000
@@ -3924,6 +3924,12 @@ restart:
uint next_status;
uint hash_requests;
+ LINT_INIT(next_hash_link);
+ LINT_INIT(next_diskpos);
+ LINT_INIT(next_file);
+ LINT_INIT(next_status);
+ LINT_INIT(hash_requests);
+
total_found++;
found++;
KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used);
=== modified file 'mysys/my_gethostbyname.c'
--- a/mysys/my_gethostbyname.c 2006-12-31 00:32:21 +0000
+++ b/mysys/my_gethostbyname.c 2010-03-30 12:36:49 +0000
@@ -91,9 +91,12 @@ extern pthread_mutex_t LOCK_gethostbynam
is finished with the structure.
*/
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
+struct hostent *
+my_gethostbyname_r(const char *name,
+ struct hostent *result __attribute__((unused)),
+ char *buffer __attribute__((unused)),
+ int buflen__attribute__((unused)),
+ int *h_errnop)
{
struct hostent *hp;
pthread_mutex_lock(&LOCK_gethostbyname_r);
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-03-25 13:33:39 +0000
+++ b/sql/handler.cc 2010-03-31 08:17:03 +0000
@@ -4252,7 +4252,7 @@ int handler::read_multi_range_first(KEY_
*/
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
- int result;
+ int result= 0;
DBUG_ENTER("handler::read_multi_range_next");
/* We should not be called after the last call returned EOF. */
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2010-03-15 11:51:23 +0000
+++ b/sql/item.cc 2010-03-31 08:17:03 +0000
@@ -7040,7 +7040,7 @@ bool Item_cache_int::cache_value()
}
-void Item_cache_int::store(Item *item, longlong val_arg)
+void Item_cache_int::store_longlong(Item *item, longlong val_arg)
{
/* An explicit values is given, save it. */
value_cached= TRUE;
=== modified file 'sql/item.h'
--- a/sql/item.h 2010-03-15 11:51:23 +0000
+++ b/sql/item.h 2010-03-31 08:17:03 +0000
@@ -1132,7 +1132,8 @@ class Field_enumerator
{
public:
virtual void visit_field(Field *field)= 0;
- virtual ~Field_enumerator() {}; /* purecov: inspected */
+ virtual ~Field_enumerator() {}; /* purecov: inspected */
+ Field_enumerator() {} /* Remove gcc warning */
};
@@ -3148,7 +3149,7 @@ public:
Item_cache_int(enum_field_types field_type_arg):
Item_cache(field_type_arg), value(0) {}
- void store(Item *item, longlong val_arg);
+ void store_longlong(Item *item, longlong val_arg);
double val_real();
longlong val_int();
String* val_str(String *str);
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2010-03-04 08:03:07 +0000
+++ b/sql/item_cmpfunc.cc 2010-03-28 18:10:00 +0000
@@ -879,7 +879,7 @@ get_time_value(THD *thd, Item ***item_ar
Item_cache_int *cache= new Item_cache_int();
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
@@ -917,13 +917,13 @@ int Arg_comparator::set_cmp_func(Item_re
cache->set_used_tables(1);
if (!(*a)->is_datetime())
{
- cache->store((*a), const_value);
+ cache->store_longlong((*a), const_value);
a_cache= cache;
a= (Item **)&a_cache;
}
else
{
- cache->store((*b), const_value);
+ cache->store_longlong((*b), const_value);
b_cache= cache;
b= (Item **)&b_cache;
}
@@ -1145,7 +1145,7 @@ get_datetime_value(THD *thd, Item ***ite
Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
=== modified file 'sql/item_create.cc'
--- a/sql/item_create.cc 2010-03-04 08:03:07 +0000
+++ b/sql/item_create.cc 2010-03-29 19:07:45 +0000
@@ -76,7 +76,7 @@ public:
@param thd The current thread
@return An item representing the function call
*/
- virtual Item *create(THD *thd) = 0;
+ virtual Item *create_builder(THD *thd) = 0;
protected:
/** Constructor. */
@@ -101,7 +101,7 @@ public:
@param arg1 The first argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1) = 0;
+ virtual Item *create_1_arg(THD *thd, Item *arg1) = 0;
protected:
/** Constructor. */
@@ -127,7 +127,7 @@ public:
@param arg2 The second argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2) = 0;
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) = 0;
protected:
/** Constructor. */
@@ -154,7 +154,7 @@ public:
@param arg3 The third argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
protected:
/** Constructor. */
@@ -171,8 +171,8 @@ protected:
class Create_sp_func : public Create_qfunc
{
public:
- virtual Item *create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list);
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list);
static Create_sp_func s_singleton;
@@ -217,7 +217,7 @@ protected:
class Create_func_abs : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_abs s_singleton;
@@ -230,7 +230,7 @@ protected:
class Create_func_acos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_acos s_singleton;
@@ -243,7 +243,7 @@ protected:
class Create_func_addtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_addtime s_singleton;
@@ -256,7 +256,7 @@ protected:
class Create_func_aes_encrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_encrypt s_singleton;
@@ -269,7 +269,7 @@ protected:
class Create_func_aes_decrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_decrypt s_singleton;
@@ -283,7 +283,7 @@ protected:
class Create_func_area : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_area s_singleton;
@@ -298,7 +298,7 @@ protected:
class Create_func_as_wkb : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkb s_singleton;
@@ -313,7 +313,7 @@ protected:
class Create_func_as_wkt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkt s_singleton;
@@ -327,7 +327,7 @@ protected:
class Create_func_asin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_asin s_singleton;
@@ -353,7 +353,7 @@ protected:
class Create_func_benchmark : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_benchmark s_singleton;
@@ -366,7 +366,7 @@ protected:
class Create_func_bin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bin s_singleton;
@@ -379,7 +379,7 @@ protected:
class Create_func_bit_count : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_count s_singleton;
@@ -392,7 +392,7 @@ protected:
class Create_func_bit_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_length s_singleton;
@@ -405,7 +405,7 @@ protected:
class Create_func_ceiling : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ceiling s_singleton;
@@ -419,7 +419,7 @@ protected:
class Create_func_centroid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_centroid s_singleton;
@@ -433,7 +433,7 @@ protected:
class Create_func_char_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_char_length s_singleton;
@@ -446,7 +446,7 @@ protected:
class Create_func_coercibility : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_coercibility s_singleton;
@@ -459,7 +459,7 @@ protected:
class Create_func_compress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_compress s_singleton;
@@ -498,7 +498,7 @@ protected:
class Create_func_connection_id : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_connection_id s_singleton;
@@ -512,7 +512,7 @@ protected:
class Create_func_contains : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_contains s_singleton;
@@ -526,7 +526,7 @@ protected:
class Create_func_conv : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_conv s_singleton;
@@ -539,7 +539,7 @@ protected:
class Create_func_convert_tz : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_convert_tz s_singleton;
@@ -552,7 +552,7 @@ protected:
class Create_func_cos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cos s_singleton;
@@ -565,7 +565,7 @@ protected:
class Create_func_cot : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cot s_singleton;
@@ -578,7 +578,7 @@ protected:
class Create_func_crc32 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_crc32 s_singleton;
@@ -592,7 +592,7 @@ protected:
class Create_func_crosses : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_crosses s_singleton;
@@ -606,7 +606,7 @@ protected:
class Create_func_date_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_date_format s_singleton;
@@ -619,7 +619,7 @@ protected:
class Create_func_datediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_datediff s_singleton;
@@ -632,7 +632,7 @@ protected:
class Create_func_dayname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayname s_singleton;
@@ -645,7 +645,7 @@ protected:
class Create_func_dayofmonth : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofmonth s_singleton;
@@ -658,7 +658,7 @@ protected:
class Create_func_dayofweek : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofweek s_singleton;
@@ -671,7 +671,7 @@ protected:
class Create_func_dayofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofyear s_singleton;
@@ -684,7 +684,7 @@ protected:
class Create_func_decode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_decode s_singleton;
@@ -697,7 +697,7 @@ protected:
class Create_func_degrees : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_degrees s_singleton;
@@ -737,7 +737,7 @@ protected:
class Create_func_dimension : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dimension s_singleton;
@@ -752,7 +752,7 @@ protected:
class Create_func_disjoint : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_disjoint s_singleton;
@@ -779,7 +779,7 @@ protected:
class Create_func_encode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_encode s_singleton;
@@ -806,7 +806,7 @@ protected:
class Create_func_endpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_endpoint s_singleton;
@@ -821,7 +821,7 @@ protected:
class Create_func_envelope : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_envelope s_singleton;
@@ -836,7 +836,7 @@ protected:
class Create_func_equals : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_equals s_singleton;
@@ -850,7 +850,7 @@ protected:
class Create_func_exp : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exp s_singleton;
@@ -877,7 +877,7 @@ protected:
class Create_func_exteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exteriorring s_singleton;
@@ -904,7 +904,7 @@ protected:
class Create_func_find_in_set : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_find_in_set s_singleton;
@@ -917,7 +917,7 @@ protected:
class Create_func_floor : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_floor s_singleton;
@@ -930,7 +930,7 @@ protected:
class Create_func_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_format s_singleton;
@@ -943,7 +943,7 @@ protected:
class Create_func_found_rows : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_found_rows s_singleton;
@@ -956,7 +956,7 @@ protected:
class Create_func_from_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_from_days s_singleton;
@@ -1013,7 +1013,7 @@ protected:
class Create_func_geometry_type : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_geometry_type s_singleton;
@@ -1028,7 +1028,7 @@ protected:
class Create_func_geometryn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_geometryn s_singleton;
@@ -1042,7 +1042,7 @@ protected:
class Create_func_get_lock : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_get_lock s_singleton;
@@ -1056,7 +1056,7 @@ protected:
class Create_func_glength : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_glength s_singleton;
@@ -1083,7 +1083,7 @@ protected:
class Create_func_hex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_hex s_singleton;
@@ -1096,7 +1096,7 @@ protected:
class Create_func_ifnull : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_ifnull s_singleton;
@@ -1109,7 +1109,7 @@ protected:
class Create_func_inet_ntoa : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_ntoa s_singleton;
@@ -1122,7 +1122,7 @@ protected:
class Create_func_inet_aton : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_aton s_singleton;
@@ -1135,7 +1135,7 @@ protected:
class Create_func_instr : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_instr s_singleton;
@@ -1149,7 +1149,7 @@ protected:
class Create_func_interiorringn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_interiorringn s_singleton;
@@ -1164,7 +1164,7 @@ protected:
class Create_func_intersects : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_intersects s_singleton;
@@ -1178,7 +1178,7 @@ protected:
class Create_func_is_free_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_free_lock s_singleton;
@@ -1191,7 +1191,7 @@ protected:
class Create_func_is_used_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_used_lock s_singleton;
@@ -1205,7 +1205,7 @@ protected:
class Create_func_isclosed : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isclosed s_singleton;
@@ -1220,7 +1220,7 @@ protected:
class Create_func_isempty : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isempty s_singleton;
@@ -1234,7 +1234,7 @@ protected:
class Create_func_isnull : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isnull s_singleton;
@@ -1248,7 +1248,7 @@ protected:
class Create_func_issimple : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_issimple s_singleton;
@@ -1262,7 +1262,7 @@ protected:
class Create_func_last_day : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_last_day s_singleton;
@@ -1288,7 +1288,7 @@ protected:
class Create_func_lcase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_lcase s_singleton;
@@ -1314,7 +1314,7 @@ protected:
class Create_func_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_length s_singleton;
@@ -1327,7 +1327,7 @@ protected:
class Create_func_ln : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ln s_singleton;
@@ -1340,7 +1340,7 @@ protected:
class Create_func_load_file : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_load_file s_singleton;
@@ -1379,7 +1379,7 @@ protected:
class Create_func_log10 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log10 s_singleton;
@@ -1392,7 +1392,7 @@ protected:
class Create_func_log2 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log2 s_singleton;
@@ -1405,7 +1405,7 @@ protected:
class Create_func_lpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_lpad s_singleton;
@@ -1418,7 +1418,7 @@ protected:
class Create_func_ltrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ltrim s_singleton;
@@ -1431,7 +1431,7 @@ protected:
class Create_func_makedate : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_makedate s_singleton;
@@ -1444,7 +1444,7 @@ protected:
class Create_func_maketime : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_maketime s_singleton;
@@ -1483,7 +1483,7 @@ protected:
class Create_func_md5 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_md5 s_singleton;
@@ -1496,7 +1496,7 @@ protected:
class Create_func_monthname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_monthname s_singleton;
@@ -1509,7 +1509,7 @@ protected:
class Create_func_name_const : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_name_const s_singleton;
@@ -1522,7 +1522,7 @@ protected:
class Create_func_nullif : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_nullif s_singleton;
@@ -1536,7 +1536,7 @@ protected:
class Create_func_numgeometries : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numgeometries s_singleton;
@@ -1551,7 +1551,7 @@ protected:
class Create_func_numinteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numinteriorring s_singleton;
@@ -1566,7 +1566,7 @@ protected:
class Create_func_numpoints : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numpoints s_singleton;
@@ -1580,7 +1580,7 @@ protected:
class Create_func_oct : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_oct s_singleton;
@@ -1593,7 +1593,7 @@ protected:
class Create_func_ord : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ord s_singleton;
@@ -1607,7 +1607,7 @@ protected:
class Create_func_overlaps : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_overlaps s_singleton;
@@ -1621,7 +1621,7 @@ protected:
class Create_func_period_add : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_add s_singleton;
@@ -1634,7 +1634,7 @@ protected:
class Create_func_period_diff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_diff s_singleton;
@@ -1647,7 +1647,7 @@ protected:
class Create_func_pi : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_pi s_singleton;
@@ -1661,7 +1661,7 @@ protected:
class Create_func_pointn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pointn s_singleton;
@@ -1675,7 +1675,7 @@ protected:
class Create_func_pow : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pow s_singleton;
@@ -1688,7 +1688,7 @@ protected:
class Create_func_quote : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_quote s_singleton;
@@ -1701,7 +1701,7 @@ protected:
class Create_func_radians : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_radians s_singleton;
@@ -1727,7 +1727,7 @@ protected:
class Create_func_release_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_release_lock s_singleton;
@@ -1740,7 +1740,7 @@ protected:
class Create_func_reverse : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_reverse s_singleton;
@@ -1766,7 +1766,7 @@ protected:
class Create_func_row_count : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_row_count s_singleton;
@@ -1779,7 +1779,7 @@ protected:
class Create_func_rpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_rpad s_singleton;
@@ -1792,7 +1792,7 @@ protected:
class Create_func_rtrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_rtrim s_singleton;
@@ -1805,7 +1805,7 @@ protected:
class Create_func_sec_to_time : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sec_to_time s_singleton;
@@ -1818,7 +1818,7 @@ protected:
class Create_func_sha : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sha s_singleton;
@@ -1831,7 +1831,7 @@ protected:
class Create_func_sign : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sign s_singleton;
@@ -1844,7 +1844,7 @@ protected:
class Create_func_sin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sin s_singleton;
@@ -1857,7 +1857,7 @@ protected:
class Create_func_sleep : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sleep s_singleton;
@@ -1870,7 +1870,7 @@ protected:
class Create_func_soundex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_soundex s_singleton;
@@ -1883,7 +1883,7 @@ protected:
class Create_func_space : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_space s_singleton;
@@ -1896,7 +1896,7 @@ protected:
class Create_func_sqrt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sqrt s_singleton;
@@ -1910,7 +1910,7 @@ protected:
class Create_func_srid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_srid s_singleton;
@@ -1925,7 +1925,7 @@ protected:
class Create_func_startpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_startpoint s_singleton;
@@ -1939,7 +1939,7 @@ protected:
class Create_func_str_to_date : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_str_to_date s_singleton;
@@ -1952,7 +1952,7 @@ protected:
class Create_func_strcmp : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_strcmp s_singleton;
@@ -1965,7 +1965,7 @@ protected:
class Create_func_substr_index : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_substr_index s_singleton;
@@ -1978,7 +1978,7 @@ protected:
class Create_func_subtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_subtime s_singleton;
@@ -1991,7 +1991,7 @@ protected:
class Create_func_tan : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_tan s_singleton;
@@ -2004,7 +2004,7 @@ protected:
class Create_func_time_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_time_format s_singleton;
@@ -2017,7 +2017,7 @@ protected:
class Create_func_time_to_sec : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_time_to_sec s_singleton;
@@ -2030,7 +2030,7 @@ protected:
class Create_func_timediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_timediff s_singleton;
@@ -2043,7 +2043,7 @@ protected:
class Create_func_to_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_to_days s_singleton;
@@ -2057,7 +2057,7 @@ protected:
class Create_func_touches : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_touches s_singleton;
@@ -2071,7 +2071,7 @@ protected:
class Create_func_ucase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ucase s_singleton;
@@ -2084,7 +2084,7 @@ protected:
class Create_func_uncompress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompress s_singleton;
@@ -2097,7 +2097,7 @@ protected:
class Create_func_uncompressed_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompressed_length s_singleton;
@@ -2110,7 +2110,7 @@ protected:
class Create_func_unhex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_unhex s_singleton;
@@ -2136,7 +2136,7 @@ protected:
class Create_func_uuid : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid s_singleton;
@@ -2149,7 +2149,7 @@ protected:
class Create_func_uuid_short : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid_short s_singleton;
@@ -2162,7 +2162,7 @@ protected:
class Create_func_version : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_version s_singleton;
@@ -2175,7 +2175,7 @@ protected:
class Create_func_weekday : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekday s_singleton;
@@ -2188,7 +2188,7 @@ protected:
class Create_func_weekofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekofyear s_singleton;
@@ -2202,7 +2202,7 @@ protected:
class Create_func_within : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_within s_singleton;
@@ -2217,7 +2217,7 @@ protected:
class Create_func_x : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_x s_singleton;
@@ -2231,7 +2231,7 @@ protected:
class Create_func_xml_extractvalue : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_xml_extractvalue s_singleton;
@@ -2244,7 +2244,7 @@ protected:
class Create_func_xml_update : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_xml_update s_singleton;
@@ -2258,7 +2258,7 @@ protected:
class Create_func_y : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_y s_singleton;
@@ -2353,7 +2353,7 @@ Create_qfunc::create(THD *thd, LEX_STRIN
if (thd->lex->copy_db_to(&db.str, &db.length))
return NULL;
- return create(thd, db, name, false, item_list);
+ return create_with_db(thd, db, name, false, item_list);
}
@@ -2470,8 +2470,8 @@ Create_udf_func::create(THD *thd, udf_fu
Create_sp_func Create_sp_func::s_singleton;
Item*
-Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list)
+Create_sp_func::create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list)
{
int arg_count= 0;
Item *func= NULL;
@@ -2538,7 +2538,7 @@ Create_func_arg0::create(THD *thd, LEX_S
return NULL;
}
- return create(thd);
+ return create_builder(thd);
}
@@ -2564,7 +2564,7 @@ Create_func_arg1::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1);
+ return create_1_arg(thd, param_1);
}
@@ -2592,7 +2592,7 @@ Create_func_arg2::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2);
+ return create_2_arg(thd, param_1, param_2);
}
@@ -2622,14 +2622,14 @@ Create_func_arg3::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2, param_3);
+ return create_3_arg(thd, param_1, param_2, param_3);
}
Create_func_abs Create_func_abs::s_singleton;
Item*
-Create_func_abs::create(THD *thd, Item *arg1)
+Create_func_abs::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_abs(arg1);
}
@@ -2638,7 +2638,7 @@ Create_func_abs::create(THD *thd, Item *
Create_func_acos Create_func_acos::s_singleton;
Item*
-Create_func_acos::create(THD *thd, Item *arg1)
+Create_func_acos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_acos(arg1);
}
@@ -2647,7 +2647,7 @@ Create_func_acos::create(THD *thd, Item
Create_func_addtime Create_func_addtime::s_singleton;
Item*
-Create_func_addtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_addtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 0);
}
@@ -2656,7 +2656,7 @@ Create_func_addtime::create(THD *thd, It
Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton;
Item*
-Create_func_aes_encrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_encrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_encrypt(arg1, arg2);
}
@@ -2665,7 +2665,7 @@ Create_func_aes_encrypt::create(THD *thd
Create_func_aes_decrypt Create_func_aes_decrypt::s_singleton;
Item*
-Create_func_aes_decrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_decrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_decrypt(arg1, arg2);
}
@@ -2675,7 +2675,7 @@ Create_func_aes_decrypt::create(THD *thd
Create_func_area Create_func_area::s_singleton;
Item*
-Create_func_area::create(THD *thd, Item *arg1)
+Create_func_area::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_area(arg1);
}
@@ -2686,7 +2686,7 @@ Create_func_area::create(THD *thd, Item
Create_func_as_wkb Create_func_as_wkb::s_singleton;
Item*
-Create_func_as_wkb::create(THD *thd, Item *arg1)
+Create_func_as_wkb::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkb(arg1);
}
@@ -2697,7 +2697,7 @@ Create_func_as_wkb::create(THD *thd, Ite
Create_func_as_wkt Create_func_as_wkt::s_singleton;
Item*
-Create_func_as_wkt::create(THD *thd, Item *arg1)
+Create_func_as_wkt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkt(arg1);
}
@@ -2707,7 +2707,7 @@ Create_func_as_wkt::create(THD *thd, Ite
Create_func_asin Create_func_asin::s_singleton;
Item*
-Create_func_asin::create(THD *thd, Item *arg1)
+Create_func_asin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_asin(arg1);
}
@@ -2753,7 +2753,7 @@ Create_func_atan::create_native(THD *thd
Create_func_benchmark Create_func_benchmark::s_singleton;
Item*
-Create_func_benchmark::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_benchmark::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_benchmark(arg1, arg2);
@@ -2763,7 +2763,7 @@ Create_func_benchmark::create(THD *thd,
Create_func_bin Create_func_bin::s_singleton;
Item*
-Create_func_bin::create(THD *thd, Item *arg1)
+Create_func_bin::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i2= new (thd->mem_root) Item_int((int32) 2,1);
@@ -2774,7 +2774,7 @@ Create_func_bin::create(THD *thd, Item *
Create_func_bit_count Create_func_bit_count::s_singleton;
Item*
-Create_func_bit_count::create(THD *thd, Item *arg1)
+Create_func_bit_count::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_count(arg1);
}
@@ -2783,7 +2783,7 @@ Create_func_bit_count::create(THD *thd,
Create_func_bit_length Create_func_bit_length::s_singleton;
Item*
-Create_func_bit_length::create(THD *thd, Item *arg1)
+Create_func_bit_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_length(arg1);
}
@@ -2792,7 +2792,7 @@ Create_func_bit_length::create(THD *thd,
Create_func_ceiling Create_func_ceiling::s_singleton;
Item*
-Create_func_ceiling::create(THD *thd, Item *arg1)
+Create_func_ceiling::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ceiling(arg1);
}
@@ -2802,7 +2802,7 @@ Create_func_ceiling::create(THD *thd, It
Create_func_centroid Create_func_centroid::s_singleton;
Item*
-Create_func_centroid::create(THD *thd, Item *arg1)
+Create_func_centroid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_centroid(arg1);
}
@@ -2812,7 +2812,7 @@ Create_func_centroid::create(THD *thd, I
Create_func_char_length Create_func_char_length::s_singleton;
Item*
-Create_func_char_length::create(THD *thd, Item *arg1)
+Create_func_char_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_char_length(arg1);
}
@@ -2821,7 +2821,7 @@ Create_func_char_length::create(THD *thd
Create_func_coercibility Create_func_coercibility::s_singleton;
Item*
-Create_func_coercibility::create(THD *thd, Item *arg1)
+Create_func_coercibility::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_coercibility(arg1);
}
@@ -2873,7 +2873,7 @@ Create_func_concat_ws::create_native(THD
Create_func_compress Create_func_compress::s_singleton;
Item*
-Create_func_compress::create(THD *thd, Item *arg1)
+Create_func_compress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_compress(arg1);
}
@@ -2882,7 +2882,7 @@ Create_func_compress::create(THD *thd, I
Create_func_connection_id Create_func_connection_id::s_singleton;
Item*
-Create_func_connection_id::create(THD *thd)
+Create_func_connection_id::create_builder(THD *thd)
{
thd->lex->safe_to_cache_query= 0;
return new (thd->mem_root) Item_func_connection_id();
@@ -2893,7 +2893,7 @@ Create_func_connection_id::create(THD *t
Create_func_contains Create_func_contains::s_singleton;
Item*
-Create_func_contains::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_contains::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CONTAINS_FUNC);
@@ -2904,7 +2904,7 @@ Create_func_contains::create(THD *thd, I
Create_func_conv Create_func_conv::s_singleton;
Item*
-Create_func_conv::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_conv::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_conv(arg1, arg2, arg3);
}
@@ -2913,7 +2913,7 @@ Create_func_conv::create(THD *thd, Item
Create_func_convert_tz Create_func_convert_tz::s_singleton;
Item*
-Create_func_convert_tz::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_convert_tz::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_convert_tz(arg1, arg2, arg3);
}
@@ -2922,7 +2922,7 @@ Create_func_convert_tz::create(THD *thd,
Create_func_cos Create_func_cos::s_singleton;
Item*
-Create_func_cos::create(THD *thd, Item *arg1)
+Create_func_cos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_cos(arg1);
}
@@ -2931,7 +2931,7 @@ Create_func_cos::create(THD *thd, Item *
Create_func_cot Create_func_cot::s_singleton;
Item*
-Create_func_cot::create(THD *thd, Item *arg1)
+Create_func_cot::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "1", 1, 1);
Item *i2= new (thd->mem_root) Item_func_tan(arg1);
@@ -2942,7 +2942,7 @@ Create_func_cot::create(THD *thd, Item *
Create_func_crc32 Create_func_crc32::s_singleton;
Item*
-Create_func_crc32::create(THD *thd, Item *arg1)
+Create_func_crc32::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_crc32(arg1);
}
@@ -2952,7 +2952,7 @@ Create_func_crc32::create(THD *thd, Item
Create_func_crosses Create_func_crosses::s_singleton;
Item*
-Create_func_crosses::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_crosses::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CROSSES_FUNC);
@@ -2963,7 +2963,7 @@ Create_func_crosses::create(THD *thd, It
Create_func_date_format Create_func_date_format::s_singleton;
Item*
-Create_func_date_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_date_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 0);
}
@@ -2972,7 +2972,7 @@ Create_func_date_format::create(THD *thd
Create_func_datediff Create_func_datediff::s_singleton;
Item*
-Create_func_datediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_datediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
Item *i1= new (thd->mem_root) Item_func_to_days(arg1);
Item *i2= new (thd->mem_root) Item_func_to_days(arg2);
@@ -2984,7 +2984,7 @@ Create_func_datediff::create(THD *thd, I
Create_func_dayname Create_func_dayname::s_singleton;
Item*
-Create_func_dayname::create(THD *thd, Item *arg1)
+Create_func_dayname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayname(arg1);
}
@@ -2993,7 +2993,7 @@ Create_func_dayname::create(THD *thd, It
Create_func_dayofmonth Create_func_dayofmonth::s_singleton;
Item*
-Create_func_dayofmonth::create(THD *thd, Item *arg1)
+Create_func_dayofmonth::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofmonth(arg1);
}
@@ -3002,7 +3002,7 @@ Create_func_dayofmonth::create(THD *thd,
Create_func_dayofweek Create_func_dayofweek::s_singleton;
Item*
-Create_func_dayofweek::create(THD *thd, Item *arg1)
+Create_func_dayofweek::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 1);
}
@@ -3011,7 +3011,7 @@ Create_func_dayofweek::create(THD *thd,
Create_func_dayofyear Create_func_dayofyear::s_singleton;
Item*
-Create_func_dayofyear::create(THD *thd, Item *arg1)
+Create_func_dayofyear::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofyear(arg1);
}
@@ -3020,7 +3020,7 @@ Create_func_dayofyear::create(THD *thd,
Create_func_decode Create_func_decode::s_singleton;
Item*
-Create_func_decode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_decode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_decode(arg1, arg2);
}
@@ -3029,7 +3029,7 @@ Create_func_decode::create(THD *thd, Ite
Create_func_degrees Create_func_degrees::s_singleton;
Item*
-Create_func_degrees::create(THD *thd, Item *arg1)
+Create_func_degrees::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "degrees", arg1,
180/M_PI, 0.0);
@@ -3114,7 +3114,7 @@ Create_func_des_encrypt::create_native(T
Create_func_dimension Create_func_dimension::s_singleton;
Item*
-Create_func_dimension::create(THD *thd, Item *arg1)
+Create_func_dimension::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dimension(arg1);
}
@@ -3125,7 +3125,7 @@ Create_func_dimension::create(THD *thd,
Create_func_disjoint Create_func_disjoint::s_singleton;
Item*
-Create_func_disjoint::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_disjoint::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_DISJOINT_FUNC);
@@ -3157,7 +3157,7 @@ Create_func_elt::create_native(THD *thd,
Create_func_encode Create_func_encode::s_singleton;
Item*
-Create_func_encode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_encode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_encode(arg1, arg2);
}
@@ -3205,7 +3205,7 @@ Create_func_encrypt::create_native(THD *
Create_func_endpoint Create_func_endpoint::s_singleton;
Item*
-Create_func_endpoint::create(THD *thd, Item *arg1)
+Create_func_endpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_ENDPOINT);
@@ -3217,7 +3217,7 @@ Create_func_endpoint::create(THD *thd, I
Create_func_envelope Create_func_envelope::s_singleton;
Item*
-Create_func_envelope::create(THD *thd, Item *arg1)
+Create_func_envelope::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_envelope(arg1);
}
@@ -3228,7 +3228,7 @@ Create_func_envelope::create(THD *thd, I
Create_func_equals Create_func_equals::s_singleton;
Item*
-Create_func_equals::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_equals::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_EQUALS_FUNC);
@@ -3239,7 +3239,7 @@ Create_func_equals::create(THD *thd, Ite
Create_func_exp Create_func_exp::s_singleton;
Item*
-Create_func_exp::create(THD *thd, Item *arg1)
+Create_func_exp::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_exp(arg1);
}
@@ -3302,7 +3302,7 @@ Create_func_export_set::create_native(TH
Create_func_exteriorring Create_func_exteriorring::s_singleton;
Item*
-Create_func_exteriorring::create(THD *thd, Item *arg1)
+Create_func_exteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_EXTERIORRING);
@@ -3334,7 +3334,7 @@ Create_func_field::create_native(THD *th
Create_func_find_in_set Create_func_find_in_set::s_singleton;
Item*
-Create_func_find_in_set::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_find_in_set::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_find_in_set(arg1, arg2);
}
@@ -3343,7 +3343,7 @@ Create_func_find_in_set::create(THD *thd
Create_func_floor Create_func_floor::s_singleton;
Item*
-Create_func_floor::create(THD *thd, Item *arg1)
+Create_func_floor::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_floor(arg1);
}
@@ -3352,7 +3352,7 @@ Create_func_floor::create(THD *thd, Item
Create_func_format Create_func_format::s_singleton;
Item*
-Create_func_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_format(arg1, arg2);
}
@@ -3361,7 +3361,7 @@ Create_func_format::create(THD *thd, Ite
Create_func_found_rows Create_func_found_rows::s_singleton;
Item*
-Create_func_found_rows::create(THD *thd)
+Create_func_found_rows::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -3372,7 +3372,7 @@ Create_func_found_rows::create(THD *thd)
Create_func_from_days Create_func_from_days::s_singleton;
Item*
-Create_func_from_days::create(THD *thd, Item *arg1)
+Create_func_from_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_from_days(arg1);
}
@@ -3500,7 +3500,7 @@ Create_func_geometry_from_wkb::create_na
Create_func_geometry_type Create_func_geometry_type::s_singleton;
Item*
-Create_func_geometry_type::create(THD *thd, Item *arg1)
+Create_func_geometry_type::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_geometry_type(arg1);
}
@@ -3511,7 +3511,7 @@ Create_func_geometry_type::create(THD *t
Create_func_geometryn Create_func_geometryn::s_singleton;
Item*
-Create_func_geometryn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_geometryn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_GEOMETRYN);
@@ -3522,7 +3522,7 @@ Create_func_geometryn::create(THD *thd,
Create_func_get_lock Create_func_get_lock::s_singleton;
Item*
-Create_func_get_lock::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_get_lock::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3534,7 +3534,7 @@ Create_func_get_lock::create(THD *thd, I
Create_func_glength Create_func_glength::s_singleton;
Item*
-Create_func_glength::create(THD *thd, Item *arg1)
+Create_func_glength::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_glength(arg1);
}
@@ -3565,7 +3565,7 @@ Create_func_greatest::create_native(THD
Create_func_hex Create_func_hex::s_singleton;
Item*
-Create_func_hex::create(THD *thd, Item *arg1)
+Create_func_hex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_hex(arg1);
}
@@ -3574,7 +3574,7 @@ Create_func_hex::create(THD *thd, Item *
Create_func_ifnull Create_func_ifnull::s_singleton;
Item*
-Create_func_ifnull::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_ifnull::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_ifnull(arg1, arg2);
}
@@ -3583,7 +3583,7 @@ Create_func_ifnull::create(THD *thd, Ite
Create_func_inet_ntoa Create_func_inet_ntoa::s_singleton;
Item*
-Create_func_inet_ntoa::create(THD *thd, Item *arg1)
+Create_func_inet_ntoa::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_ntoa(arg1);
}
@@ -3592,7 +3592,7 @@ Create_func_inet_ntoa::create(THD *thd,
Create_func_inet_aton Create_func_inet_aton::s_singleton;
Item*
-Create_func_inet_aton::create(THD *thd, Item *arg1)
+Create_func_inet_aton::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_aton(arg1);
}
@@ -3601,7 +3601,7 @@ Create_func_inet_aton::create(THD *thd,
Create_func_instr Create_func_instr::s_singleton;
Item*
-Create_func_instr::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_instr::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_locate(arg1, arg2);
}
@@ -3611,7 +3611,7 @@ Create_func_instr::create(THD *thd, Item
Create_func_interiorringn Create_func_interiorringn::s_singleton;
Item*
-Create_func_interiorringn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_interiorringn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_INTERIORRINGN);
@@ -3623,7 +3623,7 @@ Create_func_interiorringn::create(THD *t
Create_func_intersects Create_func_intersects::s_singleton;
Item*
-Create_func_intersects::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_intersects::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_INTERSECTS_FUNC);
@@ -3634,7 +3634,7 @@ Create_func_intersects::create(THD *thd,
Create_func_is_free_lock Create_func_is_free_lock::s_singleton;
Item*
-Create_func_is_free_lock::create(THD *thd, Item *arg1)
+Create_func_is_free_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3645,7 +3645,7 @@ Create_func_is_free_lock::create(THD *th
Create_func_is_used_lock Create_func_is_used_lock::s_singleton;
Item*
-Create_func_is_used_lock::create(THD *thd, Item *arg1)
+Create_func_is_used_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3657,7 +3657,7 @@ Create_func_is_used_lock::create(THD *th
Create_func_isclosed Create_func_isclosed::s_singleton;
Item*
-Create_func_isclosed::create(THD *thd, Item *arg1)
+Create_func_isclosed::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isclosed(arg1);
}
@@ -3668,7 +3668,7 @@ Create_func_isclosed::create(THD *thd, I
Create_func_isempty Create_func_isempty::s_singleton;
Item*
-Create_func_isempty::create(THD *thd, Item *arg1)
+Create_func_isempty::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isempty(arg1);
}
@@ -3678,7 +3678,7 @@ Create_func_isempty::create(THD *thd, It
Create_func_isnull Create_func_isnull::s_singleton;
Item*
-Create_func_isnull::create(THD *thd, Item *arg1)
+Create_func_isnull::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isnull(arg1);
}
@@ -3688,7 +3688,7 @@ Create_func_isnull::create(THD *thd, Ite
Create_func_issimple Create_func_issimple::s_singleton;
Item*
-Create_func_issimple::create(THD *thd, Item *arg1)
+Create_func_issimple::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_issimple(arg1);
}
@@ -3698,7 +3698,7 @@ Create_func_issimple::create(THD *thd, I
Create_func_last_day Create_func_last_day::s_singleton;
Item*
-Create_func_last_day::create(THD *thd, Item *arg1)
+Create_func_last_day::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_last_day(arg1);
}
@@ -3744,7 +3744,7 @@ Create_func_last_insert_id::create_nativ
Create_func_lcase Create_func_lcase::s_singleton;
Item*
-Create_func_lcase::create(THD *thd, Item *arg1)
+Create_func_lcase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_lcase(arg1);
}
@@ -3774,7 +3774,7 @@ Create_func_least::create_native(THD *th
Create_func_length Create_func_length::s_singleton;
Item*
-Create_func_length::create(THD *thd, Item *arg1)
+Create_func_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_length(arg1);
}
@@ -3783,7 +3783,7 @@ Create_func_length::create(THD *thd, Ite
Create_func_ln Create_func_ln::s_singleton;
Item*
-Create_func_ln::create(THD *thd, Item *arg1)
+Create_func_ln::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ln(arg1);
}
@@ -3792,7 +3792,7 @@ Create_func_ln::create(THD *thd, Item *a
Create_func_load_file Create_func_load_file::s_singleton;
Item*
-Create_func_load_file::create(THD *thd, Item *arg1)
+Create_func_load_file::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3881,7 +3881,7 @@ Create_func_log::create_native(THD *thd,
Create_func_log10 Create_func_log10::s_singleton;
Item*
-Create_func_log10::create(THD *thd, Item *arg1)
+Create_func_log10::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log10(arg1);
}
@@ -3890,7 +3890,7 @@ Create_func_log10::create(THD *thd, Item
Create_func_log2 Create_func_log2::s_singleton;
Item*
-Create_func_log2::create(THD *thd, Item *arg1)
+Create_func_log2::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log2(arg1);
}
@@ -3899,7 +3899,7 @@ Create_func_log2::create(THD *thd, Item
Create_func_lpad Create_func_lpad::s_singleton;
Item*
-Create_func_lpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_lpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_lpad(arg1, arg2, arg3);
}
@@ -3908,7 +3908,7 @@ Create_func_lpad::create(THD *thd, Item
Create_func_ltrim Create_func_ltrim::s_singleton;
Item*
-Create_func_ltrim::create(THD *thd, Item *arg1)
+Create_func_ltrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ltrim(arg1);
}
@@ -3917,7 +3917,7 @@ Create_func_ltrim::create(THD *thd, Item
Create_func_makedate Create_func_makedate::s_singleton;
Item*
-Create_func_makedate::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_makedate::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_makedate(arg1, arg2);
}
@@ -3926,7 +3926,7 @@ Create_func_makedate::create(THD *thd, I
Create_func_maketime Create_func_maketime::s_singleton;
Item*
-Create_func_maketime::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_maketime::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_maketime(arg1, arg2, arg3);
}
@@ -4001,7 +4001,7 @@ Create_func_master_pos_wait::create_nati
Create_func_md5 Create_func_md5::s_singleton;
Item*
-Create_func_md5::create(THD *thd, Item *arg1)
+Create_func_md5::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_md5(arg1);
}
@@ -4010,7 +4010,7 @@ Create_func_md5::create(THD *thd, Item *
Create_func_monthname Create_func_monthname::s_singleton;
Item*
-Create_func_monthname::create(THD *thd, Item *arg1)
+Create_func_monthname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_monthname(arg1);
}
@@ -4019,7 +4019,7 @@ Create_func_monthname::create(THD *thd,
Create_func_name_const Create_func_name_const::s_singleton;
Item*
-Create_func_name_const::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_name_const::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_name_const(arg1, arg2);
}
@@ -4028,7 +4028,7 @@ Create_func_name_const::create(THD *thd,
Create_func_nullif Create_func_nullif::s_singleton;
Item*
-Create_func_nullif::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_nullif::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_nullif(arg1, arg2);
}
@@ -4038,7 +4038,7 @@ Create_func_nullif::create(THD *thd, Ite
Create_func_numgeometries Create_func_numgeometries::s_singleton;
Item*
-Create_func_numgeometries::create(THD *thd, Item *arg1)
+Create_func_numgeometries::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numgeometries(arg1);
}
@@ -4049,7 +4049,7 @@ Create_func_numgeometries::create(THD *t
Create_func_numinteriorring Create_func_numinteriorring::s_singleton;
Item*
-Create_func_numinteriorring::create(THD *thd, Item *arg1)
+Create_func_numinteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numinteriorring(arg1);
}
@@ -4060,7 +4060,7 @@ Create_func_numinteriorring::create(THD
Create_func_numpoints Create_func_numpoints::s_singleton;
Item*
-Create_func_numpoints::create(THD *thd, Item *arg1)
+Create_func_numpoints::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numpoints(arg1);
}
@@ -4070,7 +4070,7 @@ Create_func_numpoints::create(THD *thd,
Create_func_oct Create_func_oct::s_singleton;
Item*
-Create_func_oct::create(THD *thd, Item *arg1)
+Create_func_oct::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i8= new (thd->mem_root) Item_int((int32) 8,1);
@@ -4081,7 +4081,7 @@ Create_func_oct::create(THD *thd, Item *
Create_func_ord Create_func_ord::s_singleton;
Item*
-Create_func_ord::create(THD *thd, Item *arg1)
+Create_func_ord::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ord(arg1);
}
@@ -4091,7 +4091,7 @@ Create_func_ord::create(THD *thd, Item *
Create_func_overlaps Create_func_overlaps::s_singleton;
Item*
-Create_func_overlaps::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_overlaps::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_OVERLAPS_FUNC);
@@ -4102,7 +4102,7 @@ Create_func_overlaps::create(THD *thd, I
Create_func_period_add Create_func_period_add::s_singleton;
Item*
-Create_func_period_add::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_add::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_add(arg1, arg2);
}
@@ -4111,7 +4111,7 @@ Create_func_period_add::create(THD *thd,
Create_func_period_diff Create_func_period_diff::s_singleton;
Item*
-Create_func_period_diff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_diff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_diff(arg1, arg2);
}
@@ -4120,7 +4120,7 @@ Create_func_period_diff::create(THD *thd
Create_func_pi Create_func_pi::s_singleton;
Item*
-Create_func_pi::create(THD *thd)
+Create_func_pi::create_builder(THD *thd)
{
return new (thd->mem_root) Item_static_float_func("pi()", M_PI, 6, 8);
}
@@ -4130,7 +4130,7 @@ Create_func_pi::create(THD *thd)
Create_func_pointn Create_func_pointn::s_singleton;
Item*
-Create_func_pointn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pointn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_POINTN);
@@ -4141,7 +4141,7 @@ Create_func_pointn::create(THD *thd, Ite
Create_func_pow Create_func_pow::s_singleton;
Item*
-Create_func_pow::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pow::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_pow(arg1, arg2);
}
@@ -4150,7 +4150,7 @@ Create_func_pow::create(THD *thd, Item *
Create_func_quote Create_func_quote::s_singleton;
Item*
-Create_func_quote::create(THD *thd, Item *arg1)
+Create_func_quote::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_quote(arg1);
}
@@ -4159,7 +4159,7 @@ Create_func_quote::create(THD *thd, Item
Create_func_radians Create_func_radians::s_singleton;
Item*
-Create_func_radians::create(THD *thd, Item *arg1)
+Create_func_radians::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "radians", arg1,
M_PI/180, 0.0);
@@ -4216,7 +4216,7 @@ Create_func_rand::create_native(THD *thd
Create_func_release_lock Create_func_release_lock::s_singleton;
Item*
-Create_func_release_lock::create(THD *thd, Item *arg1)
+Create_func_release_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4227,7 +4227,7 @@ Create_func_release_lock::create(THD *th
Create_func_reverse Create_func_reverse::s_singleton;
Item*
-Create_func_reverse::create(THD *thd, Item *arg1)
+Create_func_reverse::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_reverse(arg1);
}
@@ -4274,7 +4274,7 @@ Create_func_round::create_native(THD *th
Create_func_row_count Create_func_row_count::s_singleton;
Item*
-Create_func_row_count::create(THD *thd)
+Create_func_row_count::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4285,7 +4285,7 @@ Create_func_row_count::create(THD *thd)
Create_func_rpad Create_func_rpad::s_singleton;
Item*
-Create_func_rpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_rpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_rpad(arg1, arg2, arg3);
}
@@ -4294,7 +4294,7 @@ Create_func_rpad::create(THD *thd, Item
Create_func_rtrim Create_func_rtrim::s_singleton;
Item*
-Create_func_rtrim::create(THD *thd, Item *arg1)
+Create_func_rtrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_rtrim(arg1);
}
@@ -4303,7 +4303,7 @@ Create_func_rtrim::create(THD *thd, Item
Create_func_sec_to_time Create_func_sec_to_time::s_singleton;
Item*
-Create_func_sec_to_time::create(THD *thd, Item *arg1)
+Create_func_sec_to_time::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sec_to_time(arg1);
}
@@ -4312,7 +4312,7 @@ Create_func_sec_to_time::create(THD *thd
Create_func_sha Create_func_sha::s_singleton;
Item*
-Create_func_sha::create(THD *thd, Item *arg1)
+Create_func_sha::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sha(arg1);
}
@@ -4321,7 +4321,7 @@ Create_func_sha::create(THD *thd, Item *
Create_func_sign Create_func_sign::s_singleton;
Item*
-Create_func_sign::create(THD *thd, Item *arg1)
+Create_func_sign::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sign(arg1);
}
@@ -4330,7 +4330,7 @@ Create_func_sign::create(THD *thd, Item
Create_func_sin Create_func_sin::s_singleton;
Item*
-Create_func_sin::create(THD *thd, Item *arg1)
+Create_func_sin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sin(arg1);
}
@@ -4339,7 +4339,7 @@ Create_func_sin::create(THD *thd, Item *
Create_func_sleep Create_func_sleep::s_singleton;
Item*
-Create_func_sleep::create(THD *thd, Item *arg1)
+Create_func_sleep::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4350,7 +4350,7 @@ Create_func_sleep::create(THD *thd, Item
Create_func_soundex Create_func_soundex::s_singleton;
Item*
-Create_func_soundex::create(THD *thd, Item *arg1)
+Create_func_soundex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_soundex(arg1);
}
@@ -4359,7 +4359,7 @@ Create_func_soundex::create(THD *thd, It
Create_func_space Create_func_space::s_singleton;
Item*
-Create_func_space::create(THD *thd, Item *arg1)
+Create_func_space::create_1_arg(THD *thd, Item *arg1)
{
/**
TODO: Fix Bug#23637
@@ -4387,7 +4387,7 @@ Create_func_space::create(THD *thd, Item
Create_func_sqrt Create_func_sqrt::s_singleton;
Item*
-Create_func_sqrt::create(THD *thd, Item *arg1)
+Create_func_sqrt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sqrt(arg1);
}
@@ -4397,7 +4397,7 @@ Create_func_sqrt::create(THD *thd, Item
Create_func_srid Create_func_srid::s_singleton;
Item*
-Create_func_srid::create(THD *thd, Item *arg1)
+Create_func_srid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_srid(arg1);
}
@@ -4408,7 +4408,7 @@ Create_func_srid::create(THD *thd, Item
Create_func_startpoint Create_func_startpoint::s_singleton;
Item*
-Create_func_startpoint::create(THD *thd, Item *arg1)
+Create_func_startpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_STARTPOINT);
@@ -4419,7 +4419,7 @@ Create_func_startpoint::create(THD *thd,
Create_func_str_to_date Create_func_str_to_date::s_singleton;
Item*
-Create_func_str_to_date::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_str_to_date::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_str_to_date(arg1, arg2);
}
@@ -4428,7 +4428,7 @@ Create_func_str_to_date::create(THD *thd
Create_func_strcmp Create_func_strcmp::s_singleton;
Item*
-Create_func_strcmp::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_strcmp::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_strcmp(arg1, arg2);
}
@@ -4437,7 +4437,7 @@ Create_func_strcmp::create(THD *thd, Ite
Create_func_substr_index Create_func_substr_index::s_singleton;
Item*
-Create_func_substr_index::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_substr_index::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_substr_index(arg1, arg2, arg3);
}
@@ -4446,7 +4446,7 @@ Create_func_substr_index::create(THD *th
Create_func_subtime Create_func_subtime::s_singleton;
Item*
-Create_func_subtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_subtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 1);
}
@@ -4455,7 +4455,7 @@ Create_func_subtime::create(THD *thd, It
Create_func_tan Create_func_tan::s_singleton;
Item*
-Create_func_tan::create(THD *thd, Item *arg1)
+Create_func_tan::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_tan(arg1);
}
@@ -4464,7 +4464,7 @@ Create_func_tan::create(THD *thd, Item *
Create_func_time_format Create_func_time_format::s_singleton;
Item*
-Create_func_time_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_time_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 1);
}
@@ -4473,7 +4473,7 @@ Create_func_time_format::create(THD *thd
Create_func_time_to_sec Create_func_time_to_sec::s_singleton;
Item*
-Create_func_time_to_sec::create(THD *thd, Item *arg1)
+Create_func_time_to_sec::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_time_to_sec(arg1);
}
@@ -4482,7 +4482,7 @@ Create_func_time_to_sec::create(THD *thd
Create_func_timediff Create_func_timediff::s_singleton;
Item*
-Create_func_timediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_timediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_timediff(arg1, arg2);
}
@@ -4491,7 +4491,7 @@ Create_func_timediff::create(THD *thd, I
Create_func_to_days Create_func_to_days::s_singleton;
Item*
-Create_func_to_days::create(THD *thd, Item *arg1)
+Create_func_to_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_to_days(arg1);
}
@@ -4501,7 +4501,7 @@ Create_func_to_days::create(THD *thd, It
Create_func_touches Create_func_touches::s_singleton;
Item*
-Create_func_touches::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_touches::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_TOUCHES_FUNC);
@@ -4512,7 +4512,7 @@ Create_func_touches::create(THD *thd, It
Create_func_ucase Create_func_ucase::s_singleton;
Item*
-Create_func_ucase::create(THD *thd, Item *arg1)
+Create_func_ucase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ucase(arg1);
}
@@ -4521,7 +4521,7 @@ Create_func_ucase::create(THD *thd, Item
Create_func_uncompress Create_func_uncompress::s_singleton;
Item*
-Create_func_uncompress::create(THD *thd, Item *arg1)
+Create_func_uncompress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompress(arg1);
}
@@ -4530,7 +4530,7 @@ Create_func_uncompress::create(THD *thd,
Create_func_uncompressed_length Create_func_uncompressed_length::s_singleton;
Item*
-Create_func_uncompressed_length::create(THD *thd, Item *arg1)
+Create_func_uncompressed_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompressed_length(arg1);
}
@@ -4539,7 +4539,7 @@ Create_func_uncompressed_length::create(
Create_func_unhex Create_func_unhex::s_singleton;
Item*
-Create_func_unhex::create(THD *thd, Item *arg1)
+Create_func_unhex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_unhex(arg1);
}
@@ -4584,7 +4584,7 @@ Create_func_unix_timestamp::create_nativ
Create_func_uuid Create_func_uuid::s_singleton;
Item*
-Create_func_uuid::create(THD *thd)
+Create_func_uuid::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4595,7 +4595,7 @@ Create_func_uuid::create(THD *thd)
Create_func_uuid_short Create_func_uuid_short::s_singleton;
Item*
-Create_func_uuid_short::create(THD *thd)
+Create_func_uuid_short::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4606,7 +4606,7 @@ Create_func_uuid_short::create(THD *thd)
Create_func_version Create_func_version::s_singleton;
Item*
-Create_func_version::create(THD *thd)
+Create_func_version::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
return new (thd->mem_root) Item_static_string_func("version()",
@@ -4620,7 +4620,7 @@ Create_func_version::create(THD *thd)
Create_func_weekday Create_func_weekday::s_singleton;
Item*
-Create_func_weekday::create(THD *thd, Item *arg1)
+Create_func_weekday::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 0);
}
@@ -4629,7 +4629,7 @@ Create_func_weekday::create(THD *thd, It
Create_func_weekofyear Create_func_weekofyear::s_singleton;
Item*
-Create_func_weekofyear::create(THD *thd, Item *arg1)
+Create_func_weekofyear::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "0", 3, 1);
return new (thd->mem_root) Item_func_week(arg1, i1);
@@ -4640,7 +4640,7 @@ Create_func_weekofyear::create(THD *thd,
Create_func_within Create_func_within::s_singleton;
Item*
-Create_func_within::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_within::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_WITHIN_FUNC);
@@ -4652,7 +4652,7 @@ Create_func_within::create(THD *thd, Ite
Create_func_x Create_func_x::s_singleton;
Item*
-Create_func_x::create(THD *thd, Item *arg1)
+Create_func_x::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_x(arg1);
}
@@ -4662,7 +4662,7 @@ Create_func_x::create(THD *thd, Item *ar
Create_func_xml_extractvalue Create_func_xml_extractvalue::s_singleton;
Item*
-Create_func_xml_extractvalue::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_xml_extractvalue::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_xml_extractvalue(arg1, arg2);
}
@@ -4671,7 +4671,7 @@ Create_func_xml_extractvalue::create(THD
Create_func_xml_update Create_func_xml_update::s_singleton;
Item*
-Create_func_xml_update::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_xml_update::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_xml_update(arg1, arg2, arg3);
}
@@ -4681,7 +4681,7 @@ Create_func_xml_update::create(THD *thd,
Create_func_y Create_func_y::s_singleton;
Item*
-Create_func_y::create(THD *thd, Item *arg1)
+Create_func_y::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_y(arg1);
}
=== modified file 'sql/item_create.h'
--- a/sql/item_create.h 2007-08-15 13:43:08 +0000
+++ b/sql/item_create.h 2010-03-28 18:10:00 +0000
@@ -91,8 +91,9 @@ public:
@param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call
*/
- virtual Item* create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list) = 0;
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name,
+ List<Item> *item_list) = 0;
protected:
/** Constructor. */
=== modified file 'sql/item_sum.cc'
--- a/sql/item_sum.cc 2010-01-15 15:27:55 +0000
+++ b/sql/item_sum.cc 2010-03-28 18:10:00 +0000
@@ -642,7 +642,7 @@ Item_sum_hybrid::fix_fields(THD *thd, It
default:
DBUG_ASSERT(0);
};
- setup(args[0], NULL);
+ setup_item(args[0], NULL);
/* MIN/MAX can return NULL for empty set indepedent of the used column */
maybe_null= 1;
unsigned_flag=item->unsigned_flag;
@@ -676,7 +676,7 @@ Item_sum_hybrid::fix_fields(THD *thd, It
of the original MIN/MAX object and it is saved in this object's cache.
*/
-void Item_sum_hybrid::setup(Item *item, Item *value_arg)
+void Item_sum_hybrid::setup_item(Item *item, Item *value_arg)
{
value= Item_cache::get_cache(item);
value->setup(item);
@@ -1646,7 +1646,7 @@ void Item_sum_hybrid::no_rows_in_result(
Item *Item_sum_min::copy_or_same(THD* thd)
{
Item_sum_min *item= new (thd->mem_root) Item_sum_min(thd, this);
- item->setup(args[0], value);
+ item->setup_item(args[0], value);
return item;
}
@@ -1669,7 +1669,7 @@ bool Item_sum_min::add()
Item *Item_sum_max::copy_or_same(THD* thd)
{
Item_sum_max *item= new (thd->mem_root) Item_sum_max(thd, this);
- item->setup(args[0], value);
+ item->setup_item(args[0], value);
return item;
}
=== modified file 'sql/item_sum.h'
--- a/sql/item_sum.h 2010-02-01 06:14:12 +0000
+++ b/sql/item_sum.h 2010-03-31 08:17:03 +0000
@@ -870,7 +870,7 @@ protected:
was_values(item->was_values)
{ }
bool fix_fields(THD *, Item **);
- void setup(Item *item, Item *value_arg);
+ void setup_item(Item *item, Item *value_arg);
void clear();
double val_real();
longlong val_int();
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-03-15 11:51:23 +0000
+++ b/sql/log.cc 2010-03-31 08:17:03 +0000
@@ -5424,7 +5424,7 @@ int TC_LOG_MMAP::open(const char *opt_na
pg->state=POOL;
pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST);
pthread_cond_init (&pg->cond, 0);
- pg->start=(my_xid *)(data + i*tc_log_page_size);
+ pg->ptr= pg->start=(my_xid *)(data + i*tc_log_page_size);
pg->size=pg->free=tc_log_page_size/sizeof(my_xid);
pg->end=pg->start + pg->size;
}
@@ -5659,7 +5659,15 @@ int TC_LOG_MMAP::sync()
/* marking 'syncing' slot free */
pthread_mutex_lock(&LOCK_sync);
syncing=0;
- pthread_cond_signal(&active->cond); // wake up a new syncer
+ /*
+ we check the "active" pointer without LOCK_active. Still, it's safe -
+ "active" can change from NULL to not NULL any time, but it
+ will take LOCK_sync before waiting on active->cond. That is, it can never
+ miss a signal.
+ And "active" can change to NULL only after LOCK_sync, so this is safe too.
+ */
+ if (active)
+ pthread_cond_signal(&active->cond); // wake up a new syncer
pthread_mutex_unlock(&LOCK_sync);
return err;
}
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-29 15:13:53 +0000
+++ b/sql/mysqld.cc 2010-03-31 08:17:03 +0000
@@ -8371,6 +8371,8 @@ mysqld_get_one_option(int optid,
case (int) OPT_INIT_RPL_ROLE:
{
int role;
+ LINT_INIT(role);
+
if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role))
{
rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
@@ -8427,6 +8429,8 @@ mysqld_get_one_option(int optid,
case OPT_BINLOG_FORMAT:
{
int id;
+ LINT_INIT(id);
+
if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id))
{
global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
@@ -8677,6 +8681,8 @@ mysqld_get_one_option(int optid,
else
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type))
delay_key_write_options= (uint) type-1;
}
@@ -8688,6 +8694,8 @@ mysqld_get_one_option(int optid,
case OPT_TX_ISOLATION:
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type))
global_system_variables.tx_isolation= (type-1);
break;
@@ -8775,6 +8783,7 @@ mysqld_get_one_option(int optid,
ulong method_conv;
int method;
LINT_INIT(method_conv);
+ LINT_INIT(method);
myisam_stats_method_str= argument;
if (!find_opt_type(argument, &myisam_stats_method_typelib,
@@ -8837,6 +8846,7 @@ mysqld_get_one_option(int optid,
case OPT_THREAD_HANDLING:
{
int id;
+ LINT_INIT(id);
if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id))
global_system_variables.thread_handling= id - 1;
opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];
=== modified file 'sql/net_serv.cc'
--- a/sql/net_serv.cc 2010-02-23 12:04:58 +0000
+++ b/sql/net_serv.cc 2010-03-29 19:07:45 +0000
@@ -279,7 +279,7 @@ static int net_data_is_ready(my_socket s
@param clear_buffer if <> 0, then clear all data from comm buff
*/
-void net_clear(NET *net, my_bool clear_buffer)
+void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
size_t count;
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2010-03-15 11:51:23 +0000
+++ b/sql/set_var.cc 2010-03-31 08:17:03 +0000
@@ -1266,16 +1266,16 @@ uchar *sys_var_set::value_ptr(THD *thd,
void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
{
- slave_exec_mode_options= 0;
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ slave_exec_mode_options= (ULL(1) << SLAVE_EXEC_MODE_STRICT);
}
bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
{
bool rc= sys_var_set::check(thd, var);
if (!rc &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ test_all_bits(var->save_result.ulong_value,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
rc= true;
my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
@@ -1297,15 +1297,16 @@ void fix_slave_exec_mode(enum_var_type t
DBUG_ENTER("fix_slave_exec_mode");
compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT
> SLAVE_EXEC_MODE_LAST_BIT - 1);
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ if (test_all_bits(slave_exec_mode_options,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
sql_print_error("Ambiguous slave modes combination."
" STRICT will be used");
- bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT);
+ slave_exec_mode_options&= ~(ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT);
}
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ if (!(slave_exec_mode_options & (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT)))
+ slave_exec_mode_options|= (ULL(1)<< SLAVE_EXEC_MODE_STRICT);
DBUG_VOID_RETURN;
}
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-29 15:13:53 +0000
+++ b/sql/sql_class.h 2010-03-31 08:17:03 +0000
@@ -63,6 +63,7 @@ public:
bool report_error(THD *thd);
bool is_invalidated() const { return m_invalidated; }
void reset_reprepare_observer() { m_invalidated= FALSE; }
+ Reprepare_observer() {} /* Remove gcc warning */
private:
bool m_invalidated;
};
@@ -1117,6 +1118,7 @@ public:
/* Ignore error */
return TRUE;
}
+ Dummy_error_handler() {} /* Remove gcc warning */
};
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-03-15 11:51:23 +0000
+++ b/sql/sql_table.cc 2010-03-31 08:17:03 +0000
@@ -5704,6 +5704,10 @@ compare_tables(TABLE *table,
*/
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
uint db_options= 0; /* not used */
+
+ /* Set default value for return value (to ensure it's always set) */
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+
/* Create the prepared information. */
if (mysql_prepare_create_table(thd, create_info,
&tmp_alter_info,
@@ -5762,7 +5766,6 @@ compare_tables(TABLE *table,
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
{
DBUG_PRINT("info", ("Basic checks -> ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5792,7 +5795,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("NULL behaviour difference in field '%s' -> "
"ALTER_TABLE_DATA_CHANGED", new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5828,7 +5830,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED",
new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
// Clear indexed marker
@@ -5963,7 +5964,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("check_if_incompatible_data() -> "
"ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_view.cc 2010-03-30 12:36:49 +0000
@@ -1034,10 +1034,12 @@ bool mysql_make_view(THD *thd, File_pars
bool parse_status;
bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables);
-
DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
+ LINT_INIT(parse_status);
+ LINT_INIT(view_select);
+
if (table->view)
{
/*
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-03-29 15:13:53 +0000
+++ b/sql/sql_yacc.yy 2010-03-31 08:17:03 +0000
@@ -8190,7 +8190,7 @@ function_call_generic:
builder= find_qualified_function_builder(thd);
DBUG_ASSERT(builder);
- item= builder->create(thd, $1, $3, true, $5);
+ item= builder->create_with_db(thd, $1, $3, true, $5);
if (! ($$= item))
{
=== modified file 'storage/example/ha_example.h'
--- a/storage/example/ha_example.h 2007-08-13 13:11:25 +0000
+++ b/storage/example/ha_example.h 2010-03-28 18:10:00 +0000
@@ -155,7 +155,8 @@ public:
/** @brief
This method will never be called if you do not implement indexes.
*/
- virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
+ virtual double read_time(uint index, uint ranges, ha_rows rows)
+ { return (double) rows / 20.0+1; }
/*
Everything below are methods that we implement in ha_example.cc.
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2010-03-30 12:35:15 +0000
+++ b/storage/maria/ma_loghandler.c 2010-03-31 08:17:03 +0000
@@ -1274,6 +1274,8 @@ static my_bool translog_set_lsn_for_file
for (file= from_file; file <= to_file; file++)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT(info.max_lsn);
+
File fd= open_logfile_by_number_no_cache(file);
LINT_INIT_STRUCT(info);
if ((fd < 0) ||
@@ -3967,7 +3969,8 @@ my_bool translog_init_with_table(const c
if (!old_log_was_recovered && old_flags == flags)
{
LOGHANDLER_FILE_INFO info;
- LINT_INIT_STRUCT(info);
+ LINT_INIT(info.maria_version);
+
/*
Accessing &log_descriptor.open_files without mutex is safe
because it is initialization
=== modified file 'storage/maria/ma_search.c'
--- a/storage/maria/ma_search.c 2010-03-15 11:51:23 +0000
+++ b/storage/maria/ma_search.c 2010-03-31 08:17:03 +0000
@@ -76,8 +76,8 @@ int _ma_search(register MARIA_HA *info,
bmove512(info->keyread_buff, page_buff, info->s->block_size);
/* Save position for a possible read next / previous */
- info->int_keypos= info->keyread_buff + (ulonglong) info->int_keypos;
- info->int_maxpos= info->keyread_buff + (ulonglong) info->int_maxpos;
+ info->int_keypos= info->keyread_buff + info->keypos_offset;
+ info->int_maxpos= info->keyread_buff + info->maxpos_offset;
info->int_keytree_version= key->keyinfo->version;
info->last_search_keypage= info->last_keypage;
info->page_changed= 0;
@@ -214,8 +214,8 @@ static int _ma_search_no_save(register M
info->cur_row.trid= _ma_trid_from_key(&info->last_key);
/* Store offset to key */
- info->int_keypos= (uchar*) (keypos - page.buff);
- info->int_maxpos= (uchar*) (maxpos - page.buff);
+ info->keypos_offset= (uint) (keypos - page.buff);
+ info->maxpos_offset= (uint) (maxpos - page.buff);
info->int_nod_flag= nod_flag;
info->last_keypage= pos;
*res_page_link= page_link;
=== modified file 'storage/maria/maria_def.h'
--- a/storage/maria/maria_def.h 2010-03-09 19:22:24 +0000
+++ b/storage/maria/maria_def.h 2010-03-28 18:10:00 +0000
@@ -506,8 +506,10 @@ struct st_maria_handler
uchar *first_mbr_key; /* Searhed spatial key */
uchar *rec_buff; /* Temp buffer for recordpack */
uchar *blob_buff; /* Temp buffer for blobs */
- uchar *int_keypos, /* Save position for next/previous */
- *int_maxpos; /* -""- */
+ uchar *int_keypos; /* Save position for next/previous */
+ uchar *int_maxpos; /* -""- */
+ uint keypos_offset; /* Tmp storage for offset int_keypos */
+ uint maxpos_offset; /* Tmp storage for offset int_maxpos */
uchar *update_field_data; /* Used by update in rows-in-block */
uint int_nod_flag; /* -""- */
uint32 int_keytree_version; /* -""- */
=== modified file 'storage/myisam/ft_stopwords.c'
--- a/storage/myisam/ft_stopwords.c 2010-03-10 10:32:14 +0000
+++ b/storage/myisam/ft_stopwords.c 2010-03-28 18:10:00 +0000
@@ -44,9 +44,10 @@ static void FT_STOPWORD_free(FT_STOPWORD
static int ft_add_stopword(const char *w)
{
FT_STOPWORD sw;
- return !w ||
- (((sw.len= (uint) strlen(sw.pos=(const uchar *)w)) >= ft_min_word_len) &&
- (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL));
+ return (!w ||
+ (((sw.len= (uint) strlen((char*) (sw.pos=(const uchar *)w))) >=
+ ft_min_word_len) &&
+ (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL)));
}
int ft_init_stopwords()
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2010-03-04 08:03:07 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-03-30 12:36:49 +0000
@@ -382,7 +382,7 @@ static MI_INFO *myisammrg_attach_childre
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
}
DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d",
- my_errno ? NULL : (long) myisam, my_errno));
+ my_errno ? 0L : (long) myisam, my_errno));
err:
DBUG_RETURN(my_errno ? NULL : myisam);
=== modified file 'storage/myisammrg/myrg_open.c'
--- a/storage/myisammrg/myrg_open.c 2009-09-23 13:21:29 +0000
+++ b/storage/myisammrg/myrg_open.c 2010-03-30 12:36:49 +0000
@@ -239,6 +239,7 @@ MYRG_INFO *myrg_parent_open(const char *
rc= 1;
errpos= 0;
bzero((char*) &file_cache, sizeof(file_cache));
+ LINT_INIT(m_info);
/* Open MERGE meta file. */
if ((fd= my_open(fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT,
=== added directory 'storage/oqgraph'
=== added file 'storage/oqgraph/CMakeFiles.txt'
--- a/storage/oqgraph/CMakeFiles.txt 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/CMakeFiles.txt 2010-01-04 08:27:50 +0000
@@ -0,0 +1,22 @@
+# Copyright (C) 2006 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+ADD_LIBRARY(oqgraph ha_oqgraph.cc)
=== added file 'storage/oqgraph/Makefile.am'
--- a/storage/oqgraph/Makefile.am 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/Makefile.am 2010-03-30 18:12:00 +0000
@@ -0,0 +1,96 @@
+# Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+# ======================================================================
+# Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+# Mk.II implementation by Antony Curtis & Arjen Lentz
+# For more information, documentation, support, enhancement engineering,
+# and non-GPL licensing, see http://openquery.com/graph
+# or contact graph(a)openquery.com
+# For packaged binaries, see http://ourdelta.org
+# ======================================================================
+
+mysqlplugindir= $(pkglibdir)/plugin
+
+BOOST_CXXFLAGS = -frtti -fexceptions -fimplicit-templates
+#BOOST_CXXFLAGS+= -g
+#original flags before 2009-11-10
+#BOOST_CXXFLAGS+= -O3 -fomit-frame-pointer -fstrict-aliasing
+#BOOST_CXXFLAGS+= -momit-leaf-frame-pointer -falign-loops
+#modified flags:
+# - remove omit-frame-pointer, x86 specific (fails on PPC) + hinders debugging
+# Option details from gcc man:
+# Don't keep the frame pointer in a register for functions that don't need one.
+# This avoids the instructions to save, set up and restore frame pointers;
+# it also makes an extra register available in many functions.
+# It also makes debugging impossible on some machines.
+# (automatically gets enabled anyway by -O* on some architectures)
+BOOST_CXXFLAGS+= -O3 -fstrict-aliasing
+BOOST_CXXFLAGS+= -falign-loops
+BOOST_CXXFLAGS+= -fvisibility-inlines-hidden
+BOOST_CXXFLAGS+= -funroll-loops -fno-trapping-math
+
+EXTRA_DIST = ha_oqgraph.h ha_oqgraph.cc graphcore.cc \
+ graphcore-graph.h graphcore-types.h graphcore.h \
+ CMakeFiles.txt plug.in oqgraph_probes.d
+
+# DTRACE = @DTRACE@
+# DTRACEFLAGS = @DTRACEFLAGS@
+# DTRACEFILES = .libs/liboqgraph_engine_la-ha_oqgraph.o
+
+ORIG_CXXFLAGS = @CXXFLAGS@
+CXXFLAGS=
+noinst_HEADERS = ha_oqgraph.h \
+ graphcore-graph.h graphcore-types.h graphcore.h
+# oqgraph_probes.h
+
+noinst_LTLIBRARIES = libgraphcore.la
+libgraphcore_la_SOURCES = graphcore.cc
+libgraphcore_la_CXXFLAGS = $(ORIG_CXXFLAGS) $(BOOST_CXXFLAGS)
+
+if BUILD_OQGRAPH_FOR_MYSQL
+
+if BUILD_OQGRAPH_STANDALONE
+INCLUDES = -DDBUG_ON -DSAFE_MUTEX -DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX -DHAVE_OQGRAPH $(MYSQL_INC)
+else
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/regex -I$(top_srcdir)/sql -I$(srcdir) -DHAVE_OQGRAPH
+endif !BUILD_OQGRAPH_STANDALONE
+
+EXTRA_LTLIBRARIES = oqgraph_engine.la
+mysqlplugin_LTLIBRARIES = @plugin_oqgraph_shared_target@
+oqgraph_engine_la_SOURCES = ha_oqgraph.cc
+oqgraph_engine_la_LIBADD = libgraphcore.la
+
+# if HAVE_DTRACE
+# oqgraph_engine_la_LIBADD += oqgraph_probes.o
+# endif
+
+oqgraph_engine_la_LDFLAGS = -module -rpath $(mysqlplugindir)
+oqgraph_engine_la_CFLAGS = $(ORIG_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+oqgraph_engine_la_CXXFLAGS = $(ORIG_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+
+# oqgraph_probes.h: oqgraph_probes.d
+# $(DTRACE) $(DTRACEFLAGS) -h -s oqgraph_probes.d
+# mv oqgraph_probes.h oqgraph_probes.h.bak
+# sed "s/#include <unistd.h>//g" oqgraph_probes.h.bak > oqgraph_probes.h
+# rm oqgraph_probes.h.bak
+
+# oqgraph_probes.o:
+# $(DTRACE) $(DTRACEFLAGS) -G -s oqgraph_probes.d $(DTRACEFILES)
+
+endif BUILD_OQGRAPH_FOR_MYSQL
+
+# End
=== added file 'storage/oqgraph/README'
--- a/storage/oqgraph/README 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/README 2010-03-30 07:33:38 +0000
@@ -0,0 +1,16 @@
+OQGraph storage engine
+Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+The Open Query GRAPH engine (OQGRAPH) is a computation engine allowing
+hierarchies and more complex graph structures to be handled in a
+relational fashion. In a nutshell, tree structures and
+friend-of-a-friend style searches can now be done using standard SQL
+syntax, and results joined onto other tables.
+
+See http://openquery.com/graph for more information.
+
+
+INSTALLATION
+
+OQGraph requires at least version 1.40.0 of the Boost library. To
+obtain a copy of the Boost library, see http://www.boost.org/
=== added file 'storage/oqgraph/graphcore-graph.h'
--- a/storage/oqgraph/graphcore-graph.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphcore-graph.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,48 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifndef oq_graphcore_graph_h_
+#define oq_graphcore_graph_h_
+
+typedef adjacency_list
+<
+ vecS,
+ vecS,
+ bidirectionalS,
+ VertexInfo,
+ EdgeInfo
+> Graph;
+
+#define GRAPH_WEIGHTMAP(G) get(&EdgeInfo::weight, G)
+typedef property_map<Graph, EdgeWeight EdgeInfo::*>::type weightmap_type;
+
+#define GRAPH_INDEXMAP(G) get(vertex_index, G)
+typedef property_map<Graph, vertex_index_t>::type indexmap_type;
+
+#define GRAPH_IDMAP(G) get(&VertexInfo::id, G)
+typedef property_map<Graph, VertexID VertexInfo::*>::type idmap_type;
+
+#endif
=== added file 'storage/oqgraph/graphcore-types.h'
--- a/storage/oqgraph/graphcore-types.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphcore-types.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,36 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifndef oq_graphcore_types_h_
+#define oq_graphcore_types_h_
+namespace open_query
+{
+
+ typedef unsigned long long VertexID;
+ typedef double EdgeWeight;
+
+}
+#endif
=== added file 'storage/oqgraph/graphcore.cc'
--- a/storage/oqgraph/graphcore.cc 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphcore.cc 2010-03-31 07:54:07 +0000
@@ -0,0 +1,1101 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#include <strings.h>
+
+#define BOOST_ALL_NO_LIB 1
+
+#include <boost/config.hpp>
+
+#include <set>
+#include <stack>
+
+#include <boost/property_map/property_map.hpp>
+
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/graph_archetypes.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/reverse_graph.hpp>
+#include <boost/graph/graph_utility.hpp>
+
+#include "graphcore.h"
+
+using namespace open_query;
+using namespace boost;
+
+static const row empty_row = { 0 };
+
+namespace open_query
+{
+ enum vertex_id_t { vertex_id };
+
+ struct VertexInfo {
+ inline VertexInfo() { }
+
+ inline VertexInfo(VertexID _id)
+ : id(_id) { }
+
+ VertexID id;
+ };
+
+ struct EdgeInfo {
+ EdgeWeight weight;
+ };
+}
+
+namespace boost
+{
+ BOOST_INSTALL_PROPERTY(vertex, id);
+
+ namespace graph
+ {
+ template<>
+ struct internal_vertex_name<VertexInfo>
+ {
+ typedef multi_index::member<VertexInfo, VertexID, &VertexInfo::id> type;
+ };
+
+ template<>
+ struct internal_vertex_constructor<VertexInfo>
+ {
+ typedef vertex_from_name<VertexInfo> type;
+ };
+ }
+}
+
+namespace open_query
+{
+
+ #include "graphcore-graph.h"
+
+ typedef graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef graph_traits<Graph>::edge_descriptor Edge;
+
+ typedef std::list<std::pair<Vertex,optional<EdgeWeight> > > shortest_path_list;
+ typedef shortest_path_list::iterator shortest_path_iterator;
+
+ template<typename ID, typename IDMap>
+ class id_equals_t
+ {
+ public:
+ id_equals_t(ID id, IDMap map)
+ : m_id(id), m_map(map)
+ { }
+ template<typename V>
+ bool operator()(V u) const
+ {
+ return m_map[u] == m_id;
+ }
+ private:
+ ID m_id;
+ IDMap m_map;
+ };
+
+ template<typename ID, typename IDMap>
+ inline id_equals_t<ID,IDMap>
+ id_equals(ID id, IDMap idmap)
+ {
+ return id_equals_t<ID,IDMap>(id, idmap);
+ }
+
+ template<typename T, typename Graph>
+ class target_equals_t
+ {
+ public:
+ target_equals_t(T target, Graph &g)
+ : m_target(target), m_g(g)
+ { }
+ template<typename V>
+ bool operator()(V u) const
+ {
+ return target(u, m_g) == m_target;
+ }
+ private:
+ T m_target;
+ Graph &m_g;
+ };
+
+ template<typename T, typename Graph>
+ inline target_equals_t<T,Graph>
+ target_equals(T target, Graph &g)
+ {
+ return target_equals_t<T,Graph>(target, g);
+ }
+
+ template<typename T, typename Graph>
+ class source_equals_t
+ {
+ public:
+ source_equals_t(T source, Graph &g)
+ : m_source(source), m_g(g)
+ { }
+ template<typename V>
+ bool operator()(V u) const
+ {
+ return source(u, m_g) == m_source;
+ }
+ private:
+ T m_source;
+ Graph &m_g;
+ };
+
+ template<typename T, typename Graph>
+ inline source_equals_t<T,Graph>
+ source_equals(T source, Graph &g)
+ {
+ return source_equals_t<T,Graph>(source, g);
+ }
+
+ struct reference
+ {
+ int m_flags;
+ int m_sequence;
+ Vertex m_vertex;
+ Edge m_edge;
+ EdgeWeight m_weight;
+
+ enum
+ {
+ HAVE_SEQUENCE = 1,
+ HAVE_WEIGHT = 2,
+ HAVE_EDGE = 4,
+ };
+
+ inline reference()
+ : m_flags(0), m_sequence(0),
+ m_vertex(graph_traits<Graph>::null_vertex()),
+ m_edge(), m_weight(0)
+ { }
+
+ inline reference(int s, Edge e)
+ : m_flags(HAVE_SEQUENCE | HAVE_EDGE), m_sequence(s),
+ m_vertex(graph_traits<Graph>::null_vertex()),
+ m_edge(e), m_weight(0)
+ { }
+
+ inline reference(int s, Vertex v, const optional<Edge> &e,
+ const optional<EdgeWeight> &w)
+ : m_flags(HAVE_SEQUENCE | (w ? HAVE_WEIGHT : 0) | (e ? HAVE_EDGE : 0)),
+ m_sequence(s), m_vertex(v)
+ {
+ if (w) m_weight= *w;
+ if (e) m_edge= *e;
+ }
+
+ inline reference(int s, Vertex v, Edge e, EdgeWeight w)
+ : m_flags(HAVE_SEQUENCE | HAVE_WEIGHT | HAVE_EDGE),
+ m_sequence(s), m_vertex(v), m_edge(e), m_weight(w)
+ { }
+
+ inline reference(int s, Vertex v, EdgeWeight w)
+ : m_flags(HAVE_SEQUENCE | HAVE_WEIGHT),
+ m_sequence(s), m_vertex(v), m_edge(), m_weight(w)
+ { }
+
+ inline reference(int s, Vertex v)
+ : m_flags(HAVE_SEQUENCE), m_sequence(s), m_vertex(v), m_edge(),
+ m_weight(0)
+ { }
+
+ optional<int> sequence() const
+ {
+ if (m_flags & HAVE_SEQUENCE)
+ {
+ return m_sequence;
+ }
+ return optional<int>();
+ }
+
+ optional<Vertex> vertex() const
+ {
+ if (m_vertex != graph_traits<Graph>::null_vertex())
+ return m_vertex;
+ return optional<Vertex>();
+ }
+
+ optional<Edge> edge() const
+ {
+ if (m_flags & HAVE_EDGE)
+ return m_edge;
+ return optional<Edge>();
+ };
+
+ optional<EdgeWeight> weight() const
+ {
+ if (m_flags & HAVE_WEIGHT)
+ return m_weight;
+ return optional<EdgeWeight>();
+ }
+ };
+}
+
+namespace open_query {
+ class GRAPHCORE_INTERNAL oqgraph_share
+ {
+ public:
+ Graph g;
+
+ weightmap_type weightmap;
+ idmap_type idmap;
+ indexmap_type indexmap;
+
+ optional<Vertex> find_vertex(VertexID id) const;
+ optional<Edge> find_edge(Vertex, Vertex) const;
+
+ inline oqgraph_share() throw()
+ : g(),
+ weightmap(GRAPH_WEIGHTMAP(g)),
+ idmap(GRAPH_IDMAP(g)),
+ indexmap(GRAPH_INDEXMAP(g))
+ { }
+ inline ~oqgraph_share()
+ { }
+ };
+
+ class GRAPHCORE_INTERNAL oqgraph_cursor
+ {
+ public:
+ oqgraph_share *const share;
+
+ inline oqgraph_cursor(oqgraph_share *arg)
+ : share(arg)
+ { }
+ virtual ~oqgraph_cursor()
+ { }
+
+ virtual int fetch_row(const row &, row&) = 0;
+ virtual int fetch_row(const row &, row&, const reference&) = 0;
+ virtual void current(reference& ref) const = 0;
+ };
+}
+
+namespace open_query {
+ class GRAPHCORE_INTERNAL stack_cursor : public oqgraph_cursor
+ {
+ private:
+ optional<EdgeWeight> no_weight;
+ public:
+ int sequence;
+ std::stack<reference> results;
+ reference last;
+
+ inline stack_cursor(oqgraph_share *arg)
+ : oqgraph_cursor(arg), no_weight(), sequence(0), results(), last()
+ { }
+
+ int fetch_row(const row &, row&);
+ int fetch_row(const row &, row&, const reference&);
+
+ void current(reference& ref) const
+ {
+ ref= last;
+ }
+ };
+
+ class GRAPHCORE_INTERNAL vertices_cursor : public oqgraph_cursor
+ {
+ typedef graph_traits<Graph>::vertex_iterator vertex_iterator;
+
+ size_t position;
+ reference last;
+ public:
+ inline vertices_cursor(oqgraph_share *arg)
+ : oqgraph_cursor(arg), position(0)
+ { }
+
+ int fetch_row(const row &, row&);
+ int fetch_row(const row &, row&, const reference&);
+
+ void current(reference& ref) const
+ {
+ ref= last;
+ }
+
+ };
+
+ class GRAPHCORE_INTERNAL edges_cursor : public oqgraph_cursor
+ {
+ typedef graph_traits<Graph>::edge_iterator edge_iterator;
+ typedef edge_iterator::difference_type edge_difference;
+
+ edge_difference position;
+ reference last;
+ public:
+ inline edges_cursor(oqgraph_share *arg)
+ : oqgraph_cursor(arg), position(0), last()
+ { }
+
+ int fetch_row(const row &, row&);
+ int fetch_row(const row &, row&, const reference&);
+
+ void current(reference& ref) const
+ {
+ ref= last;
+ }
+ };
+
+ struct GRAPHCORE_INTERNAL oqgraph_visit_dist
+ : public base_visitor<oqgraph_visit_dist>
+ {
+ typedef on_finish_vertex event_filter;
+
+ oqgraph_visit_dist(std::vector<Vertex>::iterator p,
+ std::vector<EdgeWeight>::iterator d,
+ stack_cursor *cursor)
+ : seq(0), m_cursor(*cursor), m_p(p), m_d(d)
+ { assert(cursor); }
+
+ template<class T, class Graph>
+ void operator()(T u, Graph &g)
+ {
+ m_cursor.results.push(reference(++seq, u, m_d[GRAPH_INDEXMAP(g)[u]]));
+ }
+ private:
+ int seq;
+ stack_cursor &m_cursor;
+ std::vector<Vertex>::iterator m_p;
+ std::vector<EdgeWeight>::iterator m_d;
+ };
+
+ template<bool record_weight, typename goal_filter>
+ struct GRAPHCORE_INTERNAL oqgraph_goal
+ : public base_visitor<oqgraph_goal<record_weight,goal_filter> >
+ {
+ typedef goal_filter event_filter;
+
+ oqgraph_goal(Vertex goal, std::vector<Vertex>::iterator p,
+ stack_cursor *cursor)
+ : m_goal(goal), m_cursor(*cursor), m_p(p)
+ { assert(cursor); }
+
+ template<class T, class Graph>
+ void operator()(T u, Graph &g)
+ {
+ if (u == m_goal)
+ {
+ int seq= 0;
+ indexmap_type indexmap= GRAPH_INDEXMAP(g);
+
+ for (Vertex q, v= u;; v = q, seq++)
+ if ((q= m_p[ indexmap[v] ]) == v)
+ break;
+
+ for (Vertex v= u;; u= v)
+ {
+ optional<Edge> edge;
+ optional<EdgeWeight> weight;
+ v= m_p[ indexmap[u] ];
+ if (record_weight && u != v)
+ {
+ typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end)= out_edges(v, g); ei != ei_end; ++ei)
+ {
+ if (target(*ei, g) == u)
+ {
+ edge= *ei;
+ weight= GRAPH_WEIGHTMAP(g)[*ei];
+ break;
+ }
+ }
+ }
+ else if (u != v)
+ weight= 1;
+ m_cursor.results.push(reference(seq--, u, edge, weight));
+ if (u == v)
+ break;
+ }
+ throw this;
+ }
+ }
+
+ private:
+ Vertex m_goal;
+ stack_cursor &m_cursor;
+ std::vector<Vertex>::iterator m_p;
+ };
+}
+
+namespace open_query
+{
+ inline oqgraph::oqgraph(oqgraph_share *arg) throw()
+ : share(arg), cursor(0)
+ { }
+
+ inline oqgraph::~oqgraph() throw()
+ {
+ delete cursor;
+ }
+
+ unsigned oqgraph::edges_count() const throw()
+ {
+ return num_edges(share->g);
+ }
+
+ unsigned oqgraph::vertices_count() const throw()
+ {
+ return num_vertices(share->g);
+ }
+
+ oqgraph* oqgraph::create(oqgraph_share *share) throw()
+ {
+ assert(share != NULL);
+ return new (std::nothrow) oqgraph(share);
+ }
+
+ oqgraph_share* oqgraph::create() throw()
+ {
+ return new (std::nothrow) oqgraph_share();
+ }
+
+ optional<Edge>
+ oqgraph_share::find_edge(Vertex orig, Vertex dest) const
+ {
+ if (in_degree(dest, g) >= out_degree(orig, g))
+ {
+ graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ tie(ei, ei_end)= out_edges(orig, g);
+ if ((ei= find_if(ei, ei_end, target_equals(dest, g))) != ei_end)
+ return *ei;
+ }
+ else
+ {
+ graph_traits<Graph>::in_edge_iterator ei, ei_end;
+ tie(ei, ei_end)= in_edges(dest, g);
+ if ((ei= find_if(ei, ei_end, source_equals(orig, g))) != ei_end)
+ return *ei;
+ }
+ return optional<Edge>();
+ }
+
+ optional<Vertex>
+ oqgraph_share::find_vertex(VertexID id) const
+ {
+ return boost::graph::find_vertex(id, g);
+ }
+
+ int oqgraph::delete_all() throw()
+ {
+ share->g.clear();
+ return 0;
+ }
+
+ int oqgraph::insert_edge(
+ VertexID orig_id, VertexID dest_id, EdgeWeight weight, bool replace) throw()
+ {
+ optional<Vertex> orig, dest;
+ optional<Edge> edge;
+ bool inserted= 0;
+
+ if (weight < 0)
+ return INVALID_WEIGHT;
+ if (!(orig= share->find_vertex(orig_id)))
+ {
+ try
+ {
+ orig= add_vertex(VertexInfo(orig_id), share->g);
+ if (orig == graph_traits<Graph>::null_vertex())
+ return CANNOT_ADD_VERTEX;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_VERTEX;
+ }
+ }
+ if (!(dest= share->find_vertex(dest_id)))
+ {
+ try
+ {
+ dest= add_vertex(VertexInfo(dest_id), share->g);
+ if (dest == graph_traits<Graph>::null_vertex())
+ return CANNOT_ADD_VERTEX;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_VERTEX;
+ }
+ }
+ if (!(edge= share->find_edge(*orig, *dest)))
+ {
+ try
+ {
+ tie(edge, inserted)= add_edge(*orig, *dest, share->g);
+ if (!inserted)
+ return CANNOT_ADD_EDGE;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_EDGE;
+ }
+ }
+ else
+ {
+ if (!replace)
+ return DUPLICATE_EDGE;
+ }
+ share->weightmap[*edge]= weight;
+ return OK;
+ }
+
+ int oqgraph::delete_edge(current_row_st) throw()
+ {
+ reference ref;
+ if (cursor)
+ return EDGE_NOT_FOUND;
+ cursor->current(ref);
+ optional<Edge> edge;
+ if (!(edge= ref.edge()))
+ return EDGE_NOT_FOUND;
+ Vertex orig= source(*edge, share->g);
+ Vertex dest= target(*edge, share->g);
+ remove_edge(*edge, share->g);
+ if (!degree(orig, share->g))
+ remove_vertex(orig, share->g);
+ if (!degree(dest, share->g))
+ remove_vertex(dest, share->g);
+ return OK;
+ }
+
+ int oqgraph::modify_edge(current_row_st,
+ VertexID *orig_id, VertexID *dest_id, EdgeWeight *weight,
+ bool replace) throw()
+ {
+ if (!cursor)
+ return EDGE_NOT_FOUND;
+ reference ref;
+ cursor->current(ref);
+ optional<Edge> edge;
+ if (!(edge= ref.edge()))
+ return EDGE_NOT_FOUND;
+ if (weight && *weight < 0)
+ return INVALID_WEIGHT;
+
+ optional<Vertex> orig= source(*edge, share->g),
+ dest= target(*edge, share->g);
+
+ bool orig_neq= orig_id ? share->idmap[*orig] != *orig_id : 0;
+ bool dest_neq= dest_id ? share->idmap[*dest] != *dest_id : 0;
+ if (orig_neq || dest_neq)
+ {
+ optional<Edge> new_edge;
+ if (orig_neq && !(orig= share->find_vertex(*orig_id)))
+ {
+ try
+ {
+ orig= add_vertex(VertexInfo(*orig_id), share->g);
+ if (orig == graph_traits<Graph>::null_vertex())
+ return CANNOT_ADD_VERTEX;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_VERTEX;
+ }
+ }
+ if (dest_neq && !(dest= share->find_vertex(*dest_id)))
+ {
+ try
+ {
+ dest= add_vertex(VertexInfo(*dest_id), share->g);
+ if (dest == graph_traits<Graph>::null_vertex())
+ return CANNOT_ADD_VERTEX;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_VERTEX;
+ }
+ }
+ if (!(new_edge= share->find_edge(*orig, *dest)))
+ {
+ try
+ {
+ bool inserted;
+ tie(new_edge, inserted)= add_edge(*orig, *dest, share->g);
+ if (!inserted)
+ return CANNOT_ADD_EDGE;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_EDGE;
+ }
+ }
+ else
+ {
+ if (!replace)
+ return DUPLICATE_EDGE;
+ }
+ share->weightmap[*new_edge]= share->weightmap[*edge];
+ remove_edge(*edge, share->g);
+ edge= new_edge;
+ }
+ if (weight)
+ share->weightmap[*edge]= *weight;
+ return OK;
+ }
+
+ int oqgraph::modify_edge(
+ VertexID orig_id, VertexID dest_id, EdgeWeight weight) throw()
+ {
+ optional<Vertex> orig, dest;
+ optional<Edge> edge;
+
+ if (weight < 0)
+ return INVALID_WEIGHT;
+ if (!(orig= share->find_vertex(orig_id)))
+ return EDGE_NOT_FOUND;
+ if (!(dest= share->find_vertex(dest_id)))
+ return EDGE_NOT_FOUND;
+ if (!(edge= share->find_edge(*orig, *dest)))
+ return EDGE_NOT_FOUND;
+ share->weightmap[*edge]= weight;
+ return OK;
+ }
+
+
+ int oqgraph::delete_edge(VertexID orig_id, VertexID dest_id) throw()
+ {
+ optional<Vertex> orig, dest;
+ optional<Edge> edge;
+
+ if (!(orig= share->find_vertex(orig_id)))
+ return EDGE_NOT_FOUND;
+ if (!(dest= share->find_vertex(dest_id)))
+ return EDGE_NOT_FOUND;
+ if (!(edge= share->find_edge(*orig, *dest)))
+ return EDGE_NOT_FOUND;
+ remove_edge(*edge, share->g);
+ if (!degree(*orig, share->g))
+ remove_vertex(*orig, share->g);
+ if (!degree(*dest, share->g))
+ remove_vertex(*dest, share->g);
+ return OK;
+ }
+
+
+ int oqgraph::search(int *latch, VertexID *orig_id, VertexID *dest_id) throw()
+ {
+ optional<Vertex> orig, dest;
+ int op= 0, seq= 0;
+ enum {
+ NO_SEARCH = 0,
+ DIJKSTRAS = 1,
+ BREADTH_FIRST = 2,
+
+ ALGORITHM = 0x0ffff,
+ HAVE_ORIG = 0x10000,
+ HAVE_DEST = 0x20000,
+ };
+
+ delete cursor; cursor= 0;
+ row_info= empty_row;
+ if ((row_info.latch_indicator= latch))
+ op= ALGORITHM & (row_info.latch= *latch);
+ if ((row_info.orig_indicator= orig_id) && (op|= HAVE_ORIG))
+ orig= share->find_vertex((row_info.orig= *orig_id));
+ if ((row_info.dest_indicator= dest_id) && (op|= HAVE_DEST))
+ dest= share->find_vertex((row_info.dest= *dest_id));
+ //try
+ //{
+ switch (op)
+ {
+ case NO_SEARCH | HAVE_ORIG | HAVE_DEST:
+ case NO_SEARCH | HAVE_ORIG:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && orig)
+ {
+ graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end)= out_edges(*orig, share->g); ei != ei_end; ++ei)
+ {
+ Vertex v= target(*ei, share->g);
+ static_cast<stack_cursor*>(cursor)->
+ results.push(reference(++seq, v, *ei, share->weightmap[*ei]));
+ }
+ }
+ /* fall through */
+ case NO_SEARCH | HAVE_DEST:
+ if ((op & HAVE_DEST) &&
+ (cursor || (cursor= new (std::nothrow) stack_cursor(share))) &&
+ dest)
+ {
+ graph_traits<Graph>::in_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end)= in_edges(*dest, share->g); ei != ei_end; ++ei)
+ {
+ Vertex v= source(*ei, share->g);
+ static_cast<stack_cursor*>(cursor)->
+ results.push(reference(++seq, v, *ei, share->weightmap[*ei]));
+ }
+ }
+ break;
+
+ case NO_SEARCH:
+ cursor= new (std::nothrow) vertices_cursor(share);
+ break;
+
+ case DIJKSTRAS | HAVE_ORIG | HAVE_DEST:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && orig && dest)
+ {
+ std::vector<Vertex> p(num_vertices(share->g));
+ std::vector<EdgeWeight> d(num_vertices(share->g));
+ oqgraph_goal<true, on_finish_vertex>
+ vis(*dest, p.begin(), static_cast<stack_cursor*>(cursor));
+ p[share->indexmap[*orig]]= *orig;
+ try
+ {
+ dijkstra_shortest_paths(share->g, *orig,
+ weight_map(
+ share->weightmap
+ ).
+ distance_map(
+ make_iterator_property_map(d.begin(), share->indexmap)
+ ).
+ predecessor_map(
+ make_iterator_property_map(p.begin(), share->indexmap)
+ ).
+ visitor(
+ make_dijkstra_visitor(vis)
+ )
+ );
+ }
+ catch (...)
+ { /* printf("found\n"); */ }
+ }
+ break;
+
+ case BREADTH_FIRST | HAVE_ORIG | HAVE_DEST:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && orig && dest)
+ {
+ std::vector<Vertex> p(num_vertices(share->g));
+ oqgraph_goal<false, on_discover_vertex>
+ vis(*dest, p.begin(), static_cast<stack_cursor*>(cursor));
+ p[share->indexmap[*orig]]= *orig;
+ try
+ {
+ breadth_first_search(share->g, *orig,
+ visitor(make_bfs_visitor(
+ std::make_pair(
+ record_predecessors(
+ make_iterator_property_map(p.begin(), share->indexmap),
+ on_tree_edge()
+ ),
+ vis)
+ )
+ )
+ );
+ }
+ catch (...)
+ { /* printf("found\n"); */ }
+ }
+ break;
+
+ case DIJKSTRAS | HAVE_ORIG:
+ case BREADTH_FIRST | HAVE_ORIG:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && (orig || dest))
+ {
+ std::vector<Vertex> p(num_vertices(share->g));
+ std::vector<EdgeWeight> d(num_vertices(share->g));
+ oqgraph_visit_dist vis(p.begin(), d.begin(),
+ static_cast<stack_cursor*>(cursor));
+ p[share->indexmap[*orig]]= *orig;
+ switch (ALGORITHM & op)
+ {
+ case DIJKSTRAS:
+ dijkstra_shortest_paths(share->g, *orig,
+ weight_map(
+ share->weightmap
+ ).
+ distance_map(
+ make_iterator_property_map(d.begin(), share->indexmap)
+ ).
+ predecessor_map(
+ make_iterator_property_map(p.begin(), share->indexmap)
+ ).
+ visitor(
+ make_dijkstra_visitor(vis)
+ )
+ );
+ break;
+ case BREADTH_FIRST:
+ breadth_first_search(share->g, *orig,
+ visitor(make_bfs_visitor(
+ std::make_pair(
+ record_predecessors(
+ make_iterator_property_map(p.begin(),
+ share->indexmap),
+ on_tree_edge()
+ ),
+ std::make_pair(
+ record_distances(
+ make_iterator_property_map(d.begin(),
+ share->indexmap),
+ on_tree_edge()
+ ),
+ vis
+ ))
+ ))
+ );
+ break;
+ default:
+ abort();
+ }
+ }
+ break;
+
+ case BREADTH_FIRST | HAVE_DEST:
+ case DIJKSTRAS | HAVE_DEST:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && (orig || dest))
+ {
+ std::vector<Vertex> p(num_vertices(share->g));
+ std::vector<EdgeWeight> d(num_vertices(share->g));
+ oqgraph_visit_dist vis(p.begin(), d.begin(),
+ static_cast<stack_cursor*>(cursor));
+ reverse_graph<Graph> r(share->g);
+ p[share->indexmap[*dest]]= *dest;
+ switch (ALGORITHM & op)
+ {
+ case DIJKSTRAS:
+ dijkstra_shortest_paths(r, *dest,
+ weight_map(
+ share->weightmap
+ ).
+ distance_map(
+ make_iterator_property_map(d.begin(), share->indexmap)
+ ).
+ predecessor_map(
+ make_iterator_property_map(p.begin(), share->indexmap)
+ ).
+ visitor(
+ make_dijkstra_visitor(vis)
+ )
+ );
+ break;
+ case BREADTH_FIRST:
+ breadth_first_search(r, *dest,
+ visitor(make_bfs_visitor(
+ std::make_pair(
+ record_predecessors(
+ make_iterator_property_map(p.begin(),
+ share->indexmap),
+ on_tree_edge()
+ ),
+ std::make_pair(
+ record_distances(
+ make_iterator_property_map(d.begin(),
+ share->indexmap),
+ on_tree_edge()
+ ),
+ vis
+ ))
+ ))
+ );
+ break;
+ default:
+ abort();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+ //}
+ //catch (...)
+ //{
+ // return MISC_FAIL;
+ //}
+ }
+
+ int oqgraph::fetch_row(row& result) throw()
+ {
+ if (!cursor)
+ return NO_MORE_DATA;
+ return cursor->fetch_row(row_info, result);
+ }
+
+ int oqgraph::fetch_row(row& result, const void* ref_ptr) throw()
+ {
+ const reference &ref= *(const reference*) ref_ptr;
+ if (!cursor)
+ return NO_MORE_DATA;
+ return cursor->fetch_row(row_info, result, ref);
+ }
+
+ void oqgraph::row_ref(void *ref_ptr) throw()
+ {
+ reference &ref= *(reference*) ref_ptr;
+ if (cursor)
+ cursor->current(ref);
+ else
+ ref= reference();
+ }
+
+ int oqgraph::random(bool scan) throw()
+ {
+ if (scan || !cursor)
+ {
+ delete cursor; cursor= 0;
+ if (!(cursor= new (std::nothrow) edges_cursor(share)))
+ return MISC_FAIL;
+ }
+ row_info= empty_row;
+ return OK;
+ }
+
+ void oqgraph::free(oqgraph *graph) throw()
+ {
+ delete graph;
+ }
+
+ void oqgraph::free(oqgraph_share *graph) throw()
+ {
+ delete graph;
+ }
+
+ const size_t oqgraph::sizeof_ref= sizeof(reference);
+}
+
+int stack_cursor::fetch_row(const row &row_info, row &result)
+{
+ if (!results.empty())
+ {
+ if (int res= fetch_row(row_info, result, results.top()))
+ return res;
+ results.pop();
+ return oqgraph::OK;
+ }
+ else
+ {
+ last= reference();
+ return oqgraph::NO_MORE_DATA;
+ }
+}
+
+int stack_cursor::fetch_row(const row &row_info, row &result,
+ const reference &ref)
+{
+ last= ref;
+ if (optional<Vertex> v= last.vertex())
+ {
+ optional<int> seq;
+ optional<EdgeWeight> w;
+ optional<Vertex> v;
+ result= row_info;
+ if ((result.seq_indicator= seq= last.sequence()))
+ result.seq= *seq;
+ if ((result.link_indicator= v= last.vertex()))
+ result.link= share->idmap[*v];
+ if ((result.weight_indicator= w= last.weight()))
+ result.weight= *w;
+ return oqgraph::OK;
+ }
+ else
+ return oqgraph::NO_MORE_DATA;
+}
+
+
+int vertices_cursor::fetch_row(const row &row_info, row &result)
+{
+ vertex_iterator it, end;
+ reference ref;
+ size_t count= position;
+ for (tie(it, end)= vertices(share->g); count && it != end; ++it, --count)
+ ;
+ if (it != end)
+ ref= reference(position+1, *it);
+ if (int res= fetch_row(row_info, result, ref))
+ return res;
+ position++;
+ return oqgraph::OK;
+}
+
+int vertices_cursor::fetch_row(const row &row_info, row &result,
+ const reference &ref)
+{
+ last= ref;
+ optional<Vertex> v= last.vertex();
+ result= row_info;
+ if (v)
+ {
+ result.link_indicator= 1;
+ result.link= share->idmap[*v];
+#ifdef DISPLAY_VERTEX_INFO
+ result.seq_indicator= 1;
+ if ((result.seq= degree(*v, share->g)))
+ {
+ EdgeWeight weight= 0;
+ graph_traits<Graph>::in_edge_iterator iei, iei_end;
+ for (tie(iei, iei_end)= in_edges(*v, share->g); iei != iei_end; ++iei)
+ weight+= share->weightmap[*iei];
+ graph_traits<Graph>::out_edge_iterator oei, oei_end;
+ for (tie(oei, oei_end)= out_edges(*v, share->g); oei != oei_end; ++oei)
+ weight+= share->weightmap[*oei];
+ result.weight_indicator= 1;
+ result.weight= weight / result.seq;
+ }
+#endif
+ return oqgraph::OK;
+ }
+ else
+ return oqgraph::NO_MORE_DATA;
+}
+
+int edges_cursor::fetch_row(const row &row_info, row &result)
+{
+ edge_iterator it, end;
+ reference ref;
+ size_t count= position;
+ for (tie(it, end)= edges(share->g); count && it != end; ++it, --count)
+ ;
+ if (it != end)
+ ref= reference(position+1, *it);
+ if (int res= fetch_row(row_info, result, ref))
+ return res;
+ ++position;
+ return oqgraph::OK;
+}
+
+int edges_cursor::fetch_row(const row &row_info, row &result,
+ const reference &ref)
+{
+ optional<Edge> edge;
+ if ((edge= (last= ref).edge()))
+ {
+ result= row_info;
+ result.orig_indicator= result.dest_indicator= result.weight_indicator= 1;
+ result.orig= share->idmap[ source( *edge, share->g ) ];
+ result.dest= share->idmap[ target( *edge, share->g ) ];
+ result.weight= share->weightmap[ *edge ];
+ return oqgraph::OK;
+ }
+ return oqgraph::NO_MORE_DATA;
+}
+
+namespace boost {
+ GRAPHCORE_INTERNAL void throw_exception(std::exception const&)
+ {
+ abort();
+ }
+}
=== added file 'storage/oqgraph/graphcore.h'
--- a/storage/oqgraph/graphcore.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphcore.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,116 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifndef oq_graphcore_h_
+#define oq_graphcore_h_
+
+/* #define GRAPHCORE_INTERNAL __attribute__((visibility("hidden"))) */
+#define GRAPHCORE_INTERNAL
+
+#include "graphcore-types.h"
+
+namespace open_query
+{
+ class oqgraph_share;
+ class oqgraph_cursor;
+
+ struct row
+ {
+ bool latch_indicator;
+ bool orig_indicator;
+ bool dest_indicator;
+ bool weight_indicator;
+ bool seq_indicator;
+ bool link_indicator;
+
+ int latch;
+ VertexID orig;
+ VertexID dest;
+ EdgeWeight weight;
+ unsigned seq;
+ VertexID link;
+ };
+
+ class oqgraph
+ {
+ oqgraph_share *const share;
+ oqgraph_cursor *cursor;
+ row row_info;
+
+ inline oqgraph(oqgraph_share*) throw();
+ inline ~oqgraph() throw();
+ public:
+
+ enum error_code
+ {
+ OK= 0,
+ NO_MORE_DATA,
+ EDGE_NOT_FOUND,
+ INVALID_WEIGHT,
+ DUPLICATE_EDGE,
+ CANNOT_ADD_VERTEX,
+ CANNOT_ADD_EDGE,
+ MISC_FAIL
+ };
+
+ struct current_row_st {};
+ static inline current_row_st current_row()
+ { return current_row_st(); }
+
+ unsigned vertices_count() const throw();
+ unsigned edges_count() const throw();
+
+ int delete_all(void) throw();
+
+ int insert_edge(VertexID, VertexID, EdgeWeight, bool=0) throw();
+ int modify_edge(VertexID, VertexID, EdgeWeight) throw();
+ int delete_edge(VertexID, VertexID) throw();
+
+ int modify_edge(current_row_st,
+ VertexID*, VertexID*, EdgeWeight*, bool=0) throw();
+ int delete_edge(current_row_st) throw();
+
+ int replace_edge(VertexID orig, VertexID dest, EdgeWeight weight) throw()
+ { return insert_edge(orig, dest, weight, true); }
+
+ int search(int*, VertexID*, VertexID*) throw();
+ int random(bool) throw();
+
+ int fetch_row(row&) throw();
+ int fetch_row(row&, const void*) throw();
+ void row_ref(void*) throw();
+
+ static oqgraph* create(oqgraph_share*) throw();
+ static oqgraph_share *create() throw();
+
+ static void free(oqgraph*) throw();
+ static void free(oqgraph_share*) throw();
+
+ static const size_t sizeof_ref;
+ };
+
+}
+#endif
=== added file 'storage/oqgraph/graphstore.c'
--- a/storage/oqgraph/graphstore.c 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphstore.c 2010-01-04 08:27:50 +0000
@@ -0,0 +1,356 @@
+/*
+ * Graph Engine - Copyright (C) 2007 by Arjen Lentz (arjen(a)openquery.com.au)
+ * graphstore.c internal storage system
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <my_global.h>
+#include <my_sys.h>
+#include "graphstore.h"
+
+
+/*
+ create a new vertex, and add it to the list (or start a list)
+ NOTE! gspp is ptr to base ptr
+
+ returns 1 for ok, 0 for error
+*/
+static int _add_vertex (GRAPHSTORE **gspp, GRAPH_VERTEXID id)
+{
+ GRAPHSTORE *newgsp;
+ GRAPHSTORE *gscurp;
+
+ if (gspp == NULL)
+ return 0;
+
+ /* not allowing 0 */
+ if (!id)
+ return 0;
+
+ if (*gspp != NULL) {
+ for (gscurp = *gspp; gscurp != NULL; gscurp = gscurp->next) {
+ if (gscurp->vertex->id == id)
+ return 1; /* we can ignore, id already exists */
+ }
+ }
+
+ /* allocate and initialise */
+ if ((newgsp = my_malloc(sizeof (GRAPHSTORE),MYF(MY_ZEROFILL))) == NULL)
+ return 0;
+
+ if ((newgsp->vertex = my_malloc(sizeof (GRAPH_VERTEX),MYF(MY_ZEROFILL))) == NULL) {
+ my_free(newgsp,MYF(0));
+ return 0;
+ }
+
+ newgsp->vertex->id = id;
+ /* add new vertex to end of list */
+ if (*gspp != NULL) {
+ for (gscurp = *gspp; gscurp->next != NULL; gscurp = gscurp->next);
+ gscurp->next = newgsp;
+ }
+ else /* new list */
+ *gspp = newgsp;
+
+ /* ok */
+ return 1;
+}
+
+
+/*
+ find a vertex by id
+
+ returns ptr or NULL
+*/
+static GRAPH_VERTEX *_find_vertex (GRAPHSTORE *gsp, GRAPH_VERTEXID id)
+{
+ /* just loop through the list to find id */
+ while (gsp != NULL && gsp->vertex->id != id)
+ gsp = gsp->next;
+
+ /* return ptr to vertex, or NULL */
+ return (gsp != NULL ? gsp->vertex : NULL);
+}
+
+
+/*
+ add edge
+ both vertices must already exist; graphstore_insert() does this
+
+ return 1 for ok, 0 for error (already exists, alloc error, etc)
+*/
+static int _add_edge (GRAPHSTORE *gsp, GRAPH_VERTEXID origid, GRAPH_VERTEXID destid, GRAPH_WEIGHT weight)
+{
+ GRAPH_VERTEX *origvp, *destvp;
+ GRAPH_EDGE *ep, *newep;
+
+ /* find both vertices */
+ if ((origvp = _find_vertex(gsp,origid)) == NULL ||
+ (destvp = _find_vertex(gsp,destid)) == NULL)
+ return 0;
+
+ /* check if edge already exists */
+ for (ep = origvp->forward_edge; ep != NULL; ep = ep->next_edge) {
+ if (ep->vertex->id == destid)
+ return 0;
+ }
+
+ /* allocate and initialise new edge */
+ if ((newep = my_malloc(sizeof (GRAPH_EDGE),MYF(MY_ZEROFILL))) == NULL)
+ return 0;
+
+ newep->vertex = destvp;
+ newep->weight = weight;
+
+ /* insert new edge at start of chain, that's easiest */
+ ep = origvp->forward_edge;
+ origvp->forward_edge = newep;
+ newep->next_edge = ep;
+
+ /* ok */
+ return 1;
+}
+
+
+/*
+ create a new row, and add it to the graph set (or start set)
+ NOTE! gsetpp is ptr to base ptr
+
+ returns 1 for ok, 0 for error
+*/
+static int _add_graph_set (GRAPH_SET **gsetpp, GRAPH_TUPLE *gtp)
+{
+ GRAPH_SET *newgsetp;
+ GRAPH_SET *gsetcurp;
+
+ if (gsetpp == NULL || gtp == NULL)
+ return 0;
+
+ /* allocate and initialise */
+ if ((newgsetp = my_malloc(sizeof (GRAPH_SET),MYF(MY_ZEROFILL))) == NULL)
+ return 0;
+
+ /* put in the data */
+ memcpy(&newgsetp->tuple,gtp,sizeof (GRAPH_TUPLE));
+
+ /* add new row to end of set */
+ if (*gsetpp != NULL) {
+ for (gsetcurp = *gsetpp; gsetcurp->next != NULL; gsetcurp = gsetcurp->next);
+ gsetcurp->next = newgsetp;
+ }
+ else { /* new set */
+ *gsetpp = newgsetp;
+ }
+
+ /* ok */
+ return 1;
+}
+
+
+/*
+ free a graph set (release memory)
+
+ returns 1 for ok, 0 for error
+*/
+int free_graph_set (GRAPH_SET *gsetp)
+{
+ GRAPH_SET *nextgsetp;
+
+ if (gsetp == NULL)
+ return 0;
+
+ while (gsetp != NULL) {
+ nextgsetp = gsetp->next;
+ /* free() is a void function, nothing to check */
+ my_free(gsetp,MYF(0));
+ gsetp = nextgsetp;
+ }
+
+ /* ok */
+ return 1;
+}
+
+
+/*
+ insert new data into graphstore
+ this can be either a vertex or an edge, depending on the params
+ NOTE! gspp is ptr to base ptr
+
+ returns 1 for ok, 0 for error
+*/
+int graphstore_insert (GRAPHSTORE **gspp, GRAPH_TUPLE *gtp)
+{
+ if (gspp == NULL)
+ return 0;
+
+ /* if nada or no orig vertex, we can't do anything */
+ if (gtp == NULL || !gtp->origid)
+ return 0;
+
+#if 0
+printf("inserting: origid=%lu destid=%lu weight=%lu\n",gtp->origid,gtp->destid,gtp->weight);
+#endif
+
+ if (!gtp->destid) /* no edge param so just adding vertex */
+ return _add_vertex(gspp,gtp->origid);
+
+ /*
+ add an edge
+ first add both vertices just in case they didn't yet exist...
+ not checking result there: if there's a prob, _add_edge() will catch.
+ */
+ _add_vertex(gspp,gtp->origid);
+ _add_vertex(gspp,gtp->destid);
+ return _add_edge(*gspp,gtp->origid,gtp->destid,gtp->weight);
+}
+
+
+/*
+ this is an internal function used by graphstore_query()
+
+ find any path from originating vertex to destid
+ if found, add to the result set on the way back
+ NOTE: recursive function!
+
+ returns 1 for hit, 0 for nothing, -1 for error
+*/
+int _find_any_path(GRAPH_SET **gsetpp, GRAPH_VERTEXID origid, GRAPH_VERTEXID destid, GRAPH_VERTEX *gvp, GRAPH_SEQ depth)
+{
+ GRAPH_EDGE *gep;
+ GRAPH_TUPLE tup;
+ int res;
+
+ if (gvp->id == destid) {
+ /* found target! */
+ bzero(&tup,sizeof (GRAPH_TUPLE));
+ tup.origid = origid;
+ tup.destid = destid;
+ tup.seq = depth;
+ tup.linkid = gvp->id;
+ return (_add_graph_set(gsetpp,&tup) ? 1 : -1);
+ }
+
+ /* walk through all edges for this vertex */
+ for (gep = gvp->forward_edge; gep; gep = gep->next_edge) {
+ /* recurse */
+ res = _find_any_path(gsetpp,origid,destid,gep->vertex,depth+1);
+ if (res < 0)
+ return res;
+ if (res > 0) {
+ /* found somewhere below this one, insert ourselves and return */
+ bzero(&tup,sizeof (GRAPH_TUPLE));
+ tup.origid = origid;
+ tup.destid = destid;
+ tup.weight = gep->weight;
+ tup.seq = depth;
+ tup.linkid = gvp->id;
+ return (_add_graph_set(gsetpp,&tup) ? 1 : -1);
+ }
+ }
+
+ /* nothing found but no error */
+ return 0;
+}
+
+
+/*
+ query graphstore
+ latch specifies what operation to perform
+
+ we need to feed the conditions in... (through engine condition pushdown)
+ for now we just presume one condition per field so we just feed in a tuple
+ this also means we can just find constants, not ranges
+
+ return ptr to GRAPH_SET
+ caller must free with free_graph_set()
+*/
+GRAPH_SET *graphstore_query (GRAPHSTORE *gsp, GRAPH_TUPLE *gtp)
+{
+ GRAPH_SET *gsetp = NULL;
+ GRAPH_SET *gsetcurp;
+ GRAPH_SET *newgsetp;
+
+ if (gsp == NULL || gtp == NULL)
+ return (NULL);
+
+ switch (gtp->latch) {
+ case 0: /* return all vertices/edges */
+ {
+ GRAPHSTORE *gscurp;
+ GRAPH_EDGE *gep;
+ GRAPH_TUPLE tup;
+
+ /* walk through all vertices */
+ for (gscurp = gsp; gscurp != NULL; gscurp = gscurp->next) {
+ /* check for condition */
+ if (gtp->origid && gscurp->vertex->id != gtp->origid)
+ continue;
+
+ bzero(&tup,sizeof (GRAPH_TUPLE));
+ tup.origid = gscurp->vertex->id;
+
+ /* no edges? */
+ if (gscurp->vertex->forward_edge == NULL) {
+ /* just add vertex to set */
+ if (!_add_graph_set(&gsetp,&tup)) {
+ if (gsetp != NULL) /* clean up */
+ my_free(gsetp,MYF(0));
+ return (NULL);
+ }
+ }
+ else {
+ /* walk through all edges */
+ for (gep = gscurp->vertex->forward_edge; gep; gep = gep->next_edge) {
+ tup.destid = gep->vertex->id;
+ tup.weight = gep->weight;
+
+ /* just add vertex to set */
+ if (!_add_graph_set(&gsetp,&tup)) {
+ if (gsetp != NULL) /* clean up */
+ my_free(gsetp,MYF(0));
+ return (NULL);
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case 1: /* find a path between origid and destid */
+ /* yes it'll just go with the first path it finds! */
+ {
+ GRAPHSTORE *gscurp;
+ GRAPH_VERTEX *origvp;
+ GRAPH_TUPLE tup;
+
+ if (!gtp->origid || !gtp->destid)
+ return NULL;
+
+ /* find both vertices */
+ if ((origvp = _find_vertex(gsp,gtp->origid)) == NULL ||
+ _find_vertex(gsp,gtp->destid) == NULL)
+ return NULL;
+
+ if (_find_any_path(&gsetp,gtp->origid,gtp->destid,origvp,0) < 0) { /* error? */
+ if (gsetp != NULL) /* clean up */
+ my_free(gsetp,MYF(0));
+ return NULL;
+ }
+ }
+ break;
+
+ default:
+ /* this ends up being an empty set */
+ break;
+ }
+
+ /* Fix up latch column with the proper value - to be relationally correct */
+ for (gsetcurp = gsetp; gsetcurp != NULL; gsetcurp = gsetcurp->next)
+ gsetcurp->tuple.latch = gtp->latch;
+
+ return gsetp;
+}
+
+
+
+/* end of graphstore.c */
\ No newline at end of file
=== added file 'storage/oqgraph/graphstore.h'
--- a/storage/oqgraph/graphstore.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphstore.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,90 @@
+/*
+ * Graph Engine - Copyright (C) 2007 by Arjen Lentz (arjen(a)openquery.com.au)
+ * graphstore.h internal storage system
+ */
+//typedef unsigned short uint16;
+//typedef unsigned long long uint64;
+
+
+/*
+ This is essentially what a GRAPH engine table looks like on the MySQL end:
+ CREATE TABLE foo (
+ latch SMALLINT UNSIGNED NULL,
+ origid BIGINT UNSIGNED NULL,
+ destid BIGINT UNSIGNED NULL,
+ weight BIGINT UNSIGNED NULL,
+ seq BIGINT UNSIGNED NULL,
+ linkid BIGINT UNSIGNED NULL
+ ) ENGINE=OQGRAPH
+*/
+
+
+/*
+ We represent the above in C in the following way:
+*/
+typedef uint16 GRAPH_LATCH;
+typedef uint64 GRAPH_VERTEXID;
+typedef uint64 GRAPH_WEIGHT;
+typedef uint64 GRAPH_SEQ;
+
+typedef struct graph_tuple {
+ GRAPH_LATCH latch; /* function */
+ GRAPH_VERTEXID origid; /* vertex (should be != 0) */
+ GRAPH_VERTEXID destid; /* edge */
+ GRAPH_WEIGHT weight; /* weight */
+ GRAPH_SEQ seq; /* seq# within (origid) */
+ GRAPH_VERTEXID linkid; /* current step between origid/destid */
+} GRAPH_TUPLE;
+
+typedef struct graph_set {
+ GRAPH_TUPLE tuple;
+ struct graph_set *next;
+} GRAPH_SET;
+
+
+/*
+ Internally, sets look nothing like the above
+
+ - We have vertices, connected by edges.
+ - Each vertex' edges are maintained in a linked list.
+ - Edges can be weighted.
+
+ There are some issues with this structure, it'd be a pest to do a delete
+ So for now, let's just not support deletes!
+*/
+/* the below is half-gross and will likely change */
+typedef struct graph_edge {
+ struct graph_vertex {
+ GRAPH_VERTEXID id;
+ struct graph_edge *forward_edge;
+ } *vertex;
+ GRAPH_WEIGHT weight;
+ struct graph_edge *next_edge;
+} GRAPH_EDGE;
+
+typedef struct graph_vertex GRAPH_VERTEX;
+
+
+/*
+ A rough internal storage system for a set
+*/
+/* this below is fully gross and will definitely change */
+typedef struct graphstore {
+ GRAPH_VERTEX *vertex; /* changed to ptr when integrating into MySQL */
+ struct graphstore *next;
+} GRAPHSTORE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* public function declarations */
+int graphstore_insert (GRAPHSTORE **gspp, GRAPH_TUPLE *gtp);
+GRAPH_SET *graphstore_query (GRAPHSTORE *gsp, GRAPH_TUPLE *gtp);
+int free_graph_set (GRAPH_SET *gsetp);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* end of graphstore.h */
\ No newline at end of file
=== added file 'storage/oqgraph/ha_oqgraph.cc'
--- a/storage/oqgraph/ha_oqgraph.cc 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/ha_oqgraph.cc 2010-01-04 13:32:42 +0000
@@ -0,0 +1,1040 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+ Portions of this file copyright (C) 2000-2006 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation // gcc: Class implementation
+#endif
+
+#define MYSQL_SERVER // to have THD
+#include "mysql_priv.h"
+#if MYSQL_VERSION_ID >= 50100
+#include <mysql/plugin.h>
+#endif
+
+#ifdef HAVE_OQGRAPH
+
+#include "ha_oqgraph.h"
+#include "graphcore.h"
+
+#define OQGRAPH_STATS_UPDATE_THRESHOLD 10
+
+using namespace open_query;
+
+
+struct oqgraph_info_st
+{
+ THR_LOCK lock;
+ oqgraph_share *graph;
+ uint use_count;
+ uint key_stat_version;
+ uint records;
+ bool dropped;
+ char name[FN_REFLEN+1];
+};
+
+static const char oqgraph_description[]=
+ "Open Query Graph Computation Engine, stored in memory "
+ "(http://openquery.com/graph)";
+
+#if MYSQL_VERSION_ID < 50100
+static bool oqgraph_init();
+
+handlerton oqgraph_hton= {
+ "OQGRAPH",
+ SHOW_OPTION_YES,
+ oqgraph_description,
+ DB_TYPE_OQGRAPH,
+ oqgraph_init,
+ 0, /* slot */
+ 0, /* savepoint size. */
+ NULL, /* close_connection */
+ NULL, /* savepoint */
+ NULL, /* rollback to savepoint */
+ NULL, /* release savepoint */
+ NULL, /* commit */
+ NULL, /* rollback */
+ NULL, /* prepare */
+ NULL, /* recover */
+ NULL, /* commit_by_xid */
+ NULL, /* rollback_by_xid */
+ NULL, /* create_cursor_read_view */
+ NULL, /* set_cursor_read_view */
+ NULL, /* close_cursor_read_view */
+ HTON_NO_FLAGS
+};
+
+#define STATISTIC_INCREMENT(X) \
+statistic_increment(table->in_use->status_var.X, &LOCK_status)
+#define MOVE(X) move_field(X)
+#define RECORDS records
+#else
+#define STATISTIC_INCREMENT(X) ha_statistic_increment(&SSV::X)
+#define MOVE(X) move_field_offset(X)
+#define RECORDS stats.records
+#endif
+
+static HASH oqgraph_open_tables;
+static pthread_mutex_t LOCK_oqgraph;
+static bool oqgraph_init_done= 0;
+
+#if MYSQL_VERSION_ID >= 50130
+#define HASH_KEY_LENGTH size_t
+#else
+#define HASH_KEY_LENGTH uint
+#endif
+
+static uchar* get_key(const uchar *ptr, HASH_KEY_LENGTH *length,
+ my_bool)
+{
+ const OQGRAPH_INFO *share= (const OQGRAPH_INFO*) ptr;
+ *length= strlen(share->name);
+ return (uchar*) share->name;
+}
+
+#if MYSQL_VERSION_ID >= 50100
+static handler* oqgraph_create_handler(handlerton *hton, TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
+{
+ return new (mem_root) ha_oqgraph(hton, table);
+}
+
+static int oqgraph_init(handlerton *hton)
+{
+#else
+static bool oqgraph_init()
+{
+ if (have_oqgraph == SHOW_OPTION_DISABLED)
+ return 1;
+#endif
+ if (pthread_mutex_init(&LOCK_oqgraph, MY_MUTEX_INIT_FAST))
+ goto error;
+ if (hash_init(&oqgraph_open_tables, &my_charset_bin, 32, 0, 0,
+ get_key, 0, 0))
+ {
+ pthread_mutex_destroy(&LOCK_oqgraph);
+ goto error;
+ }
+#if MYSQL_VERSION_ID >= 50100
+ hton->state= SHOW_OPTION_YES;
+ hton->db_type= DB_TYPE_AUTOASSIGN;
+ hton->create= oqgraph_create_handler;
+ hton->flags= HTON_NO_FLAGS;
+#endif
+ oqgraph_init_done= TRUE;
+ return 0;
+error:
+#if MYSQL_VERSION_ID < 50100
+ have_oqgraph= SHOW_OPTION_DISABLED;
+#endif
+ return 1;
+}
+
+#if MYSQL_VERSION_ID >= 50100
+static int oqgraph_fini(void *)
+{
+ hash_free(&oqgraph_open_tables);
+ pthread_mutex_destroy(&LOCK_oqgraph);
+ oqgraph_init_done= FALSE;
+ return 0;
+}
+#endif
+
+static OQGRAPH_INFO *get_share(const char *name, TABLE *table=0)
+{
+ OQGRAPH_INFO *share;
+ uint length= strlen(name);
+
+ safe_mutex_assert_owner(&LOCK_oqgraph);
+ if (!(share= (OQGRAPH_INFO*) hash_search(&oqgraph_open_tables,
+ (byte*) name, length)))
+ {
+ if (!table ||
+ !(share= new OQGRAPH_INFO))
+ return 0;
+ share->use_count= share->key_stat_version= share->records= 0;
+ share->dropped= 0;
+ strmov(share->name, name);
+ if (!(share->graph= oqgraph::create()))
+ {
+ delete share;
+ return 0;
+ }
+ if (my_hash_insert(&oqgraph_open_tables, (byte*) share))
+ {
+ oqgraph::free(share->graph);
+ delete share;
+ return 0;
+ }
+ thr_lock_init(&share->lock);
+ }
+ share->use_count++;
+ return share;
+}
+
+static int free_share(OQGRAPH_INFO *share, bool drop=0)
+{
+ safe_mutex_assert_owner(&LOCK_oqgraph);
+ if (!share)
+ return 0;
+ if (drop)
+ {
+ share->dropped= true;
+ hash_delete(&oqgraph_open_tables, (byte*) share);
+ }
+ if (!--share->use_count)
+ {
+ if (share->dropped)
+ {
+ thr_lock_delete(&share->lock);
+ oqgraph::free(share->graph);
+ delete share;
+ }
+ }
+ return 0;
+}
+
+static int error_code(int res)
+{
+ switch (res)
+ {
+ case oqgraph::OK:
+ return 0;
+ case oqgraph::NO_MORE_DATA:
+ return HA_ERR_END_OF_FILE;
+ case oqgraph::EDGE_NOT_FOUND:
+ return HA_ERR_KEY_NOT_FOUND;
+ case oqgraph::INVALID_WEIGHT:
+ return HA_ERR_AUTOINC_ERANGE;
+ case oqgraph::DUPLICATE_EDGE:
+ return HA_ERR_FOUND_DUPP_KEY;
+ case oqgraph::CANNOT_ADD_VERTEX:
+ case oqgraph::CANNOT_ADD_EDGE:
+ return HA_ERR_RECORD_FILE_FULL;
+ case oqgraph::MISC_FAIL:
+ default:
+ return HA_ERR_CRASHED_ON_USAGE;
+ }
+}
+
+/**
+ * Check if table complies with our designated structure
+ *
+ * ColName Type Attributes
+ * ======= ======== =============
+ * latch SMALLINT UNSIGNED NULL
+ * origid BIGINT UNSIGNED NULL
+ * destid BIGINT UNSIGNED NULL
+ * weight DOUBLE NULL
+ * seq BIGINT UNSIGNED NULL
+ * linkid BIGINT UNSIGNED NULL
+ * =================================
+ *
+ CREATE TABLE foo (
+ latch SMALLINT UNSIGNED NULL,
+ origid BIGINT UNSIGNED NULL,
+ destid BIGINT UNSIGNED NULL,
+ weight DOUBLE NULL,
+ seq BIGINT UNSIGNED NULL,
+ linkid BIGINT UNSIGNED NULL,
+ KEY (latch, origid, destid) USING HASH,
+ KEY (latch, destid, origid) USING HASH
+ ) ENGINE=OQGRAPH
+
+ */
+static int oqgraph_check_table_structure (TABLE *table_arg)
+{
+ int i;
+ struct { const char *colname; int coltype; } skel[] = {
+ { "latch" , MYSQL_TYPE_SHORT },
+ { "origid", MYSQL_TYPE_LONGLONG },
+ { "destid", MYSQL_TYPE_LONGLONG },
+ { "weight", MYSQL_TYPE_DOUBLE },
+ { "seq" , MYSQL_TYPE_LONGLONG },
+ { "linkid", MYSQL_TYPE_LONGLONG },
+ { NULL , 0}
+ };
+
+ DBUG_ENTER("ha_oqgraph::table_structure_ok");
+
+ Field **field= table_arg->field;
+ for (i= 0; *field && skel[i].colname; i++, field++) {
+ /* Check Column Type */
+ if ((*field)->type() != skel[i].coltype)
+ DBUG_RETURN(-1);
+ if (skel[i].coltype != MYSQL_TYPE_DOUBLE) {
+ /* Check Is UNSIGNED */
+ if (!((*field)->flags & UNSIGNED_FLAG ))
+ DBUG_RETURN(-1);
+ }
+ /* Check THAT NOT NULL isn't set */
+ if ((*field)->flags & NOT_NULL_FLAG)
+ DBUG_RETURN(-1);
+ /* Check the column name */
+ if (strcmp(skel[i].colname,(*field)->field_name))
+ DBUG_RETURN(-1);
+ }
+
+ if (skel[i].colname || *field || !table_arg->key_info || !table_arg->s->keys)
+ DBUG_RETURN(-1);
+
+ KEY *key= table_arg->key_info;
+ for (uint i= 0; i < table_arg->s->keys; ++i, ++key)
+ {
+ Field **field= table_arg->field;
+ /* check that the first key part is the latch and it is a hash key */
+ if (!(field[0] == key->key_part[0].field &&
+ HA_KEY_ALG_HASH == key->algorithm))
+ DBUG_RETURN(-1);
+ if (key->key_parts == 3)
+ {
+ /* KEY (latch, origid, destid) USING HASH */
+ /* KEY (latch, destid, origid) USING HASH */
+ if (!(field[1] == key->key_part[1].field &&
+ field[2] == key->key_part[2].field) &&
+ !(field[1] == key->key_part[2].field &&
+ field[2] == key->key_part[1].field))
+ DBUG_RETURN(-1);
+ }
+ else
+ DBUG_RETURN(-1);
+ }
+
+ DBUG_RETURN(0);
+}
+
+/*****************************************************************************
+** OQGRAPH tables
+*****************************************************************************/
+
+#if MYSQL_VERSION_ID >= 50100
+ha_oqgraph::ha_oqgraph(handlerton *hton, TABLE_SHARE *table_arg)
+ : handler(hton, table_arg),
+#else
+ha_oqgraph::ha_oqgraph(TABLE *table_arg)
+ : handler(&oqgraph_hton, table_arg),
+#endif
+ share(0), graph(0), records_changed(0), key_stat_version(0)
+{ }
+
+
+static const char *ha_oqgraph_exts[] =
+{
+ NullS
+};
+
+const char **ha_oqgraph::bas_ext() const
+{
+ return ha_oqgraph_exts;
+}
+
+#if MYSQL_VERSION_ID >= 50100
+ulonglong ha_oqgraph::table_flags() const
+#else
+ulong ha_oqgraph::table_flags() const
+#endif
+{
+ return (HA_NO_BLOBS | HA_NULL_IN_KEY |
+ HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED);
+}
+
+ulong ha_oqgraph::index_flags(uint inx, uint part, bool all_parts) const
+{
+ return HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR;
+}
+
+int ha_oqgraph::open(const char *name, int mode, uint test_if_locked)
+{
+ pthread_mutex_lock(&LOCK_oqgraph);
+ if ((share = get_share(name, table)))
+ {
+ ref_length= oqgraph::sizeof_ref;
+ }
+
+ if (share)
+ {
+ /* Initialize variables for the opened table */
+ thr_lock_data_init(&share->lock, &lock, NULL);
+
+ graph= oqgraph::create(share->graph);
+
+ /*
+ We cannot run update_key_stats() here because we do not have a
+ lock on the table. The 'records' count might just be changed
+ temporarily at this moment and we might get wrong statistics (Bug
+ #10178). Instead we request for update. This will be done in
+ ha_oqgraph::info(), which is always called before key statistics are
+ used.
+ */
+ key_stat_version= share->key_stat_version-1;
+ }
+ pthread_mutex_unlock(&LOCK_oqgraph);
+
+ return (share ? 0 : 1);
+}
+
+int ha_oqgraph::close(void)
+{
+ pthread_mutex_lock(&LOCK_oqgraph);
+ oqgraph::free(graph); graph= 0;
+ int res= free_share(share);
+ pthread_mutex_unlock(&LOCK_oqgraph);
+ return error_code(res);
+}
+
+void ha_oqgraph::update_key_stats()
+{
+ for (uint i= 0; i < table->s->keys; i++)
+ {
+ KEY *key=table->key_info+i;
+ if (!key->rec_per_key)
+ continue;
+ if (key->algorithm != HA_KEY_ALG_BTREE)
+ {
+ if (key->flags & HA_NOSAME)
+ key->rec_per_key[key->key_parts-1]= 1;
+ else
+ {
+ unsigned vertices= graph->vertices_count();
+ unsigned edges= graph->edges_count();
+ uint no_records= vertices ? 2 * (edges + vertices) / vertices : 2;
+ if (no_records < 2)
+ no_records= 2;
+ key->rec_per_key[key->key_parts-1]= no_records;
+ }
+ }
+ }
+ records_changed= 0;
+ /* At the end of update_key_stats() we can proudly claim they are OK. */
+ key_stat_version= share->key_stat_version;
+}
+
+
+int ha_oqgraph::write_row(byte * buf)
+{
+ int res= oqgraph::MISC_FAIL;
+ Field ** const field= table->field;
+ STATISTIC_INCREMENT(ha_write_count);
+
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+#endif
+ my_ptrdiff_t ptrdiff= buf - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ field[3]->MOVE(ptrdiff);
+ }
+
+ if (!field[1]->is_null() && !field[2]->is_null())
+ {
+ VertexID orig_id= (VertexID) field[1]->val_int();
+ VertexID dest_id= (VertexID) field[2]->val_int();
+ EdgeWeight weight= 1;
+
+ if (!field[3]->is_null())
+ weight= (EdgeWeight) field[3]->val_real();
+
+ if (!(res= graph->insert_edge(orig_id, dest_id, weight, replace_dups)))
+ {
+ ++records_changed;
+ share->records++;
+ }
+ if (res == oqgraph::DUPLICATE_EDGE && ignore_dups && !insert_dups)
+ res= oqgraph::OK;
+ }
+
+ if (ptrdiff)
+ {
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ field[3]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+#endif
+
+ if (!res && records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records)
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ share->key_stat_version++;
+ }
+
+ return error_code(res);
+}
+
+int ha_oqgraph::update_row(const byte * old, byte * buf)
+{
+ int res= oqgraph::MISC_FAIL;
+ VertexID orig_id, dest_id;
+ EdgeWeight weight= 1;
+ Field **field= table->field;
+ STATISTIC_INCREMENT(ha_update_count);
+
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+#endif
+ my_ptrdiff_t ptrdiff= buf - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(ptrdiff);
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ field[3]->MOVE(ptrdiff);
+ }
+
+ if (inited == INDEX || inited == RND)
+ {
+ VertexID *origp= 0, *destp= 0;
+ EdgeWeight *weightp= 0;
+ if (!field[1]->is_null())
+ *(origp= &orig_id)= (VertexID) field[1]->val_int();
+ if (!field[2]->is_null())
+ *(destp= &dest_id)= (VertexID) field[2]->val_int();
+ if (!field[3]->is_null())
+ *(weightp= &weight)= (EdgeWeight) field[3]->val_real();
+
+ my_ptrdiff_t ptrdiff2= old - buf;
+
+ field[0]->MOVE(ptrdiff2);
+ field[1]->MOVE(ptrdiff2);
+ field[2]->MOVE(ptrdiff2);
+ field[3]->MOVE(ptrdiff2);
+
+ if (field[0]->is_null())
+ {
+ if (!origp == field[1]->is_null() &&
+ *origp == (VertexID) field[1]->val_int())
+ origp= 0;
+ if (!destp == field[2]->is_null() &&
+ *destp == (VertexID) field[2]->val_int())
+ origp= 0;
+ if (!weightp == field[3]->is_null() &&
+ *weightp == (VertexID) field[3]->val_real())
+ weightp= 0;
+
+ if (!(res= graph->modify_edge(oqgraph::current_row(),
+ origp, destp, weightp, replace_dups)))
+ ++records_changed;
+ else if (ignore_dups && res == oqgraph::DUPLICATE_EDGE)
+ res= oqgraph::OK;
+ }
+
+ field[0]->MOVE(-ptrdiff2);
+ field[1]->MOVE(-ptrdiff2);
+ field[2]->MOVE(-ptrdiff2);
+ field[3]->MOVE(-ptrdiff2);
+ }
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(-ptrdiff);
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ field[3]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+#endif
+
+ if (!res && records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records)
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ share->key_stat_version++;
+ }
+ return error_code(res);
+}
+
+int ha_oqgraph::delete_row(const byte * buf)
+{
+ int res= oqgraph::EDGE_NOT_FOUND;
+ Field **field= table->field;
+ STATISTIC_INCREMENT(ha_delete_count);
+
+ if (inited == INDEX || inited == RND)
+ {
+ if ((res= graph->delete_edge(oqgraph::current_row())) == oqgraph::OK)
+ {
+ ++records_changed;
+ share->records--;
+ }
+ }
+ if (res != oqgraph::OK)
+ {
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+#endif
+ my_ptrdiff_t ptrdiff= buf - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(ptrdiff);
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ }
+
+ if (field[0]->is_null() && !field[1]->is_null() && !field[2]->is_null())
+ {
+ VertexID orig_id= (VertexID) field[1]->val_int();
+ VertexID dest_id= (VertexID) field[2]->val_int();
+
+ if ((res= graph->delete_edge(orig_id, dest_id)) == oqgraph::OK)
+ {
+ ++records_changed;
+ share->records--;
+ }
+ }
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(-ptrdiff);
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+#endif
+ }
+
+ if (!res && table->s->tmp_table == NO_TMP_TABLE &&
+ records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records)
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ share->key_stat_version++;
+ }
+ return error_code(res);
+}
+
+int ha_oqgraph::index_read(byte * buf, const byte * key, uint key_len,
+ enum ha_rkey_function find_flag)
+{
+ DBUG_ASSERT(inited==INDEX);
+ return index_read_idx(buf, active_index, key, key_len, find_flag);
+}
+
+int ha_oqgraph::index_next_same(byte *buf, const byte *key, uint key_len)
+{
+ int res;
+ open_query::row row;
+ DBUG_ASSERT(inited==INDEX);
+ STATISTIC_INCREMENT(ha_read_key_count);
+ if (!(res= graph->fetch_row(row)))
+ res= fill_record(buf, row);
+ table->status= res ? STATUS_NOT_FOUND : 0;
+ return error_code(res);
+}
+
+int ha_oqgraph::index_read_idx(byte * buf, uint index, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag)
+{
+ Field **field= table->field;
+ KEY *key_info= table->key_info + index;
+ int res;
+ VertexID orig_id, dest_id;
+ int latch;
+ VertexID *orig_idp=0, *dest_idp=0;
+ int *latchp=0;
+ open_query::row row;
+ STATISTIC_INCREMENT(ha_read_key_count);
+
+ bmove_align(buf, table->s->default_values, table->s->reclength);
+ key_restore(buf, (byte*) key, key_info, key_len);
+
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+#endif
+ my_ptrdiff_t ptrdiff= buf - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(ptrdiff);
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ }
+
+ if (!field[0]->is_null())
+ {
+ latch= (int) field[0]->val_int();
+ latchp= &latch;
+ }
+
+ if (!field[1]->is_null())
+ {
+ orig_id= (VertexID) field[1]->val_int();
+ orig_idp= &orig_id;
+ }
+
+ if (!field[2]->is_null())
+ {
+ dest_id= (VertexID) field[2]->val_int();
+ dest_idp= &dest_id;
+ }
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(-ptrdiff);
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+#endif
+
+ res= graph->search(latchp, orig_idp, dest_idp);
+
+ if (!res && !(res= graph->fetch_row(row)))
+ res= fill_record(buf, row);
+ table->status = res ? STATUS_NOT_FOUND : 0;
+ return error_code(res);
+}
+
+int ha_oqgraph::fill_record(byte *record, const open_query::row &row)
+{
+ Field **field= table->field;
+
+ bmove_align(record, table->s->default_values, table->s->reclength);
+
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
+#endif
+ my_ptrdiff_t ptrdiff= record - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(ptrdiff);
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ field[3]->MOVE(ptrdiff);
+ field[4]->MOVE(ptrdiff);
+ field[5]->MOVE(ptrdiff);
+ }
+
+ // just each field specifically, no sense iterating
+ if (row.latch_indicator)
+ {
+ field[0]->set_notnull();
+ field[0]->store((longlong) row.latch);
+ }
+
+ if (row.orig_indicator)
+ {
+ field[1]->set_notnull();
+ field[1]->store((longlong) row.orig);
+ }
+
+ if (row.dest_indicator)
+ {
+ field[2]->set_notnull();
+ field[2]->store((longlong) row.dest);
+ }
+
+ if (row.weight_indicator)
+ {
+ field[3]->set_notnull();
+ field[3]->store((double) row.weight);
+ }
+
+ if (row.seq_indicator)
+ {
+ field[4]->set_notnull();
+ field[4]->store((longlong) row.seq);
+ }
+
+ if (row.link_indicator)
+ {
+ field[5]->set_notnull();
+ field[5]->store((longlong) row.link);
+ }
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(-ptrdiff);
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ field[3]->MOVE(-ptrdiff);
+ field[4]->MOVE(-ptrdiff);
+ field[5]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->write_set, old_map);
+#endif
+
+ return 0;
+}
+
+int ha_oqgraph::rnd_init(bool scan)
+{
+ return error_code(graph->random(scan));
+}
+
+int ha_oqgraph::rnd_next(byte *buf)
+{
+ int res;
+ open_query::row row;
+ STATISTIC_INCREMENT(ha_read_rnd_next_count);
+ if (!(res= graph->fetch_row(row)))
+ res= fill_record(buf, row);
+ table->status= res ? STATUS_NOT_FOUND: 0;
+ return error_code(res);
+}
+
+int ha_oqgraph::rnd_pos(byte * buf, byte *pos)
+{
+ int res;
+ open_query::row row;
+ STATISTIC_INCREMENT(ha_read_rnd_count);
+ if (!(res= graph->fetch_row(row, pos)))
+ res= fill_record(buf, row);
+ table->status=res ? STATUS_NOT_FOUND: 0;
+ return error_code(res);
+}
+
+void ha_oqgraph::position(const byte *record)
+{
+ graph->row_ref((void*) ref); // Ref is aligned
+}
+
+int ha_oqgraph::cmp_ref(const byte *ref1, const byte *ref2)
+{
+ return memcmp(ref1, ref2, oqgraph::sizeof_ref);
+}
+
+int ha_oqgraph::info(uint flag)
+{
+ RECORDS= graph->vertices_count() + graph->edges_count();
+#if 0
+ records= hp_info.records;
+ deleted= hp_info.deleted;
+ errkey= hp_info.errkey;
+ mean_rec_length= hp_info.reclength;
+ data_file_length= hp_info.data_length;
+ index_file_length= hp_info.index_length;
+ max_data_file_length= hp_info.max_records* hp_info.reclength;
+ delete_length= hp_info.deleted * hp_info.reclength;
+#endif
+ /*
+ If info() is called for the first time after open(), we will still
+ have to update the key statistics. Hoping that a table lock is now
+ in place.
+ */
+ if (key_stat_version != share->key_stat_version)
+ update_key_stats();
+ return 0;
+}
+
+int ha_oqgraph::extra(enum ha_extra_function operation)
+{
+ switch (operation)
+ {
+ case HA_EXTRA_IGNORE_DUP_KEY:
+ ignore_dups= true;
+ break;
+ case HA_EXTRA_NO_IGNORE_DUP_KEY:
+ ignore_dups= false;
+ insert_dups= false;
+ break;
+ case HA_EXTRA_WRITE_CAN_REPLACE:
+ replace_dups= true;
+ break;
+ case HA_EXTRA_WRITE_CANNOT_REPLACE:
+ replace_dups= false;
+ break;
+ case HA_EXTRA_INSERT_WITH_UPDATE:
+ insert_dups= true;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int ha_oqgraph::delete_all_rows()
+{
+ int res;
+ if (!(res= graph->delete_all()))
+ {
+ share->records= 0;
+ }
+
+ if (!res && table->s->tmp_table == NO_TMP_TABLE)
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ share->key_stat_version++;
+ }
+ return error_code(res);
+}
+
+int ha_oqgraph::external_lock(THD *thd, int lock_type)
+{
+ return 0; // No external locking
+}
+
+
+THR_LOCK_DATA **ha_oqgraph::store_lock(THD *thd,
+ THR_LOCK_DATA **to,
+ enum thr_lock_type lock_type)
+{
+ if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
+ lock.type=lock_type;
+ *to++= &lock;
+ return to;
+}
+
+/*
+ We have to ignore ENOENT entries as the HEAP table is created on open and
+ not when doing a CREATE on the table.
+*/
+
+int ha_oqgraph::delete_table(const char *name)
+{
+ int res= 0;
+ OQGRAPH_INFO *share;
+ pthread_mutex_lock(&LOCK_oqgraph);
+ if ((share= get_share(name)))
+ {
+ res= free_share(share, true);
+ }
+ pthread_mutex_unlock(&LOCK_oqgraph);
+ return error_code(res);
+}
+
+int ha_oqgraph::rename_table(const char * from, const char * to)
+{
+ pthread_mutex_lock(&LOCK_oqgraph);
+ if (OQGRAPH_INFO *share= get_share(from))
+ {
+ strmov(share->name, to);
+ hash_update(&oqgraph_open_tables, (byte*) share,
+ (byte*) from, strlen(from));
+ }
+ pthread_mutex_unlock(&LOCK_oqgraph);
+ return 0;
+}
+
+
+ha_rows ha_oqgraph::records_in_range(uint inx, key_range *min_key,
+ key_range *max_key)
+{
+ KEY *key=table->key_info+inx;
+ //if (key->algorithm == HA_KEY_ALG_BTREE)
+ // return btree_records_in_range(file, inx, min_key, max_key);
+
+ if (!min_key || !max_key ||
+ min_key->length != max_key->length ||
+ min_key->length < key->key_length - key->key_part[2].store_length ||
+ min_key->flag != HA_READ_KEY_EXACT ||
+ max_key->flag != HA_READ_AFTER_KEY)
+ {
+ if (min_key->length == key->key_part[0].store_length)
+ {
+ // If latch is not null and equals 0, return # nodes
+ DBUG_ASSERT(key->key_part[0].store_length == 3);
+ if (key->key_part[0].null_bit && !min_key->key[0] &&
+ !min_key->key[1] && !min_key->key[2])
+ return graph->vertices_count();
+ }
+ return HA_POS_ERROR; // Can only use exact keys
+ }
+
+ if (RECORDS <= 1)
+ return RECORDS;
+
+ /* Assert that info() did run. We need current statistics here. */
+ DBUG_ASSERT(key_stat_version == share->key_stat_version);
+ ha_rows result= key->rec_per_key[key->key_parts-1];
+
+ return result;
+}
+
+
+int ha_oqgraph::create(const char *name, TABLE *table_arg,
+ HA_CREATE_INFO *create_info)
+{
+ int res = -1;
+ OQGRAPH_INFO *share;
+
+ pthread_mutex_lock(&LOCK_oqgraph);
+ if ((share= get_share(name)))
+ {
+ free_share(share);
+ }
+ else
+ {
+ if (!oqgraph_check_table_structure(table_arg))
+ res= 0;;
+ }
+ pthread_mutex_unlock(&LOCK_oqgraph);
+
+ if (this->share)
+ info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ return error_code(res);
+}
+
+
+void ha_oqgraph::update_create_info(HA_CREATE_INFO *create_info)
+{
+ table->file->info(HA_STATUS_AUTO);
+ //if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
+ // create_info->auto_increment_value= auto_increment_value;
+}
+
+#if MYSQL_VERSION_ID >= 50100
+struct st_mysql_storage_engine oqgraph_storage_engine=
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+
+mysql_declare_plugin(oqgraph)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &oqgraph_storage_engine,
+ "OQGRAPH",
+ "Arjen Lentz & Antony T Curtis, Open Query",
+ oqgraph_description,
+ PLUGIN_LICENSE_GPL,
+ (int (*)(void*)) oqgraph_init, /* Plugin Init */
+ oqgraph_fini, /* Plugin Deinit */
+ 0x0200, /* Version: 2.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+}
+mysql_declare_plugin_end;
+#endif
+
+#endif
=== added file 'storage/oqgraph/ha_oqgraph.h'
--- a/storage/oqgraph/ha_oqgraph.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/ha_oqgraph.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,114 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+ Portions of this file copyright (C) 2000-2006 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface /* gcc class implementation */
+#endif
+
+
+typedef struct oqgraph_info_st OQGRAPH_INFO;
+
+#if MYSQL_VERSION_ID >= 50120
+typedef uchar byte;
+#endif
+
+namespace open_query
+{
+ struct row;
+ class oqgraph;
+}
+
+/* class for the the Open Query Graph handler */
+
+class ha_oqgraph: public handler
+{
+ OQGRAPH_INFO *share;
+ open_query::oqgraph *graph;
+ THR_LOCK_DATA lock;
+ /* number of records changed since last statistics update */
+ uint records_changed;
+ uint key_stat_version;
+ bool replace_dups, ignore_dups, insert_dups;
+
+ int fill_record(byte*, const open_query::row&);
+
+public:
+#if MYSQL_VERSION_ID >= 50100
+ ha_oqgraph(handlerton *hton, TABLE_SHARE *table);
+ ulonglong table_flags() const;
+#else
+ ha_oqgraph(TABLE *table);
+ ulong table_flags() const;
+#endif
+ ~ha_oqgraph() {}
+ const char *table_type() const
+ {
+ return "OQGRAPH";
+ }
+ const char *index_type(uint inx)
+ {
+ return "HASH";
+ }
+ /* Rows also use a fixed-size format */
+ enum row_type get_row_type() const { return ROW_TYPE_FIXED; }
+ const char **bas_ext() const;
+ ulong index_flags(uint inx, uint part, bool all_parts) const;
+ uint max_supported_keys() const { return MAX_KEY; }
+ uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
+ double scan_time() { return (double) 1000000000; }
+ double read_time(uint index, uint ranges, ha_rows rows)
+ { return 1; }
+
+ int open(const char *name, int mode, uint test_if_locked);
+ int close(void);
+ int write_row(byte * buf);
+ int update_row(const byte * old_data, byte * new_data);
+ int delete_row(const byte * buf);
+ int index_read(byte * buf, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag);
+ int index_read_idx(byte * buf, uint idx, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag);
+ int index_next_same(byte * buf, const byte * key, uint key_len);
+ int rnd_init(bool scan);
+ int rnd_next(byte *buf);
+ int rnd_pos(byte * buf, byte *pos);
+ void position(const byte *record);
+ int info(uint);
+ int extra(enum ha_extra_function operation);
+ int external_lock(THD *thd, int lock_type);
+ int delete_all_rows(void);
+ ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
+ int delete_table(const char *from);
+ int rename_table(const char * from, const char * to);
+ int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
+ void update_create_info(HA_CREATE_INFO *create_info);
+
+ THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
+ enum thr_lock_type lock_type);
+ int cmp_ref(const byte *ref1, const byte *ref2);
+private:
+ void update_key_stats();
+};
=== added file 'storage/oqgraph/oqgraph_config.h.in'
--- a/storage/oqgraph/oqgraph_config.h.in 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/oqgraph_config.h.in 2010-01-04 08:27:50 +0000
@@ -0,0 +1,73 @@
+/* src/oqgraph_config.h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Enables DTRACE Support */
+#undef HAVE_DTRACE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <syslimits.h> header file. */
+#undef HAVE_SYSLIMITS_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Source directory for MySQL */
+#undef MYSQL_SRC
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
=== added file 'storage/oqgraph/oqgraph_probes.d'
--- a/storage/oqgraph/oqgraph_probes.d 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/oqgraph_probes.d 2010-01-04 08:27:50 +0000
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004-2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+provider oqgraph {
+ probe open();
+ probe close();
+};
=== added file 'storage/oqgraph/plug.in'
--- a/storage/oqgraph/plug.in 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/plug.in 2010-03-30 07:33:38 +0000
@@ -0,0 +1,24 @@
+MYSQL_STORAGE_ENGINE(oqgraph,,[Graph Storage Engine],
+ [Open Query Graph Computation Engine], [])
+MYSQL_PLUGIN_DYNAMIC(oqgraph, [oqgraph_engine.la])
+MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(oqgraph, [ha_oqgraph.cc])
+AM_CONDITIONAL([BUILD_OQGRAPH_FOR_MYSQL], true)
+AM_CONDITIONAL([BUILD_OQGRAPH_STANDALONE], false)
+AM_CONDITIONAL([HAVE_DTRACE], false)
+
+AC_LANG_PUSH([C++])
+
+AC_MSG_CHECKING([for Boost usable by OQGraph engine])
+AC_PREPROC_IFELSE(
+ [
+#include <boost/version.hpp>
+#if BOOST_VERSION >= 104000
+#else
+#error oops
+#endif
+ ],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ with_plugin_oqgraph=no])
+
+AC_LANG_POP()
=== modified file 'storage/xtradb/include/page0page.h'
--- a/storage/xtradb/include/page0page.h 2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/page0page.h 2010-03-28 18:10:00 +0000
@@ -517,7 +517,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec); /*!< in: pointer to record */
+ const rec_t* rec); /*!< in: pointer to record */
/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
=== modified file 'storage/xtradb/include/page0page.ic'
--- a/storage/xtradb/include/page0page.ic 2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/page0page.ic 2010-03-28 18:10:00 +0000
@@ -731,7 +731,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec) /*!< in: pointer to record */
+ const rec_t* rec) /*!< in: pointer to record */
{
return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
}
=== modified file 'storage/xtradb/include/ut0lst.h'
--- a/storage/xtradb/include/ut0lst.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0lst.h 2010-03-30 12:36:49 +0000
@@ -158,7 +158,7 @@ Inserts a NODE2 after NODE1 in a list.
/** Invalidate the pointers in a list node.
@param NAME list name
@param N pointer to the node that was removed */
-# define UT_LIST_REMOVE_CLEAR(NAME, N) while (0)
+# define UT_LIST_REMOVE_CLEAR(NAME, N) {} while (0)
#endif
/*******************************************************************//**
=== modified file 'strings/ctype-ucs2.c'
--- a/strings/ctype-ucs2.c 2010-03-15 11:51:23 +0000
+++ b/strings/ctype-ucs2.c 2010-03-31 08:17:03 +0000
@@ -203,7 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@@ -317,7 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_I
const char *s, const char *t, size_t len)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const char *se=s+len;
const char *te=t+len;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@@ -1384,7 +1384,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
=== modified file 'strings/ctype-utf8.c'
--- a/strings/ctype-utf8.c 2010-01-06 19:20:16 +0000
+++ b/strings/ctype-utf8.c 2010-03-31 08:17:03 +0000
@@ -2308,7 +2308,7 @@ static int my_strnncoll_utf8(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc), t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
@@ -2378,7 +2378,7 @@ static int my_strnncollsp_utf8(CHARSET_I
my_bool diff_if_only_endspace_difference)
{
int s_res, t_res, res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se= s+slen, *te= t+tlen;
MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-03-10 10:32:14 +0000
+++ b/support-files/compiler_warnings.supp 2010-03-30 12:36:49 +0000
@@ -39,6 +39,7 @@ sync/sync0rw\.c: unused parameter
sync/sync0sync\.c: unused parameter
sync/sync0sync\.c: unused variable
ut/ut0ut\.c: ignoring return value of
+srv/srv0srv\.c: value computed is not used
#
# bdb is not critical to keep up to date
@@ -66,6 +67,16 @@ db_vrfy.c : .*comparison is always false
/usr/share/aclocal/audiofile.m4 : .*
#
+# Ignore strict-aliasing warnings (for now)
+#
+.*: break strict-aliasing rules
+
+#
+# Ignore not important declaration warnings
+#
+.*: only defines private constructors and has no friends
+
+#
# Ignore all conversion warnings on windows 64
# (Is safe as we are not yet supporting strings >= 2G)
#
@@ -100,6 +111,11 @@ db_vrfy.c : .*comparison is always false
storage/maria/ma_pagecache.c: .*'info_check_pin' defined but not used
#
+# Pbxt
+#
+xaction_xt\.cc: may be used uninitialized in this function
+
+#
# I think these are due to mix of C and C++.
#
storage/pbxt/ : typedef.*was ignored in this declaration
@@ -112,6 +128,7 @@ include/runtime.hpp: .*pure_error.*
.*/extra/yassl/taocrypt/src/blowfish\.cpp: array subscript is above array bounds
.*/extra/yassl/taocrypt/src/file\.cpp: ignoring return value
.*/extra/yassl/taocrypt/src/integer\.cpp: control reaches end of non-void function
+mySTL/algorithm\.hpp: is used uninitialized in this function
#
# Groff warnings on OpenSUSE.
@@ -123,18 +140,18 @@ include/runtime.hpp: .*pure_error.*
#
listener.cc : .*conversion from 'SOCKET' to 'int'.*
net_serv.cc : .*conversion from 'SOCKET' to 'int'.*
-set_var.cc: right-hand operand of comma has no effect : 1000-1400
-
# allow a little moving space for the warning below
-mi_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
-ma_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
+mi_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
+ma_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
#
# Wrong compiler warnings
#
.* : .*no matching operator delete found; memory will not be freed if initialization throws an exception.*
-ctype-simple.c : .*unary minus operator applied to unsigned type, result still unsigned.*
+ctype-simple\.c : .*unary minus operator applied to unsigned type, result still unsigned.*
# Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478
-regexec\.c : .*passing argument 3 of.*matcher.* discards qualifiers from pointer target type.*
+regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type
+libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000
+storage/xtradb/dict/dict0dict\.c: passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
=== modified file 'unittest/mysys/waiting_threads-t.c'
--- a/unittest/mysys/waiting_threads-t.c 2010-01-28 14:49:14 +0000
+++ b/unittest/mysys/waiting_threads-t.c 2010-03-30 12:36:49 +0000
@@ -258,7 +258,7 @@ void do_tests()
#define test_kill_strategy(X) \
diag("kill strategy: " #X); \
DBUG_EXECUTE("reset_file", \
- { rewind(DBUG_FILE); (void) ftruncate(fileno(DBUG_FILE), 0); }); \
+ { rewind(DBUG_FILE); my_chsize(fileno(DBUG_FILE), 0, 0, MYF(MY_WME)); }); \
DBUG_PRINT("info", ("kill strategy: " #X)); \
kill_strategy=X; \
do_one_test();
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2793)
by knielsen@knielsen-hq.org 31 Mar '10
by knielsen@knielsen-hq.org 31 Mar '10
31 Mar '10
#At lp:maria
2793 knielsen(a)knielsen-hq.org 2010-03-31
Fix compiler warnings
modified:
storage/oqgraph/graphcore.cc
=== modified file 'storage/oqgraph/graphcore.cc'
--- a/storage/oqgraph/graphcore.cc 2010-03-30 07:33:38 +0000
+++ b/storage/oqgraph/graphcore.cc 2010-03-31 07:54:07 +0000
@@ -1021,7 +1021,8 @@ int vertices_cursor::fetch_row(const row
vertex_iterator it, end;
reference ref;
size_t count= position;
- for (tie(it, end)= vertices(share->g); count && it != end; ++it, --count);
+ for (tie(it, end)= vertices(share->g); count && it != end; ++it, --count)
+ ;
if (it != end)
ref= reference(position+1, *it);
if (int res= fetch_row(row_info, result, ref))
@@ -1066,7 +1067,8 @@ int edges_cursor::fetch_row(const row &r
edge_iterator it, end;
reference ref;
size_t count= position;
- for (tie(it, end)= edges(share->g); count && it != end; ++it, --count);
+ for (tie(it, end)= edges(share->g); count && it != end; ++it, --count)
+ ;
if (it != end)
ref= reference(position+1, *it);
if (int res= fetch_row(row_info, result, ref))
1
0
Hi Arjen,
I wanted to see if there was something I could do to help getting
oqgraph-in-mariadb moving again.
As I understand it, the issues are the following:
1. Current OQGraph autoconf test enables OQGraph by default in the build if a
too old Boost is installed on the machine. This means that a plain
./configure && make will not work on such machines. (In other words, OQGraph
must not be enabled by default on machines where it does not compile).
2. OQGraph is affected by a bug in Boost, so it actually requires a patched
Boost (until some Boost version is released with the fix included).
3. Even if OQGraph is included properly into the MariaDB source tree, we still
need to set up package building so that it will actually be able to build and
include OQGraph.
So one possible solution for issue 3 is to include the patched boost headers
inside the storage/oqgraph/ directory. I remember that including all of boost
was infeasible due to the sheer size of the library. But you mentioned that
just the graph part of Boost would do. How big is this subset (number of files
/ number of lines?).
Another solution would be to create an ourdelta package of the patched boost
development headers. We could then make this a build dependency of mariadb
.debs. But not sure if this is too much work to set up (and not sure about how
this would work for .deb either).
A third solution could be to just install the patched boost in
/usr/local/include on the build VMs. This should work, though it's not 100%
nice in terms of providing full source code (you could always release OQGraph
as GPL with a boost linking exception if we're really paranoid).
A fourth solution could be to include the graph part of boost (with bug fix)
as a patch in ourdelta/bakery/, just like the other patches already
there.
For issue 1 + 2, if you can point me to what the bug in boost is I could look
into making an autoconf test for this bug, and only enable OQGraph by default
if a boost without the bug is found. Or failing that, if you can supply me
with the minimum version of boost needed, I could try for an autoconf test
that does not enable OQGraph by defaults on hosts where it breaks the build.
What do you think?
- Kristian.
2
4

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2803)
by knielsen@knielsen-hq.org 30 Mar '10
by knielsen@knielsen-hq.org 30 Mar '10
30 Mar '10
#At lp:maria
2803 knielsen(a)knielsen-hq.org 2010-03-30 [merge]
automerge for buildbot test
modified:
mysql-test/Makefile.am
=== modified file 'mysql-test/Makefile.am'
--- a/mysql-test/Makefile.am 2009-12-03 11:19:05 +0000
+++ b/mysql-test/Makefile.am 2010-03-30 19:00:59 +0000
@@ -102,7 +102,8 @@ TEST_DIRS = t r include std_data std_dat
suite/rpl_ndb suite/rpl_ndb/t suite/rpl_ndb/r \
suite/parts suite/parts/t suite/parts/r suite/parts/inc \
suite/pbxt/t suite/pbxt/r \
- suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include
+ suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \
+ suite/oqgraph suite/oqgraph/t suite/oqgraph/r suite/oqgraph/include
# Used by dist-hook and install-data-local to copy all
# test files into either dist or install directory
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2792)
by knielsen@knielsen-hq.org 30 Mar '10
by knielsen@knielsen-hq.org 30 Mar '10
30 Mar '10
#At lp:maria
2792 knielsen(a)knielsen-hq.org 2010-03-30
OQGraph testsuite was forgotten from `make dist`.
modified:
mysql-test/Makefile.am
=== modified file 'mysql-test/Makefile.am'
--- a/mysql-test/Makefile.am 2009-12-03 11:19:05 +0000
+++ b/mysql-test/Makefile.am 2010-03-30 19:00:59 +0000
@@ -102,7 +102,8 @@ TEST_DIRS = t r include std_data std_dat
suite/rpl_ndb suite/rpl_ndb/t suite/rpl_ndb/r \
suite/parts suite/parts/t suite/parts/r suite/parts/inc \
suite/pbxt/t suite/pbxt/r \
- suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include
+ suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \
+ suite/oqgraph suite/oqgraph/t suite/oqgraph/r suite/oqgraph/include
# Used by dist-hook and install-data-local to copy all
# test files into either dist or install directory
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2802)
by knielsen@knielsen-hq.org 30 Mar '10
by knielsen@knielsen-hq.org 30 Mar '10
30 Mar '10
#At lp:maria
2802 knielsen(a)knielsen-hq.org 2010-03-30 [merge]
automerge for buildbot test
removed:
storage/oqgraph/oqgraph_probes.h
modified:
storage/oqgraph/Makefile.am
=== modified file 'storage/oqgraph/Makefile.am'
--- a/storage/oqgraph/Makefile.am 2010-01-04 08:27:50 +0000
+++ b/storage/oqgraph/Makefile.am 2010-03-30 18:12:00 +0000
@@ -47,15 +47,15 @@ EXTRA_DIST = ha_oqgraph.h ha_oqgraph.cc
graphcore-graph.h graphcore-types.h graphcore.h \
CMakeFiles.txt plug.in oqgraph_probes.d
-DTRACE = @DTRACE@
-DTRACEFLAGS = @DTRACEFLAGS@
-DTRACEFILES = .libs/liboqgraph_engine_la-ha_oqgraph.o
+# DTRACE = @DTRACE@
+# DTRACEFLAGS = @DTRACEFLAGS@
+# DTRACEFILES = .libs/liboqgraph_engine_la-ha_oqgraph.o
ORIG_CXXFLAGS = @CXXFLAGS@
CXXFLAGS=
noinst_HEADERS = ha_oqgraph.h \
- graphcore-graph.h graphcore-types.h graphcore.h \
- oqgraph_probes.h
+ graphcore-graph.h graphcore-types.h graphcore.h
+# oqgraph_probes.h
noinst_LTLIBRARIES = libgraphcore.la
libgraphcore_la_SOURCES = graphcore.cc
@@ -74,22 +74,22 @@ mysqlplugin_LTLIBRARIES = @plugin_oqgrap
oqgraph_engine_la_SOURCES = ha_oqgraph.cc
oqgraph_engine_la_LIBADD = libgraphcore.la
-if HAVE_DTRACE
- oqgraph_engine_la_LIBADD += oqgraph_probes.o
-endif
+# if HAVE_DTRACE
+# oqgraph_engine_la_LIBADD += oqgraph_probes.o
+# endif
oqgraph_engine_la_LDFLAGS = -module -rpath $(mysqlplugindir)
oqgraph_engine_la_CFLAGS = $(ORIG_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
oqgraph_engine_la_CXXFLAGS = $(ORIG_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-oqgraph_probes.h: oqgraph_probes.d
- $(DTRACE) $(DTRACEFLAGS) -h -s oqgraph_probes.d
- mv oqgraph_probes.h oqgraph_probes.h.bak
- sed "s/#include <unistd.h>//g" oqgraph_probes.h.bak > oqgraph_probes.h
- rm oqgraph_probes.h.bak
+# oqgraph_probes.h: oqgraph_probes.d
+# $(DTRACE) $(DTRACEFLAGS) -h -s oqgraph_probes.d
+# mv oqgraph_probes.h oqgraph_probes.h.bak
+# sed "s/#include <unistd.h>//g" oqgraph_probes.h.bak > oqgraph_probes.h
+# rm oqgraph_probes.h.bak
-oqgraph_probes.o:
- $(DTRACE) $(DTRACEFLAGS) -G -s oqgraph_probes.d $(DTRACEFILES)
+# oqgraph_probes.o:
+# $(DTRACE) $(DTRACEFLAGS) -G -s oqgraph_probes.d $(DTRACEFILES)
endif BUILD_OQGRAPH_FOR_MYSQL
=== removed file 'storage/oqgraph/oqgraph_probes.h'
--- a/storage/oqgraph/oqgraph_probes.h 2010-01-04 08:27:50 +0000
+++ b/storage/oqgraph/oqgraph_probes.h 1970-01-01 00:00:00 +0000
@@ -1,45 +0,0 @@
-/*
- * Generated by dtrace(1M).
- */
-
-#ifndef _OQGRAPH_PROBES_H
-#define _OQGRAPH_PROBES_H
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if _DTRACE_VERSION
-
-#define OQGRAPH_CLOSE() \
- __dtrace_oqgraph___close()
-#define OQGRAPH_CLOSE_ENABLED() \
- __dtraceenabled_oqgraph___close()
-#define OQGRAPH_OPEN() \
- __dtrace_oqgraph___open()
-#define OQGRAPH_OPEN_ENABLED() \
- __dtraceenabled_oqgraph___open()
-
-
-extern void __dtrace_oqgraph___close(void);
-extern int __dtraceenabled_oqgraph___close(void);
-extern void __dtrace_oqgraph___open(void);
-extern int __dtraceenabled_oqgraph___open(void);
-
-#else
-
-#define OQGRAPH_CLOSE()
-#define OQGRAPH_CLOSE_ENABLED() (0)
-#define OQGRAPH_OPEN()
-#define OQGRAPH_OPEN_ENABLED() (0)
-
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _OQGRAPH_PROBES_H */
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2791)
by knielsen@knielsen-hq.org 30 Mar '10
by knielsen@knielsen-hq.org 30 Mar '10
30 Mar '10
#At lp:maria
2791 knielsen(a)knielsen-hq.org 2010-03-30
Comment out dtrace stuff for now, as it does not work properly on systems that lack dtrace.
Remove generated header from bzr
removed:
storage/oqgraph/oqgraph_probes.h
modified:
storage/oqgraph/Makefile.am
=== modified file 'storage/oqgraph/Makefile.am'
--- a/storage/oqgraph/Makefile.am 2010-01-04 08:27:50 +0000
+++ b/storage/oqgraph/Makefile.am 2010-03-30 18:12:00 +0000
@@ -47,15 +47,15 @@ EXTRA_DIST = ha_oqgraph.h ha_oqgraph.cc
graphcore-graph.h graphcore-types.h graphcore.h \
CMakeFiles.txt plug.in oqgraph_probes.d
-DTRACE = @DTRACE@
-DTRACEFLAGS = @DTRACEFLAGS@
-DTRACEFILES = .libs/liboqgraph_engine_la-ha_oqgraph.o
+# DTRACE = @DTRACE@
+# DTRACEFLAGS = @DTRACEFLAGS@
+# DTRACEFILES = .libs/liboqgraph_engine_la-ha_oqgraph.o
ORIG_CXXFLAGS = @CXXFLAGS@
CXXFLAGS=
noinst_HEADERS = ha_oqgraph.h \
- graphcore-graph.h graphcore-types.h graphcore.h \
- oqgraph_probes.h
+ graphcore-graph.h graphcore-types.h graphcore.h
+# oqgraph_probes.h
noinst_LTLIBRARIES = libgraphcore.la
libgraphcore_la_SOURCES = graphcore.cc
@@ -74,22 +74,22 @@ mysqlplugin_LTLIBRARIES = @plugin_oqgrap
oqgraph_engine_la_SOURCES = ha_oqgraph.cc
oqgraph_engine_la_LIBADD = libgraphcore.la
-if HAVE_DTRACE
- oqgraph_engine_la_LIBADD += oqgraph_probes.o
-endif
+# if HAVE_DTRACE
+# oqgraph_engine_la_LIBADD += oqgraph_probes.o
+# endif
oqgraph_engine_la_LDFLAGS = -module -rpath $(mysqlplugindir)
oqgraph_engine_la_CFLAGS = $(ORIG_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
oqgraph_engine_la_CXXFLAGS = $(ORIG_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-oqgraph_probes.h: oqgraph_probes.d
- $(DTRACE) $(DTRACEFLAGS) -h -s oqgraph_probes.d
- mv oqgraph_probes.h oqgraph_probes.h.bak
- sed "s/#include <unistd.h>//g" oqgraph_probes.h.bak > oqgraph_probes.h
- rm oqgraph_probes.h.bak
+# oqgraph_probes.h: oqgraph_probes.d
+# $(DTRACE) $(DTRACEFLAGS) -h -s oqgraph_probes.d
+# mv oqgraph_probes.h oqgraph_probes.h.bak
+# sed "s/#include <unistd.h>//g" oqgraph_probes.h.bak > oqgraph_probes.h
+# rm oqgraph_probes.h.bak
-oqgraph_probes.o:
- $(DTRACE) $(DTRACEFLAGS) -G -s oqgraph_probes.d $(DTRACEFILES)
+# oqgraph_probes.o:
+# $(DTRACE) $(DTRACEFLAGS) -G -s oqgraph_probes.d $(DTRACEFILES)
endif BUILD_OQGRAPH_FOR_MYSQL
=== removed file 'storage/oqgraph/oqgraph_probes.h'
--- a/storage/oqgraph/oqgraph_probes.h 2010-01-04 08:27:50 +0000
+++ b/storage/oqgraph/oqgraph_probes.h 1970-01-01 00:00:00 +0000
@@ -1,45 +0,0 @@
-/*
- * Generated by dtrace(1M).
- */
-
-#ifndef _OQGRAPH_PROBES_H
-#define _OQGRAPH_PROBES_H
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if _DTRACE_VERSION
-
-#define OQGRAPH_CLOSE() \
- __dtrace_oqgraph___close()
-#define OQGRAPH_CLOSE_ENABLED() \
- __dtraceenabled_oqgraph___close()
-#define OQGRAPH_OPEN() \
- __dtrace_oqgraph___open()
-#define OQGRAPH_OPEN_ENABLED() \
- __dtraceenabled_oqgraph___open()
-
-
-extern void __dtrace_oqgraph___close(void);
-extern int __dtraceenabled_oqgraph___close(void);
-extern void __dtrace_oqgraph___open(void);
-extern int __dtraceenabled_oqgraph___open(void);
-
-#else
-
-#define OQGRAPH_CLOSE()
-#define OQGRAPH_CLOSE_ENABLED() (0)
-#define OQGRAPH_OPEN()
-#define OQGRAPH_OPEN_ENABLED() (0)
-
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _OQGRAPH_PROBES_H */
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2801)
by knielsen@knielsen-hq.org 30 Mar '10
by knielsen@knielsen-hq.org 30 Mar '10
30 Mar '10
#At lp:maria
2801 knielsen(a)knielsen-hq.org 2010-03-30 [merge]
automerge for buildbot test
added:
mysql-test/suite/oqgraph/
mysql-test/suite/oqgraph/include/
mysql-test/suite/oqgraph/include/have_oqgraph_engine.inc
mysql-test/suite/oqgraph/r/
mysql-test/suite/oqgraph/r/basic.result
mysql-test/suite/oqgraph/t/
mysql-test/suite/oqgraph/t/basic-master.opt
mysql-test/suite/oqgraph/t/basic.test
mysql-test/suite/pbxt/r/pbxt_xa.result
mysql-test/suite/pbxt/t/pbxt_xa.test
mysql-test/suite/pbxt/t/suite.opt
storage/oqgraph/
storage/oqgraph/CMakeFiles.txt
storage/oqgraph/Makefile.am
storage/oqgraph/README
storage/oqgraph/graphcore-graph.h
storage/oqgraph/graphcore-types.h
storage/oqgraph/graphcore.cc
storage/oqgraph/graphcore.h
storage/oqgraph/graphstore.c
storage/oqgraph/graphstore.h
storage/oqgraph/ha_oqgraph.cc
storage/oqgraph/ha_oqgraph.h
storage/oqgraph/oqgraph_config.h.in
storage/oqgraph/oqgraph_probes.d
storage/oqgraph/oqgraph_probes.h
storage/oqgraph/plug.in
modified:
BUILD/SETUP.sh
extra/comp_err.c
extra/libevent/kqueue.c
include/my_global.h
mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test
mysql-test/include/default_mysqld.cnf
mysql-test/lib/My/SafeProcess.pm
mysql-test/lib/My/SafeProcess/safe_process.cc
mysql-test/lib/mtr_cases.pm
mysql-test/lib/v1/mysql-test-run.pl
mysql-test/mysql-test-run.pl
mysql-test/r/foreign_key.result
mysql-test/r/information_schema.result
mysql-test/suite/parts/t/rpl_partition.test
mysql-test/suite/rpl/r/rpl_do_grant.result
mysql-test/suite/rpl/t/rpl_do_grant.test
mysql-test/suite/rpl/t/rpl_name_const.test
mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
mysql-test/suite/rpl/t/rpl_row_trig003.test
mysql-test/t/bug47671-master.opt
mysql-test/t/ctype_latin1_de-master.opt
mysql-test/t/ctype_ucs2_def-master.opt
mysql-test/t/foreign_key.test
mysql-test/t/information_schema.test
mysql-test/valgrind.supp
mysys/mf_keycache.c
mysys/my_gethostbyname.c
sql-common/client.c
sql/handler.cc
sql/item.cc
sql/item.h
sql/item_cmpfunc.cc
sql/item_create.cc
sql/item_create.h
sql/item_sum.cc
sql/item_sum.h
sql/log.cc
sql/mysqld.cc
sql/net_serv.cc
sql/set_var.cc
sql/sql_class.h
sql/sql_delete.cc
sql/sql_lex.cc
sql/sql_plugin.cc
sql/sql_plugin.h
sql/sql_table.cc
sql/sql_view.cc
sql/sql_yacc.yy
sql/table.cc
storage/example/ha_example.h
storage/federatedx/ha_federatedx.cc
storage/maria/ma_delete.c
storage/maria/ma_loghandler.c
storage/maria/ma_search.c
storage/maria/maria_def.h
storage/myisam/ft_stopwords.c
storage/myisam/mi_create.c
storage/myisam/mi_write.c
storage/myisammrg/ha_myisammrg.cc
storage/myisammrg/myrg_open.c
storage/xtradb/btr/btr0cur.c
storage/xtradb/fil/fil0fil.c
storage/xtradb/include/page0page.h
storage/xtradb/include/page0page.ic
storage/xtradb/include/ut0lst.h
strings/ctype-ucs2.c
strings/ctype-utf8.c
support-files/compiler_warnings.supp
unittest/mysys/waiting_threads-t.c
vio/viossl.c
=== modified file 'BUILD/SETUP.sh'
--- a/BUILD/SETUP.sh 2010-01-07 12:02:18 +0000
+++ b/BUILD/SETUP.sh 2010-03-30 16:16:57 +0000
@@ -204,7 +204,7 @@ if test -z "$CC" ; then
fi
if test -z "$CXX" ; then
- CXX=gcc
+ CXX=g++
fi
# If ccache (a compiler cache which reduces build time)
=== modified file 'extra/comp_err.c'
--- a/extra/comp_err.c 2009-11-20 10:11:31 +0000
+++ b/extra/comp_err.c 2010-03-30 12:36:49 +0000
@@ -660,7 +660,7 @@ static ha_checksum checksum_format_speci
case 'u':
case 'x':
case 's':
- chksum= my_checksum(chksum, start, (uint) (p + 1 - start));
+ chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start));
start= 0; /* Not in format specifier anymore */
break;
=== modified file 'extra/libevent/kqueue.c'
--- a/extra/libevent/kqueue.c 2009-03-12 22:27:35 +0000
+++ b/extra/libevent/kqueue.c 2010-03-30 12:36:49 +0000
@@ -144,7 +144,7 @@ kq_init(struct event_base *base)
*/
if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
- kqueueop->events[0].ident != -1 ||
+ ((int) kqueueop->events[0].ident) != -1 ||
kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue; not using.", __func__);
free(kqueueop->changes);
=== modified file 'include/my_global.h'
--- a/include/my_global.h 2010-03-04 08:03:07 +0000
+++ b/include/my_global.h 2010-03-10 10:32:14 +0000
@@ -1260,9 +1260,9 @@ do { doubleget_union _tmp; \
} while (0)
#define float4get(V,M) do { *((float *) &(V)) = *((const float*) (M)); } while(0)
#define float8get(V,M) doubleget((V),(M))
-#define float4store(V,M) memcpy((uchar*) V,(const uchar*) (&M),sizeof(float))
-#define floatstore(T,V) memcpy((uchar*)(T), (const uchar*)(&V),sizeof(float))
-#define floatget(V,M) memcpy((uchar*) &V,(const uchar*) (M),sizeof(float))
+#define float4store(V,M) memcpy((uchar*) V,(uchar*) (&M),sizeof(float))
+#define floatstore(T,V) memcpy((uchar*)(T), (uchar*)(&V),sizeof(float))
+#define floatget(V,M) memcpy((uchar*) &V,(uchar*) (M),sizeof(float))
#define float8store(V,M) doublestore((V),(M))
#else
=== modified file 'mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test'
--- a/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-01-22 09:38:21 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-03-28 18:10:00 +0000
@@ -157,3 +157,4 @@ INSERT INTO t1 VALUES (1);
DROP TEMPORARY TABLE t1;
+--sync_slave_with_master
=== modified file 'mysql-test/include/default_mysqld.cnf'
--- a/mysql-test/include/default_mysqld.cnf 2008-04-08 14:51:26 +0000
+++ b/mysql-test/include/default_mysqld.cnf 2010-03-28 18:10:00 +0000
@@ -2,7 +2,7 @@
[mysqld]
open-files-limit= 1024
local-infile
-default-character-set= latin1
+character-set-server= latin1
# Increase default connect_timeout to avoid intermittent
# disconnects when test servers are put under load see BUG#28359
=== modified file 'mysql-test/lib/My/SafeProcess.pm'
--- a/mysql-test/lib/My/SafeProcess.pm 2009-04-29 14:13:38 +0000
+++ b/mysql-test/lib/My/SafeProcess.pm 2010-03-10 10:32:14 +0000
@@ -384,9 +384,9 @@ sub kill {
sub _collect {
- my ($self)= @_;
+ my ($self, $exit_code)= @_;
- $self->{EXIT_STATUS}= $?;
+ $self->{EXIT_STATUS}= $exit_code;
_verbose("_collect: $self");
# Take the process out of running list
@@ -453,6 +453,7 @@ sub wait_one {
#_verbose("blocking: $blocking, use_alarm: $use_alarm");
my $retpid;
+ my $exit_code;
eval
{
# alarm should break the wait
@@ -461,6 +462,7 @@ sub wait_one {
alarm($timeout) if $use_alarm;
$retpid= waitpid($pid, $blocking ? 0 : &WNOHANG);
+ $exit_code= $?;
alarm(0) if $use_alarm;
};
@@ -492,7 +494,7 @@ sub wait_one {
#warn "wait_one: expected pid $pid but got $retpid"
# unless( $retpid == $pid );
- $self->_collect();
+ $self->_collect($exit_code);
return 0;
}
@@ -505,6 +507,8 @@ sub wait_one {
#
sub wait_any {
my $ret_pid;
+ my $exit_code;
+
if (IS_WIN32PERL) {
# Can't wait for -1 => use a polling loop
do {
@@ -514,6 +518,7 @@ sub wait_any {
last if $pid == $ret_pid;
}
} while ($ret_pid == 0);
+ $exit_code= $?;
}
else
{
@@ -523,6 +528,7 @@ sub wait_any {
print STDERR "wait_any, got invalid pid: $ret_pid\n";
return undef;
}
+ $exit_code= $?;
}
# Look it up in "running" table
@@ -532,7 +538,7 @@ sub wait_any {
print STDERR "running: ". join(", ", keys(%running)). "\n";
return undef;
}
- $proc->_collect;
+ $proc->_collect($exit_code);
return $proc;
}
=== modified file 'mysql-test/lib/My/SafeProcess/safe_process.cc'
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc 2009-07-08 12:31:22 +0000
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc 2010-03-28 18:10:00 +0000
@@ -159,7 +159,7 @@ int main(int argc, char* const argv[] )
signal(SIGCHLD, handle_signal);
signal(SIGABRT, handle_abort);
- sprintf(safe_process_name, "safe_process[%d]", own_pid);
+ sprintf(safe_process_name, "safe_process[%d]", (int) own_pid);
message("Started");
=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm 2010-01-15 15:27:55 +0000
+++ b/mysql-test/lib/mtr_cases.pm 2010-03-30 16:16:57 +0000
@@ -681,6 +681,8 @@ sub optimize_cases {
if ( $default_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
if ( $default_engine =~ /^innodb/i );
+ $tinfo->{'pbxt_test'}= 1
+ if ( $default_engine =~ /^pbxt/i );
}
}
@@ -778,6 +780,8 @@ sub collect_one_test_case {
my $disabled= shift;
my $suite_opts= shift;
+ my $local_default_storage_engine= $default_storage_engine;
+
#print "collect_one_test_case\n";
#print " suitedir: $suitedir\n";
#print " testdir: $testdir\n";
@@ -932,15 +936,26 @@ sub collect_one_test_case {
tags_from_test_file($tinfo,"$testdir/${tname}.test");
- if ( defined $default_storage_engine )
+ # Get default storage engine from suite.opt file
+
+ if (defined $suite_opts &&
+ "@$suite_opts" =~ "default-storage-engine=\s*([^\s]*)")
+ {
+ $local_default_storage_engine= $1;
+ }
+
+ if ( defined $local_default_storage_engine )
{
# Different default engine is used
# tag test to require that engine
$tinfo->{'ndb_test'}= 1
- if ( $default_storage_engine =~ /^ndb/i );
+ if ( $local_default_storage_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
- if ( $default_storage_engine =~ /^innodb/i );
+ if ( $local_default_storage_engine =~ /^innodb/i );
+
+ $tinfo->{'pbxt_test'}= 1
+ if ( $local_default_storage_engine =~ /^pbxt/i );
}
@@ -1103,6 +1118,28 @@ sub collect_one_test_case {
$tinfo->{template_path}= $config;
}
+ if ( $tinfo->{'pbxt_test'} )
+ {
+ # This is a test that needs pbxt
+ if ( $::mysqld_variables{'pbxt'} eq "OFF" ||
+ ! exists $::mysqld_variables{'pbxt'} )
+ {
+ # Engine is not supported, skip it
+ $tinfo->{'skip'}= 1;
+ return $tinfo;
+ }
+ }
+ else
+ {
+ # Only disable engine if it's on by default (to avoid warnings about
+ # not existing loose options
+ if ( $::mysqld_variables{'pbxt'} eq "ON")
+ {
+ push(@{$tinfo->{'master_opt'}}, "--loose-skip-pbxt");
+ push(@{$tinfo->{'slave_opt'}}, "--loose-skip-pbxt");
+ }
+ }
+
if ( $tinfo->{'example_plugin_test'} )
{
if ( !$ENV{'EXAMPLE_PLUGIN'} )
@@ -1113,6 +1150,16 @@ sub collect_one_test_case {
}
}
+ if ( $tinfo->{'oqgraph_test'} )
+ {
+ if ( !$ENV{'OQGRAPH_PLUGIN'} )
+ {
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "Test requires the OQGraph storage engine";
+ return $tinfo;
+ }
+ }
+
# Set extra config file to use
if (defined $defaults_extra_file) {
@@ -1156,6 +1203,7 @@ my @tags=
["include/have_log_bin.inc", "need_binlog", 1],
["include/have_innodb.inc", "innodb_test", 1],
+ ["include/have_pbxt.inc", "pbxt_test", 1],
["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1],
["include/have_ndb.inc", "ndb_test", 1],
@@ -1167,6 +1215,7 @@ my @tags=
["include/not_embedded.inc", "not_embedded", 1],
["include/not_valgrind.inc", "not_valgrind", 1],
["include/have_example_plugin.inc", "example_plugin_test", 1],
+ ["include/have_oqgraph_engine.inc", "oqgraph_test", 1],
["include/have_ssl.inc", "need_ssl", 1],
);
=== modified file 'mysql-test/lib/v1/mysql-test-run.pl'
--- a/mysql-test/lib/v1/mysql-test-run.pl 2010-03-04 08:03:07 +0000
+++ b/mysql-test/lib/v1/mysql-test-run.pl 2010-03-28 18:10:00 +0000
@@ -3965,7 +3965,7 @@ sub mysqld_arguments ($$$$) {
}
}
- mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
+ mtr_add_arg($args, "%s--character-set-server-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl 2010-03-04 08:03:07 +0000
+++ b/mysql-test/mysql-test-run.pl 2010-03-30 16:16:57 +0000
@@ -126,7 +126,7 @@ my $path_config_file; # The ge
# executables will be used by the test suite.
our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
-my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts";
+my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,oqgraph";
my $opt_suites;
our $opt_verbose= 0; # Verbose output, enable with --verbose
@@ -1912,6 +1912,33 @@ sub detect_plugins {
$ENV{'HA_EXAMPLE_SO'}="'".$plugin_filename."'";
$ENV{'EXAMPLE_PLUGIN_LOAD'}="--plugin_load=EXAMPLE=".$plugin_filename;
}
+
+ # --------------------------------------------------------------------------
+ # Add the path where mysqld will find graph_engine.so
+ # --------------------------------------------------------------------------
+ if ($mysql_version_id >= 50100 && !(IS_WINDOWS && $opt_embedded_server)) {
+ my $plugin_filename;
+ if (IS_WINDOWS)
+ {
+ $plugin_filename = "oqgraph_engine.dll";
+ }
+ else
+ {
+ $plugin_filename = "oqgraph_engine.so";
+ }
+ my $lib_oqgraph_plugin=
+ mtr_file_exists(vs_config_dirs('storage/oqgraph',$plugin_filename),
+ "$basedir/storage/oqgraph/.libs/".$plugin_filename,
+ "$basedir/lib/mariadb/plugin/".$plugin_filename,
+ "$basedir/lib/mysql/plugin/".$plugin_filename);
+ $ENV{'OQGRAPH_PLUGIN'}=
+ ($lib_oqgraph_plugin ? basename($lib_oqgraph_plugin) : "");
+ $ENV{'OQGRAPH_PLUGIN_OPT'}= "--plugin-dir=".
+ ($lib_oqgraph_plugin ? dirname($lib_oqgraph_plugin) : "");
+
+ $ENV{'GRAPH_ENGINE_SO'}="'".$plugin_filename."'";
+ $ENV{'OQGRAPH_PLUGIN_LOAD'}="--plugin_load=;OQGRAPH=".$plugin_filename.";";
+ }
}
#
@@ -4102,7 +4129,7 @@ sub start_check_warnings ($$) {
error => $errfile,
output => $errfile,
args => \$args,
- user_data => $errfile,
+ user_data => [$errfile, $mysqld],
verbose => $opt_verbose,
);
mtr_verbose("Started $proc");
@@ -4148,7 +4175,7 @@ sub check_warnings ($) {
if ( delete $started{$proc->pid()} ) {
# One check warning process returned
my $res= $proc->exit_status();
- my $err_file= $proc->user_data();
+ my ($err_file, $mysqld)= @{$proc->user_data()};
if ( $res == 0 or $res == 62 ){
@@ -4184,7 +4211,8 @@ sub check_warnings ($) {
my $report= mtr_grab_file($err_file);
$tinfo->{comment}.=
"Could not execute 'check-warnings' for ".
- "testcase '$tname' (res: $res):\n";
+ "testcase '$tname' (res: $res) server: '".
+ $mysqld->name() .":\n";
$tinfo->{comment}.= $report;
$result= 2;
=== modified file 'mysql-test/r/foreign_key.result'
--- a/mysql-test/r/foreign_key.result 2001-09-28 05:05:54 +0000
+++ b/mysql-test/r/foreign_key.result 2010-03-10 13:39:02 +0000
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1,t2;
create table t1 (
a int not null references t2,
b int not null references t2 (c),
@@ -13,3 +13,30 @@ foreign key (a,b) references t3 (c,d) on
create index a on t1 (a);
create unique index b on t1 (a,b);
drop table t1;
+create table t1 (id int primary key) engine = innodb;
+create table t2 (id int PRIMARY KEY, FOREIGN KEY (id) REFERENCES t1(id)) engine=innodb;
+insert into t1 values (1), (2), (3), (4), (5), (6);
+insert into t2 values (3), (5);
+delete from t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+select * from t1;
+id
+1
+2
+3
+4
+5
+6
+delete ignore from t1;
+Warnings:
+Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+select row_count();
+row_count()
+-1
+select * from t1;
+id
+3
+5
+drop table t2;
+drop table t1;
=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result 2010-03-04 08:03:07 +0000
+++ b/mysql-test/r/information_schema.result 2010-03-10 09:12:23 +0000
@@ -1386,7 +1386,7 @@ who
other connection here
SELECT IF(`time` > 0, 'OK', `time`) AS time_low,
IF(`time` < 1000, 'OK', `time`) AS time_high,
-IF(time_ms > 1500, 'OK', time_ms) AS time_ms_low,
+IF(time_ms >= 1000, 'OK', time_ms) AS time_ms_low,
IF(time_ms < 1000000, 'OK', time_ms) AS time_ms_high
FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID=@tid;
=== added directory 'mysql-test/suite/oqgraph'
=== added directory 'mysql-test/suite/oqgraph/include'
=== added file 'mysql-test/suite/oqgraph/include/have_oqgraph_engine.inc'
--- a/mysql-test/suite/oqgraph/include/have_oqgraph_engine.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/oqgraph/include/have_oqgraph_engine.inc 2010-01-04 08:27:50 +0000
@@ -0,0 +1,4 @@
+disable_query_log;
+--require r/true.require
+select (PLUGIN_LIBRARY LIKE 'oqgraph_engine%') as `TRUE` from information_schema.plugins where PLUGIN_NAME='OQGRAPH';
+enable_query_log;
=== added directory 'mysql-test/suite/oqgraph/r'
=== added file 'mysql-test/suite/oqgraph/r/basic.result'
--- a/mysql-test/suite/oqgraph/r/basic.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/oqgraph/r/basic.result 2010-01-04 08:27:50 +0000
@@ -0,0 +1,63 @@
+drop table if exists graph;
+Warnings:
+Note 1051 Unknown table 'graph'
+CREATE TABLE graph (
+latch SMALLINT UNSIGNED NULL,
+origid BIGINT UNSIGNED NULL,
+destid BIGINT UNSIGNED NULL,
+weight DOUBLE NULL,
+seq BIGINT UNSIGNED NULL,
+linkid BIGINT UNSIGNED NULL,
+KEY (latch, origid, destid) USING HASH,
+KEY (latch, destid, origid) USING HASH
+) ENGINE=OQGRAPH;
+delete from graph;
+insert into graph(origid, destid) values (1,2), (2,1);
+insert into graph(origid, destid) values (1,3), (3,1);
+insert into graph(origid, destid) values (3,4), (4,3);
+insert into graph(origid, destid) values (3,5), (5,3);
+insert into graph(origid, destid) values (5,6), (6,5);
+select * from graph where latch = 2 and origid = 1 and weight = 1;
+latch origid destid weight seq linkid
+2 1 NULL 1 3 3
+2 1 NULL 1 2 2
+select * from graph where latch = 2 and origid = 1 and weight = 2;
+latch origid destid weight seq linkid
+2 1 NULL 2 5 5
+2 1 NULL 2 4 4
+select * from graph
+where latch = 2 and origid = 1 and (weight = 1 or weight = 2);
+latch origid destid weight seq linkid
+2 1 NULL 2 5 5
+2 1 NULL 2 4 4
+2 1 NULL 1 3 3
+2 1 NULL 1 2 2
+select * from graph where latch=1 and origid=1 and destid=6;
+latch origid destid weight seq linkid
+1 1 6 NULL 0 1
+1 1 6 1 1 3
+1 1 6 1 2 5
+1 1 6 1 3 6
+select * from graph where latch=1 and origid=1 and destid=4;
+latch origid destid weight seq linkid
+1 1 4 NULL 0 1
+1 1 4 1 1 3
+1 1 4 1 2 4
+select * from graph where latch=1 and origid=4 and destid=1;
+latch origid destid weight seq linkid
+1 4 1 NULL 0 4
+1 4 1 1 1 3
+1 4 1 1 2 1
+insert into graph (origid,destid) values (4,6);
+delete from graph where origid=5;
+delete from graph where origid=3 and destid=5;
+select * from graph where latch=1 and origid=1 and destid=6;
+latch origid destid weight seq linkid
+1 1 6 NULL 0 1
+1 1 6 1 1 3
+1 1 6 1 2 4
+1 1 6 1 3 6
+select * from graph where latch=1 and origid=6 and destid=1;
+latch origid destid weight seq linkid
+truncate table graph;
+drop table graph;
=== added directory 'mysql-test/suite/oqgraph/t'
=== added file 'mysql-test/suite/oqgraph/t/basic-master.opt'
--- a/mysql-test/suite/oqgraph/t/basic-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/oqgraph/t/basic-master.opt 2010-01-04 08:27:50 +0000
@@ -0,0 +1,2 @@
+$OQGRAPH_PLUGIN_OPT
+$OQGRAPH_PLUGIN_LOAD
=== added file 'mysql-test/suite/oqgraph/t/basic.test'
--- a/mysql-test/suite/oqgraph/t/basic.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/oqgraph/t/basic.test 2010-01-04 08:27:50 +0000
@@ -0,0 +1,45 @@
+-- source suite/oqgraph/include/have_oqgraph_engine.inc
+
+drop table if exists graph;
+
+CREATE TABLE graph (
+ latch SMALLINT UNSIGNED NULL,
+ origid BIGINT UNSIGNED NULL,
+ destid BIGINT UNSIGNED NULL,
+ weight DOUBLE NULL,
+ seq BIGINT UNSIGNED NULL,
+ linkid BIGINT UNSIGNED NULL,
+ KEY (latch, origid, destid) USING HASH,
+ KEY (latch, destid, origid) USING HASH
+ ) ENGINE=OQGRAPH;
+
+delete from graph;
+
+insert into graph(origid, destid) values (1,2), (2,1);
+insert into graph(origid, destid) values (1,3), (3,1);
+insert into graph(origid, destid) values (3,4), (4,3);
+insert into graph(origid, destid) values (3,5), (5,3);
+insert into graph(origid, destid) values (5,6), (6,5);
+
+select * from graph where latch = 2 and origid = 1 and weight = 1;
+
+select * from graph where latch = 2 and origid = 1 and weight = 2;
+
+select * from graph
+where latch = 2 and origid = 1 and (weight = 1 or weight = 2);
+
+select * from graph where latch=1 and origid=1 and destid=6;
+select * from graph where latch=1 and origid=1 and destid=4;
+select * from graph where latch=1 and origid=4 and destid=1;
+
+insert into graph (origid,destid) values (4,6);
+
+delete from graph where origid=5;
+delete from graph where origid=3 and destid=5;
+
+select * from graph where latch=1 and origid=1 and destid=6;
+select * from graph where latch=1 and origid=6 and destid=1;
+
+truncate table graph;
+
+drop table graph;
=== modified file 'mysql-test/suite/parts/t/rpl_partition.test'
--- a/mysql-test/suite/parts/t/rpl_partition.test 2009-02-01 12:00:48 +0000
+++ b/mysql-test/suite/parts/t/rpl_partition.test 2010-03-29 19:07:45 +0000
@@ -1,6 +1,7 @@
--source include/have_partition.inc
--source include/have_innodb.inc
--source include/master-slave.inc
+--source include/big_test.inc
--vertical_results
=== added file 'mysql-test/suite/pbxt/r/pbxt_xa.result'
--- a/mysql-test/suite/pbxt/r/pbxt_xa.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/r/pbxt_xa.result 2010-03-24 22:12:39 +0000
@@ -0,0 +1,18 @@
+drop table if exists t1, t2;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+SELECT @@log_bin;
+@@log_bin
+0
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+a
+1
+select * from t2;
+b
+2
+drop table t1, t2;
+drop database pbxt;
=== added file 'mysql-test/suite/pbxt/t/pbxt_xa.test'
--- a/mysql-test/suite/pbxt/t/pbxt_xa.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/pbxt_xa.test 2010-03-24 22:12:39 +0000
@@ -0,0 +1,23 @@
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+#
+# bug lp:544173, xa crash with two 2pc-capable storage engines without binlog
+#
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+# verify that binlog is off
+SELECT @@log_bin;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+select * from t2;
+drop table t1, t2;
+drop database pbxt;
+
=== added file 'mysql-test/suite/pbxt/t/suite.opt'
--- a/mysql-test/suite/pbxt/t/suite.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/suite.opt 2010-03-30 12:36:49 +0000
@@ -0,0 +1 @@
+--default-storage-engine=pbxt
=== modified file 'mysql-test/suite/rpl/r/rpl_do_grant.result'
--- a/mysql-test/suite/rpl/r/rpl_do_grant.result 2009-12-06 23:12:11 +0000
+++ b/mysql-test/suite/rpl/r/rpl_do_grant.result 2010-03-28 18:10:00 +0000
@@ -165,10 +165,9 @@ USE bug42217_db;
DROP FUNCTION upgrade_del_func;
DROP FUNCTION upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
-USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+stop slave;
+DROP USER 'create_rout_db'@'localhost';
######## BUG#49119 #######
### i) test case from the 'how to repeat section'
stop slave;
=== modified file 'mysql-test/suite/rpl/t/rpl_do_grant.test'
--- a/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-03-04 08:03:07 +0000
+++ b/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-03-28 18:10:00 +0000
@@ -209,12 +209,18 @@ USE bug42217_db;
DROP FUNCTION upgrade_del_func;
DROP FUNCTION upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+
+sync_slave_with_master;
+
+# Drop the user that was already dropped on the slave
connection slave;
-USE mtr;
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+--disable_warnings
+stop slave;
+connection master;
+DROP USER 'create_rout_db'@'localhost';
+--enable_warnings
# BUG#49119: Master crashes when executing 'REVOKE ... ON
# {PROCEDURE|FUNCTION} FROM ...'
=== modified file 'mysql-test/suite/rpl/t/rpl_name_const.test'
--- a/mysql-test/suite/rpl/t/rpl_name_const.test 2009-04-08 23:42:51 +0000
+++ b/mysql-test/suite/rpl/t/rpl_name_const.test 2010-03-28 18:10:00 +0000
@@ -45,3 +45,4 @@ select * from t1 order by id;
connection master;
drop table t1;
drop procedure test_procedure;
+--sync_slave_with_master
=== modified file 'mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test'
--- a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2007-12-12 10:14:59 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2010-03-28 18:10:00 +0000
@@ -53,6 +53,7 @@ UPDATE t1 SET a=99 WHERE a = 0;
SHOW BINLOG EVENTS;
DROP TABLE t1;
+--sync_slave_with_master
# BUG#17620: Replicate (Row Based) Fails when Query Cache enabled on
# slave
=== modified file 'mysql-test/suite/rpl/t/rpl_row_trig003.test'
--- a/mysql-test/suite/rpl/t/rpl_row_trig003.test 2007-12-06 15:27:10 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_trig003.test 2010-03-29 19:07:45 +0000
@@ -149,6 +149,8 @@ DROP TABLE IF EXISTS test.t2;
DROP TABLE IF EXISTS test.t3;
--enable_warnings
+sync_slave_with_master;
+
diff_files $MYSQLTEST_VARDIR/tmp/trg003_master.sql $MYSQLTEST_VARDIR/tmp/trg003_slave.sql;
# End of 5.0 test case
=== modified file 'mysql-test/t/bug47671-master.opt'
--- a/mysql-test/t/bug47671-master.opt 2009-11-25 06:55:49 +0000
+++ b/mysql-test/t/bug47671-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-character-set=utf8 --skip-character-set-client-handshake
+--character-set-server=utf8 --skip-character-set-client-handshake
=== modified file 'mysql-test/t/ctype_latin1_de-master.opt'
--- a/mysql-test/t/ctype_latin1_de-master.opt 2003-05-21 23:57:27 +0000
+++ b/mysql-test/t/ctype_latin1_de-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-character-set=latin1 --default-collation=latin1_german2_ci
+--character-set-server=latin1 --default-collation=latin1_german2_ci
=== modified file 'mysql-test/t/ctype_ucs2_def-master.opt'
--- a/mysql-test/t/ctype_ucs2_def-master.opt 2007-02-19 11:04:38 +0000
+++ b/mysql-test/t/ctype_ucs2_def-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-collation=ucs2_unicode_ci --default-character-set=ucs2,latin1
+--default-collation=ucs2_unicode_ci --character-set-server=ucs2,latin1
=== modified file 'mysql-test/t/foreign_key.test'
--- a/mysql-test/t/foreign_key.test 2005-07-28 00:22:47 +0000
+++ b/mysql-test/t/foreign_key.test 2010-03-10 13:39:02 +0000
@@ -2,8 +2,10 @@
# Test syntax of foreign keys
#
+-- source include/have_innodb.inc
+
--disable_warnings
-drop table if exists t1;
+drop table if exists t1,t2;
--enable_warnings
create table t1 (
@@ -23,3 +25,23 @@ create unique index b on t1 (a,b);
drop table t1;
# End of 4.1 tests
+
+#
+# Test DELETE IGNORE
+# Bug#44987 DELETE IGNORE and FK constraint
+#
+
+create table t1 (id int primary key) engine = innodb;
+create table t2 (id int PRIMARY KEY, FOREIGN KEY (id) REFERENCES t1(id)) engine=innodb;
+insert into t1 values (1), (2), (3), (4), (5), (6);
+insert into t2 values (3), (5);
+
+--error 1451
+delete from t1;
+select * from t1;
+
+delete ignore from t1;
+select row_count();
+select * from t1;
+drop table t2;
+drop table t1;
=== modified file 'mysql-test/t/information_schema.test'
--- a/mysql-test/t/information_schema.test 2010-03-04 08:03:07 +0000
+++ b/mysql-test/t/information_schema.test 2010-03-10 09:12:23 +0000
@@ -1114,7 +1114,7 @@ eval SET @tid=$ID;
--enable_query_log
SELECT IF(`time` > 0, 'OK', `time`) AS time_low,
IF(`time` < 1000, 'OK', `time`) AS time_high,
- IF(time_ms > 1500, 'OK', time_ms) AS time_ms_low,
+ IF(time_ms >= 1000, 'OK', time_ms) AS time_ms_low,
IF(time_ms < 1000000, 'OK', time_ms) AS time_ms_high
FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID=@tid;
=== modified file 'mysql-test/valgrind.supp'
--- a/mysql-test/valgrind.supp 2010-01-18 12:56:10 +0000
+++ b/mysql-test/valgrind.supp 2010-03-10 09:11:02 +0000
@@ -469,6 +469,26 @@
}
{
+ dlclose memory loss from plugin variant 8
+ Memcheck:Leak
+ fun:calloc
+ fun:_dlerror_run
+ fun:dlclose
+ fun:_Z15free_plugin_memP12st_plugin_dl
+ fun:_Z13plugin_dl_delPK19st_mysql_lex_string
+}
+
+{
+ dlclose memory loss from plugin variant 9
+ Memcheck:Leak
+ fun:calloc
+ fun:_dlerror_run
+ fun:dlclose
+ fun:_ZL15free_plugin_memP12st_plugin_dl
+ fun:_ZL13plugin_dl_delPK19st_mysql_lex_string
+}
+
+{
dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 32/64 bit ver 1
Memcheck:Leak
fun:*alloc
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2009-12-03 11:19:05 +0000
+++ b/mysys/mf_keycache.c 2010-03-30 12:36:49 +0000
@@ -3924,6 +3924,12 @@ restart:
uint next_status;
uint hash_requests;
+ LINT_INIT(next_hash_link);
+ LINT_INIT(next_diskpos);
+ LINT_INIT(next_file);
+ LINT_INIT(next_status);
+ LINT_INIT(hash_requests);
+
total_found++;
found++;
KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used);
=== modified file 'mysys/my_gethostbyname.c'
--- a/mysys/my_gethostbyname.c 2006-12-31 00:32:21 +0000
+++ b/mysys/my_gethostbyname.c 2010-03-30 12:36:49 +0000
@@ -91,9 +91,12 @@ extern pthread_mutex_t LOCK_gethostbynam
is finished with the structure.
*/
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
+struct hostent *
+my_gethostbyname_r(const char *name,
+ struct hostent *result __attribute__((unused)),
+ char *buffer __attribute__((unused)),
+ int buflen__attribute__((unused)),
+ int *h_errnop)
{
struct hostent *hp;
pthread_mutex_lock(&LOCK_gethostbyname_r);
=== modified file 'sql-common/client.c'
--- a/sql-common/client.c 2010-01-29 18:42:22 +0000
+++ b/sql-common/client.c 2010-03-28 18:10:00 +0000
@@ -1863,7 +1863,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
uint port, const char *unix_socket,ulong client_flag)
{
char buff[NAME_LEN+USERNAME_LENGTH+100];
- char error_string[1024];
char *end,*host_info= NULL;
my_socket sock;
in_addr_t ip_addr;
@@ -2304,6 +2303,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
/* Do the SSL layering. */
struct st_mysql_options *options= &mysql->options;
struct st_VioSSLFd *ssl_fd;
+ char error_string[1024];
/*
Send client_flag, max_packet_size - unencrypted otherwise
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-03-08 13:57:32 +0000
+++ b/sql/handler.cc 2010-03-30 12:36:49 +0000
@@ -4129,7 +4129,7 @@ int handler::read_multi_range_first(KEY_
*/
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
- int result;
+ int result= 0;
DBUG_ENTER("handler::read_multi_range_next");
/* We should not be called after the last call returned EOF. */
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2010-03-04 08:03:07 +0000
+++ b/sql/item.cc 2010-03-28 18:10:00 +0000
@@ -7010,7 +7010,7 @@ bool Item_cache_int::cache_value()
}
-void Item_cache_int::store(Item *item, longlong val_arg)
+void Item_cache_int::store_longlong(Item *item, longlong val_arg)
{
/* An explicit values is given, save it. */
value_cached= TRUE;
=== modified file 'sql/item.h'
--- a/sql/item.h 2010-03-04 08:03:07 +0000
+++ b/sql/item.h 2010-03-30 12:36:49 +0000
@@ -1077,7 +1077,8 @@ class Field_enumerator
{
public:
virtual void visit_field(Field *field)= 0;
- virtual ~Field_enumerator() {}; /* purecov: inspected */
+ virtual ~Field_enumerator() {}; /* purecov: inspected */
+ Field_enumerator() {} /* Remove gcc warning */
};
@@ -3045,7 +3046,7 @@ public:
Item_cache_int(enum_field_types field_type_arg):
Item_cache(field_type_arg), value(0) {}
- void store(Item *item, longlong val_arg);
+ void store_longlong(Item *item, longlong val_arg);
double val_real();
longlong val_int();
String* val_str(String *str);
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2010-03-04 08:03:07 +0000
+++ b/sql/item_cmpfunc.cc 2010-03-28 18:10:00 +0000
@@ -879,7 +879,7 @@ get_time_value(THD *thd, Item ***item_ar
Item_cache_int *cache= new Item_cache_int();
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
@@ -917,13 +917,13 @@ int Arg_comparator::set_cmp_func(Item_re
cache->set_used_tables(1);
if (!(*a)->is_datetime())
{
- cache->store((*a), const_value);
+ cache->store_longlong((*a), const_value);
a_cache= cache;
a= (Item **)&a_cache;
}
else
{
- cache->store((*b), const_value);
+ cache->store_longlong((*b), const_value);
b_cache= cache;
b= (Item **)&b_cache;
}
@@ -1145,7 +1145,7 @@ get_datetime_value(THD *thd, Item ***ite
Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
=== modified file 'sql/item_create.cc'
--- a/sql/item_create.cc 2010-03-04 08:03:07 +0000
+++ b/sql/item_create.cc 2010-03-29 19:07:45 +0000
@@ -76,7 +76,7 @@ public:
@param thd The current thread
@return An item representing the function call
*/
- virtual Item *create(THD *thd) = 0;
+ virtual Item *create_builder(THD *thd) = 0;
protected:
/** Constructor. */
@@ -101,7 +101,7 @@ public:
@param arg1 The first argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1) = 0;
+ virtual Item *create_1_arg(THD *thd, Item *arg1) = 0;
protected:
/** Constructor. */
@@ -127,7 +127,7 @@ public:
@param arg2 The second argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2) = 0;
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) = 0;
protected:
/** Constructor. */
@@ -154,7 +154,7 @@ public:
@param arg3 The third argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
protected:
/** Constructor. */
@@ -171,8 +171,8 @@ protected:
class Create_sp_func : public Create_qfunc
{
public:
- virtual Item *create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list);
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list);
static Create_sp_func s_singleton;
@@ -217,7 +217,7 @@ protected:
class Create_func_abs : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_abs s_singleton;
@@ -230,7 +230,7 @@ protected:
class Create_func_acos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_acos s_singleton;
@@ -243,7 +243,7 @@ protected:
class Create_func_addtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_addtime s_singleton;
@@ -256,7 +256,7 @@ protected:
class Create_func_aes_encrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_encrypt s_singleton;
@@ -269,7 +269,7 @@ protected:
class Create_func_aes_decrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_decrypt s_singleton;
@@ -283,7 +283,7 @@ protected:
class Create_func_area : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_area s_singleton;
@@ -298,7 +298,7 @@ protected:
class Create_func_as_wkb : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkb s_singleton;
@@ -313,7 +313,7 @@ protected:
class Create_func_as_wkt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkt s_singleton;
@@ -327,7 +327,7 @@ protected:
class Create_func_asin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_asin s_singleton;
@@ -353,7 +353,7 @@ protected:
class Create_func_benchmark : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_benchmark s_singleton;
@@ -366,7 +366,7 @@ protected:
class Create_func_bin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bin s_singleton;
@@ -379,7 +379,7 @@ protected:
class Create_func_bit_count : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_count s_singleton;
@@ -392,7 +392,7 @@ protected:
class Create_func_bit_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_length s_singleton;
@@ -405,7 +405,7 @@ protected:
class Create_func_ceiling : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ceiling s_singleton;
@@ -419,7 +419,7 @@ protected:
class Create_func_centroid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_centroid s_singleton;
@@ -433,7 +433,7 @@ protected:
class Create_func_char_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_char_length s_singleton;
@@ -446,7 +446,7 @@ protected:
class Create_func_coercibility : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_coercibility s_singleton;
@@ -459,7 +459,7 @@ protected:
class Create_func_compress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_compress s_singleton;
@@ -498,7 +498,7 @@ protected:
class Create_func_connection_id : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_connection_id s_singleton;
@@ -512,7 +512,7 @@ protected:
class Create_func_contains : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_contains s_singleton;
@@ -526,7 +526,7 @@ protected:
class Create_func_conv : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_conv s_singleton;
@@ -539,7 +539,7 @@ protected:
class Create_func_convert_tz : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_convert_tz s_singleton;
@@ -552,7 +552,7 @@ protected:
class Create_func_cos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cos s_singleton;
@@ -565,7 +565,7 @@ protected:
class Create_func_cot : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cot s_singleton;
@@ -578,7 +578,7 @@ protected:
class Create_func_crc32 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_crc32 s_singleton;
@@ -592,7 +592,7 @@ protected:
class Create_func_crosses : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_crosses s_singleton;
@@ -606,7 +606,7 @@ protected:
class Create_func_date_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_date_format s_singleton;
@@ -619,7 +619,7 @@ protected:
class Create_func_datediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_datediff s_singleton;
@@ -632,7 +632,7 @@ protected:
class Create_func_dayname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayname s_singleton;
@@ -645,7 +645,7 @@ protected:
class Create_func_dayofmonth : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofmonth s_singleton;
@@ -658,7 +658,7 @@ protected:
class Create_func_dayofweek : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofweek s_singleton;
@@ -671,7 +671,7 @@ protected:
class Create_func_dayofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofyear s_singleton;
@@ -684,7 +684,7 @@ protected:
class Create_func_decode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_decode s_singleton;
@@ -697,7 +697,7 @@ protected:
class Create_func_degrees : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_degrees s_singleton;
@@ -737,7 +737,7 @@ protected:
class Create_func_dimension : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dimension s_singleton;
@@ -752,7 +752,7 @@ protected:
class Create_func_disjoint : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_disjoint s_singleton;
@@ -779,7 +779,7 @@ protected:
class Create_func_encode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_encode s_singleton;
@@ -806,7 +806,7 @@ protected:
class Create_func_endpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_endpoint s_singleton;
@@ -821,7 +821,7 @@ protected:
class Create_func_envelope : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_envelope s_singleton;
@@ -836,7 +836,7 @@ protected:
class Create_func_equals : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_equals s_singleton;
@@ -850,7 +850,7 @@ protected:
class Create_func_exp : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exp s_singleton;
@@ -877,7 +877,7 @@ protected:
class Create_func_exteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exteriorring s_singleton;
@@ -904,7 +904,7 @@ protected:
class Create_func_find_in_set : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_find_in_set s_singleton;
@@ -917,7 +917,7 @@ protected:
class Create_func_floor : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_floor s_singleton;
@@ -930,7 +930,7 @@ protected:
class Create_func_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_format s_singleton;
@@ -943,7 +943,7 @@ protected:
class Create_func_found_rows : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_found_rows s_singleton;
@@ -956,7 +956,7 @@ protected:
class Create_func_from_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_from_days s_singleton;
@@ -1013,7 +1013,7 @@ protected:
class Create_func_geometry_type : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_geometry_type s_singleton;
@@ -1028,7 +1028,7 @@ protected:
class Create_func_geometryn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_geometryn s_singleton;
@@ -1042,7 +1042,7 @@ protected:
class Create_func_get_lock : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_get_lock s_singleton;
@@ -1056,7 +1056,7 @@ protected:
class Create_func_glength : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_glength s_singleton;
@@ -1083,7 +1083,7 @@ protected:
class Create_func_hex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_hex s_singleton;
@@ -1096,7 +1096,7 @@ protected:
class Create_func_ifnull : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_ifnull s_singleton;
@@ -1109,7 +1109,7 @@ protected:
class Create_func_inet_ntoa : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_ntoa s_singleton;
@@ -1122,7 +1122,7 @@ protected:
class Create_func_inet_aton : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_aton s_singleton;
@@ -1135,7 +1135,7 @@ protected:
class Create_func_instr : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_instr s_singleton;
@@ -1149,7 +1149,7 @@ protected:
class Create_func_interiorringn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_interiorringn s_singleton;
@@ -1164,7 +1164,7 @@ protected:
class Create_func_intersects : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_intersects s_singleton;
@@ -1178,7 +1178,7 @@ protected:
class Create_func_is_free_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_free_lock s_singleton;
@@ -1191,7 +1191,7 @@ protected:
class Create_func_is_used_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_used_lock s_singleton;
@@ -1205,7 +1205,7 @@ protected:
class Create_func_isclosed : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isclosed s_singleton;
@@ -1220,7 +1220,7 @@ protected:
class Create_func_isempty : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isempty s_singleton;
@@ -1234,7 +1234,7 @@ protected:
class Create_func_isnull : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isnull s_singleton;
@@ -1248,7 +1248,7 @@ protected:
class Create_func_issimple : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_issimple s_singleton;
@@ -1262,7 +1262,7 @@ protected:
class Create_func_last_day : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_last_day s_singleton;
@@ -1288,7 +1288,7 @@ protected:
class Create_func_lcase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_lcase s_singleton;
@@ -1314,7 +1314,7 @@ protected:
class Create_func_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_length s_singleton;
@@ -1327,7 +1327,7 @@ protected:
class Create_func_ln : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ln s_singleton;
@@ -1340,7 +1340,7 @@ protected:
class Create_func_load_file : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_load_file s_singleton;
@@ -1379,7 +1379,7 @@ protected:
class Create_func_log10 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log10 s_singleton;
@@ -1392,7 +1392,7 @@ protected:
class Create_func_log2 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log2 s_singleton;
@@ -1405,7 +1405,7 @@ protected:
class Create_func_lpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_lpad s_singleton;
@@ -1418,7 +1418,7 @@ protected:
class Create_func_ltrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ltrim s_singleton;
@@ -1431,7 +1431,7 @@ protected:
class Create_func_makedate : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_makedate s_singleton;
@@ -1444,7 +1444,7 @@ protected:
class Create_func_maketime : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_maketime s_singleton;
@@ -1483,7 +1483,7 @@ protected:
class Create_func_md5 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_md5 s_singleton;
@@ -1496,7 +1496,7 @@ protected:
class Create_func_monthname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_monthname s_singleton;
@@ -1509,7 +1509,7 @@ protected:
class Create_func_name_const : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_name_const s_singleton;
@@ -1522,7 +1522,7 @@ protected:
class Create_func_nullif : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_nullif s_singleton;
@@ -1536,7 +1536,7 @@ protected:
class Create_func_numgeometries : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numgeometries s_singleton;
@@ -1551,7 +1551,7 @@ protected:
class Create_func_numinteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numinteriorring s_singleton;
@@ -1566,7 +1566,7 @@ protected:
class Create_func_numpoints : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numpoints s_singleton;
@@ -1580,7 +1580,7 @@ protected:
class Create_func_oct : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_oct s_singleton;
@@ -1593,7 +1593,7 @@ protected:
class Create_func_ord : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ord s_singleton;
@@ -1607,7 +1607,7 @@ protected:
class Create_func_overlaps : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_overlaps s_singleton;
@@ -1621,7 +1621,7 @@ protected:
class Create_func_period_add : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_add s_singleton;
@@ -1634,7 +1634,7 @@ protected:
class Create_func_period_diff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_diff s_singleton;
@@ -1647,7 +1647,7 @@ protected:
class Create_func_pi : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_pi s_singleton;
@@ -1661,7 +1661,7 @@ protected:
class Create_func_pointn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pointn s_singleton;
@@ -1675,7 +1675,7 @@ protected:
class Create_func_pow : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pow s_singleton;
@@ -1688,7 +1688,7 @@ protected:
class Create_func_quote : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_quote s_singleton;
@@ -1701,7 +1701,7 @@ protected:
class Create_func_radians : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_radians s_singleton;
@@ -1727,7 +1727,7 @@ protected:
class Create_func_release_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_release_lock s_singleton;
@@ -1740,7 +1740,7 @@ protected:
class Create_func_reverse : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_reverse s_singleton;
@@ -1766,7 +1766,7 @@ protected:
class Create_func_row_count : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_row_count s_singleton;
@@ -1779,7 +1779,7 @@ protected:
class Create_func_rpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_rpad s_singleton;
@@ -1792,7 +1792,7 @@ protected:
class Create_func_rtrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_rtrim s_singleton;
@@ -1805,7 +1805,7 @@ protected:
class Create_func_sec_to_time : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sec_to_time s_singleton;
@@ -1818,7 +1818,7 @@ protected:
class Create_func_sha : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sha s_singleton;
@@ -1831,7 +1831,7 @@ protected:
class Create_func_sign : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sign s_singleton;
@@ -1844,7 +1844,7 @@ protected:
class Create_func_sin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sin s_singleton;
@@ -1857,7 +1857,7 @@ protected:
class Create_func_sleep : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sleep s_singleton;
@@ -1870,7 +1870,7 @@ protected:
class Create_func_soundex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_soundex s_singleton;
@@ -1883,7 +1883,7 @@ protected:
class Create_func_space : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_space s_singleton;
@@ -1896,7 +1896,7 @@ protected:
class Create_func_sqrt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sqrt s_singleton;
@@ -1910,7 +1910,7 @@ protected:
class Create_func_srid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_srid s_singleton;
@@ -1925,7 +1925,7 @@ protected:
class Create_func_startpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_startpoint s_singleton;
@@ -1939,7 +1939,7 @@ protected:
class Create_func_str_to_date : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_str_to_date s_singleton;
@@ -1952,7 +1952,7 @@ protected:
class Create_func_strcmp : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_strcmp s_singleton;
@@ -1965,7 +1965,7 @@ protected:
class Create_func_substr_index : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_substr_index s_singleton;
@@ -1978,7 +1978,7 @@ protected:
class Create_func_subtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_subtime s_singleton;
@@ -1991,7 +1991,7 @@ protected:
class Create_func_tan : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_tan s_singleton;
@@ -2004,7 +2004,7 @@ protected:
class Create_func_time_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_time_format s_singleton;
@@ -2017,7 +2017,7 @@ protected:
class Create_func_time_to_sec : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_time_to_sec s_singleton;
@@ -2030,7 +2030,7 @@ protected:
class Create_func_timediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_timediff s_singleton;
@@ -2043,7 +2043,7 @@ protected:
class Create_func_to_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_to_days s_singleton;
@@ -2057,7 +2057,7 @@ protected:
class Create_func_touches : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_touches s_singleton;
@@ -2071,7 +2071,7 @@ protected:
class Create_func_ucase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ucase s_singleton;
@@ -2084,7 +2084,7 @@ protected:
class Create_func_uncompress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompress s_singleton;
@@ -2097,7 +2097,7 @@ protected:
class Create_func_uncompressed_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompressed_length s_singleton;
@@ -2110,7 +2110,7 @@ protected:
class Create_func_unhex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_unhex s_singleton;
@@ -2136,7 +2136,7 @@ protected:
class Create_func_uuid : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid s_singleton;
@@ -2149,7 +2149,7 @@ protected:
class Create_func_uuid_short : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid_short s_singleton;
@@ -2162,7 +2162,7 @@ protected:
class Create_func_version : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_version s_singleton;
@@ -2175,7 +2175,7 @@ protected:
class Create_func_weekday : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekday s_singleton;
@@ -2188,7 +2188,7 @@ protected:
class Create_func_weekofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekofyear s_singleton;
@@ -2202,7 +2202,7 @@ protected:
class Create_func_within : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_within s_singleton;
@@ -2217,7 +2217,7 @@ protected:
class Create_func_x : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_x s_singleton;
@@ -2231,7 +2231,7 @@ protected:
class Create_func_xml_extractvalue : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_xml_extractvalue s_singleton;
@@ -2244,7 +2244,7 @@ protected:
class Create_func_xml_update : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_xml_update s_singleton;
@@ -2258,7 +2258,7 @@ protected:
class Create_func_y : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_y s_singleton;
@@ -2353,7 +2353,7 @@ Create_qfunc::create(THD *thd, LEX_STRIN
if (thd->lex->copy_db_to(&db.str, &db.length))
return NULL;
- return create(thd, db, name, false, item_list);
+ return create_with_db(thd, db, name, false, item_list);
}
@@ -2470,8 +2470,8 @@ Create_udf_func::create(THD *thd, udf_fu
Create_sp_func Create_sp_func::s_singleton;
Item*
-Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list)
+Create_sp_func::create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list)
{
int arg_count= 0;
Item *func= NULL;
@@ -2538,7 +2538,7 @@ Create_func_arg0::create(THD *thd, LEX_S
return NULL;
}
- return create(thd);
+ return create_builder(thd);
}
@@ -2564,7 +2564,7 @@ Create_func_arg1::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1);
+ return create_1_arg(thd, param_1);
}
@@ -2592,7 +2592,7 @@ Create_func_arg2::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2);
+ return create_2_arg(thd, param_1, param_2);
}
@@ -2622,14 +2622,14 @@ Create_func_arg3::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2, param_3);
+ return create_3_arg(thd, param_1, param_2, param_3);
}
Create_func_abs Create_func_abs::s_singleton;
Item*
-Create_func_abs::create(THD *thd, Item *arg1)
+Create_func_abs::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_abs(arg1);
}
@@ -2638,7 +2638,7 @@ Create_func_abs::create(THD *thd, Item *
Create_func_acos Create_func_acos::s_singleton;
Item*
-Create_func_acos::create(THD *thd, Item *arg1)
+Create_func_acos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_acos(arg1);
}
@@ -2647,7 +2647,7 @@ Create_func_acos::create(THD *thd, Item
Create_func_addtime Create_func_addtime::s_singleton;
Item*
-Create_func_addtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_addtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 0);
}
@@ -2656,7 +2656,7 @@ Create_func_addtime::create(THD *thd, It
Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton;
Item*
-Create_func_aes_encrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_encrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_encrypt(arg1, arg2);
}
@@ -2665,7 +2665,7 @@ Create_func_aes_encrypt::create(THD *thd
Create_func_aes_decrypt Create_func_aes_decrypt::s_singleton;
Item*
-Create_func_aes_decrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_decrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_decrypt(arg1, arg2);
}
@@ -2675,7 +2675,7 @@ Create_func_aes_decrypt::create(THD *thd
Create_func_area Create_func_area::s_singleton;
Item*
-Create_func_area::create(THD *thd, Item *arg1)
+Create_func_area::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_area(arg1);
}
@@ -2686,7 +2686,7 @@ Create_func_area::create(THD *thd, Item
Create_func_as_wkb Create_func_as_wkb::s_singleton;
Item*
-Create_func_as_wkb::create(THD *thd, Item *arg1)
+Create_func_as_wkb::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkb(arg1);
}
@@ -2697,7 +2697,7 @@ Create_func_as_wkb::create(THD *thd, Ite
Create_func_as_wkt Create_func_as_wkt::s_singleton;
Item*
-Create_func_as_wkt::create(THD *thd, Item *arg1)
+Create_func_as_wkt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkt(arg1);
}
@@ -2707,7 +2707,7 @@ Create_func_as_wkt::create(THD *thd, Ite
Create_func_asin Create_func_asin::s_singleton;
Item*
-Create_func_asin::create(THD *thd, Item *arg1)
+Create_func_asin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_asin(arg1);
}
@@ -2753,7 +2753,7 @@ Create_func_atan::create_native(THD *thd
Create_func_benchmark Create_func_benchmark::s_singleton;
Item*
-Create_func_benchmark::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_benchmark::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_benchmark(arg1, arg2);
@@ -2763,7 +2763,7 @@ Create_func_benchmark::create(THD *thd,
Create_func_bin Create_func_bin::s_singleton;
Item*
-Create_func_bin::create(THD *thd, Item *arg1)
+Create_func_bin::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i2= new (thd->mem_root) Item_int((int32) 2,1);
@@ -2774,7 +2774,7 @@ Create_func_bin::create(THD *thd, Item *
Create_func_bit_count Create_func_bit_count::s_singleton;
Item*
-Create_func_bit_count::create(THD *thd, Item *arg1)
+Create_func_bit_count::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_count(arg1);
}
@@ -2783,7 +2783,7 @@ Create_func_bit_count::create(THD *thd,
Create_func_bit_length Create_func_bit_length::s_singleton;
Item*
-Create_func_bit_length::create(THD *thd, Item *arg1)
+Create_func_bit_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_length(arg1);
}
@@ -2792,7 +2792,7 @@ Create_func_bit_length::create(THD *thd,
Create_func_ceiling Create_func_ceiling::s_singleton;
Item*
-Create_func_ceiling::create(THD *thd, Item *arg1)
+Create_func_ceiling::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ceiling(arg1);
}
@@ -2802,7 +2802,7 @@ Create_func_ceiling::create(THD *thd, It
Create_func_centroid Create_func_centroid::s_singleton;
Item*
-Create_func_centroid::create(THD *thd, Item *arg1)
+Create_func_centroid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_centroid(arg1);
}
@@ -2812,7 +2812,7 @@ Create_func_centroid::create(THD *thd, I
Create_func_char_length Create_func_char_length::s_singleton;
Item*
-Create_func_char_length::create(THD *thd, Item *arg1)
+Create_func_char_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_char_length(arg1);
}
@@ -2821,7 +2821,7 @@ Create_func_char_length::create(THD *thd
Create_func_coercibility Create_func_coercibility::s_singleton;
Item*
-Create_func_coercibility::create(THD *thd, Item *arg1)
+Create_func_coercibility::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_coercibility(arg1);
}
@@ -2873,7 +2873,7 @@ Create_func_concat_ws::create_native(THD
Create_func_compress Create_func_compress::s_singleton;
Item*
-Create_func_compress::create(THD *thd, Item *arg1)
+Create_func_compress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_compress(arg1);
}
@@ -2882,7 +2882,7 @@ Create_func_compress::create(THD *thd, I
Create_func_connection_id Create_func_connection_id::s_singleton;
Item*
-Create_func_connection_id::create(THD *thd)
+Create_func_connection_id::create_builder(THD *thd)
{
thd->lex->safe_to_cache_query= 0;
return new (thd->mem_root) Item_func_connection_id();
@@ -2893,7 +2893,7 @@ Create_func_connection_id::create(THD *t
Create_func_contains Create_func_contains::s_singleton;
Item*
-Create_func_contains::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_contains::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CONTAINS_FUNC);
@@ -2904,7 +2904,7 @@ Create_func_contains::create(THD *thd, I
Create_func_conv Create_func_conv::s_singleton;
Item*
-Create_func_conv::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_conv::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_conv(arg1, arg2, arg3);
}
@@ -2913,7 +2913,7 @@ Create_func_conv::create(THD *thd, Item
Create_func_convert_tz Create_func_convert_tz::s_singleton;
Item*
-Create_func_convert_tz::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_convert_tz::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_convert_tz(arg1, arg2, arg3);
}
@@ -2922,7 +2922,7 @@ Create_func_convert_tz::create(THD *thd,
Create_func_cos Create_func_cos::s_singleton;
Item*
-Create_func_cos::create(THD *thd, Item *arg1)
+Create_func_cos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_cos(arg1);
}
@@ -2931,7 +2931,7 @@ Create_func_cos::create(THD *thd, Item *
Create_func_cot Create_func_cot::s_singleton;
Item*
-Create_func_cot::create(THD *thd, Item *arg1)
+Create_func_cot::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "1", 1, 1);
Item *i2= new (thd->mem_root) Item_func_tan(arg1);
@@ -2942,7 +2942,7 @@ Create_func_cot::create(THD *thd, Item *
Create_func_crc32 Create_func_crc32::s_singleton;
Item*
-Create_func_crc32::create(THD *thd, Item *arg1)
+Create_func_crc32::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_crc32(arg1);
}
@@ -2952,7 +2952,7 @@ Create_func_crc32::create(THD *thd, Item
Create_func_crosses Create_func_crosses::s_singleton;
Item*
-Create_func_crosses::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_crosses::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CROSSES_FUNC);
@@ -2963,7 +2963,7 @@ Create_func_crosses::create(THD *thd, It
Create_func_date_format Create_func_date_format::s_singleton;
Item*
-Create_func_date_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_date_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 0);
}
@@ -2972,7 +2972,7 @@ Create_func_date_format::create(THD *thd
Create_func_datediff Create_func_datediff::s_singleton;
Item*
-Create_func_datediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_datediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
Item *i1= new (thd->mem_root) Item_func_to_days(arg1);
Item *i2= new (thd->mem_root) Item_func_to_days(arg2);
@@ -2984,7 +2984,7 @@ Create_func_datediff::create(THD *thd, I
Create_func_dayname Create_func_dayname::s_singleton;
Item*
-Create_func_dayname::create(THD *thd, Item *arg1)
+Create_func_dayname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayname(arg1);
}
@@ -2993,7 +2993,7 @@ Create_func_dayname::create(THD *thd, It
Create_func_dayofmonth Create_func_dayofmonth::s_singleton;
Item*
-Create_func_dayofmonth::create(THD *thd, Item *arg1)
+Create_func_dayofmonth::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofmonth(arg1);
}
@@ -3002,7 +3002,7 @@ Create_func_dayofmonth::create(THD *thd,
Create_func_dayofweek Create_func_dayofweek::s_singleton;
Item*
-Create_func_dayofweek::create(THD *thd, Item *arg1)
+Create_func_dayofweek::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 1);
}
@@ -3011,7 +3011,7 @@ Create_func_dayofweek::create(THD *thd,
Create_func_dayofyear Create_func_dayofyear::s_singleton;
Item*
-Create_func_dayofyear::create(THD *thd, Item *arg1)
+Create_func_dayofyear::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofyear(arg1);
}
@@ -3020,7 +3020,7 @@ Create_func_dayofyear::create(THD *thd,
Create_func_decode Create_func_decode::s_singleton;
Item*
-Create_func_decode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_decode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_decode(arg1, arg2);
}
@@ -3029,7 +3029,7 @@ Create_func_decode::create(THD *thd, Ite
Create_func_degrees Create_func_degrees::s_singleton;
Item*
-Create_func_degrees::create(THD *thd, Item *arg1)
+Create_func_degrees::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "degrees", arg1,
180/M_PI, 0.0);
@@ -3114,7 +3114,7 @@ Create_func_des_encrypt::create_native(T
Create_func_dimension Create_func_dimension::s_singleton;
Item*
-Create_func_dimension::create(THD *thd, Item *arg1)
+Create_func_dimension::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dimension(arg1);
}
@@ -3125,7 +3125,7 @@ Create_func_dimension::create(THD *thd,
Create_func_disjoint Create_func_disjoint::s_singleton;
Item*
-Create_func_disjoint::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_disjoint::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_DISJOINT_FUNC);
@@ -3157,7 +3157,7 @@ Create_func_elt::create_native(THD *thd,
Create_func_encode Create_func_encode::s_singleton;
Item*
-Create_func_encode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_encode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_encode(arg1, arg2);
}
@@ -3205,7 +3205,7 @@ Create_func_encrypt::create_native(THD *
Create_func_endpoint Create_func_endpoint::s_singleton;
Item*
-Create_func_endpoint::create(THD *thd, Item *arg1)
+Create_func_endpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_ENDPOINT);
@@ -3217,7 +3217,7 @@ Create_func_endpoint::create(THD *thd, I
Create_func_envelope Create_func_envelope::s_singleton;
Item*
-Create_func_envelope::create(THD *thd, Item *arg1)
+Create_func_envelope::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_envelope(arg1);
}
@@ -3228,7 +3228,7 @@ Create_func_envelope::create(THD *thd, I
Create_func_equals Create_func_equals::s_singleton;
Item*
-Create_func_equals::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_equals::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_EQUALS_FUNC);
@@ -3239,7 +3239,7 @@ Create_func_equals::create(THD *thd, Ite
Create_func_exp Create_func_exp::s_singleton;
Item*
-Create_func_exp::create(THD *thd, Item *arg1)
+Create_func_exp::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_exp(arg1);
}
@@ -3302,7 +3302,7 @@ Create_func_export_set::create_native(TH
Create_func_exteriorring Create_func_exteriorring::s_singleton;
Item*
-Create_func_exteriorring::create(THD *thd, Item *arg1)
+Create_func_exteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_EXTERIORRING);
@@ -3334,7 +3334,7 @@ Create_func_field::create_native(THD *th
Create_func_find_in_set Create_func_find_in_set::s_singleton;
Item*
-Create_func_find_in_set::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_find_in_set::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_find_in_set(arg1, arg2);
}
@@ -3343,7 +3343,7 @@ Create_func_find_in_set::create(THD *thd
Create_func_floor Create_func_floor::s_singleton;
Item*
-Create_func_floor::create(THD *thd, Item *arg1)
+Create_func_floor::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_floor(arg1);
}
@@ -3352,7 +3352,7 @@ Create_func_floor::create(THD *thd, Item
Create_func_format Create_func_format::s_singleton;
Item*
-Create_func_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_format(arg1, arg2);
}
@@ -3361,7 +3361,7 @@ Create_func_format::create(THD *thd, Ite
Create_func_found_rows Create_func_found_rows::s_singleton;
Item*
-Create_func_found_rows::create(THD *thd)
+Create_func_found_rows::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -3372,7 +3372,7 @@ Create_func_found_rows::create(THD *thd)
Create_func_from_days Create_func_from_days::s_singleton;
Item*
-Create_func_from_days::create(THD *thd, Item *arg1)
+Create_func_from_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_from_days(arg1);
}
@@ -3500,7 +3500,7 @@ Create_func_geometry_from_wkb::create_na
Create_func_geometry_type Create_func_geometry_type::s_singleton;
Item*
-Create_func_geometry_type::create(THD *thd, Item *arg1)
+Create_func_geometry_type::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_geometry_type(arg1);
}
@@ -3511,7 +3511,7 @@ Create_func_geometry_type::create(THD *t
Create_func_geometryn Create_func_geometryn::s_singleton;
Item*
-Create_func_geometryn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_geometryn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_GEOMETRYN);
@@ -3522,7 +3522,7 @@ Create_func_geometryn::create(THD *thd,
Create_func_get_lock Create_func_get_lock::s_singleton;
Item*
-Create_func_get_lock::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_get_lock::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3534,7 +3534,7 @@ Create_func_get_lock::create(THD *thd, I
Create_func_glength Create_func_glength::s_singleton;
Item*
-Create_func_glength::create(THD *thd, Item *arg1)
+Create_func_glength::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_glength(arg1);
}
@@ -3565,7 +3565,7 @@ Create_func_greatest::create_native(THD
Create_func_hex Create_func_hex::s_singleton;
Item*
-Create_func_hex::create(THD *thd, Item *arg1)
+Create_func_hex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_hex(arg1);
}
@@ -3574,7 +3574,7 @@ Create_func_hex::create(THD *thd, Item *
Create_func_ifnull Create_func_ifnull::s_singleton;
Item*
-Create_func_ifnull::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_ifnull::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_ifnull(arg1, arg2);
}
@@ -3583,7 +3583,7 @@ Create_func_ifnull::create(THD *thd, Ite
Create_func_inet_ntoa Create_func_inet_ntoa::s_singleton;
Item*
-Create_func_inet_ntoa::create(THD *thd, Item *arg1)
+Create_func_inet_ntoa::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_ntoa(arg1);
}
@@ -3592,7 +3592,7 @@ Create_func_inet_ntoa::create(THD *thd,
Create_func_inet_aton Create_func_inet_aton::s_singleton;
Item*
-Create_func_inet_aton::create(THD *thd, Item *arg1)
+Create_func_inet_aton::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_aton(arg1);
}
@@ -3601,7 +3601,7 @@ Create_func_inet_aton::create(THD *thd,
Create_func_instr Create_func_instr::s_singleton;
Item*
-Create_func_instr::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_instr::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_locate(arg1, arg2);
}
@@ -3611,7 +3611,7 @@ Create_func_instr::create(THD *thd, Item
Create_func_interiorringn Create_func_interiorringn::s_singleton;
Item*
-Create_func_interiorringn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_interiorringn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_INTERIORRINGN);
@@ -3623,7 +3623,7 @@ Create_func_interiorringn::create(THD *t
Create_func_intersects Create_func_intersects::s_singleton;
Item*
-Create_func_intersects::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_intersects::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_INTERSECTS_FUNC);
@@ -3634,7 +3634,7 @@ Create_func_intersects::create(THD *thd,
Create_func_is_free_lock Create_func_is_free_lock::s_singleton;
Item*
-Create_func_is_free_lock::create(THD *thd, Item *arg1)
+Create_func_is_free_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3645,7 +3645,7 @@ Create_func_is_free_lock::create(THD *th
Create_func_is_used_lock Create_func_is_used_lock::s_singleton;
Item*
-Create_func_is_used_lock::create(THD *thd, Item *arg1)
+Create_func_is_used_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3657,7 +3657,7 @@ Create_func_is_used_lock::create(THD *th
Create_func_isclosed Create_func_isclosed::s_singleton;
Item*
-Create_func_isclosed::create(THD *thd, Item *arg1)
+Create_func_isclosed::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isclosed(arg1);
}
@@ -3668,7 +3668,7 @@ Create_func_isclosed::create(THD *thd, I
Create_func_isempty Create_func_isempty::s_singleton;
Item*
-Create_func_isempty::create(THD *thd, Item *arg1)
+Create_func_isempty::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isempty(arg1);
}
@@ -3678,7 +3678,7 @@ Create_func_isempty::create(THD *thd, It
Create_func_isnull Create_func_isnull::s_singleton;
Item*
-Create_func_isnull::create(THD *thd, Item *arg1)
+Create_func_isnull::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isnull(arg1);
}
@@ -3688,7 +3688,7 @@ Create_func_isnull::create(THD *thd, Ite
Create_func_issimple Create_func_issimple::s_singleton;
Item*
-Create_func_issimple::create(THD *thd, Item *arg1)
+Create_func_issimple::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_issimple(arg1);
}
@@ -3698,7 +3698,7 @@ Create_func_issimple::create(THD *thd, I
Create_func_last_day Create_func_last_day::s_singleton;
Item*
-Create_func_last_day::create(THD *thd, Item *arg1)
+Create_func_last_day::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_last_day(arg1);
}
@@ -3744,7 +3744,7 @@ Create_func_last_insert_id::create_nativ
Create_func_lcase Create_func_lcase::s_singleton;
Item*
-Create_func_lcase::create(THD *thd, Item *arg1)
+Create_func_lcase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_lcase(arg1);
}
@@ -3774,7 +3774,7 @@ Create_func_least::create_native(THD *th
Create_func_length Create_func_length::s_singleton;
Item*
-Create_func_length::create(THD *thd, Item *arg1)
+Create_func_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_length(arg1);
}
@@ -3783,7 +3783,7 @@ Create_func_length::create(THD *thd, Ite
Create_func_ln Create_func_ln::s_singleton;
Item*
-Create_func_ln::create(THD *thd, Item *arg1)
+Create_func_ln::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ln(arg1);
}
@@ -3792,7 +3792,7 @@ Create_func_ln::create(THD *thd, Item *a
Create_func_load_file Create_func_load_file::s_singleton;
Item*
-Create_func_load_file::create(THD *thd, Item *arg1)
+Create_func_load_file::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3881,7 +3881,7 @@ Create_func_log::create_native(THD *thd,
Create_func_log10 Create_func_log10::s_singleton;
Item*
-Create_func_log10::create(THD *thd, Item *arg1)
+Create_func_log10::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log10(arg1);
}
@@ -3890,7 +3890,7 @@ Create_func_log10::create(THD *thd, Item
Create_func_log2 Create_func_log2::s_singleton;
Item*
-Create_func_log2::create(THD *thd, Item *arg1)
+Create_func_log2::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log2(arg1);
}
@@ -3899,7 +3899,7 @@ Create_func_log2::create(THD *thd, Item
Create_func_lpad Create_func_lpad::s_singleton;
Item*
-Create_func_lpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_lpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_lpad(arg1, arg2, arg3);
}
@@ -3908,7 +3908,7 @@ Create_func_lpad::create(THD *thd, Item
Create_func_ltrim Create_func_ltrim::s_singleton;
Item*
-Create_func_ltrim::create(THD *thd, Item *arg1)
+Create_func_ltrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ltrim(arg1);
}
@@ -3917,7 +3917,7 @@ Create_func_ltrim::create(THD *thd, Item
Create_func_makedate Create_func_makedate::s_singleton;
Item*
-Create_func_makedate::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_makedate::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_makedate(arg1, arg2);
}
@@ -3926,7 +3926,7 @@ Create_func_makedate::create(THD *thd, I
Create_func_maketime Create_func_maketime::s_singleton;
Item*
-Create_func_maketime::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_maketime::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_maketime(arg1, arg2, arg3);
}
@@ -4001,7 +4001,7 @@ Create_func_master_pos_wait::create_nati
Create_func_md5 Create_func_md5::s_singleton;
Item*
-Create_func_md5::create(THD *thd, Item *arg1)
+Create_func_md5::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_md5(arg1);
}
@@ -4010,7 +4010,7 @@ Create_func_md5::create(THD *thd, Item *
Create_func_monthname Create_func_monthname::s_singleton;
Item*
-Create_func_monthname::create(THD *thd, Item *arg1)
+Create_func_monthname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_monthname(arg1);
}
@@ -4019,7 +4019,7 @@ Create_func_monthname::create(THD *thd,
Create_func_name_const Create_func_name_const::s_singleton;
Item*
-Create_func_name_const::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_name_const::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_name_const(arg1, arg2);
}
@@ -4028,7 +4028,7 @@ Create_func_name_const::create(THD *thd,
Create_func_nullif Create_func_nullif::s_singleton;
Item*
-Create_func_nullif::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_nullif::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_nullif(arg1, arg2);
}
@@ -4038,7 +4038,7 @@ Create_func_nullif::create(THD *thd, Ite
Create_func_numgeometries Create_func_numgeometries::s_singleton;
Item*
-Create_func_numgeometries::create(THD *thd, Item *arg1)
+Create_func_numgeometries::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numgeometries(arg1);
}
@@ -4049,7 +4049,7 @@ Create_func_numgeometries::create(THD *t
Create_func_numinteriorring Create_func_numinteriorring::s_singleton;
Item*
-Create_func_numinteriorring::create(THD *thd, Item *arg1)
+Create_func_numinteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numinteriorring(arg1);
}
@@ -4060,7 +4060,7 @@ Create_func_numinteriorring::create(THD
Create_func_numpoints Create_func_numpoints::s_singleton;
Item*
-Create_func_numpoints::create(THD *thd, Item *arg1)
+Create_func_numpoints::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numpoints(arg1);
}
@@ -4070,7 +4070,7 @@ Create_func_numpoints::create(THD *thd,
Create_func_oct Create_func_oct::s_singleton;
Item*
-Create_func_oct::create(THD *thd, Item *arg1)
+Create_func_oct::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i8= new (thd->mem_root) Item_int((int32) 8,1);
@@ -4081,7 +4081,7 @@ Create_func_oct::create(THD *thd, Item *
Create_func_ord Create_func_ord::s_singleton;
Item*
-Create_func_ord::create(THD *thd, Item *arg1)
+Create_func_ord::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ord(arg1);
}
@@ -4091,7 +4091,7 @@ Create_func_ord::create(THD *thd, Item *
Create_func_overlaps Create_func_overlaps::s_singleton;
Item*
-Create_func_overlaps::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_overlaps::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_OVERLAPS_FUNC);
@@ -4102,7 +4102,7 @@ Create_func_overlaps::create(THD *thd, I
Create_func_period_add Create_func_period_add::s_singleton;
Item*
-Create_func_period_add::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_add::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_add(arg1, arg2);
}
@@ -4111,7 +4111,7 @@ Create_func_period_add::create(THD *thd,
Create_func_period_diff Create_func_period_diff::s_singleton;
Item*
-Create_func_period_diff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_diff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_diff(arg1, arg2);
}
@@ -4120,7 +4120,7 @@ Create_func_period_diff::create(THD *thd
Create_func_pi Create_func_pi::s_singleton;
Item*
-Create_func_pi::create(THD *thd)
+Create_func_pi::create_builder(THD *thd)
{
return new (thd->mem_root) Item_static_float_func("pi()", M_PI, 6, 8);
}
@@ -4130,7 +4130,7 @@ Create_func_pi::create(THD *thd)
Create_func_pointn Create_func_pointn::s_singleton;
Item*
-Create_func_pointn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pointn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_POINTN);
@@ -4141,7 +4141,7 @@ Create_func_pointn::create(THD *thd, Ite
Create_func_pow Create_func_pow::s_singleton;
Item*
-Create_func_pow::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pow::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_pow(arg1, arg2);
}
@@ -4150,7 +4150,7 @@ Create_func_pow::create(THD *thd, Item *
Create_func_quote Create_func_quote::s_singleton;
Item*
-Create_func_quote::create(THD *thd, Item *arg1)
+Create_func_quote::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_quote(arg1);
}
@@ -4159,7 +4159,7 @@ Create_func_quote::create(THD *thd, Item
Create_func_radians Create_func_radians::s_singleton;
Item*
-Create_func_radians::create(THD *thd, Item *arg1)
+Create_func_radians::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "radians", arg1,
M_PI/180, 0.0);
@@ -4216,7 +4216,7 @@ Create_func_rand::create_native(THD *thd
Create_func_release_lock Create_func_release_lock::s_singleton;
Item*
-Create_func_release_lock::create(THD *thd, Item *arg1)
+Create_func_release_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4227,7 +4227,7 @@ Create_func_release_lock::create(THD *th
Create_func_reverse Create_func_reverse::s_singleton;
Item*
-Create_func_reverse::create(THD *thd, Item *arg1)
+Create_func_reverse::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_reverse(arg1);
}
@@ -4274,7 +4274,7 @@ Create_func_round::create_native(THD *th
Create_func_row_count Create_func_row_count::s_singleton;
Item*
-Create_func_row_count::create(THD *thd)
+Create_func_row_count::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4285,7 +4285,7 @@ Create_func_row_count::create(THD *thd)
Create_func_rpad Create_func_rpad::s_singleton;
Item*
-Create_func_rpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_rpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_rpad(arg1, arg2, arg3);
}
@@ -4294,7 +4294,7 @@ Create_func_rpad::create(THD *thd, Item
Create_func_rtrim Create_func_rtrim::s_singleton;
Item*
-Create_func_rtrim::create(THD *thd, Item *arg1)
+Create_func_rtrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_rtrim(arg1);
}
@@ -4303,7 +4303,7 @@ Create_func_rtrim::create(THD *thd, Item
Create_func_sec_to_time Create_func_sec_to_time::s_singleton;
Item*
-Create_func_sec_to_time::create(THD *thd, Item *arg1)
+Create_func_sec_to_time::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sec_to_time(arg1);
}
@@ -4312,7 +4312,7 @@ Create_func_sec_to_time::create(THD *thd
Create_func_sha Create_func_sha::s_singleton;
Item*
-Create_func_sha::create(THD *thd, Item *arg1)
+Create_func_sha::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sha(arg1);
}
@@ -4321,7 +4321,7 @@ Create_func_sha::create(THD *thd, Item *
Create_func_sign Create_func_sign::s_singleton;
Item*
-Create_func_sign::create(THD *thd, Item *arg1)
+Create_func_sign::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sign(arg1);
}
@@ -4330,7 +4330,7 @@ Create_func_sign::create(THD *thd, Item
Create_func_sin Create_func_sin::s_singleton;
Item*
-Create_func_sin::create(THD *thd, Item *arg1)
+Create_func_sin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sin(arg1);
}
@@ -4339,7 +4339,7 @@ Create_func_sin::create(THD *thd, Item *
Create_func_sleep Create_func_sleep::s_singleton;
Item*
-Create_func_sleep::create(THD *thd, Item *arg1)
+Create_func_sleep::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4350,7 +4350,7 @@ Create_func_sleep::create(THD *thd, Item
Create_func_soundex Create_func_soundex::s_singleton;
Item*
-Create_func_soundex::create(THD *thd, Item *arg1)
+Create_func_soundex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_soundex(arg1);
}
@@ -4359,7 +4359,7 @@ Create_func_soundex::create(THD *thd, It
Create_func_space Create_func_space::s_singleton;
Item*
-Create_func_space::create(THD *thd, Item *arg1)
+Create_func_space::create_1_arg(THD *thd, Item *arg1)
{
/**
TODO: Fix Bug#23637
@@ -4387,7 +4387,7 @@ Create_func_space::create(THD *thd, Item
Create_func_sqrt Create_func_sqrt::s_singleton;
Item*
-Create_func_sqrt::create(THD *thd, Item *arg1)
+Create_func_sqrt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sqrt(arg1);
}
@@ -4397,7 +4397,7 @@ Create_func_sqrt::create(THD *thd, Item
Create_func_srid Create_func_srid::s_singleton;
Item*
-Create_func_srid::create(THD *thd, Item *arg1)
+Create_func_srid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_srid(arg1);
}
@@ -4408,7 +4408,7 @@ Create_func_srid::create(THD *thd, Item
Create_func_startpoint Create_func_startpoint::s_singleton;
Item*
-Create_func_startpoint::create(THD *thd, Item *arg1)
+Create_func_startpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_STARTPOINT);
@@ -4419,7 +4419,7 @@ Create_func_startpoint::create(THD *thd,
Create_func_str_to_date Create_func_str_to_date::s_singleton;
Item*
-Create_func_str_to_date::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_str_to_date::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_str_to_date(arg1, arg2);
}
@@ -4428,7 +4428,7 @@ Create_func_str_to_date::create(THD *thd
Create_func_strcmp Create_func_strcmp::s_singleton;
Item*
-Create_func_strcmp::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_strcmp::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_strcmp(arg1, arg2);
}
@@ -4437,7 +4437,7 @@ Create_func_strcmp::create(THD *thd, Ite
Create_func_substr_index Create_func_substr_index::s_singleton;
Item*
-Create_func_substr_index::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_substr_index::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_substr_index(arg1, arg2, arg3);
}
@@ -4446,7 +4446,7 @@ Create_func_substr_index::create(THD *th
Create_func_subtime Create_func_subtime::s_singleton;
Item*
-Create_func_subtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_subtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 1);
}
@@ -4455,7 +4455,7 @@ Create_func_subtime::create(THD *thd, It
Create_func_tan Create_func_tan::s_singleton;
Item*
-Create_func_tan::create(THD *thd, Item *arg1)
+Create_func_tan::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_tan(arg1);
}
@@ -4464,7 +4464,7 @@ Create_func_tan::create(THD *thd, Item *
Create_func_time_format Create_func_time_format::s_singleton;
Item*
-Create_func_time_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_time_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 1);
}
@@ -4473,7 +4473,7 @@ Create_func_time_format::create(THD *thd
Create_func_time_to_sec Create_func_time_to_sec::s_singleton;
Item*
-Create_func_time_to_sec::create(THD *thd, Item *arg1)
+Create_func_time_to_sec::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_time_to_sec(arg1);
}
@@ -4482,7 +4482,7 @@ Create_func_time_to_sec::create(THD *thd
Create_func_timediff Create_func_timediff::s_singleton;
Item*
-Create_func_timediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_timediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_timediff(arg1, arg2);
}
@@ -4491,7 +4491,7 @@ Create_func_timediff::create(THD *thd, I
Create_func_to_days Create_func_to_days::s_singleton;
Item*
-Create_func_to_days::create(THD *thd, Item *arg1)
+Create_func_to_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_to_days(arg1);
}
@@ -4501,7 +4501,7 @@ Create_func_to_days::create(THD *thd, It
Create_func_touches Create_func_touches::s_singleton;
Item*
-Create_func_touches::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_touches::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_TOUCHES_FUNC);
@@ -4512,7 +4512,7 @@ Create_func_touches::create(THD *thd, It
Create_func_ucase Create_func_ucase::s_singleton;
Item*
-Create_func_ucase::create(THD *thd, Item *arg1)
+Create_func_ucase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ucase(arg1);
}
@@ -4521,7 +4521,7 @@ Create_func_ucase::create(THD *thd, Item
Create_func_uncompress Create_func_uncompress::s_singleton;
Item*
-Create_func_uncompress::create(THD *thd, Item *arg1)
+Create_func_uncompress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompress(arg1);
}
@@ -4530,7 +4530,7 @@ Create_func_uncompress::create(THD *thd,
Create_func_uncompressed_length Create_func_uncompressed_length::s_singleton;
Item*
-Create_func_uncompressed_length::create(THD *thd, Item *arg1)
+Create_func_uncompressed_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompressed_length(arg1);
}
@@ -4539,7 +4539,7 @@ Create_func_uncompressed_length::create(
Create_func_unhex Create_func_unhex::s_singleton;
Item*
-Create_func_unhex::create(THD *thd, Item *arg1)
+Create_func_unhex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_unhex(arg1);
}
@@ -4584,7 +4584,7 @@ Create_func_unix_timestamp::create_nativ
Create_func_uuid Create_func_uuid::s_singleton;
Item*
-Create_func_uuid::create(THD *thd)
+Create_func_uuid::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4595,7 +4595,7 @@ Create_func_uuid::create(THD *thd)
Create_func_uuid_short Create_func_uuid_short::s_singleton;
Item*
-Create_func_uuid_short::create(THD *thd)
+Create_func_uuid_short::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4606,7 +4606,7 @@ Create_func_uuid_short::create(THD *thd)
Create_func_version Create_func_version::s_singleton;
Item*
-Create_func_version::create(THD *thd)
+Create_func_version::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
return new (thd->mem_root) Item_static_string_func("version()",
@@ -4620,7 +4620,7 @@ Create_func_version::create(THD *thd)
Create_func_weekday Create_func_weekday::s_singleton;
Item*
-Create_func_weekday::create(THD *thd, Item *arg1)
+Create_func_weekday::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 0);
}
@@ -4629,7 +4629,7 @@ Create_func_weekday::create(THD *thd, It
Create_func_weekofyear Create_func_weekofyear::s_singleton;
Item*
-Create_func_weekofyear::create(THD *thd, Item *arg1)
+Create_func_weekofyear::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "0", 3, 1);
return new (thd->mem_root) Item_func_week(arg1, i1);
@@ -4640,7 +4640,7 @@ Create_func_weekofyear::create(THD *thd,
Create_func_within Create_func_within::s_singleton;
Item*
-Create_func_within::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_within::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_WITHIN_FUNC);
@@ -4652,7 +4652,7 @@ Create_func_within::create(THD *thd, Ite
Create_func_x Create_func_x::s_singleton;
Item*
-Create_func_x::create(THD *thd, Item *arg1)
+Create_func_x::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_x(arg1);
}
@@ -4662,7 +4662,7 @@ Create_func_x::create(THD *thd, Item *ar
Create_func_xml_extractvalue Create_func_xml_extractvalue::s_singleton;
Item*
-Create_func_xml_extractvalue::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_xml_extractvalue::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_xml_extractvalue(arg1, arg2);
}
@@ -4671,7 +4671,7 @@ Create_func_xml_extractvalue::create(THD
Create_func_xml_update Create_func_xml_update::s_singleton;
Item*
-Create_func_xml_update::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_xml_update::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_xml_update(arg1, arg2, arg3);
}
@@ -4681,7 +4681,7 @@ Create_func_xml_update::create(THD *thd,
Create_func_y Create_func_y::s_singleton;
Item*
-Create_func_y::create(THD *thd, Item *arg1)
+Create_func_y::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_y(arg1);
}
=== modified file 'sql/item_create.h'
--- a/sql/item_create.h 2007-08-15 13:43:08 +0000
+++ b/sql/item_create.h 2010-03-28 18:10:00 +0000
@@ -91,8 +91,9 @@ public:
@param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call
*/
- virtual Item* create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list) = 0;
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name,
+ List<Item> *item_list) = 0;
protected:
/** Constructor. */
=== modified file 'sql/item_sum.cc'
--- a/sql/item_sum.cc 2010-01-15 15:27:55 +0000
+++ b/sql/item_sum.cc 2010-03-28 18:10:00 +0000
@@ -642,7 +642,7 @@ Item_sum_hybrid::fix_fields(THD *thd, It
default:
DBUG_ASSERT(0);
};
- setup(args[0], NULL);
+ setup_item(args[0], NULL);
/* MIN/MAX can return NULL for empty set indepedent of the used column */
maybe_null= 1;
unsigned_flag=item->unsigned_flag;
@@ -676,7 +676,7 @@ Item_sum_hybrid::fix_fields(THD *thd, It
of the original MIN/MAX object and it is saved in this object's cache.
*/
-void Item_sum_hybrid::setup(Item *item, Item *value_arg)
+void Item_sum_hybrid::setup_item(Item *item, Item *value_arg)
{
value= Item_cache::get_cache(item);
value->setup(item);
@@ -1646,7 +1646,7 @@ void Item_sum_hybrid::no_rows_in_result(
Item *Item_sum_min::copy_or_same(THD* thd)
{
Item_sum_min *item= new (thd->mem_root) Item_sum_min(thd, this);
- item->setup(args[0], value);
+ item->setup_item(args[0], value);
return item;
}
@@ -1669,7 +1669,7 @@ bool Item_sum_min::add()
Item *Item_sum_max::copy_or_same(THD* thd)
{
Item_sum_max *item= new (thd->mem_root) Item_sum_max(thd, this);
- item->setup(args[0], value);
+ item->setup_item(args[0], value);
return item;
}
=== modified file 'sql/item_sum.h'
--- a/sql/item_sum.h 2010-01-15 15:27:55 +0000
+++ b/sql/item_sum.h 2010-03-28 18:10:00 +0000
@@ -858,7 +858,7 @@ protected:
was_values(item->was_values)
{ }
bool fix_fields(THD *, Item **);
- void setup(Item *item, Item *value_arg);
+ void setup_item(Item *item, Item *value_arg);
void clear();
double val_real();
longlong val_int();
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-03-04 08:03:07 +0000
+++ b/sql/log.cc 2010-03-24 22:12:39 +0000
@@ -5387,7 +5387,7 @@ int TC_LOG_MMAP::open(const char *opt_na
pg->state=POOL;
pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST);
pthread_cond_init (&pg->cond, 0);
- pg->start=(my_xid *)(data + i*tc_log_page_size);
+ pg->ptr= pg->start=(my_xid *)(data + i*tc_log_page_size);
pg->size=pg->free=tc_log_page_size/sizeof(my_xid);
pg->end=pg->start + pg->size;
}
@@ -5622,7 +5622,15 @@ int TC_LOG_MMAP::sync()
/* marking 'syncing' slot free */
pthread_mutex_lock(&LOCK_sync);
syncing=0;
- pthread_cond_signal(&active->cond); // wake up a new syncer
+ /*
+ we check the "active" pointer without LOCK_active. Still, it's safe -
+ "active" can change from NULL to not NULL any time, but it
+ will take LOCK_sync before waiting on active->cond. That is, it can never
+ miss a signal.
+ And "active" can change to NULL only after LOCK_sync, so this is safe too.
+ */
+ if (active)
+ pthread_cond_signal(&active->cond); // wake up a new syncer
pthread_mutex_unlock(&LOCK_sync);
return err;
}
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-09 19:31:28 +0000
+++ b/sql/mysqld.cc 2010-03-30 16:48:41 +0000
@@ -8323,6 +8323,8 @@ mysqld_get_one_option(int optid,
case (int) OPT_INIT_RPL_ROLE:
{
int role;
+ LINT_INIT(role);
+
if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role))
{
rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
@@ -8378,6 +8380,8 @@ mysqld_get_one_option(int optid,
case OPT_BINLOG_FORMAT:
{
int id;
+ LINT_INIT(id);
+
if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id))
{
global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
@@ -8628,6 +8632,8 @@ mysqld_get_one_option(int optid,
else
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type))
delay_key_write_options= (uint) type-1;
}
@@ -8639,6 +8645,8 @@ mysqld_get_one_option(int optid,
case OPT_TX_ISOLATION:
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type))
global_system_variables.tx_isolation= (type-1);
break;
@@ -8726,6 +8734,7 @@ mysqld_get_one_option(int optid,
ulong method_conv;
int method;
LINT_INIT(method_conv);
+ LINT_INIT(method);
myisam_stats_method_str= argument;
if (!find_opt_type(argument, &myisam_stats_method_typelib,
@@ -8788,6 +8797,7 @@ mysqld_get_one_option(int optid,
case OPT_THREAD_HANDLING:
{
int id;
+ LINT_INIT(id);
if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id))
global_system_variables.thread_handling= id - 1;
opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];
=== modified file 'sql/net_serv.cc'
--- a/sql/net_serv.cc 2010-02-23 12:04:58 +0000
+++ b/sql/net_serv.cc 2010-03-29 19:07:45 +0000
@@ -279,7 +279,7 @@ static int net_data_is_ready(my_socket s
@param clear_buffer if <> 0, then clear all data from comm buff
*/
-void net_clear(NET *net, my_bool clear_buffer)
+void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
size_t count;
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2010-03-09 19:23:30 +0000
+++ b/sql/set_var.cc 2010-03-28 18:10:00 +0000
@@ -1263,16 +1263,16 @@ uchar *sys_var_set::value_ptr(THD *thd,
void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
{
- slave_exec_mode_options= 0;
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ slave_exec_mode_options= (ULL(1) << SLAVE_EXEC_MODE_STRICT);
}
bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
{
bool rc= sys_var_set::check(thd, var);
if (!rc &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ test_all_bits(var->save_result.ulong_value,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
rc= true;
my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
@@ -1294,15 +1294,16 @@ void fix_slave_exec_mode(enum_var_type t
DBUG_ENTER("fix_slave_exec_mode");
compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT
> SLAVE_EXEC_MODE_LAST_BIT - 1);
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ if (test_all_bits(slave_exec_mode_options,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
sql_print_error("Ambiguous slave modes combination."
" STRICT will be used");
- bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT);
+ slave_exec_mode_options&= ~(ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT);
}
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ if (!(slave_exec_mode_options & (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT)))
+ slave_exec_mode_options|= (ULL(1)<< SLAVE_EXEC_MODE_STRICT);
DBUG_VOID_RETURN;
}
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-04 08:03:07 +0000
+++ b/sql/sql_class.h 2010-03-30 12:36:49 +0000
@@ -63,6 +63,7 @@ public:
bool report_error(THD *thd);
bool is_invalidated() const { return m_invalidated; }
void reset_reprepare_observer() { m_invalidated= FALSE; }
+ Reprepare_observer() {} /* Remove gcc warning */
private:
bool m_invalidated;
};
@@ -1107,6 +1108,7 @@ public:
/* Ignore error */
return TRUE;
}
+ Dummy_error_handler() {} /* Remove gcc warning */
};
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_delete.cc 2010-03-10 13:55:40 +0000
@@ -335,8 +335,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *
InnoDB it can fail in a FOREIGN KEY error or an
out-of-tablespace error.
*/
- error= 1;
- break;
+ if (!select_lex->no_error)
+ {
+ error= 1;
+ break;
+ }
}
}
else
=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_lex.cc 2010-03-10 10:32:14 +0000
@@ -1842,13 +1842,15 @@ void st_select_lex_unit::exclude_tree()
void st_select_lex::mark_as_dependent(st_select_lex *last, Item *dependency)
{
SELECT_LEX *next_to_last;
+
+ DBUG_ASSERT(this != last);
+
/*
Mark all selects from resolved to 1 before select where was
found table as depended (of select where was found table)
*/
- for (SELECT_LEX *s= this;
- s && s != last;
- s= s->outer_select())
+ SELECT_LEX *s= this;
+ do
{
if (!(s->uncacheable & UNCACHEABLE_DEPENDENT))
{
@@ -1866,7 +1868,8 @@ void st_select_lex::mark_as_dependent(st
}
}
next_to_last= s;
- }
+ } while ((s= s->outer_select()) != last && s != 0);
+
is_correlated= TRUE;
this->master_unit()->item->is_correlated= TRUE;
if (dependency)
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-03-09 19:23:30 +0000
+++ b/sql/sql_plugin.cc 2010-03-12 19:05:21 +0000
@@ -333,7 +333,7 @@ static inline void free_plugin_mem(struc
dlclose(p->handle);
#endif
my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR));
- if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION)
+ if (p->allocated)
my_free((uchar*)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
}
@@ -454,33 +454,37 @@ static st_plugin_dl *plugin_dl_add(const
#endif
}
- for (i= 0;
- ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- /* no op */;
-
- cur= (struct st_mysql_plugin*)
- my_malloc(i*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
- if (!cur)
+ if (sizeof_st_plugin != sizeof(st_mysql_plugin))
{
- free_plugin_mem(&plugin_dl);
- if (report & REPORT_TO_USER)
- my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
- if (report & REPORT_TO_LOG)
- sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
- DBUG_RETURN(0);
- }
- /*
- All st_plugin fields not initialized in the plugin explicitly, are
- set to 0. It matches C standard behaviour for struct initializers that
- have less values than the struct definition.
- */
- for (i=0;
- (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
+ for (i= 0;
+ ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_mysql_plugin*)
+ my_malloc((i+1)*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(&plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
+ DBUG_RETURN(0);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
- sym= cur;
+ sym= cur;
+ plugin_dl.allocated= true;
+ }
}
plugin_dl.plugins= (struct st_mysql_plugin *)sym;
=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h 2010-03-08 13:57:32 +0000
+++ b/sql/sql_plugin.h 2010-03-12 19:05:21 +0000
@@ -63,7 +63,8 @@ struct st_plugin_dl
LEX_STRING dl;
void *handle;
struct st_mysql_plugin *plugins;
- int version;
+ int version;
+ bool allocated;
uint ref_count; /* number of plugins loaded from the library */
};
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_table.cc 2010-03-30 12:36:49 +0000
@@ -5668,6 +5668,10 @@ compare_tables(TABLE *table,
*/
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
uint db_options= 0; /* not used */
+
+ /* Set default value for return value (to ensure it's always set) */
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+
/* Create the prepared information. */
if (mysql_prepare_create_table(thd, create_info,
&tmp_alter_info,
@@ -5726,7 +5730,6 @@ compare_tables(TABLE *table,
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
{
DBUG_PRINT("info", ("Basic checks -> ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5756,7 +5759,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("NULL behaviour difference in field '%s' -> "
"ALTER_TABLE_DATA_CHANGED", new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5779,7 +5781,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED",
new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
// Clear indexed marker
@@ -5914,7 +5915,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("check_if_incompatible_data() -> "
"ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_view.cc 2010-03-30 12:36:49 +0000
@@ -1034,10 +1034,12 @@ bool mysql_make_view(THD *thd, File_pars
bool parse_status;
bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables);
-
DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
+ LINT_INIT(parse_status);
+ LINT_INIT(view_select);
+
if (table->view)
{
/*
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-03-04 08:03:07 +0000
+++ b/sql/sql_yacc.yy 2010-03-28 18:10:00 +0000
@@ -8082,7 +8082,7 @@ function_call_generic:
builder= find_qualified_function_builder(thd);
DBUG_ASSERT(builder);
- item= builder->create(thd, $1, $3, true, $5);
+ item= builder->create_with_db(thd, $1, $3, true, $5);
if (! ($$= item))
{
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2010-03-09 19:23:30 +0000
+++ b/sql/table.cc 2010-03-10 10:32:14 +0000
@@ -2053,6 +2053,8 @@ ulong get_form_pos(File file, uchar *hea
ulong ret_value=0;
DBUG_ENTER("get_form_pos");
+ LINT_INIT(buf);
+
names=uint2korr(head+8);
a_length=(names+2)*sizeof(char *); /* Room for two extra */
=== modified file 'storage/example/ha_example.h'
--- a/storage/example/ha_example.h 2007-08-13 13:11:25 +0000
+++ b/storage/example/ha_example.h 2010-03-28 18:10:00 +0000
@@ -155,7 +155,8 @@ public:
/** @brief
This method will never be called if you do not implement indexes.
*/
- virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
+ virtual double read_time(uint index, uint ranges, ha_rows rows)
+ { return (double) rows / 20.0+1; }
/*
Everything below are methods that we implement in ha_example.cc.
=== modified file 'storage/federatedx/ha_federatedx.cc'
--- a/storage/federatedx/ha_federatedx.cc 2009-12-03 11:34:11 +0000
+++ b/storage/federatedx/ha_federatedx.cc 2010-03-10 10:32:14 +0000
@@ -1783,7 +1783,7 @@ int ha_federatedx::open(const char *name
int ha_federatedx::close(void)
{
- int retval, error;
+ int retval= 0, error;
THD *thd= current_thd;
DBUG_ENTER("ha_federatedx::close");
=== modified file 'storage/maria/ma_delete.c'
--- a/storage/maria/ma_delete.c 2009-01-12 11:12:00 +0000
+++ b/storage/maria/ma_delete.c 2010-03-10 10:32:14 +0000
@@ -169,6 +169,8 @@ my_bool _ma_ck_delete(MARIA_HA *info, MA
MARIA_KEY org_key;
DBUG_ENTER("_ma_ck_delete");
+ LINT_INIT_STRUCT(org_key);
+
save_key_data= key->data;
if (share->now_transactional)
{
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2010-01-06 21:27:53 +0000
+++ b/storage/maria/ma_loghandler.c 2010-03-30 12:36:49 +0000
@@ -1211,6 +1211,8 @@ static my_bool translog_set_lsn_for_file
for (file= from_file; file <= to_file; file++)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT(info.max_lsn);
+
File fd= open_logfile_by_number_no_cache(file);
if ((fd < 0) ||
((translog_read_file_header(&info, fd) ||
@@ -1394,6 +1396,7 @@ LSN translog_get_file_max_lsn_stored(uin
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT_STRUCT(info);
File fd= open_logfile_by_number_no_cache(file);
if ((fd < 0) ||
(translog_read_file_header(&info, fd) | my_close(fd, MYF(MY_WME))))
@@ -3844,6 +3847,8 @@ my_bool translog_init_with_table(const c
if (!old_log_was_recovered && old_flags == flags)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT(info.maria_version);
+
/*
Accessing &log_descriptor.open_files without mutex is safe
because it is initialization
=== modified file 'storage/maria/ma_search.c'
--- a/storage/maria/ma_search.c 2010-03-09 19:22:24 +0000
+++ b/storage/maria/ma_search.c 2010-03-28 18:10:00 +0000
@@ -76,8 +76,8 @@ int _ma_search(register MARIA_HA *info,
bmove512(info->keyread_buff, page_buff, info->s->block_size);
/* Save position for a possible read next / previous */
- info->int_keypos= info->keyread_buff + (ulonglong) info->int_keypos;
- info->int_maxpos= info->keyread_buff + (ulonglong) info->int_maxpos;
+ info->int_keypos= info->keyread_buff + info->keypos_offset;
+ info->int_maxpos= info->keyread_buff + info->maxpos_offset;
info->int_keytree_version= key->keyinfo->version;
info->last_search_keypage= info->last_keypage;
info->page_changed= 0;
@@ -214,8 +214,8 @@ static int _ma_search_no_save(register M
info->cur_row.trid= _ma_trid_from_key(&info->last_key);
/* Store offset to key */
- info->int_keypos= (uchar*) (keypos - page.buff);
- info->int_maxpos= (uchar*) (maxpos - page.buff);
+ info->keypos_offset= (uint) (keypos - page.buff);
+ info->maxpos_offset= (uint) (maxpos - page.buff);
info->int_nod_flag= nod_flag;
info->last_keypage= pos;
*res_page_link= page_link;
=== modified file 'storage/maria/maria_def.h'
--- a/storage/maria/maria_def.h 2010-03-09 19:22:24 +0000
+++ b/storage/maria/maria_def.h 2010-03-28 18:10:00 +0000
@@ -506,8 +506,10 @@ struct st_maria_handler
uchar *first_mbr_key; /* Searhed spatial key */
uchar *rec_buff; /* Temp buffer for recordpack */
uchar *blob_buff; /* Temp buffer for blobs */
- uchar *int_keypos, /* Save position for next/previous */
- *int_maxpos; /* -""- */
+ uchar *int_keypos; /* Save position for next/previous */
+ uchar *int_maxpos; /* -""- */
+ uint keypos_offset; /* Tmp storage for offset int_keypos */
+ uint maxpos_offset; /* Tmp storage for offset int_maxpos */
uchar *update_field_data; /* Used by update in rows-in-block */
uint int_nod_flag; /* -""- */
uint32 int_keytree_version; /* -""- */
=== modified file 'storage/myisam/ft_stopwords.c'
--- a/storage/myisam/ft_stopwords.c 2010-01-28 14:49:14 +0000
+++ b/storage/myisam/ft_stopwords.c 2010-03-28 18:10:00 +0000
@@ -44,9 +44,10 @@ static void FT_STOPWORD_free(FT_STOPWORD
static int ft_add_stopword(const char *w)
{
FT_STOPWORD sw;
- return !w ||
- (((sw.len= (uint) strlen(sw.pos=w)) >= ft_min_word_len) &&
- (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL));
+ return (!w ||
+ (((sw.len= (uint) strlen((char*) (sw.pos=(const uchar *)w))) >=
+ ft_min_word_len) &&
+ (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL)));
}
int ft_init_stopwords()
=== modified file 'storage/myisam/mi_create.c'
--- a/storage/myisam/mi_create.c 2010-01-14 16:51:00 +0000
+++ b/storage/myisam/mi_create.c 2010-03-12 19:03:37 +0000
@@ -192,6 +192,13 @@ int mi_create(const char *name,uint keys
options|= HA_OPTION_CHECKSUM;
min_pack_length++;
}
+ /*
+ Don't set HA_OPTION_NULL_FIELDS if no checksums, as this flag makes
+ that file incompatible with MySQL. This is ok, as this flag is only
+ used if one specifics table level checksums.
+ */
+ if (!(options & HA_OPTION_CHECKSUM))
+ options&= ~HA_OPTION_NULL_FIELDS;
if (flags & HA_CREATE_DELAY_KEY_WRITE)
options|= HA_OPTION_DELAY_KEY_WRITE;
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
=== modified file 'storage/myisam/mi_write.c'
--- a/storage/myisam/mi_write.c 2009-12-03 11:19:05 +0000
+++ b/storage/myisam/mi_write.c 2010-03-10 10:32:14 +0000
@@ -735,10 +735,12 @@ static uchar *_mi_find_last_pos(MI_KEYDE
}
end=page+length-key_ref_length;
+ DBUG_ASSERT(page < end);
*key='\0';
length=0;
lastpos=page;
- while (page < end)
+
+ do
{
prevpos=lastpos; lastpos=page;
last_length=length;
@@ -749,7 +751,8 @@ static uchar *_mi_find_last_pos(MI_KEYDE
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0);
}
- }
+ } while (page < end);
+
*return_key_length=last_length;
*after_key=lastpos;
DBUG_PRINT("exit",("returns: 0x%lx page: 0x%lx end: 0x%lx",
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2010-03-04 08:03:07 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-03-30 12:36:49 +0000
@@ -382,7 +382,7 @@ static MI_INFO *myisammrg_attach_childre
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
}
DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d",
- my_errno ? NULL : (long) myisam, my_errno));
+ my_errno ? 0L : (long) myisam, my_errno));
err:
DBUG_RETURN(my_errno ? NULL : myisam);
=== modified file 'storage/myisammrg/myrg_open.c'
--- a/storage/myisammrg/myrg_open.c 2009-09-23 13:21:29 +0000
+++ b/storage/myisammrg/myrg_open.c 2010-03-30 12:36:49 +0000
@@ -239,6 +239,7 @@ MYRG_INFO *myrg_parent_open(const char *
rc= 1;
errpos= 0;
bzero((char*) &file_cache, sizeof(file_cache));
+ LINT_INIT(m_info);
/* Open MERGE meta file. */
if ((fd= my_open(fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT,
=== added directory 'storage/oqgraph'
=== added file 'storage/oqgraph/CMakeFiles.txt'
--- a/storage/oqgraph/CMakeFiles.txt 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/CMakeFiles.txt 2010-01-04 08:27:50 +0000
@@ -0,0 +1,22 @@
+# Copyright (C) 2006 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+ADD_LIBRARY(oqgraph ha_oqgraph.cc)
=== added file 'storage/oqgraph/Makefile.am'
--- a/storage/oqgraph/Makefile.am 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/Makefile.am 2010-01-04 08:27:50 +0000
@@ -0,0 +1,96 @@
+# Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+# ======================================================================
+# Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+# Mk.II implementation by Antony Curtis & Arjen Lentz
+# For more information, documentation, support, enhancement engineering,
+# and non-GPL licensing, see http://openquery.com/graph
+# or contact graph(a)openquery.com
+# For packaged binaries, see http://ourdelta.org
+# ======================================================================
+
+mysqlplugindir= $(pkglibdir)/plugin
+
+BOOST_CXXFLAGS = -frtti -fexceptions -fimplicit-templates
+#BOOST_CXXFLAGS+= -g
+#original flags before 2009-11-10
+#BOOST_CXXFLAGS+= -O3 -fomit-frame-pointer -fstrict-aliasing
+#BOOST_CXXFLAGS+= -momit-leaf-frame-pointer -falign-loops
+#modified flags:
+# - remove omit-frame-pointer, x86 specific (fails on PPC) + hinders debugging
+# Option details from gcc man:
+# Don't keep the frame pointer in a register for functions that don't need one.
+# This avoids the instructions to save, set up and restore frame pointers;
+# it also makes an extra register available in many functions.
+# It also makes debugging impossible on some machines.
+# (automatically gets enabled anyway by -O* on some architectures)
+BOOST_CXXFLAGS+= -O3 -fstrict-aliasing
+BOOST_CXXFLAGS+= -falign-loops
+BOOST_CXXFLAGS+= -fvisibility-inlines-hidden
+BOOST_CXXFLAGS+= -funroll-loops -fno-trapping-math
+
+EXTRA_DIST = ha_oqgraph.h ha_oqgraph.cc graphcore.cc \
+ graphcore-graph.h graphcore-types.h graphcore.h \
+ CMakeFiles.txt plug.in oqgraph_probes.d
+
+DTRACE = @DTRACE@
+DTRACEFLAGS = @DTRACEFLAGS@
+DTRACEFILES = .libs/liboqgraph_engine_la-ha_oqgraph.o
+
+ORIG_CXXFLAGS = @CXXFLAGS@
+CXXFLAGS=
+noinst_HEADERS = ha_oqgraph.h \
+ graphcore-graph.h graphcore-types.h graphcore.h \
+ oqgraph_probes.h
+
+noinst_LTLIBRARIES = libgraphcore.la
+libgraphcore_la_SOURCES = graphcore.cc
+libgraphcore_la_CXXFLAGS = $(ORIG_CXXFLAGS) $(BOOST_CXXFLAGS)
+
+if BUILD_OQGRAPH_FOR_MYSQL
+
+if BUILD_OQGRAPH_STANDALONE
+INCLUDES = -DDBUG_ON -DSAFE_MUTEX -DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX -DHAVE_OQGRAPH $(MYSQL_INC)
+else
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/regex -I$(top_srcdir)/sql -I$(srcdir) -DHAVE_OQGRAPH
+endif !BUILD_OQGRAPH_STANDALONE
+
+EXTRA_LTLIBRARIES = oqgraph_engine.la
+mysqlplugin_LTLIBRARIES = @plugin_oqgraph_shared_target@
+oqgraph_engine_la_SOURCES = ha_oqgraph.cc
+oqgraph_engine_la_LIBADD = libgraphcore.la
+
+if HAVE_DTRACE
+ oqgraph_engine_la_LIBADD += oqgraph_probes.o
+endif
+
+oqgraph_engine_la_LDFLAGS = -module -rpath $(mysqlplugindir)
+oqgraph_engine_la_CFLAGS = $(ORIG_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+oqgraph_engine_la_CXXFLAGS = $(ORIG_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+
+oqgraph_probes.h: oqgraph_probes.d
+ $(DTRACE) $(DTRACEFLAGS) -h -s oqgraph_probes.d
+ mv oqgraph_probes.h oqgraph_probes.h.bak
+ sed "s/#include <unistd.h>//g" oqgraph_probes.h.bak > oqgraph_probes.h
+ rm oqgraph_probes.h.bak
+
+oqgraph_probes.o:
+ $(DTRACE) $(DTRACEFLAGS) -G -s oqgraph_probes.d $(DTRACEFILES)
+
+endif BUILD_OQGRAPH_FOR_MYSQL
+
+# End
=== added file 'storage/oqgraph/README'
--- a/storage/oqgraph/README 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/README 2010-03-30 07:33:38 +0000
@@ -0,0 +1,16 @@
+OQGraph storage engine
+Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+The Open Query GRAPH engine (OQGRAPH) is a computation engine allowing
+hierarchies and more complex graph structures to be handled in a
+relational fashion. In a nutshell, tree structures and
+friend-of-a-friend style searches can now be done using standard SQL
+syntax, and results joined onto other tables.
+
+See http://openquery.com/graph for more information.
+
+
+INSTALLATION
+
+OQGraph requires at least version 1.40.0 of the Boost library. To
+obtain a copy of the Boost library, see http://www.boost.org/
=== added file 'storage/oqgraph/graphcore-graph.h'
--- a/storage/oqgraph/graphcore-graph.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphcore-graph.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,48 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifndef oq_graphcore_graph_h_
+#define oq_graphcore_graph_h_
+
+typedef adjacency_list
+<
+ vecS,
+ vecS,
+ bidirectionalS,
+ VertexInfo,
+ EdgeInfo
+> Graph;
+
+#define GRAPH_WEIGHTMAP(G) get(&EdgeInfo::weight, G)
+typedef property_map<Graph, EdgeWeight EdgeInfo::*>::type weightmap_type;
+
+#define GRAPH_INDEXMAP(G) get(vertex_index, G)
+typedef property_map<Graph, vertex_index_t>::type indexmap_type;
+
+#define GRAPH_IDMAP(G) get(&VertexInfo::id, G)
+typedef property_map<Graph, VertexID VertexInfo::*>::type idmap_type;
+
+#endif
=== added file 'storage/oqgraph/graphcore-types.h'
--- a/storage/oqgraph/graphcore-types.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphcore-types.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,36 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifndef oq_graphcore_types_h_
+#define oq_graphcore_types_h_
+namespace open_query
+{
+
+ typedef unsigned long long VertexID;
+ typedef double EdgeWeight;
+
+}
+#endif
=== added file 'storage/oqgraph/graphcore.cc'
--- a/storage/oqgraph/graphcore.cc 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphcore.cc 2010-03-30 07:33:38 +0000
@@ -0,0 +1,1099 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#include <strings.h>
+
+#define BOOST_ALL_NO_LIB 1
+
+#include <boost/config.hpp>
+
+#include <set>
+#include <stack>
+
+#include <boost/property_map/property_map.hpp>
+
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/graph_archetypes.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/reverse_graph.hpp>
+#include <boost/graph/graph_utility.hpp>
+
+#include "graphcore.h"
+
+using namespace open_query;
+using namespace boost;
+
+static const row empty_row = { 0 };
+
+namespace open_query
+{
+ enum vertex_id_t { vertex_id };
+
+ struct VertexInfo {
+ inline VertexInfo() { }
+
+ inline VertexInfo(VertexID _id)
+ : id(_id) { }
+
+ VertexID id;
+ };
+
+ struct EdgeInfo {
+ EdgeWeight weight;
+ };
+}
+
+namespace boost
+{
+ BOOST_INSTALL_PROPERTY(vertex, id);
+
+ namespace graph
+ {
+ template<>
+ struct internal_vertex_name<VertexInfo>
+ {
+ typedef multi_index::member<VertexInfo, VertexID, &VertexInfo::id> type;
+ };
+
+ template<>
+ struct internal_vertex_constructor<VertexInfo>
+ {
+ typedef vertex_from_name<VertexInfo> type;
+ };
+ }
+}
+
+namespace open_query
+{
+
+ #include "graphcore-graph.h"
+
+ typedef graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef graph_traits<Graph>::edge_descriptor Edge;
+
+ typedef std::list<std::pair<Vertex,optional<EdgeWeight> > > shortest_path_list;
+ typedef shortest_path_list::iterator shortest_path_iterator;
+
+ template<typename ID, typename IDMap>
+ class id_equals_t
+ {
+ public:
+ id_equals_t(ID id, IDMap map)
+ : m_id(id), m_map(map)
+ { }
+ template<typename V>
+ bool operator()(V u) const
+ {
+ return m_map[u] == m_id;
+ }
+ private:
+ ID m_id;
+ IDMap m_map;
+ };
+
+ template<typename ID, typename IDMap>
+ inline id_equals_t<ID,IDMap>
+ id_equals(ID id, IDMap idmap)
+ {
+ return id_equals_t<ID,IDMap>(id, idmap);
+ }
+
+ template<typename T, typename Graph>
+ class target_equals_t
+ {
+ public:
+ target_equals_t(T target, Graph &g)
+ : m_target(target), m_g(g)
+ { }
+ template<typename V>
+ bool operator()(V u) const
+ {
+ return target(u, m_g) == m_target;
+ }
+ private:
+ T m_target;
+ Graph &m_g;
+ };
+
+ template<typename T, typename Graph>
+ inline target_equals_t<T,Graph>
+ target_equals(T target, Graph &g)
+ {
+ return target_equals_t<T,Graph>(target, g);
+ }
+
+ template<typename T, typename Graph>
+ class source_equals_t
+ {
+ public:
+ source_equals_t(T source, Graph &g)
+ : m_source(source), m_g(g)
+ { }
+ template<typename V>
+ bool operator()(V u) const
+ {
+ return source(u, m_g) == m_source;
+ }
+ private:
+ T m_source;
+ Graph &m_g;
+ };
+
+ template<typename T, typename Graph>
+ inline source_equals_t<T,Graph>
+ source_equals(T source, Graph &g)
+ {
+ return source_equals_t<T,Graph>(source, g);
+ }
+
+ struct reference
+ {
+ int m_flags;
+ int m_sequence;
+ Vertex m_vertex;
+ Edge m_edge;
+ EdgeWeight m_weight;
+
+ enum
+ {
+ HAVE_SEQUENCE = 1,
+ HAVE_WEIGHT = 2,
+ HAVE_EDGE = 4,
+ };
+
+ inline reference()
+ : m_flags(0), m_sequence(0),
+ m_vertex(graph_traits<Graph>::null_vertex()),
+ m_edge(), m_weight(0)
+ { }
+
+ inline reference(int s, Edge e)
+ : m_flags(HAVE_SEQUENCE | HAVE_EDGE), m_sequence(s),
+ m_vertex(graph_traits<Graph>::null_vertex()),
+ m_edge(e), m_weight(0)
+ { }
+
+ inline reference(int s, Vertex v, const optional<Edge> &e,
+ const optional<EdgeWeight> &w)
+ : m_flags(HAVE_SEQUENCE | (w ? HAVE_WEIGHT : 0) | (e ? HAVE_EDGE : 0)),
+ m_sequence(s), m_vertex(v)
+ {
+ if (w) m_weight= *w;
+ if (e) m_edge= *e;
+ }
+
+ inline reference(int s, Vertex v, Edge e, EdgeWeight w)
+ : m_flags(HAVE_SEQUENCE | HAVE_WEIGHT | HAVE_EDGE),
+ m_sequence(s), m_vertex(v), m_edge(e), m_weight(w)
+ { }
+
+ inline reference(int s, Vertex v, EdgeWeight w)
+ : m_flags(HAVE_SEQUENCE | HAVE_WEIGHT),
+ m_sequence(s), m_vertex(v), m_edge(), m_weight(w)
+ { }
+
+ inline reference(int s, Vertex v)
+ : m_flags(HAVE_SEQUENCE), m_sequence(s), m_vertex(v), m_edge(),
+ m_weight(0)
+ { }
+
+ optional<int> sequence() const
+ {
+ if (m_flags & HAVE_SEQUENCE)
+ {
+ return m_sequence;
+ }
+ return optional<int>();
+ }
+
+ optional<Vertex> vertex() const
+ {
+ if (m_vertex != graph_traits<Graph>::null_vertex())
+ return m_vertex;
+ return optional<Vertex>();
+ }
+
+ optional<Edge> edge() const
+ {
+ if (m_flags & HAVE_EDGE)
+ return m_edge;
+ return optional<Edge>();
+ };
+
+ optional<EdgeWeight> weight() const
+ {
+ if (m_flags & HAVE_WEIGHT)
+ return m_weight;
+ return optional<EdgeWeight>();
+ }
+ };
+}
+
+namespace open_query {
+ class GRAPHCORE_INTERNAL oqgraph_share
+ {
+ public:
+ Graph g;
+
+ weightmap_type weightmap;
+ idmap_type idmap;
+ indexmap_type indexmap;
+
+ optional<Vertex> find_vertex(VertexID id) const;
+ optional<Edge> find_edge(Vertex, Vertex) const;
+
+ inline oqgraph_share() throw()
+ : g(),
+ weightmap(GRAPH_WEIGHTMAP(g)),
+ idmap(GRAPH_IDMAP(g)),
+ indexmap(GRAPH_INDEXMAP(g))
+ { }
+ inline ~oqgraph_share()
+ { }
+ };
+
+ class GRAPHCORE_INTERNAL oqgraph_cursor
+ {
+ public:
+ oqgraph_share *const share;
+
+ inline oqgraph_cursor(oqgraph_share *arg)
+ : share(arg)
+ { }
+ virtual ~oqgraph_cursor()
+ { }
+
+ virtual int fetch_row(const row &, row&) = 0;
+ virtual int fetch_row(const row &, row&, const reference&) = 0;
+ virtual void current(reference& ref) const = 0;
+ };
+}
+
+namespace open_query {
+ class GRAPHCORE_INTERNAL stack_cursor : public oqgraph_cursor
+ {
+ private:
+ optional<EdgeWeight> no_weight;
+ public:
+ int sequence;
+ std::stack<reference> results;
+ reference last;
+
+ inline stack_cursor(oqgraph_share *arg)
+ : oqgraph_cursor(arg), no_weight(), sequence(0), results(), last()
+ { }
+
+ int fetch_row(const row &, row&);
+ int fetch_row(const row &, row&, const reference&);
+
+ void current(reference& ref) const
+ {
+ ref= last;
+ }
+ };
+
+ class GRAPHCORE_INTERNAL vertices_cursor : public oqgraph_cursor
+ {
+ typedef graph_traits<Graph>::vertex_iterator vertex_iterator;
+
+ size_t position;
+ reference last;
+ public:
+ inline vertices_cursor(oqgraph_share *arg)
+ : oqgraph_cursor(arg), position(0)
+ { }
+
+ int fetch_row(const row &, row&);
+ int fetch_row(const row &, row&, const reference&);
+
+ void current(reference& ref) const
+ {
+ ref= last;
+ }
+
+ };
+
+ class GRAPHCORE_INTERNAL edges_cursor : public oqgraph_cursor
+ {
+ typedef graph_traits<Graph>::edge_iterator edge_iterator;
+ typedef edge_iterator::difference_type edge_difference;
+
+ edge_difference position;
+ reference last;
+ public:
+ inline edges_cursor(oqgraph_share *arg)
+ : oqgraph_cursor(arg), position(0), last()
+ { }
+
+ int fetch_row(const row &, row&);
+ int fetch_row(const row &, row&, const reference&);
+
+ void current(reference& ref) const
+ {
+ ref= last;
+ }
+ };
+
+ struct GRAPHCORE_INTERNAL oqgraph_visit_dist
+ : public base_visitor<oqgraph_visit_dist>
+ {
+ typedef on_finish_vertex event_filter;
+
+ oqgraph_visit_dist(std::vector<Vertex>::iterator p,
+ std::vector<EdgeWeight>::iterator d,
+ stack_cursor *cursor)
+ : seq(0), m_cursor(*cursor), m_p(p), m_d(d)
+ { assert(cursor); }
+
+ template<class T, class Graph>
+ void operator()(T u, Graph &g)
+ {
+ m_cursor.results.push(reference(++seq, u, m_d[GRAPH_INDEXMAP(g)[u]]));
+ }
+ private:
+ int seq;
+ stack_cursor &m_cursor;
+ std::vector<Vertex>::iterator m_p;
+ std::vector<EdgeWeight>::iterator m_d;
+ };
+
+ template<bool record_weight, typename goal_filter>
+ struct GRAPHCORE_INTERNAL oqgraph_goal
+ : public base_visitor<oqgraph_goal<record_weight,goal_filter> >
+ {
+ typedef goal_filter event_filter;
+
+ oqgraph_goal(Vertex goal, std::vector<Vertex>::iterator p,
+ stack_cursor *cursor)
+ : m_goal(goal), m_cursor(*cursor), m_p(p)
+ { assert(cursor); }
+
+ template<class T, class Graph>
+ void operator()(T u, Graph &g)
+ {
+ if (u == m_goal)
+ {
+ int seq= 0;
+ indexmap_type indexmap= GRAPH_INDEXMAP(g);
+
+ for (Vertex q, v= u;; v = q, seq++)
+ if ((q= m_p[ indexmap[v] ]) == v)
+ break;
+
+ for (Vertex v= u;; u= v)
+ {
+ optional<Edge> edge;
+ optional<EdgeWeight> weight;
+ v= m_p[ indexmap[u] ];
+ if (record_weight && u != v)
+ {
+ typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end)= out_edges(v, g); ei != ei_end; ++ei)
+ {
+ if (target(*ei, g) == u)
+ {
+ edge= *ei;
+ weight= GRAPH_WEIGHTMAP(g)[*ei];
+ break;
+ }
+ }
+ }
+ else if (u != v)
+ weight= 1;
+ m_cursor.results.push(reference(seq--, u, edge, weight));
+ if (u == v)
+ break;
+ }
+ throw this;
+ }
+ }
+
+ private:
+ Vertex m_goal;
+ stack_cursor &m_cursor;
+ std::vector<Vertex>::iterator m_p;
+ };
+}
+
+namespace open_query
+{
+ inline oqgraph::oqgraph(oqgraph_share *arg) throw()
+ : share(arg), cursor(0)
+ { }
+
+ inline oqgraph::~oqgraph() throw()
+ {
+ delete cursor;
+ }
+
+ unsigned oqgraph::edges_count() const throw()
+ {
+ return num_edges(share->g);
+ }
+
+ unsigned oqgraph::vertices_count() const throw()
+ {
+ return num_vertices(share->g);
+ }
+
+ oqgraph* oqgraph::create(oqgraph_share *share) throw()
+ {
+ assert(share != NULL);
+ return new (std::nothrow) oqgraph(share);
+ }
+
+ oqgraph_share* oqgraph::create() throw()
+ {
+ return new (std::nothrow) oqgraph_share();
+ }
+
+ optional<Edge>
+ oqgraph_share::find_edge(Vertex orig, Vertex dest) const
+ {
+ if (in_degree(dest, g) >= out_degree(orig, g))
+ {
+ graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ tie(ei, ei_end)= out_edges(orig, g);
+ if ((ei= find_if(ei, ei_end, target_equals(dest, g))) != ei_end)
+ return *ei;
+ }
+ else
+ {
+ graph_traits<Graph>::in_edge_iterator ei, ei_end;
+ tie(ei, ei_end)= in_edges(dest, g);
+ if ((ei= find_if(ei, ei_end, source_equals(orig, g))) != ei_end)
+ return *ei;
+ }
+ return optional<Edge>();
+ }
+
+ optional<Vertex>
+ oqgraph_share::find_vertex(VertexID id) const
+ {
+ return boost::graph::find_vertex(id, g);
+ }
+
+ int oqgraph::delete_all() throw()
+ {
+ share->g.clear();
+ return 0;
+ }
+
+ int oqgraph::insert_edge(
+ VertexID orig_id, VertexID dest_id, EdgeWeight weight, bool replace) throw()
+ {
+ optional<Vertex> orig, dest;
+ optional<Edge> edge;
+ bool inserted= 0;
+
+ if (weight < 0)
+ return INVALID_WEIGHT;
+ if (!(orig= share->find_vertex(orig_id)))
+ {
+ try
+ {
+ orig= add_vertex(VertexInfo(orig_id), share->g);
+ if (orig == graph_traits<Graph>::null_vertex())
+ return CANNOT_ADD_VERTEX;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_VERTEX;
+ }
+ }
+ if (!(dest= share->find_vertex(dest_id)))
+ {
+ try
+ {
+ dest= add_vertex(VertexInfo(dest_id), share->g);
+ if (dest == graph_traits<Graph>::null_vertex())
+ return CANNOT_ADD_VERTEX;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_VERTEX;
+ }
+ }
+ if (!(edge= share->find_edge(*orig, *dest)))
+ {
+ try
+ {
+ tie(edge, inserted)= add_edge(*orig, *dest, share->g);
+ if (!inserted)
+ return CANNOT_ADD_EDGE;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_EDGE;
+ }
+ }
+ else
+ {
+ if (!replace)
+ return DUPLICATE_EDGE;
+ }
+ share->weightmap[*edge]= weight;
+ return OK;
+ }
+
+ int oqgraph::delete_edge(current_row_st) throw()
+ {
+ reference ref;
+ if (cursor)
+ return EDGE_NOT_FOUND;
+ cursor->current(ref);
+ optional<Edge> edge;
+ if (!(edge= ref.edge()))
+ return EDGE_NOT_FOUND;
+ Vertex orig= source(*edge, share->g);
+ Vertex dest= target(*edge, share->g);
+ remove_edge(*edge, share->g);
+ if (!degree(orig, share->g))
+ remove_vertex(orig, share->g);
+ if (!degree(dest, share->g))
+ remove_vertex(dest, share->g);
+ return OK;
+ }
+
+ int oqgraph::modify_edge(current_row_st,
+ VertexID *orig_id, VertexID *dest_id, EdgeWeight *weight,
+ bool replace) throw()
+ {
+ if (!cursor)
+ return EDGE_NOT_FOUND;
+ reference ref;
+ cursor->current(ref);
+ optional<Edge> edge;
+ if (!(edge= ref.edge()))
+ return EDGE_NOT_FOUND;
+ if (weight && *weight < 0)
+ return INVALID_WEIGHT;
+
+ optional<Vertex> orig= source(*edge, share->g),
+ dest= target(*edge, share->g);
+
+ bool orig_neq= orig_id ? share->idmap[*orig] != *orig_id : 0;
+ bool dest_neq= dest_id ? share->idmap[*dest] != *dest_id : 0;
+ if (orig_neq || dest_neq)
+ {
+ optional<Edge> new_edge;
+ if (orig_neq && !(orig= share->find_vertex(*orig_id)))
+ {
+ try
+ {
+ orig= add_vertex(VertexInfo(*orig_id), share->g);
+ if (orig == graph_traits<Graph>::null_vertex())
+ return CANNOT_ADD_VERTEX;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_VERTEX;
+ }
+ }
+ if (dest_neq && !(dest= share->find_vertex(*dest_id)))
+ {
+ try
+ {
+ dest= add_vertex(VertexInfo(*dest_id), share->g);
+ if (dest == graph_traits<Graph>::null_vertex())
+ return CANNOT_ADD_VERTEX;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_VERTEX;
+ }
+ }
+ if (!(new_edge= share->find_edge(*orig, *dest)))
+ {
+ try
+ {
+ bool inserted;
+ tie(new_edge, inserted)= add_edge(*orig, *dest, share->g);
+ if (!inserted)
+ return CANNOT_ADD_EDGE;
+ }
+ catch (...)
+ {
+ return CANNOT_ADD_EDGE;
+ }
+ }
+ else
+ {
+ if (!replace)
+ return DUPLICATE_EDGE;
+ }
+ share->weightmap[*new_edge]= share->weightmap[*edge];
+ remove_edge(*edge, share->g);
+ edge= new_edge;
+ }
+ if (weight)
+ share->weightmap[*edge]= *weight;
+ return OK;
+ }
+
+ int oqgraph::modify_edge(
+ VertexID orig_id, VertexID dest_id, EdgeWeight weight) throw()
+ {
+ optional<Vertex> orig, dest;
+ optional<Edge> edge;
+
+ if (weight < 0)
+ return INVALID_WEIGHT;
+ if (!(orig= share->find_vertex(orig_id)))
+ return EDGE_NOT_FOUND;
+ if (!(dest= share->find_vertex(dest_id)))
+ return EDGE_NOT_FOUND;
+ if (!(edge= share->find_edge(*orig, *dest)))
+ return EDGE_NOT_FOUND;
+ share->weightmap[*edge]= weight;
+ return OK;
+ }
+
+
+ int oqgraph::delete_edge(VertexID orig_id, VertexID dest_id) throw()
+ {
+ optional<Vertex> orig, dest;
+ optional<Edge> edge;
+
+ if (!(orig= share->find_vertex(orig_id)))
+ return EDGE_NOT_FOUND;
+ if (!(dest= share->find_vertex(dest_id)))
+ return EDGE_NOT_FOUND;
+ if (!(edge= share->find_edge(*orig, *dest)))
+ return EDGE_NOT_FOUND;
+ remove_edge(*edge, share->g);
+ if (!degree(*orig, share->g))
+ remove_vertex(*orig, share->g);
+ if (!degree(*dest, share->g))
+ remove_vertex(*dest, share->g);
+ return OK;
+ }
+
+
+ int oqgraph::search(int *latch, VertexID *orig_id, VertexID *dest_id) throw()
+ {
+ optional<Vertex> orig, dest;
+ int op= 0, seq= 0;
+ enum {
+ NO_SEARCH = 0,
+ DIJKSTRAS = 1,
+ BREADTH_FIRST = 2,
+
+ ALGORITHM = 0x0ffff,
+ HAVE_ORIG = 0x10000,
+ HAVE_DEST = 0x20000,
+ };
+
+ delete cursor; cursor= 0;
+ row_info= empty_row;
+ if ((row_info.latch_indicator= latch))
+ op= ALGORITHM & (row_info.latch= *latch);
+ if ((row_info.orig_indicator= orig_id) && (op|= HAVE_ORIG))
+ orig= share->find_vertex((row_info.orig= *orig_id));
+ if ((row_info.dest_indicator= dest_id) && (op|= HAVE_DEST))
+ dest= share->find_vertex((row_info.dest= *dest_id));
+ //try
+ //{
+ switch (op)
+ {
+ case NO_SEARCH | HAVE_ORIG | HAVE_DEST:
+ case NO_SEARCH | HAVE_ORIG:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && orig)
+ {
+ graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end)= out_edges(*orig, share->g); ei != ei_end; ++ei)
+ {
+ Vertex v= target(*ei, share->g);
+ static_cast<stack_cursor*>(cursor)->
+ results.push(reference(++seq, v, *ei, share->weightmap[*ei]));
+ }
+ }
+ /* fall through */
+ case NO_SEARCH | HAVE_DEST:
+ if ((op & HAVE_DEST) &&
+ (cursor || (cursor= new (std::nothrow) stack_cursor(share))) &&
+ dest)
+ {
+ graph_traits<Graph>::in_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end)= in_edges(*dest, share->g); ei != ei_end; ++ei)
+ {
+ Vertex v= source(*ei, share->g);
+ static_cast<stack_cursor*>(cursor)->
+ results.push(reference(++seq, v, *ei, share->weightmap[*ei]));
+ }
+ }
+ break;
+
+ case NO_SEARCH:
+ cursor= new (std::nothrow) vertices_cursor(share);
+ break;
+
+ case DIJKSTRAS | HAVE_ORIG | HAVE_DEST:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && orig && dest)
+ {
+ std::vector<Vertex> p(num_vertices(share->g));
+ std::vector<EdgeWeight> d(num_vertices(share->g));
+ oqgraph_goal<true, on_finish_vertex>
+ vis(*dest, p.begin(), static_cast<stack_cursor*>(cursor));
+ p[share->indexmap[*orig]]= *orig;
+ try
+ {
+ dijkstra_shortest_paths(share->g, *orig,
+ weight_map(
+ share->weightmap
+ ).
+ distance_map(
+ make_iterator_property_map(d.begin(), share->indexmap)
+ ).
+ predecessor_map(
+ make_iterator_property_map(p.begin(), share->indexmap)
+ ).
+ visitor(
+ make_dijkstra_visitor(vis)
+ )
+ );
+ }
+ catch (...)
+ { /* printf("found\n"); */ }
+ }
+ break;
+
+ case BREADTH_FIRST | HAVE_ORIG | HAVE_DEST:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && orig && dest)
+ {
+ std::vector<Vertex> p(num_vertices(share->g));
+ oqgraph_goal<false, on_discover_vertex>
+ vis(*dest, p.begin(), static_cast<stack_cursor*>(cursor));
+ p[share->indexmap[*orig]]= *orig;
+ try
+ {
+ breadth_first_search(share->g, *orig,
+ visitor(make_bfs_visitor(
+ std::make_pair(
+ record_predecessors(
+ make_iterator_property_map(p.begin(), share->indexmap),
+ on_tree_edge()
+ ),
+ vis)
+ )
+ )
+ );
+ }
+ catch (...)
+ { /* printf("found\n"); */ }
+ }
+ break;
+
+ case DIJKSTRAS | HAVE_ORIG:
+ case BREADTH_FIRST | HAVE_ORIG:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && (orig || dest))
+ {
+ std::vector<Vertex> p(num_vertices(share->g));
+ std::vector<EdgeWeight> d(num_vertices(share->g));
+ oqgraph_visit_dist vis(p.begin(), d.begin(),
+ static_cast<stack_cursor*>(cursor));
+ p[share->indexmap[*orig]]= *orig;
+ switch (ALGORITHM & op)
+ {
+ case DIJKSTRAS:
+ dijkstra_shortest_paths(share->g, *orig,
+ weight_map(
+ share->weightmap
+ ).
+ distance_map(
+ make_iterator_property_map(d.begin(), share->indexmap)
+ ).
+ predecessor_map(
+ make_iterator_property_map(p.begin(), share->indexmap)
+ ).
+ visitor(
+ make_dijkstra_visitor(vis)
+ )
+ );
+ break;
+ case BREADTH_FIRST:
+ breadth_first_search(share->g, *orig,
+ visitor(make_bfs_visitor(
+ std::make_pair(
+ record_predecessors(
+ make_iterator_property_map(p.begin(),
+ share->indexmap),
+ on_tree_edge()
+ ),
+ std::make_pair(
+ record_distances(
+ make_iterator_property_map(d.begin(),
+ share->indexmap),
+ on_tree_edge()
+ ),
+ vis
+ ))
+ ))
+ );
+ break;
+ default:
+ abort();
+ }
+ }
+ break;
+
+ case BREADTH_FIRST | HAVE_DEST:
+ case DIJKSTRAS | HAVE_DEST:
+ if ((cursor= new (std::nothrow) stack_cursor(share)) && (orig || dest))
+ {
+ std::vector<Vertex> p(num_vertices(share->g));
+ std::vector<EdgeWeight> d(num_vertices(share->g));
+ oqgraph_visit_dist vis(p.begin(), d.begin(),
+ static_cast<stack_cursor*>(cursor));
+ reverse_graph<Graph> r(share->g);
+ p[share->indexmap[*dest]]= *dest;
+ switch (ALGORITHM & op)
+ {
+ case DIJKSTRAS:
+ dijkstra_shortest_paths(r, *dest,
+ weight_map(
+ share->weightmap
+ ).
+ distance_map(
+ make_iterator_property_map(d.begin(), share->indexmap)
+ ).
+ predecessor_map(
+ make_iterator_property_map(p.begin(), share->indexmap)
+ ).
+ visitor(
+ make_dijkstra_visitor(vis)
+ )
+ );
+ break;
+ case BREADTH_FIRST:
+ breadth_first_search(r, *dest,
+ visitor(make_bfs_visitor(
+ std::make_pair(
+ record_predecessors(
+ make_iterator_property_map(p.begin(),
+ share->indexmap),
+ on_tree_edge()
+ ),
+ std::make_pair(
+ record_distances(
+ make_iterator_property_map(d.begin(),
+ share->indexmap),
+ on_tree_edge()
+ ),
+ vis
+ ))
+ ))
+ );
+ break;
+ default:
+ abort();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+ //}
+ //catch (...)
+ //{
+ // return MISC_FAIL;
+ //}
+ }
+
+ int oqgraph::fetch_row(row& result) throw()
+ {
+ if (!cursor)
+ return NO_MORE_DATA;
+ return cursor->fetch_row(row_info, result);
+ }
+
+ int oqgraph::fetch_row(row& result, const void* ref_ptr) throw()
+ {
+ const reference &ref= *(const reference*) ref_ptr;
+ if (!cursor)
+ return NO_MORE_DATA;
+ return cursor->fetch_row(row_info, result, ref);
+ }
+
+ void oqgraph::row_ref(void *ref_ptr) throw()
+ {
+ reference &ref= *(reference*) ref_ptr;
+ if (cursor)
+ cursor->current(ref);
+ else
+ ref= reference();
+ }
+
+ int oqgraph::random(bool scan) throw()
+ {
+ if (scan || !cursor)
+ {
+ delete cursor; cursor= 0;
+ if (!(cursor= new (std::nothrow) edges_cursor(share)))
+ return MISC_FAIL;
+ }
+ row_info= empty_row;
+ return OK;
+ }
+
+ void oqgraph::free(oqgraph *graph) throw()
+ {
+ delete graph;
+ }
+
+ void oqgraph::free(oqgraph_share *graph) throw()
+ {
+ delete graph;
+ }
+
+ const size_t oqgraph::sizeof_ref= sizeof(reference);
+}
+
+int stack_cursor::fetch_row(const row &row_info, row &result)
+{
+ if (!results.empty())
+ {
+ if (int res= fetch_row(row_info, result, results.top()))
+ return res;
+ results.pop();
+ return oqgraph::OK;
+ }
+ else
+ {
+ last= reference();
+ return oqgraph::NO_MORE_DATA;
+ }
+}
+
+int stack_cursor::fetch_row(const row &row_info, row &result,
+ const reference &ref)
+{
+ last= ref;
+ if (optional<Vertex> v= last.vertex())
+ {
+ optional<int> seq;
+ optional<EdgeWeight> w;
+ optional<Vertex> v;
+ result= row_info;
+ if ((result.seq_indicator= seq= last.sequence()))
+ result.seq= *seq;
+ if ((result.link_indicator= v= last.vertex()))
+ result.link= share->idmap[*v];
+ if ((result.weight_indicator= w= last.weight()))
+ result.weight= *w;
+ return oqgraph::OK;
+ }
+ else
+ return oqgraph::NO_MORE_DATA;
+}
+
+
+int vertices_cursor::fetch_row(const row &row_info, row &result)
+{
+ vertex_iterator it, end;
+ reference ref;
+ size_t count= position;
+ for (tie(it, end)= vertices(share->g); count && it != end; ++it, --count);
+ if (it != end)
+ ref= reference(position+1, *it);
+ if (int res= fetch_row(row_info, result, ref))
+ return res;
+ position++;
+ return oqgraph::OK;
+}
+
+int vertices_cursor::fetch_row(const row &row_info, row &result,
+ const reference &ref)
+{
+ last= ref;
+ optional<Vertex> v= last.vertex();
+ result= row_info;
+ if (v)
+ {
+ result.link_indicator= 1;
+ result.link= share->idmap[*v];
+#ifdef DISPLAY_VERTEX_INFO
+ result.seq_indicator= 1;
+ if ((result.seq= degree(*v, share->g)))
+ {
+ EdgeWeight weight= 0;
+ graph_traits<Graph>::in_edge_iterator iei, iei_end;
+ for (tie(iei, iei_end)= in_edges(*v, share->g); iei != iei_end; ++iei)
+ weight+= share->weightmap[*iei];
+ graph_traits<Graph>::out_edge_iterator oei, oei_end;
+ for (tie(oei, oei_end)= out_edges(*v, share->g); oei != oei_end; ++oei)
+ weight+= share->weightmap[*oei];
+ result.weight_indicator= 1;
+ result.weight= weight / result.seq;
+ }
+#endif
+ return oqgraph::OK;
+ }
+ else
+ return oqgraph::NO_MORE_DATA;
+}
+
+int edges_cursor::fetch_row(const row &row_info, row &result)
+{
+ edge_iterator it, end;
+ reference ref;
+ size_t count= position;
+ for (tie(it, end)= edges(share->g); count && it != end; ++it, --count);
+ if (it != end)
+ ref= reference(position+1, *it);
+ if (int res= fetch_row(row_info, result, ref))
+ return res;
+ ++position;
+ return oqgraph::OK;
+}
+
+int edges_cursor::fetch_row(const row &row_info, row &result,
+ const reference &ref)
+{
+ optional<Edge> edge;
+ if ((edge= (last= ref).edge()))
+ {
+ result= row_info;
+ result.orig_indicator= result.dest_indicator= result.weight_indicator= 1;
+ result.orig= share->idmap[ source( *edge, share->g ) ];
+ result.dest= share->idmap[ target( *edge, share->g ) ];
+ result.weight= share->weightmap[ *edge ];
+ return oqgraph::OK;
+ }
+ return oqgraph::NO_MORE_DATA;
+}
+
+namespace boost {
+ GRAPHCORE_INTERNAL void throw_exception(std::exception const&)
+ {
+ abort();
+ }
+}
=== added file 'storage/oqgraph/graphcore.h'
--- a/storage/oqgraph/graphcore.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphcore.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,116 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifndef oq_graphcore_h_
+#define oq_graphcore_h_
+
+/* #define GRAPHCORE_INTERNAL __attribute__((visibility("hidden"))) */
+#define GRAPHCORE_INTERNAL
+
+#include "graphcore-types.h"
+
+namespace open_query
+{
+ class oqgraph_share;
+ class oqgraph_cursor;
+
+ struct row
+ {
+ bool latch_indicator;
+ bool orig_indicator;
+ bool dest_indicator;
+ bool weight_indicator;
+ bool seq_indicator;
+ bool link_indicator;
+
+ int latch;
+ VertexID orig;
+ VertexID dest;
+ EdgeWeight weight;
+ unsigned seq;
+ VertexID link;
+ };
+
+ class oqgraph
+ {
+ oqgraph_share *const share;
+ oqgraph_cursor *cursor;
+ row row_info;
+
+ inline oqgraph(oqgraph_share*) throw();
+ inline ~oqgraph() throw();
+ public:
+
+ enum error_code
+ {
+ OK= 0,
+ NO_MORE_DATA,
+ EDGE_NOT_FOUND,
+ INVALID_WEIGHT,
+ DUPLICATE_EDGE,
+ CANNOT_ADD_VERTEX,
+ CANNOT_ADD_EDGE,
+ MISC_FAIL
+ };
+
+ struct current_row_st {};
+ static inline current_row_st current_row()
+ { return current_row_st(); }
+
+ unsigned vertices_count() const throw();
+ unsigned edges_count() const throw();
+
+ int delete_all(void) throw();
+
+ int insert_edge(VertexID, VertexID, EdgeWeight, bool=0) throw();
+ int modify_edge(VertexID, VertexID, EdgeWeight) throw();
+ int delete_edge(VertexID, VertexID) throw();
+
+ int modify_edge(current_row_st,
+ VertexID*, VertexID*, EdgeWeight*, bool=0) throw();
+ int delete_edge(current_row_st) throw();
+
+ int replace_edge(VertexID orig, VertexID dest, EdgeWeight weight) throw()
+ { return insert_edge(orig, dest, weight, true); }
+
+ int search(int*, VertexID*, VertexID*) throw();
+ int random(bool) throw();
+
+ int fetch_row(row&) throw();
+ int fetch_row(row&, const void*) throw();
+ void row_ref(void*) throw();
+
+ static oqgraph* create(oqgraph_share*) throw();
+ static oqgraph_share *create() throw();
+
+ static void free(oqgraph*) throw();
+ static void free(oqgraph_share*) throw();
+
+ static const size_t sizeof_ref;
+ };
+
+}
+#endif
=== added file 'storage/oqgraph/graphstore.c'
--- a/storage/oqgraph/graphstore.c 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphstore.c 2010-01-04 08:27:50 +0000
@@ -0,0 +1,356 @@
+/*
+ * Graph Engine - Copyright (C) 2007 by Arjen Lentz (arjen(a)openquery.com.au)
+ * graphstore.c internal storage system
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <my_global.h>
+#include <my_sys.h>
+#include "graphstore.h"
+
+
+/*
+ create a new vertex, and add it to the list (or start a list)
+ NOTE! gspp is ptr to base ptr
+
+ returns 1 for ok, 0 for error
+*/
+static int _add_vertex (GRAPHSTORE **gspp, GRAPH_VERTEXID id)
+{
+ GRAPHSTORE *newgsp;
+ GRAPHSTORE *gscurp;
+
+ if (gspp == NULL)
+ return 0;
+
+ /* not allowing 0 */
+ if (!id)
+ return 0;
+
+ if (*gspp != NULL) {
+ for (gscurp = *gspp; gscurp != NULL; gscurp = gscurp->next) {
+ if (gscurp->vertex->id == id)
+ return 1; /* we can ignore, id already exists */
+ }
+ }
+
+ /* allocate and initialise */
+ if ((newgsp = my_malloc(sizeof (GRAPHSTORE),MYF(MY_ZEROFILL))) == NULL)
+ return 0;
+
+ if ((newgsp->vertex = my_malloc(sizeof (GRAPH_VERTEX),MYF(MY_ZEROFILL))) == NULL) {
+ my_free(newgsp,MYF(0));
+ return 0;
+ }
+
+ newgsp->vertex->id = id;
+ /* add new vertex to end of list */
+ if (*gspp != NULL) {
+ for (gscurp = *gspp; gscurp->next != NULL; gscurp = gscurp->next);
+ gscurp->next = newgsp;
+ }
+ else /* new list */
+ *gspp = newgsp;
+
+ /* ok */
+ return 1;
+}
+
+
+/*
+ find a vertex by id
+
+ returns ptr or NULL
+*/
+static GRAPH_VERTEX *_find_vertex (GRAPHSTORE *gsp, GRAPH_VERTEXID id)
+{
+ /* just loop through the list to find id */
+ while (gsp != NULL && gsp->vertex->id != id)
+ gsp = gsp->next;
+
+ /* return ptr to vertex, or NULL */
+ return (gsp != NULL ? gsp->vertex : NULL);
+}
+
+
+/*
+ add edge
+ both vertices must already exist; graphstore_insert() does this
+
+ return 1 for ok, 0 for error (already exists, alloc error, etc)
+*/
+static int _add_edge (GRAPHSTORE *gsp, GRAPH_VERTEXID origid, GRAPH_VERTEXID destid, GRAPH_WEIGHT weight)
+{
+ GRAPH_VERTEX *origvp, *destvp;
+ GRAPH_EDGE *ep, *newep;
+
+ /* find both vertices */
+ if ((origvp = _find_vertex(gsp,origid)) == NULL ||
+ (destvp = _find_vertex(gsp,destid)) == NULL)
+ return 0;
+
+ /* check if edge already exists */
+ for (ep = origvp->forward_edge; ep != NULL; ep = ep->next_edge) {
+ if (ep->vertex->id == destid)
+ return 0;
+ }
+
+ /* allocate and initialise new edge */
+ if ((newep = my_malloc(sizeof (GRAPH_EDGE),MYF(MY_ZEROFILL))) == NULL)
+ return 0;
+
+ newep->vertex = destvp;
+ newep->weight = weight;
+
+ /* insert new edge at start of chain, that's easiest */
+ ep = origvp->forward_edge;
+ origvp->forward_edge = newep;
+ newep->next_edge = ep;
+
+ /* ok */
+ return 1;
+}
+
+
+/*
+ create a new row, and add it to the graph set (or start set)
+ NOTE! gsetpp is ptr to base ptr
+
+ returns 1 for ok, 0 for error
+*/
+static int _add_graph_set (GRAPH_SET **gsetpp, GRAPH_TUPLE *gtp)
+{
+ GRAPH_SET *newgsetp;
+ GRAPH_SET *gsetcurp;
+
+ if (gsetpp == NULL || gtp == NULL)
+ return 0;
+
+ /* allocate and initialise */
+ if ((newgsetp = my_malloc(sizeof (GRAPH_SET),MYF(MY_ZEROFILL))) == NULL)
+ return 0;
+
+ /* put in the data */
+ memcpy(&newgsetp->tuple,gtp,sizeof (GRAPH_TUPLE));
+
+ /* add new row to end of set */
+ if (*gsetpp != NULL) {
+ for (gsetcurp = *gsetpp; gsetcurp->next != NULL; gsetcurp = gsetcurp->next);
+ gsetcurp->next = newgsetp;
+ }
+ else { /* new set */
+ *gsetpp = newgsetp;
+ }
+
+ /* ok */
+ return 1;
+}
+
+
+/*
+ free a graph set (release memory)
+
+ returns 1 for ok, 0 for error
+*/
+int free_graph_set (GRAPH_SET *gsetp)
+{
+ GRAPH_SET *nextgsetp;
+
+ if (gsetp == NULL)
+ return 0;
+
+ while (gsetp != NULL) {
+ nextgsetp = gsetp->next;
+ /* free() is a void function, nothing to check */
+ my_free(gsetp,MYF(0));
+ gsetp = nextgsetp;
+ }
+
+ /* ok */
+ return 1;
+}
+
+
+/*
+ insert new data into graphstore
+ this can be either a vertex or an edge, depending on the params
+ NOTE! gspp is ptr to base ptr
+
+ returns 1 for ok, 0 for error
+*/
+int graphstore_insert (GRAPHSTORE **gspp, GRAPH_TUPLE *gtp)
+{
+ if (gspp == NULL)
+ return 0;
+
+ /* if nada or no orig vertex, we can't do anything */
+ if (gtp == NULL || !gtp->origid)
+ return 0;
+
+#if 0
+printf("inserting: origid=%lu destid=%lu weight=%lu\n",gtp->origid,gtp->destid,gtp->weight);
+#endif
+
+ if (!gtp->destid) /* no edge param so just adding vertex */
+ return _add_vertex(gspp,gtp->origid);
+
+ /*
+ add an edge
+ first add both vertices just in case they didn't yet exist...
+ not checking result there: if there's a prob, _add_edge() will catch.
+ */
+ _add_vertex(gspp,gtp->origid);
+ _add_vertex(gspp,gtp->destid);
+ return _add_edge(*gspp,gtp->origid,gtp->destid,gtp->weight);
+}
+
+
+/*
+ this is an internal function used by graphstore_query()
+
+ find any path from originating vertex to destid
+ if found, add to the result set on the way back
+ NOTE: recursive function!
+
+ returns 1 for hit, 0 for nothing, -1 for error
+*/
+int _find_any_path(GRAPH_SET **gsetpp, GRAPH_VERTEXID origid, GRAPH_VERTEXID destid, GRAPH_VERTEX *gvp, GRAPH_SEQ depth)
+{
+ GRAPH_EDGE *gep;
+ GRAPH_TUPLE tup;
+ int res;
+
+ if (gvp->id == destid) {
+ /* found target! */
+ bzero(&tup,sizeof (GRAPH_TUPLE));
+ tup.origid = origid;
+ tup.destid = destid;
+ tup.seq = depth;
+ tup.linkid = gvp->id;
+ return (_add_graph_set(gsetpp,&tup) ? 1 : -1);
+ }
+
+ /* walk through all edges for this vertex */
+ for (gep = gvp->forward_edge; gep; gep = gep->next_edge) {
+ /* recurse */
+ res = _find_any_path(gsetpp,origid,destid,gep->vertex,depth+1);
+ if (res < 0)
+ return res;
+ if (res > 0) {
+ /* found somewhere below this one, insert ourselves and return */
+ bzero(&tup,sizeof (GRAPH_TUPLE));
+ tup.origid = origid;
+ tup.destid = destid;
+ tup.weight = gep->weight;
+ tup.seq = depth;
+ tup.linkid = gvp->id;
+ return (_add_graph_set(gsetpp,&tup) ? 1 : -1);
+ }
+ }
+
+ /* nothing found but no error */
+ return 0;
+}
+
+
+/*
+ query graphstore
+ latch specifies what operation to perform
+
+ we need to feed the conditions in... (through engine condition pushdown)
+ for now we just presume one condition per field so we just feed in a tuple
+ this also means we can just find constants, not ranges
+
+ return ptr to GRAPH_SET
+ caller must free with free_graph_set()
+*/
+GRAPH_SET *graphstore_query (GRAPHSTORE *gsp, GRAPH_TUPLE *gtp)
+{
+ GRAPH_SET *gsetp = NULL;
+ GRAPH_SET *gsetcurp;
+ GRAPH_SET *newgsetp;
+
+ if (gsp == NULL || gtp == NULL)
+ return (NULL);
+
+ switch (gtp->latch) {
+ case 0: /* return all vertices/edges */
+ {
+ GRAPHSTORE *gscurp;
+ GRAPH_EDGE *gep;
+ GRAPH_TUPLE tup;
+
+ /* walk through all vertices */
+ for (gscurp = gsp; gscurp != NULL; gscurp = gscurp->next) {
+ /* check for condition */
+ if (gtp->origid && gscurp->vertex->id != gtp->origid)
+ continue;
+
+ bzero(&tup,sizeof (GRAPH_TUPLE));
+ tup.origid = gscurp->vertex->id;
+
+ /* no edges? */
+ if (gscurp->vertex->forward_edge == NULL) {
+ /* just add vertex to set */
+ if (!_add_graph_set(&gsetp,&tup)) {
+ if (gsetp != NULL) /* clean up */
+ my_free(gsetp,MYF(0));
+ return (NULL);
+ }
+ }
+ else {
+ /* walk through all edges */
+ for (gep = gscurp->vertex->forward_edge; gep; gep = gep->next_edge) {
+ tup.destid = gep->vertex->id;
+ tup.weight = gep->weight;
+
+ /* just add vertex to set */
+ if (!_add_graph_set(&gsetp,&tup)) {
+ if (gsetp != NULL) /* clean up */
+ my_free(gsetp,MYF(0));
+ return (NULL);
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case 1: /* find a path between origid and destid */
+ /* yes it'll just go with the first path it finds! */
+ {
+ GRAPHSTORE *gscurp;
+ GRAPH_VERTEX *origvp;
+ GRAPH_TUPLE tup;
+
+ if (!gtp->origid || !gtp->destid)
+ return NULL;
+
+ /* find both vertices */
+ if ((origvp = _find_vertex(gsp,gtp->origid)) == NULL ||
+ _find_vertex(gsp,gtp->destid) == NULL)
+ return NULL;
+
+ if (_find_any_path(&gsetp,gtp->origid,gtp->destid,origvp,0) < 0) { /* error? */
+ if (gsetp != NULL) /* clean up */
+ my_free(gsetp,MYF(0));
+ return NULL;
+ }
+ }
+ break;
+
+ default:
+ /* this ends up being an empty set */
+ break;
+ }
+
+ /* Fix up latch column with the proper value - to be relationally correct */
+ for (gsetcurp = gsetp; gsetcurp != NULL; gsetcurp = gsetcurp->next)
+ gsetcurp->tuple.latch = gtp->latch;
+
+ return gsetp;
+}
+
+
+
+/* end of graphstore.c */
\ No newline at end of file
=== added file 'storage/oqgraph/graphstore.h'
--- a/storage/oqgraph/graphstore.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/graphstore.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,90 @@
+/*
+ * Graph Engine - Copyright (C) 2007 by Arjen Lentz (arjen(a)openquery.com.au)
+ * graphstore.h internal storage system
+ */
+//typedef unsigned short uint16;
+//typedef unsigned long long uint64;
+
+
+/*
+ This is essentially what a GRAPH engine table looks like on the MySQL end:
+ CREATE TABLE foo (
+ latch SMALLINT UNSIGNED NULL,
+ origid BIGINT UNSIGNED NULL,
+ destid BIGINT UNSIGNED NULL,
+ weight BIGINT UNSIGNED NULL,
+ seq BIGINT UNSIGNED NULL,
+ linkid BIGINT UNSIGNED NULL
+ ) ENGINE=OQGRAPH
+*/
+
+
+/*
+ We represent the above in C in the following way:
+*/
+typedef uint16 GRAPH_LATCH;
+typedef uint64 GRAPH_VERTEXID;
+typedef uint64 GRAPH_WEIGHT;
+typedef uint64 GRAPH_SEQ;
+
+typedef struct graph_tuple {
+ GRAPH_LATCH latch; /* function */
+ GRAPH_VERTEXID origid; /* vertex (should be != 0) */
+ GRAPH_VERTEXID destid; /* edge */
+ GRAPH_WEIGHT weight; /* weight */
+ GRAPH_SEQ seq; /* seq# within (origid) */
+ GRAPH_VERTEXID linkid; /* current step between origid/destid */
+} GRAPH_TUPLE;
+
+typedef struct graph_set {
+ GRAPH_TUPLE tuple;
+ struct graph_set *next;
+} GRAPH_SET;
+
+
+/*
+ Internally, sets look nothing like the above
+
+ - We have vertices, connected by edges.
+ - Each vertex' edges are maintained in a linked list.
+ - Edges can be weighted.
+
+ There are some issues with this structure, it'd be a pest to do a delete
+ So for now, let's just not support deletes!
+*/
+/* the below is half-gross and will likely change */
+typedef struct graph_edge {
+ struct graph_vertex {
+ GRAPH_VERTEXID id;
+ struct graph_edge *forward_edge;
+ } *vertex;
+ GRAPH_WEIGHT weight;
+ struct graph_edge *next_edge;
+} GRAPH_EDGE;
+
+typedef struct graph_vertex GRAPH_VERTEX;
+
+
+/*
+ A rough internal storage system for a set
+*/
+/* this below is fully gross and will definitely change */
+typedef struct graphstore {
+ GRAPH_VERTEX *vertex; /* changed to ptr when integrating into MySQL */
+ struct graphstore *next;
+} GRAPHSTORE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* public function declarations */
+int graphstore_insert (GRAPHSTORE **gspp, GRAPH_TUPLE *gtp);
+GRAPH_SET *graphstore_query (GRAPHSTORE *gsp, GRAPH_TUPLE *gtp);
+int free_graph_set (GRAPH_SET *gsetp);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* end of graphstore.h */
\ No newline at end of file
=== added file 'storage/oqgraph/ha_oqgraph.cc'
--- a/storage/oqgraph/ha_oqgraph.cc 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/ha_oqgraph.cc 2010-01-04 13:32:42 +0000
@@ -0,0 +1,1040 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+ Portions of this file copyright (C) 2000-2006 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation // gcc: Class implementation
+#endif
+
+#define MYSQL_SERVER // to have THD
+#include "mysql_priv.h"
+#if MYSQL_VERSION_ID >= 50100
+#include <mysql/plugin.h>
+#endif
+
+#ifdef HAVE_OQGRAPH
+
+#include "ha_oqgraph.h"
+#include "graphcore.h"
+
+#define OQGRAPH_STATS_UPDATE_THRESHOLD 10
+
+using namespace open_query;
+
+
+struct oqgraph_info_st
+{
+ THR_LOCK lock;
+ oqgraph_share *graph;
+ uint use_count;
+ uint key_stat_version;
+ uint records;
+ bool dropped;
+ char name[FN_REFLEN+1];
+};
+
+static const char oqgraph_description[]=
+ "Open Query Graph Computation Engine, stored in memory "
+ "(http://openquery.com/graph)";
+
+#if MYSQL_VERSION_ID < 50100
+static bool oqgraph_init();
+
+handlerton oqgraph_hton= {
+ "OQGRAPH",
+ SHOW_OPTION_YES,
+ oqgraph_description,
+ DB_TYPE_OQGRAPH,
+ oqgraph_init,
+ 0, /* slot */
+ 0, /* savepoint size. */
+ NULL, /* close_connection */
+ NULL, /* savepoint */
+ NULL, /* rollback to savepoint */
+ NULL, /* release savepoint */
+ NULL, /* commit */
+ NULL, /* rollback */
+ NULL, /* prepare */
+ NULL, /* recover */
+ NULL, /* commit_by_xid */
+ NULL, /* rollback_by_xid */
+ NULL, /* create_cursor_read_view */
+ NULL, /* set_cursor_read_view */
+ NULL, /* close_cursor_read_view */
+ HTON_NO_FLAGS
+};
+
+#define STATISTIC_INCREMENT(X) \
+statistic_increment(table->in_use->status_var.X, &LOCK_status)
+#define MOVE(X) move_field(X)
+#define RECORDS records
+#else
+#define STATISTIC_INCREMENT(X) ha_statistic_increment(&SSV::X)
+#define MOVE(X) move_field_offset(X)
+#define RECORDS stats.records
+#endif
+
+static HASH oqgraph_open_tables;
+static pthread_mutex_t LOCK_oqgraph;
+static bool oqgraph_init_done= 0;
+
+#if MYSQL_VERSION_ID >= 50130
+#define HASH_KEY_LENGTH size_t
+#else
+#define HASH_KEY_LENGTH uint
+#endif
+
+static uchar* get_key(const uchar *ptr, HASH_KEY_LENGTH *length,
+ my_bool)
+{
+ const OQGRAPH_INFO *share= (const OQGRAPH_INFO*) ptr;
+ *length= strlen(share->name);
+ return (uchar*) share->name;
+}
+
+#if MYSQL_VERSION_ID >= 50100
+static handler* oqgraph_create_handler(handlerton *hton, TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
+{
+ return new (mem_root) ha_oqgraph(hton, table);
+}
+
+static int oqgraph_init(handlerton *hton)
+{
+#else
+static bool oqgraph_init()
+{
+ if (have_oqgraph == SHOW_OPTION_DISABLED)
+ return 1;
+#endif
+ if (pthread_mutex_init(&LOCK_oqgraph, MY_MUTEX_INIT_FAST))
+ goto error;
+ if (hash_init(&oqgraph_open_tables, &my_charset_bin, 32, 0, 0,
+ get_key, 0, 0))
+ {
+ pthread_mutex_destroy(&LOCK_oqgraph);
+ goto error;
+ }
+#if MYSQL_VERSION_ID >= 50100
+ hton->state= SHOW_OPTION_YES;
+ hton->db_type= DB_TYPE_AUTOASSIGN;
+ hton->create= oqgraph_create_handler;
+ hton->flags= HTON_NO_FLAGS;
+#endif
+ oqgraph_init_done= TRUE;
+ return 0;
+error:
+#if MYSQL_VERSION_ID < 50100
+ have_oqgraph= SHOW_OPTION_DISABLED;
+#endif
+ return 1;
+}
+
+#if MYSQL_VERSION_ID >= 50100
+static int oqgraph_fini(void *)
+{
+ hash_free(&oqgraph_open_tables);
+ pthread_mutex_destroy(&LOCK_oqgraph);
+ oqgraph_init_done= FALSE;
+ return 0;
+}
+#endif
+
+static OQGRAPH_INFO *get_share(const char *name, TABLE *table=0)
+{
+ OQGRAPH_INFO *share;
+ uint length= strlen(name);
+
+ safe_mutex_assert_owner(&LOCK_oqgraph);
+ if (!(share= (OQGRAPH_INFO*) hash_search(&oqgraph_open_tables,
+ (byte*) name, length)))
+ {
+ if (!table ||
+ !(share= new OQGRAPH_INFO))
+ return 0;
+ share->use_count= share->key_stat_version= share->records= 0;
+ share->dropped= 0;
+ strmov(share->name, name);
+ if (!(share->graph= oqgraph::create()))
+ {
+ delete share;
+ return 0;
+ }
+ if (my_hash_insert(&oqgraph_open_tables, (byte*) share))
+ {
+ oqgraph::free(share->graph);
+ delete share;
+ return 0;
+ }
+ thr_lock_init(&share->lock);
+ }
+ share->use_count++;
+ return share;
+}
+
+static int free_share(OQGRAPH_INFO *share, bool drop=0)
+{
+ safe_mutex_assert_owner(&LOCK_oqgraph);
+ if (!share)
+ return 0;
+ if (drop)
+ {
+ share->dropped= true;
+ hash_delete(&oqgraph_open_tables, (byte*) share);
+ }
+ if (!--share->use_count)
+ {
+ if (share->dropped)
+ {
+ thr_lock_delete(&share->lock);
+ oqgraph::free(share->graph);
+ delete share;
+ }
+ }
+ return 0;
+}
+
+static int error_code(int res)
+{
+ switch (res)
+ {
+ case oqgraph::OK:
+ return 0;
+ case oqgraph::NO_MORE_DATA:
+ return HA_ERR_END_OF_FILE;
+ case oqgraph::EDGE_NOT_FOUND:
+ return HA_ERR_KEY_NOT_FOUND;
+ case oqgraph::INVALID_WEIGHT:
+ return HA_ERR_AUTOINC_ERANGE;
+ case oqgraph::DUPLICATE_EDGE:
+ return HA_ERR_FOUND_DUPP_KEY;
+ case oqgraph::CANNOT_ADD_VERTEX:
+ case oqgraph::CANNOT_ADD_EDGE:
+ return HA_ERR_RECORD_FILE_FULL;
+ case oqgraph::MISC_FAIL:
+ default:
+ return HA_ERR_CRASHED_ON_USAGE;
+ }
+}
+
+/**
+ * Check if table complies with our designated structure
+ *
+ * ColName Type Attributes
+ * ======= ======== =============
+ * latch SMALLINT UNSIGNED NULL
+ * origid BIGINT UNSIGNED NULL
+ * destid BIGINT UNSIGNED NULL
+ * weight DOUBLE NULL
+ * seq BIGINT UNSIGNED NULL
+ * linkid BIGINT UNSIGNED NULL
+ * =================================
+ *
+ CREATE TABLE foo (
+ latch SMALLINT UNSIGNED NULL,
+ origid BIGINT UNSIGNED NULL,
+ destid BIGINT UNSIGNED NULL,
+ weight DOUBLE NULL,
+ seq BIGINT UNSIGNED NULL,
+ linkid BIGINT UNSIGNED NULL,
+ KEY (latch, origid, destid) USING HASH,
+ KEY (latch, destid, origid) USING HASH
+ ) ENGINE=OQGRAPH
+
+ */
+static int oqgraph_check_table_structure (TABLE *table_arg)
+{
+ int i;
+ struct { const char *colname; int coltype; } skel[] = {
+ { "latch" , MYSQL_TYPE_SHORT },
+ { "origid", MYSQL_TYPE_LONGLONG },
+ { "destid", MYSQL_TYPE_LONGLONG },
+ { "weight", MYSQL_TYPE_DOUBLE },
+ { "seq" , MYSQL_TYPE_LONGLONG },
+ { "linkid", MYSQL_TYPE_LONGLONG },
+ { NULL , 0}
+ };
+
+ DBUG_ENTER("ha_oqgraph::table_structure_ok");
+
+ Field **field= table_arg->field;
+ for (i= 0; *field && skel[i].colname; i++, field++) {
+ /* Check Column Type */
+ if ((*field)->type() != skel[i].coltype)
+ DBUG_RETURN(-1);
+ if (skel[i].coltype != MYSQL_TYPE_DOUBLE) {
+ /* Check Is UNSIGNED */
+ if (!((*field)->flags & UNSIGNED_FLAG ))
+ DBUG_RETURN(-1);
+ }
+ /* Check THAT NOT NULL isn't set */
+ if ((*field)->flags & NOT_NULL_FLAG)
+ DBUG_RETURN(-1);
+ /* Check the column name */
+ if (strcmp(skel[i].colname,(*field)->field_name))
+ DBUG_RETURN(-1);
+ }
+
+ if (skel[i].colname || *field || !table_arg->key_info || !table_arg->s->keys)
+ DBUG_RETURN(-1);
+
+ KEY *key= table_arg->key_info;
+ for (uint i= 0; i < table_arg->s->keys; ++i, ++key)
+ {
+ Field **field= table_arg->field;
+ /* check that the first key part is the latch and it is a hash key */
+ if (!(field[0] == key->key_part[0].field &&
+ HA_KEY_ALG_HASH == key->algorithm))
+ DBUG_RETURN(-1);
+ if (key->key_parts == 3)
+ {
+ /* KEY (latch, origid, destid) USING HASH */
+ /* KEY (latch, destid, origid) USING HASH */
+ if (!(field[1] == key->key_part[1].field &&
+ field[2] == key->key_part[2].field) &&
+ !(field[1] == key->key_part[2].field &&
+ field[2] == key->key_part[1].field))
+ DBUG_RETURN(-1);
+ }
+ else
+ DBUG_RETURN(-1);
+ }
+
+ DBUG_RETURN(0);
+}
+
+/*****************************************************************************
+** OQGRAPH tables
+*****************************************************************************/
+
+#if MYSQL_VERSION_ID >= 50100
+ha_oqgraph::ha_oqgraph(handlerton *hton, TABLE_SHARE *table_arg)
+ : handler(hton, table_arg),
+#else
+ha_oqgraph::ha_oqgraph(TABLE *table_arg)
+ : handler(&oqgraph_hton, table_arg),
+#endif
+ share(0), graph(0), records_changed(0), key_stat_version(0)
+{ }
+
+
+static const char *ha_oqgraph_exts[] =
+{
+ NullS
+};
+
+const char **ha_oqgraph::bas_ext() const
+{
+ return ha_oqgraph_exts;
+}
+
+#if MYSQL_VERSION_ID >= 50100
+ulonglong ha_oqgraph::table_flags() const
+#else
+ulong ha_oqgraph::table_flags() const
+#endif
+{
+ return (HA_NO_BLOBS | HA_NULL_IN_KEY |
+ HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED);
+}
+
+ulong ha_oqgraph::index_flags(uint inx, uint part, bool all_parts) const
+{
+ return HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR;
+}
+
+int ha_oqgraph::open(const char *name, int mode, uint test_if_locked)
+{
+ pthread_mutex_lock(&LOCK_oqgraph);
+ if ((share = get_share(name, table)))
+ {
+ ref_length= oqgraph::sizeof_ref;
+ }
+
+ if (share)
+ {
+ /* Initialize variables for the opened table */
+ thr_lock_data_init(&share->lock, &lock, NULL);
+
+ graph= oqgraph::create(share->graph);
+
+ /*
+ We cannot run update_key_stats() here because we do not have a
+ lock on the table. The 'records' count might just be changed
+ temporarily at this moment and we might get wrong statistics (Bug
+ #10178). Instead we request for update. This will be done in
+ ha_oqgraph::info(), which is always called before key statistics are
+ used.
+ */
+ key_stat_version= share->key_stat_version-1;
+ }
+ pthread_mutex_unlock(&LOCK_oqgraph);
+
+ return (share ? 0 : 1);
+}
+
+int ha_oqgraph::close(void)
+{
+ pthread_mutex_lock(&LOCK_oqgraph);
+ oqgraph::free(graph); graph= 0;
+ int res= free_share(share);
+ pthread_mutex_unlock(&LOCK_oqgraph);
+ return error_code(res);
+}
+
+void ha_oqgraph::update_key_stats()
+{
+ for (uint i= 0; i < table->s->keys; i++)
+ {
+ KEY *key=table->key_info+i;
+ if (!key->rec_per_key)
+ continue;
+ if (key->algorithm != HA_KEY_ALG_BTREE)
+ {
+ if (key->flags & HA_NOSAME)
+ key->rec_per_key[key->key_parts-1]= 1;
+ else
+ {
+ unsigned vertices= graph->vertices_count();
+ unsigned edges= graph->edges_count();
+ uint no_records= vertices ? 2 * (edges + vertices) / vertices : 2;
+ if (no_records < 2)
+ no_records= 2;
+ key->rec_per_key[key->key_parts-1]= no_records;
+ }
+ }
+ }
+ records_changed= 0;
+ /* At the end of update_key_stats() we can proudly claim they are OK. */
+ key_stat_version= share->key_stat_version;
+}
+
+
+int ha_oqgraph::write_row(byte * buf)
+{
+ int res= oqgraph::MISC_FAIL;
+ Field ** const field= table->field;
+ STATISTIC_INCREMENT(ha_write_count);
+
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+#endif
+ my_ptrdiff_t ptrdiff= buf - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ field[3]->MOVE(ptrdiff);
+ }
+
+ if (!field[1]->is_null() && !field[2]->is_null())
+ {
+ VertexID orig_id= (VertexID) field[1]->val_int();
+ VertexID dest_id= (VertexID) field[2]->val_int();
+ EdgeWeight weight= 1;
+
+ if (!field[3]->is_null())
+ weight= (EdgeWeight) field[3]->val_real();
+
+ if (!(res= graph->insert_edge(orig_id, dest_id, weight, replace_dups)))
+ {
+ ++records_changed;
+ share->records++;
+ }
+ if (res == oqgraph::DUPLICATE_EDGE && ignore_dups && !insert_dups)
+ res= oqgraph::OK;
+ }
+
+ if (ptrdiff)
+ {
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ field[3]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+#endif
+
+ if (!res && records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records)
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ share->key_stat_version++;
+ }
+
+ return error_code(res);
+}
+
+int ha_oqgraph::update_row(const byte * old, byte * buf)
+{
+ int res= oqgraph::MISC_FAIL;
+ VertexID orig_id, dest_id;
+ EdgeWeight weight= 1;
+ Field **field= table->field;
+ STATISTIC_INCREMENT(ha_update_count);
+
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+#endif
+ my_ptrdiff_t ptrdiff= buf - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(ptrdiff);
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ field[3]->MOVE(ptrdiff);
+ }
+
+ if (inited == INDEX || inited == RND)
+ {
+ VertexID *origp= 0, *destp= 0;
+ EdgeWeight *weightp= 0;
+ if (!field[1]->is_null())
+ *(origp= &orig_id)= (VertexID) field[1]->val_int();
+ if (!field[2]->is_null())
+ *(destp= &dest_id)= (VertexID) field[2]->val_int();
+ if (!field[3]->is_null())
+ *(weightp= &weight)= (EdgeWeight) field[3]->val_real();
+
+ my_ptrdiff_t ptrdiff2= old - buf;
+
+ field[0]->MOVE(ptrdiff2);
+ field[1]->MOVE(ptrdiff2);
+ field[2]->MOVE(ptrdiff2);
+ field[3]->MOVE(ptrdiff2);
+
+ if (field[0]->is_null())
+ {
+ if (!origp == field[1]->is_null() &&
+ *origp == (VertexID) field[1]->val_int())
+ origp= 0;
+ if (!destp == field[2]->is_null() &&
+ *destp == (VertexID) field[2]->val_int())
+ origp= 0;
+ if (!weightp == field[3]->is_null() &&
+ *weightp == (VertexID) field[3]->val_real())
+ weightp= 0;
+
+ if (!(res= graph->modify_edge(oqgraph::current_row(),
+ origp, destp, weightp, replace_dups)))
+ ++records_changed;
+ else if (ignore_dups && res == oqgraph::DUPLICATE_EDGE)
+ res= oqgraph::OK;
+ }
+
+ field[0]->MOVE(-ptrdiff2);
+ field[1]->MOVE(-ptrdiff2);
+ field[2]->MOVE(-ptrdiff2);
+ field[3]->MOVE(-ptrdiff2);
+ }
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(-ptrdiff);
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ field[3]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+#endif
+
+ if (!res && records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records)
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ share->key_stat_version++;
+ }
+ return error_code(res);
+}
+
+int ha_oqgraph::delete_row(const byte * buf)
+{
+ int res= oqgraph::EDGE_NOT_FOUND;
+ Field **field= table->field;
+ STATISTIC_INCREMENT(ha_delete_count);
+
+ if (inited == INDEX || inited == RND)
+ {
+ if ((res= graph->delete_edge(oqgraph::current_row())) == oqgraph::OK)
+ {
+ ++records_changed;
+ share->records--;
+ }
+ }
+ if (res != oqgraph::OK)
+ {
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+#endif
+ my_ptrdiff_t ptrdiff= buf - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(ptrdiff);
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ }
+
+ if (field[0]->is_null() && !field[1]->is_null() && !field[2]->is_null())
+ {
+ VertexID orig_id= (VertexID) field[1]->val_int();
+ VertexID dest_id= (VertexID) field[2]->val_int();
+
+ if ((res= graph->delete_edge(orig_id, dest_id)) == oqgraph::OK)
+ {
+ ++records_changed;
+ share->records--;
+ }
+ }
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(-ptrdiff);
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+#endif
+ }
+
+ if (!res && table->s->tmp_table == NO_TMP_TABLE &&
+ records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records)
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ share->key_stat_version++;
+ }
+ return error_code(res);
+}
+
+int ha_oqgraph::index_read(byte * buf, const byte * key, uint key_len,
+ enum ha_rkey_function find_flag)
+{
+ DBUG_ASSERT(inited==INDEX);
+ return index_read_idx(buf, active_index, key, key_len, find_flag);
+}
+
+int ha_oqgraph::index_next_same(byte *buf, const byte *key, uint key_len)
+{
+ int res;
+ open_query::row row;
+ DBUG_ASSERT(inited==INDEX);
+ STATISTIC_INCREMENT(ha_read_key_count);
+ if (!(res= graph->fetch_row(row)))
+ res= fill_record(buf, row);
+ table->status= res ? STATUS_NOT_FOUND : 0;
+ return error_code(res);
+}
+
+int ha_oqgraph::index_read_idx(byte * buf, uint index, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag)
+{
+ Field **field= table->field;
+ KEY *key_info= table->key_info + index;
+ int res;
+ VertexID orig_id, dest_id;
+ int latch;
+ VertexID *orig_idp=0, *dest_idp=0;
+ int *latchp=0;
+ open_query::row row;
+ STATISTIC_INCREMENT(ha_read_key_count);
+
+ bmove_align(buf, table->s->default_values, table->s->reclength);
+ key_restore(buf, (byte*) key, key_info, key_len);
+
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+#endif
+ my_ptrdiff_t ptrdiff= buf - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(ptrdiff);
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ }
+
+ if (!field[0]->is_null())
+ {
+ latch= (int) field[0]->val_int();
+ latchp= &latch;
+ }
+
+ if (!field[1]->is_null())
+ {
+ orig_id= (VertexID) field[1]->val_int();
+ orig_idp= &orig_id;
+ }
+
+ if (!field[2]->is_null())
+ {
+ dest_id= (VertexID) field[2]->val_int();
+ dest_idp= &dest_id;
+ }
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(-ptrdiff);
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+#endif
+
+ res= graph->search(latchp, orig_idp, dest_idp);
+
+ if (!res && !(res= graph->fetch_row(row)))
+ res= fill_record(buf, row);
+ table->status = res ? STATUS_NOT_FOUND : 0;
+ return error_code(res);
+}
+
+int ha_oqgraph::fill_record(byte *record, const open_query::row &row)
+{
+ Field **field= table->field;
+
+ bmove_align(record, table->s->default_values, table->s->reclength);
+
+#if MYSQL_VERSION_ID >= 50100
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
+#endif
+ my_ptrdiff_t ptrdiff= record - table->record[0];
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(ptrdiff);
+ field[1]->MOVE(ptrdiff);
+ field[2]->MOVE(ptrdiff);
+ field[3]->MOVE(ptrdiff);
+ field[4]->MOVE(ptrdiff);
+ field[5]->MOVE(ptrdiff);
+ }
+
+ // just each field specifically, no sense iterating
+ if (row.latch_indicator)
+ {
+ field[0]->set_notnull();
+ field[0]->store((longlong) row.latch);
+ }
+
+ if (row.orig_indicator)
+ {
+ field[1]->set_notnull();
+ field[1]->store((longlong) row.orig);
+ }
+
+ if (row.dest_indicator)
+ {
+ field[2]->set_notnull();
+ field[2]->store((longlong) row.dest);
+ }
+
+ if (row.weight_indicator)
+ {
+ field[3]->set_notnull();
+ field[3]->store((double) row.weight);
+ }
+
+ if (row.seq_indicator)
+ {
+ field[4]->set_notnull();
+ field[4]->store((longlong) row.seq);
+ }
+
+ if (row.link_indicator)
+ {
+ field[5]->set_notnull();
+ field[5]->store((longlong) row.link);
+ }
+
+ if (ptrdiff)
+ {
+ field[0]->MOVE(-ptrdiff);
+ field[1]->MOVE(-ptrdiff);
+ field[2]->MOVE(-ptrdiff);
+ field[3]->MOVE(-ptrdiff);
+ field[4]->MOVE(-ptrdiff);
+ field[5]->MOVE(-ptrdiff);
+ }
+#if MYSQL_VERSION_ID >= 50100
+ dbug_tmp_restore_column_map(table->write_set, old_map);
+#endif
+
+ return 0;
+}
+
+int ha_oqgraph::rnd_init(bool scan)
+{
+ return error_code(graph->random(scan));
+}
+
+int ha_oqgraph::rnd_next(byte *buf)
+{
+ int res;
+ open_query::row row;
+ STATISTIC_INCREMENT(ha_read_rnd_next_count);
+ if (!(res= graph->fetch_row(row)))
+ res= fill_record(buf, row);
+ table->status= res ? STATUS_NOT_FOUND: 0;
+ return error_code(res);
+}
+
+int ha_oqgraph::rnd_pos(byte * buf, byte *pos)
+{
+ int res;
+ open_query::row row;
+ STATISTIC_INCREMENT(ha_read_rnd_count);
+ if (!(res= graph->fetch_row(row, pos)))
+ res= fill_record(buf, row);
+ table->status=res ? STATUS_NOT_FOUND: 0;
+ return error_code(res);
+}
+
+void ha_oqgraph::position(const byte *record)
+{
+ graph->row_ref((void*) ref); // Ref is aligned
+}
+
+int ha_oqgraph::cmp_ref(const byte *ref1, const byte *ref2)
+{
+ return memcmp(ref1, ref2, oqgraph::sizeof_ref);
+}
+
+int ha_oqgraph::info(uint flag)
+{
+ RECORDS= graph->vertices_count() + graph->edges_count();
+#if 0
+ records= hp_info.records;
+ deleted= hp_info.deleted;
+ errkey= hp_info.errkey;
+ mean_rec_length= hp_info.reclength;
+ data_file_length= hp_info.data_length;
+ index_file_length= hp_info.index_length;
+ max_data_file_length= hp_info.max_records* hp_info.reclength;
+ delete_length= hp_info.deleted * hp_info.reclength;
+#endif
+ /*
+ If info() is called for the first time after open(), we will still
+ have to update the key statistics. Hoping that a table lock is now
+ in place.
+ */
+ if (key_stat_version != share->key_stat_version)
+ update_key_stats();
+ return 0;
+}
+
+int ha_oqgraph::extra(enum ha_extra_function operation)
+{
+ switch (operation)
+ {
+ case HA_EXTRA_IGNORE_DUP_KEY:
+ ignore_dups= true;
+ break;
+ case HA_EXTRA_NO_IGNORE_DUP_KEY:
+ ignore_dups= false;
+ insert_dups= false;
+ break;
+ case HA_EXTRA_WRITE_CAN_REPLACE:
+ replace_dups= true;
+ break;
+ case HA_EXTRA_WRITE_CANNOT_REPLACE:
+ replace_dups= false;
+ break;
+ case HA_EXTRA_INSERT_WITH_UPDATE:
+ insert_dups= true;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int ha_oqgraph::delete_all_rows()
+{
+ int res;
+ if (!(res= graph->delete_all()))
+ {
+ share->records= 0;
+ }
+
+ if (!res && table->s->tmp_table == NO_TMP_TABLE)
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ share->key_stat_version++;
+ }
+ return error_code(res);
+}
+
+int ha_oqgraph::external_lock(THD *thd, int lock_type)
+{
+ return 0; // No external locking
+}
+
+
+THR_LOCK_DATA **ha_oqgraph::store_lock(THD *thd,
+ THR_LOCK_DATA **to,
+ enum thr_lock_type lock_type)
+{
+ if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
+ lock.type=lock_type;
+ *to++= &lock;
+ return to;
+}
+
+/*
+ We have to ignore ENOENT entries as the HEAP table is created on open and
+ not when doing a CREATE on the table.
+*/
+
+int ha_oqgraph::delete_table(const char *name)
+{
+ int res= 0;
+ OQGRAPH_INFO *share;
+ pthread_mutex_lock(&LOCK_oqgraph);
+ if ((share= get_share(name)))
+ {
+ res= free_share(share, true);
+ }
+ pthread_mutex_unlock(&LOCK_oqgraph);
+ return error_code(res);
+}
+
+int ha_oqgraph::rename_table(const char * from, const char * to)
+{
+ pthread_mutex_lock(&LOCK_oqgraph);
+ if (OQGRAPH_INFO *share= get_share(from))
+ {
+ strmov(share->name, to);
+ hash_update(&oqgraph_open_tables, (byte*) share,
+ (byte*) from, strlen(from));
+ }
+ pthread_mutex_unlock(&LOCK_oqgraph);
+ return 0;
+}
+
+
+ha_rows ha_oqgraph::records_in_range(uint inx, key_range *min_key,
+ key_range *max_key)
+{
+ KEY *key=table->key_info+inx;
+ //if (key->algorithm == HA_KEY_ALG_BTREE)
+ // return btree_records_in_range(file, inx, min_key, max_key);
+
+ if (!min_key || !max_key ||
+ min_key->length != max_key->length ||
+ min_key->length < key->key_length - key->key_part[2].store_length ||
+ min_key->flag != HA_READ_KEY_EXACT ||
+ max_key->flag != HA_READ_AFTER_KEY)
+ {
+ if (min_key->length == key->key_part[0].store_length)
+ {
+ // If latch is not null and equals 0, return # nodes
+ DBUG_ASSERT(key->key_part[0].store_length == 3);
+ if (key->key_part[0].null_bit && !min_key->key[0] &&
+ !min_key->key[1] && !min_key->key[2])
+ return graph->vertices_count();
+ }
+ return HA_POS_ERROR; // Can only use exact keys
+ }
+
+ if (RECORDS <= 1)
+ return RECORDS;
+
+ /* Assert that info() did run. We need current statistics here. */
+ DBUG_ASSERT(key_stat_version == share->key_stat_version);
+ ha_rows result= key->rec_per_key[key->key_parts-1];
+
+ return result;
+}
+
+
+int ha_oqgraph::create(const char *name, TABLE *table_arg,
+ HA_CREATE_INFO *create_info)
+{
+ int res = -1;
+ OQGRAPH_INFO *share;
+
+ pthread_mutex_lock(&LOCK_oqgraph);
+ if ((share= get_share(name)))
+ {
+ free_share(share);
+ }
+ else
+ {
+ if (!oqgraph_check_table_structure(table_arg))
+ res= 0;;
+ }
+ pthread_mutex_unlock(&LOCK_oqgraph);
+
+ if (this->share)
+ info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ return error_code(res);
+}
+
+
+void ha_oqgraph::update_create_info(HA_CREATE_INFO *create_info)
+{
+ table->file->info(HA_STATUS_AUTO);
+ //if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
+ // create_info->auto_increment_value= auto_increment_value;
+}
+
+#if MYSQL_VERSION_ID >= 50100
+struct st_mysql_storage_engine oqgraph_storage_engine=
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+
+mysql_declare_plugin(oqgraph)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &oqgraph_storage_engine,
+ "OQGRAPH",
+ "Arjen Lentz & Antony T Curtis, Open Query",
+ oqgraph_description,
+ PLUGIN_LICENSE_GPL,
+ (int (*)(void*)) oqgraph_init, /* Plugin Init */
+ oqgraph_fini, /* Plugin Deinit */
+ 0x0200, /* Version: 2.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+}
+mysql_declare_plugin_end;
+#endif
+
+#endif
=== added file 'storage/oqgraph/ha_oqgraph.h'
--- a/storage/oqgraph/ha_oqgraph.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/ha_oqgraph.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,114 @@
+/* Copyright (C) 2007-2009 Arjen G Lentz & Antony T Curtis for Open Query
+ Portions of this file copyright (C) 2000-2006 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* ======================================================================
+ Open Query Graph Computation Engine, based on a concept by Arjen Lentz
+ Mk.II implementation by Antony Curtis & Arjen Lentz
+ For more information, documentation, support, enhancement engineering,
+ and non-GPL licensing, see http://openquery.com/graph
+ or contact graph(a)openquery.com
+ For packaged binaries, see http://ourdelta.org
+ ======================================================================
+*/
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface /* gcc class implementation */
+#endif
+
+
+typedef struct oqgraph_info_st OQGRAPH_INFO;
+
+#if MYSQL_VERSION_ID >= 50120
+typedef uchar byte;
+#endif
+
+namespace open_query
+{
+ struct row;
+ class oqgraph;
+}
+
+/* class for the the Open Query Graph handler */
+
+class ha_oqgraph: public handler
+{
+ OQGRAPH_INFO *share;
+ open_query::oqgraph *graph;
+ THR_LOCK_DATA lock;
+ /* number of records changed since last statistics update */
+ uint records_changed;
+ uint key_stat_version;
+ bool replace_dups, ignore_dups, insert_dups;
+
+ int fill_record(byte*, const open_query::row&);
+
+public:
+#if MYSQL_VERSION_ID >= 50100
+ ha_oqgraph(handlerton *hton, TABLE_SHARE *table);
+ ulonglong table_flags() const;
+#else
+ ha_oqgraph(TABLE *table);
+ ulong table_flags() const;
+#endif
+ ~ha_oqgraph() {}
+ const char *table_type() const
+ {
+ return "OQGRAPH";
+ }
+ const char *index_type(uint inx)
+ {
+ return "HASH";
+ }
+ /* Rows also use a fixed-size format */
+ enum row_type get_row_type() const { return ROW_TYPE_FIXED; }
+ const char **bas_ext() const;
+ ulong index_flags(uint inx, uint part, bool all_parts) const;
+ uint max_supported_keys() const { return MAX_KEY; }
+ uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
+ double scan_time() { return (double) 1000000000; }
+ double read_time(uint index, uint ranges, ha_rows rows)
+ { return 1; }
+
+ int open(const char *name, int mode, uint test_if_locked);
+ int close(void);
+ int write_row(byte * buf);
+ int update_row(const byte * old_data, byte * new_data);
+ int delete_row(const byte * buf);
+ int index_read(byte * buf, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag);
+ int index_read_idx(byte * buf, uint idx, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag);
+ int index_next_same(byte * buf, const byte * key, uint key_len);
+ int rnd_init(bool scan);
+ int rnd_next(byte *buf);
+ int rnd_pos(byte * buf, byte *pos);
+ void position(const byte *record);
+ int info(uint);
+ int extra(enum ha_extra_function operation);
+ int external_lock(THD *thd, int lock_type);
+ int delete_all_rows(void);
+ ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
+ int delete_table(const char *from);
+ int rename_table(const char * from, const char * to);
+ int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
+ void update_create_info(HA_CREATE_INFO *create_info);
+
+ THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
+ enum thr_lock_type lock_type);
+ int cmp_ref(const byte *ref1, const byte *ref2);
+private:
+ void update_key_stats();
+};
=== added file 'storage/oqgraph/oqgraph_config.h.in'
--- a/storage/oqgraph/oqgraph_config.h.in 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/oqgraph_config.h.in 2010-01-04 08:27:50 +0000
@@ -0,0 +1,73 @@
+/* src/oqgraph_config.h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Enables DTRACE Support */
+#undef HAVE_DTRACE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <syslimits.h> header file. */
+#undef HAVE_SYSLIMITS_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Source directory for MySQL */
+#undef MYSQL_SRC
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
=== added file 'storage/oqgraph/oqgraph_probes.d'
--- a/storage/oqgraph/oqgraph_probes.d 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/oqgraph_probes.d 2010-01-04 08:27:50 +0000
@@ -0,0 +1,19 @@
+/* Copyright (C) 2004-2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+provider oqgraph {
+ probe open();
+ probe close();
+};
=== added file 'storage/oqgraph/oqgraph_probes.h'
--- a/storage/oqgraph/oqgraph_probes.h 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/oqgraph_probes.h 2010-01-04 08:27:50 +0000
@@ -0,0 +1,45 @@
+/*
+ * Generated by dtrace(1M).
+ */
+
+#ifndef _OQGRAPH_PROBES_H
+#define _OQGRAPH_PROBES_H
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if _DTRACE_VERSION
+
+#define OQGRAPH_CLOSE() \
+ __dtrace_oqgraph___close()
+#define OQGRAPH_CLOSE_ENABLED() \
+ __dtraceenabled_oqgraph___close()
+#define OQGRAPH_OPEN() \
+ __dtrace_oqgraph___open()
+#define OQGRAPH_OPEN_ENABLED() \
+ __dtraceenabled_oqgraph___open()
+
+
+extern void __dtrace_oqgraph___close(void);
+extern int __dtraceenabled_oqgraph___close(void);
+extern void __dtrace_oqgraph___open(void);
+extern int __dtraceenabled_oqgraph___open(void);
+
+#else
+
+#define OQGRAPH_CLOSE()
+#define OQGRAPH_CLOSE_ENABLED() (0)
+#define OQGRAPH_OPEN()
+#define OQGRAPH_OPEN_ENABLED() (0)
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OQGRAPH_PROBES_H */
=== added file 'storage/oqgraph/plug.in'
--- a/storage/oqgraph/plug.in 1970-01-01 00:00:00 +0000
+++ b/storage/oqgraph/plug.in 2010-03-30 07:33:38 +0000
@@ -0,0 +1,24 @@
+MYSQL_STORAGE_ENGINE(oqgraph,,[Graph Storage Engine],
+ [Open Query Graph Computation Engine], [])
+MYSQL_PLUGIN_DYNAMIC(oqgraph, [oqgraph_engine.la])
+MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(oqgraph, [ha_oqgraph.cc])
+AM_CONDITIONAL([BUILD_OQGRAPH_FOR_MYSQL], true)
+AM_CONDITIONAL([BUILD_OQGRAPH_STANDALONE], false)
+AM_CONDITIONAL([HAVE_DTRACE], false)
+
+AC_LANG_PUSH([C++])
+
+AC_MSG_CHECKING([for Boost usable by OQGraph engine])
+AC_PREPROC_IFELSE(
+ [
+#include <boost/version.hpp>
+#if BOOST_VERSION >= 104000
+#else
+#error oops
+#endif
+ ],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ with_plugin_oqgraph=no])
+
+AC_LANG_POP()
=== modified file 'storage/xtradb/btr/btr0cur.c'
--- a/storage/xtradb/btr/btr0cur.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/btr/btr0cur.c 2010-03-10 10:32:14 +0000
@@ -3233,7 +3233,7 @@ btr_estimate_number_of_different_key_val
ulint matched_bytes;
ib_int64_t n_recs = 0;
ib_int64_t* n_diff;
- ib_int64_t* n_not_nulls;
+ ib_int64_t* n_not_nulls= 0;
ullint n_sample_pages; /* number of pages to sample */
ulint not_empty_flag = 0;
ulint total_external_size = 0;
=== modified file 'storage/xtradb/fil/fil0fil.c'
--- a/storage/xtradb/fil/fil0fil.c 2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/fil/fil0fil.c 2010-03-28 18:10:00 +0000
@@ -3168,7 +3168,7 @@ skip_info:
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
for (i = 0; (ulint) i < n_index; i++) {
- if (offset / UNIV_PAGE_SIZE == root_page[i]) {
+ if ((ulint) (offset / UNIV_PAGE_SIZE) == root_page[i]) {
/* this is index root page */
mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
+ FSEG_HDR_SPACE, id);
=== modified file 'storage/xtradb/include/page0page.h'
--- a/storage/xtradb/include/page0page.h 2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/page0page.h 2010-03-28 18:10:00 +0000
@@ -517,7 +517,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec); /*!< in: pointer to record */
+ const rec_t* rec); /*!< in: pointer to record */
/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
=== modified file 'storage/xtradb/include/page0page.ic'
--- a/storage/xtradb/include/page0page.ic 2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/page0page.ic 2010-03-28 18:10:00 +0000
@@ -731,7 +731,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec) /*!< in: pointer to record */
+ const rec_t* rec) /*!< in: pointer to record */
{
return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
}
=== modified file 'storage/xtradb/include/ut0lst.h'
--- a/storage/xtradb/include/ut0lst.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0lst.h 2010-03-30 12:36:49 +0000
@@ -158,7 +158,7 @@ Inserts a NODE2 after NODE1 in a list.
/** Invalidate the pointers in a list node.
@param NAME list name
@param N pointer to the node that was removed */
-# define UT_LIST_REMOVE_CLEAR(NAME, N) while (0)
+# define UT_LIST_REMOVE_CLEAR(NAME, N) {} while (0)
#endif
/*******************************************************************//**
=== modified file 'strings/ctype-ucs2.c'
--- a/strings/ctype-ucs2.c 2010-03-04 08:03:07 +0000
+++ b/strings/ctype-ucs2.c 2010-03-30 12:36:49 +0000
@@ -203,7 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
@@ -317,7 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_I
const char *s, const char *t, size_t len)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const char *se=s+len;
const char *te=t+len;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
@@ -1384,7 +1384,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
=== modified file 'strings/ctype-utf8.c'
--- a/strings/ctype-utf8.c 2009-10-15 21:38:29 +0000
+++ b/strings/ctype-utf8.c 2010-03-30 12:36:49 +0000
@@ -2310,7 +2310,7 @@ static int my_strnncoll_utf8(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc), t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
@@ -2380,7 +2380,7 @@ static int my_strnncollsp_utf8(CHARSET_I
my_bool diff_if_only_endspace_difference)
{
int s_res, t_res, res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se= s+slen, *te= t+tlen;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-01-28 14:49:14 +0000
+++ b/support-files/compiler_warnings.supp 2010-03-30 12:36:49 +0000
@@ -39,6 +39,7 @@ sync/sync0rw\.c: unused parameter
sync/sync0sync\.c: unused parameter
sync/sync0sync\.c: unused variable
ut/ut0ut\.c: ignoring return value of
+srv/srv0srv\.c: value computed is not used
#
# bdb is not critical to keep up to date
@@ -66,6 +67,16 @@ db_vrfy.c : .*comparison is always false
/usr/share/aclocal/audiofile.m4 : .*
#
+# Ignore strict-aliasing warnings (for now)
+#
+.*: break strict-aliasing rules
+
+#
+# Ignore not important declaration warnings
+#
+.*: only defines private constructors and has no friends
+
+#
# Ignore all conversion warnings on windows 64
# (Is safe as we are not yet supporting strings >= 2G)
#
@@ -100,6 +111,11 @@ db_vrfy.c : .*comparison is always false
storage/maria/ma_pagecache.c: .*'info_check_pin' defined but not used
#
+# Pbxt
+#
+xaction_xt\.cc: may be used uninitialized in this function
+
+#
# I think these are due to mix of C and C++.
#
storage/pbxt/ : typedef.*was ignored in this declaration
@@ -108,10 +124,11 @@ ha_pbxt\.cc : variable.*might be clobber
#
# Yassl
include/runtime.hpp: .*pure_error.*
-.*/extra/yassl/taocrypt/.*: comparison with string literal
+.*/extra/yassl/.*taocrypt/.*: comparison with string literal
.*/extra/yassl/taocrypt/src/blowfish\.cpp: array subscript is above array bounds
.*/extra/yassl/taocrypt/src/file\.cpp: ignoring return value
.*/extra/yassl/taocrypt/src/integer\.cpp: control reaches end of non-void function
+mySTL/algorithm\.hpp: is used uninitialized in this function
#
# Groff warnings on OpenSUSE.
@@ -123,18 +140,18 @@ include/runtime.hpp: .*pure_error.*
#
listener.cc : .*conversion from 'SOCKET' to 'int'.*
net_serv.cc : .*conversion from 'SOCKET' to 'int'.*
-set_var.cc: right-hand operand of comma has no effect : 1000-1400
-
# allow a little moving space for the warning below
-mi_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
-ma_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
+mi_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
+ma_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
#
# Wrong compiler warnings
#
.* : .*no matching operator delete found; memory will not be freed if initialization throws an exception.*
-ctype-simple.c : .*unary minus operator applied to unsigned type, result still unsigned.*
+ctype-simple\.c : .*unary minus operator applied to unsigned type, result still unsigned.*
# Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478
-regexec\.c : .*passing argument 3 of.*matcher.* discards qualifiers from pointer target type.*
+regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type
+libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000
+storage/xtradb/dict/dict0dict\.c: passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
=== modified file 'unittest/mysys/waiting_threads-t.c'
--- a/unittest/mysys/waiting_threads-t.c 2010-01-28 14:49:14 +0000
+++ b/unittest/mysys/waiting_threads-t.c 2010-03-30 12:36:49 +0000
@@ -258,7 +258,7 @@ void do_tests()
#define test_kill_strategy(X) \
diag("kill strategy: " #X); \
DBUG_EXECUTE("reset_file", \
- { rewind(DBUG_FILE); (void) ftruncate(fileno(DBUG_FILE), 0); }); \
+ { rewind(DBUG_FILE); my_chsize(fileno(DBUG_FILE), 0, 0, MYF(MY_WME)); }); \
DBUG_PRINT("info", ("kill strategy: " #X)); \
kill_strategy=X; \
do_one_test();
=== modified file 'vio/viossl.c'
--- a/vio/viossl.c 2010-01-29 10:42:31 +0000
+++ b/vio/viossl.c 2010-03-10 10:32:14 +0000
@@ -75,9 +75,11 @@ report_errors(SSL* ssl)
if (ssl)
{
+#ifndef DBUG_OFF
int error= SSL_get_error(ssl, l);
DBUG_PRINT("error", ("error: %s (%d)",
ERR_error_string(error, buf), error));
+#endif
}
DBUG_PRINT("info", ("socket_errno: %d", socket_errno));
1
0

[Maria-developers] Rev 2734: Maria WL#61 in file:///Users/bell/maria/bzr/work-maria-5.2-engine/
by sanja@askmonty.org 30 Mar '10
by sanja@askmonty.org 30 Mar '10
30 Mar '10
At file:///Users/bell/maria/bzr/work-maria-5.2-engine/
------------------------------------------------------------
revno: 2734
revision-id: sanja(a)askmonty.org-20100330163019-rjg72j5zifyl73nm
parent: psergey(a)askmonty.org-20091202142609-18bp41q8mejxl47t
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-engine
timestamp: Tue 2010-03-30 19:30:19 +0300
message:
Maria WL#61
Interface for maria extensions.
Alternative plugin interface with additional info (maturity and string version).
=== modified file 'CMakeLists.txt'
--- a/CMakeLists.txt 2009-10-03 19:24:13 +0000
+++ b/CMakeLists.txt 2010-03-30 16:30:19 +0000
@@ -250,7 +250,7 @@
ENDIF(WITH_${ENGINE}_STORAGE_ENGINE AND MYSQL_PLUGIN_STATIC)
IF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_${PLUGIN_NAME}_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${PLUGIN_NAME}_plugin")
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${PLUGIN_NAME})
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
@@ -268,7 +268,7 @@
# Special handling for partition(not really pluggable)
IF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_PARTITION_STORAGE_ENGINE")
- SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_partition_plugin")
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_partition_plugin")
ENDIF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
# Special handling for tmp tables with the maria engine
=== modified file 'config/ac-macros/plugins.m4'
--- a/config/ac-macros/plugins.m4 2009-04-25 10:05:32 +0000
+++ b/config/ac-macros/plugins.m4 2010-03-30 16:30:19 +0000
@@ -460,7 +460,7 @@
])
])
])
- mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]"
+ maria_plugin_defs="$maria_plugin_defs, [builtin_maria_]$2[_plugin]"
[with_plugin_]$2=yes
AC_MSG_RESULT([yes])
m4_ifdef([$11],[
=== modified file 'configure.in'
--- a/configure.in 2009-11-12 04:31:28 +0000
+++ b/configure.in 2010-03-30 16:30:19 +0000
@@ -2841,7 +2841,7 @@
AC_SUBST(mysql_plugin_dirs)
AC_SUBST(mysql_plugin_libs)
-AC_SUBST(mysql_plugin_defs)
+AC_SUBST(maria_plugin_defs)
# Now that sql_client_dirs and sql_server_dirs are stable, determine the union.
=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h 2009-09-07 20:50:10 +0000
+++ b/include/mysql/plugin.h 2010-03-30 16:30:19 +0000
@@ -65,7 +65,10 @@
Plugin API. Common for all plugin types.
*/
+/* MySQL plugin interface version */
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0100
+/* MariaDB plugin interface version */
+#define MARIA_PLUGIN_INTERFACE_VERSION 0x0100
/*
The allowable types of plugins
@@ -86,6 +89,14 @@
#define PLUGIN_LICENSE_GPL_STRING "GPL"
#define PLUGIN_LICENSE_BSD_STRING "BSD"
+/* definitions of code maturity for plugins */
+#define MariaDB_PLUGIN_MATURITY_UNKNOWN 0
+#define MariaDB_PLUGIN_MATURITY_EXPERIMENTAL 1
+#define MariaDB_PLUGIN_MATURITY_ALPHA 2
+#define MariaDB_PLUGIN_MATURITY_BETA 3
+#define MariaDB_PLUGIN_MATURITY_GAMMA 4
+#define MariaDB_PLUGIN_MATURITY_STABLE 5
+
/*
Macros for beginning and ending plugin declarations. Between
mysql_declare_plugin and mysql_declare_plugin_end there should
@@ -94,15 +105,29 @@
#ifndef MYSQL_DYNAMIC_PLUGIN
+
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
int PSIZE= sizeof(struct st_mysql_plugin); \
struct st_mysql_plugin DECLS[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+int VERSION= MARIA_PLUGIN_INTERFACE_VERSION; \
+int PSIZE= sizeof(struct st_maria_plugin); \
+struct st_maria_plugin DECLS[]= {
+
#else
+
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]= {
+
#endif
#define mysql_declare_plugin(NAME) \
@@ -111,7 +136,14 @@
builtin_ ## NAME ## _sizeof_struct_st_plugin, \
builtin_ ## NAME ## _plugin)
+#define maria_declare_plugin(NAME) \
+MARIA_DECLARE_PLUGIN__(NAME, \
+ builtin_maria_ ## NAME ## _plugin_interface_version, \
+ builtin_maria_ ## NAME ## _sizeof_struct_st_plugin, \
+ builtin_maria_ ## NAME ## _plugin)
+
#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0}}
+#define maria_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
/*
declarations for SHOW STATUS support in plugins
@@ -407,6 +439,30 @@
void * __reserved1; /* reserved for dependency checking */
};
+/*
+ MariaDB extension for plugins declaration structure.
+
+ It also copy current MySQL plugin fields to have more independency
+ in plugins extension
+*/
+
+struct st_maria_plugin
+{
+ int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ void *info; /* pointer to type-specific plugin descriptor */
+ const char *name; /* plugin name */
+ const char *author; /* plugin author (for SHOW PLUGINS) */
+ const char *descr; /* general descriptive text (for SHOW PLUGINS ) */
+ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */
+ int (*init)(void *); /* the function to invoke when plugin is loaded */
+ int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
+ unsigned int version; /* plugin version (for SHOW PLUGINS) */
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info; /* plugin version string */
+ int maturity; /* MariaDB_PLUGIN_MATURITY_XXX */
+};
+
/*************************************************************************
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
*/
=== modified file 'include/mysql/plugin.h.pp'
--- a/include/mysql/plugin.h.pp 2008-10-10 15:28:41 +0000
+++ b/include/mysql/plugin.h.pp 2010-03-30 16:30:19 +0000
@@ -46,6 +46,22 @@
struct st_mysql_sys_var **system_vars;
void * __reserved1;
};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ int maturity;
+};
enum enum_ftparser_mode
{
MYSQL_FTPARSER_SIMPLE_MODE= 0,
=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result 2009-10-19 17:14:48 +0000
+++ b/mysql-test/r/information_schema.result 2010-03-30 16:30:19 +0000
@@ -1175,7 +1175,7 @@
group by column_type order by num;
column_type group_concat(table_schema, '.', table_name) num
varchar(27) information_schema.COLUMNS 1
-varchar(7) information_schema.ROUTINES,information_schema.VIEWS 2
+varchar(7) information_schema.PLUGINS,information_schema.ROUTINES,information_schema.VIEWS 3
varchar(20) information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PROFILING 6
create table t1(f1 char(1) not null, f2 char(9) not null)
default character set utf8;
=== modified file 'plugin/daemon_example/daemon_example.cc'
--- a/plugin/daemon_example/daemon_example.cc 2007-06-27 14:49:12 +0000
+++ b/plugin/daemon_example/daemon_example.cc 2010-03-30 16:30:19 +0000
@@ -200,3 +200,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(daemon_example)
+{
+ MYSQL_DAEMON_PLUGIN,
+ &daemon_example_plugin,
+ "daemon_example",
+ "Brian Aker",
+ "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
+ PLUGIN_LICENSE_GPL,
+ daemon_example_plugin_init, /* Plugin Init */
+ daemon_example_plugin_deinit, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'plugin/fulltext/plugin_example.c'
--- a/plugin/fulltext/plugin_example.c 2007-04-26 19:26:04 +0000
+++ b/plugin/fulltext/plugin_example.c 2010-03-30 16:30:19 +0000
@@ -270,4 +270,21 @@
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(ftexample)
+{
+ MYSQL_FTPARSER_PLUGIN, /* type */
+ &simple_parser_descriptor, /* descriptor */
+ "simple_parser", /* name */
+ "MySQL AB", /* author */
+ "Simple Full-Text Parser", /* description */
+ PLUGIN_LICENSE_GPL,
+ simple_parser_plugin_init, /* init function (when loaded) */
+ simple_parser_plugin_deinit,/* deinit function (when unloaded) */
+ 0x0001, /* version */
+ simple_status, /* status variables */
+ simple_system_variables, /* system variables */
+ "0.01", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2009-09-07 20:50:10 +0000
+++ b/sql/ha_ndbcluster.cc 2010-03-30 16:30:19 +0000
@@ -10561,5 +10561,22 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ndbcluster)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ndbcluster_storage_engine,
+ ndbcluster_hton_name,
+ "MySQL AB",
+ "Clustered, fault-tolerant tables",
+ PLUGIN_LICENSE_GPL,
+ ndbcluster_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ ndb_status_variables_export,/* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
#endif
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2009-11-12 04:31:28 +0000
+++ b/sql/ha_partition.cc 2010-03-30 16:30:19 +0000
@@ -6510,5 +6510,22 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(partition)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &partition_storage_engine,
+ "partition",
+ "Mikael Ronstrom, MySQL AB",
+ "Partition Storage Engine Helper",
+ PLUGIN_LICENSE_GPL,
+ partition_initialize, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#endif
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2009-11-12 04:31:28 +0000
+++ b/sql/log.cc 2010-03-30 16:30:19 +0000
@@ -5795,3 +5795,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(binlog)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &binlog_storage_engine,
+ "binlog",
+ "MySQL AB",
+ "This is a pseudo storage engine to represent the binlog in a transaction",
+ PLUGIN_LICENSE_GPL,
+ binlog_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'sql/sql_builtin.cc.in'
--- a/sql/sql_builtin.cc.in 2006-12-31 01:29:11 +0000
+++ b/sql/sql_builtin.cc.in 2010-03-30 16:30:19 +0000
@@ -15,13 +15,12 @@
#include <mysql/plugin.h>
-typedef struct st_mysql_plugin builtin_plugin[];
-
-extern builtin_plugin
- builtin_binlog_plugin@mysql_plugin_defs@;
-
-struct st_mysql_plugin *mysqld_builtins[]=
+typedef struct st_maria_plugin builtin_maria_plugin[];
+
+extern builtin_maria_plugin
+ builtin_maria_binlog_plugin@maria_plugin_defs@;
+
+struct st_maria_plugin *mariadb_builtins[]=
{
- builtin_binlog_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
+ builtin_maria_binlog_plugin@maria_plugin_defs@,(struct st_maria_plugin *)0
};
-
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2009-11-12 04:31:28 +0000
+++ b/sql/sql_plugin.cc 2010-03-30 16:30:19 +0000
@@ -27,7 +27,7 @@
#define plugin_int_to_ref(A) &(A)
#endif
-extern struct st_mysql_plugin *mysqld_builtins[];
+extern struct st_maria_plugin *mariadb_builtins[];
/**
@note The order of the enumeration is critical.
@@ -82,6 +82,14 @@
"_mysql_sizeof_struct_st_plugin_";
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
static int min_plugin_interface_version= MYSQL_PLUGIN_INTERFACE_VERSION & ~0xFF;
+static const char *maria_plugin_interface_version_sym=
+ "_maria_plugin_interface_version_";
+static const char *maria_sizeof_st_plugin_sym=
+ "_maria_sizeof_struct_st_plugin_";
+static const char *maria_plugin_declarations_sym=
+ "_maria_plugin_declarations_";
+static int min_maria_plugin_interface_version=
+ MARIA_PLUGIN_INTERFACE_VERSION & ~0xFF;
#endif
/* Note that 'int version' must be the first field of every plugin
@@ -205,7 +213,7 @@
const char *list);
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
int *, char **);
-static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *,
+static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *,
struct st_plugin_int **);
static void unlock_variables(THD *thd, struct system_variables *vars);
static void cleanup_variables(THD *thd, struct system_variables *vars);
@@ -341,11 +349,248 @@
dlclose(p->handle);
#endif
my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR));
- if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION)
+ if (p->mariaversion != MARIA_PLUGIN_INTERFACE_VERSION)
my_free((uchar*)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
}
+/**
+ Reads data from mysql plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report What errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+ /* Determine interface version */
+ if (!sym)
+ {
+ free_plugin_mem(plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_interface_version_sym);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= 0;
+ plugin_dl->mysqlversion= *(int *)sym;
+ /* Versioning */
+ if (plugin_dl->mysqlversion < min_plugin_interface_version ||
+ (plugin_dl->mysqlversion >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
+ "plugin interface version mismatch");
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ /* convert mysql declaration to maria one */
+ {
+ int i;
+ uint sizeof_st_plugin;
+ struct st_mysql_plugin *old;
+ struct st_maria_plugin *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ DBUG_ASSERT(min_plugin_interface_version == 0);
+ sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
+ }
+
+ for (i= 0;
+ ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc(i * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl->dl.length);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ {
+
+ cur->type= old->type;
+ cur->info= old->info;
+ cur->name= old->name;
+ cur->author= old->author;
+ cur->descr= old->descr;
+ cur->license= old->license;
+ cur->init= old->init;
+ cur->deinit= old->deinit;
+ cur->version= old->version;
+ cur->status_vars= old->status_vars;
+ cur->system_vars= old->system_vars;
+ /*
+ Something like this should be added to process
+ new mysql plugin versions:
+ if (plugin_dl->mysqlversion > 0x0100)
+ {
+ cur->newfield= CONSTANT_MEANS_UNKNOWN;
+ }
+ else
+ {
+ cur->newfield= old->newfield;
+ }
+ */
+ /* Maria only fields */
+ cur->version_info= "Unknown";
+ cur->maturity= MariaDB_PLUGIN_MATURITY_UNKNOWN;
+ }
+
+ plugin_dl->plugins= (struct st_maria_plugin *)cur;
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Reads data from maria plugin interface
+
+ @param plugin_dl Structure where the data should be put
+ @param sym Reverence on version info
+ @param dlpath Path to the module
+ @param report what errors should be reported
+
+ @retval FALSE OK
+ @retval TRUE ERROR
+*/
+
+static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl,
+ void *sym, char *dlpath,
+ int report)
+{
+ DBUG_ENTER("read_maria_plugin_info");
+
+ /* Determine interface version */
+ if (!(sym))
+ {
+ free_plugin_mem(plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_interface_version_sym);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_interface_version_sym);
+ DBUG_RETURN(TRUE);
+ }
+ plugin_dl->mariaversion= *(int *)sym;
+ plugin_dl->mysqlversion= 0;
+ /* Versioning */
+ if (plugin_dl->mariaversion < min_maria_plugin_interface_version ||
+ (plugin_dl->mariaversion >> 8) > (MARIA_PLUGIN_INTERFACE_VERSION >> 8))
+ {
+ free_plugin_mem(plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
+ "plugin interface version mismatch");
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, 0,
+ "plugin interface version mismatch");
+ DBUG_RETURN(TRUE);
+ }
+ /* Find plugin declarations */
+ if (!(sym= dlsym(plugin_dl->handle, maria_plugin_declarations_sym)))
+ {
+ free_plugin_mem(plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym);
+ DBUG_RETURN(TRUE);
+ }
+ if (plugin_dl->mariaversion != MARIA_PLUGIN_INTERFACE_VERSION)
+ {
+ int i;
+ uint sizeof_st_plugin;
+ struct st_maria_plugin *old, *cur;
+ char *ptr= (char *)sym;
+
+ if ((sym= dlsym(plugin_dl->handle, maria_sizeof_st_plugin_sym)))
+ sizeof_st_plugin= *(int *)sym;
+ else
+ {
+ free_plugin_mem(plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), sizeof_st_plugin_sym);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym);
+ DBUG_RETURN(TRUE);
+ }
+
+ for (i= 0;
+ ((struct st_maria_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_maria_plugin*)
+ my_malloc(i * sizeof(struct st_maria_plugin),
+ MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl->dl.length);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl->dl.length);
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old=(struct st_maria_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ }
+ plugin_dl->plugins= (struct st_maria_plugin *)sym;
+
+ DBUG_RETURN(FALSE);
+}
+
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
#ifdef HAVE_DLOPEN
@@ -399,98 +644,22 @@
sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, errno, errmsg);
DBUG_RETURN(0);
}
- /* Determine interface version */
- if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
- {
- free_plugin_mem(&plugin_dl);
- if (report & REPORT_TO_USER)
- my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_interface_version_sym);
- if (report & REPORT_TO_LOG)
- sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_interface_version_sym);
- DBUG_RETURN(0);
- }
- plugin_dl.version= *(int *)sym;
- /* Versioning */
- if (plugin_dl.version < min_plugin_interface_version ||
- (plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
- {
- free_plugin_mem(&plugin_dl);
- if (report & REPORT_TO_USER)
- my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
- "plugin interface version mismatch");
- if (report & REPORT_TO_LOG)
- sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, 0,
- "plugin interface version mismatch");
- DBUG_RETURN(0);
- }
- /* Find plugin declarations */
- if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
- {
- free_plugin_mem(&plugin_dl);
- if (report & REPORT_TO_USER)
- my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
- if (report & REPORT_TO_LOG)
- sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym);
- DBUG_RETURN(0);
- }
-
- if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
- {
- int i;
- uint sizeof_st_plugin;
- struct st_mysql_plugin *old, *cur;
- char *ptr= (char *)sym;
-
- if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym)))
- sizeof_st_plugin= *(int *)sym;
- else
- {
-#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
- free_plugin_mem(&plugin_dl);
- if (report & REPORT_TO_USER)
- my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), sizeof_st_plugin_sym);
- if (report & REPORT_TO_LOG)
- sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym);
- DBUG_RETURN(0);
-#else
- /*
- When the following assert starts failing, we'll have to switch
- to the upper branch of the #ifdef
- */
- DBUG_ASSERT(min_plugin_interface_version == 0);
- sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
-#endif
- }
-
- for (i= 0;
- ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- /* no op */;
-
- cur= (struct st_mysql_plugin*)
- my_malloc(i*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
- if (!cur)
- {
- free_plugin_mem(&plugin_dl);
- if (report & REPORT_TO_USER)
- my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
- if (report & REPORT_TO_LOG)
- sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
- DBUG_RETURN(0);
- }
- /*
- All st_plugin fields not initialized in the plugin explicitly, are
- set to 0. It matches C standard behaviour for struct initializers that
- have less values than the struct definition.
- */
- for (i=0;
- (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
-
- sym= cur;
- }
- plugin_dl.plugins= (struct st_mysql_plugin *)sym;
+
+ /* Checks which plugin interface present and reads info */
+ if (!(sym= dlsym(plugin_dl.handle, maria_plugin_interface_version_sym)))
+ {
+ if (read_mysql_plugin_info(&plugin_dl,
+ dlsym(plugin_dl.handle,
+ plugin_interface_version_sym),
+ dlpath,
+ report))
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ if (read_maria_plugin_info(&plugin_dl, sym, dlpath, report))
+ DBUG_RETURN(0);
+ }
/* Duplicate and convert dll name */
plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1;
@@ -718,7 +887,7 @@
int *argc, char **argv, int report)
{
struct st_plugin_int tmp;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
DBUG_ENTER("plugin_add");
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
{
@@ -1120,8 +1289,8 @@
{
uint i;
bool is_myisam;
- struct st_mysql_plugin **builtins;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin **builtins;
+ struct st_maria_plugin *plugin;
struct st_plugin_int tmp, *plugin_ptr, **reap;
MEM_ROOT tmp_root;
bool reaped_mandatory_plugin= FALSE;
@@ -1160,7 +1329,7 @@
/*
First we register builtin plugins
*/
- for (builtins= mysqld_builtins; *builtins; builtins++)
+ for (builtins= mariadb_builtins; *builtins; builtins++)
{
for (plugin= *builtins; plugin->info; plugin++)
{
@@ -1290,7 +1459,7 @@
}
-static bool register_builtin(struct st_mysql_plugin *plugin,
+static bool register_builtin(struct st_maria_plugin *plugin,
struct st_plugin_int *tmp,
struct st_plugin_int **ptr)
{
@@ -1326,7 +1495,7 @@
RETURN
false - plugin registered successfully
*/
-bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
+bool plugin_register_builtin(THD *thd, struct st_maria_plugin *plugin)
{
struct st_plugin_int tmp, *ptr;
bool result= true;
@@ -1455,7 +1624,7 @@
char buffer[FN_REFLEN];
LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
struct st_plugin_dl *plugin_dl;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
char *p= buffer;
DBUG_ENTER("plugin_load_list");
while (list)
=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h 2009-05-14 12:03:33 +0000
+++ b/sql/sql_plugin.h 2010-03-30 16:30:19 +0000
@@ -62,8 +62,9 @@
{
LEX_STRING dl;
void *handle;
- struct st_mysql_plugin *plugins;
- int version;
+ struct st_maria_plugin *plugins;
+ int mysqlversion;
+ int mariaversion;
uint ref_count; /* number of plugins loaded from the library */
};
@@ -72,7 +73,7 @@
struct st_plugin_int
{
LEX_STRING name;
- struct st_mysql_plugin *plugin;
+ struct st_maria_plugin *plugin;
struct st_plugin_dl *plugin_dl;
uint state;
uint ref_count; /* number of threads using the plugin */
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2009-11-12 04:31:28 +0000
+++ b/sql/sql_show.cc 2010-03-30 16:30:19 +0000
@@ -94,11 +94,21 @@
return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
}
+
+static const LEX_STRING maturity_name[]={
+ { C_STRING_WITH_LEN("Unknown") },
+ { C_STRING_WITH_LEN("Experimental") },
+ { C_STRING_WITH_LEN("Alpha") },
+ { C_STRING_WITH_LEN("Beta") },
+ { C_STRING_WITH_LEN("Gamma") },
+ { C_STRING_WITH_LEN("Stable") }};
+
+
static my_bool show_plugins(THD *thd, plugin_ref plugin,
void *arg)
{
TABLE *table= (TABLE*) arg;
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
CHARSET_INFO *cs= system_charset_info;
char version_buf[20];
@@ -143,7 +153,7 @@
table->field[5]->set_notnull();
table->field[6]->store(version_buf,
make_version_string(version_buf, sizeof(version_buf),
- plugin_dl->version),
+ plugin_dl->mariaversion),
cs);
table->field[6]->set_notnull();
}
@@ -186,6 +196,26 @@
}
table->field[9]->set_notnull();
+ if ((uint) plug->maturity <= MariaDB_PLUGIN_MATURITY_STABLE)
+ table->field[10]->store(maturity_name[plug->maturity].str,
+ maturity_name[plug->maturity].length,
+ cs);
+ else
+ {
+ DBUG_ASSERT(0);
+ table->field[10]->store("Unknown", 7, cs);
+ }
+ table->field[10]->set_notnull();
+
+ if (plug->version_info)
+ {
+ table->field[11]->store(plug->version_info,
+ strlen(plug->version_info), cs);
+ table->field[11]->set_notnull();
+ }
+ else
+ table->field[11]->set_null();
+
return schema_table_store_record(thd, table);
}
@@ -4293,7 +4323,7 @@
if (plugin_state(plugin) != PLUGIN_IS_READY)
{
- struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_maria_plugin *plug= plugin_decl(plugin);
if (!(wild && wild[0] &&
wild_case_compare(scs, plug->name,wild)))
{
@@ -6990,6 +7020,8 @@
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
+ {"PLUGIN_MATURITY", 12, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+ {"PLUGIN_AUTH_VERSION", 80, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
=== modified file 'storage/archive/ha_archive.cc'
--- a/storage/archive/ha_archive.cc 2009-09-07 20:50:10 +0000
+++ b/storage/archive/ha_archive.cc 2010-03-30 16:30:19 +0000
@@ -1642,4 +1642,21 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(archive)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &archive_storage_engine,
+ "ARCHIVE",
+ "Brian Aker, MySQL AB",
+ "Archive storage engine",
+ PLUGIN_LICENSE_GPL,
+ archive_db_init, /* Plugin Init */
+ archive_db_done, /* Plugin Deinit */
+ 0x0300 /* 3.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/blackhole/ha_blackhole.cc'
--- a/storage/blackhole/ha_blackhole.cc 2008-11-10 20:21:49 +0000
+++ b/storage/blackhole/ha_blackhole.cc 2010-03-30 16:30:19 +0000
@@ -369,3 +369,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(blackhole)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &blackhole_storage_engine,
+ "BLACKHOLE",
+ "MySQL AB",
+ "/dev/null storage engine (anything you write to it disappears)",
+ PLUGIN_LICENSE_GPL,
+ blackhole_init, /* Plugin Init */
+ blackhole_fini, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/csv/ha_tina.cc'
--- a/storage/csv/ha_tina.cc 2009-04-25 10:05:32 +0000
+++ b/storage/csv/ha_tina.cc 2010-03-30 16:30:19 +0000
@@ -1636,4 +1636,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
-
+maria_declare_plugin(csv)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &csv_storage_engine,
+ "CSV",
+ "Brian Aker, MySQL AB",
+ "CSV storage engine",
+ PLUGIN_LICENSE_GPL,
+ tina_init_func, /* Plugin Init */
+ tina_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/example/ha_example.cc'
--- a/storage/example/ha_example.cc 2008-02-24 13:12:17 +0000
+++ b/storage/example/ha_example.cc 2010-03-30 16:30:19 +0000
@@ -906,3 +906,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(example)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &example_storage_engine,
+ "EXAMPLE",
+ "Brian Aker, MySQL AB",
+ "Example storage engine",
+ PLUGIN_LICENSE_GPL,
+ example_init_func, /* Plugin Init */
+ example_done_func, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ NULL, /* status variables */
+ example_system_variables, /* system variables */
+ "0.1", /* string version */
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/federated/ha_federated.cc'
--- a/storage/federated/ha_federated.cc 2009-09-07 20:50:10 +0000
+++ b/storage/federated/ha_federated.cc 2010-03-30 16:30:19 +0000
@@ -3379,3 +3379,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federated_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith and Brian Aker, MySQL AB",
+ "Federated MySQL storage engine",
+ PLUGIN_LICENSE_GPL,
+ federated_db_init, /* Plugin Init */
+ federated_done, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/federatedx/ha_federatedx.cc'
--- a/storage/federatedx/ha_federatedx.cc 2009-11-03 11:08:09 +0000
+++ b/storage/federatedx/ha_federatedx.cc 2010-03-30 16:30:19 +0000
@@ -3485,9 +3485,26 @@
PLUGIN_LICENSE_GPL,
federatedx_db_init, /* Plugin Init */
federatedx_done, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
+ 0x0200 /* 2.0 */,
NULL, /* status variables */
NULL, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federatedx_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith",
+ "FederatedX pluggable storage engine",
+ PLUGIN_LICENSE_GPL,
+ federatedx_db_init, /* Plugin Init */
+ federatedx_done, /* Plugin Deinit */
+ 0x0200 /* 2.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "2.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/heap/ha_heap.cc'
--- a/storage/heap/ha_heap.cc 2009-09-07 20:50:10 +0000
+++ b/storage/heap/ha_heap.cc 2010-03-30 16:30:19 +0000
@@ -767,3 +767,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(heap)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &heap_storage_engine,
+ "MEMORY",
+ "MySQL AB",
+ "Hash based, stored in memory, useful for temporary tables",
+ PLUGIN_LICENSE_GPL,
+ heap_init,
+ NULL,
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/ibmdb2i/ha_ibmdb2i.cc'
--- a/storage/ibmdb2i/ha_ibmdb2i.cc 2009-07-08 09:10:01 +0000
+++ b/storage/ibmdb2i/ha_ibmdb2i.cc 2010-03-30 16:30:19 +0000
@@ -3357,3 +3357,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(ibmdb2i)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &ibmdb2i_storage_engine,
+ "IBMDB2I",
+ "The IBM development team in Rochester, Minnesota",
+ "IBM DB2 for i Storage Engine",
+ PLUGIN_LICENSE_GPL,
+ ibmdb2i_init_func, /* Plugin Init */
+ ibmdb2i_done_func, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ ibmdb2i_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_UNKNOWN /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc 2009-10-16 22:57:48 +0000
+++ b/storage/innobase/handler/ha_innodb.cc 2010-03-30 16:30:19 +0000
@@ -8684,6 +8684,23 @@
NULL /* reserved */
}
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase OY",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ innodb_status_variables_export, /* status variables */
+ innobase_system_variables, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE, /* maturity */
+}
+maria_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/innodb_plugin/handler/i_s.cc'
--- a/storage/innodb_plugin/handler/i_s.cc 2009-08-14 15:18:52 +0000
+++ b/storage/innodb_plugin/handler/i_s.cc 2010-03-30 16:30:19 +0000
@@ -455,6 +455,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -730,6 +783,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -913,6 +1019,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
@@ -1245,6 +1404,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1295,6 +1507,60 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -1511,6 +1777,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1561,6 +1880,60 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/*******************************************************************//**
Unbind a dynamic INFORMATION_SCHEMA table.
@return 0 on success */
=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc 2009-10-26 11:35:42 +0000
+++ b/storage/maria/ha_maria.cc 2010-03-30 16:30:19 +0000
@@ -3346,9 +3346,26 @@
PLUGIN_LICENSE_GPL,
ha_maria_init, /* Plugin Init */
NULL, /* Plugin Deinit */
- 0x0100, /* 1.0 */
+ 0x0105, /* 1.5 */
status_variables, /* status variables */
system_variables, /* system variables */
NULL
}
mysql_declare_plugin_end;
+maria_declare_plugin(maria)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &maria_storage_engine,
+ "MARIA",
+ "MySQL AB",
+ "Crash-safe tables with MyISAM heritage",
+ PLUGIN_LICENSE_GPL,
+ ha_maria_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0105, /* 1.5 */
+ status_variables, /* status variables */
+ system_variables, /* system variables */
+ "1.5", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc 2009-10-17 19:12:28 +0000
+++ b/storage/myisam/ha_myisam.cc 2010-03-30 16:30:19 +0000
@@ -2183,6 +2183,23 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisam)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisam_storage_engine,
+ "MyISAM",
+ "MySQL AB",
+ "Default engine as of MySQL 3.23 with great performance",
+ PLUGIN_LICENSE_GPL,
+ myisam_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
#ifdef HAVE_QUERY_CACHE
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2009-10-15 21:38:29 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-03-30 16:30:19 +0000
@@ -1289,3 +1289,20 @@
NULL /* config options */
}
mysql_declare_plugin_end;
+maria_declare_plugin(myisammrg)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisammrg_storage_engine,
+ "MRG_MYISAM",
+ "MySQL AB",
+ "Collection of identical MyISAM tables",
+ PLUGIN_LICENSE_GPL,
+ myisammrg_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+}
+maria_declare_plugin_end;
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- a/storage/pbxt/src/ha_pbxt.cc 2009-09-03 06:15:03 +0000
+++ b/storage/pbxt/src/ha_pbxt.cc 2010-03-30 16:30:19 +0000
@@ -5507,6 +5507,40 @@
drizzle_declare_plugin_end;
#else
mysql_declare_plugin_end;
+#ifdef MARIADB_BASE_VERSION
+maria_declare_plugin(pbxt)
+{ /* PBXT */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &pbxt_storage_engine,
+ "PBXT",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "High performance, multi-versioning transactional engine",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init, /* Plugin Init */
+ pbxt_end, /* Plugin Deinit */
+ 0x0001 /* 0.1 */,
+ NULL, /* status variables */
+ pbxt_system_variables, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+},
+{ /* PBXT_STATISTICS */
+ MYSQL_INFORMATION_SCHEMA_PLUGIN,
+ &pbxt_statitics,
+ "PBXT_STATISTICS",
+ "Paul McCullagh, PrimeBase Technologies GmbH",
+ "PBXT internal system statitics",
+ PLUGIN_LICENSE_GPL,
+ pbxt_init_statitics, /* plugin init */
+ pbxt_exit_statitics, /* plugin deinit */
+ 0x0005,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ "1.0.09g RC3", /* string version */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
+}
+maria_declare_plugin_end;
+#endif
#endif
#if defined(XT_WIN) && defined(XT_COREDUMP)
=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- a/storage/xtradb/handler/ha_innodb.cc 2009-10-16 22:57:48 +0000
+++ b/storage/xtradb/handler/ha_innodb.cc 2010-03-30 16:30:19 +0000
@@ -10540,6 +10540,38 @@
i_s_innodb_index_stats,
i_s_innodb_patches
mysql_declare_plugin_end;
+maria_declare_plugin(innobase)
+{ /* InnoDB */
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase Oy",
+ "Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ INNODB_VERSION_SHORT,
+ innodb_status_variables_export,/* status variables */
+ innobase_system_variables, /* system variables */
+ INNODB_VERSION_STR, /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
+},
+i_s_innodb_rseg_maria,
+i_s_innodb_buffer_pool_pages_maria,
+i_s_innodb_buffer_pool_pages_index_maria,
+i_s_innodb_buffer_pool_pages_blob_maria,
+i_s_innodb_trx_maria,
+i_s_innodb_locks_maria,
+i_s_innodb_lock_waits_maria,
+i_s_innodb_cmp_maria,
+i_s_innodb_cmp_reset_maria,
+i_s_innodb_cmpmem_maria,
+i_s_innodb_cmpmem_reset_maria,
+i_s_innodb_table_stats_maria,
+i_s_innodb_index_stats_maria,
+i_s_innodb_patches_maria
+maria_declare_plugin_end;
+
/** @brief Initialize the default value of innodb_commit_concurrency.
=== modified file 'storage/xtradb/handler/i_s.cc'
--- a/storage/xtradb/handler/i_s.cc 2009-09-15 10:46:35 +0000
+++ b/storage/xtradb/handler/i_s.cc 2010-03-30 16:30:19 +0000
@@ -390,6 +390,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_patches_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "XTRADB_ENHANCEMENTS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Percona"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Enhancements applied to InnoDB plugin"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_patches_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_fields_info[] =
{
@@ -1037,6 +1090,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1086,6 +1192,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool index pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -1135,6 +1294,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB buffer pool blob pages"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
static ST_FIELD_INFO innodb_trx_fields_info[] =
@@ -1370,6 +1582,60 @@
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_TRX"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB transactions"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_trx_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
static ST_FIELD_INFO innodb_locks_fields_info[] =
{
@@ -1645,6 +1911,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCKS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB conflicting locks"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_locks_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{
@@ -1828,6 +2147,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Innobase Oy"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_lock_waits_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
@@ -2160,6 +2532,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2210,6 +2635,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMP_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmp_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
/* Fields of the dynamic table information_schema.innodb_cmpmem. */
static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
{
@@ -2428,6 +2906,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
@@ -2478,6 +3009,60 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
+ " reset cumulated counts"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_cmpmem_reset_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
Unbind a dynamic INFORMATION_SCHEMA table. */
static
@@ -2657,6 +3242,59 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_rseg_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_RSEG"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB rollback segment information"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_rseg_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* string version */
+ /* const char * */
+ STRUCT_FLD(version_info, "1.0"),
+
+ /* Maturity */
+ /* int */
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
/***********************************************************************
*/
static ST_FIELD_INFO i_s_innodb_table_stats_info[] =
@@ -2937,6 +3575,23 @@
STRUCT_FLD(__reserved1, NULL)
};
+UNIV_INTERN struct st_maria_plugin i_s_innodb_table_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_TABLE_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB table statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_table_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats =
{
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
@@ -2952,3 +3607,20 @@
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_index_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_INDEX_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB index statistics in memory"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_index_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
+};
=== modified file 'storage/xtradb/handler/i_s.h'
--- a/storage/xtradb/handler/i_s.h 2009-06-25 01:43:25 +0000
+++ b/storage/xtradb/handler/i_s.h 2010-03-30 16:30:19 +0000
@@ -40,4 +40,19 @@
extern struct st_mysql_plugin i_s_innodb_table_stats;
extern struct st_mysql_plugin i_s_innodb_index_stats;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria;
+extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria;
+extern struct st_maria_plugin i_s_innodb_trx_maria;
+extern struct st_maria_plugin i_s_innodb_locks_maria;
+extern struct st_maria_plugin i_s_innodb_lock_waits_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_maria;
+extern struct st_maria_plugin i_s_innodb_cmp_reset_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_maria;
+extern struct st_maria_plugin i_s_innodb_cmpmem_reset_maria;
+extern struct st_maria_plugin i_s_innodb_patches_maria;
+extern struct st_maria_plugin i_s_innodb_rseg_maria;
+extern struct st_maria_plugin i_s_innodb_table_stats_maria;
+extern struct st_maria_plugin i_s_innodb_index_stats_maria;
+
#endif /* i_s_h */
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2790)
by knielsen@knielsen-hq.org 30 Mar '10
by knielsen@knielsen-hq.org 30 Mar '10
30 Mar '10
#At lp:maria
2790 knielsen(a)knielsen-hq.org 2010-03-30 [merge]
automerge
removed:
mysql-test/r/have_big5.require
mysql-test/r/have_cp1250_ch.require
mysql-test/r/have_cp1251.require
mysql-test/r/have_cp866.require
mysql-test/r/have_cp932.require
mysql-test/r/have_eucjpms.require
mysql-test/r/have_euckr.require
mysql-test/r/have_gb2312.require
mysql-test/r/have_gbk.require
mysql-test/r/have_koi8r.require
mysql-test/r/have_latin2_ch.require
mysql-test/r/have_sjis.require
mysql-test/r/have_tis620.require
mysql-test/r/have_ucs2.require
mysql-test/r/have_ujis.require
mysql-test/r/have_utf8.require
mysql-test/suite/maria/t/maria2-master.opt
storage/xtradb/handler/handler0vars.h
storage/xtradb/handler/win_delay_loader.cc
storage/xtradb/win-plugin/
storage/xtradb/win-plugin/README
storage/xtradb/win-plugin/win-plugin.diff
added:
BUILD/compile-bintar
BUILD/util.sh
mysql-test/extra/rpl_tests/rpl_mixing_engines.inc
mysql-test/extra/rpl_tests/rpl_not_null.test
mysql-test/extra/rpl_tests/rpl_set_null.test
mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test
mysql-test/include/binlog_inject_error.inc
mysql-test/include/have_collation.inc
mysql-test/include/truncate_file.inc
mysql-test/r/bug47671.result
mysql-test/r/create-uca.result
mysql-test/r/innodb-autoinc-44030.result
mysql-test/r/innodb-consistent.result
mysql-test/r/innodb_bug44571.result
mysql-test/r/innodb_bug46676.result
mysql-test/r/innodb_bug47167.result
mysql-test/r/innodb_utf8.result
mysql-test/r/sp_sync.result
mysql-test/r/udf_query_cache.result
mysql-test/std_data/bug47012.ARM
mysql-test/std_data/bug47012.ARZ
mysql-test/std_data/bug47012.frm
mysql-test/std_data/bug47142_master-bin.000001
mysql-test/suite/binlog/r/binlog_write_error.result
mysql-test/suite/binlog/t/binlog_write_error.test
mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result
mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test
mysql-test/suite/innodb/r/innodb_bug46676.result
mysql-test/suite/innodb/r/innodb_bug47167.result
mysql-test/suite/innodb/t/innodb_bug46676.test
mysql-test/suite/innodb/t/innodb_bug47167.test
mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result
mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test
mysql-test/suite/parts/t/partition_repair_myisam-master.opt
mysql-test/suite/pbxt/r/pbxt_xa.result
mysql-test/suite/pbxt/t/pbxt_xa.test
mysql-test/suite/pbxt/t/suite.opt
mysql-test/suite/rpl/r/rpl_geometry.result
mysql-test/suite/rpl/r/rpl_loaddata_concurrent.result
mysql-test/suite/rpl/r/rpl_loaddata_symlink.result
mysql-test/suite/rpl/r/rpl_manual_change_index_file.result
mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result
mysql-test/suite/rpl/r/rpl_not_null_innodb.result
mysql-test/suite/rpl/r/rpl_not_null_myisam.result
mysql-test/suite/rpl/r/rpl_row_trunc_temp.result
mysql-test/suite/rpl/r/rpl_set_null_innodb.result
mysql-test/suite/rpl/r/rpl_set_null_myisam.result
mysql-test/suite/rpl/r/rpl_stm_binlog_direct.result
mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result
mysql-test/suite/rpl/t/rpl_geometry.test
mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test
mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.opt
mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh
mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.opt
mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh
mysql-test/suite/rpl/t/rpl_loaddata_symlink.test
mysql-test/suite/rpl/t/rpl_manual_change_index_file.test
mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test
mysql-test/suite/rpl/t/rpl_not_null_innodb.test
mysql-test/suite/rpl/t/rpl_not_null_myisam.test
mysql-test/suite/rpl/t/rpl_row_trunc_temp.test
mysql-test/suite/rpl/t/rpl_set_null_innodb.test
mysql-test/suite/rpl/t/rpl_set_null_myisam.test
mysql-test/suite/rpl/t/rpl_stm_binlog_direct-master.opt
mysql-test/suite/rpl/t/rpl_stm_binlog_direct.test
mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test
mysql-test/suite/rpl_ndb/r/rpl_ndb_set_null.result
mysql-test/suite/rpl_ndb/t/rpl_ndb_set_null.test
mysql-test/t/bug47671-master.opt
mysql-test/t/bug47671.test
mysql-test/t/create-uca.test
mysql-test/t/innodb-autoinc-44030.test
mysql-test/t/innodb-consistent-master.opt
mysql-test/t/innodb-consistent.test
mysql-test/t/innodb_bug44571.test
mysql-test/t/innodb_bug46676.test
mysql-test/t/innodb_bug47167.test
mysql-test/t/innodb_utf8.test
mysql-test/t/mysqlbinlog2-master.opt
mysql-test/t/mysqlbinlog_row-master.opt
mysql-test/t/mysqlbinlog_row_innodb-master.opt
mysql-test/t/mysqlbinlog_row_myisam-master.opt
mysql-test/t/mysqlbinlog_row_trans-master.opt
mysql-test/t/partition_innodb-master.opt
mysql-test/t/sp_sync.test
mysql-test/t/udf_query_cache-master.opt
mysql-test/t/udf_query_cache.test
storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c
renamed:
mysql-test/suite/binlog/r/binlog_tbl_metadata.result => mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result
mysql-test/suite/binlog/t/binlog_tbl_metadata.test => mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
modified:
.bzrignore
BUILD/Makefile.am
BUILD/SETUP.sh
BUILD/compile-pentium64-gcov
BUILD/compile-pentium64-gprof
BUILD/compile-solaris-amd64-debug-forte*
BUILD/compile-solaris-x86-32*
BUILD/compile-solaris-x86-32-debug*
BUILD/compile-solaris-x86-32-debug-forte*
BUILD/compile-solaris-x86-forte-32*
Makefile.am
client/client_priv.h
client/mysql.cc
client/mysql_upgrade.c
client/mysqladmin.cc
client/mysqlbinlog.cc
client/mysqldump.c
client/mysqlslap.c
client/mysqltest.cc
config/ac-macros/libevent.m4
configure.in
extra/comp_err.c
extra/libevent/devpoll.c
extra/libevent/evbuffer.c
extra/libevent/kqueue.c
extra/libevent/select.c
extra/yassl/src/yassl_error.cpp
extra/yassl/taocrypt/include/asn.hpp
extra/yassl/taocrypt/src/asn.cpp
include/config-win.h
include/ft_global.h
include/m_string.h
include/maria.h
include/my_base.h
include/my_global.h
include/my_no_pthread.h
include/my_pthread.h
include/my_stacktrace.h
include/my_sys.h
include/myisam.h
include/mysql.h
include/mysql.h.pp
include/mysql_com.h
include/violite.h
libmysql/libmysql.c
libmysql/libmysql.def
libmysqld/CMakeLists.txt
libmysqld/libmysqld.def
mysql-test/collections/default.experimental
mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test
mysql-test/extra/rpl_tests/rpl_loaddata.test
mysql-test/extra/rpl_tests/rpl_row_func003.test
mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
mysql-test/extra/rpl_tests/rpl_stm_000001.test
mysql-test/include/default_mysqld.cnf
mysql-test/include/have_big5.inc
mysql-test/include/have_cp1250_ch.inc
mysql-test/include/have_cp1251.inc
mysql-test/include/have_cp866.inc
mysql-test/include/have_cp932.inc
mysql-test/include/have_eucjpms.inc
mysql-test/include/have_euckr.inc
mysql-test/include/have_gb2312.inc
mysql-test/include/have_gbk.inc
mysql-test/include/have_koi8r.inc
mysql-test/include/have_latin2_ch.inc
mysql-test/include/have_sjis.inc
mysql-test/include/have_tis620.inc
mysql-test/include/have_ucs2.inc
mysql-test/include/have_ujis.inc
mysql-test/include/have_utf8.inc
mysql-test/include/kill_query.inc
mysql-test/include/mtr_warnings.sql
mysql-test/include/ps_conv.inc
mysql-test/include/setup_fake_relay_log.inc
mysql-test/lib/My/SafeProcess.pm
mysql-test/lib/My/SafeProcess/safe_process.cc
mysql-test/lib/mtr_cases.pm
mysql-test/lib/v1/mysql-test-run.pl
mysql-test/mysql-test-run.pl
mysql-test/r/alter_table.result
mysql-test/r/archive.result
mysql-test/r/bug46080.result*
mysql-test/r/count_distinct.result
mysql-test/r/create.result
mysql-test/r/ctype_ucs.result
mysql-test/r/ctype_utf8.result
mysql-test/r/delayed.result
mysql-test/r/delete.result
mysql-test/r/foreign_key.result
mysql-test/r/fulltext.result
mysql-test/r/fulltext_order_by.result
mysql-test/r/func_concat.result
mysql-test/r/func_group.result
mysql-test/r/func_misc.result
mysql-test/r/func_str.result
mysql-test/r/func_time.result
mysql-test/r/gis.result
mysql-test/r/grant.result
mysql-test/r/grant2.result
mysql-test/r/group_min_max.result
mysql-test/r/information_schema.result
mysql-test/r/information_schema_all_engines.result
mysql-test/r/innodb-autoinc.result
mysql-test/r/innodb-index.result
mysql-test/r/innodb-timeout.result
mysql-test/r/innodb-zip.result
mysql-test/r/innodb.result
mysql-test/r/innodb_bug36169.result
mysql-test/r/innodb_bug44369.result
mysql-test/r/innodb_file_format.result
mysql-test/r/innodb_lock_wait_timeout_1.result
mysql-test/r/innodb_mysql.result
mysql-test/r/innodb_xtradb_bug317074.result
mysql-test/r/join_outer.result
mysql-test/r/myisam.result
mysql-test/r/mysql.result
mysql-test/r/mysql_upgrade.result
mysql-test/r/mysqlbinlog.result
mysql-test/r/mysqltest.result
mysql-test/r/olap.result
mysql-test/r/openssl_1.result
mysql-test/r/order_by.result
mysql-test/r/partition.result
mysql-test/r/partition_bug18198.result
mysql-test/r/partition_error.result
mysql-test/r/partition_innodb.result
mysql-test/r/partition_pruning.result
mysql-test/r/ps.result
mysql-test/r/ps_ddl.result
mysql-test/r/query_cache.result
mysql-test/r/query_cache_notembedded.result
mysql-test/r/range.result
mysql-test/r/select.result
mysql-test/r/show_check.result
mysql-test/r/sp-destruct.result
mysql-test/r/sp-security.result
mysql-test/r/sp-ucs2.result
mysql-test/r/sp.result
mysql-test/r/sp_notembedded.result
mysql-test/r/subselect.result
mysql-test/r/table_elim.result
mysql-test/r/trigger.result
mysql-test/r/trigger_notembedded.result
mysql-test/r/type_newdecimal.result
mysql-test/r/type_year.result
mysql-test/r/udf.result
mysql-test/r/union.result
mysql-test/r/user_var.result
mysql-test/r/variables.result
mysql-test/r/view.result
mysql-test/std_data/Index.xml
mysql-test/std_data/cacert.pem
mysql-test/std_data/client-cert.pem
mysql-test/std_data/client-key.pem
mysql-test/std_data/server-cert.pem
mysql-test/std_data/server-key.pem
mysql-test/std_data/server8k-cert.pem
mysql-test/std_data/server8k-key.pem
mysql-test/suite/binlog/r/binlog_index.result
mysql-test/suite/binlog/r/binlog_killed_simulate.result
mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
mysql-test/suite/binlog/r/binlog_stm_blackhole.result
mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
mysql-test/suite/binlog/r/binlog_stm_row.result
mysql-test/suite/binlog/r/binlog_unsafe.result
mysql-test/suite/binlog/t/binlog_index.test
mysql-test/suite/binlog/t/binlog_killed.test
mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test
mysql-test/suite/binlog/t/binlog_stm_row.test
mysql-test/suite/binlog/t/binlog_unsafe.test
mysql-test/suite/funcs_1/datadict/processlist_val.inc
mysql-test/suite/funcs_1/r/is_columns_is.result
mysql-test/suite/funcs_1/r/is_tables_is.result
mysql-test/suite/innodb/r/innodb-index.result
mysql-test/suite/innodb/t/innodb-consistent-master.opt
mysql-test/suite/innodb/t/innodb-index.test
mysql-test/suite/maria/r/maria-recover.result
mysql-test/suite/maria/r/maria3.result
mysql-test/suite/maria/t/maria-recover.test
mysql-test/suite/maria/t/maria-recovery2-master.opt
mysql-test/suite/maria/t/maria3.test
mysql-test/suite/parts/inc/part_blocked_sql_funcs_main.inc
mysql-test/suite/parts/inc/partition_timestamp.inc
mysql-test/suite/parts/r/part_blocked_sql_func_innodb.result
mysql-test/suite/parts/r/part_blocked_sql_func_myisam.result
mysql-test/suite/parts/r/partition_datetime_innodb.result
mysql-test/suite/parts/r/partition_datetime_myisam.result
mysql-test/suite/parts/r/partition_recover_myisam.result
mysql-test/suite/parts/t/partition_alter1_2_innodb.test
mysql-test/suite/parts/t/partition_alter2_1_innodb.test
mysql-test/suite/parts/t/partition_alter2_2_innodb.test
mysql-test/suite/parts/t/partition_alter4_innodb.test
mysql-test/suite/parts/t/partition_recover_myisam.test
mysql-test/suite/parts/t/rpl_partition.test
mysql-test/suite/pbxt/r/func_group.result
mysql-test/suite/pbxt/r/lock_multi.result
mysql-test/suite/pbxt/r/mysqlshow.result
mysql-test/suite/pbxt/r/partition_error.result
mysql-test/suite/pbxt/r/partition_pruning.result
mysql-test/suite/pbxt/t/lock_multi.test
mysql-test/suite/pbxt/t/partition_error.test
mysql-test/suite/rpl/r/rpl_create_if_not_exists.result
mysql-test/suite/rpl/r/rpl_do_grant.result
mysql-test/suite/rpl/r/rpl_drop_temp.result
mysql-test/suite/rpl/r/rpl_err_ignoredtable.result
mysql-test/suite/rpl/r/rpl_extraCol_innodb.result
mysql-test/suite/rpl/r/rpl_extraCol_myisam.result
mysql-test/suite/rpl/r/rpl_get_lock.result
mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
mysql-test/suite/rpl/r/rpl_killed_ddl.result
mysql-test/suite/rpl/r/rpl_loaddata.result
mysql-test/suite/rpl/r/rpl_loaddata_fatal.result
mysql-test/suite/rpl/r/rpl_loaddata_map.result
mysql-test/suite/rpl/r/rpl_misc_functions.result
mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result
mysql-test/suite/rpl/r/rpl_optimize.result
mysql-test/suite/rpl/r/rpl_relayspace.result
mysql-test/suite/rpl/r/rpl_row_create_table.result
mysql-test/suite/rpl/r/rpl_row_func003.result
mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result
mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result
mysql-test/suite/rpl/r/rpl_sp.result
mysql-test/suite/rpl/r/rpl_stm_000001.result
mysql-test/suite/rpl/r/rpl_stm_log.result
mysql-test/suite/rpl/r/rpl_stm_maria.result
mysql-test/suite/rpl/r/rpl_stm_until.result
mysql-test/suite/rpl/r/rpl_temporary.result
mysql-test/suite/rpl/r/rpl_trigger.result
mysql-test/suite/rpl/t/disabled.def
mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test
mysql-test/suite/rpl/t/rpl_create_if_not_exists.test
mysql-test/suite/rpl/t/rpl_do_grant.test
mysql-test/suite/rpl/t/rpl_drop_temp.test
mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
mysql-test/suite/rpl/t/rpl_get_lock.test
mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
mysql-test/suite/rpl/t/rpl_ignore_table.test
mysql-test/suite/rpl/t/rpl_killed_ddl.test
mysql-test/suite/rpl/t/rpl_misc_functions.test
mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test
mysql-test/suite/rpl/t/rpl_name_const.test
mysql-test/suite/rpl/t/rpl_optimize.test
mysql-test/suite/rpl/t/rpl_relayspace.test
mysql-test/suite/rpl/t/rpl_rotate_logs.test
mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
mysql-test/suite/rpl/t/rpl_row_create_table.test
mysql-test/suite/rpl/t/rpl_row_trig003.test
mysql-test/suite/rpl/t/rpl_stm_maria.test
mysql-test/suite/rpl/t/rpl_stm_until.test
mysql-test/suite/rpl/t/rpl_temporary.test
mysql-test/suite/rpl/t/rpl_timezone.test
mysql-test/suite/rpl/t/rpl_trigger.test
mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result
mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result
mysql-test/t/alter_table.test
mysql-test/t/archive.test
mysql-test/t/bug46080.test
mysql-test/t/count_distinct.test
mysql-test/t/create.test
mysql-test/t/ctype_latin1_de-master.opt
mysql-test/t/ctype_ucs.test
mysql-test/t/ctype_ucs2_def-master.opt
mysql-test/t/ctype_utf8.test
mysql-test/t/ddl_i18n_koi8r.test
mysql-test/t/ddl_i18n_utf8.test
mysql-test/t/delayed.test
mysql-test/t/delete.test
mysql-test/t/disabled.def
mysql-test/t/foreign_key.test
mysql-test/t/fulltext.test
mysql-test/t/fulltext2.test
mysql-test/t/fulltext_order_by.test
mysql-test/t/func_concat.test
mysql-test/t/func_group.test
mysql-test/t/func_if.test
mysql-test/t/func_misc.test
mysql-test/t/func_str.test
mysql-test/t/gis.test
mysql-test/t/grant.test
mysql-test/t/grant2.test
mysql-test/t/group_min_max.test
mysql-test/t/information_schema.test
mysql-test/t/innodb-analyze.test
mysql-test/t/innodb-autoinc.test
mysql-test/t/innodb-index.test
mysql-test/t/innodb-master.opt
mysql-test/t/innodb-semi-consistent-master.opt
mysql-test/t/innodb-timeout.test
mysql-test/t/innodb-use-sys-malloc-master.opt
mysql-test/t/innodb-zip.test
mysql-test/t/innodb.test
mysql-test/t/innodb_bug34300.test
mysql-test/t/innodb_bug36169.test
mysql-test/t/innodb_bug36172.test
mysql-test/t/innodb_bug42101-nonzero-master.opt
mysql-test/t/innodb_bug44369.test
mysql-test/t/innodb_file_format.test
mysql-test/t/innodb_information_schema.test
mysql-test/t/innodb_lock_wait_timeout_1.test
mysql-test/t/innodb_mysql.test
mysql-test/t/innodb_xtradb_bug317074.test
mysql-test/t/join_outer.test
mysql-test/t/lock_multi.test
mysql-test/t/myisam.test
mysql-test/t/mysql.test
mysql-test/t/mysql_upgrade.test
mysql-test/t/mysqlbinlog.test
mysql-test/t/mysqltest.test
mysql-test/t/olap.test
mysql-test/t/openssl_1.test
mysql-test/t/order_by.test
mysql-test/t/partition.test
mysql-test/t/partition_bug18198.test
mysql-test/t/partition_error.test
mysql-test/t/partition_innodb.test
mysql-test/t/partition_innodb_semi_consistent.test
mysql-test/t/partition_pruning.test
mysql-test/t/ps.test
mysql-test/t/ps_ddl.test
mysql-test/t/query_cache.test
mysql-test/t/query_cache_debug.test
mysql-test/t/query_cache_notembedded.test
mysql-test/t/query_cache_ps_no_prot.test
mysql-test/t/query_cache_ps_ps_prot.test
mysql-test/t/range.test
mysql-test/t/select.test
mysql-test/t/show_check-master.opt
mysql-test/t/show_check.test
mysql-test/t/sp-destruct.test
mysql-test/t/sp-security.test
mysql-test/t/sp-ucs2.test
mysql-test/t/sp.test
mysql-test/t/sp_notembedded.test
mysql-test/t/subselect.test
mysql-test/t/table_elim.test
mysql-test/t/trigger.test
mysql-test/t/trigger_notembedded.test
mysql-test/t/type_newdecimal.test
mysql-test/t/type_year.test
mysql-test/t/udf.test
mysql-test/t/union.test
mysql-test/t/user_var.test
mysql-test/t/variables.test
mysql-test/t/view.test
mysql-test/valgrind.supp
mysys/charset.c
mysys/default.c
mysys/mf_keycache.c
mysys/mf_pack.c
mysys/my_file.c
mysys/my_gethostbyname.c
mysys/my_getopt.c
mysys/my_init.c
mysys/my_sync.c
mysys/my_thr_init.c
mysys/my_uuid.c
mysys/my_winthread.c
mysys/stacktrace.c
netware/libmysqlmain.c
scripts/make_win_bin_dist
scripts/mysql_secure_installation.pl.in
scripts/mysql_secure_installation.sh
scripts/mysql_system_tables_fix.sql
scripts/mysqlbug.sh
scripts/mysqld_multi.sh
server-tools/instance-manager/instance_map.cc
server-tools/instance-manager/listener.cc
server-tools/instance-manager/options.cc
server-tools/instance-manager/user_map.cc
sql-bench/bench-init.pl.sh
sql-bench/server-cfg.sh
sql-bench/test-ATIS.sh
sql-bench/test-alter-table.sh
sql-bench/test-big-tables.sh
sql-bench/test-connect.sh
sql-bench/test-create.sh
sql-bench/test-select.sh
sql-bench/test-transactions.sh
sql-bench/test-wisconsin.sh
sql-common/client.c
sql/CMakeLists.txt
sql/event_data_objects.cc
sql/event_db_repository.cc
sql/event_scheduler.cc*
sql/events.cc
sql/field.cc
sql/field.h
sql/filesort.cc
sql/ha_ndbcluster.cc
sql/ha_partition.cc
sql/ha_partition.h
sql/handler.cc
sql/handler.h
sql/item.cc
sql/item.h
sql/item_cmpfunc.cc
sql/item_cmpfunc.h
sql/item_create.cc
sql/item_create.h
sql/item_func.cc
sql/item_func.h
sql/item_geofunc.cc
sql/item_strfunc.cc
sql/item_strfunc.h
sql/item_subselect.cc
sql/item_subselect.h
sql/item_sum.cc
sql/item_sum.h
sql/item_timefunc.cc
sql/item_timefunc.h
sql/item_xmlfunc.cc
sql/lock.cc
sql/log.cc
sql/log.h
sql/log_event.cc
sql/log_event.h
sql/log_event_old.cc
sql/mysql_priv.h
sql/mysqld.cc
sql/net_serv.cc
sql/opt_range.cc
sql/opt_table_elimination.cc
sql/repl_failsafe.cc
sql/rpl_injector.cc
sql/rpl_record.cc
sql/rpl_record.h
sql/rpl_rli.cc
sql/rpl_rli.h
sql/rpl_tblmap.cc
sql/rpl_utility.h
sql/set_var.cc
sql/share/errmsg.txt
sql/slave.cc
sql/sp.cc
sql/sp.h
sql/sp_cache.cc
sql/sp_head.cc
sql/sp_head.h
sql/sp_pcontext.h
sql/sp_rcontext.cc
sql/sql_acl.cc
sql/sql_acl.h
sql/sql_base.cc
sql/sql_cache.cc
sql/sql_cache.h
sql/sql_class.cc
sql/sql_class.h
sql/sql_connect.cc
sql/sql_crypt.cc
sql/sql_crypt.h
sql/sql_db.cc
sql/sql_delete.cc
sql/sql_insert.cc
sql/sql_lex.cc
sql/sql_load.cc
sql/sql_parse.cc
sql/sql_partition.cc
sql/sql_partition.h
sql/sql_plugin.cc
sql/sql_plugin.h
sql/sql_prepare.cc
sql/sql_profile.cc
sql/sql_profile.h
sql/sql_rename.cc
sql/sql_repl.cc
sql/sql_select.cc
sql/sql_select.h
sql/sql_servers.cc
sql/sql_show.cc
sql/sql_table.cc
sql/sql_tablespace.cc
sql/sql_test.cc
sql/sql_trigger.cc
sql/sql_udf.cc
sql/sql_union.cc
sql/sql_update.cc
sql/sql_view.cc
sql/sql_yacc.yy
sql/table.cc
sql/table.h
sql/udf_example.def
storage/archive/CMakeLists.txt*
storage/archive/azio.c
storage/archive/azlib.h
storage/archive/ha_archive.cc
storage/example/ha_example.h
storage/federated/CMakeLists.txt*
storage/federatedx/ha_federatedx.cc
storage/ibmdb2i/db2i_constraints.cc
storage/ibmdb2i/ha_ibmdb2i.cc
storage/innobase/btr/btr0btr.c
storage/innobase/data/data0type.c
storage/innobase/fil/fil0fil.c
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.h
storage/innobase/include/fil0fil.h
storage/innobase/include/ha_prototypes.h
storage/innobase/include/lock0lock.h
storage/innobase/include/mach0data.h
storage/innobase/include/mach0data.ic
storage/innobase/include/mtr0mtr.h
storage/innobase/include/os0file.h
storage/innobase/include/srv0srv.h
storage/innobase/include/trx0trx.h
storage/innobase/lock/lock0lock.c
storage/innobase/log/log0log.c
storage/innobase/log/log0recv.c
storage/innobase/os/os0file.c
storage/innobase/row/row0mysql.c
storage/innobase/row/row0sel.c
storage/innobase/srv/srv0srv.c
storage/innobase/srv/srv0start.c
storage/innobase/trx/trx0trx.c
storage/innobase/ut/ut0ut.c
storage/innodb_plugin/ChangeLog
storage/innodb_plugin/btr/btr0btr.c
storage/innodb_plugin/btr/btr0sea.c
storage/innodb_plugin/buf/buf0buf.c
storage/innodb_plugin/data/data0type.c
storage/innodb_plugin/dict/dict0dict.c
storage/innodb_plugin/fil/fil0fil.c
storage/innodb_plugin/handler/ha_innodb.cc
storage/innodb_plugin/handler/ha_innodb.h
storage/innodb_plugin/handler/handler0alter.cc
storage/innodb_plugin/ibuf/ibuf0ibuf.c
storage/innodb_plugin/include/btr0sea.h
storage/innodb_plugin/include/db0err.h
storage/innodb_plugin/include/dict0dict.h
storage/innodb_plugin/include/fil0fil.h
storage/innodb_plugin/include/ha_prototypes.h
storage/innodb_plugin/include/ibuf0ibuf.h
storage/innodb_plugin/include/lock0lock.h
storage/innodb_plugin/include/log0log.h
storage/innodb_plugin/include/log0recv.h
storage/innodb_plugin/include/mem0mem.h
storage/innodb_plugin/include/mem0pool.h
storage/innodb_plugin/include/os0file.h
storage/innodb_plugin/include/pars0pars.h
storage/innodb_plugin/include/srv0srv.h
storage/innodb_plugin/include/thr0loc.h
storage/innodb_plugin/include/trx0i_s.h
storage/innodb_plugin/include/trx0purge.h
storage/innodb_plugin/include/trx0rseg.h
storage/innodb_plugin/include/trx0sys.h
storage/innodb_plugin/include/trx0trx.h
storage/innodb_plugin/include/trx0undo.h
storage/innodb_plugin/include/univ.i
storage/innodb_plugin/include/usr0sess.h
storage/innodb_plugin/lock/lock0lock.c
storage/innodb_plugin/log/log0log.c
storage/innodb_plugin/log/log0recv.c
storage/innodb_plugin/mem/mem0dbg.c
storage/innodb_plugin/mem/mem0pool.c
storage/innodb_plugin/os/os0file.c
storage/innodb_plugin/os/os0sync.c
storage/innodb_plugin/os/os0thread.c
storage/innodb_plugin/pars/lexyy.c
storage/innodb_plugin/pars/pars0lex.l
storage/innodb_plugin/que/que0que.c
storage/innodb_plugin/row/row0merge.c
storage/innodb_plugin/row/row0mysql.c
storage/innodb_plugin/srv/srv0srv.c
storage/innodb_plugin/srv/srv0start.c
storage/innodb_plugin/sync/sync0arr.c
storage/innodb_plugin/sync/sync0sync.c
storage/innodb_plugin/thr/thr0loc.c
storage/innodb_plugin/trx/trx0i_s.c
storage/innodb_plugin/trx/trx0purge.c
storage/innodb_plugin/trx/trx0rseg.c
storage/innodb_plugin/trx/trx0sys.c
storage/innodb_plugin/trx/trx0trx.c
storage/innodb_plugin/trx/trx0undo.c
storage/innodb_plugin/usr/usr0sess.c
storage/innodb_plugin/ut/ut0mem.c
storage/maria/ft_maria.c
storage/maria/ha_maria.cc
storage/maria/ma_blockrec.c
storage/maria/ma_check.c
storage/maria/ma_close.c
storage/maria/ma_create.c
storage/maria/ma_delete.c
storage/maria/ma_extra.c
storage/maria/ma_key_recover.h
storage/maria/ma_locking.c
storage/maria/ma_loghandler.c
storage/maria/ma_page.c
storage/maria/ma_recovery.c
storage/maria/ma_rkey.c
storage/maria/ma_search.c
storage/maria/ma_test3.c
storage/maria/ma_write.c
storage/maria/maria_def.h
storage/myisam/ft_boolean_search.c
storage/myisam/ft_myisam.c
storage/myisam/ft_nlq_search.c
storage/myisam/ft_parser.c
storage/myisam/ft_stopwords.c
storage/myisam/ftdefs.h
storage/myisam/mi_check.c
storage/myisam/mi_close.c
storage/myisam/mi_create.c
storage/myisam/mi_extra.c
storage/myisam/mi_open.c
storage/myisam/mi_packrec.c
storage/myisam/mi_static.c
storage/myisam/mi_test3.c
storage/myisam/mi_write.c
storage/myisam/myisamdef.h
storage/myisammrg/ha_myisammrg.cc
storage/myisammrg/myrg_open.c
storage/ndb/plug.in
storage/pbxt/src/ha_pbxt.cc
storage/pbxt/src/restart_xt.cc
storage/pbxt/src/thread_xt.cc
storage/pbxt/src/thread_xt.h
storage/xtradb/CMakeLists.txt
storage/xtradb/ChangeLog
storage/xtradb/Makefile.am
storage/xtradb/btr/btr0btr.c
storage/xtradb/btr/btr0cur.c
storage/xtradb/btr/btr0sea.c
storage/xtradb/buf/buf0buddy.c
storage/xtradb/buf/buf0buf.c
storage/xtradb/buf/buf0flu.c
storage/xtradb/buf/buf0lru.c
storage/xtradb/buf/buf0rea.c
storage/xtradb/data/data0type.c
storage/xtradb/dict/dict0crea.c
storage/xtradb/dict/dict0dict.c
storage/xtradb/fil/fil0fil.c
storage/xtradb/fsp/fsp0fsp.c
storage/xtradb/handler/ha_innodb.cc
storage/xtradb/handler/ha_innodb.h
storage/xtradb/handler/handler0alter.cc
storage/xtradb/handler/i_s.cc
storage/xtradb/handler/i_s.h
storage/xtradb/handler/innodb_patch_info.h
storage/xtradb/ibuf/ibuf0ibuf.c
storage/xtradb/include/btr0cur.h
storage/xtradb/include/btr0sea.h
storage/xtradb/include/buf0buf.h
storage/xtradb/include/buf0buf.ic
storage/xtradb/include/buf0lru.h
storage/xtradb/include/buf0rea.h
storage/xtradb/include/buf0types.h
storage/xtradb/include/db0err.h
storage/xtradb/include/dict0crea.h
storage/xtradb/include/dict0dict.h
storage/xtradb/include/dict0mem.h
storage/xtradb/include/fil0fil.h
storage/xtradb/include/fsp0fsp.h
storage/xtradb/include/ibuf0ibuf.h
storage/xtradb/include/lock0lock.h
storage/xtradb/include/log0log.h
storage/xtradb/include/log0log.ic
storage/xtradb/include/log0recv.h
storage/xtradb/include/mem0mem.h
storage/xtradb/include/mem0pool.h
storage/xtradb/include/mtr0mtr.h
storage/xtradb/include/os0file.h
storage/xtradb/include/os0sync.h
storage/xtradb/include/page0page.h
storage/xtradb/include/page0page.ic
storage/xtradb/include/page0zip.h
storage/xtradb/include/pars0pars.h
storage/xtradb/include/rem0cmp.h
storage/xtradb/include/rem0rec.ic
storage/xtradb/include/row0ins.h
storage/xtradb/include/row0mysql.h
storage/xtradb/include/srv0srv.h
storage/xtradb/include/sync0rw.h
storage/xtradb/include/sync0sync.h
storage/xtradb/include/thr0loc.h
storage/xtradb/include/trx0i_s.h
storage/xtradb/include/trx0purge.h
storage/xtradb/include/trx0rec.h
storage/xtradb/include/trx0rec.ic
storage/xtradb/include/trx0roll.h
storage/xtradb/include/trx0rseg.h
storage/xtradb/include/trx0sys.h
storage/xtradb/include/trx0sys.ic
storage/xtradb/include/trx0trx.h
storage/xtradb/include/trx0types.h
storage/xtradb/include/trx0undo.h
storage/xtradb/include/univ.i
storage/xtradb/include/usr0sess.h
storage/xtradb/include/ut0auxconf.h
storage/xtradb/include/ut0byte.h
storage/xtradb/include/ut0byte.ic
storage/xtradb/include/ut0lst.h
storage/xtradb/include/ut0ut.h
storage/xtradb/lock/lock0lock.c
storage/xtradb/log/log0log.c
storage/xtradb/log/log0recv.c
storage/xtradb/mem/mem0dbg.c
storage/xtradb/mem/mem0mem.c
storage/xtradb/mem/mem0pool.c
storage/xtradb/mtr/mtr0mtr.c
storage/xtradb/os/os0file.c
storage/xtradb/os/os0proc.c
storage/xtradb/os/os0sync.c
storage/xtradb/os/os0thread.c
storage/xtradb/page/page0cur.c
storage/xtradb/page/page0page.c
storage/xtradb/page/page0zip.c
storage/xtradb/pars/lexyy.c
storage/xtradb/pars/pars0lex.l
storage/xtradb/plug.in
storage/xtradb/que/que0que.c
storage/xtradb/rem/rem0cmp.c
storage/xtradb/row/row0ins.c
storage/xtradb/row/row0merge.c
storage/xtradb/row/row0mysql.c
storage/xtradb/row/row0sel.c
storage/xtradb/scripts/install_innodb_plugins.sql
storage/xtradb/scripts/install_innodb_plugins_win.sql
storage/xtradb/srv/srv0srv.c
storage/xtradb/srv/srv0start.c
storage/xtradb/sync/sync0arr.c
storage/xtradb/sync/sync0rw.c
storage/xtradb/sync/sync0sync.c
storage/xtradb/thr/thr0loc.c
storage/xtradb/trx/trx0i_s.c
storage/xtradb/trx/trx0purge.c
storage/xtradb/trx/trx0rec.c
storage/xtradb/trx/trx0roll.c
storage/xtradb/trx/trx0rseg.c
storage/xtradb/trx/trx0sys.c
storage/xtradb/trx/trx0trx.c
storage/xtradb/trx/trx0undo.c
storage/xtradb/usr/usr0sess.c
storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c
storage/xtradb/ut/ut0mem.c
storage/xtradb/ut/ut0ut.c
strings/Makefile.am
strings/ctype-ucs2.c
strings/ctype-utf8.c
strings/strmov.c
support-files/Makefile.am
support-files/compiler_warnings.supp
support-files/mysql.spec.sh
tests/mysql_client_test.c
unittest/mysys/waiting_threads-t.c
vio/vio.c
vio/viosocket.c
vio/viossl.c
win/configure.js
mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result
mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
=== modified file '.bzrignore'
--- a/.bzrignore 2009-12-22 13:50:20 +0000
+++ b/.bzrignore 2010-01-29 18:42:22 +0000
@@ -40,15 +40,15 @@
*.dsp
*.Po
*.Plo
-*/*.dir/*
+*.dir/
*/*_pure_*warnings
*/.deps
*/.libs/*
*/.pure
-*/debug/*
-*/minsizerel/*
-*/release/*
-*/relwithdebinfo/*
+debug/
+MinSizeRel/
+Release/
+RelWithDebInfo/
*~
.*.swp
./CMakeCache.txt
@@ -96,7 +96,7 @@ BitKeeper/tmp/gone
BitKeeper/tmp
BitKeeper/log
BitKeeper/etc/SCCS
-CMakeFiles/*
+CMakeFiles/
COPYING
COPYING.LIB
Docs/#manual.texi#
=== modified file 'BUILD/Makefile.am'
--- a/BUILD/Makefile.am 2009-08-29 19:04:46 +0000
+++ b/BUILD/Makefile.am 2010-01-07 13:03:54 +0000
@@ -34,6 +34,7 @@ EXTRA_DIST = FINISH.sh \
compile-amd64-max \
compile-amd64-max-sci \
compile-amd64-valgrind-max \
+ compile-bintar \
compile-darwin-mwcc \
compile-dist \
compile-hpux11-parisc2-aCC \
@@ -80,7 +81,8 @@ EXTRA_DIST = FINISH.sh \
compile-solaris-x86-32 \
compile-solaris-x86-32-debug \
compile-solaris-x86-32-debug-forte \
- compile-solaris-x86-forte-32
+ compile-solaris-x86-forte-32 \
+ util.sh
# Don't update the files from bitkeeper
%::SCCS/s.%
=== modified file 'BUILD/SETUP.sh'
--- a/BUILD/SETUP.sh 2010-01-04 08:47:15 +0000
+++ b/BUILD/SETUP.sh 2010-03-30 16:16:57 +0000
@@ -86,15 +86,9 @@ set -e
#
path=`dirname $0`
. "$path/check-cpu"
+. "$path/util.sh"
-export AM_MAKEFLAGS
-# Default to a parallel build, but only if AM_MAKEFLAGS is not set.
-# (So buildbots can easily disable this behaviour if required.)
-if test -z "$AM_MAKEFLAGS"
-then
- AM_MAKEFLAGS="-j 6"
-fi
-
+get_make_parallel_flag
# SSL library to use.--with-ssl will select our bundled yaSSL
# implementation of SSL. To use openSSl you will nee too point out
=== added file 'BUILD/compile-bintar'
--- a/BUILD/compile-bintar 1970-01-01 00:00:00 +0000
+++ b/BUILD/compile-bintar 2010-01-07 12:02:18 +0000
@@ -0,0 +1,81 @@
+#!/bin/bash
+#
+# MariaDB SQL server.
+# Copyright (C) 2010 Kristian Nielsen and Monty Program AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+# This script's purpose is to build the binary tarball packages for MariaDB
+# (currently only on Linux systems).
+#
+# Thus BUILD/compile-bintar from the appropriate source tarball will reproduce
+# such a release, provided the build environment (gcc version etc.) matches
+# (use scripts/make_binary_distribution after running this script to actually
+# create the binary tarball package).
+#
+# Note that packages are built from source tarballs not bzr checkouts.
+# Therefore, this script assumes autotools have already been run.
+#
+# We link libc dynamically, otherwise we get lots of problems loading
+# .so files at runtime (either system stuff like NSS, or server
+# plugins).
+#
+# We link libgcc statically (and avoid linking libstdc++ at all by
+# CXX=gcc), to avoid reduce nasty library version dependencies.
+
+test -f Makefile && make distclean
+
+path=`dirname $0`
+. $path/util.sh
+
+SYSTEM_TYPE="$(uname -o)"
+MACHINE_TYPE="$(uname -m)"
+
+# We cannot have a slash '/' in tarfile name.
+SYSTEM_TYPE="$(echo ${SYSTEM_TYPE} | sed -e 's/GNU\///')"
+
+# Get correct options for architecture into CPUOPT.
+get_cpuopt
+# Get correct -j option into AM_MAKEFLAGS
+get_make_parallel_flag
+
+# Use gcc rather than g++ to avoid linking libstdc++.so (which we don't need).
+COMP="gcc -static-libgcc"
+FLAGS="-O2 -fno-omit-frame-pointer -g -pipe -Wall $CPUOPT"
+
+# Don't press on in case of error.
+set -e
+
+CC="$COMP" CXX="$COMP" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \
+ ./configure \
+ --prefix=/usr/local/mysql \
+ --exec-prefix=/usr/local/mysql \
+ --libexecdir=/usr/local/mysql/bin \
+ --localstatedir=/usr/local/mysql/data \
+ \
+ --with-comment="(MariaDB - http://mariadb.com/)" \
+ --with-system-type="${SYSTEM_TYPE}" \
+ --with-machine-type="${MACHINE_TYPE}" \
+ \
+ --enable-shared --enable-static \
+ --with-client-ldflags=-static --with-mysqld-ldflags=-static \
+ --enable-thread-safe-client --enable-local-infile --with-big-tables \
+ --without-docs --with-extra-charsets=all \
+ --with-libwrap --with-ssl --with-readline --with-libevent --with-zlib-dir=bundled \
+ --with-partition --with-embedded-server \
+ --with-plugins=max-no-ndb \
+ --without-plugin-innodb_plugin
+
+make $AM_MAKEFLAGS
=== modified file 'BUILD/compile-pentium64-gcov'
--- a/BUILD/compile-pentium64-gcov 2007-08-16 00:10:16 +0000
+++ b/BUILD/compile-pentium64-gcov 2010-03-09 19:22:24 +0000
@@ -9,9 +9,9 @@ export CCACHE_DISABLE
export LDFLAGS="$gcov_link_flags"
-extra_flags="$pentium64_cflags $debug_cflags $max_cflags $gcov_compile_flags"
+extra_flags="$pentium64_cflags $max_cflags $gcov_compile_flags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
-extra_configs="$pentium64_configs $debug_configs $gcov_configs $max_configs"
+extra_configs="$pentium_configs $debug_configs $gcov_configs $max_configs --with-zlib-dir=bundled"
. "$path/FINISH.sh"
=== modified file 'BUILD/compile-pentium64-gprof'
--- a/BUILD/compile-pentium64-gprof 2007-08-16 00:10:16 +0000
+++ b/BUILD/compile-pentium64-gprof 2010-03-09 19:22:24 +0000
@@ -4,6 +4,6 @@ path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium64_cflags $gprof_compile_flags"
-extra_configs="$pentium64_configs $debug_configs $gprof_link_flags"
+extra_configs="$pentium_configs $max_configs $gprof_link_flags --with-zlib-dir=bundled"
. "$path/FINISH.sh"
=== modified file 'BUILD/compile-solaris-amd64-debug-forte' (properties changed: -x to +x)
=== modified file 'BUILD/compile-solaris-x86-32' (properties changed: -x to +x)
=== modified file 'BUILD/compile-solaris-x86-32-debug' (properties changed: -x to +x)
=== modified file 'BUILD/compile-solaris-x86-32-debug-forte' (properties changed: -x to +x)
=== modified file 'BUILD/compile-solaris-x86-forte-32' (properties changed: -x to +x)
=== added file 'BUILD/util.sh'
--- a/BUILD/util.sh 1970-01-01 00:00:00 +0000
+++ b/BUILD/util.sh 2010-01-28 22:34:22 +0000
@@ -0,0 +1,48 @@
+# MariaDB SQL server.
+# Copyright (C) 2010 Kristian Nielsen and Monty Program AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Setting cpu options.
+get_cpuopt () {
+ case "$(uname -o)" in
+ *Linux*)
+ case "$(gcc -dumpmachine)" in
+ x86_64-*)
+ # gcc barfs on -march=... on x64
+ CPUOPT="-m64 -mtune=generic"
+ ;;
+ *)
+ # we'd use i586 to not trip up mobile/lowpower devices
+ CPUOPT="-m32 -march=i586 -mtune=generic"
+ ;;
+ esac
+ ;;
+ *Solaris*)
+ # ToDo: handle 32-bit build? For now default to 64-bit.
+ CPUOPT="-D__sun -m64 -mtune=athlon64"
+ ;;
+ esac
+ return 0
+}
+
+# Default to a parallel build, but only if AM_MAKEFLAGS is not set.
+# (So buildbots can easily disable this behaviour if required.)
+get_make_parallel_flag () {
+ if test -z "$AM_MAKEFLAGS"
+ then
+ AM_MAKEFLAGS="-j 6"
+ fi
+ return 0
+}
=== modified file 'Makefile.am'
--- a/Makefile.am 2009-12-03 11:19:05 +0000
+++ b/Makefile.am 2010-01-15 15:27:55 +0000
@@ -208,10 +208,6 @@ test-bt-fast:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl $(MTR_EXTRA_OPTIONS) --force --comment=stress --suite=stress
-test-bt-fast2:
- -cd mysql-test ; MTR_BUILD_THREAD=auto \
- @PERL@ ./mysql-test-run.pl $(MTR_EXTRA_OPTIONS) --force --comment=ps --ps-protocol --report-features
-
test-bt-debug:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl $(MTR_EXTRA_OPTIONS) --comment=debug --force --timer \
=== modified file 'client/client_priv.h'
--- a/client/client_priv.h 2008-07-09 13:09:30 +0000
+++ b/client/client_priv.h 2010-03-04 08:03:07 +0000
@@ -31,6 +31,15 @@
# endif
#endif
+/* Version numbers for deprecation messages */
+#define VER_CELOSIA "5.6"
+
+#define WARN_DEPRECATED(Ver,Old,New) \
+ do { \
+ printf("Warning: The option '%s' is deprecated and will be removed " \
+ "in a future release. Please use %s instead.\n", (Old), (New)); \
+ } while(0);
+
enum options_client
{
OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
@@ -48,8 +57,8 @@ enum options_client
OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL,
OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION,
OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH,
- OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_CREATE_OPTIONS, OPT_SERVER_ARG,
- OPT_START_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME,
+ OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG,
+ OPT_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME,
OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT,
#ifdef HAVE_NDBCLUSTER_DB
OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING,
@@ -81,5 +90,7 @@ enum options_client
OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
OPT_WRITE_BINLOG, OPT_DUMP_DATE,
OPT_ABORT_SOURCE_ON_ERROR,
+ OPT_FIRST_SLAVE,
+ OPT_ALL,
OPT_MAX_CLIENT_OPTION
};
=== modified file 'client/mysql.cc'
--- a/client/mysql.cc 2009-12-03 11:34:11 +0000
+++ b/client/mysql.cc 2010-03-04 08:03:07 +0000
@@ -54,6 +54,9 @@ static char *server_version= NULL;
/* Array of options to pass to libemysqld */
#define MAX_SERVER_ARGS 64
+/* Version numbers for deprecation messages */
+#define VER_CELOSIA "5.6"
+
void* sql_alloc(unsigned size); // Don't use mysqld alloc for these
void sql_element_free(void *ptr);
#include "sql_string.h"
@@ -1349,7 +1352,7 @@ static struct my_option my_long_options[
(uchar**) &opt_rehash, (uchar**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
0, 0},
{"no-auto-rehash", 'A',
- "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
+ "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"batch", 'B',
"Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -1418,7 +1421,7 @@ static struct my_option my_long_options[
{"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
(uchar**) &line_numbers, (uchar**) &line_numbers, 0, GET_BOOL,
NO_ARG, 1, 0, 0, 0, 0, 0},
- {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG,
+ {"skip-line-numbers", 'L', "Don't write line number for errors.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"unbuffered", 'n', "Flush buffer after each query.", (uchar**) &unbuffered,
(uchar**) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -1426,7 +1429,7 @@ static struct my_option my_long_options[
(uchar**) &column_names, (uchar**) &column_names, 0, GET_BOOL,
NO_ARG, 1, 0, 0, 0, 0, 0},
{"skip-column-names", 'N',
- "Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead.",
+ "Don't write column names in results.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"set-variable", 'O',
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
@@ -1633,7 +1636,7 @@ get_one_option(int optid, const struct m
init_tee(argument);
break;
case OPT_NOTEE:
- printf("WARNING: option deprecated; use --disable-tee instead.\n");
+ WARN_DEPRECATED(VER_CELOSIA, "--no-tee", "--disable-tee");
if (opt_outfile)
end_tee();
break;
@@ -1656,7 +1659,7 @@ get_one_option(int optid, const struct m
}
break;
case OPT_NOPAGER:
- printf("WARNING: option deprecated; use --disable-pager instead.\n");
+ WARN_DEPRECATED(VER_CELOSIA, "--no-pager", "--disable-pager");
opt_nopager= 1;
break;
case OPT_MYSQL_PROTOCOL:
@@ -1702,12 +1705,18 @@ get_one_option(int optid, const struct m
if (!(status.line_buff= batch_readline_command(status.line_buff, argument)))
return 1;
break;
+ case 'g':
+ WARN_DEPRECATED(VER_CELOSIA, "-g, --no-named-commands", "--skip-named-commands");
+ break;
case 'o':
if (argument == disabled_my_option)
one_database= 0;
else
one_database= skip_updates= 1;
break;
+ case 'O':
+ WARN_DEPRECATED(VER_CELOSIA, "-O, --set-variable", "--variable-name=value");
+ break;
case 'p':
if (argument == disabled_my_option)
argument= (char*) ""; // Don't require password
@@ -3530,7 +3539,8 @@ print_table_data_vertically(MYSQL_RES *r
for (uint off=0; off < mysql_num_fields(result); off++)
{
field= mysql_fetch_field(result);
- tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
+ if (column_names)
+ tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
if (cur[off])
{
unsigned int i;
@@ -4215,7 +4225,7 @@ char *get_arg(char *line, my_bool get_ne
if (*ptr == '\\' && ptr[1]) // escaped character
{
// Remove the backslash
- strmov(ptr, ptr+1);
+ strmov_overlapp(ptr, ptr+1);
}
else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
{
@@ -4356,7 +4366,7 @@ com_status(String *buffer __attribute__(
Don't remove "limit 1",
it is protection againts SQL_SELECT_LIMIT=0
*/
- if (mysql_store_result_for_lazy(&result))
+ if (!mysql_store_result_for_lazy(&result))
{
MYSQL_ROW cur=mysql_fetch_row(result);
if (cur)
@@ -4401,7 +4411,7 @@ com_status(String *buffer __attribute__(
if (mysql_errno(&mysql) == CR_SERVER_GONE_ERROR)
return 0;
}
- if (mysql_store_result_for_lazy(&result))
+ if (!mysql_store_result_for_lazy(&result))
{
MYSQL_ROW cur=mysql_fetch_row(result);
if (cur)
@@ -4496,9 +4506,7 @@ server_version_string(MYSQL *con)
*/
if (server_version == NULL)
- {
- server_version= strdup(mysql_get_server_info(con));
- }
+ server_version= my_strdup(mysql_get_server_info(con), MYF(MY_WME));
}
return server_version ? server_version : "";
=== modified file 'client/mysql_upgrade.c'
--- a/client/mysql_upgrade.c 2009-12-03 11:34:11 +0000
+++ b/client/mysql_upgrade.c 2010-03-04 08:03:07 +0000
@@ -776,6 +776,10 @@ static int run_sql_fix_privilege_tables(
found_real_errors++;
print_line(line);
}
+ else if (strncmp(line, "WARNING", 7) == 0)
+ {
+ print_line(line);
+ }
} while ((line= get_line(line)) && *line);
}
=== modified file 'client/mysqladmin.cc'
--- a/client/mysqladmin.cc 2009-11-14 19:33:59 +0000
+++ b/client/mysqladmin.cc 2010-03-04 08:03:07 +0000
@@ -282,6 +282,9 @@ get_one_option(int optid, const struct m
charsets_dir = argument;
#endif
break;
+ case 'O':
+ WARN_DEPRECATED(VER_CELOSIA, "--set-variable", "--variable-name=value");
+ break;
case OPT_MYSQL_PROTOCOL:
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
opt->name);
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc 2009-12-03 11:19:05 +0000
+++ b/client/mysqlbinlog.cc 2010-03-04 08:03:07 +0000
@@ -41,6 +41,7 @@
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
+
char server_version[SERVER_VERSION_LENGTH];
ulong server_id = 0;
@@ -1060,7 +1061,7 @@ static struct my_option my_long_options[
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
(uchar**) &port, (uchar**) &port, 0, GET_INT, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
- {"position", 'j', "Deprecated. Use --start-position instead.",
+ {"position", OPT_POSITION, "Deprecated. Use --start-position instead.",
(uchar**) &start_position, (uchar**) &start_position, 0, GET_ULL,
REQUIRED_ARG, BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE,
/* COM_BINLOG_DUMP accepts only 4 bytes for the position */
@@ -1103,7 +1104,7 @@ static struct my_option my_long_options[
"(you should probably use quotes for your shell to set it properly).",
(uchar**) &start_datetime_str, (uchar**) &start_datetime_str,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"start-position", OPT_START_POSITION,
+ {"start-position", 'j',
"Start reading the binlog at position N. Applies to the first binlog "
"passed on the command line.",
(uchar**) &start_position, (uchar**) &start_position, 0, GET_ULL,
@@ -1314,6 +1315,9 @@ get_one_option(int optid, const struct m
case 'R':
remote_opt= 1;
break;
+ case OPT_POSITION:
+ WARN_DEPRECATED(VER_CELOSIA, "--position", "--start-position");
+ break;
case OPT_MYSQL_PROTOCOL:
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
opt->name);
@@ -1378,6 +1382,10 @@ static int parse_args(int *argc, char***
*/
static Exit_status safe_connect()
{
+ /* Close and old connections to MySQL */
+ if (mysql)
+ mysql_close(mysql);
+
mysql= mysql_init(NULL);
if (!mysql)
=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c 2009-10-15 21:38:29 +0000
+++ b/client/mysqldump.c 2010-03-04 08:03:07 +0000
@@ -179,7 +179,7 @@ HASH ignore_table;
static struct my_option my_long_options[] =
{
- {"all", 'a', "Deprecated. Use --create-options instead.",
+ {"all", OPT_ALL, "Deprecated. Use --create-options instead.",
(uchar**) &create_options, (uchar**) &create_options, 0, GET_BOOL, NO_ARG, 1,
0, 0, 0, 0, 0},
{"all-databases", 'A',
@@ -230,7 +230,7 @@ static struct my_option my_long_options[
{"compress", 'C', "Use compression in server/client protocol.",
(uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
- {"create-options", OPT_CREATE_OPTIONS,
+ {"create-options", 'a',
"Include all MySQL specific create options.",
(uchar**) &create_options, (uchar**) &create_options, 0, GET_BOOL, NO_ARG, 1,
0, 0, 0, 0, 0},
@@ -268,7 +268,7 @@ static struct my_option my_long_options[
(uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"extended-insert", 'e',
- "Allows utilization of the new, much faster INSERT syntax.",
+ "Use multiple-row INSERT syntax that include several VALUES lists.",
(uchar**) &extended_insert, (uchar**) &extended_insert, 0, GET_BOOL, NO_ARG,
1, 0, 0, 0, 0, 0},
{"fields-terminated-by", OPT_FTB,
@@ -282,7 +282,7 @@ static struct my_option my_long_options[
(uchar**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
(uchar**) &escaped, (uchar**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
+ {"first-slave", OPT_FIRST_SLAVE, "Deprecated, renamed to --lock-all-tables.",
(uchar**) &opt_lock_all_tables, (uchar**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
@@ -366,8 +366,7 @@ static struct my_option my_long_options[
NO_ARG, 0, 0, 0, 0, 0, 0},
{"no-data", 'd', "No row information.", (uchar**) &opt_no_data,
(uchar**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"no-set-names", 'N',
- "Deprecated. Use --skip-set-charset instead.",
+ {"no-set-names", 'N',"Suppress the SET NAMES statement",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"opt", OPT_OPTIMIZE,
"Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.",
@@ -760,6 +759,15 @@ get_one_option(int optid, const struct m
case '?':
usage();
exit(0);
+ case 'O':
+ WARN_DEPRECATED(VER_CELOSIA, "--set-variable", "--variable-name=value");
+ break;
+ case (int) OPT_ALL:
+ WARN_DEPRECATED(VER_CELOSIA, "--all", "--create-options");
+ break;
+ case (int) OPT_FIRST_SLAVE:
+ WARN_DEPRECATED(VER_CELOSIA, "--first-slave", "--lock-all-tables");
+ break;
case (int) OPT_MASTER_DATA:
if (!argument) /* work like in old versions */
opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
@@ -808,7 +816,7 @@ get_one_option(int optid, const struct m
&err_ptr, &err_len);
if (err_len)
{
- strmake(buff, err_ptr, min(sizeof(buff), err_len));
+ strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
exit(1);
}
@@ -4486,7 +4494,7 @@ static ulong find_set(TYPELIB *lib, cons
for (; pos != end && *pos != ','; pos++) ;
var_len= (uint) (pos - start);
- strmake(buff, start, min(sizeof(buff), var_len));
+ strmake(buff, start, min(sizeof(buff) - 1, var_len));
find= find_type(buff, lib, var_len);
if (!find)
{
=== modified file 'client/mysqlslap.c'
--- a/client/mysqlslap.c 2009-12-03 11:34:11 +0000
+++ b/client/mysqlslap.c 2010-01-29 18:42:22 +0000
@@ -292,6 +292,25 @@ static int gettimeofday(struct timeval *
}
#endif
+void set_mysql_connect_options(MYSQL *mysql)
+{
+ if (opt_compress)
+ mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS);
+#ifdef HAVE_OPENSSL
+ if (opt_use_ssl)
+ mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ opt_ssl_capath, opt_ssl_cipher);
+#endif
+ if (opt_protocol)
+ mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
+ mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+}
+
+
int main(int argc, char **argv)
{
MYSQL mysql;
@@ -323,20 +342,7 @@ int main(int argc, char **argv)
exit(1);
}
mysql_init(&mysql);
- if (opt_compress)
- mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
-#ifdef HAVE_OPENSSL
- if (opt_use_ssl)
- mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath, opt_ssl_cipher);
-#endif
- if (opt_protocol)
- mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
-#ifdef HAVE_SMEM
- if (shared_memory_base_name)
- mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
-#endif
- mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+ set_mysql_connect_options(&mysql);
if (!opt_only_print)
{
@@ -1815,6 +1821,7 @@ pthread_handler_t run_task(void *p)
my_progname, mysql_error(mysql));
exit(0);
}
+ set_mysql_connect_options(mysql);
if (mysql_thread_init())
{
@@ -1855,7 +1862,6 @@ limit_not_met:
my_progname, mysql_error(mysql));
exit(0);
}
-
if (slap_connect(mysql))
goto end;
}
@@ -2223,6 +2229,7 @@ slap_connect(MYSQL *mysql)
int x, connect_error= 1;
for (x= 0; x < 10; x++)
{
+ set_mysql_connect_options(mysql);
if (mysql_real_connect(mysql, host, user, opt_password,
create_schema_string,
opt_mysql_port,
=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc 2009-12-03 11:19:05 +0000
+++ b/client/mysqltest.cc 2010-01-28 14:49:14 +0000
@@ -657,7 +657,9 @@ public:
}
while ((bytes= fread(buf, 1, sizeof(buf), m_file)) > 0)
- fwrite(buf, 1, bytes, stderr);
+ if (fwrite(buf, 1, bytes, stderr))
+ die("Failed to write to '%s', errno: %d",
+ m_file_name, errno);
if (!lines)
{
@@ -1267,6 +1269,7 @@ void abort_not_supported_test(const char
DBUG_ENTER("abort_not_supported_test");
/* Print include filestack */
+ fflush(stdout);
fprintf(stderr, "The test '%s' is not supported by this installation\n",
file_stack->file_name);
fprintf(stderr, "Detected in file %s at line %d\n",
@@ -8098,7 +8101,10 @@ int main(int argc, char **argv)
abort_flag= 1;
break;
case Q_SKIP:
- abort_not_supported_test("%s", command->first_argument);
+ /* Eval the query, thus replacing all environment variables */
+ dynstr_set(&ds_res, 0);
+ do_eval(&ds_res, command->first_argument, command->end, FALSE);
+ abort_not_supported_test("%s",ds_res.str);
break;
case Q_RESULT:
=== modified file 'config/ac-macros/libevent.m4'
--- a/config/ac-macros/libevent.m4 2009-09-29 23:36:15 +0000
+++ b/config/ac-macros/libevent.m4 2010-01-30 12:39:39 +0000
@@ -14,13 +14,6 @@ AC_DEFUN([MYSQL_USE_BUNDLED_LIBEVENT], [
libevent_libs="\$(top_builddir)/extra/libevent/libevent.a"
libevent_includes="-I\$(top_srcdir)/extra/libevent"
- libevent_test_option="--mysqld=--thread-handling=pool-of-threads"
- AC_SUBST(libevent_libs)
- AC_SUBST(libevent_includes)
- AC_SUBST(libevent_test_option)
-
- AC_DEFINE([HAVE_LIBEVENT], [1], [If we want to use libevent and have connection pooling])
- AC_MSG_RESULT([using bundled libevent])
dnl Get the upstream file with the original libevent configure macros.
dnl Use builtin include for this, to work around path problems in old versions of aclocal.
@@ -39,17 +32,64 @@ AC_DEFUN([MYSQL_CHECK_LIBEVENT], [
AC_CONFIG_FILES(extra/libevent/Makefile)
- AC_MSG_CHECKING(for libevent)
+ AC_MSG_NOTICE([checking what libevent library to use])
+
AC_ARG_WITH([libevent],
- [ --with-libevent use libevent and have connection pooling],
- [with_libevent=$withval],
- [with_libevent=no]
- )
-
- if test "$with_libevent" != "no"; then
- MYSQL_USE_BUNDLED_LIBEVENT
- else
- AC_MSG_RESULT([disabled])
+ AC_HELP_STRING([--with-libevent=yes|no|bundled|DIR],
+ [Use libevent and have connection pooling.
+ A location of libevent library can be specified.
+ Given DIR, libevent library is
+ assumed to be in $DIR/lib and header files
+ in $DIR/include.]),
+ [with_libevent=${withval}],
+ [with_libevent=no])
+
+ case "$with_libevent" in
+ "no")
+ with_libevent=disabled
+ ;;
+ "bundled")
+ MYSQL_USE_BUNDLED_LIBEVENT
+ ;;
+ "" | "yes")
+ libevent_includes=""
+ libevent_libs="-levent"
+ AC_CHECK_LIB(event, evutil_socketpair,[with_libevent=system],
+ [with_libevent=bundled])
+ AC_CHECK_HEADER(evutil.h,,[with_libevent=bundled])
+ if test "$with_libevent" = "bundled"; then
+ MYSQL_USE_BUNDLED_LIBEVENT
+ fi
+ ;;
+ *)
+ # Test for libevent using all known library file endings
+ if test \( -f "$with_libevent/lib/libevent.a" -o \
+ -f "$with_libevent/lib/libevent.so" -o \
+ -f "$with_libevent/lib/libevent.sl" -o \
+ -f "$with_libevent/lib/libevent.dylib" \) \
+ -a -f "$with_libevent/include/evutil.h"; then
+ libevent_includes="-I$with_libevent/include"
+ libevent_libs="-L$with_libevent/lib -levent"
+ AC_CHECK_LIB(event, evutil_socketpair,[with_libevent=$with_libevent],
+ [with_libevent=no], [$libevent_libs])
+ else
+ with_libevent=no
+ fi
+ if test "$with_libevent" = "no"; then
+ AC_MSG_ERROR([libevent headers or binaries were not found])
+ fi
+ ;;
+ esac
+ AC_MSG_CHECKING(for libevent)
+ AC_MSG_RESULT([$with_libevent])
+
+ if test "$with_libevent" != "disabled"; then
+ libevent_test_option="--mysqld=--thread-handling=pool-of-threads"
+ AC_SUBST(libevent_libs)
+ AC_SUBST(libevent_includes)
+ AC_SUBST(libevent_test_option)
+ AC_DEFINE([HAVE_LIBEVENT], [1], [If we want to use libevent and have connection pooling])
fi
- AM_CONDITIONAL([HAVE_LIBEVENT], [ test "$with_libevent" != "no" ])
+ AM_CONDITIONAL([HAVE_LIBEVENT], [ test "$with_libevent" != "disabled" ])
])
+
=== modified file 'configure.in'
--- a/configure.in 2009-12-23 08:32:14 +0000
+++ b/configure.in 2010-03-04 08:03:07 +0000
@@ -1,22 +1,28 @@
dnl -*- ksh -*-
dnl Process this file with autoconf to produce a configure script.
-AC_PREREQ(2.52)dnl Minimum Autoconf version required.
+# Minimum Autoconf version required.
+AC_PREREQ(2.59)
-AC_INIT(sql/mysqld.cc)
-AC_CANONICAL_SYSTEM
-# The Docs Makefile.am parses this line!
-# remember to also update version.c in ndb
-#
+# Remember to also update version.c in ndb.
# When changing major version number please also check switch statement
-# in mysqlbinlog.cc / check_master_version().
-#
-# When merging new MySQL releases, update the version number to match the
-# MySQL version number.
-#
-# Note: the following line must be parseable by win/configure.js:GetVersion()
-AM_INIT_AUTOMAKE(mysql, 5.1.41-MariaDB-rc)
-AM_CONFIG_HEADER([include/config.h:config.h.in])
+# in mysqlbinlog::check_master_version().
+AC_INIT([MariaDB Server], [5.1.44-MariaDB], [], [mysql])
+AC_CONFIG_SRCDIR([sql/mysqld.cc])
+AC_CANONICAL_SYSTEM
+# USTAR format gives us the possibility to store longer path names in
+# TAR files, the path name is split into two parts, a 155 chacater
+# first part and a 100 character second part.
+AM_INIT_AUTOMAKE([1.9 tar-ustar])
+AC_PROG_LIBTOOL
+
+AM_CONFIG_HEADER([include/config.h])
+
+# Request support for automake silent-rules if available.
+# Default to verbose output. One can use the configure-time
+# option --enable-silent-rules or make V=0 to activate
+# silent rules.
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])])
PROTOCOL_VERSION=10
DOT_FRM_VERSION=6
@@ -30,12 +36,14 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_M
# Remember that regexps needs to quote [ and ] since this is run through m4
# We take some made up examples
#
-# VERSION 5.1.40sp1-alpha 5.0.34a
-# MYSQL_NO_DASH_VERSION 5.1.40sp1 5.0.34a
-# MYSQL_NUMERIC_VERSION 5.1.40 5.0.34
-# MYSQL_BASE_VERSION 5.1 5.0
-# MYSQL_VERSION_ID 50140 50034
+# VERSION 5.1.40sp1-alpha 5.0.34a 5.5.1-m2
+# MYSQL_U_SCORE_VERSION 5.1.40sp1_alpha 5.0.34a 5.5.1_m2
+# MYSQL_NO_DASH_VERSION 5.1.40sp1 5.0.34a 5.5.1
+# MYSQL_NUMERIC_VERSION 5.1.40 5.0.34 5.5.1
+# MYSQL_BASE_VERSION 5.1 5.0 5.5
+# MYSQL_VERSION_ID 50140 50034 50501
#
+MYSQL_U_SCORE_VERSION=`echo $VERSION | sed -e "s|-|_|"`
MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|-.*$||"`
MYSQL_NUMERIC_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|[[a-z]][[a-z0-9]]*$||"`
MYSQL_BASE_VERSION=`echo $MYSQL_NUMERIC_VERSION | sed -e "s|\.[[^.]]*$||"`
@@ -73,6 +81,7 @@ romanian russian serbian slovak spanish
#####
#####
+AC_SUBST(MYSQL_U_SCORE_VERSION)
AC_SUBST(MYSQL_NO_DASH_VERSION)
AC_SUBST(MYSQL_BASE_VERSION)
AC_SUBST(MYSQL_VERSION_ID)
@@ -224,14 +233,6 @@ then
GXX="no"
fi
-if test "$ac_cv_prog_gcc" = "yes"
-then
- AS="$CC -c"
- AC_SUBST(AS)
-else
- AC_PATH_PROG(AS, as, as)
-fi
-
# Still need ranlib for readline; local static use only so no libtool.
AC_PROG_RANLIB
# We use libtool
@@ -611,7 +612,7 @@ AC_CHECK_TOOL([NM], [nm])
if test "$TARGET_LINUX" = "true" -a "$static_nss" = ""
then
- tmp=`$NM ${other_libc_lib:-/usr/lib*}/libc.a | grep _nss_files_getaliasent_r1`
+ tmp=`$NM ${other_libc_lib:-/usr/lib*}/libc.a 2>&1 | grep _nss_files_getaliasent_r1`
if test -n "$tmp"
then
STATIC_NSS_FLAGS="-lc -lnss_files -lnss_dns -lresolv"
@@ -688,7 +689,7 @@ AC_ARG_ENABLE(assembler,
AC_MSG_CHECKING(if we should use assembler functions)
# For now we only support assembler on i386 and sparc systems
-AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
+AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $CCAS $CCASFLAGS -c strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
AM_CONDITIONAL(ASSEMBLER_sparc32, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc")
AM_CONDITIONAL(ASSEMBLER_sparc64, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparcv9")
AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc32_TRUE" = "")
@@ -2102,7 +2103,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bs
sighold sigset sigthreadmask port_create sleep thr_yield \
snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
- posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd)
+ posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd printstack)
#
#
@@ -2945,7 +2946,8 @@ echo " * Community Features: $E
echo ""
echo "---"
-# The following text is checked in ./Do-compile to verify that configure
+# The first line "Thank you ..." is checked in ./Do-compile to verify that configure
# ended sucessfully - don't remove it.
+echo
echo "Thank you for choosing MariaDB!"
echo
=== modified file 'extra/comp_err.c'
--- a/extra/comp_err.c 2009-02-13 16:41:47 +0000
+++ b/extra/comp_err.c 2010-03-30 12:36:49 +0000
@@ -660,7 +660,7 @@ static ha_checksum checksum_format_speci
case 'u':
case 'x':
case 's':
- chksum= my_checksum(chksum, start, (uint) (p - start));
+ chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start));
start= 0; /* Not in format specifier anymore */
break;
@@ -1030,8 +1030,10 @@ static char *parse_text_line(char *pos)
{
int i, nr;
char *row= pos;
+ size_t len;
DBUG_ENTER("parse_text_line");
+ len= strlen (pos);
while (*pos)
{
if (*pos == '\\')
@@ -1039,11 +1041,11 @@ static char *parse_text_line(char *pos)
switch (*++pos) {
case '\\':
case '"':
- VOID(strmov(pos - 1, pos));
+ VOID(memmove (pos - 1, pos, len - (row - pos)));
break;
case 'n':
pos[-1]= '\n';
- VOID(strmov(pos, pos + 1));
+ VOID(memmove (pos, pos + 1, len - (row - pos)));
break;
default:
if (*pos >= '0' && *pos < '8')
@@ -1053,10 +1055,10 @@ static char *parse_text_line(char *pos)
nr= nr * 8 + (*(pos++) - '0');
pos -= i;
pos[-1]= nr;
- VOID(strmov(pos, pos + i));
+ VOID(memmove (pos, pos + i, len - (row - pos)));
}
else if (*pos)
- VOID(strmov(pos - 1, pos)); /* Remove '\' */
+ VOID(memmove (pos - 1, pos, len - (row - pos))); /* Remove '\' */
}
}
else
=== modified file 'extra/libevent/devpoll.c'
--- a/extra/libevent/devpoll.c 2009-03-12 22:27:35 +0000
+++ b/extra/libevent/devpoll.c 2010-01-28 11:35:10 +0000
@@ -140,7 +140,7 @@ devpoll_init(struct event_base *base)
return (NULL);
if (getrlimit(RLIMIT_NOFILE, &rl) == 0 &&
- rl.rlim_cur != RLIM_INFINITY)
+ (unsigned long long) rl.rlim_cur != (unsigned long long) RLIM_INFINITY)
nfiles = rl.rlim_cur - 1;
/* Initialize the kernel queue */
=== modified file 'extra/libevent/evbuffer.c'
--- a/extra/libevent/evbuffer.c 2009-03-12 22:27:35 +0000
+++ b/extra/libevent/evbuffer.c 2010-01-07 13:00:06 +0000
@@ -25,12 +25,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/types.h>
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include <sys/types.h>
+
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
=== modified file 'extra/libevent/kqueue.c'
--- a/extra/libevent/kqueue.c 2009-03-12 22:27:35 +0000
+++ b/extra/libevent/kqueue.c 2010-03-30 12:36:49 +0000
@@ -144,7 +144,7 @@ kq_init(struct event_base *base)
*/
if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
- kqueueop->events[0].ident != -1 ||
+ ((int) kqueueop->events[0].ident) != -1 ||
kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue; not using.", __func__);
free(kqueueop->changes);
=== modified file 'extra/libevent/select.c'
--- a/extra/libevent/select.c 2009-03-12 22:27:35 +0000
+++ b/extra/libevent/select.c 2010-01-06 21:27:53 +0000
@@ -266,7 +266,7 @@ select_add(void *arg, struct event *ev)
* of the fd_sets for select(2)
*/
if (sop->event_fds < ev->ev_fd) {
- int fdsz = sop->event_fdsz;
+ unsigned int fdsz = sop->event_fdsz;
if (fdsz < sizeof(fd_mask))
fdsz = sizeof(fd_mask);
@@ -275,7 +275,7 @@ select_add(void *arg, struct event *ev)
(howmany(ev->ev_fd + 1, NFDBITS) * sizeof(fd_mask)))
fdsz *= 2;
- if (fdsz != sop->event_fdsz) {
+ if (fdsz != (unsigned int) sop->event_fdsz) {
if (select_resize(sop, fdsz)) {
check_selectop(sop);
return (-1);
=== modified file 'extra/yassl/src/yassl_error.cpp'
--- a/extra/yassl/src/yassl_error.cpp 2008-11-18 16:45:44 +0000
+++ b/extra/yassl/src/yassl_error.cpp 2010-01-29 10:42:31 +0000
@@ -60,7 +60,7 @@ void SetErrorString(YasslError error, ch
using namespace TaoCrypt;
const int max = MAX_ERROR_SZ; // shorthand
- switch (error) {
+ switch ((int) error) {
// yaSSL proper errors
case range_error :
=== modified file 'extra/yassl/taocrypt/include/asn.hpp'
--- a/extra/yassl/taocrypt/include/asn.hpp 2007-01-29 15:54:40 +0000
+++ b/extra/yassl/taocrypt/include/asn.hpp 2010-03-04 08:03:07 +0000
@@ -305,6 +305,7 @@ private:
bool ValidateSignature(SignerList*);
bool ConfirmSignature(Source&);
void GetKey();
+ char* AddTag(char*, const char*, const char*, word32, word32);
void GetName(NameType);
void GetValidity();
void GetDate(DateType);
=== modified file 'extra/yassl/taocrypt/src/asn.cpp'
--- a/extra/yassl/taocrypt/src/asn.cpp 2009-09-15 11:22:39 +0000
+++ b/extra/yassl/taocrypt/src/asn.cpp 2010-03-04 08:03:07 +0000
@@ -652,6 +652,23 @@ word32 CertDecoder::GetDigest()
}
+char *CertDecoder::AddTag(char *ptr, const char *buf_end,
+ const char *tag_name, word32 tag_name_length,
+ word32 tag_value_length)
+{
+ if (ptr + tag_name_length + tag_value_length > buf_end)
+ return 0;
+
+ memcpy(ptr, tag_name, tag_name_length);
+ ptr+= tag_name_length;
+
+ memcpy(ptr, source_.get_current(), tag_value_length);
+ ptr+= tag_value_length;
+
+ return ptr;
+}
+
+
// process NAME, either issuer or subject
void CertDecoder::GetName(NameType nt)
{
@@ -659,11 +676,21 @@ void CertDecoder::GetName(NameType nt)
SHA sha;
word32 length = GetSequence(); // length of all distinguished names
- assert (length < ASN_NAME_MAX);
+
+ if (length >= ASN_NAME_MAX)
+ goto err;
length += source_.get_index();
- char* ptr = (nt == ISSUER) ? issuer_ : subject_;
- word32 idx = 0;
+ char *ptr, *buf_end;
+
+ if (nt == ISSUER) {
+ ptr= issuer_;
+ buf_end= ptr + sizeof(issuer_) - 1; // 1 byte for trailing 0
+ }
+ else {
+ ptr= subject_;
+ buf_end= ptr + sizeof(subject_) - 1; // 1 byte for trailing 0
+ }
while (source_.get_index() < length) {
GetSet();
@@ -685,47 +712,36 @@ void CertDecoder::GetName(NameType nt)
byte id = source_.next();
b = source_.next(); // strType
word32 strLen = GetLength(source_);
- bool copy = false;
- if (id == COMMON_NAME) {
- memcpy(&ptr[idx], "/CN=", 4);
- idx += 4;
- copy = true;
- }
- else if (id == SUR_NAME) {
- memcpy(&ptr[idx], "/SN=", 4);
- idx += 4;
- copy = true;
- }
- else if (id == COUNTRY_NAME) {
- memcpy(&ptr[idx], "/C=", 3);
- idx += 3;
- copy = true;
- }
- else if (id == LOCALITY_NAME) {
- memcpy(&ptr[idx], "/L=", 3);
- idx += 3;
- copy = true;
- }
- else if (id == STATE_NAME) {
- memcpy(&ptr[idx], "/ST=", 4);
- idx += 4;
- copy = true;
- }
- else if (id == ORG_NAME) {
- memcpy(&ptr[idx], "/O=", 3);
- idx += 3;
- copy = true;
- }
- else if (id == ORGUNIT_NAME) {
- memcpy(&ptr[idx], "/OU=", 4);
- idx += 4;
- copy = true;
- }
-
- if (copy) {
- memcpy(&ptr[idx], source_.get_current(), strLen);
- idx += strLen;
+ switch (id) {
+ case COMMON_NAME:
+ if (!(ptr= AddTag(ptr, buf_end, "/CN=", 4, strLen)))
+ goto err;
+ break;
+ case SUR_NAME:
+ if (!(ptr= AddTag(ptr, buf_end, "/SN=", 4, strLen)))
+ goto err;
+ break;
+ case COUNTRY_NAME:
+ if (!(ptr= AddTag(ptr, buf_end, "/C=", 3, strLen)))
+ goto err;
+ break;
+ case LOCALITY_NAME:
+ if (!(ptr= AddTag(ptr, buf_end, "/L=", 3, strLen)))
+ goto err;
+ break;
+ case STATE_NAME:
+ if (!(ptr= AddTag(ptr, buf_end, "/ST=", 4, strLen)))
+ goto err;
+ break;
+ case ORG_NAME:
+ if (!(ptr= AddTag(ptr, buf_end, "/O=", 3, strLen)))
+ goto err;
+ break;
+ case ORGUNIT_NAME:
+ if (!(ptr= AddTag(ptr, buf_end, "/OU=", 4, strLen)))
+ goto err;
+ break;
}
sha.Update(source_.get_current(), strLen);
@@ -739,23 +755,20 @@ void CertDecoder::GetName(NameType nt)
source_.advance(oidSz + 1);
word32 length = GetLength(source_);
- if (email) {
- memcpy(&ptr[idx], "/emailAddress=", 14);
- idx += 14;
-
- memcpy(&ptr[idx], source_.get_current(), length);
- idx += length;
- }
+ if (email && !(ptr= AddTag(ptr, buf_end, "/emailAddress=", 14, length)))
+ goto err;
source_.advance(length);
}
}
- ptr[idx++] = 0;
+ *ptr= 0;
- if (nt == ISSUER)
- sha.Final(issuerHash_);
- else
- sha.Final(subjectHash_);
+ sha.Final(nt == ISSUER ? issuerHash_ : subjectHash_);
+
+ return;
+
+err:
+ source_.SetError(CONTENT_E);
}
=== modified file 'include/config-win.h'
--- a/include/config-win.h 2009-09-07 20:50:10 +0000
+++ b/include/config-win.h 2010-03-04 08:03:07 +0000
@@ -192,7 +192,7 @@ typedef SSIZE_T ssize_t;
#define isnan(X) _isnan(X)
#define finite(X) _finite(X)
-#ifndef UNDEF_THREAD_HACK
+#ifndef MYSQL_CLIENT_NO_THREADS
#define THREAD
#endif
#define VOID_SIGHANDLER
=== modified file 'include/ft_global.h'
--- a/include/ft_global.h 2009-11-30 13:36:06 +0000
+++ b/include/ft_global.h 2010-01-27 21:53:08 +0000
@@ -62,7 +62,8 @@ void ft_free_stopwords(void);
#define FT_SORTED 2
#define FT_EXPAND 4 /* query expansion */
-FT_INFO *ft_init_search(uint,void *, uint, uchar *, uint,CHARSET_INFO *, uchar *);
+FT_INFO *ft_init_search(uint,void *, uint, uchar *, size_t,
+ CHARSET_INFO *, uchar *);
my_bool ft_boolean_check_syntax_string(const uchar *);
/* Internal symbols for fulltext between maria and MyISAM */
=== modified file 'include/m_string.h'
--- a/include/m_string.h 2009-08-13 21:12:12 +0000
+++ b/include/m_string.h 2010-03-04 08:03:07 +0000
@@ -95,13 +95,7 @@ extern char NEAR _dig_vec_lower[];
/* Defined in strtod.c */
extern const double log_10[309];
-#ifdef BAD_STRING_COMPILER
-#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
-#else
extern char *strmov_overlapp(char *dest, const char *src);
-/* Warning: the following is likely not to work: */
-#define strmake_overlapp(A,B,C) strmake(A,B,C)
-#endif
#ifdef BAD_MEMCPY /* Problem with gcc on Alpha */
#define memcpy_fixed(A,B,C) bmove((A),(B),(C))
@@ -162,9 +156,6 @@ extern size_t strinstr(const char *str,c
extern size_t r_strinstr(const char *str, size_t from, const char *search);
extern char *strkey(char *dst,char *head,char *tail,char *flags);
extern char *strmake(char *dst,const char *src,size_t length);
-#ifndef strmake_overlapp
-extern char *strmake_overlapp(char *dst,const char *src, size_t length);
-#endif
#ifndef strmov
extern char *strmov(char *dst,const char *src);
=== modified file 'include/maria.h'
--- a/include/maria.h 2009-02-19 09:01:25 +0000
+++ b/include/maria.h 2010-01-27 21:53:08 +0000
@@ -462,7 +462,7 @@ void maria_versioning(MARIA_HA *info, my
void maria_ignore_trids(MARIA_HA *info);
/* fulltext functions */
-FT_INFO *maria_ft_init_search(uint,void *, uint, uchar *, uint,
+FT_INFO *maria_ft_init_search(uint,void *, uint, uchar *, size_t,
CHARSET_INFO *, uchar *);
/* 'Almost-internal' Maria functions */
=== modified file 'include/my_base.h'
--- a/include/my_base.h 2009-09-07 20:50:10 +0000
+++ b/include/my_base.h 2010-02-10 19:06:24 +0000
@@ -111,7 +111,7 @@ enum ha_storage_media {
enum ha_extra_function {
HA_EXTRA_NORMAL=0, /* Optimize for space (def) */
HA_EXTRA_QUICK=1, /* Optimize for speed */
- HA_EXTRA_NOT_USED=2,
+ HA_EXTRA_NOT_USED=2, /* Should be ignored by handler */
HA_EXTRA_CACHE=3, /* Cache record in HA_rrnd() */
HA_EXTRA_NO_CACHE=4, /* End caching of records (def) */
HA_EXTRA_NO_READCHECK=5, /* No readcheck on update */
=== modified file 'include/my_global.h'
--- a/include/my_global.h 2009-12-03 11:19:05 +0000
+++ b/include/my_global.h 2010-03-10 10:32:14 +0000
@@ -889,7 +889,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define FLT_MAX ((float)3.40282346638528860e+38)
#endif
#ifndef SIZE_T_MAX
-#define SIZE_T_MAX ~((size_t) 0)
+#define SIZE_T_MAX (~((size_t) 0))
#endif
#ifndef isfinite
@@ -1260,9 +1260,9 @@ do { doubleget_union _tmp; \
} while (0)
#define float4get(V,M) do { *((float *) &(V)) = *((const float*) (M)); } while(0)
#define float8get(V,M) doubleget((V),(M))
-#define float4store(V,M) memcpy((uchar*) V,(const uchar*) (&M),sizeof(float))
-#define floatstore(T,V) memcpy((uchar*)(T), (const uchar*)(&V),sizeof(float))
-#define floatget(V,M) memcpy((uchar*) &V,(const uchar*) (M),sizeof(float))
+#define float4store(V,M) memcpy((uchar*) V,(uchar*) (&M),sizeof(float))
+#define floatstore(T,V) memcpy((uchar*)(T), (uchar*)(&V),sizeof(float))
+#define floatget(V,M) memcpy((uchar*) &V,(uchar*) (M),sizeof(float))
#define float8store(V,M) doublestore((V),(M))
#else
=== modified file 'include/my_no_pthread.h'
--- a/include/my_no_pthread.h 2006-12-23 19:20:40 +0000
+++ b/include/my_no_pthread.h 2009-12-12 18:11:25 +0000
@@ -47,4 +47,12 @@
#define rw_unlock(A)
#define rwlock_destroy(A)
+typedef int my_pthread_once_t;
+#define MY_PTHREAD_ONCE_INIT 0
+#define MY_PTHREAD_ONCE_DONE 1
+
+#define my_pthread_once(C,F) do { \
+ if (*(C) != MY_PTHREAD_ONCE_DONE) { F(); *(C)= MY_PTHREAD_ONCE_DONE; } \
+ } while(0)
+
#endif
=== modified file 'include/my_pthread.h'
--- a/include/my_pthread.h 2009-06-30 12:01:29 +0000
+++ b/include/my_pthread.h 2010-03-04 08:03:07 +0000
@@ -69,6 +69,11 @@ typedef int pthread_mutexattr_t;
#define pthread_handler_t EXTERNC void * __cdecl
typedef void * (__cdecl *pthread_handler)(void *);
+typedef volatile LONG my_pthread_once_t;
+#define MY_PTHREAD_ONCE_INIT 0
+#define MY_PTHREAD_ONCE_INPROGRESS 1
+#define MY_PTHREAD_ONCE_DONE 2
+
/*
Struct and macros to be used in combination with the
windows implementation of pthread_cond_timedwait
@@ -116,6 +121,7 @@ int pthread_attr_init(pthread_attr_t *co
int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
int pthread_attr_setprio(pthread_attr_t *connect_att,int priority);
int pthread_attr_destroy(pthread_attr_t *connect_att);
+int my_pthread_once(my_pthread_once_t *once_control,void (*init_routine)(void));
struct tm *localtime_r(const time_t *timep,struct tm *tmp);
struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
@@ -215,6 +221,10 @@ extern int my_pthread_getprio(pthread_t
#define pthread_handler_t EXTERNC void *
typedef void *(* pthread_handler)(void *);
+#define my_pthread_once_t pthread_once_t
+#define MY_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
+#define my_pthread_once(C,F) pthread_once(C,F)
+
/* Test first for RTS or FSU threads */
#if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM)
@@ -543,9 +553,9 @@ void safe_mutex_free_deadlock_data(safe_
#else
#define my_pthread_mutex_init(A,B,C,D) pthread_mutex_init((A),(B))
#define my_pthread_mutex_lock(A,B) pthread_mutex_lock(A)
-#define safe_mutex_assert_owner(mp)
-#define safe_mutex_assert_not_owner(mp)
-#define safe_mutex_free_deadlock_data(mp)
+#define safe_mutex_assert_owner(mp) do {} while(0)
+#define safe_mutex_assert_not_owner(mp) do {} while(0)
+#define safe_mutex_free_deadlock_data(mp) do {} while(0)
#endif /* SAFE_MUTEX */
#if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
=== modified file 'include/my_stacktrace.h'
--- a/include/my_stacktrace.h 2008-06-19 14:02:32 +0000
+++ b/include/my_stacktrace.h 2010-01-27 10:42:20 +0000
@@ -23,7 +23,7 @@
(defined(__alpha__) && defined(__GNUC__))
#define HAVE_STACKTRACE 1
#endif
-#elif defined(__WIN__)
+#elif defined(__WIN__) || defined(HAVE_PRINTSTACK)
#define HAVE_STACKTRACE 1
#endif
=== modified file 'include/my_sys.h'
--- a/include/my_sys.h 2009-12-03 11:19:05 +0000
+++ b/include/my_sys.h 2010-03-10 09:12:23 +0000
@@ -247,6 +247,7 @@ extern CHARSET_INFO compiled_charsets[];
/* statistics */
extern ulong my_file_opened,my_stream_opened, my_tmp_file_created;
extern ulong my_file_total_opened;
+extern ulong my_sync_count;
extern uint mysys_usage_id;
extern my_bool my_init_done;
@@ -998,7 +999,6 @@ extern my_bool resolve_collation(const c
CHARSET_INFO *default_cl,
CHARSET_INFO **cl);
-extern void free_charsets(void);
extern char *get_charsets_dir(char *buf);
extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
extern my_bool init_compiled_charsets(myf flags);
=== modified file 'include/myisam.h'
--- a/include/myisam.h 2009-12-03 11:19:05 +0000
+++ b/include/myisam.h 2010-03-04 08:03:07 +0000
@@ -251,6 +251,8 @@ extern ulong myisam_bulk_insert_tree_siz
/* usually used to check if a symlink points into the mysql data home */
/* which is normally forbidden */
extern int (*myisam_test_invalid_symlink)(const char *filename);
+extern ulonglong myisam_mmap_size, myisam_mmap_used;
+extern pthread_mutex_t THR_LOCK_myisam_mmap;
/* Prototypes for myisam-functions */
@@ -296,6 +298,7 @@ extern int mi_delete_all_rows(struct st_
extern ulong _mi_calc_blob_length(uint length , const uchar *pos);
extern uint mi_get_pointer_length(ulonglong file_length, uint def);
+#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for mmap file */
/* this is used to pass to mysql_myisamchk_table */
#define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r */
=== modified file 'include/mysql.h'
--- a/include/mysql.h 2009-12-03 11:19:05 +0000
+++ b/include/mysql.h 2010-01-15 15:27:55 +0000
@@ -558,16 +558,6 @@ unsigned long STDCALL mysql_real_escape_
char *to,const char *from,
unsigned long length);
void STDCALL mysql_debug(const char *debug);
-char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
- char *to,
- unsigned long to_length,
- const char *from,
- unsigned long from_length,
- void *param,
- char *
- (*extend_buffer)
- (void *, char *to,
- unsigned long *length));
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int STDCALL mysql_thread_safe(void);
my_bool STDCALL mysql_embedded(void);
=== modified file 'include/mysql.h.pp'
--- a/include/mysql.h.pp 2009-12-03 11:19:05 +0000
+++ b/include/mysql.h.pp 2010-02-23 12:04:58 +0000
@@ -28,7 +28,7 @@ typedef struct st_net {
unsigned int *return_status;
unsigned char reading_or_writing;
char save_char;
- my_bool unused0;
+ char net_skip_rest_factor;
my_bool unused;
my_bool compress;
my_bool unused1;
@@ -518,16 +518,6 @@ unsigned long mysql_real_escape_string(M
char *to,const char *from,
unsigned long length);
void mysql_debug(const char *debug);
-char * mysql_odbc_escape_string(MYSQL *mysql,
- char *to,
- unsigned long to_length,
- const char *from,
- unsigned long from_length,
- void *param,
- char *
- (*extend_buffer)
- (void *, char *to,
- unsigned long *length));
void myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int mysql_thread_safe(void);
my_bool mysql_embedded(void);
=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h 2008-10-10 15:28:41 +0000
+++ b/include/mysql_com.h 2010-02-23 12:04:58 +0000
@@ -254,7 +254,7 @@ typedef struct st_net {
unsigned int *return_status;
unsigned char reading_or_writing;
char save_char;
- my_bool unused0; /* Please remove with the next incompatible ABI change. */
+ char net_skip_rest_factor;
my_bool unused; /* Please remove with the next incompatible ABI change */
my_bool compress;
my_bool unused1; /* Please remove with the next incompatible ABI change. */
=== modified file 'include/violite.h'
--- a/include/violite.h 2009-12-03 11:19:05 +0000
+++ b/include/violite.h 2010-01-29 10:42:31 +0000
@@ -123,8 +123,8 @@ struct st_VioSSLFd
SSL_CTX *ssl_context;
};
-int sslaccept(struct st_VioSSLFd*, Vio *, long timeout);
-int sslconnect(struct st_VioSSLFd*, Vio *, long timeout);
+int sslaccept(struct st_VioSSLFd*, Vio *, long timeout, char *error_string);
+int sslconnect(struct st_VioSSLFd*, Vio *, long timeout, char *error_string);
struct st_VioSSLFd
*new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
@@ -225,8 +225,8 @@ struct st_vio
#endif /* HAVE_SMEM */
#ifdef _WIN32
OVERLAPPED pipe_overlapped;
- DWORD read_timeout_millis;
- DWORD write_timeout_millis;
+ DWORD read_timeout_ms;
+ DWORD write_timeout_ms;
#endif
};
#endif /* vio_violite_h_ */
=== modified file 'libmysql/libmysql.c'
--- a/libmysql/libmysql.c 2009-12-03 11:34:11 +0000
+++ b/libmysql/libmysql.c 2010-03-04 08:03:07 +0000
@@ -211,7 +211,6 @@ void STDCALL mysql_server_end()
}
else
{
- free_charsets();
mysql_thread_end();
}
@@ -719,7 +718,10 @@ my_bool STDCALL mysql_change_user(MYSQL
if (!passwd)
passwd="";
- /* Store user into the buffer */
+ /*
+ Store user into the buffer.
+ Advance position as strmake returns a pointer to the closing NUL.
+ */
end= strmake(end, user, USERNAME_LENGTH) + 1;
/* write scrambled password according to server capabilities */
@@ -1269,7 +1271,7 @@ mysql_list_fields(MYSQL *mysql, const ch
{
MYSQL_RES *result;
MYSQL_FIELD *fields;
- char buff[257],*end;
+ char buff[258],*end;
DBUG_ENTER("mysql_list_fields");
DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : ""));
@@ -1642,20 +1644,6 @@ mysql_real_escape_string(MYSQL *mysql, c
return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length);
}
-
-char * STDCALL
-mysql_odbc_escape_string(MYSQL *mysql __attribute__((unused)),
- char *to __attribute__((unused)),
- ulong to_length __attribute__((unused)),
- const char *from __attribute__((unused)),
- ulong from_length __attribute__((unused)),
- void *param __attribute__((unused)),
- char * (*extend_buffer)(void *, char *, ulong *)
- __attribute__((unused)))
-{
- return NULL;
-}
-
void STDCALL
myodbc_remove_escape(MYSQL *mysql,char *name)
{
@@ -2298,7 +2286,7 @@ mysql_stmt_param_metadata(MYSQL_STMT *st
/* Store type of parameter in network buffer. */
-static void store_param_type(uchar **pos, MYSQL_BIND *param)
+static void store_param_type(unsigned char **pos, MYSQL_BIND *param)
{
uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0);
int2store(*pos, typecode);
=== modified file 'libmysql/libmysql.def'
--- a/libmysql/libmysql.def 2009-12-03 11:19:05 +0000
+++ b/libmysql/libmysql.def 2010-01-15 15:27:55 +0000
@@ -78,7 +78,6 @@ EXPORTS
mysql_next_result
mysql_num_fields
mysql_num_rows
- mysql_odbc_escape_string
mysql_options
mysql_stmt_param_count
mysql_stmt_param_metadata
=== modified file 'libmysqld/CMakeLists.txt'
--- a/libmysqld/CMakeLists.txt 2009-12-03 11:19:05 +0000
+++ b/libmysqld/CMakeLists.txt 2010-01-31 09:13:21 +0000
@@ -153,7 +153,7 @@ FILE(WRITE cmake_dummy.c " ")
# custom targets to "sql/CMakeLists.txt" and reference them here.
ADD_LIBRARY(mysqlserver STATIC ${LIBMYSQLD_SOURCES})
ADD_DEPENDENCIES(mysqlserver GenServerSource GenError)
-TARGET_LINK_LIBRARIES(mysqlserver)
+TARGET_LINK_LIBRARIES(mysqlserver psapi.lib)
# Add any additional libraries requested by engine(s)
FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
=== modified file 'libmysqld/libmysqld.def'
--- a/libmysqld/libmysqld.def 2009-12-03 11:19:05 +0000
+++ b/libmysqld/libmysqld.def 2010-01-15 15:27:55 +0000
@@ -50,7 +50,6 @@ EXPORTS
mysql_next_result
mysql_num_fields
mysql_num_rows
- mysql_odbc_escape_string
mysql_options
mysql_ping
mysql_query
=== modified file 'mysql-test/collections/default.experimental'
--- a/mysql-test/collections/default.experimental 2009-10-26 12:33:03 +0000
+++ b/mysql-test/collections/default.experimental 2010-02-01 12:05:21 +0000
@@ -13,16 +13,12 @@ funcs_1.ndb*
funcs_2.ndb_charset # joro : NDB tests marked as experimental as agreed with bochklin
main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists
-main.innodb-autoinc* # Bug#47809 2009-10-04 joro innodb-autoinc.test fails with valgrind errors with the innodb plugin
main.plugin_load @solaris # Bug#42144
+main.outfile_loaddata @solaris # joro : Bug #46895
ndb.* # joro : NDB tests marked as experimental as agreed with bochklin
-rpl.rpl_cross_version* # Bug #43913 2009-10-26 joro rpl_cross_version can't pass on conflicts complainig clash with --slave-load-tm
-rpl.rpl_get_master_version_and_clock* # Bug#46931 2009-08-26 alik rpl.rpl_get_master_version_and_clock fails on hpux11.31
rpl.rpl_innodb_bug28430* @solaris # Bug#46029
-rpl.rpl_row_create_table* # Bug#45576: rpl_row_create_table fails on PB2
-rpl.rpl_trigger* # Bug#47810 2009-10-04 joro rpl.rpl_trigger.test fails with valgrind errors with the innodb plugin
rpl_ndb.* # joro : NDB tests marked as experimental as agreed with bochklin
rpl_ndb.rpl_ndb_log # Bug#38998
=== modified file 'mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test'
--- a/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test 2009-08-28 14:13:27 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test 2009-10-22 00:21:50 +0000
@@ -407,37 +407,57 @@ sync_slave_with_master;
###########################################
# Bug#22234, Bug#23907 Extra Slave Col is not
# erroring on extra col with no default values.
-########################################################
+###############################################################
+# Error reaction is up to sql_mode of the slave sql (bug#38173)
#--echo *** Create t9 on slave ***
-STOP SLAVE;
-RESET SLAVE;
-eval CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
- d TIMESTAMP,
- e INT NOT NULL) ENGINE=$engine_type;
-
---echo *** Create t9 on Master ***
-connection master;
-eval CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
+# Please, check BUG#47741 to see why you are not testing NDB.
+if (`SELECT $engine_type != 'NDB'`)
+{
+ STOP SLAVE;
+ RESET SLAVE;
+ eval CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
+ d TIMESTAMP,
+ e INT NOT NULL,
+ f text not null,
+ g text,
+ h blob not null,
+ i blob) ENGINE=$engine_type;
+
+ --echo *** Create t9 on Master ***
+ connection master;
+ eval CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
) ENGINE=$engine_type;
-RESET MASTER;
+ RESET MASTER;
---echo *** Start Slave ***
-connection slave;
-START SLAVE;
-
---echo *** Master Data Insert ***
-connection master;
-set @b1 = 'b1b1b1b1';
-set @b1 = concat(@b1,@b1);
-INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
-
-connection slave;
---source include/wait_for_slave_sql_to_stop.inc
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
---query_vertical SHOW SLAVE STATUS
-SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
-START SLAVE;
+ --echo *** Start Slave ***
+ connection slave;
+ START SLAVE;
+
+ --echo *** Master Data Insert ***
+ connection master;
+ set @b1 = 'b1b1b1b1';
+
+ set @b1 = concat(@b1,@b1);
+ INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
+
+ # the test would stop slave if @@sql_mode for the sql thread
+ # was set to strict. Otherwise, as with this tests setup,
+ # the implicit defaults will be inserted into fields even though
+ # they are declared without DEFAULT clause.
+
+ sync_slave_with_master;
+ select * from t9;
+
+ # todo: fix Bug #43992 slave sql thread can't tune own sql_mode ...
+ # and add/restore waiting for stop test
+
+ #--source include/wait_for_slave_sql_to_stop.inc
+ #--replace_result $MASTER_MYPORT MASTER_PORT
+ #--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
+ #--query_vertical SHOW SLAVE STATUS
+ #SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+ #START SLAVE;
+}
#--echo *** Drop t9 ***
#connection master;
=== modified file 'mysql-test/extra/rpl_tests/rpl_loaddata.test'
--- a/mysql-test/extra/rpl_tests/rpl_loaddata.test 2009-10-27 15:15:53 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test 2010-01-13 10:28:42 +0000
@@ -21,14 +21,26 @@ connection slave;
reset master;
connection master;
+# MTR is not case-sensitive.
+let $lower_stmt_head= load data;
+let $UPPER_STMT_HEAD= LOAD DATA;
+if (`SELECT '$lock_option' <> ''`)
+{
+ #if $lock_option is null, an extra blank is added into the statement,
+ #this will change the result of rpl_loaddata test case. so $lock_option
+ #is set only when it is not null.
+ let $lower_stmt_head= load data $lock_option;
+ let $UPPER_STMT_HEAD= LOAD DATA $lock_option;
+}
+
select last_insert_id();
create table t1(a int not null auto_increment, b int, primary key(a) );
-load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+eval $lower_stmt_head infile '../../std_data/rpl_loaddata.dat' into table t1;
# verify that LAST_INSERT_ID() is set by LOAD DATA INFILE
select last_insert_id();
create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60));
-load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines;
+eval $lower_stmt_head infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines;
create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60));
insert into t3 select * from t2;
@@ -56,7 +68,7 @@ sync_with_master;
insert into t1 values(1,10);
connection master;
-load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+eval $lower_stmt_head infile '../../std_data/rpl_loaddata.dat' into table t1;
save_master_pos;
connection slave;
@@ -70,9 +82,11 @@ connection slave;
set global sql_slave_skip_counter=1;
start slave;
sync_with_master;
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 16 # 23 # 33 #
-show slave status;
+let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1);
+echo Last_SQL_Errno=$last_error;
+let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1);
+echo Last_SQL_Error;
+echo $last_error;
# Trigger error again to test CHANGE MASTER
@@ -80,7 +94,7 @@ connection master;
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
-load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+eval $lower_stmt_head infile '../../std_data/rpl_loaddata.dat' into table t1;
save_master_pos;
connection slave;
# The SQL slave thread should be stopped now.
@@ -92,9 +106,11 @@ connection slave;
stop slave;
change master to master_user='test';
change master to master_user='root';
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 16 # 23 # 33 #
-show slave status;
+let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1);
+echo Last_SQL_Errno=$last_error;
+let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1);
+echo Last_SQL_Error;
+echo $last_error;
# Trigger error again to test RESET SLAVE
@@ -105,7 +121,7 @@ connection master;
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
-load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+eval $lower_stmt_head infile '../../std_data/rpl_loaddata.dat' into table t1;
save_master_pos;
connection slave;
# The SQL slave thread should be stopped now.
@@ -114,9 +130,11 @@ connection slave;
# RESET SLAVE and see if error is cleared in SHOW SLAVE STATUS.
stop slave;
reset slave;
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 16 # 23 # 33 #
-show slave status;
+let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1);
+echo Last_SQL_Errno=$last_error;
+let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1);
+echo Last_SQL_Error;
+echo $last_error;
# Finally, see if logging is done ok on master for a failing LOAD DATA INFILE
@@ -125,7 +143,7 @@ reset master;
eval create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
unique(day)) engine=$engine_type; # no transactions
--error ER_DUP_ENTRY
-load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
+eval $lower_stmt_head infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
'\n##\n' starting by '>' ignore 1 lines;
select * from t2;
@@ -141,7 +159,7 @@ alter table t2 drop key day;
connection master;
delete from t2;
--error ER_DUP_ENTRY
-load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
+eval $lower_stmt_head infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
'\n##\n' starting by '>' ignore 1 lines;
connection slave;
@@ -154,7 +172,7 @@ drop table t1, t2;
CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
--error ER_DUP_ENTRY
-LOAD DATA INFILE "../../std_data/words.dat" INTO TABLE t1;
+eval $UPPER_STMT_HEAD INFILE "../../std_data/words.dat" INTO TABLE t1;
DROP TABLE IF EXISTS t1;
@@ -182,17 +200,17 @@ DROP TABLE IF EXISTS t1;
-- echo ### assertion: works with cross-referenced database
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
+-- eval $UPPER_STMT_HEAD LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
-- eval use $db1
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- echo ### assertion: works with fully qualified name on current database
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
+-- eval $UPPER_STMT_HEAD LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
-- echo ### assertion: works without fully qualified name on current database
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1
+-- eval $UPPER_STMT_HEAD LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1
-- echo ### create connection without default database
-- echo ### connect (conn2,localhost,root,,*NO-ONE*);
@@ -200,7 +218,7 @@ connect (conn2,localhost,root,,*NO-ONE*)
-- connection conn2
-- echo ### assertion: works without stating the default database
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
+-- eval $UPPER_STMT_HEAD LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
-- echo ### disconnect and switch back to master connection
-- disconnect conn2
-- connection master
@@ -219,4 +237,18 @@ source include/diff_tables.inc;
-- sync_slave_with_master
+# BUG#49479: LOAD DATA INFILE is binlogged without escaping field names
+-- source include/master-slave-reset.inc
+-- connection master
+use test;
+CREATE TABLE t1 (`key` TEXT, `text` TEXT);
+
+LOAD DATA INFILE '../../std_data/loaddata2.dat' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ',';
+SELECT * FROM t1;
+
+-- sync_slave_with_master
+-- connection master
+DROP TABLE t1;
+-- sync_slave_with_master
+
# End of 4.1 tests
=== added file 'mysql-test/extra/rpl_tests/rpl_mixing_engines.inc'
--- a/mysql-test/extra/rpl_tests/rpl_mixing_engines.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_mixing_engines.inc 2010-01-20 19:08:16 +0000
@@ -0,0 +1,554 @@
+################################################################################
+# This is an auxiliary file used by rpl_mixing_engines.test, and that it
+# executes SQL statements according to a format string, as specified in
+# rpl_mixing_engines.test. In addition, it accepts the special format
+# strings 'configure' and 'clean', used before and after everything else.
+################################################################################
+
+if (`SELECT HEX(@commands) = HEX('configure')`)
+{
+ connection master;
+
+ SET SQL_LOG_BIN=0;
+ eval CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval SET SQL_LOG_BIN=1;
+
+ connection slave;
+
+ SET SQL_LOG_BIN=0;
+ eval CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+ eval CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ eval CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
+ SET SQL_LOG_BIN=1;
+
+ connection master;
+
+ INSERT INTO nt_1(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO nt_2(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO nt_3(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO nt_4(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO nt_5(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO nt_6(trans_id, stmt_id) VALUES(1,1);
+
+ INSERT INTO tt_1(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO tt_2(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO tt_3(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO tt_4(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO tt_5(trans_id, stmt_id) VALUES(1,1);
+ INSERT INTO tt_6(trans_id, stmt_id) VALUES(1,1);
+
+ DELIMITER |;
+
+ CREATE PROCEDURE pc_i_tt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
+ BEGIN
+ DECLARE in_stmt_id INTEGER;
+ SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
+ SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
+ INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
+ INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
+ END|
+
+ CREATE PROCEDURE pc_i_nt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
+ BEGIN
+ DECLARE in_stmt_id INTEGER;
+ SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
+ SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
+ INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
+ INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
+ END|
+
+ CREATE FUNCTION fc_i_tt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
+ BEGIN
+ DECLARE in_stmt_id INTEGER;
+ SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
+ SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
+ INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
+ INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
+ RETURN "fc_i_tt_5_suc";
+ END|
+
+ CREATE FUNCTION fc_i_nt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
+ BEGIN
+ DECLARE in_stmt_id INTEGER;
+ SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
+ SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
+ INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
+ INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
+ RETURN "fc_i_nt_5_suc";
+ END|
+
+ CREATE TRIGGER tr_i_tt_3_to_nt_3 AFTER INSERT ON tt_3 FOR EACH ROW
+ BEGIN
+ DECLARE in_stmt_id INTEGER;
+ SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= NEW.trans_id;
+ SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
+ INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
+ INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
+ END|
+
+ CREATE TRIGGER tr_i_nt_4_to_tt_4 AFTER INSERT ON nt_4 FOR EACH ROW
+ BEGIN
+ DECLARE in_stmt_id INTEGER;
+ SELECT max(stmt_id) INTO in_stmt_id FROM tt_4 WHERE trans_id= NEW.trans_id;
+ SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
+ INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
+ INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
+ END|
+
+ CREATE TRIGGER tr_i_tt_5_to_tt_6 AFTER INSERT ON tt_5 FOR EACH ROW
+ BEGIN
+ DECLARE in_stmt_id INTEGER;
+ SELECT max(stmt_id) INTO in_stmt_id FROM tt_6 WHERE trans_id= NEW.trans_id;
+ SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id, 1), 1) INTO in_stmt_id;
+ INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
+ INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
+ END|
+
+ CREATE TRIGGER tr_i_nt_5_to_nt_6 AFTER INSERT ON nt_5 FOR EACH ROW
+ BEGIN
+ DECLARE in_stmt_id INTEGER;
+ SELECT max(stmt_id) INTO in_stmt_id FROM nt_6 WHERE trans_id= NEW.trans_id;
+ SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
+ INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
+ INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
+ END|
+
+ DELIMITER ;|
+
+ let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1);
+
+ let $trans_id= 7;
+ let $tb_id= 1;
+ let $stmt_id= 1;
+ let $commands= '';
+
+ SET @commands= '';
+}
+
+if (`SELECT HEX(@commands) = HEX('clean')`)
+{
+ connection master;
+
+ DROP TABLE tt_1;
+ DROP TABLE tt_2;
+ DROP TABLE tt_3;
+ DROP TABLE tt_4;
+ DROP TABLE tt_5;
+ DROP TABLE tt_6;
+
+ DROP TABLE nt_1;
+ DROP TABLE nt_2;
+ DROP TABLE nt_3;
+ DROP TABLE nt_4;
+ DROP TABLE nt_5;
+ DROP TABLE nt_6;
+
+ DROP PROCEDURE pc_i_tt_5_suc;
+ DROP PROCEDURE pc_i_nt_5_suc;
+ DROP FUNCTION fc_i_tt_5_suc;
+ DROP FUNCTION fc_i_nt_5_suc;
+
+ sync_slave_with_master;
+
+ SET @commands= '';
+}
+
+while (`SELECT HEX(@commands) != HEX('')`)
+{
+ --disable_query_log
+ SET @command= SUBSTRING_INDEX(@commands, ' ', 1);
+ let $command= `SELECT @command`;
+ --eval SET @check_commands= '$commands'
+ if (`SELECT HEX(@check_commands) = HEX('''')`)
+ {
+ let $commands= `SELECT @commands`;
+ }
+ --echo -b-b-b-b-b-b-b-b-b-b-b- >> $command << -b-b-b-b-b-b-b-b-b-b-b-
+ let $pos_command= query_get_value("SHOW MASTER STATUS", Position, 1);
+ --enable_query_log
+ if (`SELECT HEX(@command) = HEX('B')`)
+ {
+ eval BEGIN;
+ }
+ if (`SELECT HEX(@command) = HEX('T')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('T-trig')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO tt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('T-func')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval SELECT fc_i_tt_5_suc ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('T-proc')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval CALL pc_i_tt_5_suc ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('eT')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from tt_1`;
+ let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($old_trans_id, $old_stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('Te')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from tt_1`;
+ let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('Te-trig')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from tt_5`;
+ let $old_stmt_id= `SELECT max(stmt_id) from tt_5 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO tt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('Te-func')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from tt_1`;
+ let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO tt_1(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_tt_5_suc ($trans_id, $stmt_id));
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('N')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('N-trig')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO nt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('N-func')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval SELECT fc_i_nt_5_suc ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('N-proc')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval CALL pc_i_nt_5_suc ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('eN')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from nt_1`;
+ let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($old_trans_id, $old_stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('Ne')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from nt_1`;
+ let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('Ne-trig')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from nt_5`;
+ let $old_stmt_id= `SELECT max(stmt_id) from nt_5 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO nt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('Ne-func')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from nt_1`;
+ let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO nt_1(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_nt_5_suc ($trans_id, $stmt_id));
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('tN')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO nt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM tt_1;
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('tNe')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from nt_1`;
+ let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO nt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM tt_1 UNION SELECT $old_trans_id, $old_stmt_id, COUNT(*) FROM tt_1;
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('nT')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO tt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM nt_1;
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('nTe')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from tt_1`;
+ let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO tt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM nt_1 UNION SELECT $old_trans_id, $old_stmt_id, COUNT(*) FROM nt_1;
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('NT')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval UPDATE nt_3, tt_3 SET nt_3.info= "new text $trans_id --> $stmt_id", tt_3.info= "new text $trans_id --> $stmt_id" where nt_3.trans_id = tt_3.trans_id and tt_3.trans_id = 1;
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('NT-trig')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO nt_4(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('NT-func')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO nt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, fc_i_tt_5_suc($trans_id, $stmt_id));
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('NeT-trig')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from nt_4`;
+ let $old_stmt_id= `SELECT max(stmt_id) from nt_4 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO nt_4(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('NeT-func')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from nt_5`;
+ let $old_stmt_id= `SELECT max(stmt_id) from nt_5 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO nt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_tt_5_suc ($trans_id, $stmt_id));
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('TN')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval UPDATE tt_4, nt_4 SET tt_4.info= "new text $trans_id --> $stmt_id", nt_4.info= "new text $trans_id --> $stmt_id" where nt_4.trans_id = tt_4.trans_id and tt_4.trans_id = 1;
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('TN-trig')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO tt_3(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('TN-func')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ eval INSERT INTO tt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, fc_i_nt_5_suc($trans_id, $stmt_id));
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('TeN-trig')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from tt_3`;
+ let $old_stmt_id= `SELECT max(stmt_id) from tt_3 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO tt_3(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('TeN-func')`)
+ {
+ #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
+ let $old_trans_id= `SELECT max(trans_id) from tt_5`;
+ let $old_stmt_id= `SELECT max(stmt_id) from tt_5 where trans_id= $old_trans_id`;
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ eval INSERT INTO tt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_nt_5_suc ($trans_id, $stmt_id));
+ inc $stmt_id;
+ }
+ if (`SELECT HEX(@command) = HEX('CS-T->T')`)
+ {
+ --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=$engine_type SELECT * FROM tt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('CS-N->N')`)
+ {
+ --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=MyIsam SELECT * FROM nt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('CS-T->N')`)
+ {
+ --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=$engine_type SELECT * FROM nt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('CS-N->T')`)
+ {
+ --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=MyIsam SELECT * FROM tt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('CSe-T->T')`)
+ {
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=$engine_type SELECT stmt_id FROM tt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('CSe-N->N')`)
+ {
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=MyIsam SELECT stmt_id FROM nt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('CSe-T->N')`)
+ {
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=$engine_type SELECT stmt_id FROM nt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('CSe-N->T')`)
+ {
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=MyIsam SELECT stmt_id FROM tt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('CT')`)
+ {
+ --eval CREATE TEMPORARY TABLE tt_xx_$tb_id (a int) engine=$engine_type;
+ }
+ if (`SELECT HEX(@command) = HEX('IS-T<-N')`)
+ {
+ --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM nt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('ISe-T<-N')`)
+ {
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM nt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('IS-N<-T')`)
+ {
+ --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM tt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('ISe-N<-T')`)
+ {
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM tt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('IS-T<-T')`)
+ {
+ --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM tt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('ISe-T<-T')`)
+ {
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM tt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('IS-N<-N')`)
+ {
+ --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM nt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('ISe-N<-N')`)
+ {
+ --error ER_DUP_ENTRY, ER_DUP_KEY
+ --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM nt_1;
+ }
+ if (`SELECT HEX(@command) = HEX('trunc-CS-T')`)
+ {
+ eval TRUNCATE TABLE tt_xx_$tb_id;
+ }
+ if (`SELECT HEX(@command) = HEX('trunc-CS-N')`)
+ {
+ eval TRUNCATE TABLE nt_xx_$tb_id;
+ }
+ if (`SELECT HEX(@command) = HEX('trunc-CT')`)
+ {
+ eval TRUNCATE TABLE tt_xx_$tb_id;
+ }
+ if (`SELECT HEX(@command) = HEX('drop-CS')`)
+ {
+ --disable_warnings
+ eval DROP TABLE IF EXISTS tt_xx_$tb_id, nt_xx_$tb_id;
+ inc $tb_id;
+ --enable_warnings
+ }
+ if (`SELECT HEX(@command) = HEX('drop-CT')`)
+ {
+ --disable_warnings
+ eval DROP TEMPORARY TABLE IF EXISTS tt_xx_$tb_id;
+ inc $tb_id;
+ --enable_warnings
+ }
+ if (`SELECT HEX(@command) = HEX('C')`)
+ {
+ --error 0, ER_GET_ERRMSG
+ eval COMMIT;
+ }
+ if (`SELECT HEX(@command) = HEX('R')`)
+ {
+ --error 0, ER_GET_ERRMSG
+ eval ROLLBACK;
+ }
+ if (`SELECT HEX(@command) = HEX('S1')`)
+ {
+ eval SAVEPOINT s1;
+ }
+ if (`SELECT HEX(@command) = HEX('R1')`)
+ {
+ eval ROLLBACK TO s1;
+ }
+ --disable_query_log
+ SET @commands= LTRIM(SUBSTRING(@commands, LENGTH(@command) + 1));
+ inc $stmt_id;
+
+ let $binlog_start= $pos_command;
+ --source include/show_binlog_events.inc
+ --echo -e-e-e-e-e-e-e-e-e-e-e- >> $command << -e-e-e-e-e-e-e-e-e-e-e-
+ if (`SELECT HEX(@commands) = HEX('')`)
+ {
+ let $binlog_start= $pos_trans_command;
+ --echo -b-b-b-b-b-b-b-b-b-b-b- >> $commands << -b-b-b-b-b-b-b-b-b-b-b-
+ --source include/show_binlog_events.inc
+ --echo -e-e-e-e-e-e-e-e-e-e-e- >> $commands << -e-e-e-e-e-e-e-e-e-e-e-
+ --echo
+ let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1);
+ let $stmt_id= 1;
+ inc $trans_id;
+ let $commands= '';
+ }
+}
=== added file 'mysql-test/extra/rpl_tests/rpl_not_null.test'
--- a/mysql-test/extra/rpl_tests/rpl_not_null.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_not_null.test 2009-10-22 00:19:52 +0000
@@ -0,0 +1,364 @@
+#################################################################################
+# This test checks if the replication between "null" fields to either "null"
+# fields or "not null" fields works properly. In the first case, the execution
+# should work fine. In the second case, it may fail according to the sql_mode
+# being used.
+#
+# The test is devided in three main parts:
+#
+# 1 - NULL --> NULL (no failures)
+# 2 - NULL --> NOT NULL ( sql-mode = STRICT and failures)
+# 3 - NULL --> NOT NULL ( sql-mode != STRICT and no failures)
+#
+#################################################################################
+connection master;
+
+SET SQL_LOG_BIN= 0;
+eval CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+eval CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+eval CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+eval CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+
+connection slave;
+
+eval CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+eval CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+eval CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00',
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+eval CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00',
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+--echo ************* EXECUTION WITH INSERTS *************
+connection master;
+INSERT INTO t1(a,b,c) VALUES (1, null, 1);
+INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, 4);
+INSERT INTO t1(a) VALUES (5);
+
+INSERT INTO t2(a,b) VALUES (1, null);
+INSERT INTO t2(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t2(a) VALUES (3);
+
+INSERT INTO t3(a,b) VALUES (1, null);
+INSERT INTO t3(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t3(a) VALUES (3);
+
+INSERT INTO t4(a,b,c) VALUES (1, null, 1);
+INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t4(a,b) VALUES (3, null);
+INSERT INTO t4(a,c) VALUES (4, 4);
+INSERT INTO t4(a) VALUES (5);
+
+--echo ************* SHOWING THE RESULT SETS WITH INSERTS *************
+sync_slave_with_master;
+
+--echo TABLES t1 and t2 must be equal otherwise an error will be thrown.
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+let $diff_table_1=master:test.t2;
+let $diff_table_2=slave:test.t2;
+source include/diff_tables.inc;
+
+--echo TABLES t2 and t3 must be different.
+connection master;
+SELECT * FROM t3 ORDER BY a;
+connection slave;
+SELECT * FROM t3 ORDER BY a;
+connection master;
+SELECT * FROM t4 ORDER BY a;
+connection slave;
+SELECT * FROM t4 ORDER BY a;
+
+--echo ************* EXECUTION WITH UPDATES and REPLACES *************
+connection master;
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1);
+REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+UPDATE t1 set b= NULL, c= 300 where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300);
+
+--echo ************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
+sync_slave_with_master;
+
+--echo TABLES t1 and t2 must be equal otherwise an error will be thrown.
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+--echo ************* CLEANING *************
+connection master;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+
+sync_slave_with_master;
+
+connection master;
+
+SET SQL_LOG_BIN= 0;
+eval CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= $engine;
+SET SQL_LOG_BIN= 1;
+
+connection slave;
+
+eval CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= $engine;
+
+--echo ************* EXECUTION WITH INSERTS *************
+connection master;
+INSERT INTO t1(a,b,c) VALUES (1, null, b'01');
+INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01');
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, b'01');
+INSERT INTO t1(a) VALUES (5);
+
+--echo ************* SHOWING THE RESULT SETS WITH INSERTS *************
+--echo TABLES t1 and t2 must be different.
+sync_slave_with_master;
+connection master;
+SELECT a,b+0,c+0 FROM t1 ORDER BY a;
+connection slave;
+SELECT a,b+0,c+0 FROM t1 ORDER BY a;
+
+--echo ************* EXECUTION WITH UPDATES and REPLACES *************
+connection master;
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01');
+REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01');
+UPDATE t1 set b= NULL, c= b'00' where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00');
+
+--echo ************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
+--echo TABLES t1 and t2 must be equal otherwise an error will be thrown.
+sync_slave_with_master;
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+connection master;
+
+DROP TABLE t1;
+
+sync_slave_with_master;
+
+--echo ################################################################################
+--echo # NULL ---> NOT NULL (STRICT MODE)
+--echo # UNCOMMENT THIS AFTER FIXING BUG#43992
+--echo ################################################################################
+#connection slave;
+#SET GLOBAL sql_mode="TRADITIONAL";
+#
+#STOP SLAVE;
+#--source include/wait_for_slave_to_stop.inc
+#START SLAVE;
+#--source include/wait_for_slave_to_start.inc
+#
+#let $y=0;
+#while (`select $y < 6`)
+#{
+# connection master;
+#
+# SET SQL_LOG_BIN= 0;
+# eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+# eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+# eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+# SET SQL_LOG_BIN= 1;
+#
+# connection slave;
+#
+# eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+# `c` INT NOT NULL,
+# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+# eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+# `c` INT,
+# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+# eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+# `c` INT DEFAULT 500,
+# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+#
+# if (`select $y=0`)
+# {
+# --echo ************* EXECUTION WITH INSERTS *************
+# connection master;
+# INSERT INTO t1(a) VALUES (1);
+# }
+#
+# if (`select $y=1`)
+# {
+# --echo ************* EXECUTION WITH INSERTS *************
+# connection master;
+# INSERT INTO t1(a, b) VALUES (1, NULL);
+# }
+#
+# if (`select $y=2`)
+# {
+# --echo ************* EXECUTION WITH UPDATES *************
+# connection master;
+# INSERT INTO t3(a, b) VALUES (1, 1);
+# INSERT INTO t3(a, b) VALUES (2, 1);
+# UPDATE t3 SET b = NULL where a= 1;
+# }
+#
+# if (`select $y=3`)
+# {
+# --echo ************* EXECUTION WITH INSERTS/REPLACES *************
+# connection master;
+# REPLACE INTO t3(a, b) VALUES (1, null);
+# }
+#
+# if (`select $y=4`)
+# {
+# --echo ************* EXECUTION WITH UPDATES/REPLACES *************
+# connection master;
+# INSERT INTO t3(a, b) VALUES (1, 1);
+# REPLACE INTO t3(a, b) VALUES (1, null);
+# }
+#
+# if (`select $y=5`)
+# {
+# --echo ************* EXECUTION WITH MULTI-ROW INSERTS *************
+# connection master;
+#
+# SET SQL_LOG_BIN= 0;
+# INSERT INTO t2(a, b) VALUES (1, 1);
+# INSERT INTO t2(a, b) VALUES (2, 1);
+# INSERT INTO t2(a, b) VALUES (3, null);
+# INSERT INTO t2(a, b) VALUES (4, 1);
+# INSERT INTO t2(a, b) VALUES (5, 1);
+# SET SQL_LOG_BIN= 1;
+#
+# INSERT INTO t2 SELECT a + 10, b from t2;
+# --echo The statement below is just executed to stop processing
+# INSERT INTO t1(a) VALUES (1);
+# }
+#
+# --echo ************* SHOWING THE RESULT SETS *************
+# connection slave;
+# --source include/wait_for_slave_sql_to_stop.inc
+# connection master;
+# SELECT * FROM t1 ORDER BY a;
+# connection slave;
+# SELECT * FROM t1 ORDER BY a;
+# connection master;
+# SELECT * FROM t2 ORDER BY a;
+# connection slave;
+# SELECT * FROM t2 ORDER BY a;
+# connection master;
+# SELECT * FROM t3 ORDER BY a;
+# connection slave;
+# SELECT * FROM t3 ORDER BY a;
+# --source include/reset_master_and_slave.inc
+#
+# connection master;
+#
+# DROP TABLE t1;
+# DROP TABLE t2;
+# DROP TABLE t3;
+#
+# sync_slave_with_master;
+#
+# inc $y;
+#}
+#connection slave;
+#SET GLOBAL sql_mode="";
+#
+#STOP SLAVE;
+#source include/wait_for_slave_to_stop.inc;
+#START SLAVE;
+#--source include/wait_for_slave_to_start.inc
+
+--echo ################################################################################
+--echo # NULL ---> NOT NULL (NON-STRICT MODE)
+--echo ################################################################################
+connection master;
+
+SET SQL_LOG_BIN= 0;
+eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+
+connection slave;
+
+eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT NOT NULL,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
+
+--echo ************* EXECUTION WITH INSERTS *************
+connection master;
+INSERT INTO t1(a) VALUES (1);
+INSERT INTO t1(a, b) VALUES (2, NULL);
+INSERT INTO t1(a, b) VALUES (3, 1);
+
+INSERT INTO t2(a) VALUES (1);
+INSERT INTO t2(a, b) VALUES (2, NULL);
+INSERT INTO t2(a, b) VALUES (3, 1);
+
+INSERT INTO t3(a) VALUES (1);
+INSERT INTO t3(a, b) VALUES (2, NULL);
+INSERT INTO t3(a, b) VALUES (3, 1);
+INSERT INTO t3(a, b) VALUES (4, 1);
+REPLACE INTO t3(a, b) VALUES (5, null);
+
+REPLACE INTO t3(a, b) VALUES (3, null);
+UPDATE t3 SET b = NULL where a = 4;
+
+--echo ************* SHOWING THE RESULT SETS *************
+connection master;
+sync_slave_with_master;
+
+connection master;
+SELECT * FROM t1 ORDER BY a;
+connection slave;
+SELECT * FROM t1 ORDER BY a;
+connection master;
+SELECT * FROM t2 ORDER BY a;
+connection slave;
+SELECT * FROM t2 ORDER BY a;
+connection master;
+SELECT * FROM t3 ORDER BY a;
+connection slave;
+SELECT * FROM t3 ORDER BY a;
+
+connection master;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+sync_slave_with_master;
=== modified file 'mysql-test/extra/rpl_tests/rpl_row_func003.test'
--- a/mysql-test/extra/rpl_tests/rpl_row_func003.test 2007-06-18 13:36:10 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_row_func003.test 2010-01-13 09:00:03 +0000
@@ -18,6 +18,8 @@
# Vs slave. #
#############################################################################
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
+
# Begin clean up test section
connection master;
--disable_warnings
@@ -43,10 +45,12 @@ RETURN tmp;
END|
delimiter ;|
+--disable_warnings
INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
sleep 6;
INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
sleep 6;
+--enable_warnings
#Select in this test are used for debugging
#select * from test.t1;
@@ -56,7 +60,9 @@ sleep 6;
connection master;
SET AUTOCOMMIT=0;
START TRANSACTION;
+--disable_warnings
INSERT INTO test.t1 VALUES (null,test.f1());
+--enable_warnings
ROLLBACK;
SET AUTOCOMMIT=1;
#select * from test.t1;
=== modified file 'mysql-test/extra/rpl_tests/rpl_row_tabledefs.test'
--- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test 2008-03-14 20:02:52 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test 2009-10-22 00:10:42 +0000
@@ -111,21 +111,18 @@ SELECT a,b,x FROM t1_int ORDER BY a;
SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit ORDER BY a;
SELECT a,b,x FROM t1_char ORDER BY a;
-# Each of these inserts should generate an error and stop the slave
-
connection master;
INSERT INTO t9 VALUES (2);
sync_slave_with_master;
# Now slave is guaranteed to be running
connection master;
INSERT INTO t1_nodef VALUES (1,2);
-connection slave;
---source include/wait_for_slave_sql_to_stop.inc
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 4 # 7 # 8 # 9 # 20 <Last_Error> 22 # 23 # 33 # 35 <Last_IO_Errno> 36 <Last_IO_Error> 38 <Last_SQL_Error>
---query_vertical SHOW SLAVE STATUS
-SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
-START SLAVE;
+
+# Last insert on wider slave table succeeds while slave sql sql_mode permits.
+# The previous version of the above test expected slave sql to stop.
+# bug#38173 relaxed conditions to stop only with the strict mode.
+sync_slave_with_master;
+select count(*) from t1_nodef;
#
# Replicating to tables with fewer columns at the end works as of WL#3228
=== added file 'mysql-test/extra/rpl_tests/rpl_set_null.test'
--- a/mysql-test/extra/rpl_tests/rpl_set_null.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_set_null.test 2010-01-21 17:20:24 +0000
@@ -0,0 +1,86 @@
+# Both of the following tests check that comparison of binlog BI
+# against SE record will not fail due to remains from previous values
+# in the SE record (before a given field was set to null).
+#
+# In MIXED mode:
+# - Insert and update are executed as statements
+# - Delete is executed as a row event
+# - Assertion: checks that comparison will not fail because the update
+# statement will clear the record contents for the nulled
+# field. If data was not cleared, some engines may keep
+# the value and return it later as garbage - despite the
+# fact that field is null. This may cause slave to
+# falsely fail in the comparison (memcmp would fail
+# because of "garbage" in record data).
+#
+# In ROW mode:
+# - Insert, update and delete are executed as row events.
+# - Assertion: checks that comparison will not fail because the update
+# rows event will clear the record contents before
+# feeding the new value to the SE. This protects against
+# SEs that do not clear record contents when storing
+# nulled fields. If the engine did not clear the data it
+# would cause slave to falsely fail in the comparison
+# (memcmp would fail because of "garbage" in record
+# data). This scenario is pretty much the same described
+# above in MIXED mode, but checks different execution
+# path in the slave.
+
+# BUG#49481: RBR: MyISAM and bit fields may cause slave to stop on
+# delete cant find record
+
+-- source include/master-slave-reset.inc
+
+-- connection master
+-- eval CREATE TABLE t1 (c1 BIT, c2 INT) Engine=$engine
+INSERT INTO `t1` VALUES ( 1, 1 );
+UPDATE t1 SET c1=NULL where c2=1;
+-- sync_slave_with_master
+
+-- let $diff_table_1=master:test.t1
+-- let $diff_table_2=slave:test.t1
+-- source include/diff_tables.inc
+
+-- connection master
+# triggers switch to row mode when on mixed
+DELETE FROM t1 WHERE c2=1 LIMIT 1;
+-- sync_slave_with_master
+
+-- let $diff_table_1=master:test.t1
+-- let $diff_table_2=slave:test.t1
+-- source include/diff_tables.inc
+
+-- connection master
+DROP TABLE t1;
+-- sync_slave_with_master
+
+-- source include/master-slave-reset.inc
+
+-- connection master
+
+# BUG#49482: RBR: Replication may break on deletes when MyISAM tables
+# + char field are used
+
+-- eval CREATE TABLE t1 (c1 CHAR) Engine=$engine
+
+INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ;
+SELECT * FROM t1;
+UPDATE t1 SET c1=NULL WHERE c1='w';
+-- sync_slave_with_master
+
+-- let $diff_table_1=master:test.t1
+-- let $diff_table_2=slave:test.t1
+-- source include/diff_tables.inc
+
+-- connection master
+# triggers switch to row mode when on mixed
+DELETE FROM t1 LIMIT 2;
+-- sync_slave_with_master
+
+-- let $diff_table_1=master:test.t1
+-- let $diff_table_2=slave:test.t1
+-- source include/diff_tables.inc
+
+-- connection master
+DROP TABLE t1;
+-- sync_slave_with_master
=== modified file 'mysql-test/extra/rpl_tests/rpl_stm_000001.test'
--- a/mysql-test/extra/rpl_tests/rpl_stm_000001.test 2009-10-20 18:00:07 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_stm_000001.test 2009-11-18 14:50:31 +0000
@@ -1,6 +1,11 @@
--- source include/have_binlog_format_mixed_or_statement.inc
+# Requires binlog_format=statement format since query involving
+# get_lock() is logged in row format if binlog_format=mixed or row.
+-- source include/have_binlog_format_statement.inc
-- source include/master-slave.inc
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
+
+# Load some data into t1
create table t1 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t1;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
@@ -10,9 +15,7 @@ select * from t1 limit 10;
#
# Test slave with wrong password
#
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
stop slave;
connection master;
set password for root@"localhost" = password('foo');
@@ -29,16 +32,12 @@ sleep 2;
create table t3(n int);
insert into t3 values(1),(2);
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
select * from t3;
select sum(length(word)) from t1;
connection master;
drop table t1,t3;
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
# Test if the slave SQL thread can be more than 16K behind the slave
# I/O thread (> IO_SIZE)
@@ -77,12 +76,13 @@ unlock tables;
connection master;
create table t2(id int);
insert into t2 values(connection_id());
-save_master_pos;
connection master1;
# Avoid generating result
create temporary table t3(n int);
+--disable_warnings
insert into t3 select get_lock('crash_lock%20C', 1) from t2;
+--enable_warnings
connection master;
send update t1 set n = n + get_lock('crash_lock%20C', 2);
@@ -93,8 +93,11 @@ kill @id;
# We don't drop t3 as this is a temporary table
drop table t2;
connection master;
+# The get_lock function causes warning for unsafe statement.
+--disable_warnings
--error 1317,2013
reap;
+--enable_warnings
connection slave;
# The SQL slave thread should now have stopped because the query was killed on
# the master (so it has a non-zero error code in the binlog).
@@ -117,16 +120,12 @@ insert into mysql.user (Host, User, Pass
select select_priv,user from mysql.user where user = _binary'blafasel2';
update mysql.user set Select_priv = "Y" where User= _binary"blafasel2";
select select_priv,user from mysql.user where user = _binary'blafasel2';
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
select n from t1;
select select_priv,user from mysql.user where user = _binary'blafasel2';
connection master1;
drop table t1;
delete from mysql.user where user="blafasel2";
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
# End of 4.1 tests
=== added file 'mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test'
--- a/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-03-28 18:10:00 +0000
@@ -0,0 +1,160 @@
+#
+# This test verify if executing DDL statement before trying to manipulate
+# a temporary table causes row-based replication to break with error 'table
+# does not exist'.
+#
+
+# CREATE TABLE when a temporary table is open.
+CREATE TEMPORARY TABLE t1 (a INT);
+EVAL CREATE TABLE t2 (a INT, b INT) ENGINE= $ENGINE_TYPE;
+INSERT INTO t1 VALUES (1);
+
+# CREATE EVENT when a temporary table is open.
+CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+
+# ALTER EVENT when a temporary table is open.
+ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+
+# DROP EVENT when a temporary table is open.
+DROP EVENT IF EXISTS e1;
+INSERT INTO t1 VALUES (1);
+
+# CREATE PROCEDURE when a temporary table is open.
+CREATE PROCEDURE p1() SELECT 1;
+INSERT INTO t1 VALUES (1);
+
+# Alter PROCEDURE when a temporary table is open.
+ALTER PROCEDURE p1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+
+# CREATE FUNCTION when a temporary table is open.
+CREATE FUNCTION f1() RETURNS INT RETURN 123;
+INSERT INTO t1 VALUES (1);
+
+# ALTER FUNCTION when a temporary table is open.
+ALTER FUNCTION f1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+
+# CREATE DATABASE when a temporary table is open.
+CREATE DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+
+# DROP DATABASE when a temporary table is open.
+DROP DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+
+# CREATE USER when a temporary table is open.
+CREATE USER test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# GRANT select on table to user when a temporary table is open.
+GRANT SELECT ON t2 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# GRANT all on function to user when a temporary table is open.
+GRANT ALL ON f1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# GRANT all on procedure to user when a temporary table is open.
+GRANT ALL ON p1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# GRANT usage on *.* to user when a temporary table is open.
+GRANT USAGE ON *.* TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# REVOKE ALL PRIVILEGES on function to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# REVOKE ALL PRIVILEGES on table to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# REVOKE usage on *.* from user when a temporary table is open.
+REVOKE USAGE ON *.* FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# RENAME USER when a temporary table is open.
+RENAME USER test_1@localhost TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+
+# DROP USER when a temporary table is open.
+DROP USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+
+# Test ACL statement in sub statement
+DELIMITER |;
+CREATE PROCEDURE p2()
+BEGIN
+ # CREATE USER when a temporary table is open.
+ CREATE TEMPORARY TABLE t3 (a INT);
+ CREATE USER test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # GRANT select on table to user when a temporary table is open.
+ GRANT SELECT ON t2 TO test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # GRANT all on function to user when a temporary table is open.
+ GRANT ALL ON f1 TO test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # GRANT all on procedure to user when a temporary table is open.
+ GRANT ALL ON p1 TO test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # GRANT usage on *.* to user when a temporary table is open.
+ GRANT USAGE ON *.* TO test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # REVOKE ALL PRIVILEGES on function to user when a temporary table is open.
+ REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open.
+ REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # REVOKE ALL PRIVILEGES on table to user when a temporary table is open.
+ REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # REVOKE usage on *.* from user when a temporary table is open.
+ REVOKE USAGE ON *.* FROM test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # RENAME USER when a temporary table is open.
+ RENAME USER test_2@localhost TO test_3@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # DROP USER when a temporary table is open.
+ DROP USER test_3@localhost;
+ INSERT INTO t1 VALUES (1);
+ DROP TEMPORARY TABLE t3;
+END |
+DELIMITER ;|
+
+# DROP PROCEDURE when a temporary table is open.
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (1);
+DROP PROCEDURE p2;
+INSERT INTO t1 VALUES (1);
+
+# DROP FUNCTION when a temporary table is open.
+DROP FUNCTION f1;
+INSERT INTO t1 VALUES (1);
+
+# DROP TABLE when a temporary table is open.
+DROP TABLE t2;
+INSERT INTO t1 VALUES (1);
+
+DROP TEMPORARY TABLE t1;
+
+--sync_slave_with_master
=== added file 'mysql-test/include/binlog_inject_error.inc'
--- a/mysql-test/include/binlog_inject_error.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/binlog_inject_error.inc 2010-01-24 07:03:23 +0000
@@ -0,0 +1,22 @@
+#
+# === Name
+#
+# binlog_inject_error.inc
+#
+# === Description
+#
+# Inject binlog write error when running the query, verifies that the
+# query is ended with the proper error (ER_ERROR_ON_WRITE).
+#
+# === Usage
+#
+# let query= 'CREATE TABLE t1 (a INT)';
+# source include/binlog_inject_error.inc;
+#
+
+SET GLOBAL debug='d,injecting_fault_writing';
+--echo $query;
+--replace_regex /(errno: .*)/(errno: #)/
+--error ER_ERROR_ON_WRITE
+--eval $query
+SET GLOBAL debug='';
=== modified file 'mysql-test/include/default_mysqld.cnf'
--- a/mysql-test/include/default_mysqld.cnf 2008-04-08 14:51:26 +0000
+++ b/mysql-test/include/default_mysqld.cnf 2010-03-28 18:10:00 +0000
@@ -2,7 +2,7 @@
[mysqld]
open-files-limit= 1024
local-infile
-default-character-set= latin1
+character-set-server= latin1
# Increase default connect_timeout to avoid intermittent
# disconnects when test servers are put under load see BUG#28359
=== modified file 'mysql-test/include/have_big5.inc'
--- a/mysql-test/include/have_big5.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_big5.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_big5.require
-disable_query_log;
-show collation like 'big5_chinese_ci';
-enable_query_log;
+let collation=big5_chinese_ci;
+--source include/have_collation.inc
=== added file 'mysql-test/include/have_collation.inc'
--- a/mysql-test/include/have_collation.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/have_collation.inc 2009-12-27 13:54:41 +0000
@@ -0,0 +1,3 @@
+if (!`SELECT count(*) AS 'true' FROM information_schema.collations WHERE collation_name LIKE '$collation'`) {
+ skip Test needs character set '$collation';
+}
=== modified file 'mysql-test/include/have_cp1250_ch.inc'
--- a/mysql-test/include/have_cp1250_ch.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_cp1250_ch.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_cp1250_ch.require
-disable_query_log;
-show collation like 'cp1250_czech_cs';
-enable_query_log;
+let collation=cp1250_czech_cs;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_cp1251.inc'
--- a/mysql-test/include/have_cp1251.inc 2007-06-28 17:34:54 +0000
+++ b/mysql-test/include/have_cp1251.inc 2009-12-27 13:54:41 +0000
@@ -1,7 +1,2 @@
---require r/have_cp1251.require
-
---disable_query_log
-
-SHOW COLLATION LIKE 'cp1251_general_ci';
-
---enable_query_log
+let collation=cp1251_general_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_cp866.inc'
--- a/mysql-test/include/have_cp866.inc 2007-06-28 17:34:54 +0000
+++ b/mysql-test/include/have_cp866.inc 2009-12-27 13:54:41 +0000
@@ -1,7 +1,2 @@
---require r/have_cp866.require
-
---disable_query_log
-
-SHOW COLLATION LIKE 'cp866_general_ci';
-
---enable_query_log
+let collation=cp866_general_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_cp932.inc'
--- a/mysql-test/include/have_cp932.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_cp932.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_cp932.require
-disable_query_log;
-show collation like 'cp932_japanese_ci';
-enable_query_log;
+let collation=cp932_japanese_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_eucjpms.inc'
--- a/mysql-test/include/have_eucjpms.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_eucjpms.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_eucjpms.require
-disable_query_log;
-show collation like 'eucjpms_japanese_ci';
-enable_query_log;
+let collation=eucjpms_japanese_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_euckr.inc'
--- a/mysql-test/include/have_euckr.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_euckr.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_euckr.require
-disable_query_log;
-show collation like 'euckr_korean_ci';
-enable_query_log;
+let collation=euckr_korean_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_gb2312.inc'
--- a/mysql-test/include/have_gb2312.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_gb2312.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_gb2312.require
-disable_query_log;
-show collation like 'gb2312_chinese_ci';
-enable_query_log;
+let collation=gb2312_chinese_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_gbk.inc'
--- a/mysql-test/include/have_gbk.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_gbk.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_gbk.require
-disable_query_log;
-show collation like 'gbk_chinese_ci';
-enable_query_log;
+let collation=gbk_chinese_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_koi8r.inc'
--- a/mysql-test/include/have_koi8r.inc 2007-06-28 17:34:54 +0000
+++ b/mysql-test/include/have_koi8r.inc 2009-12-27 13:54:41 +0000
@@ -1,7 +1,2 @@
---require r/have_koi8r.require
-
---disable_query_log
-
-SHOW COLLATION LIKE 'koi8r_general_ci';
-
---enable_query_log
+let collation=koi8r_general_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_latin2_ch.inc'
--- a/mysql-test/include/have_latin2_ch.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_latin2_ch.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_latin2_ch.require
-disable_query_log;
-show collation like 'latin2_czech_cs';
-enable_query_log;
+let collation=latin2_czech_cs;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_sjis.inc'
--- a/mysql-test/include/have_sjis.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_sjis.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_sjis.require
-disable_query_log;
-show collation like 'sjis_japanese_ci';
-enable_query_log;
+let collation=sjis_japanese_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_tis620.inc'
--- a/mysql-test/include/have_tis620.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_tis620.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_tis620.require
-disable_query_log;
-show collation like 'tis620_thai_ci';
-enable_query_log;
+let collation=tis620_thai_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_ucs2.inc'
--- a/mysql-test/include/have_ucs2.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_ucs2.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_ucs2.require
-disable_query_log;
-show collation like 'ucs2_general_ci';
-enable_query_log;
+let collation=ucs2_general_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_ujis.inc'
--- a/mysql-test/include/have_ujis.inc 2008-07-04 16:41:27 +0000
+++ b/mysql-test/include/have_ujis.inc 2009-12-27 13:54:41 +0000
@@ -1,4 +1,2 @@
--- require r/have_ujis.require
-disable_query_log;
-show collation like 'ujis_japanese_ci';
-enable_query_log;
+let collation=ujis_japanese_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/have_utf8.inc'
--- a/mysql-test/include/have_utf8.inc 2007-06-28 17:34:54 +0000
+++ b/mysql-test/include/have_utf8.inc 2009-12-27 13:54:41 +0000
@@ -1,7 +1,2 @@
---require r/have_utf8.require
-
---disable_query_log
-
-SHOW COLLATION LIKE 'utf8_general_ci';
-
---enable_query_log
+let collation=utf8_general_ci;
+--source include/have_collation.inc
=== modified file 'mysql-test/include/kill_query.inc'
--- a/mysql-test/include/kill_query.inc 2009-03-27 05:19:50 +0000
+++ b/mysql-test/include/kill_query.inc 2009-12-10 03:44:19 +0000
@@ -52,7 +52,7 @@ if (`SELECT '$debug_lock' != ''`)
# reap the result of the waiting query
connection $connection_name;
-error 0, 1317, 1307, 1306, 1334, 1305;
+error 0, 1317, 1307, 1306, 1334, 1305, 1034;
reap;
connection master;
=== modified file 'mysql-test/include/mtr_warnings.sql'
--- a/mysql-test/include/mtr_warnings.sql 2009-12-03 11:19:05 +0000
+++ b/mysql-test/include/mtr_warnings.sql 2010-01-15 15:27:55 +0000
@@ -175,6 +175,8 @@ INSERT INTO global_suppressions VALUES
("Can't find file: '.\\\\test\\\\\\?{8}.frm'"),
("Slave: Unknown table 't1' Error_code: 1051"),
+ /* Maria storage engine dependent tests */
+
/* maria-recovery.test has warning about missing log file */
("File '.*maria_log.000.*' not found \\(Errcode: 2\\)"),
/* and about marked-corrupted table */
@@ -184,6 +186,14 @@ INSERT INTO global_suppressions VALUES
("Table '..mysqltest.t_corrupted2' is marked as crashed and should be"),
("Incorrect key file for table '..mysqltest.t_corrupted2.MAI'"),
+ /*
+ Transient network failures that cause warnings on reconnect.
+ BUG#47743 and BUG#47983.
+ */
+ ("Slave I/O: Get master SERVER_ID failed with error:.*"),
+ ("Slave I/O: Get master clock failed with error:.*"),
+ ("Slave I/O: Get master COLLATION_SERVER failed with error:.*"),
+ ("Slave I/O: Get master TIME_ZONE failed with error:.*"),
("THE_LAST_SUPPRESSION")||
=== modified file 'mysql-test/include/ps_conv.inc'
--- a/mysql-test/include/ps_conv.inc 2007-07-04 09:20:53 +0000
+++ b/mysql-test/include/ps_conv.inc 2010-01-19 10:36:52 +0000
@@ -30,6 +30,9 @@
--disable_warnings
drop table if exists t5 ;
--enable_warnings
+--disable_query_log
+SET TIME_ZONE= '+03:00';
+--enable_query_log
set @arg01= 8;
set @arg02= 8.0;
set @arg03= 80.00000000000e-1;
=== modified file 'mysql-test/include/setup_fake_relay_log.inc'
--- a/mysql-test/include/setup_fake_relay_log.inc 2009-02-09 13:17:04 +0000
+++ b/mysql-test/include/setup_fake_relay_log.inc 2010-02-02 15:16:47 +0000
@@ -69,7 +69,22 @@ let $_fake_relay_log_purge= `SELECT @@gl
# Create relay log file.
copy_file $fake_relay_log $_fake_relay_log;
# Create relay log index.
---exec echo $_fake_filename-fake.000001 > $_fake_relay_index
+
+if (`SELECT LENGTH(@@secure_file_priv) > 0`)
+{
+ -- let $_file_priv_dir= `SELECT @@secure_file_priv`;
+ -- let $_suffix= `SELECT UUID()`
+ -- let $_tmp_file= $_file_priv_dir/fake-index.$_suffix
+
+ -- eval select '$_fake_filename-fake.000001\n' into dumpfile '$_tmp_file'
+ -- copy_file $_tmp_file $_fake_relay_index
+ -- remove_file $_tmp_file
+}
+
+if (`SELECT LENGTH(@@secure_file_priv) = 0`)
+{
+ -- eval select '$_fake_filename-fake.000001\n' into dumpfile '$_fake_relay_index'
+}
# Setup replication from existing relay log.
eval CHANGE MASTER TO MASTER_HOST='dummy.localdomain', RELAY_LOG_FILE='$_fake_filename-fake.000001', RELAY_LOG_POS=4;
=== added file 'mysql-test/include/truncate_file.inc'
--- a/mysql-test/include/truncate_file.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/truncate_file.inc 2010-01-08 05:42:23 +0000
@@ -0,0 +1,16 @@
+# truncate a giving file, all contents of the file are be cleared
+
+if (`SELECT 'x$file' = 'x'`)
+{
+ --echo Please assign a file name to $file!!
+ exit;
+}
+
+let TRUNCATE_FILE= $file;
+
+perl;
+use Env;
+Env::import('TRUNCATE_FILE');
+open FILE, '>', $TRUNCATE_FILE || die "Can not open file $file";
+close FILE;
+EOF
=== modified file 'mysql-test/lib/My/SafeProcess.pm'
--- a/mysql-test/lib/My/SafeProcess.pm 2009-04-29 14:13:38 +0000
+++ b/mysql-test/lib/My/SafeProcess.pm 2010-03-10 10:32:14 +0000
@@ -384,9 +384,9 @@ sub kill {
sub _collect {
- my ($self)= @_;
+ my ($self, $exit_code)= @_;
- $self->{EXIT_STATUS}= $?;
+ $self->{EXIT_STATUS}= $exit_code;
_verbose("_collect: $self");
# Take the process out of running list
@@ -453,6 +453,7 @@ sub wait_one {
#_verbose("blocking: $blocking, use_alarm: $use_alarm");
my $retpid;
+ my $exit_code;
eval
{
# alarm should break the wait
@@ -461,6 +462,7 @@ sub wait_one {
alarm($timeout) if $use_alarm;
$retpid= waitpid($pid, $blocking ? 0 : &WNOHANG);
+ $exit_code= $?;
alarm(0) if $use_alarm;
};
@@ -492,7 +494,7 @@ sub wait_one {
#warn "wait_one: expected pid $pid but got $retpid"
# unless( $retpid == $pid );
- $self->_collect();
+ $self->_collect($exit_code);
return 0;
}
@@ -505,6 +507,8 @@ sub wait_one {
#
sub wait_any {
my $ret_pid;
+ my $exit_code;
+
if (IS_WIN32PERL) {
# Can't wait for -1 => use a polling loop
do {
@@ -514,6 +518,7 @@ sub wait_any {
last if $pid == $ret_pid;
}
} while ($ret_pid == 0);
+ $exit_code= $?;
}
else
{
@@ -523,6 +528,7 @@ sub wait_any {
print STDERR "wait_any, got invalid pid: $ret_pid\n";
return undef;
}
+ $exit_code= $?;
}
# Look it up in "running" table
@@ -532,7 +538,7 @@ sub wait_any {
print STDERR "running: ". join(", ", keys(%running)). "\n";
return undef;
}
- $proc->_collect;
+ $proc->_collect($exit_code);
return $proc;
}
=== modified file 'mysql-test/lib/My/SafeProcess/safe_process.cc'
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc 2009-07-08 12:31:22 +0000
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc 2010-03-28 18:10:00 +0000
@@ -159,7 +159,7 @@ int main(int argc, char* const argv[] )
signal(SIGCHLD, handle_signal);
signal(SIGABRT, handle_abort);
- sprintf(safe_process_name, "safe_process[%d]", own_pid);
+ sprintf(safe_process_name, "safe_process[%d]", (int) own_pid);
message("Started");
=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm 2010-01-04 12:23:17 +0000
+++ b/mysql-test/lib/mtr_cases.pm 2010-03-30 16:16:57 +0000
@@ -524,6 +524,10 @@ sub collect_one_suite
next if ($test->{'name'} eq 'sys_vars.innodb_thread_concurrency_basic');
# Can't work with InnoPlug. Test framework needs to be re-designed.
next if ($test->{'name'} eq 'main.innodb_bug46000');
+ # Fails with innodb plugin
+ next if ($test->{'name'} eq 'main.innodb-autoinc');
+ # Fails with innodb plugin: r6185 Testcases changes not included
+ next if ($test->{'name'} eq 'main.innodb_bug44369');
# Copy test options
my $new_test= My::Test->new();
while (my ($key, $value) = each(%$test))
@@ -677,6 +681,8 @@ sub optimize_cases {
if ( $default_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
if ( $default_engine =~ /^innodb/i );
+ $tinfo->{'pbxt_test'}= 1
+ if ( $default_engine =~ /^pbxt/i );
}
}
@@ -774,6 +780,8 @@ sub collect_one_test_case {
my $disabled= shift;
my $suite_opts= shift;
+ my $local_default_storage_engine= $default_storage_engine;
+
#print "collect_one_test_case\n";
#print " suitedir: $suitedir\n";
#print " testdir: $testdir\n";
@@ -928,15 +936,26 @@ sub collect_one_test_case {
tags_from_test_file($tinfo,"$testdir/${tname}.test");
- if ( defined $default_storage_engine )
+ # Get default storage engine from suite.opt file
+
+ if (defined $suite_opts &&
+ "@$suite_opts" =~ "default-storage-engine=\s*([^\s]*)")
+ {
+ $local_default_storage_engine= $1;
+ }
+
+ if ( defined $local_default_storage_engine )
{
# Different default engine is used
# tag test to require that engine
$tinfo->{'ndb_test'}= 1
- if ( $default_storage_engine =~ /^ndb/i );
+ if ( $local_default_storage_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
- if ( $default_storage_engine =~ /^innodb/i );
+ if ( $local_default_storage_engine =~ /^innodb/i );
+
+ $tinfo->{'pbxt_test'}= 1
+ if ( $local_default_storage_engine =~ /^pbxt/i );
}
@@ -1099,6 +1118,28 @@ sub collect_one_test_case {
$tinfo->{template_path}= $config;
}
+ if ( $tinfo->{'pbxt_test'} )
+ {
+ # This is a test that needs pbxt
+ if ( $::mysqld_variables{'pbxt'} eq "OFF" ||
+ ! exists $::mysqld_variables{'pbxt'} )
+ {
+ # Engine is not supported, skip it
+ $tinfo->{'skip'}= 1;
+ return $tinfo;
+ }
+ }
+ else
+ {
+ # Only disable engine if it's on by default (to avoid warnings about
+ # not existing loose options
+ if ( $::mysqld_variables{'pbxt'} eq "ON")
+ {
+ push(@{$tinfo->{'master_opt'}}, "--loose-skip-pbxt");
+ push(@{$tinfo->{'slave_opt'}}, "--loose-skip-pbxt");
+ }
+ }
+
if ( $tinfo->{'example_plugin_test'} )
{
if ( !$ENV{'EXAMPLE_PLUGIN'} )
@@ -1162,6 +1203,7 @@ my @tags=
["include/have_log_bin.inc", "need_binlog", 1],
["include/have_innodb.inc", "innodb_test", 1],
+ ["include/have_pbxt.inc", "pbxt_test", 1],
["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1],
["include/have_ndb.inc", "ndb_test", 1],
=== modified file 'mysql-test/lib/v1/mysql-test-run.pl'
--- a/mysql-test/lib/v1/mysql-test-run.pl 2009-12-09 16:43:00 +0000
+++ b/mysql-test/lib/v1/mysql-test-run.pl 2010-03-28 18:10:00 +0000
@@ -1117,14 +1117,16 @@ sub command_line_setup () {
if ( ! $opt_testcase_timeout )
{
- $opt_testcase_timeout= $default_testcase_timeout;
+ $opt_testcase_timeout=
+ $ENV{MTR_TESTCASE_TIMEOUT} || $default_testcase_timeout;
$opt_testcase_timeout*= 10 if $opt_valgrind;
$opt_testcase_timeout*= 10 if ($opt_debug and $glob_win32);
}
if ( ! $opt_suite_timeout )
{
- $opt_suite_timeout= $default_suite_timeout;
+ $opt_suite_timeout=
+ $ENV{MTR_SUITE_TIMEOUT} || $default_suite_timeout;
$opt_suite_timeout*= 6 if $opt_valgrind;
$opt_suite_timeout*= 6 if ($opt_debug and $glob_win32);
}
@@ -3963,7 +3965,7 @@ sub mysqld_arguments ($$$$) {
}
}
- mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
+ mtr_add_arg($args, "%s--character-set-server-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl 2010-01-04 12:26:56 +0000
+++ b/mysql-test/mysql-test-run.pl 2010-03-30 16:16:57 +0000
@@ -126,7 +126,7 @@ my $path_config_file; # The ge
# executables will be used by the test suite.
our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
-my $DEFAULT_SUITES= "main,binlog,federated,rpl,innodb,maria,parts,oqgraph";
+my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,oqgraph";
my $opt_suites;
our $opt_verbose= 0; # Verbose output, enable with --verbose
@@ -201,10 +201,10 @@ my $opt_mark_progress;
my $opt_sleep;
-my $opt_testcase_timeout= 15; # 15 minutes
-my $opt_suite_timeout = 360; # 6 hours
-my $opt_shutdown_timeout= 10; # 10 seconds
-my $opt_start_timeout = 180; # 180 seconds
+my $opt_testcase_timeout= $ENV{MTR_TESTCASE_TIMEOUT} || 15; # minutes
+my $opt_suite_timeout = $ENV{MTR_SUITE_TIMEOUT} || 360; # minutes
+my $opt_shutdown_timeout= $ENV{MTR_SHUTDOWN_TIMEOUT} || 10; # seconds
+my $opt_start_timeout = $ENV{MTR_START_TIMEOUT} || 180; # seconds
sub testcase_timeout { return $opt_testcase_timeout * 60; };
sub suite_timeout { return $opt_suite_timeout * 60; };
@@ -413,7 +413,6 @@ sub main {
# Not all tests completed, failure
mtr_report();
mtr_report("Only ", int(@$completed), " of $num_tests completed.");
- mtr_error("Not all tests completed");
}
mtr_print_line();
@@ -425,6 +424,10 @@ sub main {
mtr_report_stats($fail, $completed, $extra_warnings);
+ if ( @$completed != $num_tests)
+ {
+ mtr_error("Not all tests completed");
+ }
exit(0);
}
@@ -3452,7 +3455,7 @@ sub restart_forced_by_test
# Return timezone value of tinfo or default value
sub timezone {
my ($tinfo)= @_;
- return $tinfo->{timezone} || "GMT-3";
+ return $tinfo->{timezone} || "DEFAULT";
}
@@ -3482,7 +3485,11 @@ sub run_testcase ($$) {
# Init variables that can change between each test case
# -------------------------------------------------------
my $timezone= timezone($tinfo);
- $ENV{'TZ'}= $timezone;
+ if ($timezone ne 'DEFAULT') {
+ $ENV{'TZ'}= $timezone;
+ } else {
+ delete($ENV{'TZ'});
+ }
mtr_verbose("Setting timezone: $timezone");
if ( ! using_extern() )
@@ -4037,6 +4044,9 @@ sub extract_warning_lines ($) {
qr/Slave I\/O: error reconnecting to master '.*' - retry-time: [1-3] retries/,
qr/Error reading packet/,
qr/Slave: Can't drop database.* database doesn't exist/,
+ qr/Slave: Operation DROP USER failed for 'create_rout_db'/,
+ qr|Checking table: '\./mtr/test_suppressions'|,
+ qr|mysqld: Table '\./mtr/test_suppressions' is marked as crashed and should be repaired|
);
my $matched_lines= [];
@@ -4119,7 +4129,7 @@ sub start_check_warnings ($$) {
error => $errfile,
output => $errfile,
args => \$args,
- user_data => $errfile,
+ user_data => [$errfile, $mysqld],
verbose => $opt_verbose,
);
mtr_verbose("Started $proc");
@@ -4165,7 +4175,7 @@ sub check_warnings ($) {
if ( delete $started{$proc->pid()} ) {
# One check warning process returned
my $res= $proc->exit_status();
- my $err_file= $proc->user_data();
+ my ($err_file, $mysqld)= @{$proc->user_data()};
if ( $res == 0 or $res == 62 ){
@@ -4201,7 +4211,8 @@ sub check_warnings ($) {
my $report= mtr_grab_file($err_file);
$tinfo->{comment}.=
"Could not execute 'check-warnings' for ".
- "testcase '$tname' (res: $res):\n";
+ "testcase '$tname' (res: $res) server: '".
+ $mysqld->name() .":\n";
$tinfo->{comment}.= $report;
$result= 2;
@@ -5561,6 +5572,8 @@ sub usage ($) {
if ( $message )
{
print STDERR "$message\n";
+ print STDERR "For full list of options, use $0 --help\n";
+ exit;
}
print <<HERE;
=== modified file 'mysql-test/r/alter_table.result'
--- a/mysql-test/r/alter_table.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/r/alter_table.result 2010-03-04 08:03:07 +0000
@@ -1245,4 +1245,11 @@ ALTER TABLE t1 CHANGE COLUMN f1 f1_no_re
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
DROP TABLE t1;
+#
+# Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux)
+# or freezes (win) the server
+#
+CREATE TABLE t1 (a TEXT, id INT, b INT);
+ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST;
+DROP TABLE t1;
End of 5.1 tests
=== modified file 'mysql-test/r/archive.result'
--- a/mysql-test/r/archive.result 2009-09-10 06:58:13 +0000
+++ b/mysql-test/r/archive.result 2009-11-11 08:03:29 +0000
@@ -12717,3 +12717,14 @@ COUNT(t1.a)
729
DROP TABLE t1;
SET @@join_buffer_size= @save_join_buffer_size;
+SHOW CREATE TABLE t1;
+ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
+SELECT * FROM t1;
+ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
+INSERT INTO t1 (col1, col2) VALUES (1, "value");
+ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair Error Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
+test.t1 repair error Corrupt
+DROP TABLE t1;
=== modified file 'mysql-test/r/bug46080.result' (properties changed: -x to +x)
--- a/mysql-test/r/bug46080.result 2009-09-03 06:38:06 +0000
+++ b/mysql-test/r/bug46080.result 2010-02-02 12:17:21 +0000
@@ -2,8 +2,8 @@
# Bug #46080: group_concat(... order by) crashes server when
# sort_buffer_size cannot allocate
#
-call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'");
-call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k");
+call mtr.add_suppression("Out of memory at line .*, '.*my_alloc.c'");
+call mtr.add_suppression("needed .* byte (.*k)., memory in use: .* bytes (.*k)");
CREATE TABLE t1(a CHAR(255));
INSERT INTO t1 VALUES ('a');
SET @@SESSION.sort_buffer_size=5*16*1000000;
=== added file 'mysql-test/r/bug47671.result'
--- a/mysql-test/r/bug47671.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/bug47671.result 2010-01-15 15:27:55 +0000
@@ -0,0 +1,14 @@
+#
+# Bug#47671 - wrong character-set after upgrade from 5.1.34 to 5.1.39
+#
+# Extract only charset information from 'status' command output using regex
+--------------
+
+Server: MariaDB
+Server characterset: utf8
+Db characterset: utf8
+Client characterset: utf8
+Conn. characterset: utf8
+
+--------------
+
=== modified file 'mysql-test/r/count_distinct.result'
--- a/mysql-test/r/count_distinct.result 2005-05-29 23:32:50 +0000
+++ b/mysql-test/r/count_distinct.result 2009-12-22 09:52:23 +0000
@@ -40,6 +40,26 @@ select t2.isbn,city,t1.libname,count(dis
isbn city libname a
007 Berkeley Berkeley Public1 2
000 New York New York Public Libra 2
+select t2.isbn,city,@bar:=t1.libname,count(distinct t1.libname) as a
+from t3 left join t1 on t3.libname=t1.libname left join t2
+on t3.isbn=t2.isbn group by city having count(distinct
+t1.libname) > 1;
+isbn city @bar:=t1.libname a
+007 Berkeley Berkeley Public1 2
+000 New York New York Public Libra 2
+SELECT @bar;
+@bar
+Berkeley Public2
+select t2.isbn,city,concat(@bar:=t1.libname),count(distinct t1.libname) as a
+from t3 left join t1 on t3.libname=t1.libname left join t2
+on t3.isbn=t2.isbn group by city having count(distinct
+t1.libname) > 1;
+isbn city concat(@bar:=t1.libname) a
+007 Berkeley Berkeley Public1 2
+000 New York New York Public Libra 2
+SELECT @bar;
+@bar
+Berkeley Public2
drop table t1, t2, t3;
create table t1 (f1 int);
insert into t1 values (1);
=== added file 'mysql-test/r/create-uca.result'
--- a/mysql-test/r/create-uca.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/create-uca.result 2009-12-27 13:54:41 +0000
@@ -0,0 +1,31 @@
+drop table if exists t1,t2;
+CREATE TABLE t1(
+c1 INT DEFAULT 12 COMMENT 'column1',
+c2 INT NULL COMMENT 'column2',
+c3 INT NOT NULL COMMENT 'column3',
+c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
+c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b',
+c6 VARCHAR(255))
+COLLATE latin1_bin;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) DEFAULT '12' COMMENT 'column1',
+ `c2` int(11) DEFAULT NULL COMMENT 'column2',
+ `c3` int(11) NOT NULL COMMENT 'column3',
+ `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
+ `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b',
+ `c6` varchar(255) COLLATE latin1_bin DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_bin
+CREATE TABLE t2 AS SELECT * FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c1` int(11) DEFAULT '12' COMMENT 'column1',
+ `c2` int(11) DEFAULT NULL COMMENT 'column2',
+ `c3` int(11) NOT NULL COMMENT 'column3',
+ `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
+ `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b',
+ `c6` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2;
=== modified file 'mysql-test/r/create.result'
--- a/mysql-test/r/create.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/r/create.result 2010-03-04 08:03:07 +0000
@@ -820,16 +820,13 @@ i
drop table t1;
create temporary table t1 (j int);
create table if not exists t1 select 1;
-Warnings:
-Note 1050 Table 't1' already exists
select * from t1;
j
-1
drop temporary table t1;
select * from t1;
-ERROR 42S02: Table 'test.t1' doesn't exist
+1
+1
drop table t1;
-ERROR 42S02: Unknown table 't1'
create table t1 (i int);
insert into t1 values (1), (2);
lock tables t1 read;
@@ -1793,52 +1790,6 @@ t1 CREATE TABLE `t1` (
drop table t1;
# --
-# -- Bug#21380: DEFAULT definition not always transfered by CREATE
-# -- TABLE/SELECT to the new table.
-# --
-
-DROP TABLE IF EXISTS t1;
-DROP TABLE IF EXISTS t2;
-
-CREATE TABLE t1(
-c1 INT DEFAULT 12 COMMENT 'column1',
-c2 INT NULL COMMENT 'column2',
-c3 INT NOT NULL COMMENT 'column3',
-c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
-c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b',
-c6 VARCHAR(255))
-COLLATE latin1_bin;
-
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `c1` int(11) DEFAULT '12' COMMENT 'column1',
- `c2` int(11) DEFAULT NULL COMMENT 'column2',
- `c3` int(11) NOT NULL COMMENT 'column3',
- `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
- `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b',
- `c6` varchar(255) COLLATE latin1_bin DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_bin
-
-CREATE TABLE t2 AS SELECT * FROM t1;
-
-SHOW CREATE TABLE t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `c1` int(11) DEFAULT '12' COMMENT 'column1',
- `c2` int(11) DEFAULT NULL COMMENT 'column2',
- `c3` int(11) NOT NULL COMMENT 'column3',
- `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
- `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b',
- `c6` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-
-DROP TABLE t2;
-DROP TABLE t1;
-
-# -- End of test case for Bug#21380.
-
-# --
# -- Bug#18834: ALTER TABLE ADD INDEX on table with two timestamp fields
# --
=== modified file 'mysql-test/r/ctype_ucs.result'
--- a/mysql-test/r/ctype_ucs.result 2009-12-03 12:02:37 +0000
+++ b/mysql-test/r/ctype_ucs.result 2010-03-04 08:03:07 +0000
@@ -116,6 +116,26 @@ select binary 'a a' > 'a', binary 'a \
binary 'a a' > 'a' binary 'a \0' > 'a' binary 'a\0' > 'a'
1 1 1
SET CHARACTER SET koi8r;
+create table t1 (a varchar(2) character set ucs2 collate ucs2_bin, key(a));
+insert into t1 values ('A'),('A'),('B'),('C'),('D'),('A\t');
+insert into t1 values ('A\0'),('A\0'),('A\0'),('A\0'),('AZ');
+select hex(a) from t1 where a like 'A_' order by a;
+hex(a)
+00410000
+00410000
+00410000
+00410000
+00410009
+0041005A
+select hex(a) from t1 ignore key(a) where a like 'A_' order by a;
+hex(a)
+00410000
+00410000
+00410000
+00410000
+00410009
+0041005A
+drop table t1;
CREATE TABLE t1 (word VARCHAR(64) CHARACTER SET ucs2, word2 CHAR(64) CHARACTER SET ucs2);
INSERT INTO t1 VALUES (_koi8r'�koi8r'� (X'2004',X'2004');
SELECT hex(word) FROM t1 ORDER BY word;
=== modified file 'mysql-test/r/ctype_utf8.result'
--- a/mysql-test/r/ctype_utf8.result 2009-01-26 21:19:13 +0000
+++ b/mysql-test/r/ctype_utf8.result 2010-03-04 08:03:07 +0000
@@ -1,3 +1,5 @@
+drop table if exists t1,t2,t3,t4;
+drop database if exists mysqltest;
drop table if exists t1,t2;
set names utf8;
select left(_utf8 0xD0B0D0B1D0B2,1);
@@ -1848,6 +1850,24 @@ select hex(_utf8 B'001111111111');
ERROR HY000: Invalid utf8 character string: 'FF'
select (_utf8 X'616263FF');
ERROR HY000: Invalid utf8 character string: 'FF'
+#
+# Bug#44131 Binary-mode "order by" returns records in incorrect order for UTF-8 strings
+#
+CREATE TABLE t1 (id int not null primary key, name varchar(10)) character set utf8;
+INSERT INTO t1 VALUES
+(2,'一二三01'),(3,'一二三09'),(4,'一二三02'),(5,'一二三08'),
+(6,'一二三11'),(7,'一二三91'),(8,'一二三21'),(9,'一二三81');
+SELECT * FROM t1 ORDER BY BINARY(name);
+id name
+2 一二三01
+4 一二三02
+5 一二三08
+3 一二三09
+6 一二三11
+8 一二三21
+9 一二三81
+7 一二三91
+DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL);
INSERT INTO t1 VALUES (70000, 1092), (70001, 1085), (70002, 1065);
SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b;
=== modified file 'mysql-test/r/delayed.result'
--- a/mysql-test/r/delayed.result 2009-03-11 15:32:42 +0000
+++ b/mysql-test/r/delayed.result 2010-01-15 15:27:55 +0000
@@ -314,4 +314,16 @@ a b
2 2
drop table t1;
set global low_priority_updates = @old_delayed_updates;
+#
+# Bug #47682 strange behaviour of INSERT DELAYED
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (f1 integer);
+CREATE TABLE t2 (f1 integer);
+FLUSH TABLES WITH READ LOCK;
+LOCK TABLES t1 READ;
+INSERT DELAYED INTO t2 VALUES (1);
+Got one of the listed errors
+UNLOCK TABLES;
+DROP TABLE t1, t2;
End of 5.1 tests
=== modified file 'mysql-test/r/delete.result'
--- a/mysql-test/r/delete.result 2009-09-28 10:48:52 +0000
+++ b/mysql-test/r/delete.result 2010-01-29 09:36:28 +0000
@@ -324,3 +324,29 @@ a
1
2
DROP TABLE t1, t2, t3;
+#
+# Bug #46425 crash in Diagnostics_area::set_ok_status,
+# empty statement, DELETE IGNORE
+#
+CREATE table t1 (i INTEGER);
+INSERT INTO t1 VALUES (1);
+CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW
+BEGIN
+INSERT INTO t1 SELECT * FROM t1 AS A;
+END |
+DELETE IGNORE FROM t1;
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
+DROP TABLE t1;
+#
+# Bug #49552 : sql_buffer_result cause crash + not found records
+# in multitable delete/subquery
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+SET SESSION SQL_BUFFER_RESULT=1;
+DELETE t1 FROM (SELECT SUM(a) a FROM t1) x,t1;
+SET SESSION SQL_BUFFER_RESULT=DEFAULT;
+SELECT * FROM t1;
+a
+DROP TABLE t1;
+End of 5.1 tests
=== modified file 'mysql-test/r/foreign_key.result'
--- a/mysql-test/r/foreign_key.result 2001-09-28 05:05:54 +0000
+++ b/mysql-test/r/foreign_key.result 2010-03-10 13:39:02 +0000
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1,t2;
create table t1 (
a int not null references t2,
b int not null references t2 (c),
@@ -13,3 +13,30 @@ foreign key (a,b) references t3 (c,d) on
create index a on t1 (a);
create unique index b on t1 (a,b);
drop table t1;
+create table t1 (id int primary key) engine = innodb;
+create table t2 (id int PRIMARY KEY, FOREIGN KEY (id) REFERENCES t1(id)) engine=innodb;
+insert into t1 values (1), (2), (3), (4), (5), (6);
+insert into t2 values (3), (5);
+delete from t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+select * from t1;
+id
+1
+2
+3
+4
+5
+6
+delete ignore from t1;
+Warnings:
+Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+select row_count();
+row_count()
+-1
+select * from t1;
+id
+3
+5
+drop table t2;
+drop table t1;
=== modified file 'mysql-test/r/fulltext.result'
--- a/mysql-test/r/fulltext.result 2009-09-07 20:50:10 +0000
+++ b/mysql-test/r/fulltext.result 2010-03-04 08:03:07 +0000
@@ -559,3 +559,64 @@ EXECUTE s;
MATCH (col) AGAINST('findme')
DEALLOCATE PREPARE s;
DROP TABLE t1;
+#
+# Bug #49250 : spatial btree index corruption and crash
+# Part two : fulltext syntax check
+#
+CREATE TABLE t1(col1 TEXT,
+FULLTEXT INDEX USING BTREE (col1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING BTREE (col1))' at line 2
+CREATE TABLE t2(col1 TEXT);
+CREATE FULLTEXT INDEX USING BTREE ON t2(col);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING BTREE ON t2(col)' at line 1
+ALTER TABLE t2 ADD FULLTEXT INDEX USING BTREE (col1);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING BTREE (col1)' at line 1
+DROP TABLE t2;
+End of 5.0 tests
+#
+# Bug #47930: MATCH IN BOOLEAN MODE returns too many results
+# inside subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (a int, b2 char(10), FULLTEXT KEY b2 (b2));
+INSERT INTO t2 VALUES (1,'Scargill');
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (1,1), (2,1);
+# t2 should use full text index
+EXPLAIN
+SELECT count(*) FROM t1 WHERE
+not exists(
+SELECT 1 FROM t2, t3
+WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE)
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 fulltext b2 b2 0 1 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+# should return 0
+SELECT count(*) FROM t1 WHERE
+not exists(
+SELECT 1 FROM t2, t3
+WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE)
+);
+count(*)
+0
+# should return 0
+SELECT count(*) FROM t1 WHERE
+not exists(
+SELECT 1 FROM t2 IGNORE INDEX (b2), t3
+WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE)
+);
+count(*)
+0
+DROP TABLE t1,t2,t3;
+#
+# Bug #49445: Assertion failed: 0, file .\item_row.cc, line 55 with
+# fulltext search and row op
+#
+CREATE TABLE t1(a CHAR(1),FULLTEXT(a));
+SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1);
+1
+DROP TABLE t1;
+End of 5.1 tests
=== modified file 'mysql-test/r/fulltext_order_by.result'
--- a/mysql-test/r/fulltext_order_by.result 2005-08-12 16:27:54 +0000
+++ b/mysql-test/r/fulltext_order_by.result 2009-12-22 15:52:15 +0000
@@ -126,7 +126,7 @@ group by
a.text, b.id, b.betreff
order by
match(b.betreff) against ('+abc' in boolean mode) desc;
-ERROR 42S22: Unknown column 'b.betreff' in 'order clause'
+ERROR 42000: Incorrect usage/placement of 'MATCH()'
select a.text, b.id, b.betreff
from
t2 a inner join t3 b on a.id = b.forum inner join
@@ -142,7 +142,7 @@ where
match(c.beitrag) against ('+abc' in boolean mode)
order by
match(b.betreff) against ('+abc' in boolean mode) desc;
-ERROR 42S22: Unknown column 'b.betreff' in 'order clause'
+ERROR 42000: Incorrect usage/placement of 'MATCH()'
select a.text, b.id, b.betreff
from
t2 a inner join t3 b on a.id = b.forum inner join
@@ -158,7 +158,7 @@ where
match(c.beitrag) against ('+abc' in boolean mode)
order by
match(betreff) against ('+abc' in boolean mode) desc;
-text id betreff
+ERROR 42000: Incorrect usage/placement of 'MATCH()'
(select b.id, b.betreff from t3 b) union
(select b.id, b.betreff from t3 b)
order by match(betreff) against ('+abc' in boolean mode) desc;
=== modified file 'mysql-test/r/func_concat.result'
--- a/mysql-test/r/func_concat.result 2009-05-21 08:06:43 +0000
+++ b/mysql-test/r/func_concat.result 2010-01-13 04:16:36 +0000
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL );
INSERT INTO t1 VALUES (1413006,'idlfmv'),
(1413065,'smpsfz'),(1413127,'sljrhx'),(1413304,'qerfnd');
@@ -119,4 +120,14 @@ id select_type table type possible_keys
1 SIMPLE t2 index NULL PRIMARY 102 NULL 3 Using index
1 SIMPLE t1 eq_ref PRIMARY,a PRIMARY 318 func,const,const 1
DROP TABLE t1, t2;
+#
+# Bug #50096: CONCAT_WS inside procedure returning wrong data
+#
+CREATE PROCEDURE p1(a varchar(255), b int, c int)
+SET @query = CONCAT_WS(",", a, b, c);
+CALL p1("abcde", "0", "1234");
+SELECT @query;
+@query
+abcde,0,1234
+DROP PROCEDURE p1;
# End of 5.1 tests
=== modified file 'mysql-test/r/func_group.result'
--- a/mysql-test/r/func_group.result 2009-10-14 08:46:50 +0000
+++ b/mysql-test/r/func_group.result 2009-11-24 15:26:13 +0000
@@ -885,7 +885,7 @@ cast(sum(distinct df) as signed)
3
select cast(min(df) as signed) from t1;
cast(min(df) as signed)
-0
+1
select 1e8 * sum(distinct df) from t1;
1e8 * sum(distinct df)
330000000
@@ -1520,4 +1520,197 @@ max i
# Cleanup
#
DROP TABLE t1;
+#
+# Bug#43668: Wrong comparison and MIN/MAX for YEAR(2)
+#
+create table t1 (f1 year(2), f2 year(4), f3 date, f4 datetime);
+insert into t1 values
+(98,1998,19980101,"1998-01-01 00:00:00"),
+(00,2000,20000101,"2000-01-01 00:00:01"),
+(02,2002,20020101,"2002-01-01 23:59:59"),
+(60,2060,20600101,"2060-01-01 11:11:11"),
+(70,1970,19700101,"1970-11-11 22:22:22"),
+(NULL,NULL,NULL,NULL);
+select min(f1),max(f1) from t1;
+min(f1) max(f1)
+70 60
+select min(f2),max(f2) from t1;
+min(f2) max(f2)
+1970 2060
+select min(f3),max(f3) from t1;
+min(f3) max(f3)
+1970-01-01 2060-01-01
+select min(f4),max(f4) from t1;
+min(f4) max(f4)
+1970-11-11 22:22:22 2060-01-01 11:11:11
+select a.f1 as a, b.f1 as b, a.f1 > b.f1 as gt,
+a.f1 < b.f1 as lt, a.f1<=>b.f1 as eq
+from t1 a, t1 b;
+a b gt lt eq
+98 98 0 0 1
+00 98 1 0 0
+02 98 1 0 0
+60 98 1 0 0
+70 98 0 1 0
+NULL 98 NULL NULL 0
+98 00 0 1 0
+00 00 0 0 1
+02 00 1 0 0
+60 00 1 0 0
+70 00 0 1 0
+NULL 00 NULL NULL 0
+98 02 0 1 0
+00 02 0 1 0
+02 02 0 0 1
+60 02 1 0 0
+70 02 0 1 0
+NULL 02 NULL NULL 0
+98 60 0 1 0
+00 60 0 1 0
+02 60 0 1 0
+60 60 0 0 1
+70 60 0 1 0
+NULL 60 NULL NULL 0
+98 70 1 0 0
+00 70 1 0 0
+02 70 1 0 0
+60 70 1 0 0
+70 70 0 0 1
+NULL 70 NULL NULL 0
+98 NULL NULL NULL 0
+00 NULL NULL NULL 0
+02 NULL NULL NULL 0
+60 NULL NULL NULL 0
+70 NULL NULL NULL 0
+NULL NULL NULL NULL 1
+select a.f1 as a, b.f2 as b, a.f1 > b.f2 as gt,
+a.f1 < b.f2 as lt, a.f1<=>b.f2 as eq
+from t1 a, t1 b;
+a b gt lt eq
+98 1998 0 0 1
+00 1998 1 0 0
+02 1998 1 0 0
+60 1998 1 0 0
+70 1998 0 1 0
+NULL 1998 NULL NULL 0
+98 2000 0 1 0
+00 2000 0 0 1
+02 2000 1 0 0
+60 2000 1 0 0
+70 2000 0 1 0
+NULL 2000 NULL NULL 0
+98 2002 0 1 0
+00 2002 0 1 0
+02 2002 0 0 1
+60 2002 1 0 0
+70 2002 0 1 0
+NULL 2002 NULL NULL 0
+98 2060 0 1 0
+00 2060 0 1 0
+02 2060 0 1 0
+60 2060 0 0 1
+70 2060 0 1 0
+NULL 2060 NULL NULL 0
+98 1970 1 0 0
+00 1970 1 0 0
+02 1970 1 0 0
+60 1970 1 0 0
+70 1970 0 0 1
+NULL 1970 NULL NULL 0
+98 NULL NULL NULL 0
+00 NULL NULL NULL 0
+02 NULL NULL NULL 0
+60 NULL NULL NULL 0
+70 NULL NULL NULL 0
+NULL NULL NULL NULL 1
+select a.f1 as a, b.f3 as b, a.f1 > b.f3 as gt,
+a.f1 < b.f3 as lt, a.f1<=>b.f3 as eq
+from t1 a, t1 b;
+a b gt lt eq
+98 1998-01-01 0 1 0
+00 1998-01-01 1 0 0
+02 1998-01-01 1 0 0
+60 1998-01-01 1 0 0
+70 1998-01-01 0 1 0
+NULL 1998-01-01 NULL NULL 0
+98 2000-01-01 0 1 0
+00 2000-01-01 0 1 0
+02 2000-01-01 1 0 0
+60 2000-01-01 1 0 0
+70 2000-01-01 0 1 0
+NULL 2000-01-01 NULL NULL 0
+98 2002-01-01 0 1 0
+00 2002-01-01 0 1 0
+02 2002-01-01 0 1 0
+60 2002-01-01 1 0 0
+70 2002-01-01 0 1 0
+NULL 2002-01-01 NULL NULL 0
+98 2060-01-01 0 1 0
+00 2060-01-01 0 1 0
+02 2060-01-01 0 1 0
+60 2060-01-01 0 1 0
+70 2060-01-01 0 1 0
+NULL 2060-01-01 NULL NULL 0
+98 1970-01-01 1 0 0
+00 1970-01-01 1 0 0
+02 1970-01-01 1 0 0
+60 1970-01-01 1 0 0
+70 1970-01-01 0 1 0
+NULL 1970-01-01 NULL NULL 0
+98 NULL NULL NULL 0
+00 NULL NULL NULL 0
+02 NULL NULL NULL 0
+60 NULL NULL NULL 0
+70 NULL NULL NULL 0
+NULL NULL NULL NULL 1
+select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt,
+a.f1 < b.f4 as lt, a.f1<=>b.f4 as eq
+from t1 a, t1 b;
+a b gt lt eq
+98 1998-01-01 00:00:00 0 1 0
+00 1998-01-01 00:00:00 1 0 0
+02 1998-01-01 00:00:00 1 0 0
+60 1998-01-01 00:00:00 1 0 0
+70 1998-01-01 00:00:00 0 1 0
+NULL 1998-01-01 00:00:00 NULL NULL 0
+98 2000-01-01 00:00:01 0 1 0
+00 2000-01-01 00:00:01 0 1 0
+02 2000-01-01 00:00:01 1 0 0
+60 2000-01-01 00:00:01 1 0 0
+70 2000-01-01 00:00:01 0 1 0
+NULL 2000-01-01 00:00:01 NULL NULL 0
+98 2002-01-01 23:59:59 0 1 0
+00 2002-01-01 23:59:59 0 1 0
+02 2002-01-01 23:59:59 0 1 0
+60 2002-01-01 23:59:59 1 0 0
+70 2002-01-01 23:59:59 0 1 0
+NULL 2002-01-01 23:59:59 NULL NULL 0
+98 2060-01-01 11:11:11 0 1 0
+00 2060-01-01 11:11:11 0 1 0
+02 2060-01-01 11:11:11 0 1 0
+60 2060-01-01 11:11:11 0 1 0
+70 2060-01-01 11:11:11 0 1 0
+NULL 2060-01-01 11:11:11 NULL NULL 0
+98 1970-11-11 22:22:22 1 0 0
+00 1970-11-11 22:22:22 1 0 0
+02 1970-11-11 22:22:22 1 0 0
+60 1970-11-11 22:22:22 1 0 0
+70 1970-11-11 22:22:22 0 1 0
+NULL 1970-11-11 22:22:22 NULL NULL 0
+98 NULL NULL NULL 0
+00 NULL NULL NULL 0
+02 NULL NULL NULL 0
+60 NULL NULL NULL 0
+70 NULL NULL NULL 0
+NULL NULL NULL NULL 1
+select *, f1 = f2 from t1;
+f1 f2 f3 f4 f1 = f2
+98 1998 1998-01-01 1998-01-01 00:00:00 1
+00 2000 2000-01-01 2000-01-01 00:00:01 1
+02 2002 2002-01-01 2002-01-01 23:59:59 1
+60 2060 2060-01-01 2060-01-01 11:11:11 1
+70 1970 1970-01-01 1970-11-11 22:22:22 1
+NULL NULL NULL NULL NULL
+drop table t1;
+#
End of 5.1 tests
=== modified file 'mysql-test/r/func_misc.result'
--- a/mysql-test/r/func_misc.result 2009-10-28 07:52:34 +0000
+++ b/mysql-test/r/func_misc.result 2010-01-11 13:15:28 +0000
@@ -104,95 +104,6 @@ t1 CREATE TABLE `t1` (
`length(uuid())` int(10) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
-#------------------------------------------------------------------------
-# Tests for Bug#6760 and Bug#12689
-SET @row_count = 4;
-SET @sleep_time_per_result_row = 1;
-SET @max_acceptable_delay = 2;
-SET @@global.query_cache_size = 1024 * 64;
-DROP TEMPORARY TABLE IF EXISTS t_history;
-DROP TABLE IF EXISTS t1;
-CREATE TEMPORARY TABLE t_history (attempt SMALLINT,
-start_ts DATETIME, end_ts DATETIME,
-start_cached INTEGER, end_cached INTEGER);
-CREATE TABLE t1 (f1 BIGINT);
-INSERT INTO t_history
-SET attempt = 4 - 4 + 1, start_ts = NOW(),
-start_cached = 0;
-SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
-f1 SLEEP(@sleep_time_per_result_row)
-1 0
-1 0
-1 0
-1 0
-UPDATE t_history SET end_ts = NOW()
-WHERE attempt = 4 - 4 + 1;
-UPDATE t_history SET end_cached = 0
-WHERE attempt = 4 - 4 + 1;
-INSERT INTO t_history
-SET attempt = 4 - 3 + 1, start_ts = NOW(),
-start_cached = 0;
-SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
-f1 SLEEP(@sleep_time_per_result_row)
-1 0
-1 0
-1 0
-1 0
-UPDATE t_history SET end_ts = NOW()
-WHERE attempt = 4 - 3 + 1;
-UPDATE t_history SET end_cached = 0
-WHERE attempt = 4 - 3 + 1;
-INSERT INTO t_history
-SET attempt = 4 - 2 + 1, start_ts = NOW(),
-start_cached = 0;
-SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
-f1 SLEEP(@sleep_time_per_result_row)
-1 0
-1 0
-1 0
-1 0
-UPDATE t_history SET end_ts = NOW()
-WHERE attempt = 4 - 2 + 1;
-UPDATE t_history SET end_cached = 0
-WHERE attempt = 4 - 2 + 1;
-INSERT INTO t_history
-SET attempt = 4 - 1 + 1, start_ts = NOW(),
-start_cached = 0;
-SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
-f1 SLEEP(@sleep_time_per_result_row)
-1 0
-1 0
-1 0
-1 0
-UPDATE t_history SET end_ts = NOW()
-WHERE attempt = 4 - 1 + 1;
-UPDATE t_history SET end_cached = 0
-WHERE attempt = 4 - 1 + 1;
-# Test 1: Does the query with SLEEP need a reasonable time?
-SELECT COUNT(*) >= 4 - 1 INTO @aux1 FROM t_history
-WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
-BETWEEN 0 AND @max_acceptable_delay;
-SELECT @aux1 AS "Expect 1";
-Expect 1
-1
-# Test 2: Does the query with SLEEP need a reasonable time even in case
-# of the non first execution?
-SELECT COUNT(*) >= 4 - 1 - 1 INTO @aux2 FROM t_history
-WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
-BETWEEN 0 AND @max_acceptable_delay
-AND attempt > 1;
-SELECT @aux2 AS "Expect 1";
-Expect 1
-1
-# Test 3: The query with SLEEP must be not cached.
-SELECT COUNT(*) = 4 INTO @aux3 FROM t_history
-WHERE end_cached = start_cached;
-SELECT @aux3 AS "Expect 1";
-Expect 1
-1
-DROP TABLE t1;
-DROP TEMPORARY TABLE t_history;
-SET @@global.query_cache_size = default;
create table t1 select INET_ATON('255.255.0.1') as `a`;
show create table t1;
Table Create Table
=== modified file 'mysql-test/r/func_str.result'
--- a/mysql-test/r/func_str.result 2009-09-10 10:30:03 +0000
+++ b/mysql-test/r/func_str.result 2009-12-04 15:36:58 +0000
@@ -2558,3 +2558,32 @@ id select_type table type possible_keys
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer
2 DERIVED t1 ALL NULL NULL NULL NULL 2
drop table t1;
+#
+# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (a VARCHAR(20), b INT);
+CREATE TABLE t2 (a VARCHAR(20), b INT);
+INSERT INTO t1 VALUES ('ABC', 1);
+INSERT INTO t2 VALUES ('ABC', 1);
+SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
+FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
+DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
+secret
+SELECT DECODE((SELECT ENCODE('secret', 'ABC') FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
+FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
+DECODE((SELECT ENCODE('secret', 'ABC') FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
+secret
+SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), 'ABC')
+FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
+DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), 'ABC')
+secret
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+INSERT INTO t1 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1);
+INSERT INTO t2 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1);
+SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a)
+FROM t2 WHERE t2.b = 1 GROUP BY t2.b;
+DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a)
+secret
+DROP TABLE t1, t2;
=== modified file 'mysql-test/r/func_time.result'
--- a/mysql-test/r/func_time.result 2009-01-23 12:22:05 +0000
+++ b/mysql-test/r/func_time.result 2010-01-21 08:10:05 +0000
@@ -682,7 +682,7 @@ select timestampadd(SQL_TSI_FRAC_SECOND,
timestampadd(SQL_TSI_FRAC_SECOND, 1, date)
2003-01-02 00:00:00.000001
Warnings:
-Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead
+Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead
select timestampdiff(MONTH, '2001-02-01', '2001-05-01') as a;
a
3
@@ -717,7 +717,7 @@ select timestampdiff(SQL_TSI_FRAC_SECOND
a
7689538999999
Warnings:
-Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead
+Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead
select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1,
timestampdiff(SQL_TSI_DAY, '1900-02-01', '1900-03-01') as a2,
timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3,
@@ -1088,7 +1088,7 @@ timestampdiff(SQL_TSI_FRAC_SECOND, '2001
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead
+Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead
Note 1003 select timestampdiff(WEEK,'2001-02-01','2001-05-01') AS `a1`,timestampdiff(SECOND_FRAC,'2001-02-01 12:59:59.120000','2001-05-01 12:58:58.119999') AS `a2`
select time_format('100:00:00', '%H %k %h %I %l');
time_format('100:00:00', '%H %k %h %I %l')
@@ -1287,12 +1287,12 @@ SELECT TIMESTAMPADD(FRAC_SECOND, 1, '200
TIMESTAMPADD(FRAC_SECOND, 1, '2008-02-18')
2008-02-18 00:00:00.000001
Warnings:
-Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead
+Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead
SELECT TIMESTAMPDIFF(FRAC_SECOND, '2008-02-17', '2008-02-18');
TIMESTAMPDIFF(FRAC_SECOND, '2008-02-17', '2008-02-18')
86400000000
Warnings:
-Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead
+Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead
SELECT DATE_ADD('2008-02-18', INTERVAL 1 FRAC_SECOND);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND)' at line 1
SELECT DATE_SUB('2008-02-18', INTERVAL 1 FRAC_SECOND);
=== modified file 'mysql-test/r/gis.result'
--- a/mysql-test/r/gis.result 2009-10-24 06:57:31 +0000
+++ b/mysql-test/r/gis.result 2010-01-13 10:28:42 +0000
@@ -984,6 +984,19 @@ GEOMFROMTEXT(
SELECT 1 FROM t1 WHERE a <> (SELECT GEOMETRYCOLLECTIONFROMWKB(b) FROM t1);
1
DROP TABLE t1;
+#
+# Bug #49250 : spatial btree index corruption and crash
+# Part one : spatial syntax check
+#
+CREATE TABLE t1(col1 MULTIPOLYGON NOT NULL,
+SPATIAL INDEX USING BTREE (col1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING BTREE (col1))' at line 2
+CREATE TABLE t2(col1 MULTIPOLYGON NOT NULL);
+CREATE SPATIAL INDEX USING BTREE ON t2(col);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING BTREE ON t2(col)' at line 1
+ALTER TABLE t2 ADD SPATIAL INDEX USING BTREE (col1);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING BTREE (col1)' at line 1
+DROP TABLE t2;
End of 5.0 tests
create table t1 (f1 tinyint(1), f2 char(1), f3 varchar(1), f4 geometry, f5 datetime);
create view v1 as select * from t1;
=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result 2009-10-27 10:09:36 +0000
+++ b/mysql-test/r/grant.result 2010-01-29 10:42:31 +0000
@@ -29,15 +29,15 @@ show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
-grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB";
+grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "Monty Program Ab";
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
-GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'Monty Program Ab' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
-GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'Monty Program Ab' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
delete from mysql.user where user='mysqltest_1';
flush privileges;
delete from mysql.user where user='mysqltest_1';
=== modified file 'mysql-test/r/grant2.result'
--- a/mysql-test/r/grant2.result 2009-02-27 08:03:47 +0000
+++ b/mysql-test/r/grant2.result 2009-10-30 05:06:10 +0000
@@ -443,3 +443,30 @@ DROP TABLE db1.t1, db1.t2;
DROP USER mysqltest1@localhost;
DROP DATABASE db1;
End of 5.0 tests
+USE mysql;
+SELECT LEFT(CURRENT_USER(),INSTR(CURRENT_USER(),'@')-1) INTO @u;
+SELECT MID(CURRENT_USER(),INSTR(CURRENT_USER(),'@')+1) INTO @h;
+SELECT password FROM user WHERE user=@u AND host=@h INTO @pwd;
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+user host password insert_priv
+root localhost Y
+UPDATE user SET insert_priv='N' WHERE user=@u AND host=@h;
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+user host password insert_priv
+root localhost N
+GRANT INSERT ON *.* TO CURRENT_USER();
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+user host password insert_priv
+root localhost Y
+UPDATE user SET insert_priv='N' WHERE user=@u AND host=@h;
+GRANT INSERT ON *.* TO CURRENT_USER() IDENTIFIED BY 'keksdose';
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+user host password insert_priv
+root localhost *0BB7188CF0DE9B403BA66E9DD810D82652D002EB Y
+UPDATE user SET password=@pwd WHERE user=@u AND host=@h;
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+user host password insert_priv
+root localhost Y
+FLUSH PRIVILEGES;
+USE test;
+End of 5.1 tests
=== modified file 'mysql-test/r/group_min_max.result'
--- a/mysql-test/r/group_min_max.result 2009-10-09 09:30:40 +0000
+++ b/mysql-test/r/group_min_max.result 2009-11-23 10:04:17 +0000
@@ -2501,6 +2501,17 @@ SELECT a, MAX(b) FROM t WHERE b > 0 AND
a MAX(b)
2 1
DROP TABLE t;
+#
+# Bug #48472: Loose index scan inappropriately chosen for some WHERE
+# conditions
+#
+CREATE TABLE t (a INT, b INT, INDEX (a,b));
+INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1);
+INSERT INTO t SELECT * FROM t;
+SELECT a, MAX(b) FROM t WHERE 0=b+0 GROUP BY a;
+a MAX(b)
+2 0
+DROP TABLE t;
End of 5.0 tests
#
# Bug #46607: Assertion failed: (cond_type == Item::FUNC_ITEM) results in
=== removed file 'mysql-test/r/have_big5.require'
--- a/mysql-test/r/have_big5.require 2003-12-24 12:59:48 +0000
+++ b/mysql-test/r/have_big5.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-big5_chinese_ci big5 1 Yes Yes 1
=== removed file 'mysql-test/r/have_cp1250_ch.require'
--- a/mysql-test/r/have_cp1250_ch.require 2005-03-03 10:15:37 +0000
+++ b/mysql-test/r/have_cp1250_ch.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-cp1250_czech_cs cp1250 34 Yes 2
=== removed file 'mysql-test/r/have_cp1251.require'
--- a/mysql-test/r/have_cp1251.require 2007-06-28 17:34:54 +0000
+++ b/mysql-test/r/have_cp1251.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-cp1251_general_ci cp1251 51 Yes 0
=== removed file 'mysql-test/r/have_cp866.require'
--- a/mysql-test/r/have_cp866.require 2007-06-28 17:34:54 +0000
+++ b/mysql-test/r/have_cp866.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-cp866_general_ci cp866 36 Yes 0
=== removed file 'mysql-test/r/have_cp932.require'
--- a/mysql-test/r/have_cp932.require 2005-02-01 10:37:51 +0000
+++ b/mysql-test/r/have_cp932.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-cp932_japanese_ci cp932 95 Yes Yes 1
=== removed file 'mysql-test/r/have_eucjpms.require'
--- a/mysql-test/r/have_eucjpms.require 2005-02-01 10:37:51 +0000
+++ b/mysql-test/r/have_eucjpms.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-eucjpms_japanese_ci eucjpms 97 Yes Yes 1
=== removed file 'mysql-test/r/have_euckr.require'
--- a/mysql-test/r/have_euckr.require 2005-12-09 12:37:58 +0000
+++ b/mysql-test/r/have_euckr.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-euckr_korean_ci euckr 19 Yes Yes 1
=== removed file 'mysql-test/r/have_gb2312.require'
--- a/mysql-test/r/have_gb2312.require 2005-12-09 12:37:58 +0000
+++ b/mysql-test/r/have_gb2312.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-gb2312_chinese_ci gb2312 24 Yes Yes 1
=== removed file 'mysql-test/r/have_gbk.require'
--- a/mysql-test/r/have_gbk.require 2005-07-22 16:06:02 +0000
+++ b/mysql-test/r/have_gbk.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-gbk_chinese_ci gbk 28 Yes Yes 1
=== removed file 'mysql-test/r/have_koi8r.require'
--- a/mysql-test/r/have_koi8r.require 2007-06-28 17:34:54 +0000
+++ b/mysql-test/r/have_koi8r.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-koi8r_general_ci koi8r 7 Yes 0
=== removed file 'mysql-test/r/have_latin2_ch.require'
--- a/mysql-test/r/have_latin2_ch.require 2006-03-20 12:28:25 +0000
+++ b/mysql-test/r/have_latin2_ch.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-latin2_czech_cs latin2 2 Yes 4
=== removed file 'mysql-test/r/have_sjis.require'
--- a/mysql-test/r/have_sjis.require 2004-03-25 10:29:56 +0000
+++ b/mysql-test/r/have_sjis.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-sjis_japanese_ci sjis 13 Yes Yes 1
=== removed file 'mysql-test/r/have_tis620.require'
--- a/mysql-test/r/have_tis620.require 2003-12-25 16:11:01 +0000
+++ b/mysql-test/r/have_tis620.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-tis620_thai_ci tis620 18 Yes Yes 4
=== removed file 'mysql-test/r/have_ucs2.require'
--- a/mysql-test/r/have_ucs2.require 2003-06-02 12:19:06 +0000
+++ b/mysql-test/r/have_ucs2.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-ucs2_general_ci ucs2 35 Yes Yes 1
=== removed file 'mysql-test/r/have_ujis.require'
--- a/mysql-test/r/have_ujis.require 2003-09-19 10:18:19 +0000
+++ b/mysql-test/r/have_ujis.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-ujis_japanese_ci ujis 12 Yes Yes 1
=== removed file 'mysql-test/r/have_utf8.require'
--- a/mysql-test/r/have_utf8.require 2007-06-28 17:34:54 +0000
+++ b/mysql-test/r/have_utf8.require 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Collation Charset Id Default Compiled Sortlen
-utf8_general_ci utf8 33 Yes Yes 1
=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result 2009-09-29 20:19:43 +0000
+++ b/mysql-test/r/information_schema.result 2010-03-10 09:12:23 +0000
@@ -85,6 +85,7 @@ TABLE_PRIVILEGES
TRIGGERS
USER_PRIVILEGES
VIEWS
+XTRADB_ADMIN_COMMAND
XTRADB_ENHANCEMENTS
columns_priv
db
@@ -865,8 +866,8 @@ TABLE_CONSTRAINTS TABLE_NAME select
TABLE_PRIVILEGES TABLE_NAME select
VIEWS TABLE_NAME select
INNODB_BUFFER_POOL_PAGES_INDEX table_name select
-INNODB_INDEX_STATS table_name select
INNODB_TABLE_STATS table_name select
+INNODB_INDEX_STATS table_name select
delete from mysql.user where user='mysqltest_4';
delete from mysql.db where user='mysqltest_4';
flush privileges;
@@ -1385,7 +1386,7 @@ who
other connection here
SELECT IF(`time` > 0, 'OK', `time`) AS time_low,
IF(`time` < 1000, 'OK', `time`) AS time_high,
-IF(time_ms > 1500, 'OK', time_ms) AS time_ms_low,
+IF(time_ms >= 1000, 'OK', time_ms) AS time_ms_low,
IF(time_ms < 1000000, 'OK', time_ms) AS time_ms_high
FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID=@tid;
@@ -1616,4 +1617,26 @@ SET TIMESTAMP=@@TIMESTAMP + 10000000;
SELECT 'NOT_OK' AS TEST_RESULT FROM INFORMATION_SCHEMA.PROCESSLIST WHERE time < 0;
TEST_RESULT
SET TIMESTAMP=DEFAULT;
+#
+# Bug #50276: Security flaw in INFORMATION_SCHEMA.TABLES
+#
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE t1 (id INT);
+CREATE USER nonpriv;
+USE test;
+# connected as nonpriv
+# Should return 0
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1';
+COUNT(*)
+0
+USE INFORMATION_SCHEMA;
+# Should return 0
+SELECT COUNT(*) FROM TABLES WHERE TABLE_NAME='t1';
+COUNT(*)
+0
+# connected as root
+DROP USER nonpriv;
+DROP TABLE db1.t1;
+DROP DATABASE db1;
End of 5.1 tests.
=== modified file 'mysql-test/r/information_schema_all_engines.result'
--- a/mysql-test/r/information_schema_all_engines.result 2009-08-03 20:09:53 +0000
+++ b/mysql-test/r/information_schema_all_engines.result 2010-01-15 15:58:25 +0000
@@ -35,7 +35,7 @@ INNODB_CMP
INNODB_RSEG
XTRADB_ENHANCEMENTS
INNODB_BUFFER_POOL_PAGES_INDEX
-INNODB_INDEX_STATS
+XTRADB_ADMIN_COMMAND
INNODB_TRX
INNODB_CMP_RESET
INNODB_LOCK_WAITS
@@ -44,6 +44,7 @@ INNODB_LOCKS
INNODB_CMPMEM
INNODB_TABLE_STATS
INNODB_BUFFER_POOL_PAGES_BLOB
+INNODB_INDEX_STATS
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
INNER JOIN
@@ -93,7 +94,7 @@ INNODB_CMP page_size
INNODB_RSEG rseg_id
XTRADB_ENHANCEMENTS name
INNODB_BUFFER_POOL_PAGES_INDEX schema_name
-INNODB_INDEX_STATS table_name
+XTRADB_ADMIN_COMMAND result_message
INNODB_TRX trx_id
INNODB_CMP_RESET page_size
INNODB_LOCK_WAITS requesting_trx_id
@@ -102,6 +103,7 @@ INNODB_LOCKS lock_id
INNODB_CMPMEM page_size
INNODB_TABLE_STATS table_name
INNODB_BUFFER_POOL_PAGES_BLOB space_id
+INNODB_INDEX_STATS table_name
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
INNER JOIN
@@ -151,7 +153,7 @@ INNODB_CMP page_size
INNODB_RSEG rseg_id
XTRADB_ENHANCEMENTS name
INNODB_BUFFER_POOL_PAGES_INDEX schema_name
-INNODB_INDEX_STATS table_name
+XTRADB_ADMIN_COMMAND result_message
INNODB_TRX trx_id
INNODB_CMP_RESET page_size
INNODB_LOCK_WAITS requesting_trx_id
@@ -160,6 +162,7 @@ INNODB_LOCKS lock_id
INNODB_CMPMEM page_size
INNODB_TABLE_STATS table_name
INNODB_BUFFER_POOL_PAGES_BLOB space_id
+INNODB_INDEX_STATS table_name
select 1 as f1 from information_schema.tables where "CHARACTER_SETS"=
(select cast(table_name as char) from information_schema.tables
order by table_name limit 1) limit 1;
@@ -262,7 +265,7 @@ Database: information_schema
| INNODB_RSEG |
| XTRADB_ENHANCEMENTS |
| INNODB_BUFFER_POOL_PAGES_INDEX |
-| INNODB_INDEX_STATS |
+| XTRADB_ADMIN_COMMAND |
| INNODB_TRX |
| INNODB_CMP_RESET |
| INNODB_LOCK_WAITS |
@@ -271,6 +274,7 @@ Database: information_schema
| INNODB_CMPMEM |
| INNODB_TABLE_STATS |
| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_INDEX_STATS |
+---------------------------------------+
Database: INFORMATION_SCHEMA
+---------------------------------------+
@@ -310,7 +314,7 @@ Database: INFORMATION_SCHEMA
| INNODB_RSEG |
| XTRADB_ENHANCEMENTS |
| INNODB_BUFFER_POOL_PAGES_INDEX |
-| INNODB_INDEX_STATS |
+| XTRADB_ADMIN_COMMAND |
| INNODB_TRX |
| INNODB_CMP_RESET |
| INNODB_LOCK_WAITS |
@@ -319,6 +323,7 @@ Database: INFORMATION_SCHEMA
| INNODB_CMPMEM |
| INNODB_TABLE_STATS |
| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_INDEX_STATS |
+---------------------------------------+
Wildcard: inf_rmation_schema
+--------------------+
@@ -328,5 +333,5 @@ Wildcard: inf_rmation_schema
+--------------------+
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
table_schema count(*)
-information_schema 43
+information_schema 44
mysql 22
=== added file 'mysql-test/r/innodb-autoinc-44030.result'
--- a/mysql-test/r/innodb-autoinc-44030.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb-autoinc-44030.result 2010-01-22 10:03:18 +0000
@@ -0,0 +1,30 @@
+drop table if exists t1;
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (null);
+INSERT INTO t1 VALUES (null);
+ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
+SELECT * FROM t1;
+d1
+1
+2
+SELECT * FROM t1;
+d1
+1
+2
+INSERT INTO t1 VALUES(null);
+Got one of the listed errors
+ALTER TABLE t1 AUTO_INCREMENT = 3;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `d1` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`d1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(null);
+SELECT * FROM t1;
+d1
+1
+2
+3
+DROP TABLE t1;
=== modified file 'mysql-test/r/innodb-autoinc.result'
--- a/mysql-test/r/innodb-autoinc.result 2009-12-03 11:34:11 +0000
+++ b/mysql-test/r/innodb-autoinc.result 2010-03-04 08:03:07 +0000
@@ -197,7 +197,7 @@ c1 c2
5 9
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
@@ -230,7 +230,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -269,7 +269,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -282,7 +282,7 @@ SELECT * FROM t1;
c1
-1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
@@ -315,7 +315,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -330,7 +330,7 @@ SELECT * FROM t1;
c1
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
@@ -370,7 +370,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -385,7 +385,7 @@ SELECT * FROM t1;
c1
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
@@ -419,7 +419,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -434,7 +434,7 @@ c1
1
9223372036854775794
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 2
auto_increment_offset 10
@@ -452,7 +452,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -467,7 +467,7 @@ c1
1
18446744073709551603
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 2
auto_increment_offset 10
@@ -485,7 +485,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -500,7 +500,7 @@ c1
1
18446744073709551603
SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 5
auto_increment_offset 7
@@ -514,7 +514,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -533,7 +533,7 @@ c1
-9223372036854775806
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=3, @@SESSION.AUTO_INCREMENT_OFFSET=3;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 3
auto_increment_offset 3
@@ -550,7 +550,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -568,7 +568,7 @@ SET @@SESSION.AUTO_INCREMENT_INCREMENT=1
Warnings:
Warning 1292 Truncated incorrect auto_increment_increment value: '1152921504606846976'
Warning 1292 Truncated incorrect auto_increment_offset value: '1152921504606846976'
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 65535
auto_increment_offset 65535
@@ -581,7 +581,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -868,36 +868,7 @@ Got one of the listed errors
DROP TABLE t1;
DROP TABLE t2;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
-CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (null);
-INSERT INTO t1 VALUES (null);
-ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
-SELECT * FROM t1;
-d1
-1
-3
-SELECT * FROM t1;
-d1
-1
-3
-INSERT INTO t1 VALUES(null);
-Got one of the listed errors
-ALTER TABLE t1 AUTO_INCREMENT = 3;
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `d1` int(11) NOT NULL AUTO_INCREMENT,
- PRIMARY KEY (`d1`)
-) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
-INSERT INTO t1 VALUES(null);
-SELECT * FROM t1;
-d1
-1
-3
-4
-DROP TABLE t1;
-SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -1111,18 +1082,76 @@ c1 c2
3 innodb
4 NULL
DROP TABLE t1;
-CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
-CREATE INDEX i1 on T1(c2);
-SHOW CREATE TABLE T1;
+CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
+CREATE INDEX i1 on t1(c2);
+SHOW CREATE TABLE t1;
Table Create Table
-T1 CREATE TABLE `T1` (
+t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
`c2` int(11) DEFAULT NULL,
PRIMARY KEY (`c1`),
KEY `i1` (`c2`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
-INSERT INTO T1 (c2) values (0);
-SELECT * FROM T1;
+INSERT INTO t1 (c2) values (0);
+SELECT * FROM t1;
c1 c2
10 0
-DROP TABLE T1;
+DROP TABLE t1;
+CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb');
+INSERT INTO t1(C2) VALUES ('innodb');
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `C1` double NOT NULL AUTO_INCREMENT,
+ `C2` char(10) DEFAULT NULL,
+ PRIMARY KEY (`C1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb');
+INSERT INTO t1(C2) VALUES ('innodb');
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `C1` float NOT NULL AUTO_INCREMENT,
+ `C2` char(10) DEFAULT NULL,
+ PRIMARY KEY (`C1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 SET c1 = 1;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
+INSERT INTO t1 SET c1 = 2;
+INSERT INTO t1 SET c1 = -1;
+SELECT * FROM t1;
+c1
+-1
+1
+2
+INSERT INTO t1 SET c1 = -1;
+Got one of the listed errors
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+REPLACE INTO t1 VALUES (-1);
+SELECT * FROM t1;
+c1
+-1
+1
+2
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+DROP TABLE t1;
=== added file 'mysql-test/r/innodb-consistent.result'
--- a/mysql-test/r/innodb-consistent.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb-consistent.result 2010-01-15 15:58:25 +0000
@@ -0,0 +1,35 @@
+drop table if exists t1;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+begin;
+replace into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+begin;
+insert into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+select * from t1;
+a
+1
+2
+3
+4
+5
+6
+7
+drop table t1;
+drop table t2;
=== modified file 'mysql-test/r/innodb-index.result'
--- a/mysql-test/r/innodb-index.result 2009-11-30 21:37:27 +0000
+++ b/mysql-test/r/innodb-index.result 2010-01-15 15:58:25 +0000
@@ -1,4 +1,3 @@
-SET @save_innodb_file_format_check=@@global.innodb_file_format_check;
create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb;
insert into t1 values (5,5,'oo','oo'),(4,4,'tr','tr'),(3,4,'ad','ad'),(2,3,'ak','ak');
commit;
@@ -629,7 +628,7 @@ drop table t1;
create table t1(a int not null, b int, c char(10), d varchar(20), primary key (a)) engine = innodb;
insert into t1 values (1,1,'ab','ab'),(2,2,'ac','ac'),(3,3,'ac','ac'),(4,4,'afe','afe'),(5,4,'affe','affe');
alter table t1 add unique index (b), add unique index (c), add unique index (d);
-ERROR 23000: Duplicate entry '4' for key 'b'
+ERROR 23000: Duplicate entry 'ac' for key 'c'
alter table t1 add unique index (c), add unique index (b), add index (d);
ERROR 23000: Duplicate entry 'ac' for key 'c'
show create table t1;
@@ -970,6 +969,7 @@ create index t1u on t1 (u(1));
drop table t1;
set global innodb_file_per_table=0;
set global innodb_file_format=Antelope;
+set global innodb_file_format_check=Antelope;
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
CREATE TABLE t1(
@@ -1171,4 +1171,3 @@ a b
3 a
3 b
DROP TABLE t1;
-SET GLOBAL innodb_file_format_check=@save_innodb_file_format_check;
=== modified file 'mysql-test/r/innodb-timeout.result'
--- a/mysql-test/r/innodb-timeout.result 2009-06-09 13:19:13 +0000
+++ b/mysql-test/r/innodb-timeout.result 2010-01-18 12:56:10 +0000
@@ -23,6 +23,7 @@ select @@innodb_lock_wait_timeout;
create table t1(a int primary key)engine=innodb;
begin;
insert into t1 values(1),(2),(3);
+set innodb_lock_wait_timeout=5;
select * from t1 for update;
commit;
a
@@ -31,8 +32,15 @@ a
3
begin;
insert into t1 values(4);
+set innodb_lock_wait_timeout=2;
+set @a= current_timestamp();
select * from t1 for update;
-commit;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+set @b= current_timestamp();
+set @c= timestampdiff(SECOND, @a, @b);
+select if(@c >= 1 and @c <= 10, 'OK', concat("NOT OK, time passed=", @c));
+if(@c >= 1 and @c <= 10, 'OK', concat("NOT OK, time passed=", @c))
+OK
+commit;
drop table t1;
set global innodb_lock_wait_timeout=50;
=== modified file 'mysql-test/r/innodb-zip.result'
--- a/mysql-test/r/innodb-zip.result 2009-06-09 15:08:46 +0000
+++ b/mysql-test/r/innodb-zip.result 2010-01-15 15:58:25 +0000
@@ -196,15 +196,15 @@ drop table t1;
set innodb_strict_mode = on;
create table t1 (id int primary key) engine = innodb key_block_size = 0;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16]
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 9;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 1;
create table t4 (id int primary key) engine = innodb key_block_size = 2;
@@ -233,30 +233,30 @@ key_block_size = 8 row_format = compress
create table t2 (id int primary key) engine = innodb
key_block_size = 8 row_format = redundant;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb
key_block_size = 8 row_format = compact;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb
key_block_size = 8 row_format = dynamic;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb
key_block_size = 8 row_format = default;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t5' (errno: 1478)
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -266,26 +266,26 @@ drop table t1;
create table t1 (id int primary key) engine = innodb
key_block_size = 9 row_format = redundant;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
-Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = compact;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
-Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = dynamic;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
-Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t2' (errno: 1478)
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -293,45 +293,45 @@ table_schema table_name row_format
set global innodb_file_per_table = off;
create table t1 (id int primary key) engine = innodb key_block_size = 1;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 2;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 4;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb key_block_size = 8;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb key_block_size = 16;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t5' (errno: 1478)
create table t6 (id int primary key) engine = innodb row_format = compressed;
ERROR HY000: Can't create table 'test.t6' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
+Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
Error 1005 Can't create table 'test.t6' (errno: 1478)
create table t7 (id int primary key) engine = innodb row_format = dynamic;
ERROR HY000: Can't create table 'test.t7' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
Error 1005 Can't create table 'test.t7' (errno: 1478)
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
@@ -345,45 +345,45 @@ set global innodb_file_per_table = on;
set global innodb_file_format = `0`;
create table t1 (id int primary key) engine = innodb key_block_size = 1;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 2;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 4;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb key_block_size = 8;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb key_block_size = 16;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t5' (errno: 1478)
create table t6 (id int primary key) engine = innodb row_format = compressed;
ERROR HY000: Can't create table 'test.t6' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t6' (errno: 1478)
create table t7 (id int primary key) engine = innodb row_format = dynamic;
ERROR HY000: Can't create table 'test.t7' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t7' (errno: 1478)
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
=== modified file 'mysql-test/r/innodb.result'
--- a/mysql-test/r/innodb.result 2009-11-13 21:26:08 +0000
+++ b/mysql-test/r/innodb.result 2010-01-15 15:58:25 +0000
@@ -3090,7 +3090,7 @@ ERROR HY000: Lock wait timeout exceeded;
commit;
drop table t1, t2, t3, t5, t6, t8, t9;
CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
-ERROR HY000: Can't create table 'test.t1' (errno: -1)
+ERROR 42000: Incorrect column name 'DB_ROW_ID'
CREATE TABLE t1 (
a BIGINT(20) NOT NULL,
PRIMARY KEY (a)
@@ -3160,15 +3160,6 @@ ALTER TABLE t2 MODIFY a INT NOT NULL;
ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150)
DELETE FROM t1;
DROP TABLE t2,t1;
-CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY)
-ENGINE=InnoDB;
-INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4);
-DELETE FROM t1;
-INSERT INTO t1 VALUES ('DDD');
-SELECT * FROM t1;
-a
-DDD
-DROP TABLE t1;
CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
AUTO_INCREMENT=42;
INSERT INTO t1 VALUES (0),(347),(0);
=== modified file 'mysql-test/r/innodb_bug36169.result'
--- a/mysql-test/r/innodb_bug36169.result 2009-11-13 21:26:08 +0000
+++ b/mysql-test/r/innodb_bug36169.result 2010-01-15 15:58:25 +0000
@@ -1,4 +1,2 @@
-set @old_innodb_file_format=@@innodb_file_format;
-set @old_innodb_file_per_table=@@innodb_file_per_table;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
=== modified file 'mysql-test/r/innodb_bug44369.result'
--- a/mysql-test/r/innodb_bug44369.result 2009-11-02 14:59:44 +0000
+++ b/mysql-test/r/innodb_bug44369.result 2010-01-15 15:58:25 +0000
@@ -1,14 +1,6 @@
create table bug44369 (DB_ROW_ID int) engine=innodb;
-ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+ERROR 42000: Incorrect column name 'DB_ROW_ID'
create table bug44369 (db_row_id int) engine=innodb;
-ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
-show warnings;
-Level Code Message
-Warning 1005 Error creating table 'test/bug44369' with column name 'db_row_id'. 'db_row_id' is a reserved name. Please try to re-create the table with a different column name.
-Error 1005 Can't create table 'test.bug44369' (errno: -1)
+ERROR 42000: Incorrect column name 'db_row_id'
create table bug44369 (db_TRX_Id int) engine=innodb;
-ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
-show warnings;
-Level Code Message
-Warning 1005 Error creating table 'test/bug44369' with column name 'db_TRX_Id'. 'db_TRX_Id' is a reserved name. Please try to re-create the table with a different column name.
-Error 1005 Can't create table 'test.bug44369' (errno: -1)
+ERROR 42000: Incorrect column name 'db_TRX_Id'
=== added file 'mysql-test/r/innodb_bug44571.result'
--- a/mysql-test/r/innodb_bug44571.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb_bug44571.result 2010-01-15 15:58:25 +0000
@@ -0,0 +1,7 @@
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+ERROR 42000: Key column 'foo' doesn't exist in table
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+CREATE INDEX bug44571c ON bug44571 (bar);
+DROP TABLE bug44571;
=== added file 'mysql-test/r/innodb_bug46676.result'
--- a/mysql-test/r/innodb_bug46676.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb_bug46676.result 2010-01-15 15:58:25 +0000
@@ -0,0 +1,9 @@
+SET foreign_key_checks=0;
+CREATE TABLE t1 (id int, foreign key (id) references t2(id)) ENGINE=INNODB;
+CREATE TABLE t2 (id int, foreign key (id) references t1(id)) ENGINE=INNODB;
+SET foreign_key_checks=1;
+SELECT COUNT(*) FROM information_schema.key_column_usage WHERE REFERENCED_TABLE_NAME in ('t1', 't2');
+COUNT(*)
+2
+SET foreign_key_checks=0;
+DROP TABLE t1, t2;
=== added file 'mysql-test/r/innodb_bug47167.result'
--- a/mysql-test/r/innodb_bug47167.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb_bug47167.result 2010-01-15 15:58:25 +0000
@@ -0,0 +1,24 @@
+set @old_innodb_file_format_check=@@innodb_file_format_check;
+select @old_innodb_file_format_check;
+@old_innodb_file_format_check
+Antelope
+set global innodb_file_format_check = Barracuda;
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
+set global innodb_file_format_check = DEFAULT;
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
+set global innodb_file_format_check = @old_innodb_file_format_check;
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Antelope
+set global innodb_file_format_check = cheetah;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format_check = Bear;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format_check = on;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format_check = off;
+ERROR HY000: Incorrect arguments to SET
=== modified file 'mysql-test/r/innodb_file_format.result'
--- a/mysql-test/r/innodb_file_format.result 2009-11-30 21:37:27 +0000
+++ b/mysql-test/r/innodb_file_format.result 2010-01-15 15:58:25 +0000
@@ -1,4 +1,3 @@
-set @old_innodb_file_format=@@innodb_file_format;
call mtr.add_suppression("InnoDB: invalid innodb_file_format_check value");
select @@innodb_file_format;
@@innodb_file_format
@@ -32,8 +31,6 @@ select @@innodb_file_format_check;
@@innodb_file_format_check
Barracuda
set global innodb_file_format_check=default;
-Warnings:
-Warning 1210 Ignoring SET innodb_file_format=on
select @@innodb_file_format_check;
@@innodb_file_format_check
Barracuda
@@ -44,5 +41,4 @@ ERROR HY000: Incorrect arguments to SET
select @@innodb_file_format_check;
@@innodb_file_format_check
Barracuda
-set global innodb_file_format=@old_innodb_file_format;
-set global innodb_file_format_check=Antelope;
+set global innodb_file_format_check=antelope;
=== modified file 'mysql-test/r/innodb_lock_wait_timeout_1.result'
--- a/mysql-test/r/innodb_lock_wait_timeout_1.result 2009-11-03 17:45:52 +0000
+++ b/mysql-test/r/innodb_lock_wait_timeout_1.result 2009-11-12 11:43:33 +0000
@@ -48,6 +48,24 @@ commit;
set autocommit=default;
drop table t1;
#
+# Bug #37183 insert ignore into .. select ... hangs
+# after deadlock was encountered
+#
+create table t1(id int primary key,v int)engine=innodb;
+insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
+create table t2 like t1;
+begin;
+update t1 set v=id*2 where id=1;
+begin;
+update t1 set v=id*2 where id=2;
+update t1 set v=id*2 where id=2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+insert ignore into t2 select * from t1 where id=1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+rollback;
+rollback;
+drop table t1, t2;
+#
# Bug#41756 Strange error messages about locks from InnoDB
#
drop table if exists t1;
=== modified file 'mysql-test/r/innodb_mysql.result'
--- a/mysql-test/r/innodb_mysql.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/r/innodb_mysql.result 2010-01-15 15:27:55 +0000
@@ -2251,4 +2251,26 @@ c >= '2009-10-09 00:00:00.001' AND c <=
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
DROP TABLE t1;
+#
+# Bug #46175: NULL read_view and consistent read assertion
+#
+CREATE TABLE t1(a CHAR(13),KEY(a)) ENGINE=innodb;
+CREATE TABLE t2(b DATETIME,KEY(b)) ENGINE=innodb;
+INSERT INTO t1 VALUES (),();
+INSERT INTO t2 VALUES (),();
+CREATE OR REPLACE VIEW v1 AS SELECT 1 FROM t2
+WHERE b =(SELECT a FROM t1 LIMIT 1);
+CREATE PROCEDURE p1(num INT)
+BEGIN
+DECLARE i INT DEFAULT 0;
+REPEAT
+SHOW CREATE VIEW v1;
+SET i:=i+1;
+UNTIL i>num END REPEAT;
+END|
+# Should not crash
+# Should not crash
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1,t2;
End of 5.1 tests
=== added file 'mysql-test/r/innodb_utf8.result'
--- a/mysql-test/r/innodb_utf8.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb_utf8.result 2009-12-27 13:54:41 +0000
@@ -0,0 +1,10 @@
+drop table if exists t1;
+CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY)
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4);
+DELETE FROM t1;
+INSERT INTO t1 VALUES ('DDD');
+SELECT * FROM t1;
+a
+DDD
+DROP TABLE t1;
=== modified file 'mysql-test/r/innodb_xtradb_bug317074.result'
--- a/mysql-test/r/innodb_xtradb_bug317074.result 2009-10-28 07:52:34 +0000
+++ b/mysql-test/r/innodb_xtradb_bug317074.result 2010-01-15 15:58:25 +0000
@@ -1,6 +1,5 @@
SET @old_innodb_file_format=@@innodb_file_format;
SET @old_innodb_file_per_table=@@innodb_file_per_table;
-SET @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
DROP TABLE IF EXISTS `test1`;
@@ -29,4 +28,4 @@ ALTER TABLE test1 ENGINE=MyISAM;
DROP TABLE test1;
SET GLOBAL innodb_file_format=@old_innodb_file_format;
SET GLOBAL innodb_file_per_table=@old_innodb_file_per_table;
-SET GLOBAL innodb_file_format_check=@old_innodb_file_format_check;
+set global innodb_file_format_check=Antelope;
=== modified file 'mysql-test/r/join_outer.result'
--- a/mysql-test/r/join_outer.result 2007-05-27 19:22:44 +0000
+++ b/mysql-test/r/join_outer.result 2009-12-17 09:55:18 +0000
@@ -1254,3 +1254,38 @@ SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WH
c e d
1 0 NULL
DROP TABLE t1,t2;
+#
+# Bug#47650: using group by with rollup without indexes returns incorrect
+# results with where
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 ( a INT, b INT );
+INSERT INTO t2 VALUES (1, 1),(1, 2),(1, 3),(2, 4),(2, 5);
+EXPLAIN
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 LEFT JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 LEFT JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+a COUNT( t2.b ) SUM( t2.b ) MAX( t2.b )
+1 3 6 3
+NULL 3 6 3
+EXPLAIN
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using where
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+a COUNT( t2.b ) SUM( t2.b ) MAX( t2.b )
+1 3 6 3
+NULL 3 6 3
+DROP TABLE t1, t2;
=== modified file 'mysql-test/r/myisam.result'
--- a/mysql-test/r/myisam.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/r/myisam.result 2010-03-04 08:03:07 +0000
@@ -1853,6 +1853,21 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
+#
+# Bug #49465: valgrind warnings and incorrect live checksum...
+#
+CREATE TABLE t1(
+a VARCHAR(1), b VARCHAR(1), c VARCHAR(1),
+f VARCHAR(1), g VARCHAR(1), h VARCHAR(1),
+i VARCHAR(1), j VARCHAR(1), k VARCHAR(1)) CHECKSUM=1;
+INSERT INTO t1 VALUES('', '', '', '', '', '', '', '', '');
+CHECKSUM TABLE t1 QUICK;
+Table Checksum
+test.t1 467455460
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 467455460
+DROP TABLE t1;
End of 5.0 tests
create table t1 (a int not null, key `a` (a) key_block_size=1024);
show create table t1;
=== modified file 'mysql-test/r/mysql.result'
--- a/mysql-test/r/mysql.result 2009-07-31 23:43:46 +0000
+++ b/mysql-test/r/mysql.result 2009-12-17 20:06:36 +0000
@@ -230,4 +230,9 @@ a: b
</resultset>
drop table t1;
+Bug #47147: mysql client option --skip-column-names does not apply to vertical output
+
+*************************** 1. row ***************************
+1
+
End of tests
=== modified file 'mysql-test/r/mysql_upgrade.result'
--- a/mysql-test/r/mysql_upgrade.result 2009-01-26 14:20:33 +0000
+++ b/mysql-test/r/mysql_upgrade.result 2009-12-04 16:00:20 +0000
@@ -127,3 +127,45 @@ mysql.time_zone_transition
mysql.time_zone_transition_type OK
mysql.user OK
set GLOBAL sql_mode=default;
+#
+# Bug #41569 mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table
+# but does not set values.
+#
+CREATE PROCEDURE testproc() BEGIN END;
+UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc';
+UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc';
+UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc';
+mtr.global_suppressions OK
+mtr.test_suppressions OK
+mysql.columns_priv OK
+mysql.db OK
+mysql.event OK
+mysql.func OK
+mysql.general_log
+Error : You can't use locks with log tables.
+status : OK
+mysql.help_category OK
+mysql.help_keyword OK
+mysql.help_relation OK
+mysql.help_topic OK
+mysql.host OK
+mysql.ndb_binlog_index OK
+mysql.plugin OK
+mysql.proc OK
+mysql.procs_priv OK
+mysql.servers OK
+mysql.slow_log
+Error : You can't use locks with log tables.
+status : OK
+mysql.tables_priv OK
+mysql.time_zone OK
+mysql.time_zone_leap_second OK
+mysql.time_zone_name OK
+mysql.time_zone_transition OK
+mysql.time_zone_transition_type OK
+mysql.user OK
+CALL testproc();
+DROP PROCEDURE testproc;
+WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (latin1). Please verify if necessary.
+WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (latin1_swedish_ci). Please verify if necessary.
+WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary.
=== modified file 'mysql-test/r/mysqlbinlog.result'
--- a/mysql-test/r/mysqlbinlog.result 2009-09-30 02:31:25 +0000
+++ b/mysql-test/r/mysqlbinlog.result 2010-01-27 12:23:28 +0000
@@ -44,16 +44,16 @@ SET TIMESTAMP=1000000000/*!*/;
insert into t2 values ()
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
/*!*/;
DELIMITER ;
# End of log file
@@ -93,6 +93,7 @@ ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- --position --
+Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead.
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -144,16 +145,16 @@ SET TIMESTAMP=1000000000/*!*/;
insert into t2 values ()
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
/*!*/;
DELIMITER ;
# End of log file
@@ -193,6 +194,7 @@ ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- --position --
+Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead.
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -233,6 +235,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead.
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -359,29 +362,29 @@ SET @@session.collation_database=DEFAULT
create table t1 (a varchar(64) character set utf8)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=7/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=7/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO TABLE `t1` CHARACTER SET koi8r FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO TABLE `t1` CHARACTER SET koi8r FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
drop table t1
=== modified file 'mysql-test/r/mysqltest.result'
--- a/mysql-test/r/mysqltest.result 2009-10-08 09:30:03 +0000
+++ b/mysql-test/r/mysqltest.result 2010-01-11 13:15:28 +0000
@@ -1,3 +1,4 @@
+SET GLOBAL max_connections = 1000;
select 0 as "before_use_test" ;
before_use_test
0
=== modified file 'mysql-test/r/olap.result'
--- a/mysql-test/r/olap.result 2009-10-30 15:59:06 +0000
+++ b/mysql-test/r/olap.result 2009-12-08 09:26:11 +0000
@@ -753,4 +753,16 @@ b
100
NULL
DROP TABLE t1, t2;
+#
+# Bug #48475: DISTINCT is ignored with GROUP BY WITH ROLLUP
+# and only const tables
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+SELECT DISTINCT b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+b
+1
+NULL
+DROP TABLE t1, t2;
End of 5.0 tests
=== modified file 'mysql-test/r/openssl_1.result'
--- a/mysql-test/r/openssl_1.result 2009-05-25 13:00:18 +0000
+++ b/mysql-test/r/openssl_1.result 2010-03-04 08:03:07 +0000
@@ -3,8 +3,8 @@ create table t1(f1 int);
insert into t1 values (5);
grant select on test.* to ssl_user1@localhost require SSL;
grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA";
-grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer(a)mysql.com";
-grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer(a)mysql.com" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB";
+grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB";
+grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB";
grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx";
flush privileges;
connect(localhost,ssl_user5,,test,MASTER_PORT,MASTER_SOCKET);
@@ -44,9 +44,9 @@ ERROR 42000: DELETE command denied to us
drop user ssl_user1@localhost, ssl_user2@localhost,
ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost;
drop table t1;
-mysqltest: Could not open connection 'default': 2026 SSL connection error
-mysqltest: Could not open connection 'default': 2026 SSL connection error
-mysqltest: Could not open connection 'default': 2026 SSL connection error
+mysqltest: Could not open connection 'default': 2026 SSL error: ASN: bad other signature confirmation
+mysqltest: Could not open connection 'default': 2026 SSL error: ASN: bad other signature confirmation
+mysqltest: Could not open connection 'default': 2026 SSL error: ASN: bad other signature confirmation
SSL error: Unable to get private key from ''
mysqltest: Could not open connection 'default': 2026 SSL connection error
SSL error: Unable to get certificate from ''
=== modified file 'mysql-test/r/order_by.result'
--- a/mysql-test/r/order_by.result 2009-10-14 14:30:39 +0000
+++ b/mysql-test/r/order_by.result 2009-12-10 15:38:01 +0000
@@ -1444,6 +1444,36 @@ FROM t3;
2
NULL
DROP TABLE t1, t2, t3;
+#
+# Bug #42760: Select doesn't return desired results when we have null
+# values
+#
+CREATE TABLE t1 (
+a INT,
+c INT,
+UNIQUE KEY a_c (a,c),
+KEY (a));
+INSERT INTO t1 VALUES (1, 10), (2, NULL);
+# Must use ref-or-null on the a_c index
+EXPLAIN
+SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref_or_null a_c,a a_c 10 const,const 1 Using where
+# Must return 1 row
+SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
+col
+1
+# Must use ref-or-null on the a_c index
+EXPLAIN
+SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC;
+id select_type table type possible_keys key key_len ref rows Extra
+x x x ref_or_null a_c,a x x x x x
+# Must return 1 row
+SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC;
+col
+1
+DROP TABLE t1;
+End of 5.0 tests
CREATE TABLE t2 (a varchar(32), b int(11), c float, d double,
UNIQUE KEY a (a,b,c), KEY b (b), KEY c (c));
CREATE TABLE t1 (a varchar(32), b char(3), UNIQUE KEY a (a,b), KEY b (b));
=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/r/partition.result 2010-03-04 08:03:07 +0000
@@ -1,4 +1,10 @@
drop table if exists t1, t2;
+CREATE TABLE t1 (a INT, b INT)
+PARTITION BY LIST (a)
+SUBPARTITION BY HASH (b)
+(PARTITION p1 VALUES IN (1));
+ALTER TABLE t1 ADD COLUMN c INT;
+DROP TABLE t1;
CREATE TABLE t1 (
a int NOT NULL,
b int NOT NULL);
@@ -18,8 +24,8 @@ a timestamp NOT NULL DEFAULT CURRENT_TIM
b varchar(10),
PRIMARY KEY (a)
)
-PARTITION BY RANGE (to_days(a)) (
-PARTITION p1 VALUES LESS THAN (733407),
+PARTITION BY RANGE (UNIX_TIMESTAMP(a)) (
+PARTITION p1 VALUES LESS THAN (1199134800),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
INSERT INTO t1 VALUES ('2007-07-30 17:35:48', 'p1');
@@ -31,7 +37,7 @@ a b
2009-07-14 17:35:55 pmax
2009-09-21 17:31:42 pmax
ALTER TABLE t1 REORGANIZE PARTITION pmax INTO (
-PARTITION p3 VALUES LESS THAN (733969),
+PARTITION p3 VALUES LESS THAN (1247688000),
PARTITION pmax VALUES LESS THAN MAXVALUE);
SELECT * FROM t1;
a b
@@ -45,11 +51,18 @@ t1 CREATE TABLE `t1` (
`b` varchar(10) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY RANGE (to_days(a))
-(PARTITION p1 VALUES LESS THAN (733407) ENGINE = MyISAM,
- PARTITION p3 VALUES LESS THAN (733969) ENGINE = MyISAM,
+/*!50100 PARTITION BY RANGE (UNIX_TIMESTAMP(a))
+(PARTITION p1 VALUES LESS THAN (1199134800) ENGINE = MyISAM,
+ PARTITION p3 VALUES LESS THAN (1247688000) ENGINE = MyISAM,
PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
DROP TABLE t1;
+create table t1 (a int NOT NULL, b varchar(5) NOT NULL)
+default charset=utf8
+partition by list (a)
+subpartition by key (b)
+(partition p0 values in (1),
+partition p1 values in (2));
+drop table t1;
create table t1 (a int, b int, key(a))
partition by list (a)
( partition p0 values in (1),
@@ -2045,10 +2058,15 @@ DROP TABLE t1;
#
# Bug #45807: crash accessing partitioned table and sql_mode
# contains ONLY_FULL_GROUP_BY
+# Bug#46923: select count(*) from partitioned table fails with
+# ONLY_FULL_GROUP_BY
#
SET SESSION SQL_MODE='ONLY_FULL_GROUP_BY';
CREATE TABLE t1(id INT,KEY(id)) ENGINE=MYISAM
PARTITION BY HASH(id) PARTITIONS 2;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
DROP TABLE t1;
SET SESSION SQL_MODE=DEFAULT;
#
=== modified file 'mysql-test/r/partition_bug18198.result'
--- a/mysql-test/r/partition_bug18198.result 2007-06-13 15:28:59 +0000
+++ b/mysql-test/r/partition_bug18198.result 2009-12-13 20:29:50 +0000
@@ -126,7 +126,7 @@ ERROR HY000: This partition function is
create table t1 (col1 date)
partition by range(unix_timestamp(col1))
(partition p0 values less than (10), partition p1 values less than (30));
-ERROR HY000: This partition function is not allowed
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
create table t1 (col1 datetime)
partition by range(week(col1))
(partition p0 values less than (10), partition p1 values less than (30));
=== modified file 'mysql-test/r/partition_error.result'
--- a/mysql-test/r/partition_error.result 2009-02-18 20:29:30 +0000
+++ b/mysql-test/r/partition_error.result 2009-12-13 20:29:50 +0000
@@ -138,7 +138,7 @@ primary key(a,b))
partition by hash (rand(a))
partitions 2
(partition x1, partition x2);
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')
partitions 2
(partition x1, partition x2)' at line 6
CREATE TABLE t1 (
@@ -149,7 +149,7 @@ primary key(a,b))
partition by range (rand(a))
partitions 2
(partition x1 values less than (0), partition x2 values less than (2));
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')
partitions 2
(partition x1 values less than (0), partition x2 values less than' at line 6
CREATE TABLE t1 (
@@ -160,7 +160,7 @@ primary key(a,b))
partition by list (rand(a))
partitions 2
(partition x1 values in (1), partition x2 values in (2));
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')
partitions 2
(partition x1 values in (1), partition x2 values in (2))' at line 6
CREATE TABLE t1 (
@@ -275,7 +275,7 @@ c int not null,
primary key (a,b))
partition by key (a)
subpartition by hash (rand(a+b));
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 7
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 7
CREATE TABLE t1 (
a int not null,
b int not null,
@@ -372,7 +372,7 @@ partition by range (3+4)
partitions 2
(partition x1 values less than (4) tablespace ts1,
partition x2 values less than (8) tablespace ts2);
-ERROR HY000: Constant/Random expression in (sub)partitioning function is not allowed
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
CREATE TABLE t1 (
a int not null,
b int not null,
@@ -542,7 +542,7 @@ partition by list (3+4)
partitions 2
(partition x1 values in (4) tablespace ts1,
partition x2 values in (8) tablespace ts2);
-ERROR HY000: Constant/Random expression in (sub)partitioning function is not allowed
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
CREATE TABLE t1 (
a int not null,
b int not null,
@@ -634,13 +634,13 @@ partition by range (ascii(v))
ERROR HY000: This partition function is not allowed
create table t1 (a int)
partition by hash (rand(a));
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2
create table t1 (a int)
partition by hash(CURTIME() + a);
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2
create table t1 (a int)
partition by hash (NOW()+a);
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2
create table t1 (a int)
partition by hash (extract(hour from convert_tz(a, '+00:00', '+00:00')));
ERROR HY000: This partition function is not allowed
@@ -651,3 +651,295 @@ ERROR HY000: This partition function is
create table t1 (a char(10))
partition by hash (extractvalue(a,'a'));
ERROR HY000: This partition function is not allowed
+#
+# Bug #42849: innodb crash with varying time_zone on partitioned
+# timestamp primary key
+#
+CREATE TABLE old (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (UNIX_TIMESTAMP(a)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (a) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: The PARTITION function returns the wrong type
+ALTER TABLE old
+PARTITION BY RANGE (a) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: The PARTITION function returns the wrong type
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (a+0) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (a+0) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (a % 2) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (a % 2) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (ABS(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (ABS(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (CEILING(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (CEILING(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (FLOOR(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (FLOOR(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (TO_DAYS(a)) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (TO_DAYS(a)) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (DAYOFYEAR(a)) (
+PARTITION p VALUES LESS THAN (231),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (DAYOFYEAR(a)) (
+PARTITION p VALUES LESS THAN (231),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (DAYOFMONTH(a)) (
+PARTITION p VALUES LESS THAN (19),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (DAYOFMONTH(a)) (
+PARTITION p VALUES LESS THAN (19),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (DAYOFWEEK(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (DAYOFWEEK(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (MONTH(a)) (
+PARTITION p VALUES LESS THAN (8),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (MONTH(a)) (
+PARTITION p VALUES LESS THAN (8),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (HOUR(a)) (
+PARTITION p VALUES LESS THAN (17),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (HOUR(a)) (
+PARTITION p VALUES LESS THAN (17),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (MINUTE(a)) (
+PARTITION p VALUES LESS THAN (55),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (MINUTE(a)) (
+PARTITION p VALUES LESS THAN (55),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (QUARTER(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (QUARTER(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (SECOND(a)) (
+PARTITION p VALUES LESS THAN (7),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (SECOND(a)) (
+PARTITION p VALUES LESS THAN (7),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (YEARWEEK(a)) (
+PARTITION p VALUES LESS THAN (200833),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (YEARWEEK(a)) (
+PARTITION p VALUES LESS THAN (200833),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (YEAR(a)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (YEAR(a)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (WEEKDAY(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (WEEKDAY(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (TIME_TO_SEC(a)) (
+PARTITION p VALUES LESS THAN (64507),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (TIME_TO_SEC(a)) (
+PARTITION p VALUES LESS THAN (64507),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (EXTRACT(DAY FROM a)) (
+PARTITION p VALUES LESS THAN (18),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (EXTRACT(DAY FROM a)) (
+PARTITION p VALUES LESS THAN (18),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL, b TIMESTAMP NOT NULL, PRIMARY KEY(a,b))
+PARTITION BY RANGE (DATEDIFF(a, a)) (
+PARTITION p VALUES LESS THAN (18),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (DATEDIFF(a, a)) (
+PARTITION p VALUES LESS THAN (18),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (YEAR(a + 0)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (YEAR(a + 0)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (TO_DAYS(a + '2008-01-01')) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (TO_DAYS(a + '2008-01-01')) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (YEAR(a + '2008-01-01')) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (YEAR(a + '2008-01-01')) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old ADD COLUMN b DATE;
+CREATE TABLE new (a TIMESTAMP, b DATE)
+PARTITION BY RANGE (YEAR(a + b)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (YEAR(a + b)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP, b DATE)
+PARTITION BY RANGE (TO_DAYS(a + b)) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (TO_DAYS(a + b)) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP, b date)
+PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old
+PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE new (a TIMESTAMP, b TIMESTAMP)
+PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE old MODIFY b TIMESTAMP;
+ALTER TABLE old
+PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+DROP TABLE old;
+End of 5.1 tests
=== modified file 'mysql-test/r/partition_innodb.result'
--- a/mysql-test/r/partition_innodb.result 2009-09-10 06:54:26 +0000
+++ b/mysql-test/r/partition_innodb.result 2010-01-18 16:49:18 +0000
@@ -274,3 +274,47 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB
PARTITION BY list(a) (PARTITION p1 VALUES IN (1));
CREATE INDEX i1 ON t1 (a);
DROP TABLE t1;
+#
+# Bug#47343: InnoDB fails to clean-up after lock wait timeout on
+# REORGANIZE PARTITION
+#
+CREATE TABLE t1 (
+a INT,
+b DATE NOT NULL,
+PRIMARY KEY (a, b)
+) ENGINE=InnoDB
+PARTITION BY RANGE (a) (
+PARTITION pMAX VALUES LESS THAN MAXVALUE
+) ;
+INSERT INTO t1 VALUES (1, '2001-01-01'), (2, '2002-02-02'), (3, '2003-03-03');
+START TRANSACTION;
+SELECT * FROM t1 FOR UPDATE;
+a b
+1 2001-01-01
+2 2002-02-02
+3 2003-03-03
+# Connection con1
+ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO
+(PARTITION p3 VALUES LESS THAN (3),
+PARTITION pMAX VALUES LESS THAN MAXVALUE);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SHOW WARNINGS;
+Level Code Message
+Error 1205 Lock wait timeout exceeded; try restarting transaction
+ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO
+(PARTITION p3 VALUES LESS THAN (3),
+PARTITION pMAX VALUES LESS THAN MAXVALUE);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SHOW WARNINGS;
+Level Code Message
+Error 1205 Lock wait timeout exceeded; try restarting transaction
+t1.frm
+t1.par
+# Connection default
+SELECT * FROM t1;
+a b
+1 2001-01-01
+2 2002-02-02
+3 2003-03-03
+COMMIT;
+DROP TABLE t1;
=== modified file 'mysql-test/r/partition_pruning.result'
--- a/mysql-test/r/partition_pruning.result 2009-10-16 20:19:51 +0000
+++ b/mysql-test/r/partition_pruning.result 2010-01-17 21:00:37 +0000
@@ -1,4 +1,614 @@
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+#
+# Bug#49742: Partition Pruning not working correctly for RANGE
+#
+CREATE TABLE t1 (a INT PRIMARY KEY)
+PARTITION BY RANGE (a) (
+PARTITION p0 VALUES LESS THAN (1),
+PARTITION p1 VALUES LESS THAN (2),
+PARTITION p2 VALUES LESS THAN (3),
+PARTITION p3 VALUES LESS THAN (4),
+PARTITION p4 VALUES LESS THAN (5),
+PARTITION p5 VALUES LESS THAN (6),
+PARTITION max VALUES LESS THAN MAXVALUE);
+INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8);
+SELECT * FROM t1 WHERE a < 1;
+a
+-1
+0
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+SELECT * FROM t1 WHERE a < 2;
+a
+-1
+0
+1
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index
+SELECT * FROM t1 WHERE a < 3;
+a
+-1
+0
+1
+2
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+SELECT * FROM t1 WHERE a < 4;
+a
+-1
+0
+1
+2
+3
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 5 Using where; Using index
+SELECT * FROM t1 WHERE a < 5;
+a
+-1
+0
+1
+2
+3
+4
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 6 Using where; Using index
+SELECT * FROM t1 WHERE a < 6;
+a
+-1
+0
+1
+2
+3
+4
+5
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 7 Using where; Using index
+SELECT * FROM t1 WHERE a < 7;
+a
+-1
+0
+1
+2
+3
+4
+5
+6
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a <= 1;
+a
+-1
+0
+1
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a <= 2;
+a
+-1
+0
+1
+2
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a <= 3;
+a
+-1
+0
+1
+2
+3
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a <= 4;
+a
+-1
+0
+1
+2
+3
+4
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a <= 5;
+a
+-1
+0
+1
+2
+3
+4
+5
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a <= 6;
+a
+-1
+0
+1
+2
+3
+4
+5
+6
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a <= 7;
+a
+-1
+0
+1
+2
+3
+4
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 7;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a = 1;
+a
+1
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1 system PRIMARY NULL NULL NULL 1
+SELECT * FROM t1 WHERE a = 2;
+a
+2
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2 system PRIMARY NULL NULL NULL 1
+SELECT * FROM t1 WHERE a = 3;
+a
+3
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p3 system PRIMARY NULL NULL NULL 1
+SELECT * FROM t1 WHERE a = 4;
+a
+4
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p4 system PRIMARY NULL NULL NULL 1
+SELECT * FROM t1 WHERE a = 5;
+a
+5
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p5 system PRIMARY NULL NULL NULL 1
+SELECT * FROM t1 WHERE a = 6;
+a
+6
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max const PRIMARY PRIMARY 4 const 1 Using index
+SELECT * FROM t1 WHERE a = 7;
+a
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 7;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max const PRIMARY PRIMARY 4 const 1 Using index
+SELECT * FROM t1 WHERE a >= 1;
+a
+1
+2
+3
+4
+5
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a >= 2;
+a
+2
+3
+4
+5
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a >= 3;
+a
+3
+4
+5
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a >= 4;
+a
+4
+5
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a >= 5;
+a
+5
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a >= 6;
+a
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a >= 7;
+a
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 7;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+SELECT * FROM t1 WHERE a > 1;
+a
+2
+3
+4
+5
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a > 2;
+a
+3
+4
+5
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a > 3;
+a
+4
+5
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a > 4;
+a
+5
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a > 5;
+a
+6
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index
+SELECT * FROM t1 WHERE a > 6;
+a
+7
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+SELECT * FROM t1 WHERE a > 7;
+a
+8
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 7;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+DROP TABLE t1;
+CREATE TABLE t1 (a INT PRIMARY KEY)
+PARTITION BY RANGE (a) (
+PARTITION p0 VALUES LESS THAN (1),
+PARTITION p1 VALUES LESS THAN (2),
+PARTITION p2 VALUES LESS THAN (3),
+PARTITION p3 VALUES LESS THAN (4),
+PARTITION p4 VALUES LESS THAN (5),
+PARTITION max VALUES LESS THAN MAXVALUE);
+INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7);
+SELECT * FROM t1 WHERE a < 1;
+a
+-1
+0
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+SELECT * FROM t1 WHERE a < 2;
+a
+-1
+0
+1
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index
+SELECT * FROM t1 WHERE a < 3;
+a
+-1
+0
+1
+2
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+SELECT * FROM t1 WHERE a < 4;
+a
+-1
+0
+1
+2
+3
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 5 Using where; Using index
+SELECT * FROM t1 WHERE a < 5;
+a
+-1
+0
+1
+2
+3
+4
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 6 Using where; Using index
+SELECT * FROM t1 WHERE a < 6;
+a
+-1
+0
+1
+2
+3
+4
+5
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index
+SELECT * FROM t1 WHERE a <= 1;
+a
+-1
+0
+1
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a <= 2;
+a
+-1
+0
+1
+2
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a <= 3;
+a
+-1
+0
+1
+2
+3
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a <= 4;
+a
+-1
+0
+1
+2
+3
+4
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a <= 5;
+a
+-1
+0
+1
+2
+3
+4
+5
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index
+SELECT * FROM t1 WHERE a <= 6;
+a
+-1
+0
+1
+2
+3
+4
+5
+6
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index
+SELECT * FROM t1 WHERE a = 1;
+a
+1
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1 system PRIMARY NULL NULL NULL 1
+SELECT * FROM t1 WHERE a = 2;
+a
+2
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2 system PRIMARY NULL NULL NULL 1
+SELECT * FROM t1 WHERE a = 3;
+a
+3
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p3 system PRIMARY NULL NULL NULL 1
+SELECT * FROM t1 WHERE a = 4;
+a
+4
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p4 system PRIMARY NULL NULL NULL 1
+SELECT * FROM t1 WHERE a = 5;
+a
+5
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max const PRIMARY PRIMARY 4 const 1 Using index
+SELECT * FROM t1 WHERE a = 6;
+a
+6
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max const PRIMARY PRIMARY 4 const 1 Using index
+SELECT * FROM t1 WHERE a >= 1;
+a
+1
+2
+3
+4
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a >= 2;
+a
+2
+3
+4
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a >= 3;
+a
+3
+4
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a >= 4;
+a
+4
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a >= 5;
+a
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a >= 6;
+a
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+SELECT * FROM t1 WHERE a > 1;
+a
+2
+3
+4
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a > 2;
+a
+3
+4
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a > 3;
+a
+4
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a > 4;
+a
+5
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index
+SELECT * FROM t1 WHERE a > 5;
+a
+6
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+SELECT * FROM t1 WHERE a > 6;
+a
+7
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+DROP TABLE t1;
# test of RANGE and index
CREATE TABLE t1 (a DATE, KEY(a))
PARTITION BY RANGE (TO_DAYS(a))
@@ -1816,7 +2426,7 @@ id select_type table partitions type pos
1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 910 Using where
explain partitions select * from t2 where (a > 100 AND a < 600);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2,p3 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 910 Using where
explain partitions select * from t2 where b = 4;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76 Using where
=== modified file 'mysql-test/r/ps.result'
--- a/mysql-test/r/ps.result 2009-05-27 15:19:44 +0000
+++ b/mysql-test/r/ps.result 2009-12-26 11:25:56 +0000
@@ -1917,6 +1917,53 @@ execute stmt using @arg;
?
-12345.5432100000
deallocate prepare stmt;
+#
+# Bug#48508: Crash on prepared statement re-execution.
+#
+create table t1(b int);
+insert into t1 values (0);
+create view v1 AS select 1 as a from t1 where b;
+prepare stmt from "select * from v1 where a";
+execute stmt;
+a
+execute stmt;
+a
+deallocate prepare stmt;
+drop table t1;
+drop view v1;
+create table t1(a bigint);
+create table t2(b tinyint);
+insert into t2 values (null);
+prepare stmt from "select 1 from t1 join t2 on a xor b where b > 1 and a =1";
+execute stmt;
+1
+execute stmt;
+1
+deallocate prepare stmt;
+drop table t1,t2;
+#
+#
+# Bug #49570: Assertion failed: !(order->used & map)
+# on re-execution of prepared statement
+#
+CREATE TABLE t1(a INT PRIMARY KEY);
+INSERT INTO t1 VALUES(0), (1);
+PREPARE stmt FROM
+"SELECT 1 FROM t1 JOIN t1 t2 USING(a) GROUP BY t2.a, t1.a";
+EXECUTE stmt;
+1
+1
+1
+EXECUTE stmt;
+1
+1
+1
+EXECUTE stmt;
+1
+1
+1
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
End of 5.0 tests.
create procedure proc_1() reset query cache;
call proc_1();
@@ -2922,4 +2969,23 @@ execute stmt;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
drop table t1;
deallocate prepare stmt;
+#
+# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
+#
+prepare encode from "select encode(?, ?) into @ciphertext";
+prepare decode from "select decode(?, ?) into @plaintext";
+set @str="abc", @key="cba";
+execute encode using @str, @key;
+execute decode using @ciphertext, @key;
+select @plaintext;
+@plaintext
+abc
+set @str="bcd", @key="dcb";
+execute encode using @str, @key;
+execute decode using @ciphertext, @key;
+select @plaintext;
+@plaintext
+bcd
+deallocate prepare encode;
+deallocate prepare decode;
End of 5.1 tests.
=== modified file 'mysql-test/r/ps_ddl.result'
--- a/mysql-test/r/ps_ddl.result 2008-08-13 19:42:21 +0000
+++ b/mysql-test/r/ps_ddl.result 2010-01-16 07:44:24 +0000
@@ -1695,23 +1695,23 @@ SUCCESS
drop table t2;
create temporary table t2 (a int);
execute stmt;
-ERROR 42S01: Table 't2' already exists
call p_verify_reprepare_count(1);
SUCCESS
execute stmt;
ERROR 42S01: Table 't2' already exists
-call p_verify_reprepare_count(0);
+call p_verify_reprepare_count(1);
SUCCESS
drop temporary table t2;
execute stmt;
-call p_verify_reprepare_count(1);
+ERROR 42S01: Table 't2' already exists
+call p_verify_reprepare_count(0);
SUCCESS
drop table t2;
execute stmt;
-call p_verify_reprepare_count(0);
+call p_verify_reprepare_count(1);
SUCCESS
drop table t2;
=== modified file 'mysql-test/r/query_cache.result'
--- a/mysql-test/r/query_cache.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/r/query_cache.result 2010-01-11 13:15:28 +0000
@@ -1302,6 +1302,15 @@ drop procedure f3;
drop procedure f4;
drop table t1;
set GLOBAL query_cache_size=0;
+set GLOBAL query_cache_size=100000;
+set SESSION query_cache_size=10000;
+ERROR HY000: Variable 'query_cache_size' is a GLOBAL variable and should be set with SET GLOBAL
+set global query_cache_limit=100;
+set global query_cache_size=100;
+set global query_cache_type=demand;
+set GLOBAL query_cache_type=default;
+set GLOBAL query_cache_limit=default;
+set GLOBAL query_cache_size=default;
End of 4.1 tests
SET GLOBAL query_cache_size=102400;
create table t1(a int);
@@ -1707,6 +1716,95 @@ Variable_name Value
Qcache_hits 2
DROP TABLE t1;
SET GLOBAL query_cache_size= default;
+#------------------------------------------------------------------------
+# Tests for Bug#6760 and Bug#12689
+SET @row_count = 4;
+SET @sleep_time_per_result_row = 1;
+SET @max_acceptable_delay = 2;
+SET @@global.query_cache_size = 1024 * 64;
+DROP TEMPORARY TABLE IF EXISTS t_history;
+DROP TABLE IF EXISTS t1;
+CREATE TEMPORARY TABLE t_history (attempt SMALLINT,
+start_ts DATETIME, end_ts DATETIME,
+start_cached INTEGER, end_cached INTEGER);
+CREATE TABLE t1 (f1 BIGINT);
+INSERT INTO t_history
+SET attempt = 4 - 4 + 1, start_ts = NOW(),
+start_cached = 0;
+SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
+f1 SLEEP(@sleep_time_per_result_row)
+1 0
+1 0
+1 0
+1 0
+UPDATE t_history SET end_ts = NOW()
+WHERE attempt = 4 - 4 + 1;
+UPDATE t_history SET end_cached = 0
+WHERE attempt = 4 - 4 + 1;
+INSERT INTO t_history
+SET attempt = 4 - 3 + 1, start_ts = NOW(),
+start_cached = 0;
+SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
+f1 SLEEP(@sleep_time_per_result_row)
+1 0
+1 0
+1 0
+1 0
+UPDATE t_history SET end_ts = NOW()
+WHERE attempt = 4 - 3 + 1;
+UPDATE t_history SET end_cached = 0
+WHERE attempt = 4 - 3 + 1;
+INSERT INTO t_history
+SET attempt = 4 - 2 + 1, start_ts = NOW(),
+start_cached = 0;
+SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
+f1 SLEEP(@sleep_time_per_result_row)
+1 0
+1 0
+1 0
+1 0
+UPDATE t_history SET end_ts = NOW()
+WHERE attempt = 4 - 2 + 1;
+UPDATE t_history SET end_cached = 0
+WHERE attempt = 4 - 2 + 1;
+INSERT INTO t_history
+SET attempt = 4 - 1 + 1, start_ts = NOW(),
+start_cached = 0;
+SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
+f1 SLEEP(@sleep_time_per_result_row)
+1 0
+1 0
+1 0
+1 0
+UPDATE t_history SET end_ts = NOW()
+WHERE attempt = 4 - 1 + 1;
+UPDATE t_history SET end_cached = 0
+WHERE attempt = 4 - 1 + 1;
+# Test 1: Does the query with SLEEP need a reasonable time?
+SELECT COUNT(*) >= 4 - 1 INTO @aux1 FROM t_history
+WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
+BETWEEN 0 AND @max_acceptable_delay;
+SELECT @aux1 AS "Expect 1";
+Expect 1
+1
+# Test 2: Does the query with SLEEP need a reasonable time even in case
+# of the non first execution?
+SELECT COUNT(*) >= 4 - 1 - 1 INTO @aux2 FROM t_history
+WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
+BETWEEN 0 AND @max_acceptable_delay
+AND attempt > 1;
+SELECT @aux2 AS "Expect 1";
+Expect 1
+1
+# Test 3: The query with SLEEP must be not cached.
+SELECT COUNT(*) = 4 INTO @aux3 FROM t_history
+WHERE end_cached = start_cached;
+SELECT @aux3 AS "Expect 1";
+Expect 1
+1
+DROP TABLE t1;
+DROP TEMPORARY TABLE t_history;
+SET @@global.query_cache_size = default;
End of 5.0 tests
SET GLOBAL query_cache_size=1024*1024*512;
CREATE TABLE t1 (a ENUM('rainbow'));
=== modified file 'mysql-test/r/query_cache_notembedded.result'
--- a/mysql-test/r/query_cache_notembedded.result 2009-02-13 19:32:24 +0000
+++ b/mysql-test/r/query_cache_notembedded.result 2010-01-11 13:15:28 +0000
@@ -382,3 +382,55 @@ set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size=default;
+drop table if exists t1|
+create table t1 (
+id char(16) not null default '',
+data int not null
+)|
+drop procedure if exists bug3583|
+drop procedure if exists bug3583|
+create procedure bug3583()
+begin
+declare c int;
+select * from t1;
+select count(*) into c from t1;
+select c;
+end|
+insert into t1 values ("x", 3), ("y", 5)|
+set @x = @@query_cache_size|
+set global query_cache_size = 10*1024*1024|
+flush status|
+flush query cache|
+show status like 'Qcache_hits'|
+Variable_name Value
+Qcache_hits 0
+call bug3583()|
+id data
+x 3
+y 5
+c
+2
+show status like 'Qcache_hits'|
+Variable_name Value
+Qcache_hits 0
+call bug3583()|
+id data
+x 3
+y 5
+c
+2
+call bug3583()|
+id data
+x 3
+y 5
+c
+2
+show status like 'Qcache_hits'|
+Variable_name Value
+Qcache_hits 2
+set global query_cache_size = @x|
+flush status|
+flush query cache|
+delete from t1|
+drop procedure bug3583|
+drop table t1|
=== modified file 'mysql-test/r/range.result'
--- a/mysql-test/r/range.result 2009-11-02 12:24:07 +0000
+++ b/mysql-test/r/range.result 2009-12-08 09:26:11 +0000
@@ -1603,4 +1603,54 @@ SELECT str_to_date('', '%Y-%m-%d');
str_to_date('', '%Y-%m-%d')
0000-00-00
DROP TABLE t1, t2;
+#
+# Bug#48459: valgrind errors with query using 'Range checked for each
+# record'
+#
+CREATE TABLE t1 (
+a INT,
+b CHAR(2),
+c INT,
+d INT,
+KEY ( c ),
+KEY ( d, a, b ( 2 ) ),
+KEY ( b ( 1 ) )
+);
+INSERT INTO t1 VALUES ( NULL, 'a', 1, 2 ), ( NULL, 'a', 1, 2 ),
+( 1, 'a', 1, 2 ), ( 1, 'a', 1, 2 );
+CREATE TABLE t2 (
+a INT,
+c INT,
+e INT,
+KEY ( e )
+);
+INSERT INTO t2 VALUES ( 1, 1, NULL ), ( 1, 1, NULL );
+# Should not give Valgrind warnings
+SELECT 1
+FROM t1, t2
+WHERE t1.d <> '1' AND t1.b > '1'
+AND t1.a = t2.a AND t1.c = t2.c;
+1
+1
+1
+1
+1
+DROP TABLE t1, t2;
+#
+# Bug #48665: sql-bench's insert test fails due to wrong result
+#
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a));
+INSERT INTO t1 VALUES (0,0), (1,1);
+EXPLAIN
+SELECT * FROM t1 FORCE INDEX (PRIMARY)
+WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+id select_type table type possible_keys key key_len ref rows Extra
+@ @ @ range @ @ @ @ @ @
+# Should return 2 rows
+SELECT * FROM t1 FORCE INDEX (PRIMARY)
+WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+a b
+0 0
+1 1
+DROP TABLE t1;
End of 5.1 tests
=== modified file 'mysql-test/r/select.result'
--- a/mysql-test/r/select.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/r/select.result 2010-03-04 08:03:07 +0000
@@ -4426,6 +4426,168 @@ ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE
INTO @var0;
ERROR 21000: Subquery returns more than 1 row
DROP TABLE t1;
+#
+# Bug #48458: simple query tries to allocate enormous amount of
+# memory
+#
+CREATE TABLE t1(a INT NOT NULL, b YEAR);
+INSERT INTO t1 VALUES ();
+Warnings:
+Warning 1364 Field 'a' doesn't have a default value
+CREATE TABLE t2(c INT);
+# Should not err out because of out-of-memory
+SELECT 1 FROM t2 JOIN t1 ON 1=1
+WHERE a != '1' AND NOT a >= b OR NOT ROW(b,a )<> ROW(a,a);
+1
+DROP TABLE t1,t2;
+#
+# Bug #49199: Optimizer handles incorrectly:
+# field='const1' AND field='const2' in some cases
+
+CREATE TABLE t1(a DATETIME NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+a
+2001-01-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+a
+2001-01-01
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01' AS `a` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a TIMESTAMP NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+a
+2001-01-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+a b
+2001-01-01 00:00:00 2001-01-01
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATETIME NOT NULL, b VARCHAR(20) NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+a b
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 0
+SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
+a b
+2001-01-01 00:00:00 2001-01-01
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1
+DROP TABLE t1;
+CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT x.a, y.a, z.a FROM t1 x
+JOIN t1 y ON x.a=y.a
+JOIN t1 z ON y.a=z.a
+WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
+a a a
+2001-01-01 00:00:00 2001-01-01 00:00:00 2001-01-01 00:00:00
+EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x
+JOIN t1 y ON x.a=y.a
+JOIN t1 z ON y.a=z.a
+WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE x system NULL NULL NULL NULL 1 100.00
+1 SIMPLE y system NULL NULL NULL NULL 1 100.00
+1 SIMPLE z system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a` from `test`.`t1` `x` join `test`.`t1` `y` join `test`.`t1` `z` where 1
+DROP TABLE t1;
+#
+# Bug #49897: crash in ptr_compare when char(0) NOT NULL
+# column is used for ORDER BY
+#
+SET @old_sort_buffer_size= @@session.sort_buffer_size;
+SET @@sort_buffer_size= 40000;
+CREATE TABLE t1(a CHAR(0) NOT NULL);
+INSERT INTO t1 VALUES (0), (0), (0);
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+EXPLAIN SELECT a FROM t1 ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
+SELECT a FROM t1 ORDER BY a;
+DROP TABLE t1;
+CREATE TABLE t1(a CHAR(0) NOT NULL, b CHAR(0) NOT NULL, c int);
+INSERT INTO t1 VALUES (0, 0, 0), (0, 0, 2), (0, 0, 1);
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+EXPLAIN SELECT a FROM t1 ORDER BY a LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
+SELECT a FROM t1 ORDER BY a LIMIT 5;
+a
+
+
+
+
+
+EXPLAIN SELECT * FROM t1 ORDER BY a, b LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
+SELECT * FROM t1 ORDER BY a, b LIMIT 5;
+a b c
+ 0
+ 2
+ 1
+ 0
+ 2
+EXPLAIN SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort
+SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
+a b c
+ 0
+ 0
+ 0
+ 0
+ 0
+EXPLAIN SELECT * FROM t1 ORDER BY c, a LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort
+SELECT * FROM t1 ORDER BY c, a LIMIT 5;
+a b c
+ 0
+ 0
+ 0
+ 0
+ 0
+SET @@sort_buffer_size= @old_sort_buffer_size;
+DROP TABLE t1;
End of 5.0 tests
create table t1(a INT, KEY (a));
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
@@ -4576,4 +4738,47 @@ field2
15:13:38
drop table A,AA,B,BB;
#end of test for bug#45266
+#
+# BUG#48052: Valgrind warning - uninitialized value in init_read_record()
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL,
+i int(11) DEFAULT NULL,
+v varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (2,7,'m');
+INSERT INTO t1 VALUES (3,9,'m');
+SELECT v
+FROM t1
+WHERE NOT pk > 0
+HAVING v <= 't'
+ORDER BY pk;
+v
+DROP TABLE t1;
+#
+# Bug#49489 Uninitialized cache led to a wrong result.
+#
+CREATE TABLE t1(c1 DOUBLE(5,4));
+INSERT INTO t1 VALUES (9.1234);
+SELECT * FROM t1 WHERE c1 < 9.12345;
+c1
+9.1234
+DROP TABLE t1;
+# End of test for bug#49489.
+#
+# Bug #49517: Inconsistent behavior while using
+# NULLable BIGINT and INT columns in comparison
+#
+CREATE TABLE t1(a BIGINT UNSIGNED NOT NULL, b BIGINT NULL, c INT NULL);
+INSERT INTO t1 VALUES(105, NULL, NULL);
+SELECT * FROM t1 WHERE b < 102;
+a b c
+SELECT * FROM t1 WHERE c < 102;
+a b c
+SELECT * FROM t1 WHERE 102 < b;
+a b c
+SELECT * FROM t1 WHERE 102 < c;
+a b c
+DROP TABLE t1;
End of 5.1 tests
=== modified file 'mysql-test/r/show_check.result'
--- a/mysql-test/r/show_check.result 2009-03-06 14:56:17 +0000
+++ b/mysql-test/r/show_check.result 2010-03-04 08:03:07 +0000
@@ -252,13 +252,11 @@ drop table t1;
flush tables;
show open tables;
Database Table In_use Name_locked
-mysql general_log 0 0
create table t1(n int);
insert into t1 values (1);
show open tables;
Database Table In_use Name_locked
test t1 0 0
-mysql general_log 0 0
drop table t1;
create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" ENGINE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
show create table t1;
@@ -1454,4 +1452,10 @@ GRANT PROCESS ON *.* TO test_u@localhost
SHOW ENGINE MYISAM MUTEX;
SHOW ENGINE MYISAM STATUS;
DROP USER test_u@localhost;
+#
+# Bug #48985: show create table crashes if previous access to the table
+# was killed
+#
+SHOW CREATE TABLE non_existent;
+ERROR 70100: Query execution was interrupted
End of 5.1 tests
=== modified file 'mysql-test/r/sp-destruct.result'
--- a/mysql-test/r/sp-destruct.result 2008-04-08 14:51:26 +0000
+++ b/mysql-test/r/sp-destruct.result 2010-02-10 19:06:24 +0000
@@ -1,3 +1,5 @@
+call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted");
+flush table mysql.proc;
use test;
drop procedure if exists bug14233;
drop function if exists bug14233;
@@ -11,11 +13,13 @@ create table t1 (id int);
create trigger t1_ai after insert on t1 for each row call bug14233();
alter table mysql.proc drop type;
call bug14233();
-ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
+ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
create view v1 as select bug14233_f();
-ERROR HY000: Failed to load routine test.bug14233_f. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
+ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
insert into t1 values (0);
-ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
+ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
+show procedure status;
+ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
flush table mysql.proc;
call bug14233();
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
@@ -88,3 +92,28 @@ show procedure status where db=DATABASE(
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
show function status where db=DATABASE();
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
+DROP TABLE IF EXISTS proc_backup;
+DROP PROCEDURE IF EXISTS p1;
+# Backup the proc table
+RENAME TABLE mysql.proc TO proc_backup;
+CREATE TABLE mysql.proc LIKE proc_backup;
+FLUSH TABLE mysql.proc;
+# Test with a valid table.
+CREATE PROCEDURE p1()
+SET @foo = 10;
+CALL p1();
+SHOW PROCEDURE STATUS;
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
+test p1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
+# Modify a field of the table.
+ALTER TABLE mysql.proc MODIFY comment CHAR (32);
+CREATE PROCEDURE p2()
+SET @foo = 10;
+ERROR HY000: Cannot load from mysql.proc. The table is probably corrupted
+# Procedure loaded from the cache
+CALL p1();
+SHOW PROCEDURE STATUS;
+ERROR HY000: Cannot load from mysql.proc. The table is probably corrupted
+DROP TABLE mysql.proc;
+RENAME TABLE proc_backup TO mysql.proc;
+FLUSH TABLE mysql.proc;
=== modified file 'mysql-test/r/sp-security.result'
--- a/mysql-test/r/sp-security.result 2009-03-06 14:56:17 +0000
+++ b/mysql-test/r/sp-security.result 2009-11-27 16:10:28 +0000
@@ -510,4 +510,60 @@ DROP USER mysqltest_u1@localhost;
DROP PROCEDURE p_suid;
DROP FUNCTION f_suid;
DROP TABLE t1;
+#
+# Bug #48872 : Privileges for stored functions ignored if function name
+# is mixed case
+#
+CREATE DATABASE B48872;
+USE B48872;
+CREATE TABLE `TestTab` (id INT);
+INSERT INTO `TestTab` VALUES (1),(2);
+CREATE FUNCTION `f_Test`() RETURNS INT RETURN 123;
+CREATE FUNCTION `f_Test_denied`() RETURNS INT RETURN 123;
+CREATE USER 'tester';
+CREATE USER 'Tester';
+GRANT SELECT ON TABLE `TestTab` TO 'tester';
+GRANT EXECUTE ON FUNCTION `f_Test` TO 'tester';
+GRANT EXECUTE ON FUNCTION `f_Test_denied` TO 'Tester';
+SELECT f_Test();
+f_Test()
+123
+SELECT * FROM TestTab;
+id
+1
+2
+SELECT * FROM TestTab;
+id
+1
+2
+SELECT `f_Test`();
+`f_Test`()
+123
+SELECT `F_TEST`();
+`F_TEST`()
+123
+SELECT f_Test();
+f_Test()
+123
+SELECT F_TEST();
+F_TEST()
+123
+SELECT * FROM TestTab;
+SELECT `f_Test`();
+SELECT `F_TEST`();
+SELECT f_Test();
+SELECT F_TEST();
+SELECT `f_Test_denied`();
+`f_Test_denied`()
+123
+SELECT `F_TEST_DENIED`();
+`F_TEST_DENIED`()
+123
+DROP TABLE `TestTab`;
+DROP FUNCTION `f_Test`;
+DROP FUNCTION `f_Test_denied`;
+USE test;
+DROP USER 'tester';
+DROP USER 'Tester';
+DROP DATABASE B48872;
End of 5.0 tests.
=== modified file 'mysql-test/r/sp-ucs2.result'
--- a/mysql-test/r/sp-ucs2.result 2007-02-19 10:57:06 +0000
+++ b/mysql-test/r/sp-ucs2.result 2009-12-02 11:17:08 +0000
@@ -12,3 +12,29 @@ a
foo string
drop function bug17615|
drop table t3|
+SET NAMES utf8;
+DROP FUNCTION IF EXISTS bug48766;
+CREATE FUNCTION bug48766 ()
+RETURNS ENUM( 'w' ) CHARACTER SET ucs2
+RETURN 0;
+SHOW CREATE FUNCTION bug48766;
+Function sql_mode Create Function character_set_client collation_connection Database Collation
+bug48766 CREATE DEFINER=`root`@`localhost` FUNCTION `bug48766`() RETURNS enum('w') CHARSET ucs2
+RETURN 0 utf8 utf8_general_ci latin1_swedish_ci
+SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_NAME='bug48766';
+DTD_IDENTIFIER
+enum('w') CHARSET ucs2
+DROP FUNCTION bug48766;
+CREATE FUNCTION bug48766 ()
+RETURNS ENUM('а','б','в','г') CHARACTER SET ucs2
+RETURN 0;
+SHOW CREATE FUNCTION bug48766;
+Function sql_mode Create Function character_set_client collation_connection Database Collation
+bug48766 CREATE DEFINER=`root`@`localhost` FUNCTION `bug48766`() RETURNS enum('а','б','в','г') CHARSET ucs2
+RETURN 0 utf8 utf8_general_ci latin1_swedish_ci
+SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_NAME='bug48766';
+DTD_IDENTIFIER
+enum('а','б','в','г') CHARSET ucs2
+DROP FUNCTION bug48766;
=== modified file 'mysql-test/r/sp.result'
--- a/mysql-test/r/sp.result 2009-10-23 13:54:58 +0000
+++ b/mysql-test/r/sp.result 2009-12-23 13:44:03 +0000
@@ -6963,6 +6963,22 @@ CALL p1();
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
+CREATE TABLE t1 ( f1 integer, primary key (f1));
+CREATE TABLE t2 LIKE t1;
+CREATE TEMPORARY TABLE t3 LIKE t1;
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ;
+END|
+CALL p1;
+ERROR HY000: Can't reopen table: 'A'
+CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 );
+DROP TABLE t3;
+CALL p1;
+f1
+CALL p1;
+f1
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
+DROP VIEW t3;
#
# Bug #46629: Item_in_subselect::val_int(): Assertion `0'
# on subquery inside a SP
@@ -6979,6 +6995,64 @@ CALL p1;
ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery'
DROP PROCEDURE p1;
DROP TABLE t1, t2;
+#
+# Bug#47627: SET @@{global.session}.local_variable in stored routine causes crash
+# Bug#48626: Crash or lost connection using SET for declared variables with @@
+#
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SET @@SESSION.v= 10;
+END//
+ERROR HY000: Unknown system variable 'v'
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SET v= 10;
+END//
+call p2()//
+CREATE PROCEDURE p3()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SELECT @@SESSION.v;
+END//
+ERROR HY000: Unknown system variable 'v'
+CREATE PROCEDURE p4()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SET @@GLOBAL.v= 10;
+END//
+ERROR HY000: Unknown system variable 'v'
+CREATE PROCEDURE p5()
+BEGIN
+DECLARE init_connect INT DEFAULT 0;
+SET init_connect= 10;
+SET @@GLOBAL.init_connect= 'SELECT 1';
+SET @@SESSION.IDENTITY= 1;
+SELECT @@SESSION.IDENTITY;
+SELECT @@GLOBAL.init_connect;
+SELECT init_connect;
+END//
+CREATE PROCEDURE p6()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SET @@v= 0;
+END//
+ERROR HY000: Unknown system variable 'v'
+SET @old_init_connect= @@GLOBAL.init_connect;
+CALL p5();
+@@SESSION.IDENTITY
+1
+@@GLOBAL.init_connect
+SELECT 1
+init_connect
+10
+SET @@GLOBAL.init_connect= @old_init_connect;
+DROP PROCEDURE p2;
+DROP PROCEDURE p5;
# ------------------------------------------------------------------
# -- End of 5.1 tests
# ------------------------------------------------------------------
=== modified file 'mysql-test/r/sp_notembedded.result'
--- a/mysql-test/r/sp_notembedded.result 2009-10-13 18:21:42 +0000
+++ b/mysql-test/r/sp_notembedded.result 2010-01-11 13:15:28 +0000
@@ -25,58 +25,6 @@ call bug4902_2()|
show warnings|
Level Code Message
drop procedure bug4902_2|
-drop table if exists t1|
-create table t1 (
-id char(16) not null default '',
-data int not null
-)|
-drop procedure if exists bug3583|
-drop procedure if exists bug3583|
-create procedure bug3583()
-begin
-declare c int;
-select * from t1;
-select count(*) into c from t1;
-select c;
-end|
-insert into t1 values ("x", 3), ("y", 5)|
-set @x = @@query_cache_size|
-set global query_cache_size = 10*1024*1024|
-flush status|
-flush query cache|
-show status like 'Qcache_hits'|
-Variable_name Value
-Qcache_hits 0
-call bug3583()|
-id data
-x 3
-y 5
-c
-2
-show status like 'Qcache_hits'|
-Variable_name Value
-Qcache_hits 0
-call bug3583()|
-id data
-x 3
-y 5
-c
-2
-call bug3583()|
-id data
-x 3
-y 5
-c
-2
-show status like 'Qcache_hits'|
-Variable_name Value
-Qcache_hits 2
-set global query_cache_size = @x|
-flush status|
-flush query cache|
-delete from t1|
-drop procedure bug3583|
-drop table t1|
drop procedure if exists bug6807|
create procedure bug6807()
begin
=== added file 'mysql-test/r/sp_sync.result'
--- a/mysql-test/r/sp_sync.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/sp_sync.result 2010-01-12 14:16:26 +0000
@@ -0,0 +1,23 @@
+Tests of syncronization of stored procedure execution.
+#
+# Bug#48157: crash in Item_field::used_tables
+#
+CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b;
+CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b;
+CREATE PROCEDURE p1()
+BEGIN
+UPDATE t1 JOIN t2 USING( a, b ) SET t1.b = 1, t2.b = 1;
+END|
+LOCK TABLES t1 WRITE, t2 WRITE;
+SET DEBUG_SYNC = 'multi_update_reopen_tables SIGNAL parked WAIT_FOR go';
+CALL p1();
+DROP TABLE t1, t2;
+SET DEBUG_SYNC = 'now WAIT_FOR parked';
+CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b;
+CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b;
+SET DEBUG_SYNC = 'now SIGNAL go';
+# Without the DEBUG_SYNC supplied in the same patch as this test in the
+# code, this test statement will hang.
+DROP TABLE t1, t2;
+DROP PROCEDURE p1;
+SET DEBUG_SYNC = 'RESET';
=== modified file 'mysql-test/r/subselect.result'
--- a/mysql-test/r/subselect.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/r/subselect.result 2010-03-04 08:03:07 +0000
@@ -4410,6 +4410,31 @@ WHERE a = 230;
MAX(b) (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
NULL 0
DROP TABLE t1, st1, st2;
+#
+# Bug #48709: Assertion failed in sql_select.cc:11782:
+# int join_read_key(JOIN_TAB*)
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t1 VALUES (10,1), (14,1);
+CREATE TABLE t2 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3);
+# should have eq_ref for t1
+EXPLAIN
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+id select_type table type possible_keys key key_len ref rows Extra
+x x outr ALL x x x x x x
+x x t1 eq_ref x x x x x x
+x x t2 index x x x x x x
+# should not crash on debug binaries
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+pk int_key
+3 3
+7 3
+DROP TABLE t1,t2;
End of 5.0 tests.
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
@@ -4574,4 +4599,17 @@ SELECT 1 FROM t1 GROUP BY
1
1
DROP TABLE t1;
+#
+# Bug #49512 : subquery with aggregate function crash
+# subselect_single_select_engine::exec()
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+# should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+FROM t1,t1 a
+);
+1
+DROP TABLE t1;
End of 5.1 tests.
=== modified file 'mysql-test/r/table_elim.result'
--- a/mysql-test/r/table_elim.result 2009-09-16 19:05:03 +0000
+++ b/mysql-test/r/table_elim.result 2010-03-06 12:09:02 +0000
@@ -1,4 +1,4 @@
-drop table if exists t0, t1, t2, t3;
+drop table if exists t0, t1, t2, t3, t4, t5, t6;
drop view if exists v1, v2;
create table t1 (a int);
insert into t1 values (0),(1),(2),(3);
@@ -418,3 +418,120 @@ id select_type table type possible_keys
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where
drop table t1, t2;
+#
+# LPBUG#523593: Running RQG optimizer_no_subquery crashes MariaDB
+#
+CREATE TABLE t1 (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_date_key` date DEFAULT NULL,
+`col_date_nokey` date DEFAULT NULL,
+`col_time_key` time DEFAULT NULL,
+`col_time_nokey` time DEFAULT NULL,
+`col_datetime_key` datetime DEFAULT NULL,
+`col_datetime_nokey` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_int_key` (`col_int_key`),
+KEY `col_date_key` (`col_date_key`),
+KEY `col_time_key` (`col_time_key`),
+KEY `col_datetime_key` (`col_datetime_key`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+);
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t1 VALUES
+(10,7,8,NULL,NULL,'01:27:35','01:27:35','2002-02-26 06:14:37','2002-02-26 06:14:37','v','v'),
+(11,1,9,'2006-06-14','2006-06-14','19:48:31','19:48:31','1900-01-01 00:00:00','1900-01-01 00:00:00','r','r');
+INSERT INTO t2 SELECT * FROM t1;
+SELECT table2.col_int_key AS field1
+FROM (
+t2 AS table1
+RIGHT OUTER JOIN
+(
+( t1 AS table2 STRAIGHT_JOIN
+t1 AS table3 ON (
+(table3.col_varchar_nokey = table2.col_varchar_key ) AND
+(table3.pk = table2.col_int_key))
+)
+) ON
+(
+(table3.col_varchar_key = table2.col_varchar_key) OR
+(table3.col_int_key = table2.pk)
+)
+)
+HAVING field1 < 216;
+field1
+DROP TABLE t1, t2;
+#
+# LPBUG#524025 Running RQG outer_join test leads to crash
+#
+CREATE TABLE t0 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t1 (
+col_int int(11) DEFAULT NULL,
+col_int_key int(11) DEFAULT NULL,
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_varchar_10_latin1 varchar(10) DEFAULT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (5,5,1,'t'), (NULL,NULL,2,'y');
+CREATE TABLE t2 (
+col_int int(11) DEFAULT NULL
+);
+INSERT INTO t2 VALUES (8), (4);
+CREATE TABLE t3 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+PRIMARY KEY (pk)
+);
+INSERT INTO t3 VALUES (1),(8);
+CREATE TABLE t4 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_varchar_1024_latin1_key varchar(1024) DEFAULT NULL,
+col_int int(11) DEFAULT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t4 VALUES (1,'o',1), (2,'w',2);
+CREATE TABLE t5 (
+col_varchar_1024_utf8_key varchar(1024) CHARACTER SET utf8 DEFAULT NULL,
+col_varchar_1024_latin1_key varchar(1024) DEFAULT NULL,
+col_varchar_10_utf8_key varchar(1024) CHARACTER SET utf8 DEFAULT NULL,
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t5 VALUES ('k','a','z',1,2),('x','a','w',2,7);
+CREATE TABLE t6 (
+col_int int(11) DEFAULT NULL,
+col_int_key int(11) DEFAULT NULL
+);
+INSERT INTO t6 VALUES (6,1),(8,3);
+SELECT
+table3.col_int AS field1,
+table1.col_int AS field2,
+table1.col_int_key AS field3,
+table1.pk AS field4,
+table1.col_int AS field5,
+table2.col_int AS field6
+FROM
+t1 AS table1
+LEFT OUTER JOIN
+t4 AS table2
+LEFT JOIN t6 AS table3
+RIGHT JOIN t3 AS table4
+LEFT JOIN t5 AS table5 ON table4.pk = table5.pk
+LEFT JOIN t0 AS table6 ON table5.col_int_key = table6.pk
+ON table3.col_int_key = table5.pk
+ON table2.col_varchar_1024_latin1_key = table5.col_varchar_10_utf8_key
+LEFT JOIN t6 AS table7 ON table2.pk = table7.col_int
+ON table1.col_varchar_10_latin1 = table5.col_varchar_1024_latin1_key
+LEFT JOIN t2 AS table8 ON table3.col_int = table8.col_int
+WHERE
+table1.col_int_key < table2.pk
+HAVING
+field4 != 6;
+field1 field2 field3 field4 field5 field6
+drop table t0,t1,t2,t3,t4,t5,t6;
=== modified file 'mysql-test/r/trigger.result'
--- a/mysql-test/r/trigger.result 2009-06-22 12:51:33 +0000
+++ b/mysql-test/r/trigger.result 2010-01-12 08:19:48 +0000
@@ -1448,33 +1448,6 @@ isave
1
2
drop table t1, t2, t3;
-CREATE TABLE t1 (id INTEGER);
-CREATE TABLE t2 (id INTEGER);
-INSERT INTO t2 VALUES (1),(2);
-CREATE TRIGGER t1_test AFTER INSERT ON t1 FOR EACH ROW
-INSERT INTO t2 VALUES (new.id);
-SELECT GET_LOCK('B26162',120);
-GET_LOCK('B26162',120)
-1
-SELECT 'rl_acquirer', GET_LOCK('B26162',120), id FROM t2 WHERE id = 1;
-SET SESSION LOW_PRIORITY_UPDATES=1;
-SET GLOBAL LOW_PRIORITY_UPDATES=1;
-INSERT INTO t1 VALUES (5);
-SELECT 'rl_contender', id FROM t2 WHERE id > 1;
-SELECT RELEASE_LOCK('B26162');
-RELEASE_LOCK('B26162')
-1
-rl_acquirer GET_LOCK('B26162',120) id
-rl_acquirer 1 1
-SELECT RELEASE_LOCK('B26162');
-RELEASE_LOCK('B26162')
-1
-rl_contender id
-rl_contender 2
-DROP TRIGGER t1_test;
-DROP TABLE t1,t2;
-SET SESSION LOW_PRIORITY_UPDATES=DEFAULT;
-SET GLOBAL LOW_PRIORITY_UPDATES=DEFAULT;
Bug#28502 Triggers that update another innodb table will block
on X lock unnecessarily
=== modified file 'mysql-test/r/trigger_notembedded.result'
--- a/mysql-test/r/trigger_notembedded.result 2009-09-17 11:33:23 +0000
+++ b/mysql-test/r/trigger_notembedded.result 2010-01-12 08:19:48 +0000
@@ -445,6 +445,33 @@ DROP TABLE t2;
DROP TABLE t1;
DROP DATABASE mysqltest_db1;
USE test;
+CREATE TABLE t1 (id INTEGER);
+CREATE TABLE t2 (id INTEGER);
+INSERT INTO t2 VALUES (1),(2);
+CREATE TRIGGER t1_test AFTER INSERT ON t1 FOR EACH ROW
+INSERT INTO t2 VALUES (new.id);
+SELECT GET_LOCK('B26162',120);
+GET_LOCK('B26162',120)
+1
+SELECT 'rl_acquirer', GET_LOCK('B26162',120), id FROM t2 WHERE id = 1;
+SET SESSION LOW_PRIORITY_UPDATES=1;
+SET GLOBAL LOW_PRIORITY_UPDATES=1;
+INSERT INTO t1 VALUES (5);
+SELECT 'rl_contender', id FROM t2 WHERE id > 1;
+SELECT RELEASE_LOCK('B26162');
+RELEASE_LOCK('B26162')
+1
+rl_acquirer GET_LOCK('B26162',120) id
+rl_acquirer 1 1
+SELECT RELEASE_LOCK('B26162');
+RELEASE_LOCK('B26162')
+1
+rl_contender id
+rl_contender 2
+DROP TRIGGER t1_test;
+DROP TABLE t1,t2;
+SET SESSION LOW_PRIORITY_UPDATES=DEFAULT;
+SET GLOBAL LOW_PRIORITY_UPDATES=DEFAULT;
End of 5.0 tests.
drop table if exists t1;
create table t1 (i int);
=== modified file 'mysql-test/r/type_newdecimal.result'
--- a/mysql-test/r/type_newdecimal.result 2009-11-02 11:21:39 +0000
+++ b/mysql-test/r/type_newdecimal.result 2009-12-08 09:26:11 +0000
@@ -1630,3 +1630,287 @@ SELECT my_col FROM t1;
my_col
0.012345687012345687012345687012
DROP TABLE t1;
+#
+# Bug#45261: Crash, stored procedure + decimal
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 SELECT
+/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
+AS c1;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,0) NO 0
+SELECT * FROM t1;
+c1
+99999999999999999999999999999999999999999999999999999999999999999
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
+AS c1;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,0) NO 0
+SELECT * FROM t1;
+c1
+99999999999999999999999999999999999999999999999999999999999999999
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
+AS c1;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,0) NO 0
+SELECT * FROM t1;
+c1
+99999999999999999999999999999999999999999999999999999999999999999
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
+AS c1;
+Warnings:
+Error 1292 Truncated incorrect DECIMAL value: ''
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,0) NO 0
+SELECT * FROM t1;
+c1
+99999999999999999999999999999999999999999999999999999999999999999
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
+AS c1;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,30) NO 0.000000000000000000000000000000
+SELECT * FROM t1;
+c1
+99999999999999999999999999999999999.999999999999999999999999999999
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
+AS c1;
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(31,30) NO 0.000000000000000000000000000000
+SELECT * FROM t1;
+c1
+1.100000000000000000000000000000
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
+AS c1;
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(31,30) NO 0.000000000000000000000000000000
+SELECT * FROM t1;
+c1
+1.100000000000000000000000000000
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
+AS c1;
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(30,30) NO 0.000000000000000000000000000000
+SELECT * FROM t1;
+c1
+0.100000000000000000000000000000
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
+AS c1;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,30) NO 0.000000000000000000000000000000
+SELECT * FROM t1;
+c1
+99999999999999999999999999999999999.999999999999999999999999999999
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
+AS c1;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,1) NO 0.0
+SELECT * FROM t1;
+c1
+9999999999999999999999999999999999999999999999999999999999999999.9
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
+AS c1;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,1) NO 0.0
+SELECT * FROM t1;
+c1
+9999999999999999999999999999999999999999999999999999999999999999.9
+DROP TABLE t1;
+CREATE TABLE t1 SELECT
+.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
+AS c1;
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(30,30) NO 0.000000000000000000000000000000
+SELECT * FROM t1;
+c1
+0.123456789012345678901234567890
+DROP TABLE t1;
+CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(33,30) NO 0.000000000000000000000000000000
+SELECT * FROM t1;
+c1
+123.123456789012345678901234567890
+DROP TABLE t1;
+CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,30) NO 0.000000000000000000000000000000
+SELECT * FROM t1;
+c1
+2.100000000000000000000000000000
+DROP TABLE t1;
+#
+# Test that the integer and decimal parts are properly calculated.
+#
+CREATE TABLE t1 (a DECIMAL(30,30));
+INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
+CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 3
+DESC t2;
+Field Type Null Key Default Extra
+c1 decimal(32,30) YES NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DECIMAL(30,30));
+INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
+CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c1' at row 2
+Note 1265 Data truncated for column 'c1' at row 3
+DESC t2;
+Field Type Null Key Default Extra
+c1 decimal(34,0) YES NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DECIMAL(30,30));
+INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
+CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+DESC t2;
+Field Type Null Key Default Extra
+c1 decimal(65,30) YES NULL
+DROP TABLE t1,t2;
+#
+# Test that variables get maximum precision.
+#
+SET @decimal= 1.1;
+CREATE TABLE t1 SELECT @decimal AS c1;
+DESC t1;
+Field Type Null Key Default Extra
+c1 decimal(65,30) YES NULL
+SELECT * FROM t1;
+c1
+1.100000000000000000000000000000
+DROP TABLE t1;
+#
+# Bug #45261 : Crash, stored procedure + decimal
+# Original test by the reporter.
+#
+# should not crash
+CREATE TABLE t1
+SELECT .123456789012345678901234567890123456789012345678901234567890123456 AS a;
+Warnings:
+Note 1265 Data truncated for column 'a' at row 1
+DROP TABLE t1;
+CREATE PROCEDURE test_proc()
+BEGIN
+# The las non critical CUSER definition is:
+# DECLARE mycursor CURSOR FOR SELECT 1 %
+# .12345678912345678912345678912345678912345678912345678912345678912 AS my_col;
+DECLARE mycursor CURSOR FOR
+SELECT 1 %
+.123456789123456789123456789123456789123456789123456789123456789123456789123456789
+AS my_col;
+OPEN mycursor;
+CLOSE mycursor;
+END|
+# should not crash
+CALL test_proc();
+DROP PROCEDURE test_proc;
+#
+# Bug #48370 Absolutely wrong calculations with GROUP BY and
+# decimal fields when using IF
+#
+CREATE TABLE currencies (id int, rate decimal(16,4),
+PRIMARY KEY (id), KEY (rate));
+INSERT INTO currencies VALUES (11,0.7028);
+INSERT INTO currencies VALUES (1,1);
+CREATE TABLE payments (
+id int,
+supplier_id int,
+status int,
+currency_id int,
+vat decimal(7,4),
+PRIMARY KEY (id),
+KEY currency_id (currency_id),
+KEY supplier_id (supplier_id)
+);
+INSERT INTO payments (id,status,vat,supplier_id,currency_id) VALUES
+(3001,2,0.0000,344,11), (1,2,0.0000,1,1);
+CREATE TABLE sub_tasks (
+id int,
+currency_id int,
+price decimal(16,4),
+discount decimal(10,4),
+payment_id int,
+PRIMARY KEY (id),
+KEY currency_id (currency_id),
+KEY payment_id (payment_id)
+) ;
+INSERT INTO sub_tasks (id, price, discount, payment_id, currency_id) VALUES
+(52, 12.60, 0, 3001, 11), (56, 14.58, 0, 3001, 11);
+# should return 1 and the same values in col 2 and 3
+select STRAIGHT_JOIN
+(1 + PAY.vat) AS mult,
+SUM(ROUND((SUB.price - ROUND(ROUND(SUB.price, 2) * SUB.discount, 2)) *
+CUR.rate / CUR.rate, 2)
+) v_net_with_discount,
+SUM(ROUND((SUB.price - ROUND(ROUND(SUB.price, 2) * SUB.discount, 1)) *
+CUR.rate / CUR.rate , 2)
+* (1 + PAY.vat)
+) v_total
+from
+currencies CUR, payments PAY, sub_tasks SUB
+where
+SUB.payment_id = PAY.id and
+PAY.currency_id = CUR.id and
+PAY.id > 2
+group by PAY.id + 1;
+mult v_net_with_discount v_total
+1.0000 27.18 27.180000
+DROP TABLE currencies, payments, sub_tasks;
+End of 5.1 tests
=== modified file 'mysql-test/r/type_year.result'
--- a/mysql-test/r/type_year.result 2007-03-29 04:08:30 +0000
+++ b/mysql-test/r/type_year.result 2010-01-13 10:28:42 +0000
@@ -46,3 +46,267 @@ a
2001
drop table t1;
End of 5.0 tests
+#
+# Bug #49480: WHERE using YEAR columns returns unexpected results
+#
+CREATE TABLE t2(yy YEAR(2), c2 CHAR(4));
+CREATE TABLE t4(yyyy YEAR(4), c4 CHAR(4));
+INSERT INTO t2 (c2) VALUES (NULL),(1970),(1999),(2000),(2001),(2069);
+INSERT INTO t4 (c4) SELECT c2 FROM t2;
+UPDATE t2 SET yy = c2;
+UPDATE t4 SET yyyy = c4;
+SELECT * FROM t2;
+yy c2
+NULL NULL
+70 1970
+99 1999
+00 2000
+01 2001
+69 2069
+SELECT * FROM t4;
+yyyy c4
+NULL NULL
+1970 1970
+1999 1999
+2000 2000
+2001 2001
+2069 2069
+# Comparison of YEAR(2) with YEAR(4)
+SELECT * FROM t2, t4 WHERE yy = yyyy;
+yy c2 yyyy c4
+70 1970 1970 1970
+99 1999 1999 1999
+00 2000 2000 2000
+01 2001 2001 2001
+69 2069 2069 2069
+SELECT * FROM t2, t4 WHERE yy <=> yyyy;
+yy c2 yyyy c4
+NULL NULL NULL NULL
+70 1970 1970 1970
+99 1999 1999 1999
+00 2000 2000 2000
+01 2001 2001 2001
+69 2069 2069 2069
+SELECT * FROM t2, t4 WHERE yy < yyyy;
+yy c2 yyyy c4
+70 1970 1999 1999
+70 1970 2000 2000
+99 1999 2000 2000
+70 1970 2001 2001
+99 1999 2001 2001
+00 2000 2001 2001
+70 1970 2069 2069
+99 1999 2069 2069
+00 2000 2069 2069
+01 2001 2069 2069
+SELECT * FROM t2, t4 WHERE yy > yyyy;
+yy c2 yyyy c4
+99 1999 1970 1970
+00 2000 1970 1970
+01 2001 1970 1970
+69 2069 1970 1970
+00 2000 1999 1999
+01 2001 1999 1999
+69 2069 1999 1999
+01 2001 2000 2000
+69 2069 2000 2000
+69 2069 2001 2001
+# Comparison of YEAR(2) with YEAR(2)
+SELECT * FROM t2 a, t2 b WHERE a.yy = b.yy;
+yy c2 yy c2
+70 1970 70 1970
+99 1999 99 1999
+00 2000 00 2000
+01 2001 01 2001
+69 2069 69 2069
+SELECT * FROM t2 a, t2 b WHERE a.yy <=> b.yy;
+yy c2 yy c2
+NULL NULL NULL NULL
+70 1970 70 1970
+99 1999 99 1999
+00 2000 00 2000
+01 2001 01 2001
+69 2069 69 2069
+SELECT * FROM t2 a, t2 b WHERE a.yy < b.yy;
+yy c2 yy c2
+70 1970 99 1999
+70 1970 00 2000
+99 1999 00 2000
+70 1970 01 2001
+99 1999 01 2001
+00 2000 01 2001
+70 1970 69 2069
+99 1999 69 2069
+00 2000 69 2069
+01 2001 69 2069
+# Comparison of YEAR(4) with YEAR(4)
+SELECT * FROM t4 a, t4 b WHERE a.yyyy = b.yyyy;
+yyyy c4 yyyy c4
+1970 1970 1970 1970
+1999 1999 1999 1999
+2000 2000 2000 2000
+2001 2001 2001 2001
+2069 2069 2069 2069
+SELECT * FROM t4 a, t4 b WHERE a.yyyy <=> b.yyyy;
+yyyy c4 yyyy c4
+NULL NULL NULL NULL
+1970 1970 1970 1970
+1999 1999 1999 1999
+2000 2000 2000 2000
+2001 2001 2001 2001
+2069 2069 2069 2069
+SELECT * FROM t4 a, t4 b WHERE a.yyyy < b.yyyy;
+yyyy c4 yyyy c4
+1970 1970 1999 1999
+1970 1970 2000 2000
+1999 1999 2000 2000
+1970 1970 2001 2001
+1999 1999 2001 2001
+2000 2000 2001 2001
+1970 1970 2069 2069
+1999 1999 2069 2069
+2000 2000 2069 2069
+2001 2001 2069 2069
+# Comparison with constants:
+SELECT * FROM t2 WHERE yy = NULL;
+yy c2
+SELECT * FROM t4 WHERE yyyy = NULL;
+yyyy c4
+SELECT * FROM t2 WHERE yy <=> NULL;
+yy c2
+NULL NULL
+SELECT * FROM t4 WHERE yyyy <=> NULL;
+yyyy c4
+NULL NULL
+SELECT * FROM t2 WHERE yy < NULL;
+yy c2
+SELECT * FROM t2 WHERE yy > NULL;
+yy c2
+SELECT * FROM t2 WHERE yy = NOW();
+yy c2
+SELECT * FROM t4 WHERE yyyy = NOW();
+yyyy c4
+SELECT * FROM t2 WHERE yy = 99;
+yy c2
+99 1999
+SELECT * FROM t2 WHERE 99 = yy;
+yy c2
+99 1999
+SELECT * FROM t4 WHERE yyyy = 99;
+yyyy c4
+1999 1999
+SELECT * FROM t2 WHERE yy = 'test';
+yy c2
+00 2000
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'test'
+SELECT * FROM t4 WHERE yyyy = 'test';
+yyyy c4
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'test'
+SELECT * FROM t2 WHERE yy = '1999';
+yy c2
+99 1999
+SELECT * FROM t4 WHERE yyyy = '1999';
+yyyy c4
+1999 1999
+SELECT * FROM t2 WHERE yy = 1999;
+yy c2
+99 1999
+SELECT * FROM t4 WHERE yyyy = 1999;
+yyyy c4
+1999 1999
+SELECT * FROM t2 WHERE yy = 1999.1;
+yy c2
+99 1999
+SELECT * FROM t4 WHERE yyyy = 1999.1;
+yyyy c4
+1999 1999
+SELECT * FROM t2 WHERE yy = 1998.9;
+yy c2
+99 1999
+SELECT * FROM t4 WHERE yyyy = 1998.9;
+yyyy c4
+1999 1999
+# Coverage tests for YEAR with zero/2000 constants:
+SELECT * FROM t2 WHERE yy = 0;
+yy c2
+00 2000
+SELECT * FROM t2 WHERE yy = '0';
+yy c2
+00 2000
+SELECT * FROM t2 WHERE yy = '0000';
+yy c2
+00 2000
+SELECT * FROM t2 WHERE yy = '2000';
+yy c2
+00 2000
+SELECT * FROM t2 WHERE yy = 2000;
+yy c2
+00 2000
+SELECT * FROM t4 WHERE yyyy = 0;
+yyyy c4
+SELECT * FROM t4 WHERE yyyy = '0';
+yyyy c4
+2000 2000
+SELECT * FROM t4 WHERE yyyy = '0000';
+yyyy c4
+SELECT * FROM t4 WHERE yyyy = '2000';
+yyyy c4
+2000 2000
+SELECT * FROM t4 WHERE yyyy = 2000;
+yyyy c4
+2000 2000
+# Comparison with constants those are out of YEAR range
+# (coverage test for backward compatibility)
+SELECT COUNT(yy) FROM t2;
+COUNT(yy)
+5
+SELECT COUNT(yyyy) FROM t4;
+COUNT(yyyy)
+5
+SELECT COUNT(*) FROM t2 WHERE yy = -1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t4 WHERE yyyy > -1;
+COUNT(*)
+5
+SELECT COUNT(*) FROM t2 WHERE yy > -1000000000000000000;
+COUNT(*)
+5
+SELECT COUNT(*) FROM t4 WHERE yyyy > -1000000000000000000;
+COUNT(*)
+5
+SELECT COUNT(*) FROM t2 WHERE yy < 2156;
+COUNT(*)
+5
+SELECT COUNT(*) FROM t4 WHERE yyyy < 2156;
+COUNT(*)
+5
+SELECT COUNT(*) FROM t2 WHERE yy < 1000000000000000000;
+COUNT(*)
+5
+SELECT COUNT(*) FROM t4 WHERE yyyy < 1000000000000000000;
+COUNT(*)
+5
+SELECT * FROM t2 WHERE yy < 123;
+yy c2
+70 1970
+99 1999
+00 2000
+01 2001
+69 2069
+SELECT * FROM t2 WHERE yy > 123;
+yy c2
+SELECT * FROM t4 WHERE yyyy < 123;
+yyyy c4
+SELECT * FROM t4 WHERE yyyy > 123;
+yyyy c4
+1970 1970
+1999 1999
+2000 2000
+2001 2001
+2069 2069
+DROP TABLE t2, t4;
+#
+End of 5.1 tests
=== modified file 'mysql-test/r/udf.result'
--- a/mysql-test/r/udf.result 2009-09-07 09:57:22 +0000
+++ b/mysql-test/r/udf.result 2010-01-22 21:19:21 +0000
@@ -38,8 +38,6 @@ ERROR HY000: Can't initialize function '
select reverse_lookup("127.0.0.1");
select reverse_lookup(127,0,0,1);
select reverse_lookup("localhost");
-reverse_lookup("localhost")
-NULL
select avgcost();
ERROR HY000: Can't initialize function 'avgcost'; wrong number of arguments: AVGCOST() requires two arguments
select avgcost(100,23.76);
@@ -311,29 +309,6 @@ drop function f3;
drop function metaphon;
drop function myfunc_double;
drop function myfunc_int;
-CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
-create table t1 (a char);
-set GLOBAL query_cache_size=1355776;
-reset query cache;
-select metaphon('MySQL') from t1;
-metaphon('MySQL')
-show status like "Qcache_hits";
-Variable_name Value
-Qcache_hits 0
-show status like "Qcache_queries_in_cache";
-Variable_name Value
-Qcache_queries_in_cache 0
-select metaphon('MySQL') from t1;
-metaphon('MySQL')
-show status like "Qcache_hits";
-Variable_name Value
-Qcache_hits 0
-show status like "Qcache_queries_in_cache";
-Variable_name Value
-Qcache_queries_in_cache 0
-drop table t1;
-drop function metaphon;
-set GLOBAL query_cache_size=default;
DROP DATABASE IF EXISTS mysqltest;
CREATE DATABASE mysqltest;
USE mysqltest;
=== added file 'mysql-test/r/udf_query_cache.result'
--- a/mysql-test/r/udf_query_cache.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/udf_query_cache.result 2010-01-11 13:15:28 +0000
@@ -0,0 +1,24 @@
+drop table if exists t1;
+CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
+create table t1 (a char);
+set GLOBAL query_cache_size=1355776;
+reset query cache;
+select metaphon('MySQL') from t1;
+metaphon('MySQL')
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select metaphon('MySQL') from t1;
+metaphon('MySQL')
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+drop function metaphon;
+set GLOBAL query_cache_size=default;
=== modified file 'mysql-test/r/union.result'
--- a/mysql-test/r/union.result 2009-09-15 10:46:35 +0000
+++ b/mysql-test/r/union.result 2010-03-04 08:03:07 +0000
@@ -1588,3 +1588,63 @@ Warnings:
Note 1003 select '0' AS `a` from `test`.`t1` union select '0' AS `a` from `test`.`t1` order by `a`
DROP TABLE t1;
End of 5.0 tests
+#
+# Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY
+# <any non-const-function>
+#
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+# Should not crash
+EXPLAIN EXTENDED
+SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 UNION t1 ALL NULL NULL NULL NULL 2 100.00
+NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (`a` + 12)
+# Should not crash
+SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12;
+a
+1
+2
+# Should not crash
+EXPLAIN EXTENDED
+SELECT * FROM t1 UNION SELECT * FROM t1
+ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
+ERROR 42000: Incorrect usage/placement of 'MATCH()'
+# Should not crash
+SELECT * FROM t1 UNION SELECT * FROM t1
+ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
+ERROR 42000: Incorrect usage/placement of 'MATCH()'
+# Should not crash
+(SELECT * FROM t1) UNION (SELECT * FROM t1)
+ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
+a
+1
+2
+# Should not crash
+EXPLAIN EXTENDED
+SELECT * FROM t1 UNION SELECT * FROM t1
+ORDER BY (SELECT a FROM t2 WHERE b = 12);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 UNION t1 ALL NULL NULL NULL NULL 2 100.00
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (select `test`.`t1`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`b` = 12))
+# Should not crash
+SELECT * FROM t1 UNION SELECT * FROM t1
+ORDER BY (SELECT a FROM t2 WHERE b = 12);
+# Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+b
+1
+2
+DROP TABLE t1,t2;
+End of 5.1 tests
=== modified file 'mysql-test/r/user_var.result'
--- a/mysql-test/r/user_var.result 2009-05-15 13:03:22 +0000
+++ b/mysql-test/r/user_var.result 2009-12-22 10:38:33 +0000
@@ -409,6 +409,21 @@ SELECT a, b FROM t1 WHERE a=2 AND b=3 GR
a b
2 3
DROP TABLE t1;
+CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL);
+CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11));
+CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL);
+INSERT INTO t1 VALUES(10, 10);
+INSERT INTO t1 VALUES(10, 10);
+INSERT INTO t2 VALUES(10, 10, 10);
+INSERT INTO t2 VALUES(10, 10, 10);
+INSERT INTO t3 VALUES(10, 10);
+INSERT INTO t3 VALUES(10, 10);
+SELECT MIN(t2.f1),
+@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo)
+FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1;
+MIN(t2.f1) @bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo)
+10 NULL
+DROP TABLE t1, t2, t3;
End of 5.0 tests
CREATE TABLE t1 (i INT);
CREATE TRIGGER t_after_insert AFTER INSERT ON t1 FOR EACH ROW SET @bug42188 = 10;
=== modified file 'mysql-test/r/variables.result'
--- a/mysql-test/r/variables.result 2009-09-15 10:46:35 +0000
+++ b/mysql-test/r/variables.result 2010-03-10 09:12:23 +0000
@@ -19,8 +19,6 @@ set @my_myisam_max_sort_file_size =@@glo
set @my_net_buffer_length =@@global.net_buffer_length;
set @my_net_write_timeout =@@global.net_write_timeout;
set @my_net_read_timeout =@@global.net_read_timeout;
-set @my_query_cache_limit =@@global.query_cache_limit;
-set @my_query_cache_type =@@global.query_cache_type;
set @my_rpl_recovery_rank =@@global.rpl_recovery_rank;
set @my_server_id =@@global.server_id;
set @my_slow_launch_time =@@global.slow_launch_time;
@@ -215,7 +213,6 @@ storage_engine MRG_MYISAM
select * from information_schema.global_variables where variable_name like 'storage_engine';
VARIABLE_NAME VARIABLE_VALUE
STORAGE_ENGINE MRG_MYISAM
-set GLOBAL query_cache_size=100000;
set GLOBAL myisam_max_sort_file_size=2000000;
show global variables like 'myisam_max_sort_file_size';
Variable_name Value
@@ -423,8 +420,6 @@ ERROR 42000: Variable 'big_tables' can't
show local variables like 'storage_engine';
Variable_name Value
storage_engine MEMORY
-set SESSION query_cache_size=10000;
-ERROR HY000: Variable 'query_cache_size' is a GLOBAL variable and should be set with SET GLOBAL
set GLOBAL storage_engine=DEFAULT;
ERROR 42000: Variable 'storage_engine' doesn't have a default value
set character_set_client=UNKNOWN_CHARACTER_SET;
@@ -529,9 +524,6 @@ Warnings:
Warning 1292 Truncated incorrect net_buffer_length value: '100'
set net_read_timeout=100;
set net_write_timeout=100;
-set global query_cache_limit=100;
-set global query_cache_size=100;
-set global query_cache_type=demand;
set read_buffer_size=100;
Warnings:
Warning 1292 Truncated incorrect read_buffer_size value: '100'
@@ -567,7 +559,7 @@ set sql_log_bin=1;
set sql_log_off=1;
set sql_log_update=1;
Warnings:
-Note 1315 The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored
+Note 1315 The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored. This option will be removed in MySQL 5.6.
set sql_low_priority_updates=1;
set sql_max_join_size=200;
select @@sql_max_join_size,@@max_join_size;
@@ -583,8 +575,6 @@ set storage_engine=myisam;
set global thread_cache_size=100;
set timestamp=1, timestamp=default;
set tmp_table_size=100;
-Warnings:
-Warning 1292 Truncated incorrect tmp_table_size value: '100'
set tx_isolation="READ-COMMITTED";
set wait_timeout=100;
set log_warnings=1;
@@ -1019,6 +1009,12 @@ ERROR HY000: Variable 'hostname' is a re
show variables like 'hostname';
Variable_name Value
hostname #
+#
+# BUG#37408 - Compressed MyISAM files should not require/use mmap()
+#
+# Test 'myisam_mmap_size' option is not dynamic
+SET @@myisam_mmap_size= 500M;
+ERROR HY000: Variable 'myisam_mmap_size' is a read only variable
End of 5.0 tests
set join_buffer_size=1;
Warnings:
@@ -1047,8 +1043,6 @@ set global myisam_max_sort_file_size =@m
set global net_buffer_length =@my_net_buffer_length;
set global net_write_timeout =@my_net_write_timeout;
set global net_read_timeout =@my_net_read_timeout;
-set global query_cache_limit =@my_query_cache_limit;
-set global query_cache_type =@my_query_cache_type;
set global rpl_recovery_rank =@my_rpl_recovery_rank;
set global server_id =@my_server_id;
set global slow_launch_time =@my_slow_launch_time;
@@ -1271,12 +1265,12 @@ ERROR HY000: Variable 'lower_case_table_
#
SHOW VARIABLES like 'myisam_recover_options';
Variable_name Value
-myisam_recover_options OFF
+myisam_recover_options DEFAULT
SELECT @@session.myisam_recover_options;
ERROR HY000: Variable 'myisam_recover_options' is a GLOBAL variable
SELECT @@global.myisam_recover_options;
@@global.myisam_recover_options
-OFF
+DEFAULT
SET @@session.myisam_recover_options= 'x';
ERROR HY000: Variable 'myisam_recover_options' is a read only variable
SET @@global.myisam_recover_options= 'x';
=== modified file 'mysql-test/r/view.result'
--- a/mysql-test/r/view.result 2009-10-15 21:38:29 +0000
+++ b/mysql-test/r/view.result 2010-02-10 19:06:24 +0000
@@ -155,13 +155,13 @@ v5 VIEW
v6 VIEW
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MyISAM 10 Fixed 5 9 45 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
-v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW
-v2 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW
-v3 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW
-v4 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW
-v5 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW
-v6 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL VIEW
+t1 MyISAM 10 Fixed 5 9 45 # 1024 0 NULL # # # latin1_swedish_ci NULL
+v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
+v2 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
+v3 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
+v4 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
+v5 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
+v6 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
drop view v1,v2,v3,v4,v5,v6;
create view v1 (c,d,e,f) as select a,b,
a in (select a+2 from t1), a = all (select a from t1) from t1;
=== modified file 'mysql-test/std_data/Index.xml'
--- a/mysql-test/std_data/Index.xml 2009-10-12 07:43:15 +0000
+++ b/mysql-test/std_data/Index.xml 2009-12-15 09:48:29 +0000
@@ -8,6 +8,13 @@
</rules>
</collation>
+ <collation name="utf8_hugeid_ci" id="2047000000">
+ <rules>
+ <reset>a</reset>
+ <s>b</s>
+ </rules>
+ </collation>
+
</charset>
<charset name="ucs2">
=== added file 'mysql-test/std_data/bug47012.ARM'
Binary files a/mysql-test/std_data/bug47012.ARM 1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/bug47012.ARM 2009-11-11 08:03:29 +0000 differ
=== added file 'mysql-test/std_data/bug47012.ARZ'
Binary files a/mysql-test/std_data/bug47012.ARZ 1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/bug47012.ARZ 2009-11-11 08:03:29 +0000 differ
=== added file 'mysql-test/std_data/bug47012.frm'
Binary files a/mysql-test/std_data/bug47012.frm 1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/bug47012.frm 2009-11-11 08:03:29 +0000 differ
=== added file 'mysql-test/std_data/bug47142_master-bin.000001'
Binary files a/mysql-test/std_data/bug47142_master-bin.000001 1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/bug47142_master-bin.000001 2010-01-25 15:46:48 +0000 differ
=== modified file 'mysql-test/std_data/cacert.pem'
--- a/mysql-test/std_data/cacert.pem 2009-06-11 16:21:32 +0000
+++ b/mysql-test/std_data/cacert.pem 2010-03-04 08:03:07 +0000
@@ -1,17 +1,17 @@
-----BEGIN CERTIFICATE-----
-MIICrTCCAhagAwIBAgIJAJXpePU0UOTVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+MIICrTCCAhagAwIBAgIJAMI7xZKjhrDbMA0GCSqGSIb3DQEBBAUAMEQxCzAJBgNV
BAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYD
-VQQKEwhNeVNRTCBBQjAeFw0wOTAxMjgxMDQ5NDZaFw0xNDAxMjcxMDQ5NDZaMEQx
+VQQKEwhNeVNRTCBBQjAeFw0xMDAxMjkxMTQ3MTBaFw0xNTAxMjgxMTQ3MTBaMEQx
CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxh
MREwDwYDVQQKEwhNeVNRTCBBQjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
-4XQHAe5R1+TXC8noZtWf+d5E0v1C59FWpn9SWEUCBjE5UiIwuJvi4Y+7xWGOXLAI
-/JzJx5gNXLBiTsE/zh0uX9fKlajLhxB0GN+QU0ZlpQ1BeYipEcNXeI/7cT499f6v
-XWabnTflivdCgHSWUOQ20/Lzs6kP6/e6OoZd/DPSjPECAwEAAaOBpjCBozAdBgNV
-HQ4EFgQU8uLqVWWkmuKsnZf1RWz294wRrd8wdAYDVR0jBG0wa4AU8uLqVWWkmuKs
-nZf1RWz294wRrd+hSKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxh
-MRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAJXpePU0UOTV
-MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAMMTE5sDN+Z0ZlV7KvH3g
-6+aKvql8dTpRT3hYukeQlWua0nq74WPGVw0c4e/M/vbiMwmJcCYpB9pd4+dHqzSw
-aPyoenjY6UF8n7B4quWy3SIUk2LSHeJLW+kzJn2afN9gvipFhdVh/uU2TIyLGOur
-Z/vmJX2W7hF1uqPnbfa8Lrw=
+wQYsOEfrN4ESP3FjsI8cghE+tZVuyK2gck61lwieVxjgFMtBd65mI5a1y9pmlOI1
+yM4SB2Ppqcuw7/e1CdV1y7lvHrGNt5yqEHbN4QX1gvsN8TQauP/2WILturk4R4Hq
+rKg0ZySu7f1Xhl0ed9a48LpaEHD17IcxWEGMMJwAxF0CAwEAAaOBpjCBozAMBgNV
+HRMEBTADAQH/MB0GA1UdDgQWBBSvktYQ0ahLnyxyVKqty+WpBbBrDTB0BgNVHSME
+bTBrgBSvktYQ0ahLnyxyVKqty+WpBbBrDaFIpEYwRDELMAkGA1UEBhMCU0UxEDAO
+BgNVBAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FM
+IEFCggkAwjvFkqOGsNswDQYJKoZIhvcNAQEEBQADgYEAdKN1PjwMHAKG2Ww1145g
+JQGBnKxSFOUaoSvkBi/4ntTM+ysnViWh7WvxyWjR9zU9arfr7aqsDeQxm0XDOqzj
+AQ/cQIla2/Li8tXyfc06bisH/IHRaSc2zWqioTKbEwMdVOdrvq4a8V8ic3xYyIWn
+7F4WeS07J8LKardSvM0+hOA=
-----END CERTIFICATE-----
=== modified file 'mysql-test/std_data/client-cert.pem'
--- a/mysql-test/std_data/client-cert.pem 2009-06-11 16:21:32 +0000
+++ b/mysql-test/std_data/client-cert.pem 2010-03-04 08:03:07 +0000
@@ -1,55 +1,46 @@
Certificate:
Data:
- Version: 3 (0x2)
- Serial Number: 3 (0x3)
- Signature Algorithm: sha1WithRSAEncryption
+ Version: 1 (0x0)
+ Serial Number: 1048577 (0x100001)
+ Signature Algorithm: md5WithRSAEncryption
Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB
Validity
- Not Before: Jan 28 11:04:39 2009 GMT
- Not After : Jan 28 11:04:39 2010 GMT
- Subject: C=SE, ST=Uppsala, O=MySQL AB/emailAddress=abstract.mysql.developer(a)mysql.com
+ Not Before: Jan 29 11:50:22 2010 GMT
+ Not After : Jan 28 11:50:22 2015 GMT
+ Subject: C=SE, ST=Uppsala, O=MySQL AB
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (512 bit)
- Modulus (512 bit):
- 00:e1:52:30:2c:d9:be:64:28:91:5d:7a:fd:d9:e9:
- 14:35:7a:d2:94:4e:91:46:e0:db:9f:6b:79:f4:4c:
- ac:6e:07:61:34:86:74:62:a7:a8:44:af:fa:87:87:
- a8:7d:42:61:ff:ab:50:d4:7b:bf:75:fa:d5:d5:b3:
- 74:fb:56:1e:37
+ Public-Key: (1024 bit)
+ Modulus:
+ 00:cc:9a:37:49:13:66:dc:cf:e3:0b:13:a1:23:ed:
+ 78:db:4e:bd:11:f6:8c:0d:76:f9:a3:32:56:9a:f8:
+ a1:21:6a:55:4e:4d:3f:e6:67:9d:26:99:b2:cd:a4:
+ 9a:d2:2b:59:5c:d7:8a:d3:60:68:f8:18:bd:c5:be:
+ 15:e1:2a:3c:a3:d4:61:cb:f5:11:94:17:81:81:f7:
+ 87:8c:f6:6a:d2:ee:d8:e6:77:f6:62:66:4d:2e:16:
+ 8d:08:81:4a:c9:c6:4b:31:e5:b9:c7:8a:84:96:48:
+ a7:47:8c:0d:26:90:56:4e:e6:a5:6e:8c:b3:f2:9f:
+ fc:3d:78:9b:49:6e:86:83:77
Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- X509v3 Subject Key Identifier:
- 58:30:B5:9B:2C:05:94:06:BA:3D:3C:F0:B2:CD:1D:67:65:E3:7F:85
- X509v3 Authority Key Identifier:
- keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF
- DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB
- serial:95:E9:78:F5:34:50:E4:D5
-
- Signature Algorithm: sha1WithRSAEncryption
- 05:19:e3:13:14:fc:c5:28:bf:69:f8:00:b3:25:cb:bd:ca:9f:
- 2f:4c:b3:a8:04:11:f0:74:27:bd:82:2c:b4:49:9b:a7:59:f0:
- f7:87:d1:e0:ba:99:a2:fe:4b:1d:10:6f:e4:a2:b3:cd:7f:8b:
- 68:31:46:ee:cd:9e:e2:47:e1:4c:fa:74:d1:e2:8b:cc:a0:4b:
- a8:24:d1:a4:c3:6b:2a:c6:28:cd:41:e0:06:48:e6:cf:f2:3c:
- ca:37:95:d7:29:64:6b:91:91:83:e7:ac:c8:0b:87:bc:da:a6:
- aa:f1:44:43:c8:74:7b:15:26:91:2e:03:c4:71:50:6c:f8:68:
- dc:8c
+ Signature Algorithm: md5WithRSAEncryption
+ 5e:1f:a3:53:5f:24:13:1c:f8:28:32:b0:7f:69:69:f3:0e:c0:
+ 34:87:10:03:7d:da:15:8b:bd:19:b8:1a:56:31:e7:85:49:81:
+ c9:7f:45:20:74:3e:89:c0:e0:26:84:51:cc:04:16:ce:69:99:
+ 01:e1:26:99:b3:e3:f5:bd:ec:5f:a0:84:e4:38:da:75:78:7b:
+ 89:9c:d2:cd:60:95:20:ba:8e:e3:7c:e6:df:76:3a:7c:89:77:
+ 02:94:86:11:3a:c4:61:7d:6f:71:83:21:8a:17:fb:17:e2:ee:
+ 02:6b:61:c1:b4:52:63:d7:d8:46:b2:c5:9c:6f:38:91:8a:35:
+ 32:0b
-----BEGIN CERTIFICATE-----
-MIICfzCCAeigAwIBAgIBAzANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ
-MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT
-UUwgQUIwHhcNMDkwMTI4MTEwNDM5WhcNMTAwMTI4MTEwNDM5WjBlMQswCQYDVQQG
-EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxMTAvBgkq
-hkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wXDAN
-BgkqhkiG9w0BAQEFAANLADBIAkEA4VIwLNm+ZCiRXXr92ekUNXrSlE6RRuDbn2t5
-9EysbgdhNIZ0YqeoRK/6h4eofUJh/6tQ1Hu/dfrV1bN0+1YeNwIDAQABo4GjMIGg
-MAkGA1UdEwQCMAAwHQYDVR0OBBYEFFgwtZssBZQGuj088LLNHWdl43+FMHQGA1Ud
-IwRtMGuAFPLi6lVlpJrirJ2X9UVs9veMEa3foUikRjBEMQswCQYDVQQGEwJTRTEQ
-MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT
-UUwgQUKCCQCV6Xj1NFDk1TANBgkqhkiG9w0BAQUFAAOBgQAFGeMTFPzFKL9p+ACz
-Jcu9yp8vTLOoBBHwdCe9giy0SZunWfD3h9Hgupmi/ksdEG/korPNf4toMUbuzZ7i
-R+FM+nTR4ovMoEuoJNGkw2sqxijNQeAGSObP8jzKN5XXKWRrkZGD56zIC4e82qaq
-8URDyHR7FSaRLgPEcVBs+GjcjA==
+MIIB5zCCAVACAxAAATANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G
+A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg
+QUIwHhcNMTAwMTI5MTE1MDIyWhcNMTUwMTI4MTE1MDIyWjAyMQswCQYDVQQGEwJT
+RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIwgZ8wDQYJKoZI
+hvcNAQEBBQADgY0AMIGJAoGBAMyaN0kTZtzP4wsToSPteNtOvRH2jA12+aMyVpr4
+oSFqVU5NP+ZnnSaZss2kmtIrWVzXitNgaPgYvcW+FeEqPKPUYcv1EZQXgYH3h4z2
+atLu2OZ39mJmTS4WjQiBSsnGSzHluceKhJZIp0eMDSaQVk7mpW6Ms/Kf/D14m0lu
+hoN3AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAXh+jU18kExz4KDKwf2lp8w7ANIcQ
+A33aFYu9GbgaVjHnhUmByX9FIHQ+icDgJoRRzAQWzmmZAeEmmbPj9b3sX6CE5Dja
+dXh7iZzSzWCVILqO43zm33Y6fIl3ApSGETrEYX1vcYMhihf7F+LuAmthwbRSY9fY
+RrLFnG84kYo1Mgs=
-----END CERTIFICATE-----
=== modified file 'mysql-test/std_data/client-key.pem'
--- a/mysql-test/std_data/client-key.pem 2009-06-11 16:21:32 +0000
+++ b/mysql-test/std_data/client-key.pem 2010-03-04 08:03:07 +0000
@@ -1,9 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIBOQIBAAJBAOFSMCzZvmQokV16/dnpFDV60pROkUbg259refRMrG4HYTSGdGKn
-qESv+oeHqH1CYf+rUNR7v3X61dWzdPtWHjcCAwEAAQJAXYooM8ZlcuEgj+VKU1ee
-qyEFIMqJJxqcMk+E/nWCM96WxCP3zHNSrqNfSpI3ld7QzMwhdRz+gFLxT2gGNpIw
-MQIhAPxzM/lDihe67X3ADYtDl9ZjA8Pm430x9sXlcxI17tCZAiEA5H1SyFl4mUee
-9VnfSC2XGW7lwz72ZygfVX+b7tLWF08CIEh40gzW5MfXM+KLxdea+fXjyursV5ZT
-R6KcMiKiNQLRAiAcmHqlzFzFgisotai2Fc6VRkXHG7gmzOSvBJt1VjmpDQIge6jf
-2N7whTdvC4ferB+zUlgWQdyvx1c3T4gnt6PYdaY=
+MIICXQIBAAKBgQDMmjdJE2bcz+MLE6Ej7XjbTr0R9owNdvmjMlaa+KEhalVOTT/m
+Z50mmbLNpJrSK1lc14rTYGj4GL3FvhXhKjyj1GHL9RGUF4GB94eM9mrS7tjmd/Zi
+Zk0uFo0IgUrJxksx5bnHioSWSKdHjA0mkFZO5qVujLPyn/w9eJtJboaDdwIDAQAB
+AoGASqk/4We2En+93y3jkIO4pXafIe3w/3zZ7caRue1ehx4RUQh5d+95djuB9u7J
+HEZ7TpjM7QNyao5EueL6gvbxt0LXFvqAMni7yM9tt/HUYtHHPqYiRtUny9bKYFTm
+l8szCCMal/wD9GZU9ByHDNHm7tHUMyMhARNTYSgx+SERFmECQQD/6jJocC4SXf6f
+T3LqimWR02lbJ7qCoDgRglsUXh0zjrG+IIiAyE+QOCCx1GMe3Uw6bsIuYwdHT6as
+WcdPs04xAkEAzKulvEvLVvN5zfa/DTYRTV7jh6aDleOxjsD5oN/oJXoACnPzVuUL
+qQQMNtuAXm6Q1QItrRxpQsSKbY0UQka6JwJBAOSgoNoG5lIIYTKIMvzwGV+XBLeo
+HYsXgh+6Wo4uql3mLErUG78ZtWL9kc/tE4R+ZdyKGLaCR/1gXmH5bwN4B/ECQEBb
+uUH8k3REG4kojesZlVc+/00ojzgS4UKCa/yqa9VdB6ZBz8MDQydinnShkTwgiGpy
+xOoqhO753o2UT0qH8wECQQC99IEJWUnwvExVMkLaZH5NjAFJkb22sjkmuT11tAgU
+RQgOMoDOm6driojnOnDWOkx1r1Gy9NgMLooduja4v6cx
-----END RSA PRIVATE KEY-----
=== modified file 'mysql-test/std_data/server-cert.pem'
--- a/mysql-test/std_data/server-cert.pem 2009-06-11 16:21:32 +0000
+++ b/mysql-test/std_data/server-cert.pem 2010-03-04 08:03:07 +0000
@@ -1,55 +1,41 @@
Certificate:
Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
+ Version: 1 (0x0)
+ Serial Number: 1048578 (0x100002)
+ Signature Algorithm: md5WithRSAEncryption
Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB
Validity
- Not Before: Jan 28 10:55:13 2009 GMT
- Not After : Jan 28 10:55:13 2010 GMT
- Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer(a)mysql.com
+ Not Before: Jan 29 11:56:49 2010 GMT
+ Not After : Jan 28 11:56:49 2015 GMT
+ Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (512 bit)
- Modulus (512 bit):
- 00:b6:8f:e5:b7:b4:86:83:13:8a:f9:bf:63:cb:64:
- 2d:b9:51:d1:de:ab:7b:45:1f:aa:b5:66:73:13:f9:
- a6:07:d5:ba:7c:fa:92:bd:37:e2:ad:87:db:3e:b6:
- 6a:12:64:f8:ee:17:e3:15:06:2f:a8:82:68:bf:57:
- 8d:c3:04:98:27
+ Public-Key: (512 bit)
+ Modulus:
+ 00:cd:e4:87:51:9d:72:11:a0:d1:fa:f3:92:8b:13:
+ 1c:eb:f7:e2:9a:2f:72:a8:d6:65:48:d1:69:af:1b:
+ c0:4c:13:e5:60:60:51:41:e9:ab:a6:bc:13:bb:0c:
+ 5e:32:7c:d9:6c:9e:cd:05:24:84:78:db:80:91:2e:
+ d8:88:2b:c2:ed
Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- X509v3 Subject Key Identifier:
- D9:9A:B8:5F:22:EA:04:10:C8:25:7D:82:57:E6:2E:FD:19:29:E7:DA
- X509v3 Authority Key Identifier:
- keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF
- DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB
- serial:95:E9:78:F5:34:50:E4:D5
-
- Signature Algorithm: sha1WithRSAEncryption
- 54:07:2d:21:0b:a5:af:3b:58:23:32:5e:56:7f:ab:58:63:48:
- 91:aa:38:90:89:16:f9:cc:bf:a4:0e:78:2b:9f:c5:1b:58:a6:
- e6:08:8f:2e:ae:97:03:21:9b:f1:cd:c0:26:8f:1d:d7:28:27:
- a0:8e:81:09:1b:1c:0f:c9:a5:41:3a:2d:44:3f:9c:fa:87:ff:
- c8:4c:2b:44:f7:1b:c1:3e:4f:01:7f:e9:26:cc:9f:1c:06:b5:
- 0b:27:d1:10:90:be:93:0c:9c:e7:b0:d1:ea:27:99:4e:06:14:
- 0c:7a:e9:c1:52:c5:33:68:bc:61:0d:db:81:3b:57:48:57:bf:
- 42:9a
+ Signature Algorithm: md5WithRSAEncryption
+ 73:ce:9c:6e:39:46:b4:14:be:da:3f:f3:1b:ba:90:bc:23:43:
+ d7:82:2a:70:4e:a6:d9:5a:65:5c:b7:df:71:df:75:77:c5:80:
+ a4:af:fa:d2:59:e2:fd:c9:9c:f0:98:95:8e:69:a9:8c:7c:d8:
+ 6f:48:d2:e3:36:e0:cd:ff:3f:d1:a5:e6:ab:75:09:c4:50:10:
+ c4:96:dd:bf:3b:de:32:46:da:ca:4a:f1:d6:52:8a:33:2f:ab:
+ f5:2e:70:3f:d4:9c:be:00:c8:03:f9:39:8a:df:5b:70:3c:40:
+ ef:03:be:7c:3d:1d:32:32:f3:51:81:e2:83:30:6e:3d:38:9b:
+ fb:3c
-----BEGIN CERTIFICATE-----
-MIICkzCCAfygAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ
-MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT
-UUwgQUIwHhcNMDkwMTI4MTA1NTEzWhcNMTAwMTI4MTA1NTEzWjB5MQswCQYDVQQG
-EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQBgNV
-BAMTCWxvY2FsaG9zdDExMC8GCSqGSIb3DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2
-ZWxvcGVyQG15c3FsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC2j+W3tIaD
-E4r5v2PLZC25UdHeq3tFH6q1ZnMT+aYH1bp8+pK9N+Kth9s+tmoSZPjuF+MVBi+o
-gmi/V43DBJgnAgMBAAGjgaMwgaAwCQYDVR0TBAIwADAdBgNVHQ4EFgQU2Zq4XyLq
-BBDIJX2CV+Yu/Rkp59owdAYDVR0jBG0wa4AU8uLqVWWkmuKsnZf1RWz294wRrd+h
-SKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdV
-cHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAJXpePU0UOTVMA0GCSqGSIb3DQEB
-BQUAA4GBAFQHLSELpa87WCMyXlZ/q1hjSJGqOJCJFvnMv6QOeCufxRtYpuYIjy6u
-lwMhm/HNwCaPHdcoJ6COgQkbHA/JpUE6LUQ/nPqH/8hMK0T3G8E+TwF/6SbMnxwG
-tQsn0RCQvpMMnOew0eonmU4GFAx66cFSxTNovGEN24E7V0hXv0Ka
+MIIBtzCCASACAxAAAjANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G
+A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg
+QUIwHhcNMTAwMTI5MTE1NjQ5WhcNMTUwMTI4MTE1NjQ5WjBGMQswCQYDVQQGEwJT
+RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQBgNVBAMT
+CWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDN5IdRnXIRoNH685KL
+Exzr9+KaL3Ko1mVI0WmvG8BME+VgYFFB6aumvBO7DF4yfNlsns0FJIR424CRLtiI
+K8LtAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAc86cbjlGtBS+2j/zG7qQvCND14Iq
+cE6m2VplXLffcd91d8WApK/60lni/cmc8JiVjmmpjHzYb0jS4zbgzf8/0aXmq3UJ
+xFAQxJbdvzveMkbaykrx1lKKMy+r9S5wP9ScvgDIA/k5it9bcDxA7wO+fD0dMjLz
+UYHigzBuPTib+zw=
-----END CERTIFICATE-----
=== modified file 'mysql-test/std_data/server-key.pem'
--- a/mysql-test/std_data/server-key.pem 2009-06-11 16:21:32 +0000
+++ b/mysql-test/std_data/server-key.pem 2010-03-04 08:03:07 +0000
@@ -1,9 +1,9 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIBOQIBAAJBALaP5be0hoMTivm/Y8tkLblR0d6re0UfqrVmcxP5pgfVunz6kr03
-4q2H2z62ahJk+O4X4xUGL6iCaL9XjcMEmCcCAwEAAQJASA5VwgNb0CKHiPm0ntOk
-hG+54SRX3DmafEy6gRjZIl/bZ/asSLhXUZ+CeohyrQh7BZgYWvykd8pRISL9eKsU
-GQIhAOXkUrOtP/EtjyqNluEqZdG+RZi/7p61JS3Ce13Myu+LAiEAy0uMlV34AJpM
-b40FPKqlHxw8DD/Dt1iKhNVAg8+LDVUCIFjv7fbJDbW2VG63/Cj8CAwOukoP5rbL
-iaicVrHBKrllAiB9+MiaXeopZXNrxDS0jQFYr8Q9yt1aJVFgUkxx4Q9HKQIgZPs0
-KlF3NNNWw78INaAEkyf0IEssnLMsuoCWw0DIOak=
+MIIBOwIBAAJBAM3kh1GdchGg0frzkosTHOv34povcqjWZUjRaa8bwEwT5WBgUUHp
+q6a8E7sMXjJ82WyezQUkhHjbgJEu2Igrwu0CAwEAAQJBAJuwhFbF3NzRpBbEmnqJ
+4GPa1UJMQMLFJF+04tqj/HxJcAIVhOJhGmmtYNw1yjz/ZsPnfJCMz4eFOtdjvGtf
+peECIQDmFFg2WLvYo+2m9w9V7z4ZIkg7ixYkI/ObUUctfZkPOQIhAOUWnrvjFrAX
+bIvYT/YR50+3ZDLEc51XxNgJnWqWYl1VAiEAnTOFWgyivFC1DgF8PvDp8u5TgCt2
+A1d1GMgd490O+TECIC/WMl0/hTxOF9930vKqOGf//o9PUGkZq8QE9fcM4gtlAiAE
+iOcFpnLjtWj57jrhuw214ucnB5rklkQQe+AtcARNkg==
-----END RSA PRIVATE KEY-----
=== modified file 'mysql-test/std_data/server8k-cert.pem'
--- a/mysql-test/std_data/server8k-cert.pem 2009-06-11 16:21:32 +0000
+++ b/mysql-test/std_data/server8k-cert.pem 2010-03-04 08:03:07 +0000
@@ -1,138 +1,125 @@
Certificate:
Data:
- Version: 3 (0x2)
- Serial Number: 4 (0x4)
- Signature Algorithm: sha1WithRSAEncryption
+ Version: 1 (0x0)
+ Serial Number: 1048579 (0x100003)
+ Signature Algorithm: md5WithRSAEncryption
Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB
Validity
- Not Before: Jan 28 11:12:27 2009 GMT
- Not After : Jan 28 11:12:27 2010 GMT
+ Not Before: Jan 29 12:01:53 2010 GMT
+ Not After : Jan 28 12:01:53 2015 GMT
Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=server
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (8192 bit)
- Modulus (8192 bit):
- 00:c0:8f:22:03:24:59:67:46:14:d6:8f:60:09:58:
- 06:07:45:f1:78:71:55:f1:ea:b9:30:8a:cd:c3:3c:
- b9:bf:65:6e:18:ed:a0:b8:c9:19:56:6f:c4:90:19:
- c8:65:09:db:ff:bf:82:a1:08:ad:01:4f:5a:a3:d4:
- 3d:78:7e:4b:4a:01:a4:7d:e8:7b:05:3e:7d:d8:b9:
- 55:58:60:d6:1c:ce:e8:32:62:2c:19:60:f3:ed:05:
- 99:6d:c9:77:07:2e:11:6d:0b:9a:c7:68:38:46:e8:
- fa:31:80:df:e8:79:f0:f1:fd:a9:94:c3:fa:0d:f5:
- 78:ac:49:7e:d5:17:fd:e1:ee:44:f3:c7:0e:30:32:
- 5d:a9:19:25:e4:bb:21:1d:fe:3c:84:48:40:f5:58:
- f4:bf:13:8c:85:68:bb:ec:f5:dd:c6:38:d1:b0:77:
- 1f:a6:8e:4f:8d:e2:6f:49:74:f5:3f:90:65:8e:99:
- 1e:59:9c:1c:b5:26:24:c4:b1:de:1e:fb:96:65:c4:
- 31:14:1a:53:b8:5e:62:8a:c7:04:f7:b4:36:a4:af:
- 07:c8:27:06:ed:dd:e6:f4:8c:62:f1:65:40:d0:9f:
- 9f:a9:14:c8:8e:8b:74:d6:67:5a:d0:c9:4d:35:a1:
- d5:7b:39:3a:42:9f:e4:d0:f4:c6:0f:2e:42:30:4b:
- 56:b2:3d:6d:8e:2d:58:c5:69:99:35:49:95:95:99:
- b6:87:29:2b:32:d1:50:08:cd:25:14:48:6d:10:99:
- 85:61:3c:41:26:21:55:cc:1f:cf:ad:b0:2f:b9:89:
- d8:4e:a0:18:ff:75:1d:b6:97:7c:c5:fa:8b:dc:93:
- 17:86:0a:64:d4:09:35:d5:83:34:6d:5c:6d:c6:8c:
- cd:b9:ec:c2:93:c6:c1:b7:cc:04:6f:22:e0:07:bf:
- e0:d9:9b:2f:d5:a0:50:cc:f9:f0:95:83:8f:f4:30:
- 83:72:94:d7:b5:4b:da:cc:9f:54:3b:8d:78:77:0b:
- 24:6c:0f:c2:96:61:96:2f:b8:5f:b5:7a:ab:7a:5b:
- 97:7a:a9:ad:40:8b:f2:d6:c6:8d:81:d9:94:61:8f:
- 9d:03:c5:b9:10:03:68:83:bf:04:81:cc:ac:bd:34:
- 89:e8:d4:8d:43:20:e2:b6:a4:11:3d:15:2a:82:0c:
- d6:3a:6a:8c:62:d4:93:bc:c3:80:bf:1b:b4:2b:0a:
- 7a:34:f0:cd:1e:82:3f:25:0f:d1:04:a8:0a:05:19:
- b0:d6:16:83:39:af:0b:45:7d:cb:14:7e:4d:aa:aa:
- c2:39:a8:46:38:ab:bd:ab:2a:bd:34:43:7f:da:25:
- de:2b:fb:69:3b:fe:3b:87:fd:98:94:76:4a:bf:04:
- a3:31:e3:3a:ff:6f:04:fa:fa:24:e4:2a:89:e9:0e:
- bf:44:4c:72:85:82:3c:89:4a:03:63:01:41:92:53:
- d0:82:60:6e:d8:ff:8c:a2:b4:1a:3b:20:6d:ae:74:
- 92:30:4e:48:e3:51:a6:cb:73:97:06:13:03:32:23:
- 9b:7d:a2:c7:3a:a9:af:97:8c:51:ed:fe:fa:b4:b4:
- 1a:a3:87:fc:cf:8c:8e:e6:80:15:03:fd:fe:7d:bd:
- b1:76:f1:5f:b3:09:2b:4c:4d:a7:7c:b5:72:b1:d6:
- db:38:c0:67:a4:54:bc:87:09:a5:39:ba:1a:7e:3f:
- 74:60:ad:3d:4b:be:94:53:f3:64:16:c7:33:35:ec:
- 41:00:95:b6:de:99:62:a2:7a:28:9a:45:4d:fa:cd:
- a6:77:f6:de:58:72:50:c8:7d:69:38:db:07:04:84:
- d8:4d:39:f7:50:13:43:ae:2d:af:45:a4:2a:39:56:
- 3c:b8:b7:d8:26:a4:36:c9:23:aa:aa:b8:49:0b:21:
- ba:9e:7a:2b:7f:4d:29:9f:0e:00:1e:b4:5e:a6:fa:
- 49:fe:8d:e5:74:57:d8:ba:d9:92:2c:d2:ac:84:1d:
- f2:a6:a4:44:1c:bf:88:41:32:7e:d1:c3:2f:6e:bc:
- 0f:5d:19:a6:8f:74:2b:67:ba:dd:a9:db:68:b5:ce:
- 9d:25:48:df:54:08:d0:1d:4f:2e:5b:24:bc:05:0f:
- fb:58:46:fa:02:ca:53:93:29:cf:10:27:c2:a0:18:
- d0:f5:d4:b9:3c:5e:df:8e:6c:f5:7c:b9:b4:54:cc:
- 39:16:5d:3c:da:96:b3:c3:6c:d4:70:5d:d3:30:a7:
- a6:bd:6f:dd:41:bc:a8:de:42:60:59:9a:85:25:0d:
- 2a:45:c3:05:b4:6e:7a:4a:4d:ca:8c:0a:e5:6c:34:
- bc:20:9b:6d:4a:ca:ca:b6:a6:3a:a0:db:c3:0e:20:
- 1a:12:1b:77:dd:cb:1d:7f:c3:0d:0d:e7:c1:fd:96:
- d2:c7:68:80:99:a0:d9:8a:33:21:a3:8b:a2:5a:a7:
- 7e:27:06:02:7f:ed:60:11:37:34:54:17:7f:4d:90:
- 14:1e:69:37:0d:ba:f0:2b:f0:a3:2d:62:79:c8:76:
- a8:ea:c8:e7:3b:1f:c6:4f:c2:0c:d7:ac:f0:77:53:
- 5d:f0:50:b4:df:9b:03:ca:4d:41:e1:18:b2:25:30:
- 86:1d:63:e5:67:b1:53:cd:6b:4e:83:1a:b9:5e:2d:
- 05:15:6b:d4:8e:b1:97:fc:31:03:57:cb:bf:27:7f:
- cd:5f:27:7e:66:e7:3c:17:09:b6:11:2a:4f:33:cd:
- eb:1a:d3:6f:d5:15:8b:8b:ce:68:6b:7e:9a:95:e5:
- 74:7f:17:57:d9
+ Public-Key: (8192 bit)
+ Modulus:
+ 00:ca:aa:1d:c4:11:ec:91:f0:c7:ff:5f:90:92:fc:
+ 40:0c:5e:b7:3d:00:c5:20:d5:0f:89:31:07:d7:41:
+ 4c:8b:60:80:aa:38:14:de:93:6b:9c:74:88:41:68:
+ b5:02:41:01:2d:86:a2:7a:95:53:5e:7b:67:2f:6c:
+ 1e:29:51:f9:44:fd:4a:80:be:b2:23:a1:3e:1b:38:
+ cf:88:c4:71:ee:f8:6b:41:c5:2d:c0:c3:52:ac:59:
+ 7d:81:34:19:95:32:b8:9a:51:b6:41:36:d4:c4:a1:
+ ae:84:e6:38:b9:e8:bf:96:be:19:7a:6b:77:4d:e0:
+ de:e6:b3:b6:6b:bc:3d:dd:68:bc:4b:c4:eb:f5:36:
+ 93:ed:56:a2:15:50:8a:10:e8:d6:22:ed:6c:b1:cd:
+ c3:18:c9:f6:0a:e1:de:61:65:62:d6:14:41:8c:b5:
+ fb:14:68:c1:cf:12:5d:41:21:9d:57:11:43:7d:bb:
+ 43:2c:21:bb:c3:44:7d:a8:cf:1f:c3:71:75:b5:47:
+ c2:7d:ce:38:3c:73:64:9e:15:d8:a7:27:cf:bd:40:
+ c8:45:08:e3:c8:39:a8:0b:8e:c2:5b:7b:f1:47:91:
+ 12:91:cc:e1:00:e0:94:5b:bd:32:e4:0c:8d:c3:be:
+ cc:76:32:52:12:69:b0:18:e0:b0:c2:76:34:5a:5f:
+ 79:d9:f6:81:9d:02:0a:61:69:1c:33:ce:49:fa:76:
+ 03:1e:07:5b:27:0b:bf:34:9e:34:96:b8:03:9b:50:
+ 3a:6a:2f:17:7a:14:cf:65:63:00:37:52:a8:73:ce:
+ 4b:14:40:f4:d2:9a:56:54:33:b8:77:2e:42:5b:8f:
+ ec:1f:18:f4:ad:ab:8a:4a:8d:6d:70:25:f3:58:e7:
+ cb:66:51:14:7d:16:f4:eb:6d:56:76:76:51:6e:d6:
+ 1d:da:d3:8d:c0:64:5a:67:4e:af:e2:bf:33:d1:b8:
+ f6:2a:fc:57:87:a7:35:5e:80:c9:ac:fc:87:c9:71:
+ 17:91:bf:b7:4d:a3:ed:3c:1b:27:f4:66:a0:f9:46:
+ 03:27:cc:ea:80:f6:4b:40:f6:41:94:cd:bd:0a:b3:
+ ef:26:be:de:6f:69:ae:0f:3f:1c:55:63:33:90:9b:
+ ed:ca:5a:12:4d:de:4b:06:c2:a2:92:b0:42:3d:31:
+ af:a4:15:12:15:f8:8a:e9:88:8d:cf:fd:85:66:50:
+ 6f:11:f1:9f:48:f3:b5:ba:9d:86:68:24:a2:5d:a8:
+ 7c:54:42:fa:d8:b5:c5:f2:dd:0e:0f:d0:68:e4:54:
+ 7e:c5:b9:a0:9b:65:2d:77:f4:8f:b9:30:0a:d5:86:
+ 5c:ed:c9:7c:d1:da:9d:0d:63:50:ee:e5:1e:92:63:
+ cc:a2:0c:e8:4a:96:02:4d:dc:8f:df:7c:8f:08:18:
+ a8:30:88:d7:af:89:ad:fc:57:4b:10:f9:f1:cb:48:
+ e8:b6:3b:c8:3f:fc:c2:d3:d1:4a:10:3c:1b:6b:64:
+ dc:e5:65:1e:5b:b2:da:b1:e2:24:97:8f:ee:c0:4b:
+ 8e:18:83:7c:17:a6:3c:45:b3:60:06:23:f2:2f:18:
+ 13:9e:17:8a:c6:72:79:8c:4d:04:f3:9d:ea:e0:25:
+ d3:33:8c:1e:11:47:63:1f:a5:45:3f:bd:85:b3:fe:
+ a5:68:ee:48:b7:0c:a4:c9:7f:72:d0:75:66:9b:6a:
+ f9:a0:50:f3:a8:59:6d:a3:dd:38:4f:70:2b:bb:ff:
+ 92:2e:71:ab:ef:e9:00:ed:0d:d1:b4:6f:f0:8e:b2:
+ 09:fb:4d:61:0d:d9:10:d5:54:11:cd:03:94:84:fd:
+ a8:68:e4:45:6e:1e:6a:1e:2f:85:a1:6d:f5:b6:c0:
+ f1:ee:f7:36:e9:fe:c2:f7:ad:cc:13:46:5b:88:42:
+ f0:2d:1f:b5:0e:7e:b5:2b:e4:8d:ab:b9:87:30:6a:
+ 3d:12:f4:ad:f3:1c:ac:cc:1a:48:29:2a:96:7b:80:
+ 00:0b:6e:59:87:bf:a3:ca:70:99:1b:1c:fd:72:3d:
+ b2:d3:94:4a:cf:55:75:be:1f:40:ec:55:35:48:2d:
+ 55:f0:00:da:3c:b0:60:ba:11:32:66:54:0b:be:06:
+ a4:5e:b7:c9:59:bb:4d:f4:92:06:26:48:6e:c2:12:
+ d4:7c:f0:20:b8:a2:e1:bc:6a:b6:19:0e:37:47:55:
+ c9:f2:49:0d:96:75:a2:84:64:bf:34:fc:be:b2:41:
+ e4:f5:88:eb:e1:b7:26:a5:e5:41:c2:20:0c:f6:e2:
+ a8:a5:e7:76:54:a5:fb:4b:80:05:7d:18:85:7a:ba:
+ bc:b7:ad:c0:2f:60:85:cc:15:12:1c:2f:0a:9e:f3:
+ 7c:40:cf:f4:3e:23:d2:95:ca:d0:06:58:52:f0:84:
+ d8:0f:3d:eb:ff:12:68:94:79:8f:be:40:29:5f:98:
+ c8:90:6c:05:2f:99:8c:2a:63:78:1f:23:b1:29:c5:
+ e7:49:c9:b2:92:0f:53:0b:d5:71:28:17:c2:19:bf:
+ 60:bf:7c:87:a8:ab:c1:f4:0a:c1:b8:d2:68:ee:c1:
+ ce:a7:13:13:17:6d:24:5d:a2:37:a6:d7:7d:48:8b:
+ 2b:74:2d:40:2e:ca:19:d5:b6:3e:6c:42:71:fa:cf:
+ 85:87:f9:de:80:73:8b:89:f4:70:f0:d8:d7:ff:40:
+ 41:9c:c7:15:6d:9b:6e:4c:b5:52:02:99:79:32:73:
+ ca:26:a0:ac:31:6f:c4:b0:f5:da:bb:c2:1f:e0:9f:
+ 44:ba:25:f7:9f
Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- X509v3 Subject Key Identifier:
- 58:12:24:59:A7:3C:29:15:89:5A:C2:12:DB:E7:A5:42:10:21:B7:BA
- X509v3 Authority Key Identifier:
- keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF
- DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB
- serial:95:E9:78:F5:34:50:E4:D5
-
- Signature Algorithm: sha1WithRSAEncryption
- cd:cb:5c:83:35:ea:cb:cb:c3:a8:c3:95:e2:e6:6f:4d:d8:e4:
- ee:41:dd:3f:35:82:ac:2f:fd:63:89:4f:3a:19:d7:81:75:b3:
- a3:fc:36:b2:12:d5:c6:56:bc:13:60:37:33:6e:a0:d8:ae:7c:
- 88:f9:4b:ee:7b:1f:c8:f0:56:19:07:4d:bb:45:52:1c:78:81:
- 07:7c:13:86:b8:86:70:85:e4:71:25:58:78:d1:be:de:22:82:
- 6d:1a:4b:06:ac:f0:e8:50:87:c7:69:64:c2:61:43:cd:96:06:
- a6:7e:09:a9:02:01:2a:a2:40:f3:cd:10:80:48:d0:34:55:40:
- b9:ce
+ Signature Algorithm: md5WithRSAEncryption
+ 08:75:dc:b9:3f:aa:b6:7e:81:7a:39:d1:ee:ed:44:b6:ce:1b:
+ 37:c4:4c:19:d0:66:e6:eb:b5:4f:2a:ef:95:58:64:21:55:01:
+ 12:30:ac:8a:95:d1:06:de:29:46:a4:f1:7d:7f:b0:1e:d2:4e:
+ fb:f6:fa:9a:74:be:85:62:db:0b:82:90:58:62:c5:5f:f1:80:
+ 02:9f:c5:fb:f3:6b:b0:b4:3b:04:b1:e5:53:c2:d0:00:a1:1a:
+ 9d:65:60:6f:73:98:67:e0:9c:c8:12:94:79:59:bf:43:7b:f5:
+ 77:c8:8f:df:b1:cd:11:1c:01:19:99:c2:22:42:f7:41:ae:b4:
+ b8:1a
-----BEGIN CERTIFICATE-----
-MIIGJTCCBY6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ
-MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT
-UUwgQUIwHhcNMDkwMTI4MTExMjI3WhcNMTAwMTI4MTExMjI3WjBDMQswCQYDVQQG
-EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxDzANBgNV
-BAMTBnNlcnZlcjCCBCIwDQYJKoZIhvcNAQEBBQADggQPADCCBAoCggQBAMCPIgMk
-WWdGFNaPYAlYBgdF8XhxVfHquTCKzcM8ub9lbhjtoLjJGVZvxJAZyGUJ2/+/gqEI
-rQFPWqPUPXh+S0oBpH3oewU+fdi5VVhg1hzO6DJiLBlg8+0FmW3JdwcuEW0Lmsdo
-OEbo+jGA3+h58PH9qZTD+g31eKxJftUX/eHuRPPHDjAyXakZJeS7IR3+PIRIQPVY
-9L8TjIVou+z13cY40bB3H6aOT43ib0l09T+QZY6ZHlmcHLUmJMSx3h77lmXEMRQa
-U7heYorHBPe0NqSvB8gnBu3d5vSMYvFlQNCfn6kUyI6LdNZnWtDJTTWh1Xs5OkKf
-5ND0xg8uQjBLVrI9bY4tWMVpmTVJlZWZtocpKzLRUAjNJRRIbRCZhWE8QSYhVcwf
-z62wL7mJ2E6gGP91HbaXfMX6i9yTF4YKZNQJNdWDNG1cbcaMzbnswpPGwbfMBG8i
-4Ae/4NmbL9WgUMz58JWDj/Qwg3KU17VL2syfVDuNeHcLJGwPwpZhli+4X7V6q3pb
-l3qprUCL8tbGjYHZlGGPnQPFuRADaIO/BIHMrL00iejUjUMg4rakET0VKoIM1jpq
-jGLUk7zDgL8btCsKejTwzR6CPyUP0QSoCgUZsNYWgzmvC0V9yxR+TaqqwjmoRjir
-vasqvTRDf9ol3iv7aTv+O4f9mJR2Sr8EozHjOv9vBPr6JOQqiekOv0RMcoWCPIlK
-A2MBQZJT0IJgbtj/jKK0Gjsgba50kjBOSONRpstzlwYTAzIjm32ixzqpr5eMUe3+
-+rS0GqOH/M+MjuaAFQP9/n29sXbxX7MJK0xNp3y1crHW2zjAZ6RUvIcJpTm6Gn4/
-dGCtPUu+lFPzZBbHMzXsQQCVtt6ZYqJ6KJpFTfrNpnf23lhyUMh9aTjbBwSE2E05
-91ATQ64tr0WkKjlWPLi32CakNskjqqq4SQshup56K39NKZ8OAB60Xqb6Sf6N5XRX
-2LrZkizSrIQd8qakRBy/iEEyftHDL268D10Zpo90K2e63anbaLXOnSVI31QI0B1P
-LlskvAUP+1hG+gLKU5MpzxAnwqAY0PXUuTxe345s9Xy5tFTMORZdPNqWs8Ns1HBd
-0zCnpr1v3UG8qN5CYFmahSUNKkXDBbRuekpNyowK5Ww0vCCbbUrKyramOqDbww4g
-GhIbd93LHX/DDQ3nwf2W0sdogJmg2YozIaOLolqnficGAn/tYBE3NFQXf02QFB5p
-Nw268Cvwoy1iech2qOrI5zsfxk/CDNes8HdTXfBQtN+bA8pNQeEYsiUwhh1j5Wex
-U81rToMauV4tBRVr1I6xl/wxA1fLvyd/zV8nfmbnPBcJthEqTzPN6xrTb9UVi4vO
-aGt+mpXldH8XV9kCAwEAAaOBozCBoDAJBgNVHRMEAjAAMB0GA1UdDgQWBBRYEiRZ
-pzwpFYlawhLb56VCECG3ujB0BgNVHSMEbTBrgBTy4upVZaSa4qydl/VFbPb3jBGt
-36FIpEYwRDELMAkGA1UEBhMCU0UxEDAOBgNVBAgTB1VwcHNhbGExEDAOBgNVBAcT
-B1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCggkAlel49TRQ5NUwDQYJKoZIhvcN
-AQEFBQADgYEAzctcgzXqy8vDqMOV4uZvTdjk7kHdPzWCrC/9Y4lPOhnXgXWzo/w2
-shLVxla8E2A3M26g2K58iPlL7nsfyPBWGQdNu0VSHHiBB3wThriGcIXkcSVYeNG+
-3iKCbRpLBqzw6FCHx2lkwmFDzZYGpn4JqQIBKqJA880QgEjQNFVAuc4=
+MIIFfDCCBOUCAxAAAzANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G
+A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg
+QUIwHhcNMTAwMTI5MTIwMTUzWhcNMTUwMTI4MTIwMTUzWjBDMQswCQYDVQQGEwJT
+RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxDzANBgNVBAMT
+BnNlcnZlcjCCBCIwDQYJKoZIhvcNAQEBBQADggQPADCCBAoCggQBAMqqHcQR7JHw
+x/9fkJL8QAxetz0AxSDVD4kxB9dBTItggKo4FN6Ta5x0iEFotQJBAS2GonqVU157
+Zy9sHilR+UT9SoC+siOhPhs4z4jEce74a0HFLcDDUqxZfYE0GZUyuJpRtkE21MSh
+roTmOLnov5a+GXprd03g3uaztmu8Pd1ovEvE6/U2k+1WohVQihDo1iLtbLHNwxjJ
+9grh3mFlYtYUQYy1+xRowc8SXUEhnVcRQ327Qywhu8NEfajPH8NxdbVHwn3OODxz
+ZJ4V2Kcnz71AyEUI48g5qAuOwlt78UeREpHM4QDglFu9MuQMjcO+zHYyUhJpsBjg
+sMJ2NFpfedn2gZ0CCmFpHDPOSfp2Ax4HWycLvzSeNJa4A5tQOmovF3oUz2VjADdS
+qHPOSxRA9NKaVlQzuHcuQluP7B8Y9K2rikqNbXAl81jny2ZRFH0W9OttVnZ2UW7W
+HdrTjcBkWmdOr+K/M9G49ir8V4enNV6Ayaz8h8lxF5G/t02j7TwbJ/RmoPlGAyfM
+6oD2S0D2QZTNvQqz7ya+3m9prg8/HFVjM5Cb7cpaEk3eSwbCopKwQj0xr6QVEhX4
+iumIjc/9hWZQbxHxn0jztbqdhmgkol2ofFRC+ti1xfLdDg/QaORUfsW5oJtlLXf0
+j7kwCtWGXO3JfNHanQ1jUO7lHpJjzKIM6EqWAk3cj998jwgYqDCI16+JrfxXSxD5
+8ctI6LY7yD/8wtPRShA8G2tk3OVlHluy2rHiJJeP7sBLjhiDfBemPEWzYAYj8i8Y
+E54XisZyeYxNBPOd6uAl0zOMHhFHYx+lRT+9hbP+pWjuSLcMpMl/ctB1Zptq+aBQ
+86hZbaPdOE9wK7v/ki5xq+/pAO0N0bRv8I6yCftNYQ3ZENVUEc0DlIT9qGjkRW4e
+ah4vhaFt9bbA8e73Nun+wvetzBNGW4hC8C0ftQ5+tSvkjau5hzBqPRL0rfMcrMwa
+SCkqlnuAAAtuWYe/o8pwmRsc/XI9stOUSs9Vdb4fQOxVNUgtVfAA2jywYLoRMmZU
+C74GpF63yVm7TfSSBiZIbsIS1HzwILii4bxqthkON0dVyfJJDZZ1ooRkvzT8vrJB
+5PWI6+G3JqXlQcIgDPbiqKXndlSl+0uABX0YhXq6vLetwC9ghcwVEhwvCp7zfEDP
+9D4j0pXK0AZYUvCE2A896/8SaJR5j75AKV+YyJBsBS+ZjCpjeB8jsSnF50nJspIP
+UwvVcSgXwhm/YL98h6irwfQKwbjSaO7BzqcTExdtJF2iN6bXfUiLK3QtQC7KGdW2
+PmxCcfrPhYf53oBzi4n0cPDY1/9AQZzHFW2bbky1UgKZeTJzyiagrDFvxLD12rvC
+H+CfRLol958CAwEAATANBgkqhkiG9w0BAQQFAAOBgQAIddy5P6q2foF6OdHu7US2
+zhs3xEwZ0Gbm67VPKu+VWGQhVQESMKyKldEG3ilGpPF9f7Ae0k779vqadL6FYtsL
+gpBYYsVf8YACn8X782uwtDsEseVTwtAAoRqdZWBvc5hn4JzIEpR5Wb9De/V3yI/f
+sc0RHAEZmcIiQvdBrrS4Gg==
-----END CERTIFICATE-----
=== modified file 'mysql-test/std_data/server8k-key.pem'
--- a/mysql-test/std_data/server8k-key.pem 2009-06-11 16:21:32 +0000
+++ b/mysql-test/std_data/server8k-key.pem 2010-01-29 14:54:27 +0000
@@ -1,99 +1,99 @@
-----BEGIN RSA PRIVATE KEY-----
-MIISKAIBAAKCBAEAwI8iAyRZZ0YU1o9gCVgGB0XxeHFV8eq5MIrNwzy5v2VuGO2g
-uMkZVm/EkBnIZQnb/7+CoQitAU9ao9Q9eH5LSgGkfeh7BT592LlVWGDWHM7oMmIs
-GWDz7QWZbcl3By4RbQuax2g4Ruj6MYDf6Hnw8f2plMP6DfV4rEl+1Rf94e5E88cO
-MDJdqRkl5LshHf48hEhA9Vj0vxOMhWi77PXdxjjRsHcfpo5PjeJvSXT1P5Bljpke
-WZwctSYkxLHeHvuWZcQxFBpTuF5iiscE97Q2pK8HyCcG7d3m9Ixi8WVA0J+fqRTI
-jot01mda0MlNNaHVezk6Qp/k0PTGDy5CMEtWsj1tji1YxWmZNUmVlZm2hykrMtFQ
-CM0lFEhtEJmFYTxBJiFVzB/PrbAvuYnYTqAY/3Udtpd8xfqL3JMXhgpk1Ak11YM0
-bVxtxozNuezCk8bBt8wEbyLgB7/g2Zsv1aBQzPnwlYOP9DCDcpTXtUvazJ9UO414
-dwskbA/ClmGWL7hftXqreluXeqmtQIvy1saNgdmUYY+dA8W5EANog78EgcysvTSJ
-6NSNQyDitqQRPRUqggzWOmqMYtSTvMOAvxu0Kwp6NPDNHoI/JQ/RBKgKBRmw1haD
-Oa8LRX3LFH5NqqrCOahGOKu9qyq9NEN/2iXeK/tpO/47h/2YlHZKvwSjMeM6/28E
-+vok5CqJ6Q6/RExyhYI8iUoDYwFBklPQgmBu2P+MorQaOyBtrnSSME5I41Gmy3OX
-BhMDMiObfaLHOqmvl4xR7f76tLQao4f8z4yO5oAVA/3+fb2xdvFfswkrTE2nfLVy
-sdbbOMBnpFS8hwmlOboafj90YK09S76UU/NkFsczNexBAJW23plionoomkVN+s2m
-d/beWHJQyH1pONsHBITYTTn3UBNDri2vRaQqOVY8uLfYJqQ2ySOqqrhJCyG6nnor
-f00pnw4AHrRepvpJ/o3ldFfYutmSLNKshB3ypqREHL+IQTJ+0cMvbrwPXRmmj3Qr
-Z7rdqdtotc6dJUjfVAjQHU8uWyS8BQ/7WEb6AspTkynPECfCoBjQ9dS5PF7fjmz1
-fLm0VMw5Fl082pazw2zUcF3TMKemvW/dQbyo3kJgWZqFJQ0qRcMFtG56Sk3KjArl
-bDS8IJttSsrKtqY6oNvDDiAaEht33csdf8MNDefB/ZbSx2iAmaDZijMho4uiWqd+
-JwYCf+1gETc0VBd/TZAUHmk3DbrwK/CjLWJ5yHao6sjnOx/GT8IM16zwd1Nd8FC0
-35sDyk1B4RiyJTCGHWPlZ7FTzWtOgxq5Xi0FFWvUjrGX/DEDV8u/J3/NXyd+Zuc8
-Fwm2ESpPM83rGtNv1RWLi85oa36aleV0fxdX2QIDAQABAoIEAGv5ltvmLQ/A93xc
-x0BWEINRkBa2jrfpo9B5dOnuikWtza/Cx+X2NfQHFlSrcHhfr/JX5BsCb2iVo8DM
-CXAgeX1VMHS9wQXuxciaHCZDnqxmxUNDU3EjsYQOKLusRcdL6M+Zuz/ny+7PQ0Qw
-/N0yS46Wa9oUjon3RKRvTeSV4HIpFpcP3n/eLjDc/ielWuujnTGcBnjNWegvQROp
-5/7221YElGh8U84kbK2l9DtfjwoGoTv11lPvOxXE/scg6em7r9j+y3p3TMzMeDtT
-YBC6CA4Oa7GrWLJXROOKOQ0ddtvFNlUsZ02vG2QCbqU2y8mwJrJDI80qNbeKGel3
-SfwkssedtGoOOYHxNczwpyVNHVHrHuMPBe75gbo+5pFxVJ5ymCGWfbLJf73oVsqW
-ZimoknvkozW4+mlVlcmo3X73IxTW2U4RlXthYdj9KXsBLRaKVCQJDc934eHWkXHU
-GF2U2NonqOVd8YG/FmZQ2ig6EcW97hC6wnsWT2Uc7UNAE2RM4bY0xCUHaQiKTrEs
-CI6wpbbTV+XhDu2HmL9G+fsuSIu0RoSOCmr5jQDAVwCNPXFgBgcIxbPZ/UCJ7RHj
-GrWPBldAN8ip4osiA+B3XwBabcvwXP2fgBP/eLWN1St3q3tw5xpHpqCuhNuPSqsc
-0ntz0oIdJyRR6fXWmRFex4kXQ597z5ozm0uyg8arV3HJFxDC3DI6kKfs86/oqMSW
-l+9g+d4x6VrUOCTDk0bjN3T8HQ9ASfy9JVacqk6yuXX7a0WeeT+x9JsvFAjg2KmG
-CJUtm5w5siItMDSPpcRE4hlfgh+M7ZKS3PFgH3vvwfPMbC/IC93QoSaFzRJMyobX
-ei6PNwqJvL+HADlMfLmehE2w9ycp4Fe1Gw/NW0Ed1S6Ajo45hgXQJSIrzla6eglg
-JPsPpQ8b+weZNQ8zvc0KvfRJmZKKEb9dHvFdi68I1kV8aapQsjrMOjwHC2pnCFh/
-axkVc7a59fKUs7L6nAJhCs2sSixTorZz5PvJ6mXhWu72TCzu+kThNnEORrlWPHQl
-RFEAFpDDaGSzOMlhb92CWUMPyZU2qtzMzv4QGbP5YqTy121hXuT5OBKCF3eNLihV
-aje16k0RMFqqW3Olbm7Mp2P1C6DuwzsUJBnNwB5JzhC79Po88zNAl2d1h+qysKU1
-jxF316nhpWJ2dGJ/sbJ+XpUMd/tVrNFQMA254GFfXycsfBoQOSY5d6GfRwKUDOou
-xImbIzGUAaIYdsGKDuKtqs5S21JMJjJ/J5CwjLu9tbpP/jsp22KHCpraHAQCupSp
-+SFwWI7tRUXzREuxJixfUOnJFQYOATnMFvvtk1d6v4xoPYCVEhHq8gHqJkTyTi3Y
-BPVwT1UCggIBAOEy5gThTrEqSVFUcFJm9bJxtWZt/YhOIJWNNxeaxExHzy5hPpsw
-fZXtN4MUCeMSWI4isgIujmltwgOHMjQqsJPISn/1gVrqLmrZ2PnFzko/WA8rMUfd
-EUnOOpj2bKpChlRGHi76ZV4XGgoTXyO6mrVUcUgf3reSImdcdQ5IHa7J+lWhCQGb
-neZIyDOk41LX1TxjcYkY7vuUgmbBYComXPm2UaY3HN4E/3ElXntj6PrlozL33A56
-z4UPfv2Vv9kl0ydkTJe/WcUN2htqLFCYygF2XLlwbv2SYDCT31PkJUORbScUM46A
-DOhlxvLBFcpF+l0RtCtvnrKyFy9yZJKrcLh9x6xVChZ/aQqSptSHjll5IEcVm54Y
-Z1TjWizCI4txnaBFV0UCLt1CZrllXnyIksZLS4/dVqUIKmkxPBQUpiD5dmgDcmPB
-/LdWzS6k4MH3J3Y3tu3MNPHDwgUtnifSZrsWSYPK0F8J0dMU/mLaS9eOplAH7Eo1
-t7OrrImvitM6tUdErRYilIaoS/6YPmsPST5gY1N4n8Lf4sAE/tY8fwaWRpTVSrIw
-CoFwLtHESUOhqfuAOdr1EkDfo/RQTUVdnmWZ+D0j3du8MmsMje4x3f2CjBDXqArl
-gNnBQELDmrdif8KELNjlEpTIz0T7wEfquhVQ2dzhFpL7RLAgggD+oEBLAoICAQDa
-5WOWrAtaI1cC5C7LFxM2qXTHGRttfAtVxuigJapLqNASJuu59GGRxsCVwhthbNFh
-aCMSj+fZK7QNFkaoPwuZCEtzy0ErkVZzxYp3cP6b99mzGoCcuqiHiW5qhEkbxwdC
-f3YEsSGqE6j8TPW8feiziqo8q+QPSudI9ngkH1gjgbIrTu9iaxKJcF2CwBxe5tfB
-uFBNPIgJAaLPejRKQu17MAV2jDnBDIsZUZnm53IxQ+giIYUBay3cfC1KMJu/AnZ/
-CxETjgqqnzqdFW0b0o49Q6YQa6QXAiSjs+lL/BhjbdA5quVdFmA3CoASFQbihYfM
-4vilUg7Y4wXfzS7DyBZdfppIn+HI8PPSMv/lfdsQXecl5TU1fBDPRWYPpTZqm1II
-HDCkmGRKet/j4/oobabNRrJ6PJcxNjqeMVv/a72pypDRPIXzNxLb1BkfWDGfgu2R
-YAdRNBSJSpdoHDZ+1VO2A+/8gz9Zuiv1WxoX7+u3pCAd+0vCfHiaXiFVc7fI8F+m
-rtDmN5p3DD9l1+/v7yd+7eUezwxYecElw5E5MyAJRTYGrim8g7XvF/u9rXvH09VP
-TeIE8oJ7XzrxCmtGIxlJs6FmgUbUblOyfPZDUqPnzlo8Ru1H2iKRo2FPiMfij8mh
-H3wgFTnZpGDQjw/xop51bxVueXrmOeguS0wmk/8Z6wKCAgEA0y+bPApadJRWS1nn
-N69sTBqMZfFR6Eh0ECts9criuTJCXZk+T+SqcTYTb+4T04k52Jk63Aby8HXIkuxv
-LTK3gu86xkLiOvMP8o43Bwz0BvbeSuNThLQQ6Wjn1NiLUSOvu0pCNgYFl7YMalR+
-TRBK0y/MSDny762wa8Pt1iXVCDxLcY/h1UstSW8JqDzCHcdgJhCPwWTLgMxleZ1w
-5DYzzM2oRjq67I49Sssjjo1ESD2fzUVZbY7IG11L1t1fG3F4UiGiHlCJC92Qo1Lv
-Geoezj5EeHay70Mcx5F0xsRWGcZAWXx9WO5GrI39g1uFZro3Lp5SmsVDSwrt6UXa
-gR0bSThTTw40tqJnTE34+6ff25JWrbLay+jQxm+q+fxZvwQeMNW2IHYKot4JXWVt
-tVWSZzjnNJP6FCvTMfDFCYPPw26OFr7cwCaEKx7QriRazitMK3XWK6zsHalZwudj
-wK50PpCJAnno7KdVySCP6v4ST6Rr3POBKJq1ml2tITWo96u/ooUJ2I83QAyFr8zw
-BBBCvKdBnl6pW+P/TdmhbiEvcmrs59gaA34/6+DbV0Y++piZwswd9XML2iCgLZY8
-0IcZ6uf4PsXq4Yzcrz0HwM+tAXcyiPzkjstpCUxMShALgFxzuWOgdwpjYXnrviJk
-0EyUkzbOCHBhbhcK9CyYHfyrJX8CggIAdWwgJC9eV5glkPN+9osGT4hPkI4zXGPy
-YK03FNGfrL59/37JbRNfU6fen3dk4LpTB4Gpbserg6AiEfMlLBPF0O3WK+OYrhpk
-2e3Z/YCr1Fb8fUt2Op0W0r4ycQlNfo0ho9ZkJNgwSuAJAm72U4rnTYjREYLT8DAq
-KcWtZRM7YLCuNvU9DPqLExcn0n/juDT1AIIy8XvLLamnAM15R2znn/F+vL00Lg7g
-f1B60pbNdwgKemSoyL4J+ADU+rtgkPJtRnFVU7walLSd6K4ZvZcRnmOvrZdQitcn
-eHmGaLBvFMdPr9+w8mKScnQ7h3eoHdOrqYkIAQcn18jQ2eFjeLrY5IaJlPPPVs+K
-u/OHuj/tR7ZXzMhL5skK62U6/qGNs1pmgts8bM8i3aFUgRdGlnFbzTpje5cNM+T3
-RO0NgNL3ByIW1Wc2I+YjQ7FfWKUi2YKOljGBO1pIue09kyevRBKDuVwbXMW7MhLg
-idm5AaY+OGDeqbaoSUgkGgrsrr5IlI39gZi9jwG85qe3Spavq3ILKdfL1N8UrFGD
-/xIN0TVPtilede7vjKTK79tZu8JYaDWGc+g/mo/M1wmawLrqGNGzOwoVRruKl2In
-m9PU9wBZ1HuphDQ4DRdC/AU8qkGhmDOx4bDWEQ/R3KKFHNvhnamyfyR7xqt79gyS
-NGNIElnJuskCggIARFaK6yAVmaL74Qu3iiELj8FU9Cw8kPP5HeWUfGxCjlegdH3R
-FBtoQlDcQjYzO2uZR94Itg3yk3Dt+xbf7KxUsODwlgLj1UhV4eOXUDTosBFTrbTG
-v9gnRVH0Eyu9tF+CMUcCXhq6tnIrQOVv1ozcdXfIpk9gvIbfh4rlo6X0iM8Xge2t
-Vo7awq05t4wJBkO1xUtOaw9HabaszK/CU1iNV7cIBmaFF3AEP/KVfOs+kjubc9AF
-mqC+LVVClvJPNzm1YA5JZlxmQ0u1xXFqZv0OMoibgY+gSzaiAQz3eKB6vEv4Xv4U
-kaF9nEUTEjowpTE6uX9X0mGkXXT2wXmlTjosZFnxRX5IIrRNug30plRra5CNYPGp
-3uTmD/D7Nzi1iYitJg3yhrTQmCWiJY3x4Z0xophLkio2nlJ9WoTKf1AwTIATY7fa
-pX9bxEKldYXrYZNFlbqBPFgA/36v+JDVfMf2E9yRMCt0LAJ0HUM6zP0ngMv+S1TP
-Pu6X0WXR9JeuoaF4uJSty/xwdpST/CkHflFLVsk5n3tNQfWGjqoTSOJMgL9NRY9e
-Pc/OshHZHeCVFUSXtcf1pfmmBtT6FHX0L4cgVqA5xO8RYapnLDAFLXq2/dRv3NwW
-W9CzZcZKh7jmJw4iSIY5IU1+ThgugWoxlkcmjs/egjBclL8BBfqRIwx/vOE=
+MIISKgIBAAKCBAEAyqodxBHskfDH/1+QkvxADF63PQDFINUPiTEH10FMi2CAqjgU
+3pNrnHSIQWi1AkEBLYaiepVTXntnL2weKVH5RP1KgL6yI6E+GzjPiMRx7vhrQcUt
+wMNSrFl9gTQZlTK4mlG2QTbUxKGuhOY4uei/lr4Zemt3TeDe5rO2a7w93Wi8S8Tr
+9TaT7VaiFVCKEOjWIu1ssc3DGMn2CuHeYWVi1hRBjLX7FGjBzxJdQSGdVxFDfbtD
+LCG7w0R9qM8fw3F1tUfCfc44PHNknhXYpyfPvUDIRQjjyDmoC47CW3vxR5ESkczh
+AOCUW70y5AyNw77MdjJSEmmwGOCwwnY0Wl952faBnQIKYWkcM85J+nYDHgdbJwu/
+NJ40lrgDm1A6ai8XehTPZWMAN1Koc85LFED00ppWVDO4dy5CW4/sHxj0rauKSo1t
+cCXzWOfLZlEUfRb0621WdnZRbtYd2tONwGRaZ06v4r8z0bj2KvxXh6c1XoDJrPyH
+yXEXkb+3TaPtPBsn9Gag+UYDJ8zqgPZLQPZBlM29CrPvJr7eb2muDz8cVWMzkJvt
+yloSTd5LBsKikrBCPTGvpBUSFfiK6YiNz/2FZlBvEfGfSPO1up2GaCSiXah8VEL6
+2LXF8t0OD9Bo5FR+xbmgm2Utd/SPuTAK1YZc7cl80dqdDWNQ7uUekmPMogzoSpYC
+TdyP33yPCBioMIjXr4mt/FdLEPnxy0jotjvIP/zC09FKEDwba2Tc5WUeW7LaseIk
+l4/uwEuOGIN8F6Y8RbNgBiPyLxgTnheKxnJ5jE0E853q4CXTM4weEUdjH6VFP72F
+s/6laO5ItwykyX9y0HVmm2r5oFDzqFlto904T3Aru/+SLnGr7+kA7Q3RtG/wjrIJ
++01hDdkQ1VQRzQOUhP2oaORFbh5qHi+FoW31tsDx7vc26f7C963ME0ZbiELwLR+1
+Dn61K+SNq7mHMGo9EvSt8xyszBpIKSqWe4AAC25Zh7+jynCZGxz9cj2y05RKz1V1
+vh9A7FU1SC1V8ADaPLBguhEyZlQLvgakXrfJWbtN9JIGJkhuwhLUfPAguKLhvGq2
+GQ43R1XJ8kkNlnWihGS/NPy+skHk9Yjr4bcmpeVBwiAM9uKoped2VKX7S4AFfRiF
+erq8t63AL2CFzBUSHC8KnvN8QM/0PiPSlcrQBlhS8ITYDz3r/xJolHmPvkApX5jI
+kGwFL5mMKmN4HyOxKcXnScmykg9TC9VxKBfCGb9gv3yHqKvB9ArBuNJo7sHOpxMT
+F20kXaI3ptd9SIsrdC1ALsoZ1bY+bEJx+s+Fh/negHOLifRw8NjX/0BBnMcVbZtu
+TLVSApl5MnPKJqCsMW/EsPXau8If4J9EuiX3nwIDAQABAoIEAElnTjqq502AsV+c
+hGfId4ZDdAjjU4LtyJ+/I4DihM/ilxeQEnb/XDWhu4w9WXpEgyGzJvxRQ43wElKJ
+zW7X4voK58Yzy5++EhmX/QsjY8TTMz3yJf0wgawtCZkXfsCcS2KRf/qk2nGRwf0e
+yaMEWwhFOEMv01lgvjs/Ei55Usrz2Wd0HqaFKxUGkNQ5hJhVTOH/rqPDzAsZc0VD
+w+Dw8NhrI8bMTvF4c+IFW8NwYmWbuh87CTxdx30VPJI82ttWJ/UN1bLtU08J2IKt
+lPgOIl8ArMjcTGxD/cqZ3Wl3Pc/XCqvGUiSYMwP7Rgh1R4+DdtjEpxdGMmMAVuVI
+HPQyqpa4gv+UMqBPish0yjSuM7jXnztINOvg9Vk1sxC5AT9eaRltmiS1s+lVxe+T
+43ulf0ccYXJD/WclWSGCwloNFuokPIV+Lgo1pKsp4XDgoxQfkXwH8Q4dEqebY9rT
+Tv9FGb1bMbdl22X1oSu2lBltBZaB/QnruV7L2GaQ0tqLKizgBRuvZFSE+DWdMb6d
+9mnEB8LWtca/nzogXb5qv4GEMUX4FUAmSf1FnGWZwwDi1DFfJ860RVKf0xokGGQ3
+cm3H/F4veds88Z1hsAu0bG8h/bEAim+Whvag995cFHDD4on41KXW8wX1on9VFA1W
+CkaGUPhLRytXDBVCSJkOYYFSJlb2wqONiWe4Tn5hsantCfliTj/GVkgDq2h7dAGR
+WyoqTntJAv/xJsUOV9WmGXnWNeZX8BSO3P5dnXnMzhCWQGoprXmWFyJ3TYCJ2+CO
+rzkZbtuKvTvGc3sDJgrSVmmg0BrOkH+GyYVlJdTDBmfzoORludDCFHECa8oK7NwY
+t3o0eNlG6IqTxl2HIoPneW9nXFQtCXv6tpJjljwjlz5WpJG+kBW6bDedcxZu7olZ
+fqtnyZTB2SjzzbGdQ4JvFup8MxNyPvYiqumQXJgkyXFVDl/UFhjWuGe04i8NBJgJ
+xORcjfgLrKH1XKVBWPJdh/2YeUKIIvQ9RB4WVqXgGmD/21tgv1bVEMYabh23e/HE
+Fe1U2XQPJKxGCEtG6b4zhFP+PeZACS+Vk5IVJYK9n4SepPBPgX/wbJLOcKGpsKjp
+yx5WjopMO6T+VUV8HIduuZ+E8+uAILHDmo2Bq+LHblaxd4SkM0+hL2H36imK5CUO
+5fLuvHW88LvFtQw6xhP20s+BnmgzE5ZvNG4Iedkjvwe9HmdNDew0UYT5vNJN0ehh
+OlraBC++JYwEclrBD9SRvprT63XKDG735pPvzLQi7WKDCBn1/JEgxDIO8nkMewOZ
+FU48Mdmkn9wqPeIigQciwl62fuAQCGRG+RXMQqra4A1apqMZQEauTK50VhHDGdbc
+ye9LHaECggIBAO9lAzoYS/Lu0ticMt24P8BSbGdxSNIpEyIlTTs+7A0UjpfXsoK9
+4EJWZ7lhgbQh+SCTS662SeC+s8M6bT+3mELxUC5S/N3aCPyfjcM3JaoACkI9+VMn
+9otJZjAEwH7cNpMN0Xa8fHCEma3l3XKiVxEJbuJC86S5mpkjeXVnDajAidBtevBd
+LWJ9n2yXk+ZKUyI0mjpqItwUxOgQ/MOIvqAu66xyjg08/I1QQTuIrReAA+oaVKhp
+c42Ufn26hUhNrQCBAtMAO3VC/chciet6vEMNEM13GqLp4+PcPhRX90gO4+bNrScD
+WgiW/jc24CGan8gAenBWC/3l/C6JUsMp+ZYmPozsa0zo6edgiO/f2KXe5nP87wZT
+MxaYJgnyXJxMefI79kUHPrhpXZxuiSCEWLhCBN34Lhpr2L491i2g/FJj9i6N3EzE
+N3ic5Q63o4QFusjqIm3taQQFoGP2Cgg9owz5WJ0uRz/gtOE3XQiQA7+ozoAXOlTw
+pJK5MMtVrEoOLIbVJIpxfDcKDp3yorR8QCQLHgDBmFeNCDmk+7YP33dRIc/AVNLF
+q7cecqEc7D8AkXX8Q53GfCEg+uqbdeMQXK4BUE9iwRK9RiFhas/RJe73+Iio3S0L
+ekLpnnOfvk744ws+JWsLpsfC/ZE7OxBLPtq2xvGl/RT2G7tCjmpX3CbPAoICAQDY
+uOEJks2T105EcMPJjzNHCCqjK6S7qZaWkF3KT1Z0Mu5oUZwwHamsMg4BQJ2mjMrL
+fRBKfXQLA6vgE7zysw3F300RDxE1RVow5+JLDQ4bqupp27/M0a8fuwksyOdKHqCV
+YHzuTCxbVIFZawTjfOxJVXDHKCFCilfY1LsA+V+oFe3Ej8YYxWXkXA9ZLigpmt3s
+Wu6eFcZgF3utzIGjI6eP6lL5bWp6Bh9Avp2xrOvpFwE2m02Y7/Zom6MT4DXvByY2
+KHHQLsasEMpeLuxQXjLeTocwcxBwBFKhX95yFuv31k00VydT+NExtaZeUYi9l19J
+WmM4GjFjAqa3uUwMNVv5JfWtKMyk4FOox2XftLvMiIhV95B8hAGxtYr3hPkGg80O
+AWPq6OKUD332COXRaHkmL5aQdN3gP5zh9+rH6icLrrZbrQidVRyDw03doRoGrH7i
+ixXLyYoW80PHgqUDPohd5bFkZpi2vwXMl1YQ2TfN9TvYFSGme9YCm9ZuypnqauW/
+aAf0FI1MNwS+XDREtzPdFi0me6WxpKL4a2Z3GGNxIFuBjQ/uydWpjxkny9qI3KAp
+SgjI3kBUDGq3gf0R+Xo/d4d/4asK9Nv2Fi0X+RfGqioFaTbQl/1zhNdvhP9IcwEJ
+DLVQ3UhMdfg285RarC2Sihui0M8Smi9od9Dj6rdWMQKCAgEAiQVRFoRnnDGz/wVQ
+W/Wkj6jdoUuG+btG10lwbhOyuj3k6+Yqp4iUfoPENKgpu/eiB1InhGWT3Y5ph7m+
+ZDTqco56bTlUwIqWkDmmw3CiHy6MsKOWPFFoXQry8VMW9sWGex7yoDp8I07SQ2WJ
+HZ7rpLW4gMr/d25AnZxfXaJRgCBMAT9YmZFLc88hW99aaPproO1oxTyQnVVJ6uYm
+NqjjKv4QKJEc21jn2N5xp+iv4f6Evw65G/fXitbOm5oRxXOoLNyqyCie35wrc+37
+hwumC97DmkasuUiUBoy9/5jl0ZmsOiPJEsZpVvdNpD7FhJZjE++qJPgrPvTPJbe1
+5jz1PUrAjJqZQ9kgYC2x01JVR4NQdlz0VrNyT2FgjFrrRQ7E0bAeYh4meRjd2rat
+yC3YNgabkI0HnlnSIfl0yIMXSPUsKDNMP6gjc+aheI4FioBZC7xvXmn/rKynw+9E
+iLj2xWtGnBir8VTlUu8EUe1UJ/Qv1cL1wT5HhC95TTjJN03rkHUYyCDyjvIzsZX6
+KMHhWIAAeUBVuO7hIVVcOTXWmw2WA7o7ErTPdy13QN40Hk9t8pEkBn9f9vpQg83d
+aMypr3LTC80jY11wcZS3tSEpzCCkYVv91FV4cioTZmytWbg9A+dbNWzi1f22ctTr
+FoVrAXaSYie2trOy5bjPmPCW8qMCggIBALQUKymBSkDmTqqf6I+65ajIKGWdBizJ
+Jc/F9aj9c6DqER+tcFKq0ym6DdkMj/KsWnXrXXYH+DyOuGpg/EfOcEtS2P6rvmi9
+T8wDYg1qs6ZZxp5fcmgGc7Wx/FWyOj1kZZq5qhV4RgM9nJ1oR4+fZdcpn6RcvAZG
+XehWG20byVgpoIAL11cN7zRpKne32rd3b5/NjyjcfxGpcaNgovej0L/MvVV0jV0H
+aUCrIu1X+k6cRu3Q7hF+kwkpCcCiNS6AikfGI4wQ0hR3fy/zXXkKTMpcBglEEwyB
+Cwf8WSID2d79uvka0hr8TRc5ERyeMzkWZp7U9EzRtufGdDGFTqN2Uw4bdKCFnkYC
+AIHl7ciMrN+vM1n7c5uDNMUtTGOPojy/l8tjbFrtWBgfJ1Mg4ZW3cbNBJ6Kw+Qw0
+z28USYoEDp2uduiGRvo0lpUF29Wk37Nb8bLcTygeNxgK2u8Up3iipT0gdt4uQgbX
+g0IVHfayB6SjeS57oJJto85XHz7AKlSWroD1OGagDSifLtneU7AlanryymGHrI6H
+dsNkuqeLJFYDxQVI6UxJebiCpyxiPxwp9wtX8SS3SEyOZL5GzLn6ypGiCH1CTpW0
+EHHSy3V4DUGOc4w7eMirAnbSkxCfOmBA70NNw/uFY2XlQHKow0T0fImfKIeJagbT
+B0GPDYvUpLKBAoICAQCzYnq8xupXK7lvTLaj936qGSe54OC2sj9+UpsFiPxglNY2
+sO5zKWKyY7+rjK6zG2ciGfPEDsZNIqKw1W/KBfR2kRLqkt4bC3fSCvUztx0vtGUe
+veXlqiwETdE7RJXoaGJrgJArYJvpOd8PtWGeM+sSJNNrUlGlJnSiZ0CcypqUZgZL
+WzGFfLOQYAXCykdB1iZkBqU2C5wktvCb9sVz6G3TmAwSKTENOWWZWmh+W0J4pZFV
+ZEyvsxViJRQbwxa0kC0F5J/UtWZknO79/ZFj1H4jiAR45EjWHE+UZAkFwG8BSl54
+EKOx7GDanuRILr0dtbyi4d31nCYXdjs3x2+1N3exw4oKQIvNuF54WoowbNPu0kEb
+G+7/kLwcJqRnSV4AiLuMz5aOte7JJSw5tzgZZlAQwJO7IDfrLqodivcXF5yirwiF
+dyBpzSDmupy/aTHnCpT+l0H96jRU2awxaeRHZUqZog8gMHsslNVZEFvUFDJ7AUN/
+yyfUzJYjH18pZt0hS7jNb1O7KxZCkWGMiEcxHkgF/UINab5qruNBVKOkJ5vqGhYi
+uNkgeGsQtXJcpqMRRiVXJE0kE+26gk+iaYnBJN9jnwy8OEAlYFUHsbCPObe/vPMQ
+3RLl+ZoKdFkN/gTiy70wUTRVw+tWk+iAZc7GPX1CqDFOqGZ2t+xdF8hpsMtEww==
-----END RSA PRIVATE KEY-----
=== modified file 'mysql-test/suite/binlog/r/binlog_index.result'
--- a/mysql-test/suite/binlog/r/binlog_index.result 2009-01-23 12:22:05 +0000
+++ b/mysql-test/suite/binlog/r/binlog_index.result 2009-12-16 19:52:56 +0000
@@ -1,3 +1,8 @@
+call mtr.add_suppression('Attempting backtrace');
+call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.');
+call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file');
+call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.');
+call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.');
flush logs;
flush logs;
flush logs;
@@ -21,7 +26,6 @@ flush logs;
*** must be a warning master-bin.000001 was not found ***
Warnings:
Warning 1612 Being purged log master-bin.000001 was not found
-Warning 1612 Being purged log master-bin.000001 was not found
*** must show one record, of the active binlog, left in the index file after PURGE ***
show binary logs;
Log_name File_size
@@ -34,7 +38,114 @@ purge binary logs TO 'master-bin.000002'
ERROR HY000: Fatal error during log purge
show warnings;
Level Code Message
-Error 1377 a problem with deleting master-bin.000001; consider examining correspondence of your binlog index file to the actual binlog files
+Warning 1377 a problem with deleting master-bin.000001; consider examining correspondence of your binlog index file to the actual binlog files
Error 1377 Fatal error during log purge
reset master;
+# crash_purge_before_update_index
+flush logs;
+SET SESSION debug="+d,crash_purge_before_update_index";
+purge binary logs TO 'master-bin.000002';
+ERROR HY000: Lost connection to MySQL server during query
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000001
+master-bin.000002
+master-bin.000003
+
+# crash_purge_non_critical_after_update_index
+flush logs;
+SET SESSION debug="+d,crash_purge_non_critical_after_update_index";
+purge binary logs TO 'master-bin.000004';
+ERROR HY000: Lost connection to MySQL server during query
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000004
+master-bin.000005
+
+# crash_purge_critical_after_update_index
+flush logs;
+SET SESSION debug="+d,crash_purge_critical_after_update_index";
+purge binary logs TO 'master-bin.000006';
+ERROR HY000: Lost connection to MySQL server during query
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000006
+master-bin.000007
+
+# crash_create_non_critical_before_update_index
+SET SESSION debug="+d,crash_create_non_critical_before_update_index";
+flush logs;
+ERROR HY000: Lost connection to MySQL server during query
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000006
+master-bin.000007
+master-bin.000008
+
+# crash_create_critical_before_update_index
+SET SESSION debug="+d,crash_create_critical_before_update_index";
+flush logs;
+ERROR HY000: Lost connection to MySQL server during query
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000006
+master-bin.000007
+master-bin.000008
+master-bin.000009
+
+# crash_create_after_update_index
+SET SESSION debug="+d,crash_create_after_update_index";
+flush logs;
+ERROR HY000: Lost connection to MySQL server during query
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000006
+master-bin.000007
+master-bin.000008
+master-bin.000009
+master-bin.000010
+master-bin.000011
+
+#
+# This should put the server in unsafe state and stop
+# accepting any command. If we inject a fault at this
+# point and continue the execution the server crashes.
+# Besides the flush command does not report an error.
+#
+# fault_injection_registering_index
+SET SESSION debug="+d,fault_injection_registering_index";
+flush logs;
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000006
+master-bin.000007
+master-bin.000008
+master-bin.000009
+master-bin.000010
+master-bin.000011
+master-bin.000012
+
+# fault_injection_updating_index
+SET SESSION debug="+d,fault_injection_updating_index";
+flush logs;
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000006
+master-bin.000007
+master-bin.000008
+master-bin.000009
+master-bin.000010
+master-bin.000011
+master-bin.000012
+master-bin.000013
+
+SET SESSION debug="";
End of tests
=== modified file 'mysql-test/suite/binlog/r/binlog_killed_simulate.result'
--- a/mysql-test/suite/binlog/r/binlog_killed_simulate.result 2009-09-28 12:41:10 +0000
+++ b/mysql-test/suite/binlog/r/binlog_killed_simulate.result 2009-12-06 01:11:32 +0000
@@ -19,7 +19,7 @@ ERROR 70100: Query execution was interru
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, b) ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, `b`) ;file_id=#
select
(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null;
=== modified file 'mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result'
--- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2009-10-06 10:25:36 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2010-01-22 09:38:21 +0000
@@ -772,8 +772,11 @@ insert into t2 values (bug27417(2));
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Intvar # # INSERT_ID=3
-master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(2))
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 3 */;
count(*)
3
@@ -787,8 +790,11 @@ count(*)
2
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Intvar # # INSERT_ID=4
-master-bin.000001 # Query # # use `test`; delete from t2 where a=bug27417(3)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
select count(*) from t1 /* must be 5 */;
count(*)
5
@@ -810,8 +816,9 @@ ERROR 23000: Duplicate entry '1' for key
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Intvar # # INSERT_ID=1
-master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(1))
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 1 */;
count(*)
@@ -825,8 +832,10 @@ ERROR 23000: Duplicate entry '2' for key
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Intvar # # INSERT_ID=2
-master-bin.000001 # Query # # use `test`; insert into t2 select bug27417(1) union select bug27417(2)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 2 */;
count(*)
@@ -838,8 +847,13 @@ update t3 set b=b+bug27417(1);
ERROR 23000: Duplicate entry '4' for key 'b'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Intvar # # INSERT_ID=4
-master-bin.000001 # Query # # use `test`; update t3 set b=b+bug27417(1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 2 */;
count(*)
2
@@ -853,8 +867,9 @@ ERROR 23000: Duplicate entry '2' for key
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Intvar # # INSERT_ID=6
-master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 4 */;
count(*)
@@ -869,7 +884,7 @@ UPDATE t3,t4 SET t3.a=t4.a + bug27417(1)
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
select count(*) from t1 /* must be 1 */;
count(*)
-1
+2
drop table t4;
delete from t1;
delete from t2;
@@ -884,8 +899,10 @@ ERROR 23000: Duplicate entry '1' for key
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Intvar # # INSERT_ID=9
-master-bin.000001 # Query # # use `test`; delete from t2
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 1 */;
count(*)
@@ -904,7 +921,11 @@ ERROR 23000: Duplicate entry '1' for key
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Delete_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 1 */;
count(*)
@@ -924,12 +945,11 @@ count(*)
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Intvar # # INSERT_ID=10
-master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
-master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
-master-bin.000001 # Intvar # # INSERT_ID=10
-master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=#
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
=== modified file 'mysql-test/suite/binlog/r/binlog_stm_blackhole.result'
--- a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result 2009-09-28 12:41:10 +0000
+++ b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result 2009-12-06 01:11:32 +0000
@@ -127,7 +127,7 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; create table t2 (a varchar(200)) engine=blackhole
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=581
-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) ;file_id=#
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; alter table t1 add b int
master-bin.000001 # Query # # use `test`; alter table t1 drop b
=== modified file 'mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result'
--- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2009-09-28 12:41:10 +0000
+++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2009-12-06 01:11:32 +0000
@@ -1,3 +1,4 @@
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
drop table if exists t1, t2;
create table t1 (a int) engine=innodb;
create table t2 (a int) engine=myisam;
@@ -224,6 +225,8 @@ create table t0 (n int);
insert t0 select * from t1;
set autocommit=1;
insert into t0 select GET_LOCK("lock1",null);
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
set autocommit=0;
create table t2 (n int) engine=innodb;
insert into t2 values (3);
@@ -625,7 +628,7 @@ master-bin.000001 # Query # # BEGIN
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
master-bin.000001 # Intvar # # INSERT_ID=10
-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=#
master-bin.000001 # Query # # ROLLBACK
/* the output must denote there is the query */;
drop trigger trg_del_t2;
@@ -863,7 +866,7 @@ master-bin.000001 # User var # # @`b`=_l
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=#
master-bin.000001 # Query # # ROLLBACK
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
=== modified file 'mysql-test/suite/binlog/r/binlog_stm_row.result'
--- a/mysql-test/suite/binlog/r/binlog_stm_row.result 2009-09-07 20:50:10 +0000
+++ b/mysql-test/suite/binlog/r/binlog_stm_row.result 2010-01-15 15:27:55 +0000
@@ -1,3 +1,4 @@
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
set @saved_global_binlog_format = @@global.binlog_format;
@@ -29,6 +30,8 @@ SELECT RELEASE_LOCK('Bug#34306');
RELEASE_LOCK('Bug#34306')
1
# con2
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
SELECT RELEASE_LOCK('Bug#34306');
RELEASE_LOCK('Bug#34306')
1
=== modified file 'mysql-test/suite/binlog/r/binlog_unsafe.result'
--- a/mysql-test/suite/binlog/r/binlog_unsafe.result 2009-09-07 20:50:10 +0000
+++ b/mysql-test/suite/binlog/r/binlog_unsafe.result 2010-03-04 08:03:07 +0000
@@ -327,4 +327,90 @@ Warnings:
Note 1592 Statement may not be safe to log in statement format.
DROP TABLE t1, t2;
SET @@SESSION.SQL_MODE = @save_sql_mode;
+CREATE TABLE t1 (a VARCHAR(1000));
+INSERT INTO t1 VALUES (CURRENT_USER());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (FOUND_ROWS());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (GET_LOCK('tmp', 1));
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp'));
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (IS_USED_LOCK('tmp'));
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat'));
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1));
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (RELEASE_LOCK('tmp'));
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (ROW_COUNT());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (SESSION_USER());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (SLEEP(1));
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (SYSDATE());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (SYSTEM_USER());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (USER());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (UUID());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (UUID_SHORT());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (VERSION());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+INSERT INTO t1 VALUES (RAND());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+DELETE FROM t1;
+SET TIME_ZONE= '+03:00';
+SET TIMESTAMP=1000000;
+INSERT INTO t1 VALUES
+(CURDATE()),
+(CURRENT_DATE()),
+(CURRENT_TIME()),
+(CURRENT_TIMESTAMP()),
+(CURTIME()),
+(LOCALTIME()),
+(LOCALTIMESTAMP()),
+(NOW()),
+(UNIX_TIMESTAMP()),
+(UTC_DATE()),
+(UTC_TIME()),
+(UTC_TIMESTAMP());
+SELECT * FROM t1;
+a
+1970-01-12
+1970-01-12
+16:46:40
+1970-01-12 16:46:40
+16:46:40
+1970-01-12 16:46:40
+1970-01-12 16:46:40
+1970-01-12 16:46:40
+1000000
+1970-01-12
+13:46:40
+1970-01-12 13:46:40
+DROP TABLE t1;
"End of tests"
=== added file 'mysql-test/suite/binlog/r/binlog_write_error.result'
--- a/mysql-test/suite/binlog/r/binlog_write_error.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/r/binlog_write_error.result 2010-01-24 07:03:23 +0000
@@ -0,0 +1,108 @@
+#
+# Initialization
+#
+DROP TABLE IF EXISTS t1, t2;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP TRIGGER IF EXISTS tr1;
+DROP TRIGGER IF EXISTS tr2;
+DROP VIEW IF EXISTS v1, v2;
+#
+# Test injecting binlog write error when executing queries
+#
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE TABLE t1 (a INT);
+CREATE TABLE t1 (a INT);
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+INSERT INTO t1 VALUES (1),(2),(3);
+SET GLOBAL debug='d,injecting_fault_writing';
+INSERT INTO t1 VALUES (4),(5),(6);
+INSERT INTO t1 VALUES (4),(5),(6);
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+UPDATE t1 set a=a+1;
+UPDATE t1 set a=a+1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DELETE FROM t1;
+DELETE FROM t1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100);
+CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100);
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP TRIGGER tr1;
+DROP TRIGGER tr1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+ALTER TABLE t1 ADD (b INT);
+ALTER TABLE t1 ADD (b INT);
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE VIEW v1 AS SELECT a FROM t1;
+CREATE VIEW v1 AS SELECT a FROM t1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP VIEW v1;
+DROP VIEW v1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1;
+CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP PROCEDURE p1;
+DROP PROCEDURE p1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP TABLE t1;
+DROP TABLE t1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE FUNCTION f1() RETURNS INT return 1;
+CREATE FUNCTION f1() RETURNS INT return 1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP FUNCTION f1;
+DROP FUNCTION f1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE USER user1;
+CREATE USER user1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP USER user1;
+DROP USER user1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+#
+# Cleanup
+#
+DROP TABLE IF EXISTS t1, t2;
+DROP FUNCTION IF EXISTS f1;
+DROP PROCEDURE IF EXISTS p1;
+DROP TRIGGER IF EXISTS tr1;
+DROP VIEW IF EXISTS v1, v2;
=== modified file 'mysql-test/suite/binlog/t/binlog_index.test'
--- a/mysql-test/suite/binlog/t/binlog_index.test 2008-04-05 11:09:53 +0000
+++ b/mysql-test/suite/binlog/t/binlog_index.test 2009-12-08 16:03:19 +0000
@@ -3,6 +3,18 @@
#
source include/have_log_bin.inc;
source include/not_embedded.inc;
+# Don't test this under valgrind, memory leaks will occur
+--source include/not_valgrind.inc
+source include/have_debug.inc;
+call mtr.add_suppression('Attempting backtrace');
+call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.');
+call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file');
+call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.');
+call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.');
+let $old=`select @@debug`;
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+let $INDEX=$MYSQLD_DATADIR/master-bin.index;
#
# testing purge binary logs TO
@@ -13,7 +25,6 @@ flush logs;
flush logs;
source include/show_binary_logs.inc;
-let $MYSQLD_DATADIR= `select @@datadir`;
remove_file $MYSQLD_DATADIR/master-bin.000001;
# there must be a warning with file names
@@ -66,4 +77,159 @@ rmdir $MYSQLD_DATADIR/master-bin.000001;
--disable_warnings
reset master;
--enable_warnings
+
+--echo # crash_purge_before_update_index
+flush logs;
+
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+SET SESSION debug="+d,crash_purge_before_update_index";
+--error 2013
+purge binary logs TO 'master-bin.000002';
+
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+file_exists $MYSQLD_DATADIR/master-bin.000001;
+file_exists $MYSQLD_DATADIR/master-bin.000002;
+file_exists $MYSQLD_DATADIR/master-bin.000003;
+--chmod 0644 $INDEX
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+--echo # crash_purge_non_critical_after_update_index
+flush logs;
+
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+SET SESSION debug="+d,crash_purge_non_critical_after_update_index";
+--error 2013
+purge binary logs TO 'master-bin.000004';
+
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+--error 1
+file_exists $MYSQLD_DATADIR/master-bin.000001;
+--error 1
+file_exists $MYSQLD_DATADIR/master-bin.000002;
+--error 1
+file_exists $MYSQLD_DATADIR/master-bin.000003;
+--chmod 0644 $INDEX
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+--echo # crash_purge_critical_after_update_index
+flush logs;
+
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+SET SESSION debug="+d,crash_purge_critical_after_update_index";
+--error 2013
+purge binary logs TO 'master-bin.000006';
+
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+--error 1
+file_exists $MYSQLD_DATADIR/master-bin.000004;
+--error 1
+file_exists $MYSQLD_DATADIR/master-bin.000005;
+file_exists $MYSQLD_DATADIR/master-bin.000006;
+file_exists $MYSQLD_DATADIR/master-bin.000007;
+--error 1
+file_exists $MYSQLD_DATADIR/master-bin.000008;
+--chmod 0644 $INDEX
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+--echo # crash_create_non_critical_before_update_index
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+SET SESSION debug="+d,crash_create_non_critical_before_update_index";
+--error 2013
+flush logs;
+
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+file_exists $MYSQLD_DATADIR/master-bin.000008;
+--error 1
+file_exists $MYSQLD_DATADIR/master-bin.000009;
+--chmod 0644 $INDEX
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+--echo # crash_create_critical_before_update_index
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+SET SESSION debug="+d,crash_create_critical_before_update_index";
+--error 2013
+flush logs;
+
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+file_exists $MYSQLD_DATADIR/master-bin.000009;
+--error 1
+file_exists $MYSQLD_DATADIR/master-bin.000010;
+--error 1
+file_exists $MYSQLD_DATADIR/master-bin.000011;
+--chmod 0644 $INDEX
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+--echo # crash_create_after_update_index
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+SET SESSION debug="+d,crash_create_after_update_index";
+--error 2013
+flush logs;
+
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+file_exists $MYSQLD_DATADIR/master-bin.000010;
+file_exists $MYSQLD_DATADIR/master-bin.000011;
+--chmod 0644 $INDEX
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+--echo #
+--echo # This should put the server in unsafe state and stop
+--echo # accepting any command. If we inject a fault at this
+--echo # point and continue the execution the server crashes.
+--echo # Besides the flush command does not report an error.
+--echo #
+
+--echo # fault_injection_registering_index
+SET SESSION debug="+d,fault_injection_registering_index";
+flush logs;
+--source include/restart_mysqld.inc
+
+--chmod 0644 $INDEX
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+--echo # fault_injection_updating_index
+SET SESSION debug="+d,fault_injection_updating_index";
+flush logs;
+--source include/restart_mysqld.inc
+
+--chmod 0644 $INDEX
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+eval SET SESSION debug="$old";
+
--echo End of tests
=== modified file 'mysql-test/suite/binlog/t/binlog_killed.test'
--- a/mysql-test/suite/binlog/t/binlog_killed.test 2008-10-23 19:27:09 +0000
+++ b/mysql-test/suite/binlog/t/binlog_killed.test 2009-11-18 14:50:31 +0000
@@ -1,5 +1,5 @@
-- source include/have_innodb.inc
--- source include/have_binlog_format_mixed_or_statement.inc
+-- source include/have_binlog_format_statement.inc
# You cannot use `KILL' with the Embedded MySQL Server library,
# because the embedded server merely runs inside the threads of the host
=== modified file 'mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test'
--- a/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test 2008-02-28 11:21:44 +0000
+++ b/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test 2009-11-18 14:50:31 +0000
@@ -2,6 +2,9 @@
# For both statement and row based bin logs 9/19/2005 [jbm]
-- source include/have_binlog_format_statement.inc
+
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
+
-- source extra/binlog_tests/mix_innodb_myisam_binlog.test
set @@session.binlog_format=statement;
=== modified file 'mysql-test/suite/binlog/t/binlog_stm_row.test'
--- a/mysql-test/suite/binlog/t/binlog_stm_row.test 2009-02-19 09:01:25 +0000
+++ b/mysql-test/suite/binlog/t/binlog_stm_row.test 2010-01-15 15:27:55 +0000
@@ -1,5 +1,8 @@
--source include/have_log_bin.inc
---source include/have_binlog_format_row_or_statement.inc
+# Test sets its own binlog_format, so we restrict it to run only once
+--source include/have_binlog_format_row.inc
+
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
# Get rid of previous tests binlog
--disable_query_log
=== modified file 'mysql-test/suite/binlog/t/binlog_unsafe.test'
--- a/mysql-test/suite/binlog/t/binlog_unsafe.test 2009-09-07 20:50:10 +0000
+++ b/mysql-test/suite/binlog/t/binlog_unsafe.test 2010-03-04 08:03:07 +0000
@@ -47,6 +47,8 @@
# BUG#34768: nondeterministic INSERT using LIMIT logged in stmt mode if binlog_format=mixed
# BUG#41980, SBL, INSERT .. SELECT .. LIMIT = ERROR, even when @@SQL_LOG_BIN is 0
# BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode)
+# BUG#47995: Mark user functions as unsafe
+# BUG#49222: Mare RAND() unsafe
#
# ==== Related test cases ====
#
@@ -388,4 +390,59 @@ DELETE FROM t1 LIMIT 1;
DROP TABLE t1, t2;
SET @@SESSION.SQL_MODE = @save_sql_mode;
+
+#
+# BUG#47995: Mark user functions as unsafe
+# BUG#49222: Mare RAND() unsafe
+#
+# Test that the system functions that are supposed to be marked unsafe
+# generate a warning. Each INSERT statement below should generate a
+# warning.
+#
+
+CREATE TABLE t1 (a VARCHAR(1000));
+INSERT INTO t1 VALUES (CURRENT_USER()); #marked unsafe before BUG#47995
+INSERT INTO t1 VALUES (FOUND_ROWS()); #marked unsafe before BUG#47995
+INSERT INTO t1 VALUES (GET_LOCK('tmp', 1)); #marked unsafe in BUG#47995
+INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp')); #marked unsafe in BUG#47995
+INSERT INTO t1 VALUES (IS_USED_LOCK('tmp')); #marked unsafe in BUG#47995
+INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat')); #marked unsafe in BUG#39701
+INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1));
+INSERT INTO t1 VALUES (RELEASE_LOCK('tmp')); #marked unsafe in BUG#47995
+INSERT INTO t1 VALUES (ROW_COUNT()); #marked unsafe before BUG#47995
+INSERT INTO t1 VALUES (SESSION_USER()); #marked unsafe before BUG#47995
+INSERT INTO t1 VALUES (SLEEP(1)); #marked unsafe in BUG#47995
+INSERT INTO t1 VALUES (SYSDATE()); #marked unsafe in BUG#47995
+INSERT INTO t1 VALUES (SYSTEM_USER()); #marked unsafe before BUG#47995
+INSERT INTO t1 VALUES (USER()); #marked unsafe before BUG#47995
+INSERT INTO t1 VALUES (UUID()); #marked unsafe before BUG#47995
+INSERT INTO t1 VALUES (UUID_SHORT()); #marked unsafe before BUG#47995
+INSERT INTO t1 VALUES (VERSION()); #marked unsafe in BUG#47995
+INSERT INTO t1 VALUES (RAND()); #marked unsafe in BUG#49222
+DELETE FROM t1;
+
+# Since we replicate the TIMESTAMP variable, functions affected by the
+# TIMESTAMP variable are safe to replicate. So we check that the
+# following following functions that depend on the TIMESTAMP variable
+# are not unsafe and don't generate a warning.
+
+SET TIME_ZONE= '+03:00';
+SET TIMESTAMP=1000000;
+INSERT INTO t1 VALUES
+ (CURDATE()),
+ (CURRENT_DATE()),
+ (CURRENT_TIME()),
+ (CURRENT_TIMESTAMP()),
+ (CURTIME()),
+ (LOCALTIME()),
+ (LOCALTIMESTAMP()),
+ (NOW()),
+ (UNIX_TIMESTAMP()),
+ (UTC_DATE()),
+ (UTC_TIME()),
+ (UTC_TIMESTAMP());
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
--echo "End of tests"
=== added file 'mysql-test/suite/binlog/t/binlog_write_error.test'
--- a/mysql-test/suite/binlog/t/binlog_write_error.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/t/binlog_write_error.test 2010-01-24 07:03:23 +0000
@@ -0,0 +1,101 @@
+#
+# === Name ===
+#
+# binlog_write_error.test
+#
+# === Description ===
+#
+# This test case check if the error of writing binlog file is properly
+# reported and handled when executing statements.
+#
+# === Related Bugs ===
+#
+# BUG#37148
+#
+
+source include/have_log_bin.inc;
+source include/have_debug.inc;
+
+--echo #
+--echo # Initialization
+--echo #
+
+disable_warnings;
+DROP TABLE IF EXISTS t1, t2;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP TRIGGER IF EXISTS tr1;
+DROP TRIGGER IF EXISTS tr2;
+DROP VIEW IF EXISTS v1, v2;
+enable_warnings;
+
+--echo #
+--echo # Test injecting binlog write error when executing queries
+--echo #
+
+let $query= CREATE TABLE t1 (a INT);
+source include/binlog_inject_error.inc;
+
+INSERT INTO t1 VALUES (1),(2),(3);
+
+let $query= INSERT INTO t1 VALUES (4),(5),(6);
+source include/binlog_inject_error.inc;
+
+let $query= UPDATE t1 set a=a+1;
+source include/binlog_inject_error.inc;
+
+let $query= DELETE FROM t1;
+source include/binlog_inject_error.inc;
+
+let $query= CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100);
+source include/binlog_inject_error.inc;
+
+let $query= DROP TRIGGER tr1;
+source include/binlog_inject_error.inc;
+
+let $query= ALTER TABLE t1 ADD (b INT);
+source include/binlog_inject_error.inc;
+
+let $query= CREATE VIEW v1 AS SELECT a FROM t1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP VIEW v1;
+source include/binlog_inject_error.inc;
+
+let $query= CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP PROCEDURE p1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP TABLE t1;
+source include/binlog_inject_error.inc;
+
+let $query= CREATE FUNCTION f1() RETURNS INT return 1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP FUNCTION f1;
+source include/binlog_inject_error.inc;
+
+let $query= CREATE USER user1;
+source include/binlog_inject_error.inc;
+
+let $query= REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP USER user1;
+source include/binlog_inject_error.inc;
+
+--echo #
+--echo # Cleanup
+--echo #
+
+disable_warnings;
+DROP TABLE IF EXISTS t1, t2;
+DROP FUNCTION IF EXISTS f1;
+DROP PROCEDURE IF EXISTS p1;
+DROP TRIGGER IF EXISTS tr1;
+DROP VIEW IF EXISTS v1, v2;
+enable_warnings;
=== modified file 'mysql-test/suite/funcs_1/datadict/processlist_val.inc'
--- a/mysql-test/suite/funcs_1/datadict/processlist_val.inc 2009-10-10 09:59:06 +0000
+++ b/mysql-test/suite/funcs_1/datadict/processlist_val.inc 2010-01-11 13:15:28 +0000
@@ -238,7 +238,7 @@ echo
# Poll till all connections of 'test_user' are in a state with COMMAND = 'Sleep'
;
let $wait_condition= SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE USER = 'test_user' AND COMMAND = 'Sleep';
+ WHERE USER = 'test_user' AND COMMAND = 'Sleep' AND STATE = '';
--source include/wait_condition.inc
echo
# ----- switch to connection con2 (user = test_user) -----
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_is.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result 2009-10-10 09:59:06 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result 2010-01-16 05:12:57 +0000
@@ -127,7 +127,7 @@ NULL information_schema INNODB_BUFFER_PO
NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB page_no 2 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB part_len 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB space_id 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX accessed 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX fix_count 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
@@ -394,6 +394,7 @@ NULL information_schema VIEWS TABLE_CATA
NULL information_schema VIEWS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema VIEWS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema VIEWS VIEW_DEFINITION 4 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema XTRADB_ADMIN_COMMAND result_message 1 NO varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
NULL information_schema XTRADB_ENHANCEMENTS comment 3 NO varchar 100 300 NULL NULL utf8 utf8_general_ci varchar(100) select
NULL information_schema XTRADB_ENHANCEMENTS description 2 NO varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255) select
NULL information_schema XTRADB_ENHANCEMENTS link 4 NO varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255) select
@@ -589,7 +590,7 @@ NULL information_schema INNODB_BUFFER_PO
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX hashed bigint NULL NULL NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX accessed bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX modified bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX old bigint NULL NULL NULL NULL bigint(21) unsigned
@@ -848,6 +849,7 @@ NULL information_schema TRIGGERS CREATED
3.0000 information_schema VIEWS SECURITY_TYPE varchar 7 21 utf8 utf8_general_ci varchar(7)
3.0000 information_schema VIEWS CHARACTER_SET_CLIENT varchar 32 96 utf8 utf8_general_ci varchar(32)
3.0000 information_schema VIEWS COLLATION_CONNECTION varchar 32 96 utf8 utf8_general_ci varchar(32)
+3.0000 information_schema XTRADB_ADMIN_COMMAND result_message varchar 1024 3072 utf8 utf8_general_ci varchar(1024)
3.0000 information_schema XTRADB_ENHANCEMENTS name varchar 255 765 utf8 utf8_general_ci varchar(255)
3.0000 information_schema XTRADB_ENHANCEMENTS description varchar 255 765 utf8 utf8_general_ci varchar(255)
3.0000 information_schema XTRADB_ENHANCEMENTS comment varchar 100 300 utf8 utf8_general_ci varchar(100)
=== modified file 'mysql-test/suite/funcs_1/r/is_tables_is.result'
--- a/mysql-test/suite/funcs_1/r/is_tables_is.result 2009-10-10 09:59:06 +0000
+++ b/mysql-test/suite/funcs_1/r/is_tables_is.result 2010-01-16 05:12:57 +0000
@@ -958,6 +958,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME XTRADB_ADMIN_COMMAND
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME XTRADB_ENHANCEMENTS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1941,6 +1964,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME XTRADB_ADMIN_COMMAND
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME XTRADB_ENHANCEMENTS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
=== added file 'mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result'
--- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result 2009-12-11 07:01:16 +0000
@@ -0,0 +1,9 @@
+create table ABC (i int) engine=ibmdb2i;
+insert into ABC values(1);
+create table abc (i int) engine=ibmdb2i;
+insert into abc values (2);
+select * from ABC;
+i
+1
+drop table ABC;
+drop table abc;
=== added file 'mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test'
--- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test 2009-12-11 07:01:16 +0000
@@ -0,0 +1,10 @@
+source suite/ibmdb2i/include/have_ibmdb2i.inc;
+source include/have_case_sensitive_file_system.inc;
+
+create table ABC (i int) engine=ibmdb2i;
+insert into ABC values(1);
+create table abc (i int) engine=ibmdb2i;
+insert into abc values (2);
+select * from ABC;
+drop table ABC;
+drop table abc;
=== modified file 'mysql-test/suite/innodb/r/innodb-index.result'
--- a/mysql-test/suite/innodb/r/innodb-index.result 2009-06-10 13:51:20 +0000
+++ b/mysql-test/suite/innodb/r/innodb-index.result 2009-11-30 12:49:13 +0000
@@ -968,6 +968,7 @@ create index t1u on t1 (u(1));
drop table t1;
set global innodb_file_per_table=0;
set global innodb_file_format=Antelope;
+set global innodb_file_format_check=Antelope;
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
CREATE TABLE t1(
=== added file 'mysql-test/suite/innodb/r/innodb_bug46676.result'
--- a/mysql-test/suite/innodb/r/innodb_bug46676.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_bug46676.result 2009-11-30 12:24:54 +0000
@@ -0,0 +1,9 @@
+SET foreign_key_checks=0;
+CREATE TABLE t1 (id int, foreign key (id) references t2(id)) ENGINE=INNODB;
+CREATE TABLE t2 (id int, foreign key (id) references t1(id)) ENGINE=INNODB;
+SET foreign_key_checks=1;
+SELECT COUNT(*) FROM information_schema.key_column_usage WHERE REFERENCED_TABLE_NAME in ('t1', 't2');
+COUNT(*)
+2
+SET foreign_key_checks=0;
+DROP TABLE t1, t2;
=== added file 'mysql-test/suite/innodb/r/innodb_bug47167.result'
--- a/mysql-test/suite/innodb/r/innodb_bug47167.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_bug47167.result 2009-11-30 11:56:21 +0000
@@ -0,0 +1,24 @@
+set @old_innodb_file_format_check=@@innodb_file_format_check;
+select @old_innodb_file_format_check;
+@old_innodb_file_format_check
+Antelope
+set global innodb_file_format_check = Barracuda;
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
+set global innodb_file_format_check = DEFAULT;
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Barracuda
+set global innodb_file_format_check = @old_innodb_file_format_check;
+select @@innodb_file_format_check;
+@@innodb_file_format_check
+Antelope
+set global innodb_file_format_check = cheetah;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format_check = Bear;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format_check = on;
+ERROR HY000: Incorrect arguments to SET
+set global innodb_file_format_check = off;
+ERROR HY000: Incorrect arguments to SET
=== modified file 'mysql-test/suite/innodb/t/innodb-consistent-master.opt'
--- a/mysql-test/suite/innodb/t/innodb-consistent-master.opt 2009-10-09 13:37:47 +0000
+++ b/mysql-test/suite/innodb/t/innodb-consistent-master.opt 2009-11-30 12:49:13 +0000
@@ -1 +1 @@
---innodb_lock_wait_timeout=2
+--loose-innodb_lock_wait_timeout=2
=== modified file 'mysql-test/suite/innodb/t/innodb-index.test'
--- a/mysql-test/suite/innodb/t/innodb-index.test 2009-06-11 12:57:44 +0000
+++ b/mysql-test/suite/innodb/t/innodb-index.test 2009-11-30 12:49:13 +0000
@@ -1,5 +1,7 @@
-- source include/have_innodb.inc
+let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
+
create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb;
insert into t1 values (5,5,'oo','oo'),(4,4,'tr','tr'),(3,4,'ad','ad'),(2,3,'ak','ak');
commit;
@@ -398,6 +400,7 @@ create index t1u on t1 (u(1));
drop table t1;
eval set global innodb_file_per_table=$per_table;
eval set global innodb_file_format=$format;
+eval set global innodb_file_format_check=$format;
#
# Test to check whether CREATE INDEX handles implicit foreign key
@@ -532,3 +535,10 @@ disconnect a;
disconnect b;
DROP TABLE t1;
+
+#
+# restore environment to the state it was before this test execution
+#
+
+-- disable_query_log
+eval SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig;
=== added file 'mysql-test/suite/innodb/t/innodb_bug46676.test'
--- a/mysql-test/suite/innodb/t/innodb_bug46676.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug46676.test 2009-11-30 12:24:54 +0000
@@ -0,0 +1,16 @@
+# This is the test for bug 46676: mysqld got exception 0xc0000005
+# It is reproducible with InnoDB plugin 1.0.4 + MySQL 5.1.37.
+# But no longer reproducible after MySQL 5.1.38 (with plugin 1.0.5).
+
+--source include/have_innodb.inc
+
+SET foreign_key_checks=0;
+CREATE TABLE t1 (id int, foreign key (id) references t2(id)) ENGINE=INNODB;
+CREATE TABLE t2 (id int, foreign key (id) references t1(id)) ENGINE=INNODB;
+SET foreign_key_checks=1;
+
+# Server crashes
+SELECT COUNT(*) FROM information_schema.key_column_usage WHERE REFERENCED_TABLE_NAME in ('t1', 't2');
+
+SET foreign_key_checks=0;
+DROP TABLE t1, t2;
=== added file 'mysql-test/suite/innodb/t/innodb_bug47167.test'
--- a/mysql-test/suite/innodb/t/innodb_bug47167.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug47167.test 2009-11-30 11:56:21 +0000
@@ -0,0 +1,46 @@
+# This is the unit test for bug *47167.
+# It tests setting the global variable
+# "innodb_file_format_check" with a
+# user-Defined Variable.
+
+--source include/have_innodb.inc
+-- source suite/innodb/include/have_innodb_plugin.inc
+
+# Save the value (Antelope) in 'innodb_file_format_check' to
+# 'old_innodb_file_format_check'
+set @old_innodb_file_format_check=@@innodb_file_format_check;
+
+# @old_innodb_file_format_check shall have the value of 'Antelope'
+select @old_innodb_file_format_check;
+
+# Reset the value in 'innodb_file_format_check' to 'Barracuda'
+set global innodb_file_format_check = Barracuda;
+
+select @@innodb_file_format_check;
+
+# Set 'innodb_file_format_check' to its default value, which
+# is the latest file format supported in the current release.
+set global innodb_file_format_check = DEFAULT;
+
+select @@innodb_file_format_check;
+
+# Put the saved value back to 'innodb_file_format_check'
+set global innodb_file_format_check = @old_innodb_file_format_check;
+
+# Check whether 'innodb_file_format_check' get its original value.
+select @@innodb_file_format_check;
+
+# Following are negative tests, all should fail.
+--disable_warnings
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check = cheetah;
+
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check = Bear;
+
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check = on;
+
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check = off;
+--enable_warnings
=== modified file 'mysql-test/suite/maria/r/maria-recover.result'
--- a/mysql-test/suite/maria/r/maria-recover.result 2009-02-19 09:01:25 +0000
+++ b/mysql-test/suite/maria/r/maria-recover.result 2010-01-27 17:41:05 +0000
@@ -1,6 +1,3 @@
-call mtr.add_suppression("Checking table: '.\/mysqltest\/t_corrupted2'");
-call mtr.add_suppression("Recovering table: '.\/mysqltest\/t_corrupted2'");
-call mtr.add_suppression("Table '.\/mysqltest\/t_corrupted2' is marked as crashed and should be repaired");
select @@global.maria_recover;
@@global.maria_recover
BACKUP
=== modified file 'mysql-test/suite/maria/r/maria3.result'
--- a/mysql-test/suite/maria/r/maria3.result 2009-09-18 01:04:43 +0000
+++ b/mysql-test/suite/maria/r/maria3.result 2010-02-12 14:21:13 +0000
@@ -301,7 +301,7 @@ check table t1 extended;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
-show variables like 'maria%';
+select lower(variable_name) as Variable_name, Variable_value as Value from information_schema.session_variables where variable_name like "maria%" and variable_name not like "maria_used_for_temp_tables" order by 1;
Variable_name Value
maria_block_size 8192
maria_checkpoint_interval 30
@@ -309,16 +309,15 @@ maria_force_start_after_recovery_failure
maria_log_file_size 4294959104
maria_log_purge_type immediate
maria_max_sort_file_size 9223372036853727232
-maria_page_checksum OFF
maria_pagecache_age_threshold 300
maria_pagecache_buffer_size 8384512
maria_pagecache_division_limit 100
+maria_page_checksum OFF
maria_recover OFF
maria_repair_threads 1
maria_sort_buffer_size 8388608
maria_stats_method nulls_unequal
maria_sync_log_dir NEWFILE
-maria_used_for_temp_tables ON
show status like 'maria%';
Variable_name Value
Maria_pagecache_blocks_not_flushed #
=== modified file 'mysql-test/suite/maria/t/maria-recover.test'
--- a/mysql-test/suite/maria/t/maria-recover.test 2009-10-09 08:09:24 +0000
+++ b/mysql-test/suite/maria/t/maria-recover.test 2010-01-27 17:41:05 +0000
@@ -2,9 +2,13 @@
--source include/have_maria.inc
-call mtr.add_suppression("Checking table: '.\/mysqltest\/t_corrupted2'");
-call mtr.add_suppression("Recovering table: '.\/mysqltest\/t_corrupted2'");
-call mtr.add_suppression("Table '.\/mysqltest\/t_corrupted2' is marked as crashed and should be repaired");
+--disable_query_log
+# Note: \\. matches a single period. We use '.' as directory separator to
+# account for Unix and Windows variation.
+call mtr.add_suppression("Checking table: '\\..mysqltest.t_corrupted2'");
+call mtr.add_suppression("Recovering table: '\\..mysqltest.t_corrupted2'");
+call mtr.add_suppression("Table '\\..mysqltest.t_corrupted2' is marked as crashed and should be repaired");
+--enable_query_log
# Note: we're setting an environment variable (not prefixing it by $),
# so that the perl code below can access it.
=== modified file 'mysql-test/suite/maria/t/maria-recovery2-master.opt'
--- a/mysql-test/suite/maria/t/maria-recovery2-master.opt 2009-01-15 14:29:14 +0000
+++ b/mysql-test/suite/maria/t/maria-recovery2-master.opt 2010-02-10 19:06:24 +0000
@@ -1 +1 @@
---skip-stack-trace --skip-core-file --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp
+--skip-stack-trace --skip-core-file --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp --myisam-recover=
=== removed file 'mysql-test/suite/maria/t/maria2-master.opt'
--- a/mysql-test/suite/maria/t/maria2-master.opt 2009-02-15 10:58:34 +0000
+++ b/mysql-test/suite/maria/t/maria2-master.opt 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
---secure-file-priv=""
-
=== modified file 'mysql-test/suite/maria/t/maria3.test'
--- a/mysql-test/suite/maria/t/maria3.test 2009-06-02 09:58:27 +0000
+++ b/mysql-test/suite/maria/t/maria3.test 2010-02-12 14:21:13 +0000
@@ -259,7 +259,7 @@ drop table t1;
# Fix if we are using safemalloc
--replace_result 8388572 8388600
-show variables like 'maria%';
+select lower(variable_name) as Variable_name, Variable_value as Value from information_schema.session_variables where variable_name like "maria%" and variable_name not like "maria_used_for_temp_tables" order by 1;
--replace_column 2 #
show status like 'maria%';
=== added file 'mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result'
--- a/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result 2010-01-22 09:38:21 +0000
@@ -0,0 +1,90 @@
+CREATE TEMPORARY TABLE t1 (a INT);
+CREATE TABLE t2 (a INT, b INT) ENGINE= NDB;
+INSERT INTO t1 VALUES (1);
+CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+DROP EVENT IF EXISTS e1;
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1() SELECT 1;
+INSERT INTO t1 VALUES (1);
+ALTER PROCEDURE p1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+CREATE FUNCTION f1() RETURNS INT RETURN 123;
+INSERT INTO t1 VALUES (1);
+ALTER FUNCTION f1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+CREATE DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+DROP DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+CREATE USER test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT SELECT ON t2 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT ALL ON f1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT ALL ON p1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT USAGE ON *.* TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE USAGE ON *.* FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+RENAME USER test_1@localhost TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+DROP USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p2()
+BEGIN
+# CREATE USER when a temporary table is open.
+CREATE TEMPORARY TABLE t3 (a INT);
+CREATE USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT select on table to user when a temporary table is open.
+GRANT SELECT ON t2 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT all on function to user when a temporary table is open.
+GRANT ALL ON f1 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT all on procedure to user when a temporary table is open.
+GRANT ALL ON p1 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT usage on *.* to user when a temporary table is open.
+GRANT USAGE ON *.* TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on function to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on table to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE usage on *.* from user when a temporary table is open.
+REVOKE USAGE ON *.* FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# RENAME USER when a temporary table is open.
+RENAME USER test_2@localhost TO test_3@localhost;
+INSERT INTO t1 VALUES (1);
+# DROP USER when a temporary table is open.
+DROP USER test_3@localhost;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE t3;
+END |
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (1);
+DROP PROCEDURE p2;
+INSERT INTO t1 VALUES (1);
+DROP FUNCTION f1;
+INSERT INTO t1 VALUES (1);
+DROP TABLE t2;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE t1;
=== added file 'mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test'
--- a/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test 2010-01-22 09:38:21 +0000
@@ -0,0 +1,11 @@
+#
+# Bug#49132
+# This test verifies if executing DDL statement before trying to manipulate
+# a temporary table causes row-based replication to break with error 'table
+# does not exist' base on ndb engine.
+#
+
+source include/have_ndb.inc;
+
+LET $ENGINE_TYPE= NDB;
+source extra/rpl_tests/rpl_tmp_table_and_DDL.test;
=== modified file 'mysql-test/suite/parts/inc/part_blocked_sql_funcs_main.inc'
--- a/mysql-test/suite/parts/inc/part_blocked_sql_funcs_main.inc 2007-11-20 15:04:07 +0000
+++ b/mysql-test/suite/parts/inc/part_blocked_sql_funcs_main.inc 2009-12-14 17:27:43 +0000
@@ -152,10 +152,16 @@ let $valsqlfunc = timestampdiff(YEAR,'20
let $coltype = datetime;
--source suite/parts/inc/partition_blocked_sql_funcs.inc
-let $sqlfunc = unix_timestamp(col1);
-let $valsqlfunc = unix_timestamp ('2002-05-01');
-let $coltype = date;
---source suite/parts/inc/partition_blocked_sql_funcs.inc
+################################################################################
+# After the fix for bug #42849 the server behavior does not fit into this test's
+# architecture: for UNIX_TIMESTAMP() some of the queries in
+# suite/parts/inc/partition_blocked_sql_funcs.inc will fail with a different
+# error (ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR) and some will succeed where
+################################################################################
+#let $sqlfunc = unix_timestamp(col1);
+#let $valsqlfunc = unix_timestamp ('2002-05-01');
+#let $coltype = date;
+#--source suite/parts/inc/partition_blocked_sql_funcs.inc
let $sqlfunc = week(col1);
let $valsqlfunc = week('2002-05-01');
=== modified file 'mysql-test/suite/parts/inc/partition_timestamp.inc'
--- a/mysql-test/suite/parts/inc/partition_timestamp.inc 2009-10-28 07:52:34 +0000
+++ b/mysql-test/suite/parts/inc/partition_timestamp.inc 2010-03-04 08:03:07 +0000
@@ -36,50 +36,57 @@ select count(*) from t2;
select * from t2;
drop table t2;
-eval create table t3 (a timestamp not null, primary key(a)) engine=$engine
-partition by range (month(a)) subpartition by key (a)
-subpartitions 3 (
-partition quarter1 values less than (4),
-partition quarter2 values less than (7),
-partition quarter3 values less than (10),
-partition quarter4 values less than (13)
-);
-show create table t3;
-let $count=12;
---echo $count inserts;
---disable_query_log
-begin;
-while ($count)
-{
-eval insert into t3 values (date_add('1970-01-01 00:00:00',interval $count-1 month));
-dec $count;
-}
-commit;
---enable_query_log
-select count(*) from t3;
-select * from t3;
-drop table t3;
+################################################################################
+# The following 2 tests are no longer valid after bug #42849 has been fixed:
+# it is not possible to use a timezone-dependent (such as month(timestamp_col)
+# or just a timestamp_col in a numeric context) anymore.
+################################################################################
-eval create table t4 (a timestamp not null, primary key(a)) engine=$engine
-partition by list (month(a)) subpartition by key (a)
-subpartitions 3 (
-partition quarter1 values in (0,1,2,3),
-partition quarter2 values in (4,5,6),
-partition quarter3 values in (7,8,9),
-partition quarter4 values in (10,11,12)
-);
-show create table t4;
-let $count=12;
---echo $count inserts;
---disable_query_log
-begin;
-while ($count)
-{
-eval insert into t4 values (date_add('1970-01-01 00:00:00',interval $count-1 month));
-dec $count;
-}
-commit;
---enable_query_log
-select count(*) from t4;
-select * from t4;
-drop table t4;
+# eval create table t3 (a timestamp not null, primary key(a)) engine=$engine
+# partition by range (month(a)) subpartition by key (a)
+# subpartitions 3 (
+# partition quarter1 values less than (4),
+# partition quarter2 values less than (7),
+# partition quarter3 values less than (10),
+# partition quarter4 values less than (13)
+# );
+# show create table t3;
+# let $count=12;
+# --echo $count inserts;
+# --disable_query_log
+# SET TIME_ZONE= '+03:00';
+# begin;
+# while ($count)
+# {
+# eval insert into t3 values (date_add('1970-01-01 00:00:00',interval $count-1 month));
+# dec $count;
+# }
+# commit;
+# --enable_query_log
+# select count(*) from t3;
+# select * from t3;
+# drop table t3;
+
+# eval create table t4 (a timestamp not null, primary key(a)) engine=$engine
+# partition by list (month(a)) subpartition by key (a)
+# subpartitions 3 (
+# partition quarter1 values in (0,1,2,3),
+# partition quarter2 values in (4,5,6),
+# partition quarter3 values in (7,8,9),
+# partition quarter4 values in (10,11,12)
+# );
+# show create table t4;
+# let $count=12;
+# --echo $count inserts;
+# --disable_query_log
+# begin;
+# while ($count)
+# {
+# eval insert into t4 values (date_add('1970-01-01 00:00:00',interval $count-1 month));
+# dec $count;
+# }
+# commit;
+# --enable_query_log
+# select count(*) from t4;
+# select * from t4;
+# drop table t4;
=== modified file 'mysql-test/suite/parts/r/part_blocked_sql_func_innodb.result'
--- a/mysql-test/suite/parts/r/part_blocked_sql_func_innodb.result 2007-08-27 20:08:32 +0000
+++ b/mysql-test/suite/parts/r/part_blocked_sql_func_innodb.result 2009-12-14 17:27:43 +0000
@@ -2942,104 +2942,6 @@ drop table if exists t44 ;
drop table if exists t55 ;
drop table if exists t66 ;
-------------------------------------------------------------------------
---- unix_timestamp(col1) in partition with coltype date
--------------------------------------------------------------------------
-must all fail!
-drop table if exists t1 ;
-drop table if exists t2 ;
-drop table if exists t3 ;
-drop table if exists t4 ;
-drop table if exists t5 ;
-drop table if exists t6 ;
-create table t1 (col1 date) engine='INNODB'
-partition by range(unix_timestamp(col1))
-(partition p0 values less than (15),
-partition p1 values less than (31));
-Got one of the listed errors
-create table t2 (col1 date) engine='INNODB'
-partition by list(unix_timestamp(col1))
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30));
-Got one of the listed errors
-create table t3 (col1 date) engine='INNODB'
-partition by hash(unix_timestamp(col1));
-Got one of the listed errors
-create table t4 (colint int, col1 date) engine='INNODB'
-partition by range(colint)
-subpartition by hash(unix_timestamp(col1)) subpartitions 2
-(partition p0 values less than (15),
-partition p1 values less than (31));
-Got one of the listed errors
-create table t5 (colint int, col1 date) engine='INNODB'
-partition by list(colint)
-subpartition by hash(unix_timestamp(col1)) subpartitions 2
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30));
-Got one of the listed errors
-create table t6 (colint int, col1 date) engine='INNODB'
-partition by range(colint)
-(partition p0 values less than (unix_timestamp ('2002-05-01')),
-partition p1 values less than maxvalue);
-Got one of the listed errors
-drop table if exists t11 ;
-drop table if exists t22 ;
-drop table if exists t33 ;
-drop table if exists t44 ;
-drop table if exists t55 ;
-drop table if exists t66 ;
-create table t11 (col1 date) engine='INNODB' ;
-create table t22 (col1 date) engine='INNODB' ;
-create table t33 (col1 date) engine='INNODB' ;
-create table t44 (colint int, col1 date) engine='INNODB' ;
-create table t55 (colint int, col1 date) engine='INNODB' ;
-create table t66 (colint int, col1 date) engine='INNODB' ;
-alter table t11
-partition by range(unix_timestamp(col1))
-(partition p0 values less than (15),
-partition p1 values less than (31));
-Got one of the listed errors
-alter table t22
-partition by list(unix_timestamp(col1))
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30));
-Got one of the listed errors
-alter table t33
-partition by hash(unix_timestamp(col1));
-Got one of the listed errors
-alter table t44
-partition by range(colint)
-subpartition by hash(unix_timestamp(col1)) subpartitions 2
-(partition p0 values less than (15),
-partition p1 values less than (31));
-Got one of the listed errors
-alter table t55
-partition by list(colint)
-subpartition by hash(unix_timestamp(col1)) subpartitions 2
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30));
-Got one of the listed errors
-alter table t66
-partition by range(colint)
-(partition p0 values less than (unix_timestamp ('2002-05-01')),
-partition p1 values less than maxvalue);
-Got one of the listed errors
-drop table if exists t1 ;
-drop table if exists t2 ;
-drop table if exists t3 ;
-drop table if exists t4 ;
-drop table if exists t5 ;
-drop table if exists t6 ;
-drop table if exists t11 ;
-drop table if exists t22 ;
-drop table if exists t33 ;
-drop table if exists t44 ;
-drop table if exists t55 ;
-drop table if exists t66 ;
--------------------------------------------------------------------------
--- week(col1) in partition with coltype datetime
-------------------------------------------------------------------------
must all fail!
=== modified file 'mysql-test/suite/parts/r/part_blocked_sql_func_myisam.result'
--- a/mysql-test/suite/parts/r/part_blocked_sql_func_myisam.result 2007-08-27 20:08:32 +0000
+++ b/mysql-test/suite/parts/r/part_blocked_sql_func_myisam.result 2009-12-14 17:27:43 +0000
@@ -2942,104 +2942,6 @@ drop table if exists t44 ;
drop table if exists t55 ;
drop table if exists t66 ;
-------------------------------------------------------------------------
---- unix_timestamp(col1) in partition with coltype date
--------------------------------------------------------------------------
-must all fail!
-drop table if exists t1 ;
-drop table if exists t2 ;
-drop table if exists t3 ;
-drop table if exists t4 ;
-drop table if exists t5 ;
-drop table if exists t6 ;
-create table t1 (col1 date) engine='MYISAM'
-partition by range(unix_timestamp(col1))
-(partition p0 values less than (15),
-partition p1 values less than (31));
-Got one of the listed errors
-create table t2 (col1 date) engine='MYISAM'
-partition by list(unix_timestamp(col1))
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30));
-Got one of the listed errors
-create table t3 (col1 date) engine='MYISAM'
-partition by hash(unix_timestamp(col1));
-Got one of the listed errors
-create table t4 (colint int, col1 date) engine='MYISAM'
-partition by range(colint)
-subpartition by hash(unix_timestamp(col1)) subpartitions 2
-(partition p0 values less than (15),
-partition p1 values less than (31));
-Got one of the listed errors
-create table t5 (colint int, col1 date) engine='MYISAM'
-partition by list(colint)
-subpartition by hash(unix_timestamp(col1)) subpartitions 2
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30));
-Got one of the listed errors
-create table t6 (colint int, col1 date) engine='MYISAM'
-partition by range(colint)
-(partition p0 values less than (unix_timestamp ('2002-05-01')),
-partition p1 values less than maxvalue);
-Got one of the listed errors
-drop table if exists t11 ;
-drop table if exists t22 ;
-drop table if exists t33 ;
-drop table if exists t44 ;
-drop table if exists t55 ;
-drop table if exists t66 ;
-create table t11 (col1 date) engine='MYISAM' ;
-create table t22 (col1 date) engine='MYISAM' ;
-create table t33 (col1 date) engine='MYISAM' ;
-create table t44 (colint int, col1 date) engine='MYISAM' ;
-create table t55 (colint int, col1 date) engine='MYISAM' ;
-create table t66 (colint int, col1 date) engine='MYISAM' ;
-alter table t11
-partition by range(unix_timestamp(col1))
-(partition p0 values less than (15),
-partition p1 values less than (31));
-Got one of the listed errors
-alter table t22
-partition by list(unix_timestamp(col1))
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30));
-Got one of the listed errors
-alter table t33
-partition by hash(unix_timestamp(col1));
-Got one of the listed errors
-alter table t44
-partition by range(colint)
-subpartition by hash(unix_timestamp(col1)) subpartitions 2
-(partition p0 values less than (15),
-partition p1 values less than (31));
-Got one of the listed errors
-alter table t55
-partition by list(colint)
-subpartition by hash(unix_timestamp(col1)) subpartitions 2
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30));
-Got one of the listed errors
-alter table t66
-partition by range(colint)
-(partition p0 values less than (unix_timestamp ('2002-05-01')),
-partition p1 values less than maxvalue);
-Got one of the listed errors
-drop table if exists t1 ;
-drop table if exists t2 ;
-drop table if exists t3 ;
-drop table if exists t4 ;
-drop table if exists t5 ;
-drop table if exists t6 ;
-drop table if exists t11 ;
-drop table if exists t22 ;
-drop table if exists t33 ;
-drop table if exists t44 ;
-drop table if exists t55 ;
-drop table if exists t66 ;
--------------------------------------------------------------------------
--- week(col1) in partition with coltype datetime
-------------------------------------------------------------------------
must all fail!
=== modified file 'mysql-test/suite/parts/r/partition_datetime_innodb.result'
--- a/mysql-test/suite/parts/r/partition_datetime_innodb.result 2009-10-28 07:52:34 +0000
+++ b/mysql-test/suite/parts/r/partition_datetime_innodb.result 2010-03-04 08:03:07 +0000
@@ -125,90 +125,6 @@ a
1971-01-01 00:00:58
1971-01-01 00:00:59
drop table t2;
-create table t3 (a timestamp not null, primary key(a)) engine='InnoDB'
-partition by range (month(a)) subpartition by key (a)
-subpartitions 3 (
-partition quarter1 values less than (4),
-partition quarter2 values less than (7),
-partition quarter3 values less than (10),
-partition quarter4 values less than (13)
-);
-show create table t3;
-Table Create Table
-t3 CREATE TABLE `t3` (
- `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`a`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY RANGE (month(a))
-SUBPARTITION BY KEY (a)
-SUBPARTITIONS 3
-(PARTITION quarter1 VALUES LESS THAN (4) ENGINE = InnoDB,
- PARTITION quarter2 VALUES LESS THAN (7) ENGINE = InnoDB,
- PARTITION quarter3 VALUES LESS THAN (10) ENGINE = InnoDB,
- PARTITION quarter4 VALUES LESS THAN (13) ENGINE = InnoDB) */
-12 inserts;
-Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
-select count(*) from t3;
-count(*)
-12
-select * from t3;
-a
-0000-00-00 00:00:00
-1970-02-01 00:00:00
-1970-03-01 00:00:00
-1970-04-01 00:00:00
-1970-05-01 00:00:00
-1970-06-01 00:00:00
-1970-07-01 00:00:00
-1970-08-01 00:00:00
-1970-09-01 00:00:00
-1970-10-01 00:00:00
-1970-11-01 00:00:00
-1970-12-01 00:00:00
-drop table t3;
-create table t4 (a timestamp not null, primary key(a)) engine='InnoDB'
-partition by list (month(a)) subpartition by key (a)
-subpartitions 3 (
-partition quarter1 values in (0,1,2,3),
-partition quarter2 values in (4,5,6),
-partition quarter3 values in (7,8,9),
-partition quarter4 values in (10,11,12)
-);
-show create table t4;
-Table Create Table
-t4 CREATE TABLE `t4` (
- `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`a`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY LIST (month(a))
-SUBPARTITION BY KEY (a)
-SUBPARTITIONS 3
-(PARTITION quarter1 VALUES IN (0,1,2,3) ENGINE = InnoDB,
- PARTITION quarter2 VALUES IN (4,5,6) ENGINE = InnoDB,
- PARTITION quarter3 VALUES IN (7,8,9) ENGINE = InnoDB,
- PARTITION quarter4 VALUES IN (10,11,12) ENGINE = InnoDB) */
-12 inserts;
-Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
-select count(*) from t4;
-count(*)
-12
-select * from t4;
-a
-0000-00-00 00:00:00
-1970-02-01 00:00:00
-1970-03-01 00:00:00
-1970-04-01 00:00:00
-1970-05-01 00:00:00
-1970-06-01 00:00:00
-1970-07-01 00:00:00
-1970-08-01 00:00:00
-1970-09-01 00:00:00
-1970-10-01 00:00:00
-1970-11-01 00:00:00
-1970-12-01 00:00:00
-drop table t4;
create table t1 (a date not null, primary key(a)) engine='InnoDB'
partition by key (a) (
partition pa1 max_rows=20 min_rows=2,
=== modified file 'mysql-test/suite/parts/r/partition_datetime_myisam.result'
--- a/mysql-test/suite/parts/r/partition_datetime_myisam.result 2009-10-28 07:52:34 +0000
+++ b/mysql-test/suite/parts/r/partition_datetime_myisam.result 2010-03-04 08:03:07 +0000
@@ -125,90 +125,6 @@ a
1971-01-01 00:00:58
1971-01-01 00:00:59
drop table t2;
-create table t3 (a timestamp not null, primary key(a)) engine='MyISAM'
-partition by range (month(a)) subpartition by key (a)
-subpartitions 3 (
-partition quarter1 values less than (4),
-partition quarter2 values less than (7),
-partition quarter3 values less than (10),
-partition quarter4 values less than (13)
-);
-show create table t3;
-Table Create Table
-t3 CREATE TABLE `t3` (
- `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`a`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY RANGE (month(a))
-SUBPARTITION BY KEY (a)
-SUBPARTITIONS 3
-(PARTITION quarter1 VALUES LESS THAN (4) ENGINE = MyISAM,
- PARTITION quarter2 VALUES LESS THAN (7) ENGINE = MyISAM,
- PARTITION quarter3 VALUES LESS THAN (10) ENGINE = MyISAM,
- PARTITION quarter4 VALUES LESS THAN (13) ENGINE = MyISAM) */
-12 inserts;
-Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
-select count(*) from t3;
-count(*)
-12
-select * from t3;
-a
-0000-00-00 00:00:00
-1970-02-01 00:00:00
-1970-03-01 00:00:00
-1970-04-01 00:00:00
-1970-05-01 00:00:00
-1970-06-01 00:00:00
-1970-07-01 00:00:00
-1970-08-01 00:00:00
-1970-09-01 00:00:00
-1970-10-01 00:00:00
-1970-11-01 00:00:00
-1970-12-01 00:00:00
-drop table t3;
-create table t4 (a timestamp not null, primary key(a)) engine='MyISAM'
-partition by list (month(a)) subpartition by key (a)
-subpartitions 3 (
-partition quarter1 values in (0,1,2,3),
-partition quarter2 values in (4,5,6),
-partition quarter3 values in (7,8,9),
-partition quarter4 values in (10,11,12)
-);
-show create table t4;
-Table Create Table
-t4 CREATE TABLE `t4` (
- `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`a`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY LIST (month(a))
-SUBPARTITION BY KEY (a)
-SUBPARTITIONS 3
-(PARTITION quarter1 VALUES IN (0,1,2,3) ENGINE = MyISAM,
- PARTITION quarter2 VALUES IN (4,5,6) ENGINE = MyISAM,
- PARTITION quarter3 VALUES IN (7,8,9) ENGINE = MyISAM,
- PARTITION quarter4 VALUES IN (10,11,12) ENGINE = MyISAM) */
-12 inserts;
-Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
-select count(*) from t4;
-count(*)
-12
-select * from t4;
-a
-0000-00-00 00:00:00
-1970-02-01 00:00:00
-1970-03-01 00:00:00
-1970-04-01 00:00:00
-1970-05-01 00:00:00
-1970-06-01 00:00:00
-1970-07-01 00:00:00
-1970-08-01 00:00:00
-1970-09-01 00:00:00
-1970-10-01 00:00:00
-1970-11-01 00:00:00
-1970-12-01 00:00:00
-drop table t4;
create table t1 (a date not null, primary key(a)) engine='MyISAM'
partition by key (a) (
partition pa1 max_rows=20 min_rows=2,
=== modified file 'mysql-test/suite/parts/r/partition_recover_myisam.result'
--- a/mysql-test/suite/parts/r/partition_recover_myisam.result 2009-08-29 21:29:47 +0000
+++ b/mysql-test/suite/parts/r/partition_recover_myisam.result 2010-01-27 17:41:05 +0000
@@ -1,5 +1,3 @@
-call mtr.add_suppression("./test/t1_will_crash");
-call mtr.add_suppression("Got an error from unknown thread, ha_myisam.cc");
CREATE TABLE t1_will_crash (a INT, KEY (a)) ENGINE=MyISAM;
INSERT INTO t1_will_crash VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);
FLUSH TABLES;
=== modified file 'mysql-test/suite/parts/t/partition_alter1_2_innodb.test'
--- a/mysql-test/suite/parts/t/partition_alter1_2_innodb.test 2009-10-09 13:08:09 +0000
+++ b/mysql-test/suite/parts/t/partition_alter1_2_innodb.test 2010-01-15 15:27:55 +0000
@@ -28,6 +28,8 @@
#------------------------------------------------------------------------------#
# General not engine specific settings and requirements
+--source include/big_test.inc
+
##### Options, for debugging support #####
let $debug= 0;
let $with_partitioning= 1;
=== modified file 'mysql-test/suite/parts/t/partition_alter2_1_innodb.test'
--- a/mysql-test/suite/parts/t/partition_alter2_1_innodb.test 2009-10-09 13:08:09 +0000
+++ b/mysql-test/suite/parts/t/partition_alter2_1_innodb.test 2010-01-15 15:27:55 +0000
@@ -22,6 +22,8 @@
# any of the variables.
#
+--source include/big_test.inc
+
#------------------------------------------------------------------------------#
# General not engine specific settings and requirements
=== modified file 'mysql-test/suite/parts/t/partition_alter2_2_innodb.test'
--- a/mysql-test/suite/parts/t/partition_alter2_2_innodb.test 2009-10-09 13:08:09 +0000
+++ b/mysql-test/suite/parts/t/partition_alter2_2_innodb.test 2010-01-15 15:27:55 +0000
@@ -22,6 +22,8 @@
# any of the variables.
#
+--source include/big_test.inc
+
#------------------------------------------------------------------------------#
# General not engine specific settings and requirements
=== modified file 'mysql-test/suite/parts/t/partition_alter4_innodb.test'
--- a/mysql-test/suite/parts/t/partition_alter4_innodb.test 2009-10-09 13:08:09 +0000
+++ b/mysql-test/suite/parts/t/partition_alter4_innodb.test 2010-01-15 15:27:55 +0000
@@ -22,6 +22,8 @@
# any of the variables.
#
+--source include/big_test.inc
+
#------------------------------------------------------------------------------#
# General not engine specific settings and requirements
=== modified file 'mysql-test/suite/parts/t/partition_recover_myisam.test'
--- a/mysql-test/suite/parts/t/partition_recover_myisam.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/suite/parts/t/partition_recover_myisam.test 2010-01-27 17:41:05 +0000
@@ -1,7 +1,9 @@
# test the auto-recover (--myisam-recover) of partitioned myisam tables
-call mtr.add_suppression("./test/t1_will_crash");
+--disable_query_log
+call mtr.add_suppression("..test.t1_will_crash");
call mtr.add_suppression("Got an error from unknown thread, ha_myisam.cc");
+--enable_query_log
--source include/have_partition.inc
--disable_warnings
=== added file 'mysql-test/suite/parts/t/partition_repair_myisam-master.opt'
--- a/mysql-test/suite/parts/t/partition_repair_myisam-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/parts/t/partition_repair_myisam-master.opt 2010-02-10 21:26:06 +0000
@@ -0,0 +1 @@
+--myisam-recover=off
=== modified file 'mysql-test/suite/parts/t/rpl_partition.test'
--- a/mysql-test/suite/parts/t/rpl_partition.test 2009-02-01 12:00:48 +0000
+++ b/mysql-test/suite/parts/t/rpl_partition.test 2010-03-29 19:07:45 +0000
@@ -1,6 +1,7 @@
--source include/have_partition.inc
--source include/have_innodb.inc
--source include/master-slave.inc
+--source include/big_test.inc
--vertical_results
=== modified file 'mysql-test/suite/pbxt/r/func_group.result'
--- a/mysql-test/suite/pbxt/r/func_group.result 2009-11-24 10:19:08 +0000
+++ b/mysql-test/suite/pbxt/r/func_group.result 2010-01-16 05:12:57 +0000
@@ -885,7 +885,7 @@ cast(sum(distinct df) as signed)
3
select cast(min(df) as signed) from t1;
cast(min(df) as signed)
-0
+1
select 1e8 * sum(distinct df) from t1;
1e8 * sum(distinct df)
330000000
=== modified file 'mysql-test/suite/pbxt/r/lock_multi.result'
--- a/mysql-test/suite/pbxt/r/lock_multi.result 2009-04-02 10:03:14 +0000
+++ b/mysql-test/suite/pbxt/r/lock_multi.result 2010-01-06 21:27:53 +0000
@@ -1,22 +1,4 @@
drop table if exists t1,t2;
-create table t1(n int);
-insert into t1 values (1);
-lock tables t1 write;
-update low_priority t1 set n = 4;
-select n from t1;
-unlock tables;
-n
-1
-drop table t1;
-create table t1(n int);
-insert into t1 values (1);
-lock tables t1 read;
-update low_priority t1 set n = 4;
-select n from t1;
-unlock tables;
-n
-1
-drop table t1;
create table t1 (a int, b int);
create table t2 (c int, d int);
insert into t1 values(1,1);
@@ -43,6 +25,7 @@ insert t1 select * from t2;
drop table t2;
ERROR 42S02: Table 'test.t2' doesn't exist
drop table t1;
+End of 4.1 tests
create table t1(a int);
lock tables t1 write;
show columns from t1;
@@ -50,10 +33,10 @@ Field Type Null Key Default Extra
a int(11) YES NULL
unlock tables;
drop table t1;
-use mysql;
+USE mysql;
LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
FLUSH TABLES;
-use mysql;
+USE mysql;
SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
OPTIMIZE TABLES columns_priv, db, host, user;
Table Op Msg_type Msg_text
@@ -63,7 +46,8 @@ mysql.host optimize status OK
mysql.user optimize status OK
UNLOCK TABLES;
Select_priv
-use test;
+N
+USE test;
use test;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
@@ -90,7 +74,115 @@ DROP DATABASE mysqltest_1;
ERROR HY000: Can't drop database 'mysqltest_1'; database doesn't exist
create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb;
lock tables t1 write;
-alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
-alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
+alter table t1 auto_increment=0;
+alter table t1 auto_increment=0;
+unlock tables;
+drop table t1;
+create table t1 (a int);
+create table t2 like t1;
+# con1
+lock tables t1 write;
+# con2
+flush tables with read lock;
+# con5
+# global read lock is taken
+# con3
+select * from t2 for update;
+# waiting for release of read lock
+# con4
+# would hang and later cause a deadlock
+flush tables t2;
+# clean up
+unlock tables;
+unlock tables;
+a
+drop table t1,t2;
+#
+# Lightweight version:
+# Ensure that the wait for a GRL is done before opening tables.
+#
+create table t1 (a int);
+create table t2 like t1;
+#
+# UPDATE
+#
+# default
+flush tables with read lock;
+# con1
+update t2 set a = 1;
+# default
+# statement is waiting for release of read lock
+# con2
+flush table t2;
+# default
+unlock tables;
+# con1
+#
+# LOCK TABLES .. WRITE
+#
+# default
+flush tables with read lock;
+# con1
+lock tables t2 write;
+# default
+# statement is waiting for release of read lock
+# con2
+flush table t2;
+# default
+unlock tables;
+# con1
+unlock tables;
+drop table t1,t2;
+End of 5.0 tests
+create table t1 (i int);
+lock table t1 read;
+update t1 set i= 10;
+select * from t1;
+Timeout in wait_condition.inc for select count(*) = 1 from information_schema.processlist
+where state = "Locked" and info = "select * from t1"
+kill query ID;
+i
+ERROR 70100: Query execution was interrupted
+unlock tables;
+drop table t1;
+drop table if exists t1;
+create table t1 (i int);
+connection: default
+lock tables t1 write;
+connection: flush
+flush tables with read lock;;
+connection: default
+alter table t1 add column j int;
+connection: insert
+insert into t1 values (1,2);;
+connection: default
+unlock tables;
+connection: flush
+select * from t1;
+i j
+unlock tables;
+select * from t1;
+i j
+1 2
+drop table t1;
+drop table if exists t1;
+create table t1 (i int);
+connection: default
+lock tables t1 write;
+connection: flush
+flush tables with read lock;;
+connection: default
+flush tables;
+unlock tables;
+drop table t1;
+drop table if exists t1,t2;
+create table t1 (a int);
+flush status;
+lock tables t1 read;
+insert into t1 values(1);;
unlock tables;
drop table t1;
+select @tlwa < @tlwb;
+@tlwa < @tlwb
+1
+End of 5.1 tests
=== modified file 'mysql-test/suite/pbxt/r/mysqlshow.result'
--- a/mysql-test/suite/pbxt/r/mysqlshow.result 2009-08-17 15:57:58 +0000
+++ b/mysql-test/suite/pbxt/r/mysqlshow.result 2010-01-16 05:12:57 +0000
@@ -113,7 +113,7 @@ Database: information_schema
| INNODB_RSEG |
| XTRADB_ENHANCEMENTS |
| INNODB_BUFFER_POOL_PAGES_INDEX |
-| INNODB_INDEX_STATS |
+| XTRADB_ADMIN_COMMAND |
| INNODB_TRX |
| INNODB_CMP_RESET |
| INNODB_LOCK_WAITS |
@@ -122,6 +122,7 @@ Database: information_schema
| INNODB_CMPMEM |
| INNODB_TABLE_STATS |
| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_INDEX_STATS |
+---------------------------------------+
Database: INFORMATION_SCHEMA
+---------------------------------------+
@@ -161,7 +162,7 @@ Database: INFORMATION_SCHEMA
| INNODB_RSEG |
| XTRADB_ENHANCEMENTS |
| INNODB_BUFFER_POOL_PAGES_INDEX |
-| INNODB_INDEX_STATS |
+| XTRADB_ADMIN_COMMAND |
| INNODB_TRX |
| INNODB_CMP_RESET |
| INNODB_LOCK_WAITS |
@@ -170,6 +171,7 @@ Database: INFORMATION_SCHEMA
| INNODB_CMPMEM |
| INNODB_TABLE_STATS |
| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_INDEX_STATS |
+---------------------------------------+
Wildcard: inf_rmation_schema
+--------------------+
=== modified file 'mysql-test/suite/pbxt/r/partition_error.result'
--- a/mysql-test/suite/pbxt/r/partition_error.result 2009-04-02 10:03:14 +0000
+++ b/mysql-test/suite/pbxt/r/partition_error.result 2010-03-09 15:03:54 +0000
@@ -107,7 +107,7 @@ primary key(a,b))
partition by hash (rand(a))
partitions 2
(partition x1, partition x2);
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')
partitions 2
(partition x1, partition x2)' at line 6
CREATE TABLE t1 (
@@ -118,7 +118,7 @@ primary key(a,b))
partition by range (rand(a))
partitions 2
(partition x1 values less than (0), partition x2 values less than (2));
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')
partitions 2
(partition x1 values less than (0), partition x2 values less than' at line 6
CREATE TABLE t1 (
@@ -129,7 +129,7 @@ primary key(a,b))
partition by list (rand(a))
partitions 2
(partition x1 values in (1), partition x2 values in (2));
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')
partitions 2
(partition x1 values in (1), partition x2 values in (2))' at line 6
CREATE TABLE t1 (
@@ -244,7 +244,7 @@ c int not null,
primary key (a,b))
partition by key (a)
subpartition by hash (rand(a+b));
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 7
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 7
CREATE TABLE t1 (
a int not null,
b int not null,
@@ -341,7 +341,7 @@ partition by range (3+4)
partitions 2
(partition x1 values less than (4) tablespace ts1,
partition x2 values less than (8) tablespace ts2);
-ERROR HY000: Constant/Random expression in (sub)partitioning function is not allowed
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
CREATE TABLE t1 (
a int not null,
b int not null,
@@ -511,7 +511,7 @@ partition by list (3+4)
partitions 2
(partition x1 values in (4) tablespace ts1,
partition x2 values in (8) tablespace ts2);
-ERROR HY000: Constant/Random expression in (sub)partitioning function is not allowed
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
CREATE TABLE t1 (
a int not null,
b int not null,
@@ -603,13 +603,13 @@ partition by range (ascii(v))
ERROR HY000: This partition function is not allowed
create table t1 (a int)
partition by hash (rand(a));
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2
create table t1 (a int)
partition by hash(CURTIME() + a);
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2
create table t1 (a int)
partition by hash (NOW()+a);
-ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2
create table t1 (a int)
partition by hash (extract(hour from convert_tz(a, '+00:00', '+00:00')));
ERROR HY000: This partition function is not allowed
=== modified file 'mysql-test/suite/pbxt/r/partition_pruning.result'
--- a/mysql-test/suite/pbxt/r/partition_pruning.result 2009-08-17 15:57:58 +0000
+++ b/mysql-test/suite/pbxt/r/partition_pruning.result 2010-03-09 15:03:54 +0000
@@ -527,7 +527,7 @@ id select_type table partitions type pos
1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 910 Using where
explain partitions select * from t2 where (a > 100 AND a < 600);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 p0,p1,p2,p3 ALL NULL NULL NULL NULL 910 Using where
+1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 910 Using where
analyze table t2;
Table Op Msg_type Msg_text
test.t2 analyze status OK
=== added file 'mysql-test/suite/pbxt/r/pbxt_xa.result'
--- a/mysql-test/suite/pbxt/r/pbxt_xa.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/r/pbxt_xa.result 2010-03-24 22:12:39 +0000
@@ -0,0 +1,18 @@
+drop table if exists t1, t2;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+SELECT @@log_bin;
+@@log_bin
+0
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+a
+1
+select * from t2;
+b
+2
+drop table t1, t2;
+drop database pbxt;
=== modified file 'mysql-test/suite/pbxt/t/lock_multi.test'
--- a/mysql-test/suite/pbxt/t/lock_multi.test 2009-04-02 10:03:14 +0000
+++ b/mysql-test/suite/pbxt/t/lock_multi.test 2010-01-06 21:27:53 +0000
@@ -1,4 +1,8 @@
-- source include/not_embedded.inc
+
+# Save the initial number of concurrent sessions
+--source include/count_sessions.inc
+
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
@@ -9,42 +13,6 @@ connect (locker,localhost,root,,);
connect (reader,localhost,root,,);
connect (writer,localhost,root,,);
-connection locker;
-create table t1(n int);
-insert into t1 values (1);
-lock tables t1 write;
-connection writer;
-send update low_priority t1 set n = 4;
-connection reader;
---sleep 2
-send select n from t1;
-connection locker;
---sleep 2
-unlock tables;
-connection writer;
-reap;
-connection reader;
-reap;
-drop table t1;
-
-connection locker;
-create table t1(n int);
-insert into t1 values (1);
-lock tables t1 read;
-connection writer;
-send update low_priority t1 set n = 4;
-connection reader;
---sleep 2
-send select n from t1;
-connection locker;
---sleep 2
-unlock tables;
-connection writer;
-reap;
-connection reader;
-reap;
-drop table t1;
-
#
# Test problem when using locks with multi-updates
# It should not block when multi-update is reading on a read-locked table
@@ -58,32 +26,33 @@ insert into t1 values(2,2);
insert into t2 values(1,2);
lock table t1 read;
connection writer;
---sleep 2
-send update t1,t2 set c=a where b=d;
+update t1,t2 set c=a where b=d;
connection reader;
---sleep 2
select c from t2;
-connection writer;
-reap;
connection locker;
drop table t1;
drop table t2;
#
-# Test problem when using locks on many tables and droping a table that
+# Test problem when using locks on many tables and dropping a table that
# is to-be-locked by another thread
#
-
+#
connection locker;
create table t1 (a int);
create table t2 (a int);
lock table t1 write, t2 write;
connection reader;
-send insert t1 select * from t2;
+send
+insert t1 select * from t2;
connection locker;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Locked" and info = "insert t1 select * from t2";
+--source include/wait_condition.inc
drop table t2;
connection reader;
---error 1146
+--error ER_NO_SUCH_TABLE
reap;
connection locker;
drop table t1;
@@ -97,20 +66,26 @@ create table t1 (a int);
create table t2 (a int);
lock table t1 write, t2 write, t1 as t1_2 write, t2 as t2_2 write;
connection reader;
-send insert t1 select * from t2;
+send
+insert t1 select * from t2;
connection locker;
+# Sleep a bit till the insert of connection reader is in work and hangs
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Locked" and info = "insert t1 select * from t2";
+--source include/wait_condition.inc
drop table t2;
connection reader;
---error 1146
+--error ER_NO_SUCH_TABLE
reap;
connection locker;
drop table t1;
-# End of 4.1 tests
+--echo End of 4.1 tests
#
-# BUG#9998 - MySQL client hangs on USE "database"
+# Bug#9998 MySQL client hangs on USE "database"
#
create table t1(a int);
lock tables t1 write;
@@ -121,21 +96,30 @@ unlock tables;
drop table t1;
#
-# Bug#16986 - Deadlock condition with MyISAM tables
+# Bug#16986 Deadlock condition with MyISAM tables
#
+
+# Need a matching user in mysql.user for multi-table select
+--source include/add_anonymous_users.inc
+
connection locker;
-use mysql;
+USE mysql;
LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
FLUSH TABLES;
---sleep 1
#
connection reader;
-use mysql;
-#NOTE: This must be a multi-table select, otherwise the deadlock will not occur
-send SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
---sleep 1
+USE mysql;
+# Note: This must be a multi-table select, otherwise the deadlock will not occur
+send
+SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
#
connection locker;
+# Sleep a bit till the select of connection reader is in work and hangs
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info =
+ "SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1";
+--source include/wait_condition.inc
# Make test case independent from earlier grants.
--replace_result "Table is already up to date" "OK"
OPTIMIZE TABLES columns_priv, db, host, user;
@@ -143,7 +127,7 @@ UNLOCK TABLES;
#
connection reader;
reap;
-use test;
+USE test;
#
connection locker;
use test;
@@ -158,11 +142,16 @@ LOCK TABLE t1 WRITE;
#
# This waits until t1 is unlocked.
connection locker;
-send FLUSH TABLES WITH READ LOCK;
---sleep 1
+send
+FLUSH TABLES WITH READ LOCK;
#
-# This must not block.
connection writer;
+# Sleep a bit till the flush of connection locker is in work and hangs
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables" and info = "FLUSH TABLES WITH READ LOCK";
+--source include/wait_condition.inc
+# This must not block.
CREATE TABLE t2 (c1 int);
UNLOCK TABLES;
#
@@ -182,12 +171,17 @@ LOCK TABLE t1 WRITE;
#
# This waits until t1 is unlocked.
connection locker;
-send FLUSH TABLES WITH READ LOCK;
---sleep 1
+send
+FLUSH TABLES WITH READ LOCK;
#
# This must not block.
connection writer;
---error 1100
+# Sleep a bit till the flush of connection locker is in work and hangs
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables" and info = "FLUSH TABLES WITH READ LOCK";
+--source include/wait_condition.inc
+--error ER_TABLE_NOT_LOCKED
CREATE TABLE t2 AS SELECT * FROM t1;
UNLOCK TABLES;
#
@@ -199,8 +193,10 @@ UNLOCK TABLES;
connection default;
DROP TABLE t1;
+--source include/delete_anonymous_users.inc
+
#
-# Bug#19815 - CREATE/RENAME/DROP DATABASE can deadlock on a global read lock
+# Bug#19815 CREATE/RENAME/DROP DATABASE can deadlock on a global read lock
#
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
@@ -212,12 +208,18 @@ FLUSH TABLES WITH READ LOCK;
# With bug in place: acquire LOCK_mysql_create_table and
# wait in wait_if_global_read_lock().
connection con2;
-send DROP DATABASE mysqltest_1;
---sleep 1
+send
+DROP DATABASE mysqltest_1;
#
# With bug in place: try to acquire LOCK_mysql_create_table...
# When fixed: Reject dropping db because of the read lock.
connection con1;
+# Wait a bit so that the session con2 is in state "Waiting for release of readlock"
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for release of readlock"
+ and info = "DROP DATABASE mysqltest_1";
+--source include/wait_condition.inc
--error ER_CANT_UPDATE_WITH_READLOCK
DROP DATABASE mysqltest_1;
UNLOCK TABLES;
@@ -234,7 +236,7 @@ disconnect con2;
DROP DATABASE mysqltest_1;
#
-# Bug #17264: MySQL Server freeze
+# Bug#17264 MySQL Server freeze
#
connection locker;
# Disable warnings to allow test to run also without InnoDB
@@ -243,17 +245,22 @@ create table t1 (f1 int(12) unsigned not
--enable_warnings
lock tables t1 write;
connection writer;
---sleep 2
-delimiter //;
-send alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
-delimiter ;//
-connection reader;
---sleep 2
-delimiter //;
-send alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
-delimiter ;//
-connection locker;
---sleep 2
+send
+alter table t1 auto_increment=0;
+connection reader;
+# Wait till connection writer is blocked
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Locked" and info = "alter table t1 auto_increment=0";
+--source include/wait_condition.inc
+send
+alter table t1 auto_increment=0;
+connection locker;
+# Wait till connection reader is blocked
+let $wait_condition=
+ select count(*) = 2 from information_schema.processlist
+ where state = "Locked" and info = "alter table t1 auto_increment=0";
+--source include/wait_condition.inc
unlock tables;
connection writer;
reap;
@@ -262,8 +269,310 @@ reap;
connection locker;
drop table t1;
+#
+# Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely
+#
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+connect (con3,localhost,root,,);
+connect (con4,localhost,root,,);
+connect (con5,localhost,root,,);
+
+create table t1 (a int);
+create table t2 like t1;
+
+connection con1;
+--echo # con1
+lock tables t1 write;
+connection con2;
+--echo # con2
+send flush tables with read lock;
+connection con5;
+--echo # con5
+let $show_statement= SHOW PROCESSLIST;
+let $field= State;
+let $condition= = 'Flushing tables';
+--source include/wait_show_condition.inc
+--echo # global read lock is taken
+connection con3;
+--echo # con3
+send select * from t2 for update;
+connection con5;
+let $show_statement= SHOW PROCESSLIST;
+let $field= State;
+let $condition= = 'Waiting for release of readlock';
+--source include/wait_show_condition.inc
+--echo # waiting for release of read lock
+connection con4;
+--echo # con4
+--echo # would hang and later cause a deadlock
+flush tables t2;
+connection con1;
+--echo # clean up
+unlock tables;
+connection con2;
+--reap
+unlock tables;
+connection con3;
+--reap
+connection default;
+disconnect con5;
+disconnect con4;
+disconnect con3;
+disconnect con2;
+disconnect con1;
+
+drop table t1,t2;
+
+--echo #
+--echo # Lightweight version:
+--echo # Ensure that the wait for a GRL is done before opening tables.
+--echo #
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+create table t1 (a int);
+create table t2 like t1;
+
+--echo #
+--echo # UPDATE
+--echo #
+
+connection default;
+--echo # default
+flush tables with read lock;
+connection con1;
+--echo # con1
+send update t2 set a = 1;
+connection default;
+--echo # default
+let $show_statement= SHOW PROCESSLIST;
+let $field= State;
+let $condition= = 'Waiting for release of readlock';
+--source include/wait_show_condition.inc
+--echo # statement is waiting for release of read lock
+connection con2;
+--echo # con2
+flush table t2;
+connection default;
+--echo # default
+unlock tables;
+connection con1;
+--echo # con1
+--reap
+
+--echo #
+--echo # LOCK TABLES .. WRITE
+--echo #
+
+connection default;
+--echo # default
+flush tables with read lock;
+connection con1;
+--echo # con1
+send lock tables t2 write;
+connection default;
+--echo # default
+let $show_statement= SHOW PROCESSLIST;
+let $field= State;
+let $condition= = 'Waiting for release of readlock';
+--source include/wait_show_condition.inc
+--echo # statement is waiting for release of read lock
+connection con2;
+--echo # con2
+flush table t2;
+connection default;
+--echo # default
+unlock tables;
+connection con1;
+--echo # con1
+--reap
+unlock tables;
+
+connection default;
+disconnect con2;
+disconnect con1;
+
+drop table t1,t2;
+
+
+--echo End of 5.0 tests
+
+
+#
+# Bug#21281 Pending write lock is incorrectly removed when its
+# statement being KILLed
+#
+create table t1 (i int);
+connection locker;
+lock table t1 read;
+connection writer;
+send
+update t1 set i= 10;
+connection reader;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Locked" and info = "update t1 set i= 10";
+--source include/wait_condition.inc
+send
+select * from t1;
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Locked" and info = "select * from t1";
+--source include/wait_condition.inc
+let $ID= `select id from information_schema.processlist where state = "Locked" and info = "update t1 set i= 10"`;
+--replace_result $ID ID
+eval kill query $ID;
+connection reader;
+--reap
+connection writer;
+--error ER_QUERY_INTERRUPTED
+--reap
+connection locker;
+unlock tables;
+connection default;
+drop table t1;
+
+# Disconnect sessions used in many subtests above
+disconnect locker;
+disconnect reader;
+disconnect writer;
+
+#
+# Bug#32395 Alter table under a impending global read lock causes a server crash
+#
+
+#
+# Test ALTER TABLE under LOCK TABLES and FLUSH TABLES WITH READ LOCK
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int);
+connect (flush,localhost,root,,test,,);
+connection default;
+--echo connection: default
+lock tables t1 write;
+connection flush;
+--echo connection: flush
+--send flush tables with read lock;
+connection default;
+--echo connection: default
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+alter table t1 add column j int;
+connect (insert,localhost,root,,test,,);
+connection insert;
+--echo connection: insert
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+--send insert into t1 values (1,2);
+--echo connection: default
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for release of readlock";
+--source include/wait_condition.inc
+unlock tables;
+connection flush;
+--echo connection: flush
+--reap
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for release of readlock";
+--source include/wait_condition.inc
+select * from t1;
+unlock tables;
+connection insert;
+--reap
+connection default;
+let $wait_condition=
+ select count(*) = 1 from t1;
+--source include/wait_condition.inc
+select * from t1;
+drop table t1;
+disconnect flush;
+disconnect insert;
+
+#
+# Test that FLUSH TABLES under LOCK TABLES protects write locked tables
+# from a impending FLUSH TABLES WITH READ LOCK
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int);
+connect (flush,localhost,root,,test,,);
+connection default;
+--echo connection: default
+lock tables t1 write;
+connection flush;
+--echo connection: flush
+--send flush tables with read lock;
+connection default;
+--echo connection: default
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+flush tables;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+unlock tables;
+let $wait_condition=
+ select count(*) = 0 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+connection flush;
+--reap
+connection default;
+disconnect flush;
+drop table t1;
+
+#
+# Bug#30331 Table_locks_waited shows inaccurate values
+#
+
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+create table t1 (a int);
+flush status;
+lock tables t1 read;
+let $tlwa= `show status like 'Table_locks_waited'`;
+connect (waiter,localhost,root,,);
+connection waiter;
+--send insert into t1 values(1);
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Locked" and info = "insert into t1 values(1)";
+--source include/wait_condition.inc
+let $tlwb= `show status like 'Table_locks_waited'`;
+unlock tables;
+drop table t1;
+disconnect waiter;
+connection default;
--disable_query_log
+eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1);
+eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1);
drop database pbxt;
--enable_query_log
-# End of 5.0 tests
+select @tlwa < @tlwb;
+
+--echo End of 5.1 tests
+
+# Wait till all disconnects are completed
+--source include/wait_until_count_sessions.inc
=== modified file 'mysql-test/suite/pbxt/t/partition_error.test'
--- a/mysql-test/suite/pbxt/t/partition_error.test 2009-04-02 10:03:14 +0000
+++ b/mysql-test/suite/pbxt/t/partition_error.test 2010-03-09 15:03:54 +0000
@@ -421,7 +421,7 @@ partitions 2
#
# Partition by range, constant partition function not allowed
#
---error ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
CREATE TABLE t1 (
a int not null,
b int not null,
@@ -636,7 +636,7 @@ partition by list (a);
#
# Partition by list, constant partition function not allowed
#
---error ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
CREATE TABLE t1 (
a int not null,
b int not null,
=== added file 'mysql-test/suite/pbxt/t/pbxt_xa.test'
--- a/mysql-test/suite/pbxt/t/pbxt_xa.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/pbxt_xa.test 2010-03-24 22:12:39 +0000
@@ -0,0 +1,23 @@
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+#
+# bug lp:544173, xa crash with two 2pc-capable storage engines without binlog
+#
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+# verify that binlog is off
+SELECT @@log_bin;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+select * from t2;
+drop table t1, t2;
+drop database pbxt;
+
=== added file 'mysql-test/suite/pbxt/t/suite.opt'
--- a/mysql-test/suite/pbxt/t/suite.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/suite.opt 2010-03-30 12:36:49 +0000
@@ -0,0 +1 @@
+--default-storage-engine=pbxt
=== modified file 'mysql-test/suite/rpl/r/rpl_create_if_not_exists.result'
--- a/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result 2009-08-29 08:52:22 +0000
+++ b/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result 2010-01-16 07:44:24 +0000
@@ -31,3 +31,37 @@ SHOW EVENTS in mysqltest;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
mysqltest e root@localhost SYSTEM ONE TIME # NULL NULL NULL NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
DROP DATABASE IF EXISTS mysqltest;
+-------------BUG#47418-------------
+USE test;
+DROP TABLE IF EXISTS t3;
+CREATE TABLE t3(c1 INTEGER);
+INSERT INTO t3 VALUES(33);
+CREATE TEMPORARY TABLE t1(c1 INTEGER);
+CREATE TEMPORARY TABLE t2(c1 INTEGER);
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1);
+CREATE TABLE IF NOT EXISTS t1(c1 INTEGER) SELECT c1 FROM t3;
+CREATE TABLE t2(c1 INTEGER) SELECT c1 FROM t3;
+SELECT * FROM t1;
+c1
+1
+SELECT * FROM t2;
+c1
+1
+SELECT * FROM t1;
+c1
+33
+SELECT * FROM t2;
+c1
+33
+DROP TEMPORARY TABLE t1;
+DROP TEMPORARY TABLE t2;
+SELECT * FROM t1;
+c1
+33
+SELECT * FROM t2;
+c1
+33
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
=== modified file 'mysql-test/suite/rpl/r/rpl_do_grant.result'
--- a/mysql-test/suite/rpl/r/rpl_do_grant.result 2009-09-01 11:38:17 +0000
+++ b/mysql-test/suite/rpl/r/rpl_do_grant.result 2010-03-28 18:10:00 +0000
@@ -165,8 +165,80 @@ USE bug42217_db;
DROP FUNCTION upgrade_del_func;
DROP FUNCTION upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
-USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+stop slave;
+DROP USER 'create_rout_db'@'localhost';
+######## BUG#49119 #######
+### i) test case from the 'how to repeat section'
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1(c1 INT);
+CREATE PROCEDURE p1() SELECT * FROM t1 |
+REVOKE EXECUTE ON PROCEDURE p1 FROM 'root'@'localhost';
+ERROR 42000: There is no such grant defined for user 'root' on host 'localhost' on routine 'p1'
+DROP TABLE t1;
+DROP PROCEDURE p1;
+### ii) Test case in which REVOKE partially succeeds
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1(c1 INT);
+CREATE PROCEDURE p1() SELECT * FROM t1 |
+CREATE USER 'user49119'@'localhost';
+GRANT EXECUTE ON PROCEDURE p1 TO 'user49119'@'localhost';
+##############################################################
+### Showing grants for both users: root and user49119 (master)
+SHOW GRANTS FOR 'user49119'@'localhost';
+Grants for user49119@localhost
+GRANT USAGE ON *.* TO 'user49119'@'localhost'
+GRANT EXECUTE ON PROCEDURE `test`.`p1` TO 'user49119'@'localhost'
+SHOW GRANTS FOR CURRENT_USER;
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+##############################################################
+##############################################################
+### Showing grants for both users: root and user49119 (master)
+SHOW GRANTS FOR 'user49119'@'localhost';
+Grants for user49119@localhost
+GRANT USAGE ON *.* TO 'user49119'@'localhost'
+GRANT EXECUTE ON PROCEDURE `test`.`p1` TO 'user49119'@'localhost'
+SHOW GRANTS FOR CURRENT_USER;
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+##############################################################
+## This statement will make the revoke fail because root has no
+## execute grant. However, it will still revoke the grant for
+## user49119.
+REVOKE EXECUTE ON PROCEDURE p1 FROM 'user49119'@'localhost', 'root'@'localhost';
+ERROR 42000: There is no such grant defined for user 'root' on host 'localhost' on routine 'p1'
+##############################################################
+### Showing grants for both users: root and user49119 (master)
+### after revoke statement failure
+SHOW GRANTS FOR 'user49119'@'localhost';
+Grants for user49119@localhost
+GRANT USAGE ON *.* TO 'user49119'@'localhost'
+SHOW GRANTS FOR CURRENT_USER;
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+##############################################################
+#############################################################
+### Showing grants for both users: root and user49119 (slave)
+### after revoke statement failure (should match
+SHOW GRANTS FOR 'user49119'@'localhost';
+Grants for user49119@localhost
+GRANT USAGE ON *.* TO 'user49119'@'localhost'
+SHOW GRANTS FOR CURRENT_USER;
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+##############################################################
+DROP TABLE t1;
+DROP PROCEDURE p1;
+DROP USER 'user49119'@'localhost';
"End of test"
=== modified file 'mysql-test/suite/rpl/r/rpl_drop_temp.result'
--- a/mysql-test/suite/rpl/r/rpl_drop_temp.result 2009-08-28 09:45:57 +0000
+++ b/mysql-test/suite/rpl/r/rpl_drop_temp.result 2009-12-31 04:04:19 +0000
@@ -12,3 +12,17 @@ show status like 'Slave_open_temp_tables
Variable_name Value
Slave_open_temp_tables 0
drop database mysqltest;
+DROP TEMPORARY TABLE IF EXISTS tmp1;
+Warnings:
+Note 1051 Unknown table 'tmp1'
+CREATE TEMPORARY TABLE t1 ( a int );
+DROP TEMPORARY TABLE t1, t2;
+ERROR 42S02: Unknown table 't2'
+DROP TEMPORARY TABLE tmp2;
+ERROR 42S02: Unknown table 'tmp2'
+stop slave;
+**** On Master ****
+CREATE TEMPORARY TABLE tmp3 (a int);
+DROP TEMPORARY TABLE tmp3;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
=== modified file 'mysql-test/suite/rpl/r/rpl_err_ignoredtable.result'
--- a/mysql-test/suite/rpl/r/rpl_err_ignoredtable.result 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_err_ignoredtable.result 2009-11-18 14:50:31 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
create table t1 (a int primary key);
create table t4 (a int primary key);
insert into t1 values (1),(1);
=== modified file 'mysql-test/suite/rpl/r/rpl_extraCol_innodb.result'
--- a/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result 2009-08-28 14:13:27 +0000
+++ b/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result 2009-10-22 00:10:42 +0000
@@ -404,7 +404,11 @@ STOP SLAVE;
RESET SLAVE;
CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
d TIMESTAMP,
-e INT NOT NULL) ENGINE='InnoDB';
+e INT NOT NULL,
+f text not null,
+g text,
+h blob not null,
+i blob) ENGINE='InnoDB';
*** Create t9 on Master ***
CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
) ENGINE='InnoDB';
@@ -415,47 +419,11 @@ START SLAVE;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
-SHOW SLAVE STATUS;
-Slave_IO_State #
-Master_Host 127.0.0.1
-Master_User root
-Master_Port #
-Connect_Retry 1
-Master_Log_File master-bin.000001
-Read_Master_Log_Pos #
-Relay_Log_File #
-Relay_Log_Pos #
-Relay_Master_Log_File master-bin.000001
-Slave_IO_Running Yes
-Slave_SQL_Running No
-Replicate_Do_DB
-Replicate_Ignore_DB
-Replicate_Do_Table
-Replicate_Ignore_Table #
-Replicate_Wild_Do_Table
-Replicate_Wild_Ignore_Table
-Last_Errno 1364
-Last_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 330
-Skip_Counter 0
-Exec_Master_Log_Pos #
-Relay_Log_Space #
-Until_Condition None
-Until_Log_File
-Until_Log_Pos 0
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master #
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno #
-Last_IO_Error #
-Last_SQL_Errno 1364
-Last_SQL_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 330
-SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
-START SLAVE;
+select * from t9;
+a b c d e f g h i
+1 b1b1b1b1b1b1b1b1 Kyle 0000-00-00 00:00:00 0 NULL NULL
+2 b1b1b1b1b1b1b1b1 JOE 0000-00-00 00:00:00 0 NULL NULL
+3 b1b1b1b1b1b1b1b1 QA 0000-00-00 00:00:00 0 NULL NULL
*** Create t10 on slave ***
STOP SLAVE;
RESET SLAVE;
=== modified file 'mysql-test/suite/rpl/r/rpl_extraCol_myisam.result'
--- a/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result 2009-08-28 14:13:27 +0000
+++ b/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result 2009-10-22 00:10:42 +0000
@@ -404,7 +404,11 @@ STOP SLAVE;
RESET SLAVE;
CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
d TIMESTAMP,
-e INT NOT NULL) ENGINE='MyISAM';
+e INT NOT NULL,
+f text not null,
+g text,
+h blob not null,
+i blob) ENGINE='MyISAM';
*** Create t9 on Master ***
CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
) ENGINE='MyISAM';
@@ -415,47 +419,11 @@ START SLAVE;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
-SHOW SLAVE STATUS;
-Slave_IO_State #
-Master_Host 127.0.0.1
-Master_User root
-Master_Port #
-Connect_Retry 1
-Master_Log_File master-bin.000001
-Read_Master_Log_Pos #
-Relay_Log_File #
-Relay_Log_Pos #
-Relay_Master_Log_File master-bin.000001
-Slave_IO_Running Yes
-Slave_SQL_Running No
-Replicate_Do_DB
-Replicate_Ignore_DB
-Replicate_Do_Table
-Replicate_Ignore_Table #
-Replicate_Wild_Do_Table
-Replicate_Wild_Ignore_Table
-Last_Errno 1364
-Last_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 330
-Skip_Counter 0
-Exec_Master_Log_Pos #
-Relay_Log_Space #
-Until_Condition None
-Until_Log_File
-Until_Log_Pos 0
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master #
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno #
-Last_IO_Error #
-Last_SQL_Errno 1364
-Last_SQL_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 330
-SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
-START SLAVE;
+select * from t9;
+a b c d e f g h i
+1 b1b1b1b1b1b1b1b1 Kyle 0000-00-00 00:00:00 0 NULL NULL
+2 b1b1b1b1b1b1b1b1 JOE 0000-00-00 00:00:00 0 NULL NULL
+3 b1b1b1b1b1b1b1b1 QA 0000-00-00 00:00:00 0 NULL NULL
*** Create t10 on slave ***
STOP SLAVE;
RESET SLAVE;
=== added file 'mysql-test/suite/rpl/r/rpl_geometry.result'
--- a/mysql-test/suite/rpl/r/rpl_geometry.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_geometry.result 2010-01-05 06:25:29 +0000
@@ -0,0 +1,18 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1(a varchar(100),
+b multipoint not null,
+c varchar(256));
+insert into t1 set
+a='hello',
+b=geomfromtext('multipoint(1 1)'),
+c='geometry';
+create table t2 (a int(11) not null auto_increment primary key,
+b geometrycollection default null,
+c decimal(10,0));
+insert into t2(c) values (null);
+drop table t1, t2;
=== modified file 'mysql-test/suite/rpl/r/rpl_get_lock.result'
--- a/mysql-test/suite/rpl/r/rpl_get_lock.result 2008-02-12 19:09:16 +0000
+++ b/mysql-test/suite/rpl/r/rpl_get_lock.result 2009-11-18 14:50:31 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
create table t1(n int);
insert into t1 values(get_lock("lock",2));
select get_lock("lock",2);
=== modified file 'mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result'
--- a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result 2009-12-03 11:19:05 +0000
+++ b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result 2010-03-04 08:03:07 +0000
@@ -4,10 +4,9 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-call mtr.add_suppression("Get master clock failed with error: ");
-call mtr.add_suppression("Get master SERVER_ID failed with error: ");
-call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
+call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: .*");
call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*");
+call mtr.add_suppression("Slave I/O thread .* register on master");
SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP");
IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP")
1
=== modified file 'mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result'
--- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result 2009-09-28 12:41:10 +0000
+++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result 2010-02-02 13:38:44 +0000
@@ -885,7 +885,7 @@ master-bin.000001 # Query 1 # use `test_
master-bin.000001 # Xid 1 # #
master-bin.000001 # Query 1 # BEGIN
master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=#
-master-bin.000001 # Execute_load_query 1 # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE `t1` FIELDS TERMINATED BY '|' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, b) ;file_id=#
+master-bin.000001 # Execute_load_query 1 # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE `t1` FIELDS TERMINATED BY '|' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, `b`) ;file_id=#
master-bin.000001 # Xid 1 # #
master-bin.000001 # Query 1 # BEGIN
master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1
=== modified file 'mysql-test/suite/rpl/r/rpl_killed_ddl.result'
--- a/mysql-test/suite/rpl/r/rpl_killed_ddl.result 2009-04-08 23:42:51 +0000
+++ b/mysql-test/suite/rpl/r/rpl_killed_ddl.result 2009-12-10 03:51:42 +0000
@@ -63,7 +63,7 @@ source include/diff_master_slave.inc;
DROP DATABASE d1;
source include/kill_query.inc;
source include/diff_master_slave.inc;
-DROP DATABASE d2;
+DROP DATABASE IF EXISTS d2;
source include/kill_query.inc;
source include/diff_master_slave.inc;
CREATE EVENT e2
@@ -115,6 +115,7 @@ source include/diff_master_slave.inc;
DROP INDEX i1 on t1;
source include/kill_query.inc;
source include/diff_master_slave.inc;
+CREATE TABLE IF NOT EXISTS t4 (a int);
CREATE TRIGGER tr2 BEFORE INSERT ON t4
FOR EACH ROW BEGIN
DELETE FROM t1 WHERE a=NEW.a;
=== modified file 'mysql-test/suite/rpl/r/rpl_loaddata.result'
--- a/mysql-test/suite/rpl/r/rpl_loaddata.result 2009-10-27 15:15:53 +0000
+++ b/mysql-test/suite/rpl/r/rpl_loaddata.result 2010-01-13 10:28:42 +0000
@@ -34,9 +34,9 @@ insert into t1 values(1,10);
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
set global sql_slave_skip_counter=1;
start slave;
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2009 # # master-bin.000001 Yes Yes # 0 0 2009 # None 0 No # No 0 0
+Last_SQL_Errno=0
+Last_SQL_Error
+
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
@@ -44,9 +44,9 @@ load data infile '../../std_data/rpl_loa
stop slave;
change master to master_user='test';
change master to master_user='root';
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2044 # # master-bin.000001 No No # 0 0 2044 # None 0 No # No 0 0
+Last_SQL_Errno=0
+Last_SQL_Error
+
set global sql_slave_skip_counter=1;
start slave;
set sql_log_bin=0;
@@ -55,9 +55,9 @@ set sql_log_bin=1;
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
stop slave;
reset slave;
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error
-# 127.0.0.1 root MASTER_PORT 1 4 # # No No # 0 0 0 # None 0 No # No 0 0
+Last_SQL_Errno=0
+Last_SQL_Error
+
reset master;
create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
unique(day)) engine=MyISAM;
@@ -115,3 +115,20 @@ use b48297_db1;
Comparing tables master:b48297_db1.t1 and slave:b48297_db1.t1
DROP DATABASE b48297_db1;
DROP DATABASE b42897_db2;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+use test;
+CREATE TABLE t1 (`key` TEXT, `text` TEXT);
+LOAD DATA INFILE '../../std_data/loaddata2.dat' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ',';
+SELECT * FROM t1;
+key text
+Field A 'Field B'
+Field 1 'Field 2'
+Field 3 'Field 4'
+'Field 5' 'Field 6'
+Field 6 'Field 7'
+DROP TABLE t1;
=== added file 'mysql-test/suite/rpl/r/rpl_loaddata_concurrent.result'
--- a/mysql-test/suite/rpl/r/rpl_loaddata_concurrent.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_loaddata_concurrent.result 2010-01-07 10:34:27 +0000
@@ -0,0 +1,145 @@
+CREATE TABLE t1 (c1 char(50));
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+LOAD DATA CONCURRENT INFILE '../../std_data/words.dat' INTO TABLE t1;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (c1 char(50))
+master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`c1`) ;file_id=#
+master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA CONCURRENT INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`c1`) ;file_id=#
+DROP TABLE t1;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+reset master;
+select last_insert_id();
+last_insert_id()
+0
+create table t1(a int not null auto_increment, b int, primary key(a) );
+load data CONCURRENT infile '../../std_data/rpl_loaddata.dat' into table t1;
+select last_insert_id();
+last_insert_id()
+1
+create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60));
+load data CONCURRENT infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines;
+create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60));
+insert into t3 select * from t2;
+select * from t1;
+a b
+1 10
+2 15
+select * from t3;
+day id category name
+2003-02-22 2461 b a a a @ % ' " a
+2003-03-22 2161 c asdf
+2003-03-22 2416 a bbbbb
+drop table t1;
+drop table t2;
+drop table t3;
+create table t1(a int, b int, unique(b));
+insert into t1 values(1,10);
+load data CONCURRENT infile '../../std_data/rpl_loaddata.dat' into table t1;
+set global sql_slave_skip_counter=1;
+start slave;
+Last_SQL_Errno=0
+Last_SQL_Error
+
+set sql_log_bin=0;
+delete from t1;
+set sql_log_bin=1;
+load data CONCURRENT infile '../../std_data/rpl_loaddata.dat' into table t1;
+stop slave;
+change master to master_user='test';
+change master to master_user='root';
+Last_SQL_Errno=0
+Last_SQL_Error
+
+set global sql_slave_skip_counter=1;
+start slave;
+set sql_log_bin=0;
+delete from t1;
+set sql_log_bin=1;
+load data CONCURRENT infile '../../std_data/rpl_loaddata.dat' into table t1;
+stop slave;
+reset slave;
+Last_SQL_Errno=0
+Last_SQL_Error
+
+reset master;
+create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
+unique(day)) engine=MyISAM;
+load data CONCURRENT infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
+terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
+'\n##\n' starting by '>' ignore 1 lines;
+ERROR 23000: Duplicate entry '2003-03-22' for key 'day'
+select * from t2;
+day id category name
+2003-02-22 2461 b a a a @ % ' " a
+2003-03-22 2161 c asdf
+start slave;
+select * from t2;
+day id category name
+2003-02-22 2461 b a a a @ % ' " a
+2003-03-22 2161 c asdf
+alter table t2 drop key day;
+delete from t2;
+load data CONCURRENT infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
+terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
+'\n##\n' starting by '>' ignore 1 lines;
+ERROR 23000: Duplicate entry '2003-03-22' for key 'day'
+drop table t1, t2;
+drop table t1, t2;
+CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
+LOAD DATA CONCURRENT INFILE "../../std_data/words.dat" INTO TABLE t1;
+ERROR 23000: Duplicate entry 'Aarhus' for key 'PRIMARY'
+DROP TABLE IF EXISTS t1;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists b48297_db1;
+drop database if exists b42897_db2;
+create database b48297_db1;
+create database b42897_db2;
+use b48297_db1;
+CREATE TABLE t1 (c1 VARCHAR(256)) engine=MyISAM;;
+use b42897_db2;
+### assertion: works with cross-referenced database
+LOAD DATA CONCURRENT LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1;
+use b48297_db1;
+### assertion: works with fully qualified name on current database
+LOAD DATA CONCURRENT LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1;
+### assertion: works without fully qualified name on current database
+LOAD DATA CONCURRENT LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1;
+### create connection without default database
+### connect (conn2,localhost,root,,*NO-ONE*);
+### assertion: works without stating the default database
+LOAD DATA CONCURRENT LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1;
+### disconnect and switch back to master connection
+use b48297_db1;
+Comparing tables master:b48297_db1.t1 and slave:b48297_db1.t1
+DROP DATABASE b48297_db1;
+DROP DATABASE b42897_db2;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+use test;
+CREATE TABLE t1 (`key` TEXT, `text` TEXT);
+LOAD DATA INFILE '../../std_data/loaddata2.dat' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ',';
+SELECT * FROM t1;
+key text
+Field A 'Field B'
+Field 1 'Field 2'
+Field 3 'Field 4'
+'Field 5' 'Field 6'
+Field 6 'Field 7'
+DROP TABLE t1;
=== modified file 'mysql-test/suite/rpl/r/rpl_loaddata_fatal.result'
--- a/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result 2009-09-28 12:41:10 +0000
+++ b/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result 2009-12-06 01:11:32 +0000
@@ -53,7 +53,7 @@ Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
-Read_Master_Log_Pos 556
+Read_Master_Log_Pos 560
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
=== modified file 'mysql-test/suite/rpl/r/rpl_loaddata_map.result'
--- a/mysql-test/suite/rpl/r/rpl_loaddata_map.result 2009-09-28 12:41:10 +0000
+++ b/mysql-test/suite/rpl/r/rpl_loaddata_map.result 2009-12-06 01:11:32 +0000
@@ -20,7 +20,7 @@ master-bin.000001 # Query # # use `test`
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
master-bin.000001 # Append_block # # ;file_id=#;block_len=#
master-bin.000001 # Append_block # # ;file_id=#;block_len=#
-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (id) ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`id`) ;file_id=#
==== Verify results on slave ====
[on slave]
select count(*) from t2 /* 5 000 */;
=== added file 'mysql-test/suite/rpl/r/rpl_loaddata_symlink.result'
--- a/mysql-test/suite/rpl/r/rpl_loaddata_symlink.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_loaddata_symlink.result 2009-11-28 04:43:16 +0000
@@ -0,0 +1,17 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1(a int not null auto_increment, b int, primary key(a) );
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+select * from t1;
+a b
+1 10
+2 15
+select * from t1;
+a b
+1 10
+2 15
+drop table t1;
=== added file 'mysql-test/suite/rpl/r/rpl_manual_change_index_file.result'
--- a/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result 2010-01-08 05:42:23 +0000
@@ -0,0 +1,25 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+FLUSH LOGS;
+CREATE TABLE t1(c1 INT);
+FLUSH LOGS;
+call mtr.add_suppression('Got fatal error 1236 from master when reading data from binary log: .*could not find next log');
+Last_IO_Error
+Got fatal error 1236 from master when reading data from binary log: 'could not find next log'
+CREATE TABLE t2(c1 INT);
+FLUSH LOGS;
+CREATE TABLE t3(c1 INT);
+FLUSH LOGS;
+CREATE TABLE t4(c1 INT);
+START SLAVE IO_THREAD;
+SHOW TABLES;
+Tables_in_test
+t1
+t2
+t3
+t4
+DROP TABLE t1, t2, t3, t4;
=== modified file 'mysql-test/suite/rpl/r/rpl_misc_functions.result'
--- a/mysql-test/suite/rpl/r/rpl_misc_functions.result 2008-10-07 12:22:28 +0000
+++ b/mysql-test/suite/rpl/r/rpl_misc_functions.result 2010-01-13 09:00:03 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
create table t1(id int, i int, r1 int, r2 int, p varchar(100));
insert into t1 values(1, connection_id(), 0, 0, "");
insert into t1 values(2, 0, rand()*1000, rand()*1000, "");
=== modified file 'mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result'
--- a/mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result 2008-11-04 17:07:14 +0000
+++ b/mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result 2010-01-19 10:36:52 +0000
@@ -18,6 +18,7 @@ Server_id Host Port Rpl_recovery_rank Ma
drop table t1;
stop slave;
create table t2(id int auto_increment primary key, created datetime);
+SET TIME_ZONE= '+03:00';
set timestamp=12345;
insert into t2 set created=now();
select * from t2;
=== added file 'mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result'
--- a/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result 2010-01-13 09:00:03 +0000
@@ -0,0 +1,27 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
+CREATE TABLE t1 (a VARCHAR(1000));
+INSERT INTO t1 VALUES (CONNECTION_ID());
+INSERT INTO t1 VALUES (CONNECTION_ID());
+INSERT INTO t1 VALUES
+(CURDATE()),
+(CURRENT_DATE()),
+(CURRENT_TIME()),
+(CURRENT_TIMESTAMP()),
+(CURTIME()),
+(LOCALTIME()),
+(LOCALTIMESTAMP()),
+(NOW()),
+(UNIX_TIMESTAMP()),
+(UTC_DATE()),
+(UTC_TIME()),
+(UTC_TIMESTAMP());
+INSERT INTO t1 VALUES (RAND());
+INSERT INTO t1 VALUES (LAST_INSERT_ID());
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
=== added file 'mysql-test/suite/rpl/r/rpl_not_null_innodb.result'
--- a/mysql-test/suite/rpl/r/rpl_not_null_innodb.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_not_null_innodb.result 2009-10-22 00:19:52 +0000
@@ -0,0 +1,202 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00',
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00',
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a,b,c) VALUES (1, null, 1);
+INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, 4);
+INSERT INTO t1(a) VALUES (5);
+INSERT INTO t2(a,b) VALUES (1, null);
+INSERT INTO t2(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t2(a) VALUES (3);
+INSERT INTO t3(a,b) VALUES (1, null);
+INSERT INTO t3(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t3(a) VALUES (3);
+INSERT INTO t4(a,b,c) VALUES (1, null, 1);
+INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t4(a,b) VALUES (3, null);
+INSERT INTO t4(a,c) VALUES (4, 4);
+INSERT INTO t4(a) VALUES (5);
+************* SHOWING THE RESULT SETS WITH INSERTS *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+TABLES t2 and t3 must be different.
+SELECT * FROM t3 ORDER BY a;
+a b
+1 NULL
+2 1111-11-11
+3 NULL
+SELECT * FROM t3 ORDER BY a;
+a b c
+1 NULL 500
+2 1111-11-11 500
+3 NULL 500
+SELECT * FROM t4 ORDER BY a;
+a b c
+1 NULL 1
+2 1111-11-11 2
+3 NULL NULL
+4 NULL 4
+5 NULL NULL
+SELECT * FROM t4 ORDER BY a;
+a b
+1 NULL
+2 1111-11-11
+3 NULL
+4 NULL
+5 NULL
+************* EXECUTION WITH UPDATES and REPLACES *************
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1);
+REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+UPDATE t1 set b= NULL, c= 300 where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300);
+************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+************* CLEANING *************
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= Innodb;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= Innodb;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a,b,c) VALUES (1, null, b'01');
+INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01');
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, b'01');
+INSERT INTO t1(a) VALUES (5);
+************* SHOWING THE RESULT SETS WITH INSERTS *************
+TABLES t1 and t2 must be different.
+SELECT a,b+0,c+0 FROM t1 ORDER BY a;
+a b+0 c+0
+1 NULL 1
+2 0 1
+3 NULL NULL
+4 NULL 1
+5 NULL NULL
+SELECT a,b+0,c+0 FROM t1 ORDER BY a;
+a b+0 c+0
+1 NULL 1
+2 0 1
+3 NULL NULL
+4 NULL 1
+5 NULL NULL
+************* EXECUTION WITH UPDATES and REPLACES *************
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01');
+REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01');
+UPDATE t1 set b= NULL, c= b'00' where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00');
+************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+################################################################################
+# NULL ---> NOT NULL (STRICT MODE)
+# UNCOMMENT THIS AFTER FIXING BUG#43992
+################################################################################
+################################################################################
+# NULL ---> NOT NULL (NON-STRICT MODE)
+################################################################################
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT NOT NULL,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a) VALUES (1);
+INSERT INTO t1(a, b) VALUES (2, NULL);
+INSERT INTO t1(a, b) VALUES (3, 1);
+INSERT INTO t2(a) VALUES (1);
+INSERT INTO t2(a, b) VALUES (2, NULL);
+INSERT INTO t2(a, b) VALUES (3, 1);
+INSERT INTO t3(a) VALUES (1);
+INSERT INTO t3(a, b) VALUES (2, NULL);
+INSERT INTO t3(a, b) VALUES (3, 1);
+INSERT INTO t3(a, b) VALUES (4, 1);
+REPLACE INTO t3(a, b) VALUES (5, null);
+REPLACE INTO t3(a, b) VALUES (3, null);
+UPDATE t3 SET b = NULL where a = 4;
+************* SHOWING THE RESULT SETS *************
+SELECT * FROM t1 ORDER BY a;
+a b
+1 NULL
+2 NULL
+3 1
+SELECT * FROM t1 ORDER BY a;
+a b c
+1 0 0
+2 0 0
+3 1 0
+SELECT * FROM t2 ORDER BY a;
+a b
+1 NULL
+2 NULL
+3 1
+SELECT * FROM t2 ORDER BY a;
+a b c
+1 0 NULL
+2 0 NULL
+3 1 NULL
+SELECT * FROM t3 ORDER BY a;
+a b
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+5 NULL
+SELECT * FROM t3 ORDER BY a;
+a b c
+1 0 500
+2 0 500
+3 0 500
+4 0 500
+5 0 500
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
=== added file 'mysql-test/suite/rpl/r/rpl_not_null_myisam.result'
--- a/mysql-test/suite/rpl/r/rpl_not_null_myisam.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_not_null_myisam.result 2009-10-22 00:19:52 +0000
@@ -0,0 +1,202 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
+`c` INT DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00',
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00',
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a,b,c) VALUES (1, null, 1);
+INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, 4);
+INSERT INTO t1(a) VALUES (5);
+INSERT INTO t2(a,b) VALUES (1, null);
+INSERT INTO t2(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t2(a) VALUES (3);
+INSERT INTO t3(a,b) VALUES (1, null);
+INSERT INTO t3(a,b) VALUES (2,'1111-11-11');
+INSERT INTO t3(a) VALUES (3);
+INSERT INTO t4(a,b,c) VALUES (1, null, 1);
+INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2);
+INSERT INTO t4(a,b) VALUES (3, null);
+INSERT INTO t4(a,c) VALUES (4, 4);
+INSERT INTO t4(a) VALUES (5);
+************* SHOWING THE RESULT SETS WITH INSERTS *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+TABLES t2 and t3 must be different.
+SELECT * FROM t3 ORDER BY a;
+a b
+1 NULL
+2 1111-11-11
+3 NULL
+SELECT * FROM t3 ORDER BY a;
+a b c
+1 NULL 500
+2 1111-11-11 500
+3 NULL 500
+SELECT * FROM t4 ORDER BY a;
+a b c
+1 NULL 1
+2 1111-11-11 2
+3 NULL NULL
+4 NULL 4
+5 NULL NULL
+SELECT * FROM t4 ORDER BY a;
+a b
+1 NULL
+2 1111-11-11
+3 NULL
+4 NULL
+5 NULL
+************* EXECUTION WITH UPDATES and REPLACES *************
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1);
+REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
+UPDATE t1 set b= NULL, c= 300 where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300);
+************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+************* CLEANING *************
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= MyISAM;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL,
+PRIMARY KEY (`a`)) ENGINE= MyISAM;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a,b,c) VALUES (1, null, b'01');
+INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01');
+INSERT INTO t1(a,b) VALUES (3, null);
+INSERT INTO t1(a,c) VALUES (4, b'01');
+INSERT INTO t1(a) VALUES (5);
+************* SHOWING THE RESULT SETS WITH INSERTS *************
+TABLES t1 and t2 must be different.
+SELECT a,b+0,c+0 FROM t1 ORDER BY a;
+a b+0 c+0
+1 NULL 1
+2 0 1
+3 NULL NULL
+4 NULL 1
+5 NULL NULL
+SELECT a,b+0,c+0 FROM t1 ORDER BY a;
+a b+0 c+0
+1 NULL 1
+2 0 1
+3 NULL NULL
+4 NULL 1
+5 NULL NULL
+************* EXECUTION WITH UPDATES and REPLACES *************
+DELETE FROM t1;
+INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01');
+REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01');
+UPDATE t1 set b= NULL, c= b'00' where a= 1;
+REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00');
+************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
+TABLES t1 and t2 must be equal otherwise an error will be thrown.
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+################################################################################
+# NULL ---> NOT NULL (STRICT MODE)
+# UNCOMMENT THIS AFTER FIXING BUG#43992
+################################################################################
+################################################################################
+# NULL ---> NOT NULL (NON-STRICT MODE)
+################################################################################
+SET SQL_LOG_BIN= 0;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+SET SQL_LOG_BIN= 1;
+CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT NOT NULL,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
+`c` INT DEFAULT 500,
+PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
+************* EXECUTION WITH INSERTS *************
+INSERT INTO t1(a) VALUES (1);
+INSERT INTO t1(a, b) VALUES (2, NULL);
+INSERT INTO t1(a, b) VALUES (3, 1);
+INSERT INTO t2(a) VALUES (1);
+INSERT INTO t2(a, b) VALUES (2, NULL);
+INSERT INTO t2(a, b) VALUES (3, 1);
+INSERT INTO t3(a) VALUES (1);
+INSERT INTO t3(a, b) VALUES (2, NULL);
+INSERT INTO t3(a, b) VALUES (3, 1);
+INSERT INTO t3(a, b) VALUES (4, 1);
+REPLACE INTO t3(a, b) VALUES (5, null);
+REPLACE INTO t3(a, b) VALUES (3, null);
+UPDATE t3 SET b = NULL where a = 4;
+************* SHOWING THE RESULT SETS *************
+SELECT * FROM t1 ORDER BY a;
+a b
+1 NULL
+2 NULL
+3 1
+SELECT * FROM t1 ORDER BY a;
+a b c
+1 0 0
+2 0 0
+3 1 0
+SELECT * FROM t2 ORDER BY a;
+a b
+1 NULL
+2 NULL
+3 1
+SELECT * FROM t2 ORDER BY a;
+a b c
+1 0 NULL
+2 0 NULL
+3 1 NULL
+SELECT * FROM t3 ORDER BY a;
+a b
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+5 NULL
+SELECT * FROM t3 ORDER BY a;
+a b c
+1 0 500
+2 0 500
+3 0 500
+4 0 500
+5 0 500
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
=== modified file 'mysql-test/suite/rpl/r/rpl_optimize.result'
--- a/mysql-test/suite/rpl/r/rpl_optimize.result 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_optimize.result 2010-01-13 09:00:03 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
create table t1 (a int not null auto_increment primary key, b int, key(b));
INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
INSERT INTO t1 (a) SELECT null FROM t1;
=== modified file 'mysql-test/suite/rpl/r/rpl_relayspace.result'
--- a/mysql-test/suite/rpl/r/rpl_relayspace.result 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_relayspace.result 2010-01-18 12:56:10 +0000
@@ -14,6 +14,6 @@ start slave io_thread;
stop slave io_thread;
reset slave;
start slave;
-select master_pos_wait('master-bin.001',200,6)=-1;
-master_pos_wait('master-bin.001',200,6)=-1
+select master_pos_wait('MASTER_LOG_FILE',200,30)=-1;
+master_pos_wait('MASTER_LOG_FILE',200,30)=-1
0
=== modified file 'mysql-test/suite/rpl/r/rpl_row_create_table.result'
--- a/mysql-test/suite/rpl/r/rpl_row_create_table.result 2009-10-06 00:54:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_create_table.result 2009-11-27 13:34:39 +0000
@@ -476,4 +476,30 @@ master-bin.000001 # Table_map # # table_
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
DROP DATABASE mysqltest1;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TEMPORARY TABLE t7(c1 INT);
+CREATE TABLE t5(c1 INT);
+CREATE TABLE t4(c1 INT);
+CREATE VIEW bug48506_t1 AS SELECT 1;
+CREATE VIEW bug48506_t2 AS SELECT * FROM t4;
+CREATE VIEW bug48506_t3 AS SELECT t5.c1 AS A, t4.c1 AS B FROM t5, t4;
+CREATE TABLE bug48506_t4(c1 INT);
+DROP VIEW bug48506_t1, bug48506_t2, bug48506_t3;
+DROP TABLE bug48506_t4;
+CREATE TABLE IF NOT EXISTS bug48506_t1 LIKE t7;
+CREATE TABLE IF NOT EXISTS bug48506_t2 LIKE t7;
+CREATE TABLE IF NOT EXISTS bug48506_t3 LIKE t7;
+CREATE TABLE IF NOT EXISTS bug48506_t4 LIKE t7;
+SHOW TABLES LIKE 'bug48506%';
+Tables_in_test (bug48506%)
+bug48506_t4
+DROP VIEW IF EXISTS bug48506_t1, bug48506_t2, bug48506_t3;
+DROP TEMPORARY TABLES t7;
+DROP TABLES t4, t5;
+DROP TABLES IF EXISTS bug48506_t4;
end of the tests
=== modified file 'mysql-test/suite/rpl/r/rpl_row_func003.result'
--- a/mysql-test/suite/rpl/r/rpl_row_func003.result 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_func003.result 2010-01-13 09:00:03 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
DROP FUNCTION IF EXISTS test.f1;
DROP TABLE IF EXISTS test.t1;
CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=INNODB;
=== modified file 'mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result'
--- a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2008-04-02 09:49:22 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2010-01-27 12:23:28 +0000
@@ -152,6 +152,7 @@ c1 c3 c4 c5
5 2006-02-22 00:00:00 Tested in Texas 11
--- Test 2 position test --
+Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead.
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -314,6 +315,7 @@ ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- Test 7 reading stdin w/position --
+Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead.
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
=== modified file 'mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result'
--- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result 2008-03-14 20:02:52 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result 2009-10-22 00:10:42 +0000
@@ -105,47 +105,9 @@ a b x
2 10 Foo is a bar
INSERT INTO t9 VALUES (2);
INSERT INTO t1_nodef VALUES (1,2);
-SHOW SLAVE STATUS;
-Slave_IO_State #
-Master_Host 127.0.0.1
-Master_User root
-Master_Port #
-Connect_Retry 1
-Master_Log_File master-bin.000001
-Read_Master_Log_Pos #
-Relay_Log_File #
-Relay_Log_Pos #
-Relay_Master_Log_File master-bin.000001
-Slave_IO_Running Yes
-Slave_SQL_Running No
-Replicate_Do_DB
-Replicate_Ignore_DB
-Replicate_Do_Table
-Replicate_Ignore_Table
-Replicate_Wild_Do_Table
-Replicate_Wild_Ignore_Table
-Last_Errno 1364
-Last_Error <Last_Error>
-Skip_Counter 0
-Exec_Master_Log_Pos #
-Relay_Log_Space #
-Until_Condition None
-Until_Log_File
-Until_Log_Pos 0
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master #
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno <Last_IO_Errno>
-Last_IO_Error <Last_IO_Error>
-Last_SQL_Errno 1364
-Last_SQL_Error <Last_SQL_Error>
-SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
-START SLAVE;
+select count(*) from t1_nodef;
+count(*)
+1
INSERT INTO t9 VALUES (2);
**** On Master ****
INSERT INTO t2 VALUES (2,4);
=== modified file 'mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result'
--- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result 2008-03-14 20:02:52 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result 2009-10-22 00:10:42 +0000
@@ -105,47 +105,9 @@ a b x
2 10 Foo is a bar
INSERT INTO t9 VALUES (2);
INSERT INTO t1_nodef VALUES (1,2);
-SHOW SLAVE STATUS;
-Slave_IO_State #
-Master_Host 127.0.0.1
-Master_User root
-Master_Port #
-Connect_Retry 1
-Master_Log_File master-bin.000001
-Read_Master_Log_Pos #
-Relay_Log_File #
-Relay_Log_Pos #
-Relay_Master_Log_File master-bin.000001
-Slave_IO_Running Yes
-Slave_SQL_Running No
-Replicate_Do_DB
-Replicate_Ignore_DB
-Replicate_Do_Table
-Replicate_Ignore_Table
-Replicate_Wild_Do_Table
-Replicate_Wild_Ignore_Table
-Last_Errno 1364
-Last_Error <Last_Error>
-Skip_Counter 0
-Exec_Master_Log_Pos #
-Relay_Log_Space #
-Until_Condition None
-Until_Log_File
-Until_Log_Pos 0
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master #
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno <Last_IO_Errno>
-Last_IO_Error <Last_IO_Error>
-Last_SQL_Errno 1364
-Last_SQL_Error <Last_SQL_Error>
-SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
-START SLAVE;
+select count(*) from t1_nodef;
+count(*)
+1
INSERT INTO t9 VALUES (2);
**** On Master ****
INSERT INTO t2 VALUES (2,4);
=== renamed file 'mysql-test/suite/binlog/r/binlog_tbl_metadata.result' => 'mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result'
--- a/mysql-test/suite/binlog/r/binlog_tbl_metadata.result 2009-05-12 11:53:46 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result 2010-01-07 17:45:54 +0000
@@ -1,5 +1,11 @@
-RESET MASTER;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
DROP TABLE IF EXISTS `t1`;
+### TABLE with field_metadata_size == 290
CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
`c2` varchar(30) NOT NULL,
@@ -150,7 +156,51 @@ CREATE TABLE `t1` (
PRIMARY KEY (`c1`)
) ENGINE=InnoDB;
LOCK TABLES `t1` WRITE;
-INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1');
-DROP TABLE `t1`;
+INSERT INTO `t1`(c2) VALUES ('1');
FLUSH LOGS;
+### assertion: the slave replicated event successfully and tables match
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE `t1`;
=== Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail.
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+### action: generating several tables with different metadata
+### sizes (resorting to perl)
+### testing table with 249 field metadata size.
+### testing table with 250 field metadata size.
+### testing table with 251 field metadata size.
+### testing table with 252 field metadata size.
+### testing table with 253 field metadata size.
+### testing table with 254 field metadata size.
+### testing table with 255 field metadata size.
+### testing table with 256 field metadata size.
+### testing table with 257 field metadata size.
+### testing table with 258 field metadata size.
+FLUSH LOGS;
+### assertion: the slave replicated event successfully and tables match for t10
+Comparing tables master:test.t10 and slave:test.t10
+### assertion: the slave replicated event successfully and tables match for t9
+Comparing tables master:test.t9 and slave:test.t9
+### assertion: the slave replicated event successfully and tables match for t8
+Comparing tables master:test.t8 and slave:test.t8
+### assertion: the slave replicated event successfully and tables match for t7
+Comparing tables master:test.t7 and slave:test.t7
+### assertion: the slave replicated event successfully and tables match for t6
+Comparing tables master:test.t6 and slave:test.t6
+### assertion: the slave replicated event successfully and tables match for t5
+Comparing tables master:test.t5 and slave:test.t5
+### assertion: the slave replicated event successfully and tables match for t4
+Comparing tables master:test.t4 and slave:test.t4
+### assertion: the slave replicated event successfully and tables match for t3
+Comparing tables master:test.t3 and slave:test.t3
+### assertion: the slave replicated event successfully and tables match for t2
+Comparing tables master:test.t2 and slave:test.t2
+### assertion: the slave replicated event successfully and tables match for t1
+Comparing tables master:test.t1 and slave:test.t1
+### assertion: check that binlog is not corrupt. Using mysqlbinlog to
+### detect failure. Before the patch mysqlbinlog would find
+### a corrupted event, thence would fail.
=== added file 'mysql-test/suite/rpl/r/rpl_row_trunc_temp.result'
--- a/mysql-test/suite/rpl/r/rpl_row_trunc_temp.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_trunc_temp.result 2009-11-22 05:10:33 +0000
@@ -0,0 +1,29 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TEMPORARY TABLE t1(c1 INTEGER);
+CREATE TABLE t2(c1 INTEGER);
+CREATE TABLE t1(c1 INTEGER);
+INSERT INTO t1 VALUES(1), (2);
+INSERT INTO t2 VALUES(1), (2);
+SELECT * FROM t1;
+c1
+1
+2
+SELECT * FROM t2;
+c1
+1
+2
+TRUNCATE t1;
+TRUNCATE t2;
+SELECT * FROM t1;
+c1
+1
+2
+SELECT * FROM t2;
+c1
+DROP TABLE t1;
+DROP TABLE t2;
=== added file 'mysql-test/suite/rpl/r/rpl_set_null_innodb.result'
--- a/mysql-test/suite/rpl/r/rpl_set_null_innodb.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_set_null_innodb.result 2010-01-21 17:20:24 +0000
@@ -0,0 +1,35 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 BIT, c2 INT) Engine=InnoDB;
+INSERT INTO `t1` VALUES ( 1, 1 );
+UPDATE t1 SET c1=NULL where c2=1;
+Comparing tables master:test.t1 and slave:test.t1
+DELETE FROM t1 WHERE c2=1 LIMIT 1;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 CHAR) Engine=InnoDB;
+INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ;
+SELECT * FROM t1;
+c1
+w
+UPDATE t1 SET c1=NULL WHERE c1='w';
+Comparing tables master:test.t1 and slave:test.t1
+DELETE FROM t1 LIMIT 2;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
=== added file 'mysql-test/suite/rpl/r/rpl_set_null_myisam.result'
--- a/mysql-test/suite/rpl/r/rpl_set_null_myisam.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_set_null_myisam.result 2010-01-21 17:20:24 +0000
@@ -0,0 +1,35 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 BIT, c2 INT) Engine=MyISAM;
+INSERT INTO `t1` VALUES ( 1, 1 );
+UPDATE t1 SET c1=NULL where c2=1;
+Comparing tables master:test.t1 and slave:test.t1
+DELETE FROM t1 WHERE c2=1 LIMIT 1;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 CHAR) Engine=MyISAM;
+INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ;
+SELECT * FROM t1;
+c1
+w
+UPDATE t1 SET c1=NULL WHERE c1='w';
+Comparing tables master:test.t1 and slave:test.t1
+DELETE FROM t1 LIMIT 2;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
=== modified file 'mysql-test/suite/rpl/r/rpl_sp.result'
--- a/mysql-test/suite/rpl/r/rpl_sp.result 2009-07-02 13:40:27 +0000
+++ b/mysql-test/suite/rpl/r/rpl_sp.result 2010-02-02 13:38:44 +0000
@@ -195,7 +195,7 @@ set @old_log_bin_trust_routine_creators=
set @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators;
set global log_bin_trust_routine_creators=1;
Warnings:
-Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead
+Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.6. Please use '@@log_bin_trust_function_creators' instead
set global log_bin_trust_function_creators=0;
set global log_bin_trust_function_creators=1;
set @old_log_bin_trust_routine_creators= @@global.log_bin_trust_routine_creators;
@@ -559,11 +559,11 @@ end
master-bin.000001 # Query 1 # use `mysqltest`; SELECT `mysqltest2`.`f1`()
set @@global.log_bin_trust_routine_creators= @old_log_bin_trust_routine_creators;
Warnings:
-Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead
+Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.6. Please use '@@log_bin_trust_function_creators' instead
set @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators;
set @@global.log_bin_trust_routine_creators= @old_log_bin_trust_routine_creators;
Warnings:
-Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead
+Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.6. Please use '@@log_bin_trust_function_creators' instead
set @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators;
drop database mysqltest;
drop database mysqltest2;
=== modified file 'mysql-test/suite/rpl/r/rpl_stm_000001.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_000001.result 2007-12-12 17:19:24 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_000001.result 2009-11-18 14:50:31 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
create table t1 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t1;
load data local infile 'MYSQL_TEST_DIR/std_data/words.dat' into table t1;
=== added file 'mysql-test/suite/rpl/r/rpl_stm_binlog_direct.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_binlog_direct.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_binlog_direct.result 2010-01-20 19:08:16 +0000
@@ -0,0 +1,1360 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+set @@session.binlog_direct_non_transactional_updates= TRUE;
+#########################################################################
+# CONFIGURATION
+#########################################################################
+SET @commands= 'configure';
+SET SQL_LOG_BIN=0;
+CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+SET SQL_LOG_BIN=1;
+SET SQL_LOG_BIN=0;
+CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
+CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb;
+SET SQL_LOG_BIN=1;
+INSERT INTO nt_1(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO nt_2(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO nt_3(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO nt_4(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO nt_5(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO nt_6(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO tt_1(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO tt_2(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO tt_3(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO tt_4(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO tt_5(trans_id, stmt_id) VALUES(1,1);
+INSERT INTO tt_6(trans_id, stmt_id) VALUES(1,1);
+CREATE PROCEDURE pc_i_tt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
+BEGIN
+DECLARE in_stmt_id INTEGER;
+SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
+SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
+END|
+CREATE PROCEDURE pc_i_nt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
+BEGIN
+DECLARE in_stmt_id INTEGER;
+SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
+SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
+END|
+CREATE FUNCTION fc_i_tt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
+BEGIN
+DECLARE in_stmt_id INTEGER;
+SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
+SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
+RETURN "fc_i_tt_5_suc";
+END|
+CREATE FUNCTION fc_i_nt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
+BEGIN
+DECLARE in_stmt_id INTEGER;
+SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
+SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
+RETURN "fc_i_nt_5_suc";
+END|
+CREATE TRIGGER tr_i_tt_3_to_nt_3 AFTER INSERT ON tt_3 FOR EACH ROW
+BEGIN
+DECLARE in_stmt_id INTEGER;
+SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= NEW.trans_id;
+SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
+INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
+INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
+END|
+CREATE TRIGGER tr_i_nt_4_to_tt_4 AFTER INSERT ON nt_4 FOR EACH ROW
+BEGIN
+DECLARE in_stmt_id INTEGER;
+SELECT max(stmt_id) INTO in_stmt_id FROM tt_4 WHERE trans_id= NEW.trans_id;
+SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
+INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
+INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
+END|
+CREATE TRIGGER tr_i_tt_5_to_tt_6 AFTER INSERT ON tt_5 FOR EACH ROW
+BEGIN
+DECLARE in_stmt_id INTEGER;
+SELECT max(stmt_id) INTO in_stmt_id FROM tt_6 WHERE trans_id= NEW.trans_id;
+SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id, 1), 1) INTO in_stmt_id;
+INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
+INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
+END|
+CREATE TRIGGER tr_i_nt_5_to_nt_6 AFTER INSERT ON nt_5 FOR EACH ROW
+BEGIN
+DECLARE in_stmt_id INTEGER;
+SELECT max(stmt_id) INTO in_stmt_id FROM nt_6 WHERE trans_id= NEW.trans_id;
+SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
+INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
+INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
+END|
+SET @commands= '';
+#########################################################################
+# 1 - BINLOG ORDER
+#########################################################################
+
+
+
+
+#
+#3) Generates in the binlog what follows:
+# --> STMT "N B T C" entries, format S.
+#
+SET @commands= 'B T N C';
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (7, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (7, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T N C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (7, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T N C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (8, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (8, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (8, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (8, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T N-trig C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (8, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (8, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T N-trig C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (9, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_nt_5_suc (9, 4);
+fc_i_nt_5_suc (9, 4)
+fc_i_nt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(9,4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (9, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T N-func C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(9,4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (9, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T N-func C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (10, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_nt_5_suc (10, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1) + 1)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (10, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T N-proc C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (10, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T N-proc C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (11, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (11, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (11, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (12, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (12, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (12, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (12, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-trig C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (12, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (12, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-trig C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (13, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_nt_5_suc (13, 4);
+fc_i_nt_5_suc (13, 4)
+fc_i_nt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(13,4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (13, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-func C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(13,4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (13, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-func C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_nt_5_suc (14, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',14), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',14), NAME_CONST('in_stmt_id',1) + 1)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-proc C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',14), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',14), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-proc C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_tt_5_suc (15, 2);
+fc_i_tt_5_suc (15, 2)
+fc_i_tt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (15, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (15, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(15,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (15, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(15,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_tt_5_suc (16, 2);
+fc_i_tt_5_suc (16, 2)
+fc_i_tt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (16, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (16, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(16,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-trig C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (16, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(16,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-trig C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_tt_5_suc (17, 2);
+fc_i_tt_5_suc (17, 2)
+fc_i_tt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_nt_5_suc (17, 4);
+fc_i_nt_5_suc (17, 4)
+fc_i_nt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(17,4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(17,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-func C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(17,4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(17,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-func C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_tt_5_suc (18, 2);
+fc_i_tt_5_suc (18, 2)
+fc_i_tt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_nt_5_suc (18, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',18), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',18), NAME_CONST('in_stmt_id',1) + 1)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(18,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-proc C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',18), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',18), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(18,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-proc C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_tt_5_suc (19, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (19, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (19, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',19), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',19), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (19, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',19), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',19), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_tt_5_suc (20, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (20, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (20, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-trig C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (20, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-trig C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_tt_5_suc (21, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_nt_5_suc (21, 4);
+fc_i_nt_5_suc (21, 4)
+fc_i_nt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(21,4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',21), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',21), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-func C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(21,4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',21), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',21), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-func C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_tt_5_suc (22, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_nt_5_suc (22, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1) + 1)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-proc C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-proc C << -e-e-e-e-e-e-e-e-e-e-e-
+
+
+
+
+
+#
+#3.e) Generates in the binlog what follows if T-* fails:
+# --> STMT "N" entry, format S.
+# Otherwise, what follows if N-* fails and a N-Table is changed:
+# --> STMT "N B T C" entries, format S.
+#
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> eT << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (10, 2);
+Got one of the listed errors
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> eT << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (23, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (23, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B eT N C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (23, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> B eT N C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> Te << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (24, 2), (10, 2);
+Got one of the listed errors
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> Te << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (24, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (24, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B Te N C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (24, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> B Te N C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> eN << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (24, 4);
+Got one of the listed errors
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> eN << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T eN C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T eN C << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> Ne << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (26, 4), (24, 4);
+Got one of the listed errors
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (26, 4), (24, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> Ne << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
+COMMIT;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T Ne C << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (26, 4), (24, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+-e-e-e-e-e-e-e-e-e-e-e- >> B T Ne C << -e-e-e-e-e-e-e-e-e-e-e-
+
+
+
+
+
+#
+#4) Generates in the binlog what follows:
+# --> STMT "N B T R" entries, format S.
+#
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (27, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (27, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T N R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (27, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T N R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (28, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (28, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (28, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (28, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T N-trig R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (28, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (28, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T N-trig R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (29, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_nt_5_suc (29, 4);
+fc_i_nt_5_suc (29, 4)
+fc_i_nt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(29,4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (29, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T N-func R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(29,4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (29, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T N-func R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (30, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_nt_5_suc (30, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1) + 1)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (30, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T N-proc R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (30, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T N-proc R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (31, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (31, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (31, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (32, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (32, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (32, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (32, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-trig R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (32, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (32, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-trig R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (33, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_nt_5_suc (33, 4);
+fc_i_nt_5_suc (33, 4)
+fc_i_nt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(33,4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (33, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-func R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(33,4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (33, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-func R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_nt_5_suc (34, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',34), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',34), NAME_CONST('in_stmt_id',1) + 1)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-proc R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',34), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',34), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-proc R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_tt_5_suc (35, 2);
+fc_i_tt_5_suc (35, 2)
+fc_i_tt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (35, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (35, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(35,2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (35, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(35,2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_tt_5_suc (36, 2);
+fc_i_tt_5_suc (36, 2)
+fc_i_tt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (36, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (36, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(36,2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-trig R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (36, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(36,2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-trig R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_tt_5_suc (37, 2);
+fc_i_tt_5_suc (37, 2)
+fc_i_tt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_nt_5_suc (37, 4);
+fc_i_nt_5_suc (37, 4)
+fc_i_nt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(37,4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(37,2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-func R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(37,4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(37,2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-func R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_tt_5_suc (38, 2);
+fc_i_tt_5_suc (38, 2)
+fc_i_tt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_nt_5_suc (38, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',38), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',38), NAME_CONST('in_stmt_id',1) + 1)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(38,2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-proc R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',38), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',38), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(38,2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-proc R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_tt_5_suc (39, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (39, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (39, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',39), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',39), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (39, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',39), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',39), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_tt_5_suc (40, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_5(trans_id, stmt_id) VALUES (40, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (40, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-trig R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (40, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-trig R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_tt_5_suc (41, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b-
+SELECT fc_i_nt_5_suc (41, 4);
+fc_i_nt_5_suc (41, 4)
+fc_i_nt_5_suc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(41,4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',41), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',41), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-func R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(41,4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',41), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',41), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-func R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_tt_5_suc (42, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
+CALL pc_i_nt_5_suc (42, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1) + 1)
+-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-proc R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1))
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1) + 1)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-proc R << -e-e-e-e-e-e-e-e-e-e-e-
+
+
+
+
+
+#
+#4.e) Generates in the binlog what follows if T* fails:
+# --> STMT "B N C" entry, format S.
+# Otherwise, what follows if N* fails and a N-Table is changed:
+# --> STMT "N" entries, format S.
+#
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> eT << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 2);
+Got one of the listed errors
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> eT << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (43, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (43, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B eT N R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (43, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> B eT N R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> Te << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (44, 2), (26, 2);
+Got one of the listed errors
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> Te << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (44, 4);
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (44, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B Te N R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (44, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> B Te N R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (45, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> eN << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (44, 4);
+Got one of the listed errors
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> eN << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T eN R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B T eN R << -e-e-e-e-e-e-e-e-e-e-e-
+
+-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b-
+BEGIN;
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 2);
+Log_name Pos Event_type Server_id End_log_pos Info
+-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> Ne << -b-b-b-b-b-b-b-b-b-b-b-
+INSERT INTO nt_1(trans_id, stmt_id) VALUES (46, 4), (44, 4);
+Got one of the listed errors
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (46, 4), (44, 4)
+-e-e-e-e-e-e-e-e-e-e-e- >> Ne << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
+-b-b-b-b-b-b-b-b-b-b-b- >> B T Ne R << -b-b-b-b-b-b-b-b-b-b-b-
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (46, 4), (44, 4)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 2)
+master-bin.000001 # Query # # ROLLBACK
+-e-e-e-e-e-e-e-e-e-e-e- >> B T Ne R << -e-e-e-e-e-e-e-e-e-e-e-
+
+###################################################################################
+# CHECK CONSISTENCY
+###################################################################################
+###################################################################################
+# CLEAN
+###################################################################################
=== modified file 'mysql-test/suite/rpl/r/rpl_stm_log.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_log.result 2009-09-28 12:41:10 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_log.result 2009-12-06 01:11:32 +0000
@@ -25,7 +25,7 @@ master-bin.000001 # Query 1 # use `test`
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM
master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
-master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=1
+master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (`word`) ;file_id=1
show binlog events from 106 limit 1;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM
@@ -193,7 +193,7 @@ master-bin.000001 # Query # # use `test`
master-bin.000001 # Query # # use `test`; drop table t1
master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (`word`) ;file_id=#
master-bin.000001 # Rotate # # master-bin.000002;pos=4
show binlog events in 'master-bin.000002';
Log_name Pos Event_type Server_id End_log_pos Info
@@ -218,7 +218,7 @@ slave-bin.000001 # Query 1 # use `test`;
slave-bin.000001 # Query 1 # use `test`; drop table t1
slave-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM
slave-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
-slave-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=1
+slave-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (`word`) ;file_id=1
slave-bin.000001 # Query 1 # use `test`; create table t3 (a int)ENGINE=MyISAM
slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
show binlog events in 'slave-bin.000002' from 4;
=== modified file 'mysql-test/suite/rpl/r/rpl_stm_maria.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_maria.result 2008-01-20 04:25:26 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_maria.result 2010-03-04 08:03:07 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
=== modified file 'mysql-test/suite/rpl/r/rpl_stm_until.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_until.result 2008-07-23 11:23:52 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_until.result 2010-01-27 17:27:49 +0000
@@ -212,3 +212,51 @@ start slave sql_thread;
start slave until master_log_file='master-bin.000001', master_log_pos=776;
Warnings:
Note 1254 Slave is already running
+include/stop_slave.inc
+drop table if exists t1;
+reset slave;
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root';
+drop table if exists t1;
+reset master;
+create table t1 (a int primary key auto_increment);
+start slave;
+include/stop_slave.inc
+master and slave are in sync now
+select 0 as zero;
+zero
+0
+insert into t1 set a=null;
+insert into t1 set a=null;
+select count(*) as two from t1;
+two
+2
+start slave until master_log_file='master-bin.000001', master_log_pos= UNTIL_POS;;
+slave stopped at the prescribed position
+select 0 as zero;
+zero
+0
+select count(*) as one from t1;
+one
+1
+drop table t1;
+start slave;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+flush logs;
+stop slave;
+reset slave;
+start slave until master_log_file='master-bin.000001', master_log_pos=294 /* to stop right before DROP */;
+show tables /* t1 must exist */;
+Tables_in_test
+t1
+drop table t1;
+stop slave;
+reset slave;
+reset master;
=== modified file 'mysql-test/suite/rpl/r/rpl_temporary.result'
--- a/mysql-test/suite/rpl/r/rpl_temporary.result 2009-05-22 23:29:41 +0000
+++ b/mysql-test/suite/rpl/r/rpl_temporary.result 2010-03-04 08:03:07 +0000
@@ -4,7 +4,8 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-call mtr.add_suppression("Slave: Can\'t find record in \'user\' Error_code: 1032");
+SET sql_log_bin = 0;
+SET sql_log_bin = 1;
reset master;
DROP TABLE IF EXISTS t1;
CREATE TEMPORARY TABLE t1 (a char(1));
@@ -36,8 +37,10 @@ ERROR 42000: Access denied; you need the
SELECT @@session.sql_select_limit = @save_select_limit;
@@session.sql_select_limit = @save_select_limit
1
+SET @save_conn_id= connection_id();
SET @@session.pseudo_thread_id=100;
SET @@session.pseudo_thread_id=connection_id();
+SET @@session.pseudo_thread_id=@save_conn_id;
SET @@session.sql_log_bin=0;
SET @@session.sql_log_bin=1;
drop table if exists t1,t2;
@@ -127,6 +130,8 @@ select * from t1;
a
1
drop table t1;
+SET sql_log_bin = 0;
+SET sql_log_bin = 1;
-- Bug#43748
-- make a user on the slave that can list but not kill system threads.
FLUSH PRIVILEGES;
=== added file 'mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result'
--- a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result 2010-01-22 09:38:21 +0000
@@ -0,0 +1,96 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TEMPORARY TABLE t1 (a INT);
+CREATE TABLE t2 (a INT, b INT) ENGINE= MyISAM;
+INSERT INTO t1 VALUES (1);
+CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+DROP EVENT IF EXISTS e1;
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1() SELECT 1;
+INSERT INTO t1 VALUES (1);
+ALTER PROCEDURE p1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+CREATE FUNCTION f1() RETURNS INT RETURN 123;
+INSERT INTO t1 VALUES (1);
+ALTER FUNCTION f1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+CREATE DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+DROP DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+CREATE USER test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT SELECT ON t2 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT ALL ON f1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT ALL ON p1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT USAGE ON *.* TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE USAGE ON *.* FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+RENAME USER test_1@localhost TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+DROP USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p2()
+BEGIN
+# CREATE USER when a temporary table is open.
+CREATE TEMPORARY TABLE t3 (a INT);
+CREATE USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT select on table to user when a temporary table is open.
+GRANT SELECT ON t2 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT all on function to user when a temporary table is open.
+GRANT ALL ON f1 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT all on procedure to user when a temporary table is open.
+GRANT ALL ON p1 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT usage on *.* to user when a temporary table is open.
+GRANT USAGE ON *.* TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on function to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on table to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE usage on *.* from user when a temporary table is open.
+REVOKE USAGE ON *.* FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# RENAME USER when a temporary table is open.
+RENAME USER test_2@localhost TO test_3@localhost;
+INSERT INTO t1 VALUES (1);
+# DROP USER when a temporary table is open.
+DROP USER test_3@localhost;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE t3;
+END |
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (1);
+DROP PROCEDURE p2;
+INSERT INTO t1 VALUES (1);
+DROP FUNCTION f1;
+INSERT INTO t1 VALUES (1);
+DROP TABLE t2;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE t1;
=== modified file 'mysql-test/suite/rpl/r/rpl_trigger.result'
--- a/mysql-test/suite/rpl/r/rpl_trigger.result 2009-08-03 09:47:45 +0000
+++ b/mysql-test/suite/rpl/r/rpl_trigger.result 2009-11-18 14:50:31 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
=== modified file 'mysql-test/suite/rpl/t/disabled.def'
--- a/mysql-test/suite/rpl/t/disabled.def 2009-09-27 10:12:58 +0000
+++ b/mysql-test/suite/rpl/t/disabled.def 2009-12-01 09:21:15 +0000
@@ -10,3 +10,4 @@
#
##############################################################################
+rpl_row_create_table : Bug#45576 2009-12-01 joro rpl_row_create_table fails on PB2
=== modified file 'mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test'
--- a/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test 2008-10-29 17:38:18 +0000
+++ b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test 2009-12-16 04:41:15 +0000
@@ -233,16 +233,7 @@ COMMIT;
--connection master_a
--enable_query_log
-
---let $wait_condition= SELECT COUNT(*)=400 FROM t2 WHERE c = 1
---connection master_a
---source include/wait_condition.inc
---connection master_b
---source include/wait_condition.inc
---connection master_c
---source include/wait_condition.inc
---connection master_d
---source include/wait_condition.inc
+--source include/circular_rpl_for_4_hosts_sync.inc
--connection master_a
SELECT 'Master A',b,COUNT(*) FROM t2 WHERE c = 1 GROUP BY b ORDER BY b;
@@ -282,15 +273,7 @@ ROLLBACK;
--connection master_a
--enable_query_log
---let $wait_condition= SELECT COUNT(*)=200 FROM t2 WHERE c = 2
---connection master_a
---source include/wait_condition.inc
---connection master_b
---source include/wait_condition.inc
---connection master_c
---source include/wait_condition.inc
---connection master_d
---source include/wait_condition.inc
+--source include/circular_rpl_for_4_hosts_sync.inc
--connection master_a
SELECT 'Master A',b,COUNT(*) FROM t2 WHERE c = 2 GROUP BY b ORDER BY b;
=== modified file 'mysql-test/suite/rpl/t/rpl_create_if_not_exists.test'
--- a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test 2009-08-13 02:48:57 +0000
+++ b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test 2010-01-16 07:44:24 +0000
@@ -67,4 +67,57 @@ SHOW EVENTS in mysqltest;
connection master;
DROP DATABASE IF EXISTS mysqltest;
+
+#
+# BUG#47418 RBR fails, failure with mixup of base/temporary/view TABLE DDL
+#
+# Before the patch for this bug, 'CREATE TABLE IF NOT EXIST ... SELECT'
+# statement was binlogged as a TEMPORARY table if the object existed as
+# a temporary table. This was caused by that the temporary table was opened
+# and the results of the 'SELECT' was inserted into the temporary table if
+# a temporary table existed with the same name.
+#
+# After the patch for this bug, the base table is created and the results of
+# the 'SELECT' are inserted into it, even though a temporary table exists with
+# the same name, and the statement is still binlogged as a base table.
+#
+
+echo -------------BUG#47418-------------;
+connection master;
+USE test;
+DROP TABLE IF EXISTS t3;
+--enable_warnings
+CREATE TABLE t3(c1 INTEGER);
+INSERT INTO t3 VALUES(33);
+
+CREATE TEMPORARY TABLE t1(c1 INTEGER);
+CREATE TEMPORARY TABLE t2(c1 INTEGER);
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1);
+
+CREATE TABLE IF NOT EXISTS t1(c1 INTEGER) SELECT c1 FROM t3;
+CREATE TABLE t2(c1 INTEGER) SELECT c1 FROM t3;
+
+# In these two statements, t1 and t2 are the temporary table. there is only
+# value '1' in them. The records of t2 are not inserted into them.
+SELECT * FROM t1;
+SELECT * FROM t2;
+sync_slave_with_master;
+
+# In these two statements, t1 and t2 are the base table. The recoreds of t2
+# are inserted into it when CREATE TABLE ... SELECT was executed.
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+connection master;
+DROP TEMPORARY TABLE t1;
+DROP TEMPORARY TABLE t2;
+#In these two statements, t1 and t2 are the base table.
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
source include/master-slave-end.inc;
=== modified file 'mysql-test/suite/rpl/t/rpl_do_grant.test'
--- a/mysql-test/suite/rpl/t/rpl_do_grant.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-03-28 18:10:00 +0000
@@ -209,11 +209,117 @@ USE bug42217_db;
DROP FUNCTION upgrade_del_func;
DROP FUNCTION upgrade_alter_func;
DROP DATABASE bug42217_db;
-DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+
+sync_slave_with_master;
+
+# Drop the user that was already dropped on the slave
connection slave;
-USE mtr;
-call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+--disable_warnings
+stop slave;
+connection master;
+DROP USER 'create_rout_db'@'localhost';
+--enable_warnings
+
+# BUG#49119: Master crashes when executing 'REVOKE ... ON
+# {PROCEDURE|FUNCTION} FROM ...'
+#
+# The tests are divided into two test cases:
+#
+# i) a test case that mimics the one in the bug report.
+#
+# - We show that, despite the fact, that a revoke command fails
+# when binlogging is active, the master will not hit an
+# assertion.
+#
+# ii) a test case that partially succeeds on the master will also
+# partially succeed on the slave.
+#
+# - The revoke statement that partially succeeds tries to revoke
+# an EXECUTE grant for two users, and only one of the user has
+# the specific grant. This will cause mysql to drop one of the
+# grants and report error for the statement. The slave should
+# also drop the grants that the master succeed and the SQL
+# thread should not stop on statement failure.
+
+-- echo ######## BUG#49119 #######
+-- echo ### i) test case from the 'how to repeat section'
+-- source include/master-slave-reset.inc
+-- connection master
+
+CREATE TABLE t1(c1 INT);
+DELIMITER |;
+CREATE PROCEDURE p1() SELECT * FROM t1 |
+DELIMITER ;|
+-- error ER_NONEXISTING_PROC_GRANT
+REVOKE EXECUTE ON PROCEDURE p1 FROM 'root'@'localhost';
+
+-- sync_slave_with_master
+
+-- connection master
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+-- sync_slave_with_master
+
+-- echo ### ii) Test case in which REVOKE partially succeeds
+
+-- connection master
+-- source include/master-slave-reset.inc
+-- connection master
+
+CREATE TABLE t1(c1 INT);
+DELIMITER |;
+CREATE PROCEDURE p1() SELECT * FROM t1 |
+DELIMITER ;|
+
+CREATE USER 'user49119'@'localhost';
+GRANT EXECUTE ON PROCEDURE p1 TO 'user49119'@'localhost';
+
+-- echo ##############################################################
+-- echo ### Showing grants for both users: root and user49119 (master)
+SHOW GRANTS FOR 'user49119'@'localhost';
+SHOW GRANTS FOR CURRENT_USER;
+-- echo ##############################################################
+
+-- sync_slave_with_master
+
+-- echo ##############################################################
+-- echo ### Showing grants for both users: root and user49119 (master)
+SHOW GRANTS FOR 'user49119'@'localhost';
+SHOW GRANTS FOR CURRENT_USER;
+-- echo ##############################################################
+
+-- connection master
+
+-- echo ## This statement will make the revoke fail because root has no
+-- echo ## execute grant. However, it will still revoke the grant for
+-- echo ## user49119.
+-- error ER_NONEXISTING_PROC_GRANT
+REVOKE EXECUTE ON PROCEDURE p1 FROM 'user49119'@'localhost', 'root'@'localhost';
+
+-- echo ##############################################################
+-- echo ### Showing grants for both users: root and user49119 (master)
+-- echo ### after revoke statement failure
+SHOW GRANTS FOR 'user49119'@'localhost';
+SHOW GRANTS FOR CURRENT_USER;
+-- echo ##############################################################
+
+-- sync_slave_with_master
+
+-- echo #############################################################
+-- echo ### Showing grants for both users: root and user49119 (slave)
+-- echo ### after revoke statement failure (should match
+SHOW GRANTS FOR 'user49119'@'localhost';
+SHOW GRANTS FOR CURRENT_USER;
+-- echo ##############################################################
+
+-- connection master
+DROP TABLE t1;
+DROP PROCEDURE p1;
+DROP USER 'user49119'@'localhost';
+
+-- sync_slave_with_master
--echo "End of test"
=== modified file 'mysql-test/suite/rpl/t/rpl_drop_temp.test'
--- a/mysql-test/suite/rpl/t/rpl_drop_temp.test 2009-09-13 20:52:14 +0000
+++ b/mysql-test/suite/rpl/t/rpl_drop_temp.test 2009-12-31 04:04:19 +0000
@@ -34,4 +34,36 @@ connection master;
drop database mysqltest;
sync_slave_with_master;
+#
+# Bug#49137
+# This test verifies if DROP MULTI TEMPORARY TABLE
+# will cause different errors on master and slave,
+# when one or more of these tables do not exist.
+#
+
+connection master;
+DROP TEMPORARY TABLE IF EXISTS tmp1;
+CREATE TEMPORARY TABLE t1 ( a int );
+--error 1051
+DROP TEMPORARY TABLE t1, t2;
+--error 1051
+DROP TEMPORARY TABLE tmp2;
+sync_slave_with_master;
+
+connection slave;
+stop slave;
+wait_for_slave_to_stop;
+
+--echo **** On Master ****
+connection master;
+CREATE TEMPORARY TABLE tmp3 (a int);
+DROP TEMPORARY TABLE tmp3;
+
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+
+connection master;
+sync_slave_with_master;
+
# End of 4.1 tests
=== modified file 'mysql-test/suite/rpl/t/rpl_err_ignoredtable.test'
--- a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test 2009-10-20 18:00:07 +0000
+++ b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test 2009-11-18 14:50:31 +0000
@@ -7,6 +7,8 @@
-- source include/master-slave.inc
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
+
connection master;
create table t1 (a int primary key);
create table t4 (a int primary key);
@@ -14,19 +16,15 @@ create table t4 (a int primary key);
--error 1022, ER_DUP_ENTRY
insert into t1 values (1),(1);
insert into t4 values (1),(2);
-save_master_pos;
-connection slave;
# as the t1 table is ignored on the slave, the slave should be able to sync
-sync_with_master;
+sync_slave_with_master;
# check that the table has been ignored, because otherwise the test is nonsense
show tables like 't1';
show tables like 't4';
SELECT * FROM test.t4 ORDER BY a;
connection master;
drop table t1;
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
# Now test that even critical errors (connection killed)
# are ignored if rules allow it.
@@ -50,18 +48,17 @@ kill @id;
drop table t2,t3;
insert into t4 values (3),(4);
connection master;
+# The get_lock function causes warning for unsafe statement.
+--disable_warnings
--error 0,1317,2013
reap;
+--enable_warnings
connection master1;
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
SELECT * FROM test.t4 ORDER BY a;
connection master1;
DROP TABLE test.t4;
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
# End of 4.1 tests
# Adding comment for force manual merge 5.0 -> wl1012. delete me if needed
=== added file 'mysql-test/suite/rpl/t/rpl_geometry.test'
--- a/mysql-test/suite/rpl/t/rpl_geometry.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_geometry.test 2010-01-05 06:25:29 +0000
@@ -0,0 +1,26 @@
+source include/master-slave.inc;
+source include/have_binlog_format_row.inc;
+
+#
+# Bug#48776, Bug#43784
+#
+create table t1(a varchar(100),
+ b multipoint not null,
+ c varchar(256));
+
+insert into t1 set
+ a='hello',
+ b=geomfromtext('multipoint(1 1)'),
+ c='geometry';
+
+create table t2 (a int(11) not null auto_increment primary key,
+ b geometrycollection default null,
+ c decimal(10,0));
+
+insert into t2(c) values (null);
+
+sync_slave_with_master;
+
+connection master;
+drop table t1, t2;
+source include/master-slave-end.inc;
=== modified file 'mysql-test/suite/rpl/t/rpl_get_lock.test'
--- a/mysql-test/suite/rpl/t/rpl_get_lock.test 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/t/rpl_get_lock.test 2009-11-18 14:50:31 +0000
@@ -1,7 +1,12 @@
source include/master-slave.inc;
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
+
create table t1(n int);
+# Use of get_lock gives a warning for unsafeness if binlog_format=statement
+--disable_warnings
insert into t1 values(get_lock("lock",2));
+--enable_warnings
dirty_close master;
connection master1;
select get_lock("lock",2);
=== modified file 'mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test'
--- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test 2009-10-29 02:26:59 +0000
+++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test 2010-01-27 02:52:13 +0000
@@ -16,12 +16,13 @@
source include/master-slave.inc;
source include/have_debug.inc;
-call mtr.add_suppression("Get master clock failed with error: ");
-call mtr.add_suppression("Get master SERVER_ID failed with error: ");
-call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
+
+connection slave;
+call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: .*");
call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*");
+call mtr.add_suppression("Slave I/O thread .* register on master");
+
#Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection
-connection slave;
let $debug_saved= `select @@global.debug`;
let $debug_lock= "debug_lock.before_get_UNIX_TIMESTAMP";
=== modified file 'mysql-test/suite/rpl/t/rpl_ignore_table.test'
--- a/mysql-test/suite/rpl/t/rpl_ignore_table.test 2008-11-13 19:19:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_ignore_table.test 2009-12-27 13:54:41 +0000
@@ -1,4 +1,6 @@
source include/master-slave.inc;
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
#
# BUG#16487
=== modified file 'mysql-test/suite/rpl/t/rpl_killed_ddl.test'
--- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test 2009-09-25 06:42:43 +0000
+++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test 2010-03-04 08:03:07 +0000
@@ -156,13 +156,12 @@ source include/kill_query_and_diff_maste
send DROP DATABASE d1;
source include/kill_query_and_diff_master_slave.inc;
-send DROP DATABASE d2;
+send DROP DATABASE IF EXISTS d2;
source include/kill_query_and_diff_master_slave.inc;
######## EVENT ########
-let $diff_statement= SELECT event_name, event_body, execute_at
- FROM information_schema.events where event_name like 'e%';
+let $diff_statement= SELECT event_name, event_body, execute_at FROM information_schema.events where event_name like 'e%';
send CREATE EVENT e2
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
@@ -229,7 +228,7 @@ source include/kill_query_and_diff_maste
send DROP PROCEDURE p1;
source include/kill_query_and_diff_master_slave.inc;
-# Temporarily disabled, see comment above for DROP FUNCTION IF EXISTS
+# Temporarily disabled because of bug#43353, see comment above for DROP FUNCTION IF EXISTS
#send DROP PROCEDURE IF EXISTS p2;
#source include/kill_query_and_diff_master_slave.inc;
@@ -280,6 +279,11 @@ source include/kill_query_and_diff_maste
######## TRIGGER ########
+# Make sure table t4 exists
+connection master;
+CREATE TABLE IF NOT EXISTS t4 (a int);
+connection master1;
+
let $diff_statement= SHOW TRIGGERS LIKE 'v%';
DELIMITER //;
=== added file 'mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test'
--- a/mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test 2009-12-16 04:25:46 +0000
@@ -0,0 +1,13 @@
+-- source include/not_ndb_default.inc
+-- source include/have_log_bin.inc
+
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+CREATE TABLE t1 (c1 char(50));
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+LOAD DATA CONCURRENT INFILE '../../std_data/words.dat' INTO TABLE t1;
+-- source include/show_binlog_events.inc
+DROP TABLE t1;
+
+let $lock_option= CONCURRENT;
+let $engine_type=MyISAM;
+-- source extra/rpl_tests/rpl_loaddata.test
=== added file 'mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.opt 2009-11-28 04:43:16 +0000
@@ -0,0 +1 @@
+--secure-file-priv=$MYSQLTEST_VARDIR/std_data_master_link
=== added file 'mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh'
--- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh 2009-11-28 04:43:16 +0000
@@ -0,0 +1 @@
+ln -s $MYSQLTEST_VARDIR/std_data $MYSQLTEST_VARDIR/std_data_master_link
=== added file 'mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.opt 2009-11-28 04:43:16 +0000
@@ -0,0 +1 @@
+--slave-load-tmpdir=$MYSQLTEST_VARDIR/std_data_slave_link
=== added file 'mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh'
--- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh 2009-11-28 04:43:16 +0000
@@ -0,0 +1 @@
+ln -s $MYSQLTEST_VARDIR/std_data $MYSQLTEST_VARDIR/std_data_slave_link
=== added file 'mysql-test/suite/rpl/t/rpl_loaddata_symlink.test'
--- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test 2009-11-28 04:43:16 +0000
@@ -0,0 +1,20 @@
+#
+# BUG#43913
+# This test verifies if loading data infile will work fine
+# if the path of the load data file is a symbolic link.
+#
+--source include/master-slave.inc
+--source include/have_binlog_format_statement.inc
+
+create table t1(a int not null auto_increment, b int, primary key(a) );
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+select * from t1;
+
+sync_slave_with_master;
+connection slave;
+select * from t1;
+
+connection master;
+drop table t1;
+sync_slave_with_master;
+
=== added file 'mysql-test/suite/rpl/t/rpl_manual_change_index_file.test'
--- a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test 2010-01-08 15:32:40 +0000
@@ -0,0 +1,106 @@
+source include/master-slave.inc;
+
+#
+# BUG#28421 Infinite loop on slave relay logs
+#
+# That, manually deleteing one or more entries from 'master-bin.index', will
+# cause master infinitely loop to send one binlog file.
+#
+# Manually changing index file is a illegal action, so when this happen, we
+# send a fatal error to slave and close the dump session.
+
+FLUSH LOGS;
+# Now, 2 entries in index file.
+# ./master-bin.000001
+# ./master-bin.000002
+
+CREATE TABLE t1(c1 INT);
+# Now, the current dump file(master-bin.000002) is the second line of index
+# file
+sync_slave_with_master;
+# Now, all events has been replicate to slave. As current dump file
+# (master-bin.000002) is the last binlog file, so master is waiting for new
+# events.
+
+connection master;
+# Delete './master-bin.000001' from index file.
+let $MYSQLD_DATADIR= `SELECT @@DATADIR`;
+let $file= $MYSQLD_DATADIR/master-bin.index;
+source include/truncate_file.inc;
+
+if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`)
+{
+append_file $MYSQLD_DATADIR/master-bin.index;
+./master-bin.000002
+EOF
+sleep 0.00000001;
+}
+
+if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`)
+{
+append_file $MYSQLD_DATADIR/master-bin.index;
+.\master-bin.000002
+EOF
+sleep 0.00000001;
+}
+
+# Now, only 1 entry in index file. ./master-bin.000002
+
+# Generate master-bin.000003, but it is in the second line.
+FLUSH LOGS;
+# Now, 2 entries in index file.
+# ./master-bin.000002
+# ./master-bin.000003
+
+# Now, master know that new binlog file(master-bin.000003) has been generated.
+# It expects that the new binlog file is in third line of index file, but
+# there is no third line in index file. It is so strange that master sends an
+# error to slave.
+call mtr.add_suppression('Got fatal error 1236 from master when reading data from binary log: .*could not find next log');
+connection slave;
+source include/wait_for_slave_io_to_stop.inc;
+let $last_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
+echo Last_IO_Error;
+echo $last_error;
+
+connection master;
+
+source include/truncate_file.inc;
+
+if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`)
+{
+append_file $MYSQLD_DATADIR/master-bin.index;
+./master-bin.000001
+./master-bin.000002
+./master-bin.000003
+EOF
+sleep 0.00000001;
+}
+
+if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`)
+{
+append_file $MYSQLD_DATADIR/master-bin.index;
+.\master-bin.000001
+.\master-bin.000002
+.\master-bin.000003
+EOF
+sleep 0.00000001;
+}
+
+CREATE TABLE t2(c1 INT);
+FLUSH LOGS;
+CREATE TABLE t3(c1 INT);
+FLUSH LOGS;
+CREATE TABLE t4(c1 INT);
+
+connection slave;
+START SLAVE IO_THREAD;
+source include/wait_for_slave_io_to_start.inc;
+
+connection master;
+sync_slave_with_master;
+SHOW TABLES;
+
+connection master;
+DROP TABLE t1, t2, t3, t4;
+source include/master-slave-end.inc;
=== modified file 'mysql-test/suite/rpl/t/rpl_misc_functions.test'
--- a/mysql-test/suite/rpl/t/rpl_misc_functions.test 2008-10-07 08:25:12 +0000
+++ b/mysql-test/suite/rpl/t/rpl_misc_functions.test 2010-01-13 09:00:03 +0000
@@ -3,12 +3,16 @@
#
source include/master-slave.inc;
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
+
create table t1(id int, i int, r1 int, r2 int, p varchar(100));
insert into t1 values(1, connection_id(), 0, 0, "");
# don't put rand and password in the same query, to see if they replicate
# independently
# Pure rand test
+--disable_warnings
insert into t1 values(2, 0, rand()*1000, rand()*1000, "");
+--enable_warnings
# change the rand suite on the master (we do this because otherwise password()
# benefits from the fact that the above rand() is well replicated :
# it picks the same sequence element, which hides a possible bug in password() replication.
@@ -19,7 +23,9 @@ set sql_log_bin=1;
# Pure password test
insert into t1 values(3, 0, 0, 0, password('does_this_work?'));
# "altogether now"
+--disable_warnings
insert into t1 values(4, connection_id(), rand()*1000, rand()*1000, password('does_this_still_work?'));
+--enable_warnings
select * into outfile 'rpl_misc_functions.outfile' from t1;
let $MYSQLD_DATADIR= `select @@datadir`;
sync_slave_with_master;
@@ -73,11 +79,13 @@ DELIMITER ;|
# Exercise the functions and procedures then compare the results on
# the master to those on the slave.
+--disable_warnings
CALL test_replication_sp1();
CALL test_replication_sp2();
INSERT INTO t1 (col_a) VALUES (test_replication_sf());
INSERT INTO t1 (col_a) VALUES (test_replication_sf());
INSERT INTO t1 (col_a) VALUES (test_replication_sf());
+--enable_warnings
--sync_slave_with_master
=== modified file 'mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test'
--- a/mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test 2010-01-19 10:36:52 +0000
@@ -23,6 +23,7 @@ connection master;
# Test replication of timestamp
create table t2(id int auto_increment primary key, created datetime);
+SET TIME_ZONE= '+03:00';
set timestamp=12345;
insert into t2 set created=now();
select * from t2;
=== modified file 'mysql-test/suite/rpl/t/rpl_name_const.test'
--- a/mysql-test/suite/rpl/t/rpl_name_const.test 2009-04-08 23:42:51 +0000
+++ b/mysql-test/suite/rpl/t/rpl_name_const.test 2010-03-28 18:10:00 +0000
@@ -45,3 +45,4 @@ select * from t1 order by id;
connection master;
drop table t1;
drop procedure test_procedure;
+--sync_slave_with_master
=== added file 'mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test'
--- a/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test 2010-01-13 09:00:03 +0000
@@ -0,0 +1,57 @@
+# ==== Purpose ====
+#
+# Test that nondeterministic system functions are correctly replicated.
+#
+# (Some functions are only correctly replicated if binlog_format=MIXED
+# or ROW. See binlog_unsafe.test for a test that those variables are
+# indeed unsafe.)
+#
+# ==== Implementation ====
+#
+# We insert the values of each unsafe function into a table. Then we
+# replicate and check that the table is identical on slave.
+#
+# ==== Related bugs ====
+#
+# BUG#47995
+
+--source include/master-slave.inc
+
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
+
+CREATE TABLE t1 (a VARCHAR(1000));
+
+# We replicate the connection_id in the query_log_event
+INSERT INTO t1 VALUES (CONNECTION_ID());
+--connection master1
+INSERT INTO t1 VALUES (CONNECTION_ID());
+
+# We replicate the TIMESTAMP variable, so the following functions that
+# are affected by the TIMESTAMP variable should be safe to replicate.
+INSERT INTO t1 VALUES
+ (CURDATE()),
+ (CURRENT_DATE()),
+ (CURRENT_TIME()),
+ (CURRENT_TIMESTAMP()),
+ (CURTIME()),
+ (LOCALTIME()),
+ (LOCALTIMESTAMP()),
+ (NOW()),
+ (UNIX_TIMESTAMP()),
+ (UTC_DATE()),
+ (UTC_TIME()),
+ (UTC_TIMESTAMP());
+
+# We replicate the random seed in a rand_log_event
+--disable_warnings
+INSERT INTO t1 VALUES (RAND());
+--enable_warnings
+# We replicate the last_insert_id in an intvar_log_event
+INSERT INTO t1 VALUES (LAST_INSERT_ID());
+
+--sync_slave_with_master
+--let $diff_table_1= master:test.t1
+--let $diff_table_2= slave:test.t1
+--source include/diff_tables.inc
+
+DROP TABLE t1;
=== added file 'mysql-test/suite/rpl/t/rpl_not_null_innodb.test'
--- a/mysql-test/suite/rpl/t/rpl_not_null_innodb.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_not_null_innodb.test 2009-10-22 00:15:45 +0000
@@ -0,0 +1,19 @@
+#################################################################################
+# This test checks if the replication between "null" fields to either "null"
+# fields or "not null" fields works properly. In the first case, the execution
+# should work fine. In the second case, it may fail according to the sql_mode
+# being used.
+#
+# The test is devided in three main parts:
+#
+# 1 - NULL --> NULL (no failures)
+# 2 - NULL --> NOT NULL ( sql-mode = STRICT and failures)
+# 3 - NULL --> NOT NULL ( sql-mode != STRICT and no failures)
+#
+#################################################################################
+--source include/master-slave.inc
+--source include/have_innodb.inc
+--source include/have_binlog_format_row.inc
+
+let $engine=Innodb;
+--source extra/rpl_tests/rpl_not_null.test
=== added file 'mysql-test/suite/rpl/t/rpl_not_null_myisam.test'
--- a/mysql-test/suite/rpl/t/rpl_not_null_myisam.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_not_null_myisam.test 2009-10-22 00:15:45 +0000
@@ -0,0 +1,18 @@
+#################################################################################
+# This test checks if the replication between "null" fields to either "null"
+# fields or "not null" fields works properly. In the first case, the execution
+# should work fine. In the second case, it may fail according to the sql_mode
+# being used.
+#
+# The test is devided in three main parts:
+#
+# 1 - NULL --> NULL (no failures)
+# 2 - NULL --> NOT NULL ( sql-mode = STRICT and failures)
+# 3 - NULL --> NOT NULL ( sql-mode != STRICT and no failures)
+#
+#################################################################################
+--source include/master-slave.inc
+--source include/have_binlog_format_row.inc
+
+let $engine=MyISAM;
+--source extra/rpl_tests/rpl_not_null.test
=== modified file 'mysql-test/suite/rpl/t/rpl_optimize.test'
--- a/mysql-test/suite/rpl/t/rpl_optimize.test 2009-06-05 15:35:22 +0000
+++ b/mysql-test/suite/rpl/t/rpl_optimize.test 2010-03-04 08:03:07 +0000
@@ -15,6 +15,8 @@
-- source include/not_staging.inc
-- source include/master-slave.inc
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
+
create table t1 (a int not null auto_increment primary key, b int, key(b));
INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
INSERT INTO t1 (a) SELECT null FROM t1;
@@ -32,8 +34,8 @@ INSERT INTO t1 (a) SELECT null FROM t1;
INSERT INTO t1 (a) SELECT null FROM t1;
save_master_pos;
# a few updates to force OPTIMIZE to do something
-update t1 set b=(a/2*rand());
--disable_warnings
+update t1 set b=(a/2*rand());
delete from t1 order by b limit 10000;
--enable_warnings
=== modified file 'mysql-test/suite/rpl/t/rpl_relayspace.test'
--- a/mysql-test/suite/rpl/t/rpl_relayspace.test 2008-02-28 11:36:14 +0000
+++ b/mysql-test/suite/rpl/t/rpl_relayspace.test 2010-01-18 12:56:10 +0000
@@ -2,8 +2,10 @@
# to force the deadlock after one event.
source include/master-slave.inc;
+let $master_log_file= query_get_value(SHOW MASTER STATUS, File, 1);
connection slave;
stop slave;
+source include/wait_for_slave_to_stop.inc;
connection master;
# This will generate a master's binlog > 10 bytes
create table t1 (a int);
@@ -20,6 +22,7 @@ source include/wait_for_slave_param.inc;
# A bug caused the I/O thread to refuse stopping.
stop slave io_thread;
+source include/wait_for_slave_io_to_stop.inc;
reset slave;
start slave;
# The I/O thread stops filling the relay log when
@@ -29,9 +32,11 @@ start slave;
# So we should have a deadlock.
# if it is not resolved automatically we'll detect
# it with master_pos_wait that waits for farther than 1Ob;
-# it will timeout after 10 seconds;
+# it will timeout;
# also the slave will probably not cooperate to shutdown
# (as 2 threads are locked)
-select master_pos_wait('master-bin.001',200,6)=-1;
+--replace_result $master_log_file MASTER_LOG_FILE
+eval select master_pos_wait('$master_log_file',200,30)=-1;
+
# End of 4.1 tests
=== modified file 'mysql-test/suite/rpl/t/rpl_rotate_logs.test'
--- a/mysql-test/suite/rpl/t/rpl_rotate_logs.test 2009-03-12 09:48:41 +0000
+++ b/mysql-test/suite/rpl/t/rpl_rotate_logs.test 2010-01-27 21:53:08 +0000
@@ -153,7 +153,7 @@ disable_query_log;
while ($1)
{
#eval means expand $ expressions
- eval insert into t3 values($1 + 4);
+ eval insert HIGH_PRIORITY into t3 values($1 + 4);
dec $1;
}
enable_query_log;
=== modified file 'mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test'
--- a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2007-12-12 10:14:59 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test 2010-03-28 18:10:00 +0000
@@ -53,6 +53,7 @@ UPDATE t1 SET a=99 WHERE a = 0;
SHOW BINLOG EVENTS;
DROP TABLE t1;
+--sync_slave_with_master
# BUG#17620: Replicate (Row Based) Fails when Query Cache enabled on
# slave
=== modified file 'mysql-test/suite/rpl/t/rpl_row_create_table.test'
--- a/mysql-test/suite/rpl/t/rpl_row_create_table.test 2009-01-23 12:22:05 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_create_table.test 2009-11-27 13:34:39 +0000
@@ -292,4 +292,40 @@ connection master;
DROP DATABASE mysqltest1;
sync_slave_with_master;
+#
+# BUG#48506: crash in CREATE TABLE <existing_view> IF NOT EXISTS LIKE
+# <tmp_tbl> with RBL
+#
+
+source include/master-slave-reset.inc;
+
+connection master;
+CREATE TEMPORARY TABLE t7(c1 INT);
+CREATE TABLE t5(c1 INT);
+CREATE TABLE t4(c1 INT);
+CREATE VIEW bug48506_t1 AS SELECT 1;
+CREATE VIEW bug48506_t2 AS SELECT * FROM t4;
+CREATE VIEW bug48506_t3 AS SELECT t5.c1 AS A, t4.c1 AS B FROM t5, t4;
+CREATE TABLE bug48506_t4(c1 INT);
+--disable_warnings
+sync_slave_with_master;
+DROP VIEW bug48506_t1, bug48506_t2, bug48506_t3;
+DROP TABLE bug48506_t4;
+
+connection master;
+CREATE TABLE IF NOT EXISTS bug48506_t1 LIKE t7;
+CREATE TABLE IF NOT EXISTS bug48506_t2 LIKE t7;
+CREATE TABLE IF NOT EXISTS bug48506_t3 LIKE t7;
+CREATE TABLE IF NOT EXISTS bug48506_t4 LIKE t7;
+--enable_warnings
+sync_slave_with_master;
+
+SHOW TABLES LIKE 'bug48506%';
+
+connection master;
+DROP VIEW IF EXISTS bug48506_t1, bug48506_t2, bug48506_t3;
+DROP TEMPORARY TABLES t7;
+DROP TABLES t4, t5;
+DROP TABLES IF EXISTS bug48506_t4;
+source include/master-slave-end.inc;
--echo end of the tests
=== renamed file 'mysql-test/suite/binlog/t/binlog_tbl_metadata.test' => 'mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test'
--- a/mysql-test/suite/binlog/t/binlog_tbl_metadata.test 2009-05-12 11:53:46 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test 2010-01-14 10:49:40 +0000
@@ -2,38 +2,39 @@
# BUG#42749: infinite loop writing to row based binlog - processlist shows
# "freeing items"
#
+#
# WHY
# ===
-#
-# This bug would make table map event to report data_written one byte less
-# than what would actually be written in its body. This would cause one byte shorter
-# event end_log_pos. The ultimate impact was that it would make fixing the
-# position in MYSQL_BIN_LOG::write_cache bogus or end up in an infinite loop.
+#
+# This bug would make table map event to report data_written one
+# byte less than what would actually be written in its body. This
+# would cause one byte shorter event end_log_pos. The ultimate
+# impact was that it would make fixing the position in
+# MYSQL_BIN_LOG::write_cache bogus or end up in an infinite loop.
#
# HOW
# ===
#
# Checking that the patch fixes the problem is done as follows:
-# i) a table with several fields is created;
+#
+# i) one table with m_field_metadata sized at 290
# ii) an insert is performed;
# iii) the logs are flushed;
# iv) mysqlbinlog is used to check if it succeeds.
#
-# In step iv), before the bug was fixed, the test case would fail with
-# mysqlbinlog reporting that it was unable to succeed in reading the event.
-#
+# In step iv), before the bug was fixed, the test case would fail
+# with mysqlbinlog reporting that it was unable to succeed in
+# reading the event.
--- source include/have_log_bin.inc
+-- source include/master-slave.inc
-- source include/have_innodb.inc
-- source include/have_binlog_format_row.inc
--- connection default
-
-RESET MASTER;
-- disable_warnings
DROP TABLE IF EXISTS `t1`;
-- enable_warnings
+-- echo ### TABLE with field_metadata_size == 290
CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
`c2` varchar(30) NOT NULL,
@@ -185,15 +186,155 @@ CREATE TABLE `t1` (
) ENGINE=InnoDB;
LOCK TABLES `t1` WRITE;
+INSERT INTO `t1`(c2) VALUES ('1');
+FLUSH LOGS;
+
+-- sync_slave_with_master
+-- connection master
-INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1');
+-- echo ### assertion: the slave replicated event successfully and tables match
+-- let $diff_table_1=master:test.t1
+-- let $diff_table_2=slave:test.t1
+-- source include/diff_tables.inc
DROP TABLE `t1`;
-FLUSH LOGS;
+-- connection master
+-- sync_slave_with_master
+-- connection master
-- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail.
-- let $MYSQLD_DATADIR= `SELECT @@datadir`;
-- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog
-- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog
+
+#############################################################
+# BUG#50018: binlog corruption when table has many columns
+#
+# Same test from BUG#42749, but now we generate some SQL which
+# creates and inserts into tables with metadata size from 249
+# to 258.
+#
+# The test works as follows:
+# 1. SQL for several CREATE TABLE and INSERTS are generated
+# into a file.
+# 2. This file is then "sourced"
+# 3. The slave is synchronized with the master
+# 4. FLUSH LOGS on master
+# 5. Compare tables on master and slave.
+# 6. run mysqlbinlog on master's binary log
+#
+# Steps #5 and #6 assert that binary log is not corrupted
+# in both cases: when slave is replaying events and when
+# mysqlbinlog is used to read the binary log
+
+-- source include/master-slave-reset.inc
+-- connection master
+
+# Create several tables with field_metadata_size ranging
+# from 249 to 258 (so that we cover 251 and 255 range).
+# This should exercise the switch between using 1 or 3
+# bytes to pack m_field_metadata_size.
+#
+# Each varchar field takes up to 2 metadata bytes, see:
+#
+# Field_varstring::do_save_field_metadata (field.cc)
+#
+# The float field takes 1 byte, see:
+#
+# Field_float::do_save_field_metadata (field.cc)
+#
+
+-- let $generated_sql= $MYSQLTEST_VARDIR/tmp/b50018.sql
+-- let B50018_FILE= $generated_sql
+
+-- echo ### action: generating several tables with different metadata
+-- echo ### sizes (resorting to perl)
+-- perl
+my $file= $ENV{'B50018_FILE'};
+open(FILE, ">", "$file") or die "Unable to open bug 50018 generated SQL file: $!" ;
+
+my $tables= "";
+my $ntables= 10;
+my $base_ncols= 124;
+
+for my $i (1..$ntables)
+{
+ my $ncols= $base_ncols + $i;
+ my $metadata_size= $ncols_variable * 2 + 1;
+
+ print FILE "-- echo ### testing table with " . ($base_ncols*2 + $i) . " field metadata size.\n";
+ print FILE "CREATE TABLE t$i (\n";
+ for my $n (1..$base_ncols)
+ {
+ print FILE "c$n VARCHAR(30) NOT NULL DEFAULT 'BUG#50018',\n";
+ }
+
+ for my $n (1..$i)
+ {
+ print FILE "c" . ($base_ncols+$n) . " FLOAT NOT NULL DEFAULT 0";
+ if ($n < $i)
+ {
+ print FILE ",\n";
+ }
+ }
+
+ print FILE ") Engine=InnoDB;\n";
+
+ $tables.= " t$i WRITE";
+ if ($i < $ntables)
+ {
+ $tables .=",";
+ }
+
+ print FILE "LOCK TABLES t$i WRITE;\n";
+ print FILE "INSERT INTO t$i(c". ($base_ncols+1) . ") VALUES (50018);\n";
+ print FILE "UNLOCK TABLES;";
+}
+
+close(FILE);
+
+EOF
+
+## we don't need this in the result file
+## however, for debugging purposes you
+## may want to reactivate query logging
+-- disable_query_log
+-- source $generated_sql
+-- enable_query_log
+
+-- sync_slave_with_master
+-- connection master
+
+FLUSH LOGS;
+
+-- let $ntables=10
+while($ntables)
+{
+ -- echo ### assertion: the slave replicated event successfully and tables match for t$ntables
+ -- let $diff_table_1=master:test.t$ntables
+ -- let $diff_table_2=slave:test.t$ntables
+ -- source include/diff_tables.inc
+
+ -- connection master
+ -- disable_query_log
+ -- eval DROP TABLE t$ntables
+ -- enable_query_log
+ -- sync_slave_with_master
+ -- connection master
+
+ -- dec $ntables
+}
+
+-- echo ### assertion: check that binlog is not corrupt. Using mysqlbinlog to
+-- echo ### detect failure. Before the patch mysqlbinlog would find
+-- echo ### a corrupted event, thence would fail.
+-- let $MYSQLD_DATADIR= `SELECT @@datadir`;
+-- exec $MYSQL_BINLOG -v --hex $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog
+
+## clean up
+## For debugging purposes you might want not to remove these
+-- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog
+-- remove_file $generated_sql
+-- source include/master-slave-end.inc
=== modified file 'mysql-test/suite/rpl/t/rpl_row_trig003.test'
--- a/mysql-test/suite/rpl/t/rpl_row_trig003.test 2007-12-06 15:27:10 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_trig003.test 2010-03-29 19:07:45 +0000
@@ -149,6 +149,8 @@ DROP TABLE IF EXISTS test.t2;
DROP TABLE IF EXISTS test.t3;
--enable_warnings
+sync_slave_with_master;
+
diff_files $MYSQLTEST_VARDIR/tmp/trg003_master.sql $MYSQLTEST_VARDIR/tmp/trg003_slave.sql;
# End of 5.0 test case
=== added file 'mysql-test/suite/rpl/t/rpl_row_trunc_temp.test'
--- a/mysql-test/suite/rpl/t/rpl_row_trunc_temp.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_trunc_temp.test 2009-11-22 05:10:33 +0000
@@ -0,0 +1,35 @@
+#
+# Bug#48350 truncate temporary table crashes replication
+#
+# All statements operating on temporary tables should not be binlogged in RBR.
+# However, before fix of bug#48350, 'TRUNCATE ...' statement on a temporary
+# table was binlogged in RBR.
+#
+
+--source include/master-slave.inc
+--source include/have_binlog_format_row.inc
+
+#This statement is not binlogged in RBR.
+CREATE TEMPORARY TABLE t1(c1 INTEGER);
+CREATE TABLE t2(c1 INTEGER);
+sync_slave_with_master;
+
+CREATE TABLE t1(c1 INTEGER);
+INSERT INTO t1 VALUES(1), (2);
+INSERT INTO t2 VALUES(1), (2);
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+connection master;
+TRUNCATE t1;
+TRUNCATE t2;
+sync_slave_with_master;
+# t1 will have nothing, if 'TRUNCATE t1' has been replicate from master to
+# slave.
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+DROP TABLE t1;
+connection master;
+DROP TABLE t2;
+--source include/master-slave-end.inc
=== added file 'mysql-test/suite/rpl/t/rpl_set_null_innodb.test'
--- a/mysql-test/suite/rpl/t/rpl_set_null_innodb.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_set_null_innodb.test 2010-01-21 17:20:24 +0000
@@ -0,0 +1,6 @@
+-- source include/have_binlog_format_mixed_or_row.inc
+-- source include/master-slave.inc
+-- source include/have_innodb.inc
+
+-- let $engine= InnoDB
+-- source extra/rpl_tests/rpl_set_null.test
=== added file 'mysql-test/suite/rpl/t/rpl_set_null_myisam.test'
--- a/mysql-test/suite/rpl/t/rpl_set_null_myisam.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_set_null_myisam.test 2010-01-21 17:20:24 +0000
@@ -0,0 +1,5 @@
+-- source include/have_binlog_format_mixed_or_row.inc
+-- source include/master-slave.inc
+
+-- let $engine= MyISAM
+-- source extra/rpl_tests/rpl_set_null.test
=== added file 'mysql-test/suite/rpl/t/rpl_stm_binlog_direct-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_stm_binlog_direct-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stm_binlog_direct-master.opt 2010-01-20 19:08:16 +0000
@@ -0,0 +1 @@
+--binlog-direct-non-transactional-updates
=== added file 'mysql-test/suite/rpl/t/rpl_stm_binlog_direct.test'
--- a/mysql-test/suite/rpl/t/rpl_stm_binlog_direct.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stm_binlog_direct.test 2010-01-20 19:08:16 +0000
@@ -0,0 +1,230 @@
+################################################################################
+# This test case checks if the option "binlog-direct-non-transactional-updates"
+# makes non-transactional changes in the statement format to be written to the
+# binary log as soon as the statement commits.
+#
+# In what follows, we use the include file rpl_mixing_engines.inc to generate
+# sql commands from a format string. The format string consists of a sequence of
+# 'codes' separated by spaces. Before it set of commands, we paste the expected
+# sequence in the binary log. The following codes exist:
+#
+# - Define the scope of a transaction:
+# B - Begin.
+# C - Commit.
+# R - Rollback.
+#
+# - Change only T-Tables:
+# T - Updates a T-Table.
+# T-trig - Updates T-Tables through a trigger.
+# T-func - Updates T-Tables through a function.
+# T-proc - Updates T-Tables through a procedure.
+# eT - Fails while updating the first tuple in a T-Table.
+# Te - Fails while updating an n-tuple (n > 1) in a T-Table.
+# Te-trig - Fails while updating an n-tuple (n > 1) in a T-Table.
+# Te-func - Fails while updating an n-tuple (n > 1) in a T-Table.
+#
+# - Change only N-Tables
+# N - Updates a N-Table.
+# N-trig - Updates N-Tables through a trigger.
+# N-func - Updates N-Tables through a function.
+# N-proc - Updates N-Tables through a procedure.
+# eN - Fails while updating the first tuple in a N-Table.
+# Ne - Fails while updating an n-tuple (n > 1) in a N-Table.
+# Ne-trig - Fails while updating an n-tuple (n > 1) in a N-Table.
+# Ne-func - Fails while updating an n-tuple (n > 1) in a N-Table.
+################################################################################
+
+--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
+--source include/have_innodb.inc
+
+set @@session.binlog_direct_non_transactional_updates= TRUE;
+
+--echo #########################################################################
+--echo # CONFIGURATION
+--echo #########################################################################
+
+--let $engine_type= Innodb
+SET @commands= 'configure';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+--echo #########################################################################
+--echo # 1 - BINLOG ORDER
+--echo #########################################################################
+connection master;
+
+--echo
+--echo
+--echo
+--echo
+--echo #
+--echo #3) Generates in the binlog what follows:
+--echo # --> STMT "N B T C" entries, format S.
+--echo #
+SET @commands= 'B T N C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T N-trig C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T N-func C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T N-proc C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-trig N C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-trig N-trig C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-trig N-func C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-trig N-proc C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-func N C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-func N-trig C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-func N-func C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-func N-proc C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-proc N C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-proc N-trig C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-proc N-func C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-proc N-proc C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+
+--echo
+--echo
+--echo
+--echo
+--echo #
+--echo #3.e) Generates in the binlog what follows if T-* fails:
+--echo # --> STMT "N" entry, format S.
+--echo # Otherwise, what follows if N-* fails and a N-Table is changed:
+--echo # --> STMT "N B T C" entries, format S.
+--echo #
+SET @commands= 'B eT N C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B Te N C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T eN C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T Ne C';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+
+--echo
+--echo
+--echo
+--echo
+--echo #
+--echo #4) Generates in the binlog what follows:
+--echo # --> STMT "N B T R" entries, format S.
+--echo #
+SET @commands= 'B T N R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T N-trig R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T N-func R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T N-proc R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-trig N R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-trig N-trig R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-trig N-func R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-trig N-proc R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-func N R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-func N-trig R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-func N-func R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-func N-proc R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-proc N R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-proc N-trig R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-proc N-func R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T-proc N-proc R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+
+--echo
+--echo
+--echo
+--echo
+--echo #
+--echo #4.e) Generates in the binlog what follows if T* fails:
+--echo # --> STMT "B N C" entry, format S.
+--echo # Otherwise, what follows if N* fails and a N-Table is changed:
+--echo # --> STMT "N" entries, format S.
+--echo #
+SET @commands= 'B eT N R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B Te N R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T eN R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+SET @commands= 'B T Ne R';
+--source extra/rpl_tests/rpl_mixing_engines.inc
+
+
+--echo ###################################################################################
+--echo # CHECK CONSISTENCY
+--echo ###################################################################################
+connection master;
+sync_slave_with_master;
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql
+--diff_files $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql
+
+--echo ###################################################################################
+--echo # CLEAN
+--echo ###################################################################################
+SET @commands= 'clean';
+--source extra/rpl_tests/rpl_mixing_engines.inc
=== modified file 'mysql-test/suite/rpl/t/rpl_stm_maria.test'
--- a/mysql-test/suite/rpl/t/rpl_stm_maria.test 2008-01-20 04:25:26 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stm_maria.test 2010-03-04 08:03:07 +0000
@@ -4,6 +4,9 @@
--source include/have_binlog_format_mixed_or_statement.inc
--source include/master-slave.inc
+# Suppress warnings that rand() is unsafe in statement binlog mode
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
+
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
@@ -37,10 +40,12 @@ insert into t3 values(100,"log",0,0,0);
SET @@RAND_SEED1=658490765, @@RAND_SEED2=635893186;
+--disable_warnings
insert into t1 values(1,1,rand()),(NULL,2,rand());
insert into t2 (b) values(last_insert_id());
insert into t2 values(3,0),(NULL,0);
insert into t2 values(NULL,0),(500,0);
+--enable_warnings
select a,b, truncate(rand_value,4) from t1;
select * from t2;
=== modified file 'mysql-test/suite/rpl/t/rpl_stm_until.test'
--- a/mysql-test/suite/rpl/t/rpl_stm_until.test 2008-07-23 11:23:52 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stm_until.test 2010-01-27 17:27:49 +0000
@@ -98,3 +98,102 @@ start slave until relay_log_file='slave-
start slave sql_thread;
start slave until master_log_file='master-bin.000001', master_log_pos=776;
+#
+# bug#47210 first execution of "start slave until" stops too early
+#
+# testing that a slave rotate event that is caused by stopping the slave
+# does not intervene anymore in UNTIL condition.
+#
+
+connection slave;
+source include/stop_slave.inc;
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+reset slave;
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root';
+
+connection master;
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+reset master;
+create table t1 (a int primary key auto_increment);
+save_master_pos;
+let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+connection slave;
+start slave;
+sync_with_master;
+
+# at this point slave will close the relay log stamping it with its own
+# Rotate log event. This event won't be examined on matter of the master
+# UNTIL pos anymore.
+source include/stop_slave.inc;
+let $slave_exec_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1);
+
+--echo master and slave are in sync now
+let $diff_pos= `select $master_pos - $slave_exec_pos`;
+eval select $diff_pos as zero;
+
+connection master;
+insert into t1 set a=null;
+let $until_pos= query_get_value(SHOW MASTER STATUS, Position, 1);
+insert into t1 set a=null;
+select count(*) as two from t1;
+
+connection slave;
+--replace_result $until_pos UNTIL_POS;
+eval start slave until master_log_file='master-bin.000001', master_log_pos= $until_pos;
+source include/wait_for_slave_sql_to_stop.inc;
+let $slave_exec_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1);
+--echo slave stopped at the prescribed position
+let $diff_pos= `select $until_pos - $slave_exec_pos`;
+eval select $diff_pos as zero;
+select count(*) as one from t1;
+
+
+connection master;
+drop table t1;
+
+connection slave;
+start slave;
+sync_with_master;
+
+ # Bug #47142 "slave start until" stops 1 event too late in 4.1 to 5.0 replication
+#
+# testing fixes that refine the start position of prior-5.0 master's event
+# and by that provide correct execution of
+# START SLAVE UNTIL ... master_log_pos= x;
+# Keep the test at the end of the file because it manipulates with binlog files
+# to substitute the genuine one with a prepared on 4.1 server.
+#
+
+--source include/master-slave-reset.inc
+
+connection master;
+drop table if exists t1; # there is create table t1 in bug47142_master-bin.000001
+flush logs;
+let $MYSQLD_DATADIR= `select @@datadir`;
+--remove_file $MYSQLD_DATADIR/master-bin.000001
+--copy_file $MYSQL_TEST_DIR/std_data/bug47142_master-bin.000001 $MYSQLD_DATADIR/master-bin.000001
+
+connection slave;
+stop slave;
+reset slave;
+start slave until master_log_file='master-bin.000001', master_log_pos=294 /* to stop right before DROP */;
+--source include/wait_for_slave_sql_to_stop.inc
+
+show tables /* t1 must exist */;
+
+# clean-up of Bug #47142 testing
+
+drop table t1; # drop on slave only, master does not have t1.
+stop slave;
+reset slave;
+
+connection master;
+reset master;
+
+# End of tests
=== modified file 'mysql-test/suite/rpl/t/rpl_temporary.test'
--- a/mysql-test/suite/rpl/t/rpl_temporary.test 2009-05-22 23:29:41 +0000
+++ b/mysql-test/suite/rpl/t/rpl_temporary.test 2010-03-04 08:03:07 +0000
@@ -1,7 +1,10 @@
+-- source include/master-slave.inc
+
# Test need anonymous user when connection are made as "zedjzlcsjhd"
+# But we only need it on the master, not the slave.
+SET sql_log_bin = 0;
source include/add_anonymous_users.inc;
-
--- source include/master-slave.inc
+SET sql_log_bin = 1;
# Clean up old slave's binlogs.
# The slave is started with --log-slave-updates
@@ -17,9 +20,6 @@ source include/add_anonymous_users.inc;
save_master_pos;
connection slave;
-# Add suppression for expected warning(s) in slaves error log
-call mtr.add_suppression("Slave: Can\'t find record in \'user\' Error_code: 1032");
-
sync_with_master;
reset master;
@@ -116,8 +116,10 @@ SET @@session.sql_select_limit=10, @@ses
SELECT @@session.sql_select_limit = @save_select_limit; #shouldn't have changed
# Now as root, to be sure it works
connection con2;
+SET @save_conn_id= connection_id();
SET @@session.pseudo_thread_id=100;
SET @@session.pseudo_thread_id=connection_id();
+SET @@session.pseudo_thread_id=@save_conn_id;
SET @@session.sql_log_bin=0;
SET @@session.sql_log_bin=1;
@@ -291,7 +293,9 @@ drop table t1;
--remove_file $MYSQLTEST_VARDIR/tmp/bug14157.sql
# Delete the anonymous users
+SET sql_log_bin = 0;
source include/delete_anonymous_users.inc;
+SET sql_log_bin = 1;
=== modified file 'mysql-test/suite/rpl/t/rpl_timezone.test'
--- a/mysql-test/suite/rpl/t/rpl_timezone.test 2009-03-25 10:42:16 +0000
+++ b/mysql-test/suite/rpl/t/rpl_timezone.test 2009-12-16 19:53:56 +0000
@@ -179,8 +179,11 @@ insert into t1 values('2008-12-23 19:39:
--connection master1
SET @@session.time_zone='+02:00';
insert delayed into t1 values ('2008-12-23 19:39:39',2);
-# Forces table t1 to be closed and flushes the query cache.
-# This makes sure that 'delayed insert' is executed before next statement.
+
+# wait for the delayed insert to be executed
+let $wait_condition= SELECT date FROM t1 WHERE a=2;
+--source include/wait_condition.inc
+
flush table t1;
flush logs;
select * from t1;
=== added file 'mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test'
--- a/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test 2010-01-22 09:38:21 +0000
@@ -0,0 +1,13 @@
+#
+# Bug#49132
+# This test verifies if executing DDL statement before trying to manipulate
+# a temporary table causes row-based replication to break with error 'table
+# does not exist' base on myisam engine.
+#
+
+source include/master-slave.inc;
+source include/have_binlog_format_row.inc;
+
+LET $ENGINE_TYPE= MyISAM;
+source extra/rpl_tests/rpl_tmp_table_and_DDL.test;
+
=== modified file 'mysql-test/suite/rpl/t/rpl_trigger.test'
--- a/mysql-test/suite/rpl/t/rpl_trigger.test 2009-08-03 15:01:06 +0000
+++ b/mysql-test/suite/rpl/t/rpl_trigger.test 2010-01-13 09:00:03 +0000
@@ -5,6 +5,8 @@
--source include/have_binlog_format_mixed_or_statement.inc
--source include/master-slave.inc
+CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
+
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
@@ -38,10 +40,12 @@ insert into t3 values(100,"log",0,0,0);
SET @@RAND_SEED1=658490765, @@RAND_SEED2=635893186;
# Emulate that we have rows 2-9 deleted on the slave
+--disable_warnings
insert into t1 values(1,1,rand()),(NULL,2,rand());
insert into t2 (b) values(last_insert_id());
insert into t2 values(3,0),(NULL,0);
insert into t2 values(NULL,0),(500,0);
+--enable_warnings
select a,b, truncate(rand_value,4) from t1;
select * from t2;
@@ -89,7 +93,11 @@ end
|
delimiter ;|
+# The trigger causes a warning for unsafe statement when
+# binlog_format=statement since it uses get_lock.
+--disable_warnings
insert into t1 set a = now();
+--enable_warnings
select a=b && a=c from t1;
let $time=`select a from t1`;
@@ -135,7 +143,11 @@ disconnect con2;
truncate table t1;
drop trigger t1_first;
+# The trigger causes a warning for unsafe statement when
+# binlog_format=statement since it uses get_lock.
+--disable_warnings
insert into t1 values ("2003-03-03","2003-03-03","2003-03-03"),(bug12480(),bug12480(),bug12480()),(now(),now(),now());
+--enable_warnings
select a=b && a=c from t1;
drop function bug12480;
=== modified file 'mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result 2009-08-29 08:30:59 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result 2009-10-22 00:21:50 +0000
@@ -400,62 +400,6 @@ set @b1 = concat(@b1,@b1);
INSERT INTO t8 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
*** Drop t8 ***
DROP TABLE t8;
-STOP SLAVE;
-RESET SLAVE;
-CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
-d TIMESTAMP,
-e INT NOT NULL) ENGINE='NDB';
-*** Create t9 on Master ***
-CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
-) ENGINE='NDB';
-RESET MASTER;
-*** Start Slave ***
-START SLAVE;
-*** Master Data Insert ***
-set @b1 = 'b1b1b1b1';
-set @b1 = concat(@b1,@b1);
-INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
-SHOW SLAVE STATUS;
-Slave_IO_State #
-Master_Host 127.0.0.1
-Master_User root
-Master_Port #
-Connect_Retry 1
-Master_Log_File master-bin.000001
-Read_Master_Log_Pos #
-Relay_Log_File #
-Relay_Log_Pos #
-Relay_Master_Log_File master-bin.000001
-Slave_IO_Running Yes
-Slave_SQL_Running No
-Replicate_Do_DB
-Replicate_Ignore_DB
-Replicate_Do_Table
-Replicate_Ignore_Table #
-Replicate_Wild_Do_Table
-Replicate_Wild_Ignore_Table
-Last_Errno 1364
-Last_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 447
-Skip_Counter 0
-Exec_Master_Log_Pos #
-Relay_Log_Space #
-Until_Condition None
-Until_Log_File
-Until_Log_Pos 0
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master #
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno #
-Last_IO_Error #
-Last_SQL_Errno 1364
-Last_SQL_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 447
-SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
-START SLAVE;
*** Create t10 on slave ***
STOP SLAVE;
RESET SLAVE;
=== modified file 'mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result 2010-01-13 09:00:03 +0000
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
DROP FUNCTION IF EXISTS test.f1;
DROP TABLE IF EXISTS test.t1;
CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=NDB;
=== added file 'mysql-test/suite/rpl_ndb/r/rpl_ndb_set_null.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_set_null.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_set_null.result 2010-01-21 17:20:24 +0000
@@ -0,0 +1,35 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 BIT, c2 INT) Engine=NDB;
+INSERT INTO `t1` VALUES ( 1, 1 );
+UPDATE t1 SET c1=NULL where c2=1;
+Comparing tables master:test.t1 and slave:test.t1
+DELETE FROM t1 WHERE c2=1 LIMIT 1;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 CHAR) Engine=NDB;
+INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ;
+SELECT * FROM t1;
+c1
+w
+UPDATE t1 SET c1=NULL WHERE c1='w';
+Comparing tables master:test.t1 and slave:test.t1
+DELETE FROM t1 LIMIT 2;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
=== added file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_set_null.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_set_null.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_set_null.test 2010-01-21 17:20:24 +0000
@@ -0,0 +1,6 @@
+-- source include/have_ndb.inc
+-- source include/have_binlog_format_mixed_or_row.inc
+-- source include/ndb_master-slave.inc
+
+-- let $engine= NDB
+-- source extra/rpl_tests/rpl_set_null.test
=== modified file 'mysql-test/t/alter_table.test'
--- a/mysql-test/t/alter_table.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/alter_table.test 2010-03-04 08:03:07 +0000
@@ -1088,4 +1088,16 @@ ALTER TABLE t1 CHANGE COLUMN f1 f1_no_re
--disable_info
DROP TABLE t1;
+
+--echo #
+--echo # Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux)
+--echo # or freezes (win) the server
+--echo #
+
+CREATE TABLE t1 (a TEXT, id INT, b INT);
+ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST;
+
+DROP TABLE t1;
+
+
--echo End of 5.1 tests
=== modified file 'mysql-test/t/archive.test'
--- a/mysql-test/t/archive.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/archive.test 2010-01-15 15:27:55 +0000
@@ -1625,3 +1625,24 @@ INSERT INTO t1 VALUES('aaaaaaaaaaaaaaaaa
SELECT COUNT(t1.a) FROM t1, t1 a, t1 b, t1 c, t1 d, t1 e;
DROP TABLE t1;
SET @@join_buffer_size= @save_join_buffer_size;
+
+#
+# BUG#47012 archive tables are not upgradeable, and server crashes on any access
+#
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+copy_file std_data/bug47012.frm $MYSQLD_DATADIR/test/t1.frm;
+copy_file std_data/bug47012.ARZ $MYSQLD_DATADIR/test/t1.ARZ;
+copy_file std_data/bug47012.ARM $MYSQLD_DATADIR/test/t1.ARM;
+
+--error ER_TABLE_NEEDS_UPGRADE
+SHOW CREATE TABLE t1;
+
+--error ER_TABLE_NEEDS_UPGRADE
+SELECT * FROM t1;
+
+--error ER_TABLE_NEEDS_UPGRADE
+INSERT INTO t1 (col1, col2) VALUES (1, "value");
+
+REPAIR TABLE t1;
+DROP TABLE t1;
+remove_file $MYSQLD_DATADIR/test/t1.ARM;
=== modified file 'mysql-test/t/bug46080.test'
--- a/mysql-test/t/bug46080.test 2009-09-03 06:38:06 +0000
+++ b/mysql-test/t/bug46080.test 2010-02-02 12:17:21 +0000
@@ -3,8 +3,8 @@
--echo # sort_buffer_size cannot allocate
--echo #
-call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'");
-call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k");
+call mtr.add_suppression("Out of memory at line .*, '.*my_alloc.c'");
+call mtr.add_suppression("needed .* byte (.*k)., memory in use: .* bytes (.*k)");
CREATE TABLE t1(a CHAR(255));
INSERT INTO t1 VALUES ('a');
=== added file 'mysql-test/t/bug47671-master.opt'
--- a/mysql-test/t/bug47671-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/bug47671-master.opt 2010-03-28 18:10:00 +0000
@@ -0,0 +1 @@
+--character-set-server=utf8 --skip-character-set-client-handshake
=== added file 'mysql-test/t/bug47671.test'
--- a/mysql-test/t/bug47671.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/bug47671.test 2009-11-30 05:24:26 +0000
@@ -0,0 +1,9 @@
+# Embedded server doesn't support external clients
+--source include/not_embedded.inc
+
+--echo #
+--echo # Bug#47671 - wrong character-set after upgrade from 5.1.34 to 5.1.39
+--echo #
+--echo # Extract only charset information from 'status' command output using regex
+--replace_regex /.*mysql.*// /Connection.*// /Current.*// /SSL.*// /Using.*// /Server version.*// /Protocol.*// /UNIX.*// /Uptime.*// /Threads.*// /TCP.*//
+--exec $MYSQL -e "status";
=== modified file 'mysql-test/t/count_distinct.test'
--- a/mysql-test/t/count_distinct.test 2005-07-28 14:09:54 +0000
+++ b/mysql-test/t/count_distinct.test 2009-12-22 09:52:23 +0000
@@ -35,6 +35,25 @@ insert into t1 values ('NYC Lib','New Yo
select t2.isbn,city,t1.libname,count(t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city,t1.libname;
select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct t1.libname) > 1;
select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct concat(t1.libname,'a')) > 1;
+
+select t2.isbn,city,@bar:=t1.libname,count(distinct t1.libname) as a
+ from t3 left join t1 on t3.libname=t1.libname left join t2
+ on t3.isbn=t2.isbn group by city having count(distinct
+ t1.libname) > 1;
+#
+# Wrong result, see bug#49872
+#
+SELECT @bar;
+
+select t2.isbn,city,concat(@bar:=t1.libname),count(distinct t1.libname) as a
+ from t3 left join t1 on t3.libname=t1.libname left join t2
+ on t3.isbn=t2.isbn group by city having count(distinct
+ t1.libname) > 1;
+#
+# Wrong result, see bug#49872
+#
+SELECT @bar;
+
drop table t1, t2, t3;
#
=== added file 'mysql-test/t/create-uca.test'
--- a/mysql-test/t/create-uca.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/create-uca.test 2009-12-27 13:54:41 +0000
@@ -0,0 +1,26 @@
+# Prerequisites
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
+
+# Initial cleanup
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+#
+# Bug#21380: DEFAULT definition not always transfered by CREATE
+# TABLE/SELECT to the new table.
+#
+
+CREATE TABLE t1(
+ c1 INT DEFAULT 12 COMMENT 'column1',
+ c2 INT NULL COMMENT 'column2',
+ c3 INT NOT NULL COMMENT 'column3',
+ c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
+ c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b',
+ c6 VARCHAR(255))
+ COLLATE latin1_bin;
+SHOW CREATE TABLE t1;
+CREATE TABLE t2 AS SELECT * FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t1,t2;
=== modified file 'mysql-test/t/create.test'
--- a/mysql-test/t/create.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/create.test 2010-03-04 08:03:07 +0000
@@ -721,16 +721,15 @@ drop table t1;
# Base vs temporary tables dillema (a.k.a. bug#24508 "Inconsistent
# results of CREATE TABLE ... SELECT when temporary table exists").
# In this situation we either have to create non-temporary table and
-# insert data in it or insert data in temporary table without creation
-# of permanent table. Since currently temporary tables always shadow
-# permanent tables we adopt second approach.
+# insert data in it or insert data in temporary table without creation of
+# permanent table. After patch for Bug#47418, we create the base table and
+# instert data into it, even though a temporary table exists with the same
+# name.
create temporary table t1 (j int);
create table if not exists t1 select 1;
select * from t1;
drop temporary table t1;
---error ER_NO_SUCH_TABLE
select * from t1;
---error ER_BAD_TABLE_ERROR
drop table t1;
@@ -1400,52 +1399,6 @@ drop table t1;
--echo
--echo # --
---echo # -- Bug#21380: DEFAULT definition not always transfered by CREATE
---echo # -- TABLE/SELECT to the new table.
---echo # --
---echo
-
-
---disable_warnings
-DROP TABLE IF EXISTS t1;
-DROP TABLE IF EXISTS t2;
---enable_warnings
-
---echo
-
-CREATE TABLE t1(
- c1 INT DEFAULT 12 COMMENT 'column1',
- c2 INT NULL COMMENT 'column2',
- c3 INT NOT NULL COMMENT 'column3',
- c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
- c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b',
- c6 VARCHAR(255))
- COLLATE latin1_bin;
-
---echo
-
-SHOW CREATE TABLE t1;
-
---echo
-
-CREATE TABLE t2 AS SELECT * FROM t1;
-
---echo
-
-SHOW CREATE TABLE t2;
-
---echo
-
-DROP TABLE t2;
-DROP TABLE t1;
-
---echo
---echo # -- End of test case for Bug#21380.
-
-###########################################################################
-
---echo
---echo # --
--echo # -- Bug#18834: ALTER TABLE ADD INDEX on table with two timestamp fields
--echo # --
--echo
=== modified file 'mysql-test/t/ctype_latin1_de-master.opt'
--- a/mysql-test/t/ctype_latin1_de-master.opt 2003-05-21 23:57:27 +0000
+++ b/mysql-test/t/ctype_latin1_de-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-character-set=latin1 --default-collation=latin1_german2_ci
+--character-set-server=latin1 --default-collation=latin1_german2_ci
=== modified file 'mysql-test/t/ctype_ucs.test'
--- a/mysql-test/t/ctype_ucs.test 2009-12-03 12:02:37 +0000
+++ b/mysql-test/t/ctype_ucs.test 2010-03-04 08:03:07 +0000
@@ -15,6 +15,16 @@ SET character_set_connection=ucs2;
SET CHARACTER SET koi8r;
#
+# BUG#49028, error in LIKE with ucs2
+#
+create table t1 (a varchar(2) character set ucs2 collate ucs2_bin, key(a));
+insert into t1 values ('A'),('A'),('B'),('C'),('D'),('A\t');
+insert into t1 values ('A\0'),('A\0'),('A\0'),('A\0'),('AZ');
+select hex(a) from t1 where a like 'A_' order by a;
+select hex(a) from t1 ignore key(a) where a like 'A_' order by a;
+drop table t1;
+
+#
# Check that 0x20 is only trimmed when it is
# a part of real SPACE character, not just a part
# of a multibyte sequence.
=== modified file 'mysql-test/t/ctype_ucs2_def-master.opt'
--- a/mysql-test/t/ctype_ucs2_def-master.opt 2007-02-19 11:04:38 +0000
+++ b/mysql-test/t/ctype_ucs2_def-master.opt 2010-03-28 18:10:00 +0000
@@ -1 +1 @@
---default-collation=ucs2_unicode_ci --default-character-set=ucs2,latin1
+--default-collation=ucs2_unicode_ci --character-set-server=ucs2,latin1
=== modified file 'mysql-test/t/ctype_utf8.test'
--- a/mysql-test/t/ctype_utf8.test 2009-01-26 21:19:13 +0000
+++ b/mysql-test/t/ctype_utf8.test 2010-03-04 08:03:07 +0000
@@ -2,6 +2,15 @@
# Tests with the utf8 character set
#
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+drop database if exists mysqltest;
+--enable_warnings
+
+
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
@@ -1440,6 +1449,16 @@ select hex(_utf8 B'001111111111');
--error ER_INVALID_CHARACTER_STRING
select (_utf8 X'616263FF');
+--echo #
+--echo # Bug#44131 Binary-mode "order by" returns records in incorrect order for UTF-8 strings
+--echo #
+CREATE TABLE t1 (id int not null primary key, name varchar(10)) character set utf8;
+INSERT INTO t1 VALUES
+(2,'一二三01'),(3,'一二三09'),(4,'一二三02'),(5,'一二三08'),
+(6,'一二三11'),(7,'一二三91'),(8,'一二三21'),(9,'一二三81');
+SELECT * FROM t1 ORDER BY BINARY(name);
+DROP TABLE t1;
+
#
# Bug #36772: When using UTF8, CONVERT with GROUP BY returns truncated results
#
=== modified file 'mysql-test/t/ddl_i18n_koi8r.test'
--- a/mysql-test/t/ddl_i18n_koi8r.test 2009-05-15 10:15:56 +0000
+++ b/mysql-test/t/ddl_i18n_koi8r.test 2009-12-27 13:54:41 +0000
@@ -36,6 +36,8 @@
--source include/have_cp866.inc
--source include/have_cp1251.inc
--source include/have_koi8r.inc
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
###########################################################################
=== modified file 'mysql-test/t/ddl_i18n_utf8.test'
--- a/mysql-test/t/ddl_i18n_utf8.test 2009-05-15 10:15:56 +0000
+++ b/mysql-test/t/ddl_i18n_utf8.test 2009-12-27 13:54:41 +0000
@@ -36,6 +36,8 @@
--source include/have_cp866.inc
--source include/have_cp1251.inc
--source include/have_koi8r.inc
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
###########################################################################
=== modified file 'mysql-test/t/delayed.test'
--- a/mysql-test/t/delayed.test 2009-03-11 15:32:42 +0000
+++ b/mysql-test/t/delayed.test 2010-01-15 15:27:55 +0000
@@ -341,4 +341,28 @@ drop table t1;
set global low_priority_updates = @old_delayed_updates;
+
+--echo #
+--echo # Bug #47682 strange behaviour of INSERT DELAYED
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (f1 integer);
+CREATE TABLE t2 (f1 integer);
+
+FLUSH TABLES WITH READ LOCK;
+LOCK TABLES t1 READ;
+
+# ER_CANT_UPDATE_WITH_READLOCK with normal execution
+# ER_TABLE_NOT_LOCKED when executed as prepared statement
+--error ER_CANT_UPDATE_WITH_READLOCK, ER_TABLE_NOT_LOCKED
+INSERT DELAYED INTO t2 VALUES (1);
+
+UNLOCK TABLES;
+DROP TABLE t1, t2;
+
+
--echo End of 5.1 tests
=== modified file 'mysql-test/t/delete.test'
--- a/mysql-test/t/delete.test 2009-09-28 10:48:52 +0000
+++ b/mysql-test/t/delete.test 2010-01-29 09:36:28 +0000
@@ -336,3 +336,42 @@ SELECT * FROM t2;
SELECT * FROM t3;
DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # Bug #46425 crash in Diagnostics_area::set_ok_status,
+--echo # empty statement, DELETE IGNORE
+--echo #
+
+CREATE table t1 (i INTEGER);
+
+INSERT INTO t1 VALUES (1);
+
+--delimiter |
+
+CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW
+BEGIN
+ INSERT INTO t1 SELECT * FROM t1 AS A;
+END |
+
+--delimiter ;
+--error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
+DELETE IGNORE FROM t1;
+
+DROP TABLE t1;
+
+
+--echo #
+--echo # Bug #49552 : sql_buffer_result cause crash + not found records
+--echo # in multitable delete/subquery
+--echo #
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+SET SESSION SQL_BUFFER_RESULT=1;
+DELETE t1 FROM (SELECT SUM(a) a FROM t1) x,t1;
+
+SET SESSION SQL_BUFFER_RESULT=DEFAULT;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo End of 5.1 tests
=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/disabled.def 2010-03-04 08:03:07 +0000
@@ -11,7 +11,3 @@
##############################################################################
kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
-partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
-partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
-innodb-autoinc : Bug#48482 2009-11-02 svoj innodb-autoinc.test fails with results difference
-rpl_killed_ddl : Bug#45520: rpl_killed_ddl fails sporadically in pb2
=== modified file 'mysql-test/t/foreign_key.test'
--- a/mysql-test/t/foreign_key.test 2005-07-28 00:22:47 +0000
+++ b/mysql-test/t/foreign_key.test 2010-03-10 13:39:02 +0000
@@ -2,8 +2,10 @@
# Test syntax of foreign keys
#
+-- source include/have_innodb.inc
+
--disable_warnings
-drop table if exists t1;
+drop table if exists t1,t2;
--enable_warnings
create table t1 (
@@ -23,3 +25,23 @@ create unique index b on t1 (a,b);
drop table t1;
# End of 4.1 tests
+
+#
+# Test DELETE IGNORE
+# Bug#44987 DELETE IGNORE and FK constraint
+#
+
+create table t1 (id int primary key) engine = innodb;
+create table t2 (id int PRIMARY KEY, FOREIGN KEY (id) REFERENCES t1(id)) engine=innodb;
+insert into t1 values (1), (2), (3), (4), (5), (6);
+insert into t2 values (3), (5);
+
+--error 1451
+delete from t1;
+select * from t1;
+
+delete ignore from t1;
+select row_count();
+select * from t1;
+drop table t2;
+drop table t1;
=== modified file 'mysql-test/t/fulltext.test'
--- a/mysql-test/t/fulltext.test 2009-09-07 20:50:10 +0000
+++ b/mysql-test/t/fulltext.test 2010-03-04 08:03:07 +0000
@@ -2,6 +2,9 @@
# Test of fulltext index
#
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
+
--disable_warnings
drop table if exists t1,t2,t3;
--enable_warnings
@@ -493,3 +496,75 @@ PREPARE s FROM
EXECUTE s;
DEALLOCATE PREPARE s;
DROP TABLE t1;
+
+
+--echo #
+--echo # Bug #49250 : spatial btree index corruption and crash
+--echo # Part two : fulltext syntax check
+--echo #
+
+--error ER_PARSE_ERROR
+CREATE TABLE t1(col1 TEXT,
+ FULLTEXT INDEX USING BTREE (col1));
+CREATE TABLE t2(col1 TEXT);
+--error ER_PARSE_ERROR
+CREATE FULLTEXT INDEX USING BTREE ON t2(col);
+--error ER_PARSE_ERROR
+ALTER TABLE t2 ADD FULLTEXT INDEX USING BTREE (col1);
+
+DROP TABLE t2;
+
+
+--echo End of 5.0 tests
+
+
+--echo #
+--echo # Bug #47930: MATCH IN BOOLEAN MODE returns too many results
+--echo # inside subquery
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+
+CREATE TABLE t2 (a int, b2 char(10), FULLTEXT KEY b2 (b2));
+INSERT INTO t2 VALUES (1,'Scargill');
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (1,1), (2,1);
+
+--echo # t2 should use full text index
+EXPLAIN
+SELECT count(*) FROM t1 WHERE
+ not exists(
+ SELECT 1 FROM t2, t3
+ WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE)
+ );
+
+--echo # should return 0
+SELECT count(*) FROM t1 WHERE
+ not exists(
+ SELECT 1 FROM t2, t3
+ WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE)
+ );
+
+--echo # should return 0
+SELECT count(*) FROM t1 WHERE
+ not exists(
+ SELECT 1 FROM t2 IGNORE INDEX (b2), t3
+ WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE)
+ );
+
+DROP TABLE t1,t2,t3;
+
+
+--echo #
+--echo # Bug #49445: Assertion failed: 0, file .\item_row.cc, line 55 with
+--echo # fulltext search and row op
+--echo #
+
+CREATE TABLE t1(a CHAR(1),FULLTEXT(a));
+SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1);
+DROP TABLE t1;
+
+
+--echo End of 5.1 tests
=== modified file 'mysql-test/t/fulltext2.test'
--- a/mysql-test/t/fulltext2.test 2009-10-28 07:52:34 +0000
+++ b/mysql-test/t/fulltext2.test 2009-12-27 13:54:41 +0000
@@ -2,6 +2,9 @@
# test of new fulltext search features
#
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
+
#
# two-level tree
#
=== modified file 'mysql-test/t/fulltext_order_by.test'
--- a/mysql-test/t/fulltext_order_by.test 2005-08-12 16:27:54 +0000
+++ b/mysql-test/t/fulltext_order_by.test 2009-12-22 15:52:15 +0000
@@ -80,7 +80,7 @@ CREATE TABLE t3 (
FULLTEXT KEY betreff (betreff)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=996 ;
---error 1054
+--error ER_CANT_USE_OPTION_HERE
select a.text, b.id, b.betreff
from
t2 a inner join t3 b on a.id = b.forum inner join
@@ -100,7 +100,7 @@ group by
order by
match(b.betreff) against ('+abc' in boolean mode) desc;
---error 1054
+--error ER_CANT_USE_OPTION_HERE
select a.text, b.id, b.betreff
from
t2 a inner join t3 b on a.id = b.forum inner join
@@ -117,6 +117,7 @@ where
order by
match(b.betreff) against ('+abc' in boolean mode) desc;
+--error ER_CANT_USE_OPTION_HERE
select a.text, b.id, b.betreff
from
t2 a inner join t3 b on a.id = b.forum inner join
=== modified file 'mysql-test/t/func_concat.test'
--- a/mysql-test/t/func_concat.test 2009-05-21 08:06:43 +0000
+++ b/mysql-test/t/func_concat.test 2010-01-13 04:16:36 +0000
@@ -4,6 +4,7 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
--enable_warnings
CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL );
@@ -111,4 +112,16 @@ EXPLAIN SELECT CONCAT('gui_', t2.a), t1.
DROP TABLE t1, t2;
+--echo #
+--echo # Bug #50096: CONCAT_WS inside procedure returning wrong data
+--echo #
+
+CREATE PROCEDURE p1(a varchar(255), b int, c int)
+ SET @query = CONCAT_WS(",", a, b, c);
+
+CALL p1("abcde", "0", "1234");
+SELECT @query;
+
+DROP PROCEDURE p1;
+
--echo # End of 5.1 tests
=== modified file 'mysql-test/t/func_group.test'
--- a/mysql-test/t/func_group.test 2009-10-14 08:46:50 +0000
+++ b/mysql-test/t/func_group.test 2009-11-24 15:26:13 +0000
@@ -1053,4 +1053,35 @@ ORDER BY max;
--echo #
DROP TABLE t1;
+--echo #
+--echo # Bug#43668: Wrong comparison and MIN/MAX for YEAR(2)
+--echo #
+create table t1 (f1 year(2), f2 year(4), f3 date, f4 datetime);
+insert into t1 values
+ (98,1998,19980101,"1998-01-01 00:00:00"),
+ (00,2000,20000101,"2000-01-01 00:00:01"),
+ (02,2002,20020101,"2002-01-01 23:59:59"),
+ (60,2060,20600101,"2060-01-01 11:11:11"),
+ (70,1970,19700101,"1970-11-11 22:22:22"),
+ (NULL,NULL,NULL,NULL);
+select min(f1),max(f1) from t1;
+select min(f2),max(f2) from t1;
+select min(f3),max(f3) from t1;
+select min(f4),max(f4) from t1;
+select a.f1 as a, b.f1 as b, a.f1 > b.f1 as gt,
+ a.f1 < b.f1 as lt, a.f1<=>b.f1 as eq
+from t1 a, t1 b;
+select a.f1 as a, b.f2 as b, a.f1 > b.f2 as gt,
+ a.f1 < b.f2 as lt, a.f1<=>b.f2 as eq
+from t1 a, t1 b;
+select a.f1 as a, b.f3 as b, a.f1 > b.f3 as gt,
+ a.f1 < b.f3 as lt, a.f1<=>b.f3 as eq
+from t1 a, t1 b;
+select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt,
+ a.f1 < b.f4 as lt, a.f1<=>b.f4 as eq
+from t1 a, t1 b;
+select *, f1 = f2 from t1;
+drop table t1;
+--echo #
--echo End of 5.1 tests
+
=== modified file 'mysql-test/t/func_if.test'
--- a/mysql-test/t/func_if.test 2008-12-12 13:16:25 +0000
+++ b/mysql-test/t/func_if.test 2010-02-23 12:06:41 +0000
@@ -5,6 +5,11 @@
drop table if exists t1;
--enable_warnings
+--disable_query_log
+# Set timezone to something specific, to make it possible to use unix_timestamp
+set time_zone="+03:00";
+--enable_query_log
+
#
# Simple IF tests
#
@@ -163,5 +168,9 @@ SELECT * FROM (SELECT MAX(IFNULL(CAST(c
DROP TABLE t1;
-
--echo End of 5.0 tests
+
+--disable_query_log
+# Restore timezone to default
+set time_zone= @@global.time_zone;
+--enable_query_log
=== modified file 'mysql-test/t/func_misc.test'
--- a/mysql-test/t/func_misc.test 2009-10-28 07:52:34 +0000
+++ b/mysql-test/t/func_misc.test 2010-01-11 13:15:28 +0000
@@ -103,198 +103,6 @@ show create table t1;
drop table t1;
#
-# Bug#6760: Add SLEEP() function (feature request)
-#
-# Logics of original test:
-# Reveal that a query with SLEEP does not need less time than estimated.
-#
-# Bug#12689: SLEEP() gets incorrectly cached/optimized-away
-#
-# Description from bug report (slightly modified)
-#
-# Bug 1 (happened all time):
-# SELECT * FROM t1 WHERE SLEEP(1) will only result in a sleep of 1
-# second, regardless of the number of rows in t1.
-# Bug 2 (happened all time):
-# Such a query will also get cached by the query cache, but should not.
-#
-# Notes (mleich, 2008-05)
-# =======================
-#
-# Experiments around
-# Bug#36345 Test 'func_misc' fails on RHAS3 x86_64
-# showed that the tests for both bugs could produce in case of parallel
-# artificial system time (like via ntpd)
-# - decreases false alarm
-# - increases false success
-#
-# We try here to circumvent these issues by reimplementation of the tests
-# and sophisticated scripting, although the cause of the problems is a massive
-# error within the setup of the testing environment.
-# Tests relying on or checking derivates of the system time must never meet
-# parallel manipulations of system time.
-#
-# Results of experiments with/without manipulation of system time,
-# information_schema.processlist content, high load on testing box
-# ----------------------------------------------------------------
-# Definition: Predicted_cumulative_sleep_time =
-# #_of_result_rows * sleep_time_per_result_row
-#
-# 1. Total (real sleep time) ~= predicted_cumulative_sleep_time !!
-# 2. The state of a session within the PROCESSLIST changes to 'User sleep'
-# if the sessions runs a statement containing the sleep function and the
-# processing of the statement is just within the phase where the sleep
-# is done. (*)
-# 3. NOW() and processlist.time behave "synchronous" to system time and
-# show also the "jumps" caused by system time manipulations. (*)
-# 4. processlist.time is unsigned, the "next" value below 0 is ~ 4G (*)
-# 5. Current processlist.time ~= current real sleep time if the system time
-# was not manipulated. (*)
-# 6. High system load can cause delays of <= 2 seconds.
-# 7. Thanks to Davi for excellent hints and ideas.
-#
-# (*)
-# - information_schema.processlist is not available before MySQL 5.1.
-# - Observation of processlist content requires a
-# - "worker" session sending the query with "send" and pulling results
-# with "reap"
-# - session observing the processlist parallel to the worker session
-# "send" and "reap" do not work in case of an embedded server.
-# Conclusion: Tests based on processlist have too many restrictions.
-#
-# Solutions for subtests based on TIMEDIFF of values filled via NOW()
-# -------------------------------------------------------------------
-# Run the following sequence three times
-# 1. SELECT <start_time>
-# 2. Query with SLEEP
-# 3. SELECT <end_time>
-# If TIMEDIFF(<end_time>,<start_time>) is at least two times within a
-# reasonable range assume that we did not met errors we were looking for.
-#
-# It is extreme unlikely that we have two system time changes within the
-# < 30 seconds runtime. Even if the unlikely happens, there are so
-# frequent runs of this test on this or another testing box which will
-# catch the problem.
-#
-
---echo #------------------------------------------------------------------------
---echo # Tests for Bug#6760 and Bug#12689
-# Number of rows within the intended result set.
-SET @row_count = 4;
-# Parameter within SLEEP function
-SET @sleep_time_per_result_row = 1;
-# Maximum acceptable delay caused by high load on testing box
-SET @max_acceptable_delay = 2;
-# TIMEDIFF = time for query with sleep (mostly the time caused by SLEEP)
-# + time for delays caused by high load on testing box
-# Ensure that at least a reasonable fraction of TIMEDIFF belongs to the SLEEP
-# by appropriate setting of variables.
-# Ensure that any "judging" has a base of minimum three attempts.
-# (Test 2 uses all attempts except the first one.)
-if (!` SELECT (@sleep_time_per_result_row * @row_count - @max_acceptable_delay >
- @sleep_time_per_result_row) AND (@row_count - 1 >= 3)`)
-{
- --echo # Have to abort because of error in plausibility check
- --echo ######################################################
- --vertical_results
- SELECT @sleep_time_per_result_row * @row_count - @max_acceptable_delay >
- @sleep_time_per_result_row AS must_be_1,
- @row_count - 1 >= 3 AS must_be_also_1,
- @sleep_time_per_result_row, @row_count, @max_acceptable_delay;
- exit;
-}
-SET @@global.query_cache_size = 1024 * 64;
---disable_warnings
-DROP TEMPORARY TABLE IF EXISTS t_history;
-DROP TABLE IF EXISTS t1;
---enable_warnings
-CREATE TEMPORARY TABLE t_history (attempt SMALLINT,
-start_ts DATETIME, end_ts DATETIME,
-start_cached INTEGER, end_cached INTEGER);
-CREATE TABLE t1 (f1 BIGINT);
-let $num = `SELECT @row_count`;
---disable_query_log
-begin;
-while ($num)
-{
- INSERT INTO t1 VALUES (1);
- dec $num;
-}
-commit;
---enable_query_log
-
-let $loops = 4;
-let $num = $loops;
-while ($num)
-{
- let $Qcache_queries_in_cache =
- query_get_value(SHOW STATUS LIKE 'Qcache_queries_in_cache', Value, 1);
- eval
- INSERT INTO t_history
- SET attempt = $loops - $num + 1, start_ts = NOW(),
- start_cached = $Qcache_queries_in_cache;
- SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
- #
- # Do not determine Qcache_queries_in_cache before updating end_ts. The SHOW
- # might cost too much time on an overloaded box.
- eval
- UPDATE t_history SET end_ts = NOW()
- WHERE attempt = $loops - $num + 1;
- let $Qcache_queries_in_cache =
- query_get_value(SHOW STATUS LIKE 'Qcache_queries_in_cache', Value, 1);
- eval
- UPDATE t_history SET end_cached = $Qcache_queries_in_cache
- WHERE attempt = $loops - $num + 1;
- # DEBUG eval SELECT * FROM t_history WHERE attempt = $loops - $num + 1;
- dec $num;
-}
-
-# 1. The majority of queries with SLEEP must need a reasonable time
-# -> SLEEP has an impact on runtime
-# = Replacement for original Bug#6760 test
-# -> total runtime is clear more needed than for one result row needed
-# = Replacement for one of the original Bug#12689 tests
---echo # Test 1: Does the query with SLEEP need a reasonable time?
-eval SELECT COUNT(*) >= $loops - 1 INTO @aux1 FROM t_history
-WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
- BETWEEN 0 AND @max_acceptable_delay;
-SELECT @aux1 AS "Expect 1";
-#
-# 2. The majority of queries (the first one must be ignored) with SLEEP must
-# need a reasonable time
-# -> If we assume that the result of a cached query will be sent back
-# immediate, without any sleep, than the query with SLEEP cannot be cached
-# (current and intended behaviour for queries with SLEEP).
-# -> It could be also not excluded that the query was cached but the server
-# honoured somehow the SLEEP. Such a behaviour would be also acceptable.
-# = Replacement for one of the original Bug#12689 tests
---echo # Test 2: Does the query with SLEEP need a reasonable time even in case
---echo # of the non first execution?
-eval SELECT COUNT(*) >= $loops - 1 - 1 INTO @aux2 FROM t_history
-WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
- BETWEEN 0 AND @max_acceptable_delay
- AND attempt > 1;
-SELECT @aux2 AS "Expect 1";
-#
-# 3. The query with SLEEP should be not cached.
-# -> SHOW STATUS Qcache_queries_in_cache must be not incremented after
-# the execution of the query with SLEEP
---echo # Test 3: The query with SLEEP must be not cached.
-eval SELECT COUNT(*) = $loops INTO @aux3 FROM t_history
-WHERE end_cached = start_cached;
-SELECT @aux3 AS "Expect 1";
-#
-# Dump the content of t_history if one of the tests failed.
-if (`SELECT @aux1 + @aux2 + @aux3 <> 3`)
-{
- --echo # Some tests failed, dumping the content of t_history
- SELECT * FROM t_history;
-}
-DROP TABLE t1;
-DROP TEMPORARY TABLE t_history;
-SET @@global.query_cache_size = default;
-
-#
# Bug #21466: INET_ATON() returns signed, not unsigned
#
=== modified file 'mysql-test/t/func_str.test'
--- a/mysql-test/t/func_str.test 2009-09-10 10:30:03 +0000
+++ b/mysql-test/t/func_str.test 2009-12-04 15:36:58 +0000
@@ -1318,3 +1318,37 @@ insert into t1 values (-1),(null);
explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a;
explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a;
drop table t1;
+
+--echo #
+--echo # Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (a VARCHAR(20), b INT);
+CREATE TABLE t2 (a VARCHAR(20), b INT);
+
+INSERT INTO t1 VALUES ('ABC', 1);
+INSERT INTO t2 VALUES ('ABC', 1);
+
+SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
+ FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
+
+SELECT DECODE((SELECT ENCODE('secret', 'ABC') FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a)
+ FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
+
+SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), 'ABC')
+ FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b;
+
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+
+INSERT INTO t1 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1);
+INSERT INTO t2 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1);
+
+SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a)
+ FROM t2 WHERE t2.b = 1 GROUP BY t2.b;
+
+DROP TABLE t1, t2;
=== modified file 'mysql-test/t/gis.test'
--- a/mysql-test/t/gis.test 2009-10-24 06:57:31 +0000
+++ b/mysql-test/t/gis.test 2010-01-13 10:28:42 +0000
@@ -670,6 +670,21 @@ SELECT 1 FROM t1 WHERE a <> (SELECT GEOM
DROP TABLE t1;
+--echo #
+--echo # Bug #49250 : spatial btree index corruption and crash
+--echo # Part one : spatial syntax check
+--echo #
+
+--error ER_PARSE_ERROR
+CREATE TABLE t1(col1 MULTIPOLYGON NOT NULL,
+ SPATIAL INDEX USING BTREE (col1));
+CREATE TABLE t2(col1 MULTIPOLYGON NOT NULL);
+--error ER_PARSE_ERROR
+CREATE SPATIAL INDEX USING BTREE ON t2(col);
+--error ER_PARSE_ERROR
+ALTER TABLE t2 ADD SPATIAL INDEX USING BTREE (col1);
+
+DROP TABLE t2;
--echo End of 5.0 tests
=== modified file 'mysql-test/t/grant.test'
--- a/mysql-test/t/grant.test 2009-06-15 15:53:45 +0000
+++ b/mysql-test/t/grant.test 2010-01-29 10:42:31 +0000
@@ -35,7 +35,7 @@ revoke delete on mysqltest.* from mysqlt
show grants for mysqltest_1@localhost;
grant select on mysqltest.* to mysqltest_1@localhost require NONE;
show grants for mysqltest_1@localhost;
-grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB";
+grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "Monty Program Ab";
show grants for mysqltest_1@localhost;
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
=== modified file 'mysql-test/t/grant2.test'
--- a/mysql-test/t/grant2.test 2009-02-27 08:03:47 +0000
+++ b/mysql-test/t/grant2.test 2009-10-30 05:06:10 +0000
@@ -632,5 +632,40 @@ DROP DATABASE db1;
--echo End of 5.0 tests
+#
+# Bug #48319: Server crashes on "GRANT/REVOKE ... TO CURRENT_USER"
+#
+
+# work out who we are.
+USE mysql;
+SELECT LEFT(CURRENT_USER(),INSTR(CURRENT_USER(),'@')-1) INTO @u;
+SELECT MID(CURRENT_USER(),INSTR(CURRENT_USER(),'@')+1) INTO @h;
+SELECT password FROM user WHERE user=@u AND host=@h INTO @pwd;
+
+# show current privs.
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+
+# toggle INSERT
+UPDATE user SET insert_priv='N' WHERE user=@u AND host=@h;
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+
+# show that GRANT ... TO CURRENT_USER() no longer crashes
+GRANT INSERT ON *.* TO CURRENT_USER();
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+UPDATE user SET insert_priv='N' WHERE user=@u AND host=@h;
+
+# show that GRANT ... TO CURRENT_USER() IDENTIFIED BY ... works now
+GRANT INSERT ON *.* TO CURRENT_USER() IDENTIFIED BY 'keksdose';
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+
+UPDATE user SET password=@pwd WHERE user=@u AND host=@h;
+SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
+
+FLUSH PRIVILEGES;
+
+USE test;
+
+--echo End of 5.1 tests
+
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
=== modified file 'mysql-test/t/group_min_max.test'
--- a/mysql-test/t/group_min_max.test 2009-08-30 07:03:37 +0000
+++ b/mysql-test/t/group_min_max.test 2009-11-23 10:04:17 +0000
@@ -1016,6 +1016,18 @@ SELECT a, MAX(b) FROM t WHERE b > 0 AND
DROP TABLE t;
+--echo #
+--echo # Bug #48472: Loose index scan inappropriately chosen for some WHERE
+--echo # conditions
+--echo #
+
+CREATE TABLE t (a INT, b INT, INDEX (a,b));
+INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1);
+INSERT INTO t SELECT * FROM t;
+
+SELECT a, MAX(b) FROM t WHERE 0=b+0 GROUP BY a;
+
+DROP TABLE t;
--echo End of 5.0 tests
=== modified file 'mysql-test/t/information_schema.test'
--- a/mysql-test/t/information_schema.test 2009-11-30 13:36:06 +0000
+++ b/mysql-test/t/information_schema.test 2010-03-10 09:12:23 +0000
@@ -1114,7 +1114,7 @@ eval SET @tid=$ID;
--enable_query_log
SELECT IF(`time` > 0, 'OK', `time`) AS time_low,
IF(`time` < 1000, 'OK', `time`) AS time_high,
- IF(time_ms > 1500, 'OK', time_ms) AS time_ms_low,
+ IF(time_ms >= 1000, 'OK', time_ms) AS time_ms_low,
IF(time_ms < 1000000, 'OK', time_ms) AS time_ms_high
FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID=@tid;
@@ -1386,6 +1386,33 @@ SET TIMESTAMP=@@TIMESTAMP + 10000000;
SELECT 'NOT_OK' AS TEST_RESULT FROM INFORMATION_SCHEMA.PROCESSLIST WHERE time < 0;
SET TIMESTAMP=DEFAULT;
+
+--echo #
+--echo # Bug #50276: Security flaw in INFORMATION_SCHEMA.TABLES
+--echo #
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE t1 (id INT);
+CREATE USER nonpriv;
+USE test;
+
+connect (nonpriv_con, localhost, nonpriv,,);
+connection nonpriv_con;
+--echo # connected as nonpriv
+--echo # Should return 0
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1';
+USE INFORMATION_SCHEMA;
+--echo # Should return 0
+SELECT COUNT(*) FROM TABLES WHERE TABLE_NAME='t1';
+
+connection default;
+--echo # connected as root
+disconnect nonpriv_con;
+DROP USER nonpriv;
+DROP TABLE db1.t1;
+DROP DATABASE db1;
+
+
--echo End of 5.1 tests.
# Wait till all disconnects are completed
=== modified file 'mysql-test/t/innodb-analyze.test'
--- a/mysql-test/t/innodb-analyze.test 2009-11-13 21:26:08 +0000
+++ b/mysql-test/t/innodb-analyze.test 2010-01-15 15:58:25 +0000
@@ -11,7 +11,7 @@
-- disable_result_log
-- enable_warnings
-SET @old_innodb_stats_sample_pages=@@innodb_stats_sample_pages;
+let $sample_pages=`select @@innodb_stats_sample_pages`;
SET GLOBAL innodb_stats_sample_pages=0;
# check that the value has been adjusted to 1
@@ -62,4 +62,4 @@ SET GLOBAL innodb_stats_sample_pages=16;
ANALYZE TABLE innodb_analyze;
DROP TABLE innodb_analyze;
-SET GLOBAL innodb_stats_sample_pages=@old_innodb_stats_sample_pages;
+EVAL SET GLOBAL innodb_stats_sample_pages=$sample_pages;
=== added file 'mysql-test/t/innodb-autoinc-44030.test'
--- a/mysql-test/t/innodb-autoinc-44030.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb-autoinc-44030.test 2010-03-04 08:03:07 +0000
@@ -0,0 +1,40 @@
+-- source include/have_innodb.inc
+# embedded server ignores 'delayed', so skip this
+-- source include/not_embedded.inc
+
+let $file_format_check=`select @@innodb_file_format_check`;
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+#
+# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from
+# the index (PRIMARY)
+# This test requires a restart of the server
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (null);
+INSERT INTO t1 VALUES (null);
+ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
+SELECT * FROM t1;
+# Restart the server
+-- source include/restart_mysqld.inc
+# The MySQL and InnoDB data dictionaries should now be out of sync.
+# The select should print message to the error log
+SELECT * FROM t1;
+# MySQL have made a change (http://lists.mysql.com/commits/75268) that no
+# longer results in the two data dictionaries being out of sync. If they
+# revert their changes then this check for ER_AUTOINC_READ_FAILED will need
+# to be enabled. Also, see http://bugs.mysql.com/bug.php?id=47621.
+-- error ER_AUTOINC_READ_FAILED,1467
+INSERT INTO t1 VALUES(null);
+ALTER TABLE t1 AUTO_INCREMENT = 3;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES(null);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--disable_query_log
+EVAL SET GLOBAL innodb_file_format_check=$file_format_check;
+--enable_query_log
=== modified file 'mysql-test/t/innodb-autoinc.test'
--- a/mysql-test/t/innodb-autoinc.test 2009-12-03 11:34:11 +0000
+++ b/mysql-test/t/innodb-autoinc.test 2010-03-04 08:03:07 +0000
@@ -2,6 +2,8 @@
# embedded server ignores 'delayed', so skip this
-- source include/not_embedded.inc
+let $file_format_check=`select @@innodb_file_format_check`;
+
--disable_warnings
drop table if exists t1;
--enable_warnings
@@ -156,7 +158,7 @@ DROP TABLE t1;
#
# Test changes to AUTOINC next value calculation
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL),(5),(NULL);
@@ -173,7 +175,7 @@ DROP TABLE t1;
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(0);
@@ -193,13 +195,13 @@ DROP TABLE t1;
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
INSERT INTO t1 VALUES (-2), (NULL),(2),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
@@ -214,13 +216,13 @@ DROP TABLE t1;
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
INSERT INTO t1 VALUES (-2);
INSERT INTO t1 VALUES (NULL);
INSERT INTO t1 VALUES (2);
@@ -240,13 +242,13 @@ DROP TABLE t1;
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
INSERT INTO t1 VALUES (-2),(NULL),(2),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
@@ -262,7 +264,7 @@ DROP TABLE t1;
# Check for overflow handling when increment is > 1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -271,7 +273,7 @@ INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (9223372036854775794); #-- 2^63 - 14
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
# This should just fit
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
SELECT * FROM t1;
@@ -281,7 +283,7 @@ DROP TABLE t1;
# Check for overflow handling when increment and offser are > 1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -290,7 +292,7 @@ INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551603); #-- 2^64 - 13
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
# This should fail because of overflow but it doesn't, it seems to be
# a MySQL server bug. It wraps around to 0 for the last value.
# See MySQL Bug# 39828
@@ -313,7 +315,7 @@ DROP TABLE t1;
# Check for overflow handling when increment and offset are odd numbers
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -322,7 +324,7 @@ INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551603); #-- 2^64 - 13
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
# This should fail because of overflow but it doesn't. It fails with
# a duplicate entry message because of a MySQL server bug, it wraps
# around. See MySQL Bug# 39828, once MySQL fix the bug we can replace
@@ -344,7 +346,7 @@ DROP TABLE t1;
# and check for large -ve numbers
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -355,7 +357,7 @@ INSERT INTO t1 VALUES(-92233720368547758
INSERT INTO t1 VALUES(-9223372036854775808); #-- -2^63
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=3, @@SESSION.AUTO_INCREMENT_OFFSET=3;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
SELECT * FROM t1;
DROP TABLE t1;
@@ -364,7 +366,7 @@ DROP TABLE t1;
# large numbers 2^60
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -373,7 +375,7 @@ INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551610); #-- 2^64 - 2
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
# This should fail because of overflow but it doesn't. It wraps around
# and the autoinc values look bogus too.
# See MySQL Bug# 39828, once MySQL fix the bug we can enable the error
@@ -396,7 +398,7 @@ DROP TABLE t1;
#
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
CREATE TABLE t1 (c1 DOUBLE NOT NULL AUTO_INCREMENT, c2 INT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(NULL, 1);
INSERT INTO t1 VALUES(NULL, 2);
@@ -478,37 +480,11 @@ INSERT INTO t2 SELECT c1 FROM t1;
INSERT INTO t2 SELECT NULL FROM t1;
DROP TABLE t1;
DROP TABLE t2;
-#
-# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from
-# the index (PRIMARY)
-# This test requires a restart of the server
-SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
-CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (null);
-INSERT INTO t1 VALUES (null);
-ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
-SELECT * FROM t1;
-# Restart the server
--- source include/restart_mysqld.inc
-# The MySQL and InnoDB data dictionaries should now be out of sync.
-# The select should print message to the error log
-SELECT * FROM t1;
-# MySQL have made a change (http://lists.mysql.com/commits/75268) that no
-# longer results in the two data dictionaries being out of sync. If they
-# revert their changes then this check for ER_AUTOINC_READ_FAILED will need
-# to be enabled.
--- error ER_AUTOINC_READ_FAILED,1467
-INSERT INTO t1 VALUES(null);
-ALTER TABLE t1 AUTO_INCREMENT = 3;
-SHOW CREATE TABLE t1;
-INSERT INTO t1 VALUES(null);
-SELECT * FROM t1;
-DROP TABLE t1;
# If the user has specified negative values for an AUTOINC column then
# InnoDB should ignore those values when setting the table's max value.
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
-SHOW VARIABLES LIKE "%auto_inc%";
+SHOW VARIABLES LIKE "auto_inc%";
# TINYINT
CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, NULL);
@@ -614,9 +590,48 @@ DROP TABLE t1;
# 47125: auto_increment start value is ignored if an index is created
# and engine=innodb
#
-CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
-CREATE INDEX i1 on T1(c2);
-SHOW CREATE TABLE T1;
-INSERT INTO T1 (c2) values (0);
-SELECT * FROM T1;
-DROP TABLE T1;
+CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
+CREATE INDEX i1 on t1(c2);
+SHOW CREATE TABLE t1;
+INSERT INTO t1 (c2) values (0);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+##
+# 49032: Use the correct function to read the AUTOINC column value
+#
+CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb');
+# Restart the server
+-- source include/restart_mysqld.inc
+INSERT INTO t1(C2) VALUES ('innodb');
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+CREATE TABLE t1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb');
+# Restart the server
+-- source include/restart_mysqld.inc
+INSERT INTO t1(C2) VALUES ('innodb');
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+##
+# 47720: REPLACE INTO Autoincrement column with negative values
+#
+CREATE TABLE t1 (c1 INT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 SET c1 = 1;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 SET c1 = 2;
+INSERT INTO t1 SET c1 = -1;
+SELECT * FROM t1;
+-- error ER_DUP_ENTRY,1062
+INSERT INTO t1 SET c1 = -1;
+SHOW CREATE TABLE t1;
+REPLACE INTO t1 VALUES (-1);
+SELECT * FROM t1;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--disable_query_log
+EVAL SET GLOBAL innodb_file_format_check=$file_format_check;
+--enable_query_log
=== added file 'mysql-test/t/innodb-consistent-master.opt'
--- a/mysql-test/t/innodb-consistent-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb-consistent-master.opt 2010-01-15 15:58:25 +0000
@@ -0,0 +1 @@
+--loose-innodb_lock_wait_timeout=2
=== added file 'mysql-test/t/innodb-consistent.test'
--- a/mysql-test/t/innodb-consistent.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb-consistent.test 2010-01-15 15:58:25 +0000
@@ -0,0 +1,58 @@
+-- source include/not_embedded.inc
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+# REPLACE INTO ... SELECT and INSERT INTO ... SELECT should do
+# a consistent read of the source table.
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+
+# REPLACE INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+replace into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+# INSERT INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+insert into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+select * from t1;
+drop table t1;
+drop table t2;
+
+connection default;
+disconnect a;
+disconnect b;
=== modified file 'mysql-test/t/innodb-index.test'
--- a/mysql-test/t/innodb-index.test 2009-11-30 21:37:27 +0000
+++ b/mysql-test/t/innodb-index.test 2010-01-15 15:58:25 +0000
@@ -1,6 +1,6 @@
-- source include/have_innodb.inc
-SET @save_innodb_file_format_check=@@global.innodb_file_format_check;
+let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb;
insert into t1 values (5,5,'oo','oo'),(4,4,'tr','tr'),(3,4,'ad','ad'),(2,3,'ak','ak');
@@ -404,6 +404,7 @@ create index t1u on t1 (u(1));
drop table t1;
eval set global innodb_file_per_table=$per_table;
eval set global innodb_file_format=$format;
+eval set global innodb_file_format_check=$format;
#
# Test to check whether CREATE INDEX handles implicit foreign key
@@ -541,4 +542,9 @@ disconnect b;
DROP TABLE t1;
-SET GLOBAL innodb_file_format_check=@save_innodb_file_format_check;
+#
+# restore environment to the state it was before this test execution
+#
+
+-- disable_query_log
+eval SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig;
=== modified file 'mysql-test/t/innodb-master.opt'
--- a/mysql-test/t/innodb-master.opt 2009-06-09 13:19:13 +0000
+++ b/mysql-test/t/innodb-master.opt 2010-01-15 15:58:25 +0000
@@ -1 +1 @@
---binlog_cache_size=32768 --innodb_lock_wait_timeout=1
+--binlog_cache_size=32768 --loose_innodb_lock_wait_timeout=1
=== modified file 'mysql-test/t/innodb-semi-consistent-master.opt'
--- a/mysql-test/t/innodb-semi-consistent-master.opt 2009-06-09 13:19:13 +0000
+++ b/mysql-test/t/innodb-semi-consistent-master.opt 2010-01-15 15:58:25 +0000
@@ -1 +1 @@
---innodb_lock_wait_timeout=2
+--loose-innodb_lock_wait_timeout=2
=== modified file 'mysql-test/t/innodb-timeout.test'
--- a/mysql-test/t/innodb-timeout.test 2009-06-09 13:19:13 +0000
+++ b/mysql-test/t/innodb-timeout.test 2010-01-18 12:56:10 +0000
@@ -30,6 +30,7 @@ begin;
insert into t1 values(1),(2),(3);
connection b;
+set innodb_lock_wait_timeout=5;
--send
select * from t1 for update;
@@ -44,16 +45,20 @@ begin;
insert into t1 values(4);
connection b;
---send
+# Test that we get a lock timeout.
+# We cannot reliably test that the timeout is exactly 1 seconds due to
+# process scheduling differences on the host running the test suite. But we
+# can test that we are within reasonable range.
+set innodb_lock_wait_timeout=2;
+set @a= current_timestamp();
+--error ER_LOCK_WAIT_TIMEOUT
select * from t1 for update;
+set @b= current_timestamp();
+set @c= timestampdiff(SECOND, @a, @b);
+select if(@c >= 1 and @c <= 10, 'OK', concat("NOT OK, time passed=", @c));
connection a;
-sleep 2;
commit;
-
-connection b;
---error ER_LOCK_WAIT_TIMEOUT
-reap;
drop table t1;
connection default;
=== modified file 'mysql-test/t/innodb-use-sys-malloc-master.opt'
--- a/mysql-test/t/innodb-use-sys-malloc-master.opt 2009-06-09 13:19:13 +0000
+++ b/mysql-test/t/innodb-use-sys-malloc-master.opt 2010-01-15 15:58:25 +0000
@@ -1,2 +1 @@
---innodb-use-sys-malloc=true
---innodb-use-sys-malloc=true
+--loose-innodb-use-sys-malloc=true
=== modified file 'mysql-test/t/innodb-zip.test'
--- a/mysql-test/t/innodb-zip.test 2009-06-09 15:08:46 +0000
+++ b/mysql-test/t/innodb-zip.test 2010-01-15 15:58:25 +0000
@@ -178,11 +178,11 @@ set innodb_strict_mode = on;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 0;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb key_block_size = 9;
-show errors;
+show warnings;
create table t3 (id int primary key) engine = innodb key_block_size = 1;
@@ -208,22 +208,22 @@ key_block_size = 8 row_format = compress
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb
key_block_size = 8 row_format = redundant;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t3 (id int primary key) engine = innodb
key_block_size = 8 row_format = compact;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t4 (id int primary key) engine = innodb
key_block_size = 8 row_format = dynamic;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t5 (id int primary key) engine = innodb
key_block_size = 8 row_format = default;
-show errors;
+show warnings;
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -233,17 +233,17 @@ drop table t1;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb
key_block_size = 9 row_format = redundant;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = compact;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = dynamic;
-show errors;
+show warnings;
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -253,25 +253,25 @@ set global innodb_file_per_table = off;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 1;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb key_block_size = 2;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t3 (id int primary key) engine = innodb key_block_size = 4;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t4 (id int primary key) engine = innodb key_block_size = 8;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t5 (id int primary key) engine = innodb key_block_size = 16;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t6 (id int primary key) engine = innodb row_format = compressed;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t7 (id int primary key) engine = innodb row_format = dynamic;
-show errors;
+show warnings;
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
@@ -285,25 +285,25 @@ set global innodb_file_format = `0`;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 1;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb key_block_size = 2;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t3 (id int primary key) engine = innodb key_block_size = 4;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t4 (id int primary key) engine = innodb key_block_size = 8;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t5 (id int primary key) engine = innodb key_block_size = 16;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t6 (id int primary key) engine = innodb row_format = compressed;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t7 (id int primary key) engine = innodb row_format = dynamic;
-show errors;
+show warnings;
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
=== modified file 'mysql-test/t/innodb.test'
--- a/mysql-test/t/innodb.test 2009-11-13 21:26:08 +0000
+++ b/mysql-test/t/innodb.test 2010-01-15 15:58:25 +0000
@@ -2270,7 +2270,7 @@ disconnect j;
drop table t1, t2, t3, t5, t6, t8, t9;
# bug 18934, "InnoDB crashes when table uses column names like DB_ROW_ID"
---error 1005
+--error ER_WRONG_COLUMN_NAME
CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
#
@@ -2353,18 +2353,6 @@ DELETE FROM t1;
DROP TABLE t2,t1;
#
-# Bug #26835: table corruption after delete+insert
-#
-
-CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY)
-ENGINE=InnoDB;
-INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4);
-DELETE FROM t1;
-INSERT INTO t1 VALUES ('DDD');
-SELECT * FROM t1;
-DROP TABLE t1;
-
-#
# Bug #23313 (AUTO_INCREMENT=# not reported back for InnoDB tables)
# Bug #21404 (AUTO_INCREMENT value reset when Adding FKEY (or ALTER?))
#
=== modified file 'mysql-test/t/innodb_bug34300.test'
--- a/mysql-test/t/innodb_bug34300.test 2009-11-13 21:26:08 +0000
+++ b/mysql-test/t/innodb_bug34300.test 2010-01-15 15:58:25 +0000
@@ -9,7 +9,7 @@
-- disable_result_log
# set packet size and reconnect
-SET @save_max_allowed_packet=@@global.max_allowed_packet;
+let $max_packet=`select @@global.max_allowed_packet`;
SET @@global.max_allowed_packet=16777216;
--connect (newconn, localhost, root,,)
@@ -33,4 +33,4 @@ SELECT f4, f8 FROM bug34300;
DROP TABLE bug34300;
disconnect newconn;
connection default;
-SET @@global.max_allowed_packet=@save_max_allowed_packet;
+EVAL SET @@global.max_allowed_packet=$max_packet;
=== modified file 'mysql-test/t/innodb_bug36169.test'
--- a/mysql-test/t/innodb_bug36169.test 2009-11-13 21:26:08 +0000
+++ b/mysql-test/t/innodb_bug36169.test 2010-01-15 15:58:25 +0000
@@ -4,9 +4,9 @@
#
-- source include/have_innodb.inc
-set @old_innodb_file_format=@@innodb_file_format;
-set @old_innodb_file_per_table=@@innodb_file_per_table;
+let $file_format=`select @@innodb_file_format`;
+let $file_per_table=`select @@innodb_file_per_table`;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
@@ -1155,5 +1155,5 @@ DROP TABLE IF EXISTS table4;
DROP TABLE IF EXISTS table5;
DROP TABLE IF EXISTS table6;
-set global innodb_file_format=@old_innodb_file_format;
-set global innodb_file_per_table=@old_innodb_file_per_table;
+EVAL SET GLOBAL innodb_file_format=$file_format;
+EVAL SET GLOBAL innodb_file_per_table=$file_per_table;
=== modified file 'mysql-test/t/innodb_bug36172.test'
--- a/mysql-test/t/innodb_bug36172.test 2009-11-13 21:26:08 +0000
+++ b/mysql-test/t/innodb_bug36172.test 2010-01-15 15:58:25 +0000
@@ -13,9 +13,10 @@ SET storage_engine=InnoDB;
-- disable_query_log
-- disable_result_log
-set @old_innodb_file_per_table=@@innodb_file_per_table;
-set @old_innodb_file_format=@@innodb_file_format;
+let $file_format=`select @@innodb_file_format`;
+let $file_format_check=`select @@innodb_file_format_check`;
+let $file_per_table=`select @@innodb_file_per_table`;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=on;
@@ -27,6 +28,6 @@ INSERT IGNORE INTO `table0` SET `col19`
CHECK TABLE table0 EXTENDED;
DROP TABLE table0;
-set global innodb_file_per_table=@old_innodb_file_per_table;
-set global innodb_file_format=@old_innodb_file_format;
-set global innodb_file_format_check=Antelope;
+EVAL SET GLOBAL innodb_file_format=$file_format;
+EVAL SET GLOBAL innodb_file_format_check=$file_format_check;
+EVAL SET GLOBAL innodb_file_per_table=$file_per_table;
=== modified file 'mysql-test/t/innodb_bug42101-nonzero-master.opt'
--- a/mysql-test/t/innodb_bug42101-nonzero-master.opt 2009-05-19 08:20:28 +0000
+++ b/mysql-test/t/innodb_bug42101-nonzero-master.opt 2010-01-15 15:58:25 +0000
@@ -1 +1 @@
---innodb_commit_concurrency=1
+--loose_innodb_commit_concurrency=1
=== modified file 'mysql-test/t/innodb_bug44369.test'
--- a/mysql-test/t/innodb_bug44369.test 2009-11-02 14:59:44 +0000
+++ b/mysql-test/t/innodb_bug44369.test 2010-01-15 15:58:25 +0000
@@ -6,16 +6,12 @@
--source include/have_innodb.inc
# This create table operation should fail.
---error ER_CANT_CREATE_TABLE
+--error ER_WRONG_COLUMN_NAME
create table bug44369 (DB_ROW_ID int) engine=innodb;
# This create should fail as well
---error ER_CANT_CREATE_TABLE
+--error ER_WRONG_COLUMN_NAME
create table bug44369 (db_row_id int) engine=innodb;
-show warnings;
-
---error ER_CANT_CREATE_TABLE
+--error ER_WRONG_COLUMN_NAME
create table bug44369 (db_TRX_Id int) engine=innodb;
-
-show warnings;
=== added file 'mysql-test/t/innodb_bug44571.test'
--- a/mysql-test/t/innodb_bug44571.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb_bug44571.test 2010-01-15 15:58:25 +0000
@@ -0,0 +1,13 @@
+#
+# Bug#44571 InnoDB Plugin crashes on ADD INDEX
+# http://bugs.mysql.com/44571
+#
+-- source include/have_innodb.inc
+
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+-- error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+CREATE INDEX bug44571c ON bug44571 (bar);
+DROP TABLE bug44571;
=== added file 'mysql-test/t/innodb_bug46676.test'
--- a/mysql-test/t/innodb_bug46676.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb_bug46676.test 2010-01-15 15:58:25 +0000
@@ -0,0 +1,16 @@
+# This is the test for bug 46676: mysqld got exception 0xc0000005
+# It is reproducible with InnoDB plugin 1.0.4 + MySQL 5.1.37.
+# But no longer reproducible after MySQL 5.1.38 (with plugin 1.0.5).
+
+--source include/have_innodb.inc
+
+SET foreign_key_checks=0;
+CREATE TABLE t1 (id int, foreign key (id) references t2(id)) ENGINE=INNODB;
+CREATE TABLE t2 (id int, foreign key (id) references t1(id)) ENGINE=INNODB;
+SET foreign_key_checks=1;
+
+# Server crashes
+SELECT COUNT(*) FROM information_schema.key_column_usage WHERE REFERENCED_TABLE_NAME in ('t1', 't2');
+
+SET foreign_key_checks=0;
+DROP TABLE t1, t2;
=== added file 'mysql-test/t/innodb_bug47167.test'
--- a/mysql-test/t/innodb_bug47167.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb_bug47167.test 2010-01-15 15:58:25 +0000
@@ -0,0 +1,45 @@
+# This is the unit test for bug *47167.
+# It tests setting the global variable
+# "innodb_file_format_check" with a
+# user-Defined Variable.
+
+--source include/have_innodb.inc
+
+# Save the value (Antelope) in 'innodb_file_format_check' to
+# 'old_innodb_file_format_check'
+set @old_innodb_file_format_check=@@innodb_file_format_check;
+
+# @old_innodb_file_format_check shall have the value of 'Antelope'
+select @old_innodb_file_format_check;
+
+# Reset the value in 'innodb_file_format_check' to 'Barracuda'
+set global innodb_file_format_check = Barracuda;
+
+select @@innodb_file_format_check;
+
+# Set 'innodb_file_format_check' to its default value, which
+# is the latest file format supported in the current release.
+set global innodb_file_format_check = DEFAULT;
+
+select @@innodb_file_format_check;
+
+# Put the saved value back to 'innodb_file_format_check'
+set global innodb_file_format_check = @old_innodb_file_format_check;
+
+# Check whether 'innodb_file_format_check' get its original value.
+select @@innodb_file_format_check;
+
+# Following are negative tests, all should fail.
+--disable_warnings
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check = cheetah;
+
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check = Bear;
+
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check = on;
+
+--error ER_WRONG_ARGUMENTS
+set global innodb_file_format_check = off;
+--enable_warnings
=== modified file 'mysql-test/t/innodb_file_format.test'
--- a/mysql-test/t/innodb_file_format.test 2009-11-30 21:37:27 +0000
+++ b/mysql-test/t/innodb_file_format.test 2010-01-15 15:58:25 +0000
@@ -1,5 +1,4 @@
-- source include/have_innodb.inc
-set @old_innodb_file_format=@@innodb_file_format;
call mtr.add_suppression("InnoDB: invalid innodb_file_format_check value");
@@ -29,6 +28,4 @@ set global innodb_file_format=on;
--error ER_WRONG_ARGUMENTS
set global innodb_file_format=off;
select @@innodb_file_format_check;
-
-set global innodb_file_format=@old_innodb_file_format;
-set global innodb_file_format_check=Antelope;
+set global innodb_file_format_check=antelope;
=== modified file 'mysql-test/t/innodb_information_schema.test'
--- a/mysql-test/t/innodb_information_schema.test 2009-06-23 12:00:24 +0000
+++ b/mysql-test/t/innodb_information_schema.test 2010-01-15 15:58:25 +0000
@@ -109,19 +109,18 @@ SELECT * FROM ```t'\"_str` WHERE c1 = '3
-- send
SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE;
+-- enable_result_log
-- connection con_verify_innodb_locks
-
-# Loop, giving time for the above 2 queries to execute before continuing.
-# Without this, it sometimes happens that the SELECT FROM innodb_locks
+# Wait for the above queries to execute before continuing.
+# Without this, it sometimes happens that the SELECT from innodb_locks
# executes before some of them, resulting in less than expected number
-# of rows being selected from innodb_locks.
-SET @counter := 0;
-while (`SELECT (@counter := @counter + 1) <= 50 AND COUNT(*) != 14 FROM INFORMATION_SCHEMA.INNODB_LOCKS`)
-{
- sleep 0.1;
-}
-
--- enable_result_log
+# of rows being selected from innodb_locks. If there is a bug and there
+# are no 14 rows in innodb_locks then this test will fail with timeout.
+let $count = 14;
+let $table = INFORMATION_SCHEMA.INNODB_LOCKS;
+-- source include/wait_until_rows_count.inc
+# the above enables the query log, re-disable it
+-- disable_query_log
SELECT lock_mode, lock_type, lock_table, lock_index, lock_rec, lock_data
FROM INFORMATION_SCHEMA.INNODB_LOCKS ORDER BY lock_data;
=== modified file 'mysql-test/t/innodb_lock_wait_timeout_1.test'
--- a/mysql-test/t/innodb_lock_wait_timeout_1.test 2009-11-03 17:45:52 +0000
+++ b/mysql-test/t/innodb_lock_wait_timeout_1.test 2009-11-12 11:43:33 +0000
@@ -71,6 +71,40 @@ set autocommit=default;
drop table t1;
--echo #
+--echo # Bug #37183 insert ignore into .. select ... hangs
+--echo # after deadlock was encountered
+--echo #
+connect (con1,localhost,root,,);
+create table t1(id int primary key,v int)engine=innodb;
+insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
+create table t2 like t1;
+
+--connection con1
+begin;
+update t1 set v=id*2 where id=1;
+
+--connection default
+begin;
+update t1 set v=id*2 where id=2;
+
+--connection con1
+--error 1205
+update t1 set v=id*2 where id=2;
+
+--connection default
+--error 1205
+insert ignore into t2 select * from t1 where id=1;
+rollback;
+
+--connection con1
+rollback;
+
+--connection default
+disconnect con1;
+drop table t1, t2;
+
+
+--echo #
--echo # Bug#41756 Strange error messages about locks from InnoDB
--echo #
--disable_warnings
=== modified file 'mysql-test/t/innodb_mysql.test'
--- a/mysql-test/t/innodb_mysql.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/innodb_mysql.test 2010-01-15 15:27:55 +0000
@@ -491,5 +491,51 @@ EXPLAIN SELECT * FROM t1 WHERE a = 'TEST
c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
DROP TABLE t1;
+--echo #
+--echo # Bug #46175: NULL read_view and consistent read assertion
+--echo #
+
+CREATE TABLE t1(a CHAR(13),KEY(a)) ENGINE=innodb;
+CREATE TABLE t2(b DATETIME,KEY(b)) ENGINE=innodb;
+INSERT INTO t1 VALUES (),();
+INSERT INTO t2 VALUES (),();
+CREATE OR REPLACE VIEW v1 AS SELECT 1 FROM t2
+ WHERE b =(SELECT a FROM t1 LIMIT 1);
+
+--disable_query_log
+--disable_result_log
+CONNECT (con1, localhost, root,,);
+--enable_query_log
+--enable_result_log
+CONNECTION default;
+
+DELIMITER |;
+CREATE PROCEDURE p1(num INT)
+BEGIN
+ DECLARE i INT DEFAULT 0;
+ REPEAT
+ SHOW CREATE VIEW v1;
+ SET i:=i+1;
+ UNTIL i>num END REPEAT;
+END|
+DELIMITER ;|
+
+--echo # Should not crash
+--disable_query_log
+--disable_result_log
+--send CALL p1(1000)
+CONNECTION con1;
+--echo # Should not crash
+CALL p1(1000);
+
+CONNECTION default;
+--reap
+--enable_query_log
+--enable_result_log
+
+DISCONNECT con1;
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1,t2;
--echo End of 5.1 tests
=== added file 'mysql-test/t/innodb_utf8.test'
--- a/mysql-test/t/innodb_utf8.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb_utf8.test 2009-12-27 13:54:41 +0000
@@ -0,0 +1,24 @@
+#
+# Tests for innodb that requires not default character sets
+#
+
+--source include/have_innodb.inc
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
+
+# Setup
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+#
+# Bug #26835: table corruption after delete+insert
+#
+
+CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY)
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4);
+DELETE FROM t1;
+INSERT INTO t1 VALUES ('DDD');
+SELECT * FROM t1;
+DROP TABLE t1;
=== modified file 'mysql-test/t/innodb_xtradb_bug317074.test'
--- a/mysql-test/t/innodb_xtradb_bug317074.test 2009-10-28 07:52:34 +0000
+++ b/mysql-test/t/innodb_xtradb_bug317074.test 2010-01-15 15:58:25 +0000
@@ -2,7 +2,7 @@
SET @old_innodb_file_format=@@innodb_file_format;
SET @old_innodb_file_per_table=@@innodb_file_per_table;
-SET @old_innodb_file_format_check=@@innodb_file_format_check;
+let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
@@ -45,4 +45,4 @@ ALTER TABLE test1 ENGINE=MyISAM;
DROP TABLE test1;
SET GLOBAL innodb_file_format=@old_innodb_file_format;
SET GLOBAL innodb_file_per_table=@old_innodb_file_per_table;
-SET GLOBAL innodb_file_format_check=@old_innodb_file_format_check;
+eval set global innodb_file_format_check=$innodb_file_format_check_orig;
=== modified file 'mysql-test/t/join_outer.test'
--- a/mysql-test/t/join_outer.test 2007-06-06 17:57:07 +0000
+++ b/mysql-test/t/join_outer.test 2009-12-17 09:55:18 +0000
@@ -867,3 +867,32 @@ SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WH
DROP TABLE t1,t2;
+--echo #
+--echo # Bug#47650: using group by with rollup without indexes returns incorrect
+--echo # results with where
+--echo #
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1);
+
+CREATE TABLE t2 ( a INT, b INT );
+INSERT INTO t2 VALUES (1, 1),(1, 2),(1, 3),(2, 4),(2, 5);
+
+EXPLAIN
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 LEFT JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 LEFT JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+
+EXPLAIN
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+
+SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b )
+FROM t1 JOIN t2 USING( a )
+GROUP BY t1.a WITH ROLLUP;
+
+DROP TABLE t1, t2;
=== modified file 'mysql-test/t/lock_multi.test'
--- a/mysql-test/t/lock_multi.test 2009-07-10 23:12:13 +0000
+++ b/mysql-test/t/lock_multi.test 2009-12-18 20:32:55 +0000
@@ -626,9 +626,11 @@ let $wait_condition=
--source include/wait_condition.inc
let $tlwb= `show status like 'Table_locks_waited'`;
unlock tables;
+connection waiter;
+--reap
+connection default;
drop table t1;
disconnect waiter;
-connection default;
--disable_query_log
eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1);
eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1);
=== modified file 'mysql-test/t/myisam.test'
--- a/mysql-test/t/myisam.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/myisam.test 2010-03-04 08:03:07 +0000
@@ -1190,6 +1190,20 @@ SELECT a FROM t1;
CHECK TABLE t1;
DROP TABLE t1;
+
+--echo #
+--echo # Bug #49465: valgrind warnings and incorrect live checksum...
+--echo #
+CREATE TABLE t1(
+a VARCHAR(1), b VARCHAR(1), c VARCHAR(1),
+f VARCHAR(1), g VARCHAR(1), h VARCHAR(1),
+i VARCHAR(1), j VARCHAR(1), k VARCHAR(1)) CHECKSUM=1;
+INSERT INTO t1 VALUES('', '', '', '', '', '', '', '', '');
+CHECKSUM TABLE t1 QUICK;
+CHECKSUM TABLE t1 EXTENDED;
+DROP TABLE t1;
+
+
--echo End of 5.0 tests
=== modified file 'mysql-test/t/mysql.test'
--- a/mysql-test/t/mysql.test 2009-10-05 13:22:23 +0000
+++ b/mysql-test/t/mysql.test 2010-03-04 08:03:07 +0000
@@ -386,10 +386,16 @@ drop tables t1, t2;
#
# Bug #27884: mysql --html does not quote HTML special characters in output
#
---exec $MYSQL --html test -e "select '< & >' as '<'"
+--write_file $MYSQLTEST_VARDIR/tmp/bug27884.sql
+SELECT '< & >' AS `<`;
+EOF
+--exec $MYSQL --html test < $MYSQLTEST_VARDIR/tmp/bug27884.sql
+
+remove_file $MYSQLTEST_VARDIR/tmp/bug27884.sql;
+
#
-# Bug #27884: mysql client + null byte
+# Bug #28203: mysql client + null byte
#
create table t1 (a char(5));
insert into t1 values ('\0b\0');
@@ -403,4 +409,9 @@ insert into t1 values ('\0b\0');
drop table t1;
--echo
+--echo Bug #47147: mysql client option --skip-column-names does not apply to vertical output
+--echo
+--exec $MYSQL --skip-column-names --vertical test -e "select 1 as a"
+
+--echo
--echo End of tests
=== modified file 'mysql-test/t/mysql_upgrade.test'
--- a/mysql-test/t/mysql_upgrade.test 2009-10-05 13:22:23 +0000
+++ b/mysql-test/t/mysql_upgrade.test 2010-03-04 08:03:07 +0000
@@ -90,3 +90,22 @@ DROP USER mysqltest1@'%';
set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE';
--exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
eval set GLOBAL sql_mode=default;
+
+
+--echo #
+--echo # Bug #41569 mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table
+--echo # but does not set values.
+--echo #
+
+# Create a stored procedure and set the fields in question to null.
+# When running mysql_upgrade, a warning should be written.
+
+CREATE PROCEDURE testproc() BEGIN END;
+UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc';
+UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc';
+UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc';
+--exec $MYSQL_UPGRADE --skip-verbose --force 2> $MYSQLTEST_VARDIR/tmp/41569.txt
+CALL testproc();
+DROP PROCEDURE testproc;
+--cat_file $MYSQLTEST_VARDIR/tmp/41569.txt
+--remove_file $MYSQLTEST_VARDIR/tmp/41569.txt
=== modified file 'mysql-test/t/mysqlbinlog.test'
--- a/mysql-test/t/mysqlbinlog.test 2009-09-30 02:31:25 +0000
+++ b/mysql-test/t/mysqlbinlog.test 2009-12-06 01:11:32 +0000
@@ -71,7 +71,7 @@ select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=330 $MYSQLD_DATADIR/master-bin.000002
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=332 $MYSQLD_DATADIR/master-bin.000002
# These are tests for remote binlog.
@@ -108,7 +108,7 @@ select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=330 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=332 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# Bug#7853 mysqlbinlog does not accept input from stdin
--disable_query_log
=== added file 'mysql-test/t/mysqlbinlog2-master.opt'
--- a/mysql-test/t/mysqlbinlog2-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/mysqlbinlog2-master.opt 2010-01-19 10:36:52 +0000
@@ -0,0 +1 @@
+--timezone=GMT-3
=== added file 'mysql-test/t/mysqlbinlog_row-master.opt'
--- a/mysql-test/t/mysqlbinlog_row-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/mysqlbinlog_row-master.opt 2010-01-27 17:41:05 +0000
@@ -0,0 +1 @@
+--timezone=GMT-3
=== added file 'mysql-test/t/mysqlbinlog_row_innodb-master.opt'
--- a/mysql-test/t/mysqlbinlog_row_innodb-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/mysqlbinlog_row_innodb-master.opt 2010-01-27 17:41:05 +0000
@@ -0,0 +1 @@
+--timezone=GMT-3
=== added file 'mysql-test/t/mysqlbinlog_row_myisam-master.opt'
--- a/mysql-test/t/mysqlbinlog_row_myisam-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/mysqlbinlog_row_myisam-master.opt 2010-01-27 17:41:05 +0000
@@ -0,0 +1 @@
+--timezone=GMT-3
=== added file 'mysql-test/t/mysqlbinlog_row_trans-master.opt'
--- a/mysql-test/t/mysqlbinlog_row_trans-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/mysqlbinlog_row_trans-master.opt 2010-01-27 17:41:05 +0000
@@ -0,0 +1 @@
+--timezone=GMT-3
=== modified file 'mysql-test/t/mysqltest.test'
--- a/mysql-test/t/mysqltest.test 2009-10-08 09:30:03 +0000
+++ b/mysql-test/t/mysqltest.test 2010-01-11 13:15:28 +0000
@@ -9,6 +9,14 @@
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
+# Some tests below connect/disconnect rapidly in a loop. This causes a race
+# where mysqld may not have time to register the previous disconnects before
+# new connects, and eventually we run out of connections. So we need to
+# increase the maximum.
+let $saved_max_connections = `SELECT @@global.max_connections`;
+SET GLOBAL max_connections = 1000;
+
+
# ============================================================================
#
# Test of mysqltest itself
@@ -2319,3 +2327,7 @@ disconnect $y;
connection default;
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
+
+--disable_query_log
+--eval SET GLOBAL max_connections = $saved_max_connections
+--enable_query_log
=== modified file 'mysql-test/t/olap.test'
--- a/mysql-test/t/olap.test 2009-10-30 15:54:53 +0000
+++ b/mysql-test/t/olap.test 2009-12-08 09:26:11 +0000
@@ -390,4 +390,17 @@ SELECT DISTINCT b FROM t1, t2 GROUP BY a
DROP TABLE t1, t2;
+--echo #
+--echo # Bug #48475: DISTINCT is ignored with GROUP BY WITH ROLLUP
+--echo # and only const tables
+
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+
+SELECT DISTINCT b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
=== modified file 'mysql-test/t/openssl_1.test'
--- a/mysql-test/t/openssl_1.test 2009-05-25 13:00:18 +0000
+++ b/mysql-test/t/openssl_1.test 2010-03-04 08:03:07 +0000
@@ -15,8 +15,8 @@ insert into t1 values (5);
grant select on test.* to ssl_user1@localhost require SSL;
grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA";
-grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer(a)mysql.com";
-grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer(a)mysql.com" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB";
+grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB";
+grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB";
grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx";
flush privileges;
=== modified file 'mysql-test/t/order_by.test'
--- a/mysql-test/t/order_by.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/order_by.test 2010-03-04 08:03:07 +0000
@@ -869,6 +869,40 @@ SELECT
DROP TABLE t1, t2, t3;
+--echo #
+--echo # Bug #42760: Select doesn't return desired results when we have null
+--echo # values
+--echo #
+
+CREATE TABLE t1 (
+ a INT,
+ c INT,
+ UNIQUE KEY a_c (a,c),
+ KEY (a));
+
+INSERT INTO t1 VALUES (1, 10), (2, NULL);
+
+--echo # Must use ref-or-null on the a_c index
+EXPLAIN
+SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
+--echo # Must return 1 row
+SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
+
+# part 2 of the problem : DESC test cases
+--echo # Must use ref-or-null on the a_c index
+--replace_column 1 x 2 x 3 x 6 x 7 x 8 x 9 x 10 x
+EXPLAIN
+SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC;
+--echo # Must return 1 row
+SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC;
+
+
+DROP TABLE t1;
+
+
+--echo End of 5.0 tests
+
+
#
# Bug #35206: select query result different if the key is indexed or not
#
=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/partition.test 2010-03-04 08:03:07 +0000
@@ -15,6 +15,15 @@ drop table if exists t1, t2;
--enable_warnings
#
+# Bug#48276: can't add column if subpartition exists
+CREATE TABLE t1 (a INT, b INT)
+PARTITION BY LIST (a)
+SUBPARTITION BY HASH (b)
+(PARTITION p1 VALUES IN (1));
+ALTER TABLE t1 ADD COLUMN c INT;
+DROP TABLE t1;
+
+#
# Bug#46639: 1030 (HY000): Got error 124 from storage engine on
# INSERT ... SELECT ...
CREATE TABLE t1 (
@@ -44,8 +53,8 @@ CREATE TABLE t1 (
b varchar(10),
PRIMARY KEY (a)
)
-PARTITION BY RANGE (to_days(a)) (
- PARTITION p1 VALUES LESS THAN (733407),
+PARTITION BY RANGE (UNIX_TIMESTAMP(a)) (
+ PARTITION p1 VALUES LESS THAN (1199134800),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
@@ -55,13 +64,24 @@ INSERT INTO t1 VALUES ('2009-09-21 17:31
SELECT * FROM t1;
ALTER TABLE t1 REORGANIZE PARTITION pmax INTO (
- PARTITION p3 VALUES LESS THAN (733969),
+ PARTITION p3 VALUES LESS THAN (1247688000),
PARTITION pmax VALUES LESS THAN MAXVALUE);
SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
#
+# Bug#45904: Error when CHARSET=utf8 and subpartitioning
+#
+create table t1 (a int NOT NULL, b varchar(5) NOT NULL)
+default charset=utf8
+partition by list (a)
+subpartition by key (b)
+(partition p0 values in (1),
+ partition p1 values in (2));
+drop table t1;
+
+#
# Bug#44059: rec_per_key on empty partition gives weird optimiser results
#
create table t1 (a int, b int, key(a))
@@ -2035,11 +2055,14 @@ DROP TABLE t1;
--echo #
--echo # Bug #45807: crash accessing partitioned table and sql_mode
--echo # contains ONLY_FULL_GROUP_BY
+--echo # Bug#46923: select count(*) from partitioned table fails with
+--echo # ONLY_FULL_GROUP_BY
--echo #
SET SESSION SQL_MODE='ONLY_FULL_GROUP_BY';
CREATE TABLE t1(id INT,KEY(id)) ENGINE=MYISAM
PARTITION BY HASH(id) PARTITIONS 2;
+SELECT COUNT(*) FROM t1;
DROP TABLE t1;
SET SESSION SQL_MODE=DEFAULT;
=== modified file 'mysql-test/t/partition_bug18198.test'
--- a/mysql-test/t/partition_bug18198.test 2007-06-13 15:28:59 +0000
+++ b/mysql-test/t/partition_bug18198.test 2009-12-13 20:29:50 +0000
@@ -158,7 +158,7 @@ create table t1 (col1 datetime)
partition by range(timestampdiff(day,5,col1))
(partition p0 values less than (10), partition p1 values less than (30));
--- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
+-- error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
create table t1 (col1 date)
partition by range(unix_timestamp(col1))
(partition p0 values less than (10), partition p1 values less than (30));
=== modified file 'mysql-test/t/partition_error.test'
--- a/mysql-test/t/partition_error.test 2009-02-18 20:29:30 +0000
+++ b/mysql-test/t/partition_error.test 2009-12-13 20:29:50 +0000
@@ -466,7 +466,7 @@ partitions 2
#
# Partition by range, constant partition function not allowed
#
---error ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
CREATE TABLE t1 (
a int not null,
b int not null,
@@ -681,7 +681,7 @@ partition by list (a);
#
# Partition by list, constant partition function not allowed
#
---error ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
CREATE TABLE t1 (
a int not null,
b int not null,
@@ -840,4 +840,364 @@ partition by range (a + (select count(*)
create table t1 (a char(10))
partition by hash (extractvalue(a,'a'));
+--echo #
+--echo # Bug #42849: innodb crash with varying time_zone on partitioned
+--echo # timestamp primary key
+--echo #
+
+# A correctly partitioned table to test that trying to repartition it using
+# timezone-dependent expression will throw an error.
+CREATE TABLE old (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (UNIX_TIMESTAMP(a)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+# Check that allowed arithmetic/math functions involving TIMESTAMP values result
+# in ER_PARTITION_FUNC_NOT_ALLOWED_ERROR when used as a partitioning function
+
+--error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (a) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (a) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (a+0) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (a+0) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (a % 2) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (a % 2) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (ABS(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (ABS(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (CEILING(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (CEILING(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (FLOOR(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (FLOOR(a)) (
+PARTITION p VALUES LESS THAN (20080819),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+# Check that allowed date/time functions involving TIMESTAMP values result
+# in ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR when used as a partitioning function
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (TO_DAYS(a)) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (TO_DAYS(a)) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (DAYOFYEAR(a)) (
+PARTITION p VALUES LESS THAN (231),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (DAYOFYEAR(a)) (
+PARTITION p VALUES LESS THAN (231),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (DAYOFMONTH(a)) (
+PARTITION p VALUES LESS THAN (19),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (DAYOFMONTH(a)) (
+PARTITION p VALUES LESS THAN (19),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (DAYOFWEEK(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (DAYOFWEEK(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (MONTH(a)) (
+PARTITION p VALUES LESS THAN (8),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (MONTH(a)) (
+PARTITION p VALUES LESS THAN (8),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (HOUR(a)) (
+PARTITION p VALUES LESS THAN (17),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (HOUR(a)) (
+PARTITION p VALUES LESS THAN (17),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (MINUTE(a)) (
+PARTITION p VALUES LESS THAN (55),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (MINUTE(a)) (
+PARTITION p VALUES LESS THAN (55),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (QUARTER(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (QUARTER(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (SECOND(a)) (
+PARTITION p VALUES LESS THAN (7),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (SECOND(a)) (
+PARTITION p VALUES LESS THAN (7),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (YEARWEEK(a)) (
+PARTITION p VALUES LESS THAN (200833),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (YEARWEEK(a)) (
+PARTITION p VALUES LESS THAN (200833),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (YEAR(a)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (YEAR(a)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (WEEKDAY(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (WEEKDAY(a)) (
+PARTITION p VALUES LESS THAN (3),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (TIME_TO_SEC(a)) (
+PARTITION p VALUES LESS THAN (64507),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (TIME_TO_SEC(a)) (
+PARTITION p VALUES LESS THAN (64507),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (EXTRACT(DAY FROM a)) (
+PARTITION p VALUES LESS THAN (18),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (EXTRACT(DAY FROM a)) (
+PARTITION p VALUES LESS THAN (18),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL, b TIMESTAMP NOT NULL, PRIMARY KEY(a,b))
+PARTITION BY RANGE (DATEDIFF(a, a)) (
+PARTITION p VALUES LESS THAN (18),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (DATEDIFF(a, a)) (
+PARTITION p VALUES LESS THAN (18),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (YEAR(a + 0)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (YEAR(a + 0)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (TO_DAYS(a + '2008-01-01')) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (TO_DAYS(a + '2008-01-01')) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
+PARTITION BY RANGE (YEAR(a + '2008-01-01')) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (YEAR(a + '2008-01-01')) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+ALTER TABLE old ADD COLUMN b DATE;
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP, b DATE)
+PARTITION BY RANGE (YEAR(a + b)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (YEAR(a + b)) (
+PARTITION p VALUES LESS THAN (2008),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP, b DATE)
+PARTITION BY RANGE (TO_DAYS(a + b)) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (TO_DAYS(a + b)) (
+PARTITION p VALUES LESS THAN (733638),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP, b date)
+PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE new (a TIMESTAMP, b TIMESTAMP)
+PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+
+ALTER TABLE old MODIFY b TIMESTAMP;
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE old
+PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) (
+PARTITION p VALUES LESS THAN (1219089600),
+PARTITION pmax VALUES LESS THAN MAXVALUE);
+DROP TABLE old;
+
+--echo End of 5.1 tests
=== added file 'mysql-test/t/partition_innodb-master.opt'
--- a/mysql-test/t/partition_innodb-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/partition_innodb-master.opt 2010-01-18 16:49:18 +0000
@@ -0,0 +1 @@
+--innodb_lock_wait_timeout=1
=== modified file 'mysql-test/t/partition_innodb.test'
--- a/mysql-test/t/partition_innodb.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/partition_innodb.test 2010-03-04 08:03:07 +0000
@@ -5,6 +5,8 @@
drop table if exists t1;
--enable_warnings
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+
#
# Bug#47029: Crash when reorganize partition with subpartition
#
@@ -296,6 +298,47 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB
PARTITION BY list(a) (PARTITION p1 VALUES IN (1));
CREATE INDEX i1 ON t1 (a);
DROP TABLE t1;
-let $MYSQLD_DATADIR= `SELECT @@datadir`;
+
# Before the fix it should show extra file like #sql-2405_2.par
--list_files $MYSQLD_DATADIR/test/ *
+
+--echo #
+--echo # Bug#47343: InnoDB fails to clean-up after lock wait timeout on
+--echo # REORGANIZE PARTITION
+--echo #
+CREATE TABLE t1 (
+ a INT,
+ b DATE NOT NULL,
+ PRIMARY KEY (a, b)
+) ENGINE=InnoDB
+PARTITION BY RANGE (a) (
+ PARTITION pMAX VALUES LESS THAN MAXVALUE
+) ;
+
+INSERT INTO t1 VALUES (1, '2001-01-01'), (2, '2002-02-02'), (3, '2003-03-03');
+
+START TRANSACTION;
+SELECT * FROM t1 FOR UPDATE;
+
+connect (con1, localhost, root,,);
+--echo # Connection con1
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO
+(PARTITION p3 VALUES LESS THAN (3),
+ PARTITION pMAX VALUES LESS THAN MAXVALUE);
+SHOW WARNINGS;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO
+(PARTITION p3 VALUES LESS THAN (3),
+ PARTITION pMAX VALUES LESS THAN MAXVALUE);
+SHOW WARNINGS;
+
+#Contents of the 'test' database directory:
+--list_files $MYSQLD_DATADIR/test
+
+disconnect con1;
+connection default;
+--echo # Connection default
+SELECT * FROM t1;
+COMMIT;
+DROP TABLE t1;
=== modified file 'mysql-test/t/partition_innodb_semi_consistent.test'
--- a/mysql-test/t/partition_innodb_semi_consistent.test 2009-01-13 22:12:16 +0000
+++ b/mysql-test/t/partition_innodb_semi_consistent.test 2010-01-28 14:49:14 +0000
@@ -187,6 +187,7 @@ SELECT * FROM t1;
--echo # Switch to connection con2
connection con2;
+--reap
SELECT * FROM t1;
connection default;
=== modified file 'mysql-test/t/partition_pruning.test'
--- a/mysql-test/t/partition_pruning.test 2009-08-28 10:55:59 +0000
+++ b/mysql-test/t/partition_pruning.test 2009-12-22 17:59:37 +0000
@@ -8,6 +8,166 @@
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
--enable_warnings
+--echo #
+--echo # Bug#49742: Partition Pruning not working correctly for RANGE
+--echo #
+CREATE TABLE t1 (a INT PRIMARY KEY)
+PARTITION BY RANGE (a) (
+PARTITION p0 VALUES LESS THAN (1),
+PARTITION p1 VALUES LESS THAN (2),
+PARTITION p2 VALUES LESS THAN (3),
+PARTITION p3 VALUES LESS THAN (4),
+PARTITION p4 VALUES LESS THAN (5),
+PARTITION p5 VALUES LESS THAN (6),
+PARTITION max VALUES LESS THAN MAXVALUE);
+
+INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8);
+
+SELECT * FROM t1 WHERE a < 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 1;
+SELECT * FROM t1 WHERE a < 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 2;
+SELECT * FROM t1 WHERE a < 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 3;
+SELECT * FROM t1 WHERE a < 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 4;
+SELECT * FROM t1 WHERE a < 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 5;
+SELECT * FROM t1 WHERE a < 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6;
+SELECT * FROM t1 WHERE a < 7;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7;
+SELECT * FROM t1 WHERE a <= 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1;
+SELECT * FROM t1 WHERE a <= 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2;
+SELECT * FROM t1 WHERE a <= 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3;
+SELECT * FROM t1 WHERE a <= 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4;
+SELECT * FROM t1 WHERE a <= 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5;
+SELECT * FROM t1 WHERE a <= 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6;
+SELECT * FROM t1 WHERE a <= 7;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 7;
+SELECT * FROM t1 WHERE a = 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 1;
+SELECT * FROM t1 WHERE a = 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 2;
+SELECT * FROM t1 WHERE a = 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 3;
+SELECT * FROM t1 WHERE a = 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 4;
+SELECT * FROM t1 WHERE a = 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 5;
+SELECT * FROM t1 WHERE a = 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 6;
+SELECT * FROM t1 WHERE a = 7;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 7;
+SELECT * FROM t1 WHERE a >= 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1;
+SELECT * FROM t1 WHERE a >= 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2;
+SELECT * FROM t1 WHERE a >= 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3;
+SELECT * FROM t1 WHERE a >= 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4;
+SELECT * FROM t1 WHERE a >= 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5;
+SELECT * FROM t1 WHERE a >= 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6;
+SELECT * FROM t1 WHERE a >= 7;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 7;
+SELECT * FROM t1 WHERE a > 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1;
+SELECT * FROM t1 WHERE a > 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2;
+SELECT * FROM t1 WHERE a > 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3;
+SELECT * FROM t1 WHERE a > 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4;
+SELECT * FROM t1 WHERE a > 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5;
+SELECT * FROM t1 WHERE a > 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6;
+SELECT * FROM t1 WHERE a > 7;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 7;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT PRIMARY KEY)
+PARTITION BY RANGE (a) (
+PARTITION p0 VALUES LESS THAN (1),
+PARTITION p1 VALUES LESS THAN (2),
+PARTITION p2 VALUES LESS THAN (3),
+PARTITION p3 VALUES LESS THAN (4),
+PARTITION p4 VALUES LESS THAN (5),
+PARTITION max VALUES LESS THAN MAXVALUE);
+
+INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7);
+
+SELECT * FROM t1 WHERE a < 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 1;
+SELECT * FROM t1 WHERE a < 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 2;
+SELECT * FROM t1 WHERE a < 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 3;
+SELECT * FROM t1 WHERE a < 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 4;
+SELECT * FROM t1 WHERE a < 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 5;
+SELECT * FROM t1 WHERE a < 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6;
+SELECT * FROM t1 WHERE a <= 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1;
+SELECT * FROM t1 WHERE a <= 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2;
+SELECT * FROM t1 WHERE a <= 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3;
+SELECT * FROM t1 WHERE a <= 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4;
+SELECT * FROM t1 WHERE a <= 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5;
+SELECT * FROM t1 WHERE a <= 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6;
+SELECT * FROM t1 WHERE a = 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 1;
+SELECT * FROM t1 WHERE a = 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 2;
+SELECT * FROM t1 WHERE a = 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 3;
+SELECT * FROM t1 WHERE a = 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 4;
+SELECT * FROM t1 WHERE a = 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 5;
+SELECT * FROM t1 WHERE a = 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 6;
+SELECT * FROM t1 WHERE a >= 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1;
+SELECT * FROM t1 WHERE a >= 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2;
+SELECT * FROM t1 WHERE a >= 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3;
+SELECT * FROM t1 WHERE a >= 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4;
+SELECT * FROM t1 WHERE a >= 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5;
+SELECT * FROM t1 WHERE a >= 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6;
+SELECT * FROM t1 WHERE a > 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1;
+SELECT * FROM t1 WHERE a > 2;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2;
+SELECT * FROM t1 WHERE a > 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3;
+SELECT * FROM t1 WHERE a > 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4;
+SELECT * FROM t1 WHERE a > 5;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5;
+SELECT * FROM t1 WHERE a > 6;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6;
+DROP TABLE t1;
+
#
# Bug#20577: Partitions: use of to_days() function leads to selection failures
#
=== modified file 'mysql-test/t/ps.test'
--- a/mysql-test/t/ps.test 2009-05-27 15:19:44 +0000
+++ b/mysql-test/t/ps.test 2009-12-26 11:25:56 +0000
@@ -1991,6 +1991,45 @@ select @arg;
execute stmt using @arg;
deallocate prepare stmt;
+--echo #
+--echo # Bug#48508: Crash on prepared statement re-execution.
+--echo #
+create table t1(b int);
+insert into t1 values (0);
+create view v1 AS select 1 as a from t1 where b;
+prepare stmt from "select * from v1 where a";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+drop table t1;
+drop view v1;
+
+create table t1(a bigint);
+create table t2(b tinyint);
+insert into t2 values (null);
+prepare stmt from "select 1 from t1 join t2 on a xor b where b > 1 and a =1";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+drop table t1,t2;
+--echo #
+
+
+--echo #
+--echo # Bug #49570: Assertion failed: !(order->used & map)
+--echo # on re-execution of prepared statement
+--echo #
+CREATE TABLE t1(a INT PRIMARY KEY);
+INSERT INTO t1 VALUES(0), (1);
+PREPARE stmt FROM
+ "SELECT 1 FROM t1 JOIN t1 t2 USING(a) GROUP BY t2.a, t1.a";
+EXECUTE stmt;
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
+
--echo End of 5.0 tests.
#
@@ -3009,5 +3048,21 @@ execute stmt;
drop table t1;
deallocate prepare stmt;
+--echo #
+--echo # Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
+--echo #
+
+prepare encode from "select encode(?, ?) into @ciphertext";
+prepare decode from "select decode(?, ?) into @plaintext";
+set @str="abc", @key="cba";
+execute encode using @str, @key;
+execute decode using @ciphertext, @key;
+select @plaintext;
+set @str="bcd", @key="dcb";
+execute encode using @str, @key;
+execute decode using @ciphertext, @key;
+select @plaintext;
+deallocate prepare encode;
+deallocate prepare decode;
--echo End of 5.1 tests.
=== modified file 'mysql-test/t/ps_ddl.test'
--- a/mysql-test/t/ps_ddl.test 2008-08-13 19:42:21 +0000
+++ b/mysql-test/t/ps_ddl.test 2010-01-16 07:44:24 +0000
@@ -1445,18 +1445,19 @@ call p_verify_reprepare_count(0);
drop table t2;
# Temporary table with name of table to be created exists
create temporary table t2 (a int);
---error ER_TABLE_EXISTS_ERROR
+# Temporary table and base table are not in the same name space.
execute stmt;
call p_verify_reprepare_count(1);
--error ER_TABLE_EXISTS_ERROR
execute stmt;
-call p_verify_reprepare_count(0);
+call p_verify_reprepare_count(1);
drop temporary table t2;
+--error ER_TABLE_EXISTS_ERROR
execute stmt;
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
drop table t2;
execute stmt;
-call p_verify_reprepare_count(0);
+call p_verify_reprepare_count(1);
drop table t2;
# View with name of table to be created exists
# Attention:
=== modified file 'mysql-test/t/query_cache.test'
--- a/mysql-test/t/query_cache.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/query_cache.test 2010-01-11 13:15:28 +0000
@@ -882,6 +882,19 @@ drop procedure f4;
drop table t1;
set GLOBAL query_cache_size=0;
+# Tests moved from main.variables due to needing query cache in server.
+set GLOBAL query_cache_size=100000;
+--error ER_GLOBAL_VARIABLE
+set SESSION query_cache_size=10000;
+set global query_cache_limit=100;
+set global query_cache_size=100;
+set global query_cache_type=demand;
+
+set GLOBAL query_cache_type=default;
+set GLOBAL query_cache_limit=default;
+set GLOBAL query_cache_size=default;
+
+
--echo End of 4.1 tests
#
@@ -1288,6 +1301,198 @@ SHOW STATUS LIKE "Qcache_hits";
DROP TABLE t1;
SET GLOBAL query_cache_size= default;
+#
+# Bug#6760: Add SLEEP() function (feature request)
+#
+# Logics of original test:
+# Reveal that a query with SLEEP does not need less time than estimated.
+#
+# Bug#12689: SLEEP() gets incorrectly cached/optimized-away
+#
+# Description from bug report (slightly modified)
+#
+# Bug 1 (happened all time):
+# SELECT * FROM t1 WHERE SLEEP(1) will only result in a sleep of 1
+# second, regardless of the number of rows in t1.
+# Bug 2 (happened all time):
+# Such a query will also get cached by the query cache, but should not.
+#
+# Notes (mleich, 2008-05)
+# =======================
+#
+# Experiments around
+# Bug#36345 Test 'func_misc' fails on RHAS3 x86_64
+# showed that the tests for both bugs could produce in case of parallel
+# artificial system time (like via ntpd)
+# - decreases false alarm
+# - increases false success
+#
+# We try here to circumvent these issues by reimplementation of the tests
+# and sophisticated scripting, although the cause of the problems is a massive
+# error within the setup of the testing environment.
+# Tests relying on or checking derivates of the system time must never meet
+# parallel manipulations of system time.
+#
+# Results of experiments with/without manipulation of system time,
+# information_schema.processlist content, high load on testing box
+# ----------------------------------------------------------------
+# Definition: Predicted_cumulative_sleep_time =
+# #_of_result_rows * sleep_time_per_result_row
+#
+# 1. Total (real sleep time) ~= predicted_cumulative_sleep_time !!
+# 2. The state of a session within the PROCESSLIST changes to 'User sleep'
+# if the sessions runs a statement containing the sleep function and the
+# processing of the statement is just within the phase where the sleep
+# is done. (*)
+# 3. NOW() and processlist.time behave "synchronous" to system time and
+# show also the "jumps" caused by system time manipulations. (*)
+# 4. processlist.time is unsigned, the "next" value below 0 is ~ 4G (*)
+# 5. Current processlist.time ~= current real sleep time if the system time
+# was not manipulated. (*)
+# 6. High system load can cause delays of <= 2 seconds.
+# 7. Thanks to Davi for excellent hints and ideas.
+#
+# (*)
+# - information_schema.processlist is not available before MySQL 5.1.
+# - Observation of processlist content requires a
+# - "worker" session sending the query with "send" and pulling results
+# with "reap"
+# - session observing the processlist parallel to the worker session
+# "send" and "reap" do not work in case of an embedded server.
+# Conclusion: Tests based on processlist have too many restrictions.
+#
+# Solutions for subtests based on TIMEDIFF of values filled via NOW()
+# -------------------------------------------------------------------
+# Run the following sequence three times
+# 1. SELECT <start_time>
+# 2. Query with SLEEP
+# 3. SELECT <end_time>
+# If TIMEDIFF(<end_time>,<start_time>) is at least two times within a
+# reasonable range assume that we did not met errors we were looking for.
+#
+# It is extreme unlikely that we have two system time changes within the
+# < 30 seconds runtime. Even if the unlikely happens, there are so
+# frequent runs of this test on this or another testing box which will
+# catch the problem.
+#
+
+--echo #------------------------------------------------------------------------
+--echo # Tests for Bug#6760 and Bug#12689
+# Number of rows within the intended result set.
+SET @row_count = 4;
+# Parameter within SLEEP function
+SET @sleep_time_per_result_row = 1;
+# Maximum acceptable delay caused by high load on testing box
+SET @max_acceptable_delay = 2;
+# TIMEDIFF = time for query with sleep (mostly the time caused by SLEEP)
+# + time for delays caused by high load on testing box
+# Ensure that at least a reasonable fraction of TIMEDIFF belongs to the SLEEP
+# by appropriate setting of variables.
+# Ensure that any "judging" has a base of minimum three attempts.
+# (Test 2 uses all attempts except the first one.)
+if (!` SELECT (@sleep_time_per_result_row * @row_count - @max_acceptable_delay >
+ @sleep_time_per_result_row) AND (@row_count - 1 >= 3)`)
+{
+ --echo # Have to abort because of error in plausibility check
+ --echo ######################################################
+ --vertical_results
+ SELECT @sleep_time_per_result_row * @row_count - @max_acceptable_delay >
+ @sleep_time_per_result_row AS must_be_1,
+ @row_count - 1 >= 3 AS must_be_also_1,
+ @sleep_time_per_result_row, @row_count, @max_acceptable_delay;
+ exit;
+}
+SET @@global.query_cache_size = 1024 * 64;
+--disable_warnings
+DROP TEMPORARY TABLE IF EXISTS t_history;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+CREATE TEMPORARY TABLE t_history (attempt SMALLINT,
+start_ts DATETIME, end_ts DATETIME,
+start_cached INTEGER, end_cached INTEGER);
+CREATE TABLE t1 (f1 BIGINT);
+let $num = `SELECT @row_count`;
+--disable_query_log
+begin;
+while ($num)
+{
+ INSERT INTO t1 VALUES (1);
+ dec $num;
+}
+commit;
+--enable_query_log
+
+let $loops = 4;
+let $num = $loops;
+while ($num)
+{
+ let $Qcache_queries_in_cache =
+ query_get_value(SHOW STATUS LIKE 'Qcache_queries_in_cache', Value, 1);
+ eval
+ INSERT INTO t_history
+ SET attempt = $loops - $num + 1, start_ts = NOW(),
+ start_cached = $Qcache_queries_in_cache;
+ SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
+ #
+ # Do not determine Qcache_queries_in_cache before updating end_ts. The SHOW
+ # might cost too much time on an overloaded box.
+ eval
+ UPDATE t_history SET end_ts = NOW()
+ WHERE attempt = $loops - $num + 1;
+ let $Qcache_queries_in_cache =
+ query_get_value(SHOW STATUS LIKE 'Qcache_queries_in_cache', Value, 1);
+ eval
+ UPDATE t_history SET end_cached = $Qcache_queries_in_cache
+ WHERE attempt = $loops - $num + 1;
+ # DEBUG eval SELECT * FROM t_history WHERE attempt = $loops - $num + 1;
+ dec $num;
+}
+
+# 1. The majority of queries with SLEEP must need a reasonable time
+# -> SLEEP has an impact on runtime
+# = Replacement for original Bug#6760 test
+# -> total runtime is clear more needed than for one result row needed
+# = Replacement for one of the original Bug#12689 tests
+--echo # Test 1: Does the query with SLEEP need a reasonable time?
+eval SELECT COUNT(*) >= $loops - 1 INTO @aux1 FROM t_history
+WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
+ BETWEEN 0 AND @max_acceptable_delay;
+SELECT @aux1 AS "Expect 1";
+#
+# 2. The majority of queries (the first one must be ignored) with SLEEP must
+# need a reasonable time
+# -> If we assume that the result of a cached query will be sent back
+# immediate, without any sleep, than the query with SLEEP cannot be cached
+# (current and intended behaviour for queries with SLEEP).
+# -> It could be also not excluded that the query was cached but the server
+# honoured somehow the SLEEP. Such a behaviour would be also acceptable.
+# = Replacement for one of the original Bug#12689 tests
+--echo # Test 2: Does the query with SLEEP need a reasonable time even in case
+--echo # of the non first execution?
+eval SELECT COUNT(*) >= $loops - 1 - 1 INTO @aux2 FROM t_history
+WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
+ BETWEEN 0 AND @max_acceptable_delay
+ AND attempt > 1;
+SELECT @aux2 AS "Expect 1";
+#
+# 3. The query with SLEEP should be not cached.
+# -> SHOW STATUS Qcache_queries_in_cache must be not incremented after
+# the execution of the query with SLEEP
+--echo # Test 3: The query with SLEEP must be not cached.
+eval SELECT COUNT(*) = $loops INTO @aux3 FROM t_history
+WHERE end_cached = start_cached;
+SELECT @aux3 AS "Expect 1";
+#
+# Dump the content of t_history if one of the tests failed.
+if (`SELECT @aux1 + @aux2 + @aux3 <> 3`)
+{
+ --echo # Some tests failed, dumping the content of t_history
+ SELECT * FROM t_history;
+}
+DROP TABLE t1;
+DROP TEMPORARY TABLE t_history;
+SET @@global.query_cache_size = default;
+
--echo End of 5.0 tests
#
=== modified file 'mysql-test/t/query_cache_debug.test'
--- a/mysql-test/t/query_cache_debug.test 2009-09-07 20:50:10 +0000
+++ b/mysql-test/t/query_cache_debug.test 2010-01-29 10:42:31 +0000
@@ -1,5 +1,4 @@
--source include/not_embedded.inc
---source include/big_test.inc
--source include/have_query_cache.inc
--source include/have_debug.inc
=== modified file 'mysql-test/t/query_cache_notembedded.test'
--- a/mysql-test/t/query_cache_notembedded.test 2009-04-25 09:04:38 +0000
+++ b/mysql-test/t/query_cache_notembedded.test 2010-01-11 13:15:28 +0000
@@ -274,5 +274,52 @@ set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size=default;
+#
+# Bug#3583 query cache doesn't work for stored procedures
+#
+delimiter |;
+--disable_warnings
+drop table if exists t1|
+--enable_warnings
+create table t1 (
+ id char(16) not null default '',
+ data int not null
+)|
+--disable_warnings
+drop procedure if exists bug3583|
+--enable_warnings
+--disable_warnings
+drop procedure if exists bug3583|
+--enable_warnings
+create procedure bug3583()
+begin
+ declare c int;
+
+ select * from t1;
+ select count(*) into c from t1;
+ select c;
+end|
+
+insert into t1 values ("x", 3), ("y", 5)|
+set @x = @@query_cache_size|
+set global query_cache_size = 10*1024*1024|
+
+flush status|
+flush query cache|
+show status like 'Qcache_hits'|
+call bug3583()|
+show status like 'Qcache_hits'|
+call bug3583()|
+call bug3583()|
+show status like 'Qcache_hits'|
+
+set global query_cache_size = @x|
+flush status|
+flush query cache|
+delete from t1|
+drop procedure bug3583|
+drop table t1|
+delimiter ;|
+
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
=== modified file 'mysql-test/t/query_cache_ps_no_prot.test'
--- a/mysql-test/t/query_cache_ps_no_prot.test 2007-05-24 20:13:49 +0000
+++ b/mysql-test/t/query_cache_ps_no_prot.test 2009-12-27 13:54:41 +0000
@@ -11,8 +11,9 @@
# We cannot run on embedded server because we use multiple sessions.
--source include/not_embedded.inc
-
--source include/have_query_cache.inc
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
# The file with expected results fits only to a run without
# ps-protocol/sp-protocol/cursor-protocol/view-protocol.
=== modified file 'mysql-test/t/query_cache_ps_ps_prot.test'
--- a/mysql-test/t/query_cache_ps_ps_prot.test 2007-05-24 20:13:49 +0000
+++ b/mysql-test/t/query_cache_ps_ps_prot.test 2009-12-27 13:54:41 +0000
@@ -11,8 +11,9 @@
# We cannot run on embedded server because we use multiple sessions.
--source include/not_embedded.inc
-
--source include/have_query_cache.inc
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
# The file with expected results fits only to a run with "--ps-protocol".
if (`SELECT $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0
=== modified file 'mysql-test/t/range.test'
--- a/mysql-test/t/range.test 2009-11-02 12:24:07 +0000
+++ b/mysql-test/t/range.test 2009-12-08 09:26:11 +0000
@@ -1260,4 +1260,57 @@ SELECT str_to_date('', '%Y-%m-%d');
DROP TABLE t1, t2;
+--echo #
+--echo # Bug#48459: valgrind errors with query using 'Range checked for each
+--echo # record'
+--echo #
+CREATE TABLE t1 (
+ a INT,
+ b CHAR(2),
+ c INT,
+ d INT,
+ KEY ( c ),
+ KEY ( d, a, b ( 2 ) ),
+ KEY ( b ( 1 ) )
+);
+
+INSERT INTO t1 VALUES ( NULL, 'a', 1, 2 ), ( NULL, 'a', 1, 2 ),
+ ( 1, 'a', 1, 2 ), ( 1, 'a', 1, 2 );
+
+CREATE TABLE t2 (
+ a INT,
+ c INT,
+ e INT,
+ KEY ( e )
+);
+
+INSERT INTO t2 VALUES ( 1, 1, NULL ), ( 1, 1, NULL );
+
+--echo # Should not give Valgrind warnings
+SELECT 1
+FROM t1, t2
+WHERE t1.d <> '1' AND t1.b > '1'
+AND t1.a = t2.a AND t1.c = t2.c;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug #48665: sql-bench's insert test fails due to wrong result
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a));
+
+INSERT INTO t1 VALUES (0,0), (1,1);
+
+--replace_column 1 @ 2 @ 3 @ 5 @ 6 @ 7 @ 8 @ 9 @ 10 @
+EXPLAIN
+SELECT * FROM t1 FORCE INDEX (PRIMARY)
+ WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+
+--echo # Should return 2 rows
+SELECT * FROM t1 FORCE INDEX (PRIMARY)
+ WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+
+DROP TABLE t1;
+
--echo End of 5.1 tests
=== modified file 'mysql-test/t/select.test'
--- a/mysql-test/t/select.test 2009-10-30 14:13:13 +0000
+++ b/mysql-test/t/select.test 2010-01-29 11:08:49 +0000
@@ -3772,6 +3772,109 @@ INTO @var0;
DROP TABLE t1;
+--echo #
+--echo # Bug #48458: simple query tries to allocate enormous amount of
+--echo # memory
+--echo #
+
+CREATE TABLE t1(a INT NOT NULL, b YEAR);
+INSERT INTO t1 VALUES ();
+CREATE TABLE t2(c INT);
+--echo # Should not err out because of out-of-memory
+SELECT 1 FROM t2 JOIN t1 ON 1=1
+ WHERE a != '1' AND NOT a >= b OR NOT ROW(b,a )<> ROW(a,a);
+DROP TABLE t1,t2;
+
+
+--echo #
+--echo # Bug #49199: Optimizer handles incorrectly:
+--echo # field='const1' AND field='const2' in some cases
+--echo
+CREATE TABLE t1(a DATETIME NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+DROP TABLE t1;
+
+CREATE TABLE t1(a DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+DROP TABLE t1;
+
+CREATE TABLE t1(a TIMESTAMP NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00';
+DROP TABLE t1;
+
+CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+DROP TABLE t1;
+
+CREATE TABLE t1(a DATETIME NOT NULL, b VARCHAR(20) NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00';
+
+SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01';
+DROP TABLE t1;
+
+CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL);
+INSERT INTO t1 VALUES('2001-01-01', '2001-01-01');
+SELECT x.a, y.a, z.a FROM t1 x
+ JOIN t1 y ON x.a=y.a
+ JOIN t1 z ON y.a=z.a
+ WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
+EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x
+ JOIN t1 y ON x.a=y.a
+ JOIN t1 z ON y.a=z.a
+ WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
+DROP TABLE t1;
+
+
+--echo #
+--echo # Bug #49897: crash in ptr_compare when char(0) NOT NULL
+--echo # column is used for ORDER BY
+--echo #
+SET @old_sort_buffer_size= @@session.sort_buffer_size;
+SET @@sort_buffer_size= 40000;
+
+CREATE TABLE t1(a CHAR(0) NOT NULL);
+--disable_warnings
+INSERT INTO t1 VALUES (0), (0), (0);
+--enable_warnings
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
+EXPLAIN SELECT a FROM t1 ORDER BY a;
+--disable_result_log
+SELECT a FROM t1 ORDER BY a;
+--enable_result_log
+DROP TABLE t1;
+
+CREATE TABLE t1(a CHAR(0) NOT NULL, b CHAR(0) NOT NULL, c int);
+--disable_warnings
+INSERT INTO t1 VALUES (0, 0, 0), (0, 0, 2), (0, 0, 1);
+--enable_warnings
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
+EXPLAIN SELECT a FROM t1 ORDER BY a LIMIT 5;
+SELECT a FROM t1 ORDER BY a LIMIT 5;
+EXPLAIN SELECT * FROM t1 ORDER BY a, b LIMIT 5;
+SELECT * FROM t1 ORDER BY a, b LIMIT 5;
+EXPLAIN SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
+SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
+EXPLAIN SELECT * FROM t1 ORDER BY c, a LIMIT 5;
+SELECT * FROM t1 ORDER BY c, a LIMIT 5;
+
+SET @@sort_buffer_size= @old_sort_buffer_size;
+DROP TABLE t1;
+
--echo End of 5.0 tests
@@ -3918,4 +4021,60 @@ SELECT table1 .`time_key` field2 FROM B
drop table A,AA,B,BB;
--echo #end of test for bug#45266
+
+--echo #
+--echo # BUG#48052: Valgrind warning - uninitialized value in init_read_record()
+--echo #
+
+# Needed in 6.0 codebase
+#--echo # Disable Index condition pushdown
+#--replace_column 1 #
+#SELECT @old_icp:=@@engine_condition_pushdown;
+#SET SESSION engine_condition_pushdown = 'OFF';
+
+CREATE TABLE t1 (
+ pk int(11) NOT NULL,
+ i int(11) DEFAULT NULL,
+ v varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk)
+);
+
+INSERT INTO t1 VALUES (2,7,'m');
+INSERT INTO t1 VALUES (3,9,'m');
+
+SELECT v
+FROM t1
+WHERE NOT pk > 0
+HAVING v <= 't'
+ORDER BY pk;
+
+# Needed in 6.0 codebase
+#--echo # Restore old value for Index condition pushdown
+#SET SESSION engine_condition_pushdown=@old_icp;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#49489 Uninitialized cache led to a wrong result.
+--echo #
+CREATE TABLE t1(c1 DOUBLE(5,4));
+INSERT INTO t1 VALUES (9.1234);
+SELECT * FROM t1 WHERE c1 < 9.12345;
+DROP TABLE t1;
+--echo # End of test for bug#49489.
+
+
+--echo #
+--echo # Bug #49517: Inconsistent behavior while using
+--echo # NULLable BIGINT and INT columns in comparison
+--echo #
+CREATE TABLE t1(a BIGINT UNSIGNED NOT NULL, b BIGINT NULL, c INT NULL);
+INSERT INTO t1 VALUES(105, NULL, NULL);
+SELECT * FROM t1 WHERE b < 102;
+SELECT * FROM t1 WHERE c < 102;
+SELECT * FROM t1 WHERE 102 < b;
+SELECT * FROM t1 WHERE 102 < c;
+DROP TABLE t1;
+
+
--echo End of 5.1 tests
=== modified file 'mysql-test/t/show_check-master.opt'
--- a/mysql-test/t/show_check-master.opt 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/show_check-master.opt 2010-01-27 21:53:08 +0000
@@ -1 +1 @@
---log-output=table --slow-query-log --log-long-format --log-queries-not-using-indexes --myisam-recover="" --general-log --general-log-file="" --slow-query-log-file=""
+--log-output=file --slow-query-log --log-long-format --log-queries-not-using-indexes --myisam-recover="" --general-log --general-log-file="foo" --slow-query-log-file=""
=== modified file 'mysql-test/t/show_check.test'
--- a/mysql-test/t/show_check.test 2009-03-06 14:56:17 +0000
+++ b/mysql-test/t/show_check.test 2010-01-13 10:28:42 +0000
@@ -1207,6 +1207,28 @@ connection default;
DROP USER test_u@localhost;
+--echo #
+--echo # Bug #48985: show create table crashes if previous access to the table
+--echo # was killed
+--echo #
+
+connect(con1,localhost,root,,);
+CONNECTION con1;
+LET $ID= `SELECT connection_id()`;
+
+CONNECTION default;
+--disable_query_log
+eval KILL QUERY $ID;
+--enable_query_log
+
+CONNECTION con1;
+--error ER_QUERY_INTERRUPTED
+SHOW CREATE TABLE non_existent;
+
+CONNECTION default;
+DISCONNECT con1;
+
+
--echo End of 5.1 tests
# Wait till all disconnects are completed
=== modified file 'mysql-test/t/sp-destruct.test'
--- a/mysql-test/t/sp-destruct.test 2008-04-08 14:51:26 +0000
+++ b/mysql-test/t/sp-destruct.test 2010-02-10 19:06:24 +0000
@@ -12,8 +12,12 @@
# mysqltest should be fixed to allow REPLACE_RESULT in error message
-- source include/not_embedded.inc
+# Supress warnings written to the log file
+call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted");
+
# Backup proc table
let $MYSQLD_DATADIR= `select @@datadir`;
+flush table mysql.proc;
--copy_file $MYSQLD_DATADIR/mysql/proc.frm $MYSQLTEST_VARDIR/tmp/proc.frm
--copy_file $MYSQLD_DATADIR/mysql/proc.MYD $MYSQLTEST_VARDIR/tmp/proc.MYD
--copy_file $MYSQLD_DATADIR/mysql/proc.MYI $MYSQLTEST_VARDIR/tmp/proc.MYI
@@ -38,15 +42,14 @@ create trigger t1_ai after insert on t1
# Unsupported tampering with the mysql.proc definition
alter table mysql.proc drop type;
---replace_result $MYSQL_TEST_DIR .
---error ER_SP_PROC_TABLE_CORRUPT
+--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
call bug14233();
---replace_result $MYSQL_TEST_DIR .
---error ER_SP_PROC_TABLE_CORRUPT
+--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
create view v1 as select bug14233_f();
---replace_result $MYSQL_TEST_DIR .
---error ER_SP_PROC_TABLE_CORRUPT
+--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
insert into t1 values (0);
+--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
+show procedure status;
flush table mysql.proc;
@@ -155,3 +158,43 @@ drop procedure bug14233_3;
# Assert: These should show nothing.
show procedure status where db=DATABASE();
show function status where db=DATABASE();
+
+#
+# Bug#41726 upgrade from 5.0 to 5.1.30 crashes if you didn't run mysql_upgrade
+#
+
+
+--disable_warnings
+DROP TABLE IF EXISTS proc_backup;
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+--echo # Backup the proc table
+
+RENAME TABLE mysql.proc TO proc_backup;
+CREATE TABLE mysql.proc LIKE proc_backup;
+FLUSH TABLE mysql.proc;
+
+--echo # Test with a valid table.
+
+CREATE PROCEDURE p1()
+ SET @foo = 10;
+CALL p1();
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+SHOW PROCEDURE STATUS;
+
+--echo # Modify a field of the table.
+
+ALTER TABLE mysql.proc MODIFY comment CHAR (32);
+
+--error ER_CANNOT_LOAD_FROM_TABLE
+CREATE PROCEDURE p2()
+ SET @foo = 10;
+--echo # Procedure loaded from the cache
+CALL p1();
+--error ER_CANNOT_LOAD_FROM_TABLE
+SHOW PROCEDURE STATUS;
+
+DROP TABLE mysql.proc;
+RENAME TABLE proc_backup TO mysql.proc;
+FLUSH TABLE mysql.proc;
=== modified file 'mysql-test/t/sp-security.test'
--- a/mysql-test/t/sp-security.test 2009-03-06 14:56:17 +0000
+++ b/mysql-test/t/sp-security.test 2009-11-27 16:10:28 +0000
@@ -865,6 +865,65 @@ DROP PROCEDURE p_suid;
DROP FUNCTION f_suid;
DROP TABLE t1;
+--echo #
+--echo # Bug #48872 : Privileges for stored functions ignored if function name
+--echo # is mixed case
+--echo #
+
+CREATE DATABASE B48872;
+USE B48872;
+CREATE TABLE `TestTab` (id INT);
+INSERT INTO `TestTab` VALUES (1),(2);
+CREATE FUNCTION `f_Test`() RETURNS INT RETURN 123;
+CREATE FUNCTION `f_Test_denied`() RETURNS INT RETURN 123;
+CREATE USER 'tester';
+CREATE USER 'Tester';
+GRANT SELECT ON TABLE `TestTab` TO 'tester';
+GRANT EXECUTE ON FUNCTION `f_Test` TO 'tester';
+GRANT EXECUTE ON FUNCTION `f_Test_denied` TO 'Tester';
+
+SELECT f_Test();
+SELECT * FROM TestTab;
+
+CONNECT (con_tester,localhost,tester,,B48872);
+CONNECT (con_tester_denied,localhost,Tester,,B48872);
+CONNECTION con_tester;
+
+SELECT * FROM TestTab;
+SELECT `f_Test`();
+SELECT `F_TEST`();
+SELECT f_Test();
+SELECT F_TEST();
+
+CONNECTION con_tester_denied;
+
+--disable_result_log
+--error ER_TABLEACCESS_DENIED_ERROR
+SELECT * FROM TestTab;
+--error ER_PROCACCESS_DENIED_ERROR
+SELECT `f_Test`();
+--error ER_PROCACCESS_DENIED_ERROR
+SELECT `F_TEST`();
+--error ER_PROCACCESS_DENIED_ERROR
+SELECT f_Test();
+--error ER_PROCACCESS_DENIED_ERROR
+SELECT F_TEST();
+--enable_result_log
+SELECT `f_Test_denied`();
+SELECT `F_TEST_DENIED`();
+
+CONNECTION default;
+DISCONNECT con_tester;
+DISCONNECT con_tester_denied;
+DROP TABLE `TestTab`;
+DROP FUNCTION `f_Test`;
+DROP FUNCTION `f_Test_denied`;
+
+USE test;
+DROP USER 'tester';
+DROP USER 'Tester';
+DROP DATABASE B48872;
+
--echo End of 5.0 tests.
# Wait till all disconnects are completed
=== modified file 'mysql-test/t/sp-ucs2.test'
--- a/mysql-test/t/sp-ucs2.test 2007-02-19 10:57:06 +0000
+++ b/mysql-test/t/sp-ucs2.test 2009-12-02 11:17:08 +0000
@@ -26,3 +26,32 @@ drop table t3|
delimiter ;|
+
+#
+# Bug#48766 SHOW CREATE FUNCTION returns extra data in return clause
+#
+SET NAMES utf8;
+--disable_warnings
+DROP FUNCTION IF EXISTS bug48766;
+--enable_warnings
+#
+# Test that Latin letters are not prepended with extra '\0'.
+#
+CREATE FUNCTION bug48766 ()
+ RETURNS ENUM( 'w' ) CHARACTER SET ucs2
+ RETURN 0;
+SHOW CREATE FUNCTION bug48766;
+SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_NAME='bug48766';
+DROP FUNCTION bug48766;
+#
+# Test non-Latin characters
+#
+CREATE FUNCTION bug48766 ()
+ RETURNS ENUM('а','б','в','г') CHARACTER SET ucs2
+ RETURN 0;
+SHOW CREATE FUNCTION bug48766;
+SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_NAME='bug48766';
+
+DROP FUNCTION bug48766;
=== modified file 'mysql-test/t/sp.test'
--- a/mysql-test/t/sp.test 2009-10-23 13:54:58 +0000
+++ b/mysql-test/t/sp.test 2009-12-23 13:44:03 +0000
@@ -8242,6 +8242,25 @@ while ($tab_count)
DROP PROCEDURE p1;
DROP TABLE t1;
+#
+# Bug#47649 crash during CALL procedure
+#
+CREATE TABLE t1 ( f1 integer, primary key (f1));
+CREATE TABLE t2 LIKE t1;
+CREATE TEMPORARY TABLE t3 LIKE t1;
+delimiter |;
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ;
+END|
+delimiter ;|
+--error ER_CANT_REOPEN_TABLE
+CALL p1;
+CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 );
+DROP TABLE t3;
+CALL p1;
+CALL p1;
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
+DROP VIEW t3;
--echo #
--echo # Bug #46629: Item_in_subselect::val_int(): Assertion `0'
@@ -8263,6 +8282,73 @@ CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1, t2;
+--echo #
+--echo # Bug#47627: SET @@{global.session}.local_variable in stored routine causes crash
+--echo # Bug#48626: Crash or lost connection using SET for declared variables with @@
+--echo #
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+--enable_warnings
+
+delimiter //;
+
+--error ER_UNKNOWN_SYSTEM_VARIABLE
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SET @@SESSION.v= 10;
+END//
+
+CREATE PROCEDURE p2()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SET v= 10;
+END//
+call p2()//
+
+--error ER_UNKNOWN_SYSTEM_VARIABLE
+CREATE PROCEDURE p3()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SELECT @@SESSION.v;
+END//
+
+--error ER_UNKNOWN_SYSTEM_VARIABLE
+CREATE PROCEDURE p4()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SET @@GLOBAL.v= 10;
+END//
+
+CREATE PROCEDURE p5()
+BEGIN
+ DECLARE init_connect INT DEFAULT 0;
+ SET init_connect= 10;
+ SET @@GLOBAL.init_connect= 'SELECT 1';
+ SET @@SESSION.IDENTITY= 1;
+ SELECT @@SESSION.IDENTITY;
+ SELECT @@GLOBAL.init_connect;
+ SELECT init_connect;
+END//
+
+--error ER_UNKNOWN_SYSTEM_VARIABLE
+CREATE PROCEDURE p6()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SET @@v= 0;
+END//
+
+delimiter ;//
+
+SET @old_init_connect= @@GLOBAL.init_connect;
+CALL p5();
+SET @@GLOBAL.init_connect= @old_init_connect;
+
+DROP PROCEDURE p2;
+DROP PROCEDURE p5;
--echo # ------------------------------------------------------------------
--echo # -- End of 5.1 tests
=== modified file 'mysql-test/t/sp_notembedded.test'
--- a/mysql-test/t/sp_notembedded.test 2009-10-13 18:21:42 +0000
+++ b/mysql-test/t/sp_notembedded.test 2010-01-11 13:15:28 +0000
@@ -56,52 +56,6 @@ show warnings|
drop procedure bug4902_2|
#
-# Bug#3583 query cache doesn't work for stored procedures
-#
---disable_warnings
-drop table if exists t1|
---enable_warnings
-create table t1 (
- id char(16) not null default '',
- data int not null
-)|
---disable_warnings
-drop procedure if exists bug3583|
---enable_warnings
---disable_warnings
-drop procedure if exists bug3583|
---enable_warnings
-create procedure bug3583()
-begin
- declare c int;
-
- select * from t1;
- select count(*) into c from t1;
- select c;
-end|
-
-insert into t1 values ("x", 3), ("y", 5)|
-set @x = @@query_cache_size|
-set global query_cache_size = 10*1024*1024|
-
-flush status|
-flush query cache|
-show status like 'Qcache_hits'|
-call bug3583()|
-show status like 'Qcache_hits'|
-call bug3583()|
-call bug3583()|
-show status like 'Qcache_hits'|
-
-set global query_cache_size = @x|
-flush status|
-flush query cache|
-delete from t1|
-drop procedure bug3583|
-drop table t1|
-
-
-#
# Bug#6807 Stored procedure crash if CREATE PROCEDURE ... KILL QUERY
#
--disable_warnings
=== added file 'mysql-test/t/sp_sync.test'
--- a/mysql-test/t/sp_sync.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/sp_sync.test 2010-01-15 08:51:39 +0000
@@ -0,0 +1,58 @@
+# This test should work in embedded server after mysqltest is fixed
+-- source include/not_embedded.inc
+
+--echo Tests of syncronization of stored procedure execution.
+
+--source include/have_debug_sync.inc
+
+--echo #
+--echo # Bug#48157: crash in Item_field::used_tables
+--echo #
+
+CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b;
+CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b;
+
+DELIMITER |;
+
+CREATE PROCEDURE p1()
+BEGIN
+ UPDATE t1 JOIN t2 USING( a, b ) SET t1.b = 1, t2.b = 1;
+END|
+
+DELIMITER ;|
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+LOCK TABLES t1 WRITE, t2 WRITE;
+
+connection con2;
+LET $ID= `select connection_id()`;
+SET DEBUG_SYNC = 'multi_update_reopen_tables SIGNAL parked WAIT_FOR go';
+--send CALL p1()
+
+connection con1;
+let $wait_condition= SELECT 1 FROM information_schema.processlist WHERE ID = $ID AND
+state = "Locked";
+--source include/wait_condition.inc
+DROP TABLE t1, t2;
+SET DEBUG_SYNC = 'now WAIT_FOR parked';
+CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b;
+CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b;
+SET DEBUG_SYNC = 'now SIGNAL go';
+
+connection con2;
+--reap
+
+disconnect con1;
+disconnect con2;
+connection default;
+
+--echo # Without the DEBUG_SYNC supplied in the same patch as this test in the
+--echo # code, this test statement will hang.
+DROP TABLE t1, t2;
+DROP PROCEDURE p1;
+
+SET DEBUG_SYNC = 'RESET';
+
=== modified file 'mysql-test/t/subselect.test'
--- a/mysql-test/t/subselect.test 2009-12-03 11:19:05 +0000
+++ b/mysql-test/t/subselect.test 2010-03-04 08:03:07 +0000
@@ -3374,6 +3374,32 @@ WHERE a = 230;
DROP TABLE t1, st1, st2;
+--echo #
+--echo # Bug #48709: Assertion failed in sql_select.cc:11782:
+--echo # int join_read_key(JOIN_TAB*)
+--echo #
+
+CREATE TABLE t1 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t1 VALUES (10,1), (14,1);
+
+CREATE TABLE t2 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3);
+
+--echo # should have eq_ref for t1
+--replace_column 1 x 2 x 5 x 6 x 7 x 8 x 9 x 10 x
+EXPLAIN
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+
+--echo # should not crash on debug binaries
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+
+DROP TABLE t1,t2;
+
+
--echo End of 5.0 tests.
#
@@ -3569,4 +3595,19 @@ SELECT 1 FROM t1 GROUP BY
(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
DROP TABLE t1;
+--echo #
+--echo # Bug #49512 : subquery with aggregate function crash
+--echo # subselect_single_select_engine::exec()
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+
+--echo # should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+ SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+ FROM t1,t1 a
+);
+DROP TABLE t1;
+
--echo End of 5.1 tests.
=== modified file 'mysql-test/t/table_elim.test'
--- a/mysql-test/t/table_elim.test 2009-09-16 19:05:03 +0000
+++ b/mysql-test/t/table_elim.test 2010-03-06 12:09:02 +0000
@@ -2,7 +2,7 @@
# Table elimination (MWL#17) tests
#
--disable_warnings
-drop table if exists t0, t1, t2, t3;
+drop table if exists t0, t1, t2, t3, t4, t5, t6;
drop view if exists v1, v2;
--enable_warnings
@@ -336,3 +336,134 @@ select t1.*
from t1 left join t2 on (t2.pk=3 and t2.b=3) or (t2.pk= 4 and t2.b=3);
drop table t1, t2;
+
+--echo #
+--echo # LPBUG#523593: Running RQG optimizer_no_subquery crashes MariaDB
+--echo #
+
+CREATE TABLE t1 (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_date_key` date DEFAULT NULL,
+ `col_date_nokey` date DEFAULT NULL,
+ `col_time_key` time DEFAULT NULL,
+ `col_time_nokey` time DEFAULT NULL,
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_datetime_nokey` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_int_key` (`col_int_key`),
+ KEY `col_date_key` (`col_date_key`),
+ KEY `col_time_key` (`col_time_key`),
+ KEY `col_datetime_key` (`col_datetime_key`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+);
+CREATE TABLE t2 LIKE t1;
+
+INSERT INTO t1 VALUES
+ (10,7,8,NULL,NULL,'01:27:35','01:27:35','2002-02-26 06:14:37','2002-02-26 06:14:37','v','v'),
+ (11,1,9,'2006-06-14','2006-06-14','19:48:31','19:48:31','1900-01-01 00:00:00','1900-01-01 00:00:00','r','r');
+INSERT INTO t2 SELECT * FROM t1;
+
+SELECT table2.col_int_key AS field1
+FROM (
+ t2 AS table1
+ RIGHT OUTER JOIN
+ (
+ ( t1 AS table2 STRAIGHT_JOIN
+ t1 AS table3 ON (
+ (table3.col_varchar_nokey = table2.col_varchar_key ) AND
+ (table3.pk = table2.col_int_key))
+ )
+ ) ON
+ (
+ (table3.col_varchar_key = table2.col_varchar_key) OR
+ (table3.col_int_key = table2.pk)
+ )
+)
+HAVING field1 < 216;
+
+DROP TABLE t1, t2;
+
+
+--echo #
+--echo # LPBUG#524025 Running RQG outer_join test leads to crash
+--echo #
+
+CREATE TABLE t0 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (pk)
+);
+
+CREATE TABLE t1 (
+ col_int int(11) DEFAULT NULL,
+ col_int_key int(11) DEFAULT NULL,
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_varchar_10_latin1 varchar(10) DEFAULT NULL,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (5,5,1,'t'), (NULL,NULL,2,'y');
+
+CREATE TABLE t2 (
+ col_int int(11) DEFAULT NULL
+);
+INSERT INTO t2 VALUES (8), (4);
+
+CREATE TABLE t3 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t3 VALUES (1),(8);
+
+CREATE TABLE t4 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_varchar_1024_latin1_key varchar(1024) DEFAULT NULL,
+ col_int int(11) DEFAULT NULL,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t4 VALUES (1,'o',1), (2,'w',2);
+
+CREATE TABLE t5 (
+ col_varchar_1024_utf8_key varchar(1024) CHARACTER SET utf8 DEFAULT NULL,
+ col_varchar_1024_latin1_key varchar(1024) DEFAULT NULL,
+ col_varchar_10_utf8_key varchar(1024) CHARACTER SET utf8 DEFAULT NULL,
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) DEFAULT NULL,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t5 VALUES ('k','a','z',1,2),('x','a','w',2,7);
+
+CREATE TABLE t6 (
+ col_int int(11) DEFAULT NULL,
+ col_int_key int(11) DEFAULT NULL
+);
+INSERT INTO t6 VALUES (6,1),(8,3);
+
+SELECT
+ table3.col_int AS field1,
+ table1.col_int AS field2,
+ table1.col_int_key AS field3,
+ table1.pk AS field4,
+ table1.col_int AS field5,
+ table2.col_int AS field6
+FROM
+ t1 AS table1
+ LEFT OUTER JOIN
+ t4 AS table2
+ LEFT JOIN t6 AS table3
+ RIGHT JOIN t3 AS table4
+ LEFT JOIN t5 AS table5 ON table4.pk = table5.pk
+ LEFT JOIN t0 AS table6 ON table5.col_int_key = table6.pk
+ ON table3.col_int_key = table5.pk
+ ON table2.col_varchar_1024_latin1_key = table5.col_varchar_10_utf8_key
+ LEFT JOIN t6 AS table7 ON table2.pk = table7.col_int
+ ON table1.col_varchar_10_latin1 = table5.col_varchar_1024_latin1_key
+ LEFT JOIN t2 AS table8 ON table3.col_int = table8.col_int
+WHERE
+ table1.col_int_key < table2.pk
+HAVING
+ field4 != 6;
+
+drop table t0,t1,t2,t3,t4,t5,t6;
=== modified file 'mysql-test/t/trigger.test'
--- a/mysql-test/t/trigger.test 2009-06-22 12:51:33 +0000
+++ b/mysql-test/t/trigger.test 2010-01-12 08:19:48 +0000
@@ -1767,68 +1767,6 @@ drop table t1, t2, t3;
disconnect addconroot1;
disconnect addconroot2;
disconnect addconwithoutdb;
-#
-# Bug #26162: Trigger DML ignores low_priority_updates setting
-#
-CREATE TABLE t1 (id INTEGER);
-CREATE TABLE t2 (id INTEGER);
-
-INSERT INTO t2 VALUES (1),(2);
-
-# trigger that produces the high priority insert, but should be low, adding
-# LOW_PRIORITY fixes this
-CREATE TRIGGER t1_test AFTER INSERT ON t1 FOR EACH ROW
- INSERT INTO t2 VALUES (new.id);
-
-CONNECT (rl_holder, localhost, root,,);
-CONNECT (rl_acquirer, localhost, root,,);
-CONNECT (wl_acquirer, localhost, root,,);
-CONNECT (rl_contender, localhost, root,,);
-
-CONNECTION rl_holder;
-SELECT GET_LOCK('B26162',120);
-
-CONNECTION rl_acquirer;
---send
-SELECT 'rl_acquirer', GET_LOCK('B26162',120), id FROM t2 WHERE id = 1;
-
-CONNECTION wl_acquirer;
-SET SESSION LOW_PRIORITY_UPDATES=1;
-SET GLOBAL LOW_PRIORITY_UPDATES=1;
-#need to wait for rl_acquirer to lock on the B26162 lock
-sleep 2;
---send
-INSERT INTO t1 VALUES (5);
-
-CONNECTION rl_contender;
-# must not "see" the row inserted by the INSERT (as it must run before the
-# INSERT)
---send
-SELECT 'rl_contender', id FROM t2 WHERE id > 1;
-
-CONNECTION rl_holder;
-#need to wait for wl_acquirer and rl_contender to lock on t2
-sleep 2;
-SELECT RELEASE_LOCK('B26162');
-
-CONNECTION rl_acquirer;
---reap
-SELECT RELEASE_LOCK('B26162');
-CONNECTION wl_acquirer;
---reap
-CONNECTION rl_contender;
---reap
-
-CONNECTION default;
-DISCONNECT rl_acquirer;
-DISCONNECT wl_acquirer;
-DISCONNECT rl_contender;
-DISCONNECT rl_holder;
-
-DROP TRIGGER t1_test;
-DROP TABLE t1,t2;
-SET SESSION LOW_PRIORITY_UPDATES=DEFAULT;
-SET GLOBAL LOW_PRIORITY_UPDATES=DEFAULT;
--echo
--echo Bug#28502 Triggers that update another innodb table will block
--echo on X lock unnecessarily
=== modified file 'mysql-test/t/trigger_notembedded.test'
--- a/mysql-test/t/trigger_notembedded.test 2009-06-25 10:52:50 +0000
+++ b/mysql-test/t/trigger_notembedded.test 2010-01-12 08:19:48 +0000
@@ -875,6 +875,79 @@ DROP TABLE t1;
DROP DATABASE mysqltest_db1;
USE test;
+#
+# Bug #26162: Trigger DML ignores low_priority_updates setting
+#
+CREATE TABLE t1 (id INTEGER);
+CREATE TABLE t2 (id INTEGER);
+
+INSERT INTO t2 VALUES (1),(2);
+
+# trigger that produces the high priority insert, but should be low, adding
+# LOW_PRIORITY fixes this
+CREATE TRIGGER t1_test AFTER INSERT ON t1 FOR EACH ROW
+ INSERT INTO t2 VALUES (new.id);
+
+CONNECT (rl_holder, localhost, root,,);
+CONNECT (rl_acquirer, localhost, root,,);
+CONNECT (wl_acquirer, localhost, root,,);
+CONNECT (rl_contender, localhost, root,,);
+
+CONNECTION rl_holder;
+SELECT GET_LOCK('B26162',120);
+
+CONNECTION rl_acquirer;
+let $rl_acquirer_thread_id = `SELECT @@pseudo_thread_id`;
+--send
+SELECT 'rl_acquirer', GET_LOCK('B26162',120), id FROM t2 WHERE id = 1;
+
+CONNECTION wl_acquirer;
+let $wl_acquirer_thread_id = `SELECT @@pseudo_thread_id`;
+SET SESSION LOW_PRIORITY_UPDATES=1;
+SET GLOBAL LOW_PRIORITY_UPDATES=1;
+#need to wait for rl_acquirer to lock on the B26162 lock
+let $wait_condition=
+ SELECT STATE = 'User lock' FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE ID = $rl_acquirer_thread_id;
+--source include/wait_condition.inc
+--send
+INSERT INTO t1 VALUES (5);
+
+CONNECTION rl_contender;
+# Wait until wl_acquirer is waiting for the read lock on t2 to be released.
+let $wait_condition=
+ SELECT STATE = 'Locked' FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE ID = $wl_acquirer_thread_id;
+--source include/wait_condition.inc
+# must not "see" the row inserted by the INSERT (as it must run before the
+# INSERT)
+--send
+SELECT 'rl_contender', id FROM t2 WHERE id > 1;
+
+CONNECTION rl_holder;
+#need to wait for wl_acquirer and rl_contender to lock on t2
+sleep 2;
+SELECT RELEASE_LOCK('B26162');
+
+CONNECTION rl_acquirer;
+--reap
+SELECT RELEASE_LOCK('B26162');
+CONNECTION wl_acquirer;
+--reap
+CONNECTION rl_contender;
+--reap
+
+CONNECTION default;
+DISCONNECT rl_acquirer;
+DISCONNECT wl_acquirer;
+DISCONNECT rl_contender;
+DISCONNECT rl_holder;
+
+DROP TRIGGER t1_test;
+DROP TABLE t1,t2;
+SET SESSION LOW_PRIORITY_UPDATES=DEFAULT;
+SET GLOBAL LOW_PRIORITY_UPDATES=DEFAULT;
+
--echo End of 5.0 tests.
#
=== modified file 'mysql-test/t/type_newdecimal.test'
--- a/mysql-test/t/type_newdecimal.test 2009-11-02 11:21:39 +0000
+++ b/mysql-test/t/type_newdecimal.test 2009-12-08 09:26:11 +0000
@@ -1286,3 +1286,229 @@ CREATE TABLE t1 SELECT 1 % .123456789123
DESCRIBE t1;
SELECT my_col FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # Bug#45261: Crash, stored procedure + decimal
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 SELECT
+ /* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ /* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ /* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ /* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ /* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ /* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ /* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ .100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ /* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ /* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ /* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT
+ .123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
+ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # Test that the integer and decimal parts are properly calculated.
+--echo #
+
+CREATE TABLE t1 (a DECIMAL(30,30));
+INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
+CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
+DESC t2;
+DROP TABLE t1,t2;
+
+CREATE TABLE t1 (a DECIMAL(30,30));
+INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
+CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
+DESC t2;
+DROP TABLE t1,t2;
+
+CREATE TABLE t1 (a DECIMAL(30,30));
+INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
+CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
+DESC t2;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Test that variables get maximum precision.
+--echo #
+
+SET @decimal= 1.1;
+CREATE TABLE t1 SELECT @decimal AS c1;
+DESC t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug #45261 : Crash, stored procedure + decimal
+--echo # Original test by the reporter.
+--echo #
+
+--echo # should not crash
+CREATE TABLE t1
+SELECT .123456789012345678901234567890123456789012345678901234567890123456 AS a;
+DROP TABLE t1;
+
+delimiter |;
+CREATE PROCEDURE test_proc()
+BEGIN
+ # The las non critical CUSER definition is:
+ # DECLARE mycursor CURSOR FOR SELECT 1 %
+ # .12345678912345678912345678912345678912345678912345678912345678912 AS my_col;
+ DECLARE mycursor CURSOR FOR
+SELECT 1 %
+.123456789123456789123456789123456789123456789123456789123456789123456789123456789
+ AS my_col;
+
+ OPEN mycursor;
+ CLOSE mycursor;
+END|
+delimiter ;|
+--echo # should not crash
+CALL test_proc();
+DROP PROCEDURE test_proc;
+
+--echo #
+--echo # Bug #48370 Absolutely wrong calculations with GROUP BY and
+--echo # decimal fields when using IF
+--echo #
+
+CREATE TABLE currencies (id int, rate decimal(16,4),
+ PRIMARY KEY (id), KEY (rate));
+
+INSERT INTO currencies VALUES (11,0.7028);
+INSERT INTO currencies VALUES (1,1);
+
+CREATE TABLE payments (
+ id int,
+ supplier_id int,
+ status int,
+ currency_id int,
+ vat decimal(7,4),
+ PRIMARY KEY (id),
+ KEY currency_id (currency_id),
+ KEY supplier_id (supplier_id)
+);
+
+INSERT INTO payments (id,status,vat,supplier_id,currency_id) VALUES
+(3001,2,0.0000,344,11), (1,2,0.0000,1,1);
+
+CREATE TABLE sub_tasks (
+ id int,
+ currency_id int,
+ price decimal(16,4),
+ discount decimal(10,4),
+ payment_id int,
+ PRIMARY KEY (id),
+ KEY currency_id (currency_id),
+ KEY payment_id (payment_id)
+) ;
+
+INSERT INTO sub_tasks (id, price, discount, payment_id, currency_id) VALUES
+(52, 12.60, 0, 3001, 11), (56, 14.58, 0, 3001, 11);
+
+--echo # should return 1 and the same values in col 2 and 3
+select STRAIGHT_JOIN
+ (1 + PAY.vat) AS mult,
+ SUM(ROUND((SUB.price - ROUND(ROUND(SUB.price, 2) * SUB.discount, 2)) *
+ CUR.rate / CUR.rate, 2)
+ ) v_net_with_discount,
+
+ SUM(ROUND((SUB.price - ROUND(ROUND(SUB.price, 2) * SUB.discount, 1)) *
+ CUR.rate / CUR.rate , 2)
+ * (1 + PAY.vat)
+ ) v_total
+from
+ currencies CUR, payments PAY, sub_tasks SUB
+where
+ SUB.payment_id = PAY.id and
+ PAY.currency_id = CUR.id and
+ PAY.id > 2
+group by PAY.id + 1;
+
+DROP TABLE currencies, payments, sub_tasks;
+
+
+--echo End of 5.1 tests
=== modified file 'mysql-test/t/type_year.test'
--- a/mysql-test/t/type_year.test 2007-03-29 04:08:30 +0000
+++ b/mysql-test/t/type_year.test 2010-01-13 10:28:42 +0000
@@ -30,3 +30,109 @@ select * from t1;
drop table t1;
--echo End of 5.0 tests
+
+--echo #
+--echo # Bug #49480: WHERE using YEAR columns returns unexpected results
+--echo #
+
+CREATE TABLE t2(yy YEAR(2), c2 CHAR(4));
+CREATE TABLE t4(yyyy YEAR(4), c4 CHAR(4));
+
+INSERT INTO t2 (c2) VALUES (NULL),(1970),(1999),(2000),(2001),(2069);
+INSERT INTO t4 (c4) SELECT c2 FROM t2;
+UPDATE t2 SET yy = c2;
+UPDATE t4 SET yyyy = c4;
+
+SELECT * FROM t2;
+SELECT * FROM t4;
+
+--echo # Comparison of YEAR(2) with YEAR(4)
+
+SELECT * FROM t2, t4 WHERE yy = yyyy;
+SELECT * FROM t2, t4 WHERE yy <=> yyyy;
+SELECT * FROM t2, t4 WHERE yy < yyyy;
+SELECT * FROM t2, t4 WHERE yy > yyyy;
+
+--echo # Comparison of YEAR(2) with YEAR(2)
+
+SELECT * FROM t2 a, t2 b WHERE a.yy = b.yy;
+SELECT * FROM t2 a, t2 b WHERE a.yy <=> b.yy;
+SELECT * FROM t2 a, t2 b WHERE a.yy < b.yy;
+
+--echo # Comparison of YEAR(4) with YEAR(4)
+
+SELECT * FROM t4 a, t4 b WHERE a.yyyy = b.yyyy;
+SELECT * FROM t4 a, t4 b WHERE a.yyyy <=> b.yyyy;
+SELECT * FROM t4 a, t4 b WHERE a.yyyy < b.yyyy;
+
+--echo # Comparison with constants:
+
+SELECT * FROM t2 WHERE yy = NULL;
+SELECT * FROM t4 WHERE yyyy = NULL;
+SELECT * FROM t2 WHERE yy <=> NULL;
+SELECT * FROM t4 WHERE yyyy <=> NULL;
+SELECT * FROM t2 WHERE yy < NULL;
+SELECT * FROM t2 WHERE yy > NULL;
+
+SELECT * FROM t2 WHERE yy = NOW();
+SELECT * FROM t4 WHERE yyyy = NOW();
+
+SELECT * FROM t2 WHERE yy = 99;
+SELECT * FROM t2 WHERE 99 = yy;
+SELECT * FROM t4 WHERE yyyy = 99;
+
+SELECT * FROM t2 WHERE yy = 'test';
+SELECT * FROM t4 WHERE yyyy = 'test';
+
+SELECT * FROM t2 WHERE yy = '1999';
+SELECT * FROM t4 WHERE yyyy = '1999';
+
+SELECT * FROM t2 WHERE yy = 1999;
+SELECT * FROM t4 WHERE yyyy = 1999;
+
+SELECT * FROM t2 WHERE yy = 1999.1;
+SELECT * FROM t4 WHERE yyyy = 1999.1;
+
+SELECT * FROM t2 WHERE yy = 1998.9;
+SELECT * FROM t4 WHERE yyyy = 1998.9;
+
+--echo # Coverage tests for YEAR with zero/2000 constants:
+
+SELECT * FROM t2 WHERE yy = 0;
+SELECT * FROM t2 WHERE yy = '0';
+SELECT * FROM t2 WHERE yy = '0000';
+SELECT * FROM t2 WHERE yy = '2000';
+SELECT * FROM t2 WHERE yy = 2000;
+
+SELECT * FROM t4 WHERE yyyy = 0;
+SELECT * FROM t4 WHERE yyyy = '0';
+SELECT * FROM t4 WHERE yyyy = '0000';
+SELECT * FROM t4 WHERE yyyy = '2000';
+SELECT * FROM t4 WHERE yyyy = 2000;
+
+--echo # Comparison with constants those are out of YEAR range
+--echo # (coverage test for backward compatibility)
+
+SELECT COUNT(yy) FROM t2;
+SELECT COUNT(yyyy) FROM t4;
+
+SELECT COUNT(*) FROM t2 WHERE yy = -1;
+SELECT COUNT(*) FROM t4 WHERE yyyy > -1;
+SELECT COUNT(*) FROM t2 WHERE yy > -1000000000000000000;
+SELECT COUNT(*) FROM t4 WHERE yyyy > -1000000000000000000;
+
+SELECT COUNT(*) FROM t2 WHERE yy < 2156;
+SELECT COUNT(*) FROM t4 WHERE yyyy < 2156;
+SELECT COUNT(*) FROM t2 WHERE yy < 1000000000000000000;
+SELECT COUNT(*) FROM t4 WHERE yyyy < 1000000000000000000;
+
+SELECT * FROM t2 WHERE yy < 123;
+SELECT * FROM t2 WHERE yy > 123;
+SELECT * FROM t4 WHERE yyyy < 123;
+SELECT * FROM t4 WHERE yyyy > 123;
+
+DROP TABLE t2, t4;
+
+--echo #
+
+--echo End of 5.1 tests
=== modified file 'mysql-test/t/udf.test'
--- a/mysql-test/t/udf.test 2009-09-07 09:57:22 +0000
+++ b/mysql-test/t/udf.test 2010-01-22 21:19:21 +0000
@@ -56,9 +56,9 @@ select reverse_lookup();
--disable_result_log
select reverse_lookup("127.0.0.1");
select reverse_lookup(127,0,0,1);
+select reverse_lookup("localhost");
--enable_result_log
-select reverse_lookup("localhost");
--error ER_CANT_INITIALIZE_UDF
select avgcost();
--error ER_CANT_INITIALIZE_UDF
@@ -342,29 +342,6 @@ drop function myfunc_double;
drop function myfunc_int;
#
-# Bug #28921: Queries containing UDF functions are cached
-#
-
---replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
-eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
-create table t1 (a char);
-
-set GLOBAL query_cache_size=1355776;
-reset query cache;
-
-select metaphon('MySQL') from t1;
-show status like "Qcache_hits";
-show status like "Qcache_queries_in_cache";
-
-select metaphon('MySQL') from t1;
-show status like "Qcache_hits";
-show status like "Qcache_queries_in_cache";
-
-drop table t1;
-drop function metaphon;
-set GLOBAL query_cache_size=default;
-
-#
# Bug#28318 CREATE FUNCTION (UDF) requires a schema
#
=== added file 'mysql-test/t/udf_query_cache-master.opt'
--- a/mysql-test/t/udf_query_cache-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/udf_query_cache-master.opt 2010-01-11 13:15:28 +0000
@@ -0,0 +1 @@
+$UDF_EXAMPLE_LIB_OPT
=== added file 'mysql-test/t/udf_query_cache.test'
--- a/mysql-test/t/udf_query_cache.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/udf_query_cache.test 2010-01-11 13:15:28 +0000
@@ -0,0 +1,35 @@
+--source include/have_udf.inc
+--source include/have_query_cache.inc
+#
+# To run this tests the "sql/udf_example.c" need to be compiled into
+# udf_example.so and LD_LIBRARY_PATH should be setup to point out where
+# the library are.
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+#
+# Bug #28921: Queries containing UDF functions are cached
+#
+
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
+create table t1 (a char);
+
+set GLOBAL query_cache_size=1355776;
+reset query cache;
+
+select metaphon('MySQL') from t1;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select metaphon('MySQL') from t1;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+drop table t1;
+drop function metaphon;
+set GLOBAL query_cache_size=default;
+
=== modified file 'mysql-test/t/union.test'
--- a/mysql-test/t/union.test 2009-05-15 07:11:07 +0000
+++ b/mysql-test/t/union.test 2010-01-06 10:24:51 +0000
@@ -1102,3 +1102,58 @@ DROP TABLE t1;
--echo End of 5.0 tests
+
+
+--echo #
+--echo # Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY
+--echo # <any non-const-function>
+--echo #
+
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+
+--echo # Should not crash
+EXPLAIN EXTENDED
+SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12;
+
+--echo # Should not crash
+SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12;
+
+
+--echo # Should not crash
+--error ER_CANT_USE_OPTION_HERE
+EXPLAIN EXTENDED
+SELECT * FROM t1 UNION SELECT * FROM t1
+ ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
+
+--echo # Should not crash
+--error ER_CANT_USE_OPTION_HERE
+SELECT * FROM t1 UNION SELECT * FROM t1
+ ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
+
+--echo # Should not crash
+(SELECT * FROM t1) UNION (SELECT * FROM t1)
+ ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
+
+
+--echo # Should not crash
+EXPLAIN EXTENDED
+SELECT * FROM t1 UNION SELECT * FROM t1
+ ORDER BY (SELECT a FROM t2 WHERE b = 12);
+
+--echo # Should not crash
+--disable_result_log
+SELECT * FROM t1 UNION SELECT * FROM t1
+ ORDER BY (SELECT a FROM t2 WHERE b = 12);
+--enable_result_log
+
+--echo # Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+
+DROP TABLE t1,t2;
+
+
+--echo End of 5.1 tests
=== modified file 'mysql-test/t/user_var.test'
--- a/mysql-test/t/user_var.test 2009-05-15 13:03:22 +0000
+++ b/mysql-test/t/user_var.test 2009-12-22 10:38:33 +0000
@@ -295,6 +295,26 @@ SELECT @a, @b;
SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b;
DROP TABLE t1;
+#
+# Bug#47371: reference by same column name
+#
+CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL);
+CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11));
+CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL);
+
+INSERT INTO t1 VALUES(10, 10);
+INSERT INTO t1 VALUES(10, 10);
+INSERT INTO t2 VALUES(10, 10, 10);
+INSERT INTO t2 VALUES(10, 10, 10);
+INSERT INTO t3 VALUES(10, 10);
+INSERT INTO t3 VALUES(10, 10);
+
+SELECT MIN(t2.f1),
+@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo)
+FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1;
+
+DROP TABLE t1, t2, t3;
+
--echo End of 5.0 tests
#
=== modified file 'mysql-test/t/variables.test'
--- a/mysql-test/t/variables.test 2009-09-07 20:50:10 +0000
+++ b/mysql-test/t/variables.test 2010-03-04 08:03:07 +0000
@@ -28,8 +28,6 @@ set @my_myisam_max_sort_file_size =@@glo
set @my_net_buffer_length =@@global.net_buffer_length;
set @my_net_write_timeout =@@global.net_write_timeout;
set @my_net_read_timeout =@@global.net_read_timeout;
-set @my_query_cache_limit =@@global.query_cache_limit;
-set @my_query_cache_type =@@global.query_cache_type;
set @my_rpl_recovery_rank =@@global.rpl_recovery_rank;
set @my_server_id =@@global.server_id;
set @my_slow_launch_time =@@global.slow_launch_time;
@@ -138,7 +136,6 @@ show local variables like 'storage_engin
select * from information_schema.session_variables where variable_name like 'storage_engine';
show global variables like 'storage_engine';
select * from information_schema.global_variables where variable_name like 'storage_engine';
-set GLOBAL query_cache_size=100000;
set GLOBAL myisam_max_sort_file_size=2000000;
show global variables like 'myisam_max_sort_file_size';
@@ -255,8 +252,6 @@ set storage_engine=UNKNOWN_TABLE_TYPE;
--error ER_WRONG_VALUE_FOR_VAR
set storage_engine=MERGE, big_tables=2;
show local variables like 'storage_engine';
---error ER_GLOBAL_VARIABLE
-set SESSION query_cache_size=10000;
--error ER_NO_DEFAULT
set GLOBAL storage_engine=DEFAULT;
--error ER_UNKNOWN_CHARACTER_SET
@@ -334,9 +329,6 @@ set myisam_sort_buffer_size=100;
set global net_buffer_length=100;
set net_read_timeout=100;
set net_write_timeout=100;
-set global query_cache_limit=100;
-set global query_cache_size=100;
-set global query_cache_type=demand;
set read_buffer_size=100;
set read_rnd_buffer_size=100;
set global rpl_recovery_rank=100;
@@ -780,6 +772,12 @@ set @@hostname= "anothername";
--replace_column 2 #
show variables like 'hostname';
+--echo #
+--echo # BUG#37408 - Compressed MyISAM files should not require/use mmap()
+--echo #
+--echo # Test 'myisam_mmap_size' option is not dynamic
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@myisam_mmap_size= 500M;
--echo End of 5.0 tests
#
@@ -822,8 +820,6 @@ set global myisam_max_sort_file_size =@m
set global net_buffer_length =@my_net_buffer_length;
set global net_write_timeout =@my_net_write_timeout;
set global net_read_timeout =@my_net_read_timeout;
-set global query_cache_limit =@my_query_cache_limit;
-set global query_cache_type =@my_query_cache_type;
set global rpl_recovery_rank =@my_rpl_recovery_rank;
set global server_id =@my_server_id;
set global slow_launch_time =@my_slow_launch_time;
=== modified file 'mysql-test/t/view.test'
--- a/mysql-test/t/view.test 2009-10-15 21:38:29 +0000
+++ b/mysql-test/t/view.test 2010-02-10 19:06:24 +0000
@@ -87,7 +87,7 @@ explain extended select c from v6;
# show table/table status test
show tables;
show full tables;
---replace_column 8 # 12 # 13 #
+--replace_column 8 # 12 # 13 # 14 #
show table status;
drop view v1,v2,v3,v4,v5,v6;
=== modified file 'mysql-test/valgrind.supp'
--- a/mysql-test/valgrind.supp 2009-12-03 11:19:05 +0000
+++ b/mysql-test/valgrind.supp 2010-03-10 09:11:02 +0000
@@ -469,6 +469,26 @@
}
{
+ dlclose memory loss from plugin variant 8
+ Memcheck:Leak
+ fun:calloc
+ fun:_dlerror_run
+ fun:dlclose
+ fun:_Z15free_plugin_memP12st_plugin_dl
+ fun:_Z13plugin_dl_delPK19st_mysql_lex_string
+}
+
+{
+ dlclose memory loss from plugin variant 9
+ Memcheck:Leak
+ fun:calloc
+ fun:_dlerror_run
+ fun:dlclose
+ fun:_ZL15free_plugin_memP12st_plugin_dl
+ fun:_ZL13plugin_dl_delPK19st_mysql_lex_string
+}
+
+{
dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 32/64 bit ver 1
Memcheck:Leak
fun:*alloc
@@ -991,3 +1011,15 @@
fun:_dl_allocate_tls
fun:pthread_create*
}
+
+#
+# Bug in Glibc 2.9: http://sourceware.org/bugzilla/show_bug.cgi?id=10391
+# Fixed in latest Glibc, but suppressed here for running tests on hosts
+# with older Glibc version.
+#
+{
+ Glibc bug in __libc_res_nsend
+ Memcheck:Cond
+ fun:__libc_res_nsend
+ fun:__libc_res_nquery
+}
=== modified file 'mysys/charset.c'
--- a/mysys/charset.c 2009-09-07 20:50:10 +0000
+++ b/mysys/charset.c 2010-03-04 08:03:07 +0000
@@ -220,7 +220,8 @@ copy_uca_collation(CHARSET_INFO *to, CHA
static int add_collation(CHARSET_INFO *cs)
{
if (cs->name && (cs->number ||
- (cs->number=get_collation_number_internal(cs->name))))
+ (cs->number=get_collation_number_internal(cs->name))) &&
+ cs->number < array_elements(all_charsets))
{
if (!all_charsets[cs->number])
{
@@ -324,7 +325,6 @@ static int add_collation(CHARSET_INFO *c
#define MY_CHARSET_INDEX "Index.xml"
const char *charsets_dir= NULL;
-static int charset_initialized=0;
static my_bool my_read_charset_file(const char *filename, myf myflags)
@@ -402,63 +402,37 @@ static void *cs_alloc(size_t size)
}
-#ifdef __NETWARE__
-my_bool STDCALL init_available_charsets(myf myflags)
-#else
-static my_bool init_available_charsets(myf myflags)
-#endif
+static my_pthread_once_t charsets_initialized= MY_PTHREAD_ONCE_INIT;
+
+static void init_available_charsets(void)
{
char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
- my_bool error=FALSE;
- /*
- We have to use charset_initialized to not lock on THR_LOCK_charset
- inside get_internal_charset...
- */
- if (!charset_initialized)
+ CHARSET_INFO **cs;
+
+ bzero(&all_charsets,sizeof(all_charsets));
+ init_compiled_charsets(MYF(0));
+
+ /* Copy compiled charsets */
+ for (cs=all_charsets;
+ cs < all_charsets+array_elements(all_charsets)-1 ;
+ cs++)
{
- CHARSET_INFO **cs;
- /*
- To make things thread safe we are not allowing other threads to interfere
- while we may changing the cs_info_table
- */
- pthread_mutex_lock(&THR_LOCK_charset);
- if (!charset_initialized)
+ if (*cs)
{
- bzero(&all_charsets,sizeof(all_charsets));
- init_compiled_charsets(myflags);
-
- /* Copy compiled charsets */
- for (cs=all_charsets;
- cs < all_charsets+array_elements(all_charsets)-1 ;
- cs++)
- {
- if (*cs)
- {
- if (cs[0]->ctype)
- if (init_state_maps(*cs))
- *cs= NULL;
- }
- }
-
- strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
- error= my_read_charset_file(fname,myflags);
- charset_initialized=1;
+ if (cs[0]->ctype)
+ if (init_state_maps(*cs))
+ *cs= NULL;
}
- pthread_mutex_unlock(&THR_LOCK_charset);
}
- return error;
-}
-
-
-void free_charsets(void)
-{
- charset_initialized=0;
+
+ strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
+ my_read_charset_file(fname, MYF(0));
}
uint get_collation_number(const char *name)
{
- init_available_charsets(MYF(0));
+ my_pthread_once(&charsets_initialized, init_available_charsets);
return get_collation_number_internal(name);
}
@@ -466,7 +440,7 @@ uint get_collation_number(const char *na
uint get_charset_number(const char *charset_name, uint cs_flags)
{
CHARSET_INFO **cs;
- init_available_charsets(MYF(0));
+ my_pthread_once(&charsets_initialized, init_available_charsets);
for (cs= all_charsets;
cs < all_charsets+array_elements(all_charsets)-1 ;
@@ -483,7 +457,7 @@ uint get_charset_number(const char *char
const char *get_charset_name(uint charset_number)
{
CHARSET_INFO *cs;
- init_available_charsets(MYF(0));
+ my_pthread_once(&charsets_initialized, init_available_charsets);
cs=all_charsets[charset_number];
if (cs && (cs->number == charset_number) && cs->name )
@@ -541,7 +515,7 @@ CHARSET_INFO *get_charset(uint cs_number
if (cs_number == default_charset_info->number)
return default_charset_info;
- (void) init_available_charsets(MYF(0)); /* If it isn't initialized */
+ my_pthread_once(&charsets_initialized, init_available_charsets);
if (!cs_number || cs_number >= array_elements(all_charsets)-1)
return NULL;
@@ -563,7 +537,7 @@ CHARSET_INFO *get_charset_by_name(const
{
uint cs_number;
CHARSET_INFO *cs;
- (void) init_available_charsets(MYF(0)); /* If it isn't initialized */
+ my_pthread_once(&charsets_initialized, init_available_charsets);
cs_number=get_collation_number(cs_name);
cs= cs_number ? get_internal_charset(cs_number,flags) : NULL;
@@ -588,7 +562,7 @@ CHARSET_INFO *get_charset_by_csname(cons
DBUG_ENTER("get_charset_by_csname");
DBUG_PRINT("enter",("name: '%s'", cs_name));
- (void) init_available_charsets(MYF(0)); /* If it isn't initialized */
+ my_pthread_once(&charsets_initialized, init_available_charsets);
cs_number= get_charset_number(cs_name, cs_flags);
cs= cs_number ? get_internal_charset(cs_number, flags) : NULL;
=== modified file 'mysys/default.c'
--- a/mysys/default.c 2009-03-24 13:58:52 +0000
+++ b/mysys/default.c 2009-12-18 18:44:24 +0000
@@ -650,7 +650,7 @@ static int search_default_file_with_ext(
int recursion_level)
{
char name[FN_REFLEN + 10], buff[4096], curr_gr[4096], *ptr, *end, **tmp_ext;
- char *value, option[4096], tmp[FN_REFLEN];
+ char *value, option[4096+2], tmp[FN_REFLEN];
static const char includedir_keyword[]= "includedir";
static const char include_keyword[]= "include";
const int max_recursion_level= 10;
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2009-12-03 11:19:05 +0000
+++ b/mysys/mf_keycache.c 2010-03-30 12:36:49 +0000
@@ -3924,6 +3924,12 @@ restart:
uint next_status;
uint hash_requests;
+ LINT_INIT(next_hash_link);
+ LINT_INIT(next_diskpos);
+ LINT_INIT(next_file);
+ LINT_INIT(next_status);
+ LINT_INIT(hash_requests);
+
total_found++;
found++;
KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used);
=== modified file 'mysys/mf_pack.c'
--- a/mysys/mf_pack.c 2009-08-28 16:21:54 +0000
+++ b/mysys/mf_pack.c 2009-12-18 18:44:24 +0000
@@ -245,7 +245,7 @@ my_bool my_use_symdir=0; /* Set this if
#ifdef USE_SYMDIR
void symdirget(char *dir)
{
- char buff[FN_REFLEN];
+ char buff[FN_REFLEN+1];
char *pos=strend(dir);
if (dir[0] && pos[-1] != FN_DEVCHAR && my_access(dir, F_OK))
{
@@ -257,7 +257,7 @@ void symdirget(char *dir)
*pos++=temp; *pos=0; /* Restore old filename */
if (file >= 0)
{
- if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0)
+ if ((length= my_read(file, buff, sizeof(buff) - 1, MYF(0))) > 0)
{
for (pos= buff + length ;
pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
=== modified file 'mysys/my_file.c'
--- a/mysys/my_file.c 2006-12-23 19:20:40 +0000
+++ b/mysys/my_file.c 2010-01-28 11:35:10 +0000
@@ -51,7 +51,7 @@ static uint set_max_open_files(uint max_
DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u",
(uint) rlimit.rlim_cur,
(uint) rlimit.rlim_max));
- if (rlimit.rlim_cur == RLIM_INFINITY)
+ if ((ulonglong) rlimit.rlim_cur == (ulonglong) RLIM_INFINITY)
rlimit.rlim_cur = max_file_limit;
if (rlimit.rlim_cur >= max_file_limit)
DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */
=== modified file 'mysys/my_gethostbyname.c'
--- a/mysys/my_gethostbyname.c 2006-12-31 00:32:21 +0000
+++ b/mysys/my_gethostbyname.c 2010-03-30 12:36:49 +0000
@@ -91,9 +91,12 @@ extern pthread_mutex_t LOCK_gethostbynam
is finished with the structure.
*/
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
+struct hostent *
+my_gethostbyname_r(const char *name,
+ struct hostent *result __attribute__((unused)),
+ char *buffer __attribute__((unused)),
+ int buflen__attribute__((unused)),
+ int *h_errnop)
{
struct hostent *hp;
pthread_mutex_lock(&LOCK_gethostbyname_r);
=== modified file 'mysys/my_getopt.c'
--- a/mysys/my_getopt.c 2009-12-03 11:19:05 +0000
+++ b/mysys/my_getopt.c 2010-03-04 08:03:07 +0000
@@ -145,6 +145,10 @@ int handle_options(int *argc, char ***ar
{ /* --set-variable, or -O */
if (*cur_arg == 'O')
{
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "%s: Option '-O' is deprecated. "
+ "Use --variable-name=value instead.",
+ my_progname);
must_be_var= 1;
if (!(*++cur_arg)) /* If not -Ovar=# */
@@ -164,6 +168,11 @@ int handle_options(int *argc, char ***ar
}
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
{
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "%s: Option '--set-variable' is deprecated. "
+ "Use --variable-name=value instead.",
+ my_progname);
+
must_be_var= 1;
if (cur_arg[13] == '=')
{
@@ -414,17 +423,11 @@ invalid value '%s'",
(optp->var_type & GET_TYPE_MASK) == GET_ENUM))
{
if (optend == disabled_my_option)
- if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
- *((my_bool*) value)= (my_bool) 0;
- else
- *((ulong*) value)= (ulong) 0;
+ init_one_value(optp, value, 0);
else
{
if (!optend) /* No argument -> enable option */
- if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
- *((my_bool*) value)= (my_bool) 1;
- else
- *((ulong*) value)= (ulong) 1;
+ init_one_value(optp, value, 1);
else
argument= optend;
}
=== modified file 'mysys/my_init.c'
--- a/mysys/my_init.c 2009-10-16 15:44:58 +0000
+++ b/mysys/my_init.c 2010-03-04 08:03:07 +0000
@@ -166,7 +166,6 @@ void my_end(int infoflag)
my_print_open_files();
}
}
- free_charsets();
my_error_unregister_all();
my_once_free();
#ifdef THREAD
=== modified file 'mysys/my_sync.c'
--- a/mysys/my_sync.c 2008-04-28 16:24:05 +0000
+++ b/mysys/my_sync.c 2010-03-09 19:22:24 +0000
@@ -17,6 +17,8 @@
#include "mysys_err.h"
#include <errno.h>
+ulong my_sync_count; /* Count number of sync calls */
+
/*
Sync data in file to disk
@@ -46,6 +48,7 @@ int my_sync(File fd, myf my_flags)
DBUG_ENTER("my_sync");
DBUG_PRINT("my",("fd: %d my_flags: %d", fd, my_flags));
+ statistic_increment(my_sync_count,&THR_LOCK_open);
do
{
#if defined(F_FULLFSYNC)
@@ -100,14 +103,15 @@ static const char cur_dir_name[]= {FN_CU
RETURN
0 if ok, !=0 if error
*/
-int my_sync_dir(const char *dir_name, myf my_flags)
+int my_sync_dir(const char *dir_name __attribute__((unused)),
+ myf my_flags __attribute__((unused)))
{
#ifdef NEED_EXPLICIT_SYNC_DIR
- DBUG_ENTER("my_sync_dir");
- DBUG_PRINT("my",("Dir: '%s' my_flags: %d", dir_name, my_flags));
File dir_fd;
int res= 0;
const char *correct_dir_name;
+ DBUG_ENTER("my_sync_dir");
+ DBUG_PRINT("my",("Dir: '%s' my_flags: %d", dir_name, my_flags));
/* Sometimes the path does not contain an explicit directory */
correct_dir_name= (dir_name[0] == 0) ? cur_dir_name : dir_name;
/*
@@ -141,7 +145,8 @@ int my_sync_dir(const char *dir_name, my
RETURN
0 if ok, !=0 if error
*/
-int my_sync_dir_by_file(const char *file_name, myf my_flags)
+int my_sync_dir_by_file(const char *file_name __attribute__((unused)),
+ myf my_flags __attribute__((unused)))
{
#ifdef NEED_EXPLICIT_SYNC_DIR
char dir_name[FN_REFLEN];
=== modified file 'mysys/my_thr_init.c'
--- a/mysys/my_thr_init.c 2009-12-03 11:19:05 +0000
+++ b/mysys/my_thr_init.c 2010-03-04 08:03:07 +0000
@@ -30,7 +30,9 @@ pthread_key(struct st_my_thread_var, THR
#endif /* USE_TLS */
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
- THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time;
+ THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time,
+ THR_LOCK_myisam_mmap;
+
pthread_cond_t THR_COND_threads;
uint THR_thread_count= 0;
uint my_thread_end_wait_time= 5;
@@ -156,6 +158,7 @@ my_bool my_thread_global_init(void)
pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW);
pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_SLOW);
+ pthread_mutex_init(&THR_LOCK_myisam_mmap,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST);
@@ -253,6 +256,7 @@ void my_thread_destroy_mutex(void)
pthread_mutex_destroy(&THR_LOCK_lock);
pthread_mutex_destroy(&THR_LOCK_isam);
pthread_mutex_destroy(&THR_LOCK_myisam);
+ pthread_mutex_destroy(&THR_LOCK_myisam_mmap);
pthread_mutex_destroy(&THR_LOCK_heap);
pthread_mutex_destroy(&THR_LOCK_net);
pthread_mutex_destroy(&THR_LOCK_time);
@@ -317,7 +321,7 @@ my_bool my_thread_init(void)
/*
Skip initialization if the thread specific variable is already initialized
*/
- if (THR_KEY_mysys.id)
+ if (THR_KEY_mysys.init)
goto end;
tmp= &THR_KEY_mysys;
#endif
=== modified file 'mysys/my_uuid.c'
--- a/mysys/my_uuid.c 2009-02-01 12:02:29 +0000
+++ b/mysys/my_uuid.c 2010-01-04 18:31:26 +0000
@@ -108,7 +108,7 @@ void my_uuid_init(ulong seed1, ulong see
*/
/* purecov: begin inspected */
my_rnd_init(&uuid_rand, (ulong) (seed2+ now/2), (ulong) (now+rand()));
- for (i=0; i < sizeof(mac); i++)
+ for (i=0; i < array_elements(uuid_suffix) -2 ; i++)
mac[i]= (uchar)(my_rnd(&uuid_rand)*255);
/* purecov: end */
}
=== modified file 'mysys/my_winthread.c'
--- a/mysys/my_winthread.c 2009-03-22 12:16:09 +0000
+++ b/mysys/my_winthread.c 2010-03-04 08:03:07 +0000
@@ -148,4 +148,36 @@ int win_pthread_setspecific(void *a,void
return 0;
}
+
+/*
+ One time initialization. For simplicity, we assume initializer thread
+ does not exit within init_routine().
+*/
+int my_pthread_once(my_pthread_once_t *once_control,
+ void (*init_routine)(void))
+{
+ LONG state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS,
+ MY_PTHREAD_ONCE_INIT);
+ switch(state)
+ {
+ case MY_PTHREAD_ONCE_INIT:
+ /* This is initializer thread */
+ (*init_routine)();
+ *once_control= MY_PTHREAD_ONCE_DONE;
+ break;
+
+ case MY_PTHREAD_ONCE_INPROGRESS:
+ /* init_routine in progress. Wait for its completion */
+ while(*once_control == MY_PTHREAD_ONCE_INPROGRESS)
+ {
+ Sleep(1);
+ }
+ break;
+ case MY_PTHREAD_ONCE_DONE:
+ /* Nothing to do */
+ break;
+ }
+ return 0;
+}
+
#endif
=== modified file 'mysys/stacktrace.c'
--- a/mysys/stacktrace.c 2008-09-16 13:23:07 +0000
+++ b/mysys/stacktrace.c 2010-01-27 10:42:20 +0000
@@ -63,7 +63,26 @@ void my_safe_print_str(const char* name,
fputc('\n', stderr);
}
-#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
+#if defined(HAVE_PRINTSTACK)
+
+/* Use Solaris' symbolic stack trace routine. */
+#include <ucontext.h>
+
+void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)),
+ ulong thread_stack __attribute__((unused)))
+{
+ if (printstack(fileno(stderr)) == -1)
+ fprintf(stderr, "Error when traversing the stack, stack appears corrupt.\n");
+ else
+ fprintf(stderr,
+ "Please read "
+ "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
+ "and follow instructions on how to resolve the stack trace.\n"
+ "Resolved stack trace is much more helpful in diagnosing the\n"
+ "problem, so please do resolve it\n");
+}
+
+#elif HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
#if BACKTRACE_DEMANGLE
=== modified file 'netware/libmysqlmain.c'
--- a/netware/libmysqlmain.c 2003-01-31 23:42:26 +0000
+++ b/netware/libmysqlmain.c 2009-12-12 18:11:25 +0000
@@ -18,7 +18,7 @@
#include "my_global.h"
-my_bool init_available_charsets(myf myflags);
+void init_available_charsets(void);
/* this function is required so that global memory is allocated against this
library nlm, and not against a paticular client */
@@ -31,7 +31,7 @@ int _NonAppStart(void *NLMHandle, void *
{
mysql_server_init(0, NULL, NULL);
- init_available_charsets(MYF(0));
+ init_available_charsets();
return 0;
}
=== modified file 'scripts/make_win_bin_dist'
--- a/scripts/make_win_bin_dist 2009-12-03 11:19:05 +0000
+++ b/scripts/make_win_bin_dist 2010-01-15 15:27:55 +0000
@@ -352,7 +352,7 @@ mkdir $DESTDIR/mysql-test
cp mysql-test/mysql-test-run.pl $DESTDIR/mysql-test/
cp mysql-test/mysql-stress-test.pl $DESTDIR/mysql-test/
cp mysql-test/README $DESTDIR/mysql-test/
-cp -R mysql-test/{t,r,include,suite,std_data,lib} $DESTDIR/mysql-test/
+cp -R mysql-test/{t,r,include,suite,std_data,lib,collections} $DESTDIR/mysql-test/
rm -rf $DESTDIR/mysql-test/lib/My/SafeProcess/my_safe_kill.{dir,vcproj}
rm -rf $DESTDIR/mysql-test/lib/My/SafeProcess/my_safe_process.{dir,vcproj}
=== modified file 'scripts/mysql_secure_installation.pl.in'
--- a/scripts/mysql_secure_installation.pl.in 2007-12-28 21:58:54 +0000
+++ b/scripts/mysql_secure_installation.pl.in 2009-11-03 21:34:01 +0000
@@ -17,16 +17,41 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
use Fcntl;
+use File::Spec;
+use if $^O eq 'MSWin32', 'Term::ReadKey' => qw/ReadMode/;
use strict;
my $config = ".my.cnf.$$";
my $command = ".mysql.$$";
my $hadpass = 0;
+my $mysql; # How to call the mysql client
+my $rootpass = "";
-# FIXME
-# trap "interrupt" 2
-my $rootpass = "";
+$SIG{QUIT} = $SIG{INT} = sub {
+ print "\nAborting!\n\n";
+ echo_on();
+ cleanup();
+ exit 1;
+};
+
+
+END {
+ # Remove temporary files, even if exiting via die(), etc.
+ cleanup();
+}
+
+
+sub read_without_echo {
+ my ($prompt) = @_;
+ print $prompt;
+ echo_off();
+ my $answer = <STDIN>;
+ echo_on();
+ print "\n";
+ chomp($answer);
+ return $answer;
+}
sub echo_on {
if ($^O eq 'MSWin32') {
@@ -55,6 +80,25 @@ sub write_file {
}
sub prepare {
+ # Locate the mysql client; look in current directory first, then
+ # in path
+ our $SAVEERR; # Suppress Perl warning message
+ open SAVEERR, ">& STDERR";
+ close STDERR;
+ for my $m (File::Spec->catfile('bin', 'mysql'), 'mysql') {
+ # mysql --version should always work
+ qx($m --no-defaults --version);
+ next unless $? == 0;
+
+ $mysql = $m;
+ last;
+ }
+ open STDERR, ">& SAVEERR";
+
+ die "Can't find a 'mysql' client in PATH or ./bin\n"
+ unless $mysql;
+
+ # Create safe files to avoid leaking info to other users
foreach my $file ( $config, $command ) {
next if -f $file; # Already exists
local *FILE;
@@ -64,30 +108,50 @@ sub prepare {
}
}
+# Simple escape mechanism (\-escape any ' and \), suitable for two contexts:
+# - single-quoted SQL strings
+# - single-quoted option values on the right hand side of = in my.cnf
+#
+# These two contexts don't handle escapes identically. SQL strings allow
+# quoting any character (\C => C, for any C), but my.cnf parsing allows
+# quoting only \, ' or ". For example, password='a\b' quotes a 3-character
+# string in my.cnf, but a 2-character string in SQL.
+#
+# This simple escape works correctly in both places.
+sub basic_single_escape {
+ my ($str) = @_;
+ # Inside a character class, \ is not special; this escapes both \ and '
+ $str =~ s/([\'])/\\$1/g;
+ return $str;
+}
+
sub do_query {
my $query = shift;
write_file($command, $query);
- system("mysql --defaults-file=$config < $command");
- return $?;
+ my $rv = system("$mysql --defaults-file=$config < $command");
+ # system() returns -1 if exec fails (e.g., command not found, etc.); die
+ # in this case because nothing is going to work
+ die "Failed to execute mysql client '$mysql'\n" if $rv == -1;
+ # Return true if query executed OK, or false if there was some problem
+ # (for example, SQL error or wrong password)
+ return ($rv == 0 ? 1 : undef);
}
sub make_config {
my $password = shift;
+ my $esc_pass = basic_single_escape($rootpass);
write_file($config,
"# mysql_secure_installation config file",
"[mysql]",
"user=root",
- "password=$rootpass");
+ "password='$esc_pass'");
}
sub get_root_password {
- my $status = 1;
- while ( $status == 1 ) {
- echo_off();
- print "Enter current password for root (enter for none): ";
- my $password = <STDIN>;
- echo_on();
+ my $attempts = 3;
+ for (;;) {
+ my $password = read_without_echo("Enter current password for root (enter for none): ");
if ( $password ) {
$hadpass = 1;
} else {
@@ -95,64 +159,56 @@ sub get_root_password {
}
$rootpass = $password;
make_config($rootpass);
- do_query("");
- $status = $?;
+ last if do_query("");
+
+ die "Unable to connect to the server as root user, giving up.\n"
+ if --$attempts == 0;
}
print "OK, successfully used password, moving on...\n\n";
}
sub set_root_password {
- echo_off();
- print "New password: ";
- my $password1 = <STDIN>;
- print "\nRe-enter new password: ";
- my $password2 = <STDIN>;
- print "\n";
- echo_on();
-
- if ( $password1 eq $password2 ) {
- print "Sorry, passwords do not match.\n\n";
- return 1;
- }
+ my $password1;
+ for (;;) {
+ $password1 = read_without_echo("New password: ");
+
+ if ( !$password1 ) {
+ print "Sorry, you can't use an empty password here.\n\n";
+ next;
+ }
- if ( !$password1 ) {
- print "Sorry, you can't use an empty password here.\n\n";
- return 1;
- }
+ my $password2 = read_without_echo("Re-enter new password: ");
- do_query("UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';");
- if ( $? == 0 ) {
- print "Password updated successfully!\n";
- print "Reloading privilege tables..\n";
- if ( !reload_privilege_tables() ) {
- exit 1;
+ if ( $password1 ne $password2 ) {
+ print "Sorry, passwords do not match.\n\n";
+ next;
}
- print "\n";
- $rootpass = $password1;
- make_config($rootpass);
- } else {
- print "Password update failed!\n";
- exit 1;
+
+ last;
}
- return 0;
+ my $esc_pass = basic_single_escape($password1);
+ do_query("UPDATE mysql.user SET Password=PASSWORD('$esc_pass') WHERE User='root';")
+ or die "Password update failed!\n";
+
+ print "Password updated successfully!\n";
+ print "Reloading privilege tables..\n";
+ reload_privilege_tables()
+ or die "Can not continue.\n";
+
+ print "\n";
+ $rootpass = $password1;
+ make_config($rootpass);
}
sub remove_anonymous_users {
- do_query("DELETE FROM mysql.user WHERE User='';");
- if ( $? == 0 ) {
- print " ... Success!\n";
- } else {
- print " ... Failed!\n";
- exit 1;
- }
-
- return 0;
+ do_query("DELETE FROM mysql.user WHERE User='';")
+ or die print " ... Failed!\n";
+ print " ... Success!\n";
}
sub remove_remote_root {
- do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';");
- if ( $? == 0 ) {
+ if (do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';")) {
print " ... Success!\n";
} else {
print " ... Failed!\n";
@@ -161,44 +217,31 @@ sub remove_remote_root {
sub remove_test_database {
print " - Dropping test database...\n";
- do_query("DROP DATABASE test;");
- if ( $? == 0 ) {
+ if (do_query("DROP DATABASE test;")) {
print " ... Success!\n";
} else {
print " ... Failed! Not critical, keep moving...\n";
}
print " - Removing privileges on test database...\n";
- do_query("DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'");
- if ( $? == 0 ) {
+ if (do_query("DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'")) {
print " ... Success!\n";
} else {
print " ... Failed! Not critical, keep moving...\n";
}
-
- return 0;
}
sub reload_privilege_tables {
- do_query("FLUSH PRIVILEGES;");
- if ( $? == 0 ) {
+ if (do_query("FLUSH PRIVILEGES;")) {
print " ... Success!\n";
- return 0;
+ return 1;
} else {
print " ... Failed!\n";
- return 1;
+ return undef;
}
}
-sub interrupt {
- print "\nAborting!\n\n";
- cleanup();
- echo_on();
- exit 1;
-}
-
sub cleanup {
- print "Cleaning up...\n";
unlink($config,$command);
}
@@ -242,11 +285,7 @@ my $reply = <STDIN>;
if ( $reply =~ /n/i ) {
print " ... skipping.\n";
} else {
- my $status = 1;
- while ( $status == 1 ) {
- set_root_password();
- $status = $?;
- }
+ set_root_password();
}
print "\n";
@@ -334,8 +373,6 @@ if ( $reply =~ /n/i ) {
}
print "\n";
-cleanup();
-
print <<HERE;
=== modified file 'scripts/mysql_secure_installation.sh'
--- a/scripts/mysql_secure_installation.sh 2009-10-23 16:48:54 +0000
+++ b/scripts/mysql_secure_installation.sh 2010-01-15 15:27:55 +0000
@@ -189,16 +189,39 @@ prepare() {
}
do_query() {
- echo $1 >$command
+ echo "$1" >$command
+ #sed 's,^,> ,' < $command # Debugging
$bindir/mysql --defaults-file=$config <$command
return $?
}
+# Simple escape mechanism (\-escape any ' and \), suitable for two contexts:
+# - single-quoted SQL strings
+# - single-quoted option values on the right hand side of = in my.cnf
+#
+# These two contexts don't handle escapes identically. SQL strings allow
+# quoting any character (\C => C, for any C), but my.cnf parsing allows
+# quoting only \, ' or ". For example, password='a\b' quotes a 3-character
+# string in my.cnf, but a 2-character string in SQL.
+#
+# This simple escape works correctly in both places.
+basic_single_escape () {
+ # The quoting on this sed command is a bit complex. Single-quoted strings
+ # don't allow *any* escape mechanism, so they cannot contain a single
+ # quote. The string sed gets (as argv[1]) is: s/\(['\]\)/\\\1/g
+ #
+ # Inside a character class, \ and ' are not special, so the ['\] character
+ # class is balanced and contains two characters.
+ echo "$1" | sed 's/\(['"'"'\]\)/\\\1/g'
+}
+
make_config() {
echo "# mysql_secure_installation config file" >$config
echo "[mysql]" >>$config
echo "user=root" >>$config
- echo "password=$rootpass" >>$config
+ esc_pass=`basic_single_escape "$rootpass"`
+ echo "password='$esc_pass'" >>$config
+ #sed 's,^,> ,' < $config # Debugging
}
get_root_password() {
@@ -245,13 +268,12 @@ set_root_password() {
return 1
fi
- do_query "UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';"
+ esc_pass=`basic_single_escape "$password1"`
+ do_query "UPDATE mysql.user SET Password=PASSWORD('$esc_pass') WHERE User='root';"
if [ $? -eq 0 ]; then
echo "Password updated successfully!"
echo "Reloading privilege tables.."
- if ! reload_privilege_tables; then
- exit 1
- fi
+ reload_privilege_tables || exit 1
echo
rootpass=$password1
make_config
=== modified file 'scripts/mysql_system_tables_fix.sql'
--- a/scripts/mysql_system_tables_fix.sql 2009-10-27 10:09:36 +0000
+++ b/scripts/mysql_system_tables_fix.sql 2009-12-03 16:15:47 +0000
@@ -415,18 +415,48 @@ ALTER TABLE proc ADD character_set_clien
ALTER TABLE proc MODIFY character_set_client
char(32) collate utf8_bin DEFAULT NULL;
+SELECT CASE WHEN COUNT(*) > 0 THEN
+CONCAT ("WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (", @@character_set_client, "). Please verify if necessary.")
+ELSE NULL
+END
+AS value FROM proc WHERE character_set_client IS NULL;
+
+UPDATE proc SET character_set_client = @@character_set_client
+ WHERE character_set_client IS NULL;
+
ALTER TABLE proc ADD collation_connection
char(32) collate utf8_bin DEFAULT NULL
AFTER character_set_client;
ALTER TABLE proc MODIFY collation_connection
char(32) collate utf8_bin DEFAULT NULL;
+SELECT CASE WHEN COUNT(*) > 0 THEN
+CONCAT ("WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (", @@collation_connection, "). Please verify if necessary.")
+ELSE NULL
+END
+AS value FROM proc WHERE collation_connection IS NULL;
+
+UPDATE proc SET collation_connection = @@collation_connection
+ WHERE collation_connection IS NULL;
+
ALTER TABLE proc ADD db_collation
char(32) collate utf8_bin DEFAULT NULL
AFTER collation_connection;
ALTER TABLE proc MODIFY db_collation
char(32) collate utf8_bin DEFAULT NULL;
+SELECT CASE WHEN COUNT(*) > 0 THEN
+CONCAT ("WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary.")
+ELSE NULL
+END
+AS value FROM proc WHERE db_collation IS NULL;
+
+UPDATE proc AS p SET db_collation =
+ ( SELECT DEFAULT_COLLATION_NAME
+ FROM INFORMATION_SCHEMA.SCHEMATA
+ WHERE SCHEMA_NAME = p.db)
+ WHERE db_collation IS NULL;
+
ALTER TABLE proc ADD body_utf8 longblob DEFAULT NULL
AFTER db_collation;
ALTER TABLE proc MODIFY body_utf8 longblob DEFAULT NULL;
=== modified file 'scripts/mysqlbug.sh'
--- a/scripts/mysqlbug.sh 2007-10-19 17:06:30 +0000
+++ b/scripts/mysqlbug.sh 2009-12-27 13:54:41 +0000
@@ -21,7 +21,7 @@ echo "Finding system information for a M
VERSION="@VERSION@@MYSQL_SERVER_SUFFIX@"
COMPILATION_COMMENT="@COMPILATION_COMMENT@"
-BUGmysql="mysql(a)lists.mysql.com"
+BUGmysql="maria-developers(a)lists.launchpad.net"
# This is set by configure
COMP_CALL_INFO="CC='@SAVE_CC@' CFLAGS='@SAVE_CFLAGS@' CXX='@SAVE_CXX@' CXXFLAGS='@SAVE_CXXFLAGS@' LDFLAGS='@SAVE_LDFLAGS@' ASFLAGS='@SAVE_ASFLAGS@'"
COMP_RUN_INFO="CC='@CC@' CFLAGS='@CFLAGS@' CXX='@CXX@' CXXFLAGS='@CXXFLAGS@' LDFLAGS='@LDFLAGS@' ASFLAGS='@ASFLAGS@'"
=== modified file 'scripts/mysqld_multi.sh'
--- a/scripts/mysqld_multi.sh 2009-06-19 15:32:10 +0000
+++ b/scripts/mysqld_multi.sh 2010-01-21 08:10:05 +0000
@@ -68,7 +68,10 @@ sub main
# than a correct --defaults-extra-file option
unshift @defaults_options, "--defaults-extra-file=$1";
+ print "WARNING: --config-file is deprecated and will be removed\n";
+ print "in MySQL 5.6. Please use --defaults-extra-file instead\n";
}
+ }
}
foreach (@defaults_options)
=== modified file 'server-tools/instance-manager/instance_map.cc'
--- a/server-tools/instance-manager/instance_map.cc 2009-03-19 13:42:36 +0000
+++ b/server-tools/instance-manager/instance_map.cc 2009-12-18 19:14:09 +0000
@@ -117,13 +117,13 @@ static void parse_option(const char *opt
while (*ptr == '-')
++ptr;
- strmake(option_name_buf, ptr, MAX_OPTION_LEN + 1);
+ strmake(option_name_buf, ptr, MAX_OPTION_LEN);
eq_pos= strchr(ptr, '=');
if (eq_pos)
{
option_name_buf[eq_pos - ptr]= 0;
- strmake(option_value_buf, eq_pos + 1, MAX_OPTION_LEN + 1);
+ strmake(option_value_buf, eq_pos + 1, MAX_OPTION_LEN);
}
else
{
=== modified file 'server-tools/instance-manager/listener.cc'
--- a/server-tools/instance-manager/listener.cc 2009-04-25 10:05:32 +0000
+++ b/server-tools/instance-manager/listener.cc 2010-03-04 08:03:07 +0000
@@ -272,7 +272,7 @@ create_unix_socket(struct sockaddr_un &u
unix_socket_address.sun_family= AF_UNIX;
strmake(unix_socket_address.sun_path, Options::Main::socket_file_name,
- sizeof(unix_socket_address.sun_path));
+ sizeof(unix_socket_address.sun_path) - 1);
unlink(unix_socket_address.sun_path); // in case we have stale socket file
/*
=== modified file 'server-tools/instance-manager/options.cc'
--- a/server-tools/instance-manager/options.cc 2009-03-19 13:42:36 +0000
+++ b/server-tools/instance-manager/options.cc 2009-12-18 19:14:09 +0000
@@ -533,10 +533,10 @@ static int setup_windows_defaults()
return 1;
}
- strmake(base_name, base_name_ptr, FN_REFLEN);
+ strmake(base_name, base_name_ptr, FN_REFLEN - 1);
*base_name_ptr= 0;
- strmake(im_name, base_name, FN_REFLEN);
+ strmake(im_name, base_name, FN_REFLEN - 1);
ptr= strrchr(im_name, '.');
if (!ptr)
=== modified file 'server-tools/instance-manager/user_map.cc'
--- a/server-tools/instance-manager/user_map.cc 2009-06-29 14:00:47 +0000
+++ b/server-tools/instance-manager/user_map.cc 2009-12-18 19:14:09 +0000
@@ -25,7 +25,7 @@
User::User(const LEX_STRING *user_name_arg, const char *password)
{
user_length= (uint8) (strmake(user, user_name_arg->str,
- USERNAME_LENGTH + 1) - user);
+ USERNAME_LENGTH) - user);
set_password(password);
}
=== modified file 'sql-bench/bench-init.pl.sh'
--- a/sql-bench/bench-init.pl.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/bench-init.pl.sh 2010-02-10 21:26:06 +0000
@@ -39,8 +39,8 @@ require "$pwd/server-cfg" || die "Can't
$|=1; # Output data immediately
-$opt_skip_test=$opt_skip_create=$opt_skip_delete=$opt_verbose=$opt_fast_insert=$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=$opt_log=$opt_use_old_results=$opt_help=$opt_odbc=$opt_small_test=$opt_small_tables=$opt_samll_key_tables=$opt_stage=$opt_old_headers=$opt_die_on_errors=$opt_tcpip=$opt_random=$opt_only_missing_tests=0;
-$opt_cmp=$opt_user=$opt_password=$opt_connect_options="";
+$opt_skip_test=$opt_skip_create=$opt_skip_delete=$opt_verbose=$opt_fast_insert=$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=$opt_log=$opt_use_old_results=$opt_help=$opt_odbc=$opt_small_test=$opt_small_tables=$opt_samll_key_tables=$opt_stage=$opt_old_headers=$opt_die_on_errors=$opt_tcpip=$opt_random=$opt_only_missing_tests=$opt_temporary_tables=0;
+$opt_cmp=$opt_user=$opt_password=$opt_connect_options=$opt_connect_command= "";
$opt_server="mysql"; $opt_dir="output";
$opt_host="localhost";$opt_database="test";
$opt_machine=""; $opt_suffix="";
@@ -59,7 +59,7 @@ $log_prog_args=join(" ", skip_arguments(
"use-old-results","skip-test",
"optimization","hw",
"machine", "dir", "suffix", "log"));
-GetOptions("skip-test=s","comments=s","cmp=s","server=s","user=s","host=s","database=s","password=s","loop-count=i","row-count=i","skip-create","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","field-count=i","regions=i","groups=i","time-limit=i","log","use-old-results","machine=s","dir=s","suffix=s","help","odbc","small-test","small-tables","small-key-tables","stage=i","threads=i","random","old-headers","die-on-errors","create-options=s","hires","tcpip","silent","optimization=s","hw=s","socket=s","connect-options=s","only-missing-tests") || usage();
+GetOptions("skip-test=s","comments=s","cmp=s","server=s","user=s","host=s","database=s","password=s","loop-count=i","row-count=i","skip-create","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","field-count=i","regions=i","groups=i","time-limit=i","log","use-old-results","machine=s","dir=s","suffix=s","help","odbc","small-test","small-tables","small-key-tables","stage=i","threads=i","random","old-headers","die-on-errors","create-options=s","hires","tcpip","silent","optimization=s","hw=s","socket=s","connect-options=s","connect-command=s","only-missing-tests","temporary-tables") || usage();
usage() if ($opt_help);
$server=get_server($opt_server,$opt_host,$opt_database,$opt_odbc,
@@ -454,6 +454,9 @@ All benchmarks takes the following optio
create all MySQL tables as InnoDB tables use:
--create-options=ENGINE=InnoDB
+--temporary-tables
+ Use temporary tables for all tests.
+
--database (Default $opt_database)
In which database the test tables are created.
@@ -595,6 +598,10 @@ All benchmarks takes the following optio
Add options, which uses at DBI connect.
For example --connect-options=mysql_read_default_file=/etc/my.cnf.
+--connect-command='SQL command'
+ Initialization command to execute when logged in. Useful for setting
+ up the environment.
+
EOF
exit(0);
}
=== modified file 'sql-bench/server-cfg.sh'
--- a/sql-bench/server-cfg.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/server-cfg.sh 2010-02-10 21:26:06 +0000
@@ -159,6 +159,7 @@ sub new
$limits{'max_index'} = 16; # Max number of keys
$limits{'max_index_parts'} = 16; # Max segments/key
$limits{'max_tables'} = (($machine || '') =~ "^win") ? 5000 : 65000;
+ $limits{'max_temporary_tables'}= 400;
$limits{'max_text_size'} = 1000000; # Good enough for tests
$limits{'multi_drop'} = 1; # Drop table can take many tables
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
@@ -189,6 +190,7 @@ sub new
$self->{'transactions'} = 1; # Transactions enabled
$limits{'max_columns'} = 90; # Max number of columns in table
$limits{'max_tables'} = 32; # No comments
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
}
if (defined($main::opt_create_options) &&
$main::opt_create_options =~ /engine=bdb/i)
@@ -200,6 +202,7 @@ sub new
{
$limits{'working_blobs'} = 0; # Blobs not implemented yet
$limits{'max_tables'} = 500;
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
$self->{'transactions'} = 1; # Transactions enabled
}
@@ -249,6 +252,11 @@ sub connect
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
$dbh->do("SET OPTION LOG_OFF=1,UPDATE_LOG=0");
+ if ($main::opt_connect_command ne "")
+ {
+ $dbh->do($main::opt_connect_command) or
+ die "Can't execute connect_command: $main::opt_connect_command error: $DBI::errstr\n";
+ }
return $dbh;
}
@@ -265,7 +273,14 @@ sub create
my($self,$table_name,$fields,$index,$options) = @_;
my($query,@queries);
- $query="create table $table_name (";
+ if ($main::opt_temporary_tables)
+ {
+ $query="create temporary table $table_name (";
+ }
+ else
+ {
+ $query="create table $table_name (";
+ }
foreach $field (@$fields)
{
# $field =~ s/ decimal/ double(10,2)/i;
@@ -388,6 +403,7 @@ sub new
$limits{'max_conditions'} = 74;
$limits{'max_columns'} = 75;
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
$limits{'max_text_size'} = 32000;
$limits{'query_size'} = 65535;
$limits{'max_index'} = 5;
@@ -617,7 +633,9 @@ sub new
$limits{'max_conditions'} = 9999; # This makes Pg real slow
$limits{'max_index'} = 64; # Big enough
$limits{'max_index_parts'} = 16;
- $limits{'max_tables'} = 5000; # 10000 crashes pg 7.0.2
+ $limits{'max_tables'} = 65000;
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
+
$limits{'max_text_size'} = 65000; # Good enough for test
$limits{'multi_drop'} = 1;
$limits{'order_by_position'} = 1;
@@ -868,6 +886,8 @@ sub new
$limits{'max_conditions'} = 9999; # Probably big enough
$limits{'max_columns'} = 2000; # From crash-me
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
+
$limits{'max_text_size'} = 65492; # According to tests
$limits{'query_size'} = 65535; # Probably a limit
$limits{'max_index'} = 64; # Probably big enough
@@ -1099,6 +1119,7 @@ sub new
# above this value .... but can handle 2419 columns
# maybe something for crash-me ... but how to check ???
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
$limits{'max_text_size'} = 4095; # max returned ....
$limits{'query_size'} = 65535; # Not a limit, big enough
$limits{'max_index'} = 64; # Big enough
@@ -1369,6 +1390,8 @@ sub new
$limits{'max_conditions'} = 9999; # (Actually not a limit)
$limits{'max_columns'} = 254; # Max number of columns in table
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
+
$limits{'max_text_size'} = 2000; # Limit for blob test-connect
$limits{'query_size'} = 65525; # Max size with default buffers.
$limits{'max_index'} = 16; # Max number of keys
@@ -1642,6 +1665,8 @@ sub new
$limits{'max_column_name'} = 18; # max table and column name
$limits{'max_columns'} = 994; # Max number of columns in table
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
+
$limits{'max_index'} = 64; # Max number of keys
$limits{'max_index_parts'} = 15; # Max segments/key
$limits{'max_text_size'} = 65535; # Max size with default buffers. ??
@@ -1830,6 +1855,8 @@ sub new
$limits{'max_conditions'} = 97; # We get 'Query is too complex'
$limits{'max_columns'} = 255; # Max number of columns in table
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
+
$limits{'max_text_size'} = 255; # Max size with default buffers.
$limits{'query_size'} = 65535; # Not a limit, big enough
$limits{'max_index'} = 32; # Max number of keys
@@ -2015,6 +2042,8 @@ sub new
$limits{'max_conditions'} = 1030; # We get 'Query is too complex'
$limits{'max_columns'} = 250; # Max number of columns in table
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
+
$limits{'max_text_size'} = 9830; # Max size with default buffers.
$limits{'query_size'} = 9830; # Max size with default buffers.
$limits{'max_index'} = 64; # Max number of keys
@@ -2211,6 +2240,8 @@ sub new
$limits{'max_conditions'} = 1030; # We get 'Query is too complex'
$limits{'max_columns'} = 250; # Max number of columns in table
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
+
$limits{'max_text_size'} = 9830; # Max size with default buffers.
$limits{'query_size'} = 9830; # Max size with default buffers.
$limits{'max_index'} = 64; # Max number of keys
@@ -2443,6 +2474,8 @@ sub new
$limits{'max_conditions'} = 50; # (Actually not a limit)
$limits{'max_columns'} = 254; # Max number of columns in table
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
+
$limits{'max_text_size'} = 2000; # Limit for blob test-connect
$limits{'query_size'} = 65525; # Max size with default buffers.
$limits{'max_index'} = 16; # Max number of keys
@@ -2647,6 +2680,8 @@ sub new
$limits{'max_conditions'} = 418; # We get 'Query is too complex'
$limits{'max_columns'} = 500; # Max number of columns in table
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
+
$limits{'max_text_size'} = 254; # Max size with default buffers.
$limits{'query_size'} = 254; # Max size with default buffers.
$limits{'max_index'} = 48; # Max number of keys
@@ -2825,6 +2860,7 @@ sub new
$limits{'max_conditions'} = 9999; # (Actually not a limit)
$limits{'max_columns'} = 252; # Max number of columns in table
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
$limits{'max_text_size'} = 15000; # Max size with default buffers.
$limits{'query_size'} = 1000000; # Max size with default buffers.
$limits{'max_index'} = 32; # Max number of keys
@@ -3027,6 +3063,7 @@ sub new
$limits{'max_conditions'} = 9999; # (Actually not a limit)
$limits{'max_columns'} = 252; # Max number of columns in table
$limits{'max_tables'} = 65000; # Should be big enough
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
$limits{'max_text_size'} = 15000; # Max size with default buffers.
$limits{'query_size'} = 1000000; # Max size with default buffers.
$limits{'max_index'} = 65000; # Max number of keys
@@ -3223,6 +3260,7 @@ sub new
# The following should be 8192, but is smaller because Frontbase crashes..
$limits{'max_columns'} = 150; # Max number of columns in table
$limits{'max_tables'} = 5000; # 10000 crashed FrontBase
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
$limits{'max_text_size'} = 65000; # Max size with default buffers.
$limits{'query_size'} = 8000000; # Max size with default buffers.
$limits{'max_index'} = 38; # Max number of keys
@@ -3435,6 +3473,7 @@ sub new
$limits{'max_conditions'} = 9999; # (Actually not a limit) *
$limits{'max_columns'} = 1023; # Max number of columns in table *
$limits{'max_tables'} = 65000; # Should be big enough * unlimited actually
+ $limits{'max_temporary_tables'}= $limits{"max_tables"};
$limits{'max_text_size'} = 15000; # Max size with default buffers.
$limits{'query_size'} = 64*1024; # Max size with default buffers. *64 kb by default. May be set by system variable
$limits{'max_index'} = 510; # Max number of keys *
=== modified file 'sql-bench/test-ATIS.sh'
--- a/sql-bench/test-ATIS.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/test-ATIS.sh 2010-02-17 20:10:02 +0000
@@ -28,7 +28,7 @@ use Cwd;
use DBI;
use Benchmark;
-$opt_loop_count=100; # Run selects this many times
+$opt_loop_count=5000; # Run selects this many times
$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
=== modified file 'sql-bench/test-alter-table.sh'
--- a/sql-bench/test-alter-table.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/test-alter-table.sh 2010-02-17 20:10:02 +0000
@@ -25,7 +25,7 @@ use DBI;
use Benchmark;
$opt_start_field_count=8; # start with this many fields
-$opt_loop_count=100; # How many tests to do
+$opt_loop_count=10000; # How many tests to do
$opt_row_count=1000; # Rows in the table
$opt_field_count=1000; # Add until this many fields.
$opt_time_limit=10*60; # Don't wait more than 10 min for some tests
=== modified file 'sql-bench/test-big-tables.sh'
--- a/sql-bench/test-big-tables.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/test-big-tables.sh 2010-02-17 20:10:02 +0000
@@ -25,7 +25,7 @@ use Cwd;
use DBI;
use Benchmark;
-$opt_loop_count=1000; # Change this to make test harder/easier
+$opt_loop_count=70000; # Change this to make test harder/easier
$opt_field_count=1000;
$pwd = cwd(); $pwd = "." if ($pwd eq '');
=== modified file 'sql-bench/test-connect.sh'
--- a/sql-bench/test-connect.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/test-connect.sh 2010-02-17 20:10:02 +0000
@@ -28,7 +28,7 @@ use Cwd;
use DBI;
use Benchmark;
-$opt_loop_count=100000; # Change this to make test harder/easier
+$opt_loop_count=500000; # Change this to make test harder/easier
$str_length=65000; # This is the length of blob strings in PART:5
$max_test=20; # How many times to test if the server is busy
@@ -161,41 +161,48 @@ if ($opt_fast && defined($server->{vacuu
{
$server->vacuum(0,\$dbh);
}
-$dbh->disconnect;
+if (!$main::opt_temporary_tables)
+{
+ $dbh->disconnect;
+}
#
# First test connect/select/disconnect
#
-print "Testing connect/select 1 row from table/disconnect\n";
+if (!$main::opt_temporary_tables)
+{
+ print "Testing connect/select 1 row from table/disconnect\n";
-$loop_time=new Benchmark;
-$errors=0;
+ $loop_time=new Benchmark;
+ $errors=0;
-for ($i=0 ; $i < $small_loop_count ; $i++)
-{
- for ($j=0; $j < $max_test ; $j++)
+ for ($i=0 ; $i < $small_loop_count ; $i++)
{
- last if ($dbh = DBI->connect($server->{'data_source'}, $opt_user, $opt_password));
- $errors++;
- }
- die $DBI::errstr if ($j == $max_test);
+ for ($j=0; $j < $max_test ; $j++)
+ {
+ last if ($dbh = DBI->connect($server->{'data_source'}, $opt_user, $opt_password));
+ $errors++;
+ }
+ die $DBI::errstr if ($j == $max_test);
- $sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 1 record
+ $sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 1 record
or die $DBI::errstr;
- $dbh->disconnect;
-}
+ $dbh->disconnect;
+ }
-$end_time=new Benchmark;
-print "Warning: $errors connections didn't work without a time delay\n" if ($errors);
-print "Time to connect+select_1_row ($small_loop_count): " .
+ $end_time=new Benchmark;
+ print "Warning: $errors connections didn't work without a time delay\n" if ($errors);
+ print "Time to connect+select_1_row ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+ $dbh = $server->connect();
+}
+
#
# The same test, but without connect/disconnect
#
print "Testing select 1 row from table\n";
-$dbh = $server->connect();
$loop_time=new Benchmark;
for ($i=0 ; $i < $opt_loop_count ; $i++)
=== modified file 'sql-bench/test-create.sh'
--- a/sql-bench/test-create.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/test-create.sh 2010-02-10 21:26:06 +0000
@@ -47,7 +47,15 @@ if ($opt_small_test)
$create_loop_count/=1000;
}
-$max_tables=min($limits->{'max_tables'},$opt_loop_count);
+if ($opt_temporary_tables)
+{
+ $max_tables=min($limits->{'max_tables'},$opt_loop_count);
+}
+else
+{
+ $max_tables=min($limits->{'max_tables'},$opt_loop_count);
+ $max_tables=400;
+}
if ($opt_small_test)
{
@@ -71,7 +79,7 @@ $dbh = $server->connect();
if ($opt_force) # If tables used in this test exist, drop 'em
{
print "Okay..Let's make sure that our tables don't exist yet.\n\n";
- for ($i=1 ; $i <= $max_tables ; $i++)
+ for ($i=1 ; $i <= max($max_tables, $create_loop_count) ; $i++)
{
$dbh->do("drop table bench_$i" . $server->{'drop_attr'});
}
@@ -245,7 +253,7 @@ for ($i=2 ; $i <= $keys ; $i++)
}
$loop_time=new Benchmark;
-for ($i=1 ; $i <= $opt_loop_count ; $i++)
+for ($i=1 ; $i <= $create_loop_count ; $i++)
{
do_many($dbh,$server->create("bench_$i", \@fields, \@keys));
$dbh->do("drop table bench_$i" . $server->{'drop_attr'}) or die $DBI::errstr;
=== modified file 'sql-bench/test-select.sh'
--- a/sql-bench/test-select.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/test-select.sh 2010-03-09 19:22:24 +0000
@@ -26,7 +26,7 @@ use Getopt::Long;
use Benchmark;
$opt_loop_count=10000;
-$opt_medium_loop_count=1000;
+$opt_medium_loop_count=7000;
$opt_small_loop_count=10;
$opt_regions=6;
$opt_groups=100;
@@ -68,7 +68,8 @@ do_many($dbh,$server->create("bench1",
["region char(1) NOT NULL",
"idn integer(6) NOT NULL",
"rev_idn integer(6) NOT NULL",
- "grp integer(6) NOT NULL"],
+ "grp integer(6) NOT NULL",
+ "grp_no_key integer(6) NOT NULL"],
["primary key (region,idn)",
"unique (region,rev_idn)",
"unique (region,grp,idn)"]));
@@ -105,10 +106,10 @@ for ($id=0,$rev_id=$opt_loop_count-1 ; $
{
$grp=$id*3 % $opt_groups;
$region=chr(65+$id%$opt_regions);
- do_query($dbh,"$query'$region',$id,$rev_id,$grp)");
+ do_query($dbh,"$query'$region',$id,$rev_id,$grp,$grp)");
if ($id == $half_done)
{ # Test with different insert
- $query="insert into bench1 (region,idn,rev_idn,grp) values (";
+ $query="insert into bench1 (region,idn,rev_idn,grp,grp_no_key) values (";
}
}
@@ -323,6 +324,26 @@ if ($limits->{'group_functions'})
$end_time=new Benchmark;
print "Time for count_group_on_key_parts ($i:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $rows+=fetch_all_rows($dbh,"select grp_no_key,count(*) from bench1 group by grp_no_key");
+ }
+ $end_time=new Benchmark;
+ print "Time for count_group ($i:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $rows+=fetch_all_rows($dbh,"select grp_no_key,count(*) as cnt from bench1 group by grp_no_key order by cnt");
+ }
+ $end_time=new Benchmark;
+ print "Time for count_group_with_order ($i:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
}
if ($limits->{'group_distinct_functions'})
=== modified file 'sql-bench/test-transactions.sh'
--- a/sql-bench/test-transactions.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/test-transactions.sh 2010-02-17 20:10:02 +0000
@@ -28,8 +28,8 @@ use Benchmark;
$opt_groups=27; # Characters are 'A' -> Z
-$opt_loop_count=10000; # Change this to make test harder/easier
-$opt_medium_loop_count=100; # Change this to make test harder/easier
+$opt_loop_count=500000; # Change this to make test harder/easier
+$opt_medium_loop_count=10000; # Change this to make test harder/easier
$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
=== modified file 'sql-bench/test-wisconsin.sh'
--- a/sql-bench/test-wisconsin.sh 2009-05-29 13:40:55 +0000
+++ b/sql-bench/test-wisconsin.sh 2010-02-17 20:10:02 +0000
@@ -21,7 +21,7 @@ use Cwd;
use DBI;
use Benchmark;
-$opt_loop_count=10;
+$opt_loop_count=5000;
$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
=== modified file 'sql-common/client.c'
--- a/sql-common/client.c 2009-12-03 15:26:54 +0000
+++ b/sql-common/client.c 2010-03-28 18:10:00 +0000
@@ -1939,7 +1939,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
#if defined(HAVE_SMEM)
if ((!mysql->options.protocol ||
mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) &&
- (!host || !strcmp(host,LOCAL_HOST)))
+ (!host || !strcmp(host,LOCAL_HOST)) &&
+ mysql->options.shared_memory_base_name)
{
if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) ==
INVALID_HANDLE_VALUE)
@@ -1948,7 +1949,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
("host: '%s' socket: '%s' shared memory: %s have_tcpip: %d",
host ? host : "<null>",
unix_socket ? unix_socket : "<null>",
- (int) mysql->options.shared_memory_base_name,
+ mysql->options.shared_memory_base_name,
(int) have_tcpip));
if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)
goto error;
@@ -2302,6 +2303,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
/* Do the SSL layering. */
struct st_mysql_options *options= &mysql->options;
struct st_VioSSLFd *ssl_fd;
+ char error_string[1024];
/*
Send client_flag, max_packet_size - unencrypted otherwise
@@ -2331,9 +2333,14 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
/* Connect to the server */
DBUG_PRINT("info", ("IO layer change in progress..."));
if (sslconnect(ssl_fd, mysql->net.vio,
- (long) (mysql->options.connect_timeout)))
+ (long) (mysql->options.connect_timeout),
+ error_string))
{
- set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+ set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR,
+ unknown_sqlstate,
+ "SSL error: %s",
+ error_string[0] ? error_string :
+ ER(CR_SSL_CONNECTION_ERROR));
goto error;
}
DBUG_PRINT("info", ("IO layer change done!"));
@@ -2746,6 +2753,13 @@ void mysql_detach_stmt_list(LIST **stmt_
}
+/*
+ Close a MySQL connection and free all resources attached to it.
+
+ This function is coded in such that it can be called multiple times
+ (As some clients call this after mysql_real_connect() fails)
+*/
+
void STDCALL mysql_close(MYSQL *mysql)
{
DBUG_ENTER("mysql_close");
@@ -2779,10 +2793,16 @@ void STDCALL mysql_close(MYSQL *mysql)
}
#endif
if (mysql != mysql->master)
+ {
mysql_close(mysql->master);
+ mysql->master= 0;
+ }
#ifndef MYSQL_SERVER
if (mysql->thd)
+ {
(*mysql->methods->free_embedded_thd)(mysql);
+ mysql->thd= 0;
+ }
#endif
if (mysql->free_me)
my_free((uchar*) mysql,MYF(0));
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2009-12-03 11:19:05 +0000
+++ b/sql/CMakeLists.txt 2010-01-29 18:42:22 +0000
@@ -97,7 +97,7 @@ SET_TARGET_PROPERTIES(mysqld PROPERTIES
SET (MYSQLD_CORE_LIBS mysys zlib dbug strings yassl taocrypt vio regex sql libevent)
TARGET_LINK_LIBRARIES(mysqld ${MYSQLD_CORE_LIBS} ${MYSQLD_STATIC_ENGINE_LIBS})
-TARGET_LINK_LIBRARIES(mysqld ws2_32.lib)
+TARGET_LINK_LIBRARIES(mysqld ws2_32.lib psapi.lib)
IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS)
=== modified file 'sql/event_data_objects.cc'
--- a/sql/event_data_objects.cc 2009-12-03 11:19:05 +0000
+++ b/sql/event_data_objects.cc 2010-03-04 08:03:07 +0000
@@ -1400,7 +1400,7 @@ Event_job_data::execute(THD *thd, bool d
#endif
if (check_access(thd, EVENT_ACL, dbname.str,
- 0, 0, 0, is_schema_db(dbname.str)))
+ 0, 0, 0, is_schema_db(dbname.str, dbname.length)))
{
/*
This aspect of behavior is defined in the worklog,
=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc 2009-12-03 11:19:05 +0000
+++ b/sql/event_db_repository.cc 2010-03-04 08:03:07 +0000
@@ -26,7 +26,7 @@
*/
static
-const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] =
+const TABLE_FIELD_TYPE event_table_fields[ET_FIELD_COUNT] =
{
{
{ C_STRING_WITH_LEN("db") },
@@ -151,6 +151,24 @@ const TABLE_FIELD_W_TYPE event_table_fie
}
};
+static const TABLE_FIELD_DEF
+ event_table_def= {ET_FIELD_COUNT, event_table_fields};
+
+class Event_db_intact : public Table_check_intact
+{
+protected:
+ void report_error(uint, const char *fmt, ...)
+ {
+ va_list args;
+ va_start(args, fmt);
+ error_log_print(ERROR_LEVEL, fmt, args);
+ va_end(args);
+ }
+};
+
+/** In case of an error, a message is printed to the error log. */
+static Event_db_intact table_intact;
+
/**
Puts some data common to CREATE and ALTER EVENT into a row.
@@ -1027,6 +1045,7 @@ update_timing_fields_for_event(THD *thd,
TABLE *table= NULL;
Field **fields;
int ret= 1;
+ bool save_binlog_row_based;
DBUG_ENTER("Event_db_repository::update_timing_fields_for_event");
@@ -1034,8 +1053,8 @@ update_timing_fields_for_event(THD *thd,
Turn off row binlogging of event timing updates. These are not used
for RBR of events replicated to the slave.
*/
- if (thd->current_stmt_binlog_row_based)
- thd->clear_current_stmt_binlog_row_based();
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
+ thd->clear_current_stmt_binlog_row_based();
DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL);
@@ -1077,6 +1096,8 @@ update_timing_fields_for_event(THD *thd,
end:
if (table)
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(test(ret));
}
@@ -1117,10 +1138,8 @@ Event_db_repository::check_system_tables
}
else
{
- if (table_check_intact(tables.table, MYSQL_DB_FIELD_COUNT,
- mysql_db_table_fields))
+ if (table_intact.check(tables.table, &mysql_db_table_def))
ret= 1;
- /* in case of an error, the message is printed inside table_check_intact */
close_thread_tables(thd);
}
@@ -1154,9 +1173,8 @@ Event_db_repository::check_system_tables
}
else
{
- if (table_check_intact(tables.table, ET_FIELD_COUNT, event_table_fields))
+ if (table_intact.check(tables.table, &event_table_def))
ret= 1;
- /* in case of an error, the message is printed inside table_check_intact */
close_thread_tables(thd);
}
=== modified file 'sql/event_scheduler.cc' (properties changed: -x to +x)
--- a/sql/event_scheduler.cc 2009-09-07 20:50:10 +0000
+++ b/sql/event_scheduler.cc 2010-03-04 08:03:07 +0000
@@ -235,8 +235,9 @@ event_scheduler_thread(void *arg)
if (!res)
scheduler->run(thd);
+ DBUG_LEAVE; // Against gcc warnings
my_thread_end();
- DBUG_RETURN(0); // Against gcc warnings
+ return 0;
}
=== modified file 'sql/events.cc'
--- a/sql/events.cc 2009-12-03 11:19:05 +0000
+++ b/sql/events.cc 2010-03-04 08:03:07 +0000
@@ -388,6 +388,7 @@ Events::create_event(THD *thd, Event_par
bool if_not_exists)
{
int ret;
+ bool save_binlog_row_based;
DBUG_ENTER("Events::create_event");
/*
@@ -414,7 +415,8 @@ Events::create_event(THD *thd, Event_par
DBUG_ASSERT(parse_data->expression || parse_data->execute_at);
if (check_access(thd, EVENT_ACL, parse_data->dbname.str, 0, 0, 0,
- is_schema_db(parse_data->dbname.str)))
+ is_schema_db(parse_data->dbname.str,
+ parse_data->dbname.length)))
DBUG_RETURN(TRUE);
if (check_db_dir_existence(parse_data->dbname.str))
@@ -429,8 +431,8 @@ Events::create_event(THD *thd, Event_par
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for CREATE EVENT command.
*/
- if (thd->current_stmt_binlog_row_based)
- thd->clear_current_stmt_binlog_row_based();
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
+ thd->clear_current_stmt_binlog_row_based();
pthread_mutex_lock(&LOCK_event_metadata);
@@ -470,14 +472,18 @@ Events::create_event(THD *thd, Event_par
{
sql_print_error("Event Error: An error occurred while creating query string, "
"before writing it into binary log.");
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(TRUE);
}
/* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
will be written into the binary log as the definer for the SQL thread. */
- write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
+ ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
}
}
pthread_mutex_unlock(&LOCK_event_metadata);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(ret);
}
@@ -507,6 +513,7 @@ Events::update_event(THD *thd, Event_par
LEX_STRING *new_dbname, LEX_STRING *new_name)
{
int ret;
+ bool save_binlog_row_based;
Event_queue_element *new_element;
DBUG_ENTER("Events::update_event");
@@ -525,7 +532,8 @@ Events::update_event(THD *thd, Event_par
DBUG_RETURN(TRUE);
if (check_access(thd, EVENT_ACL, parse_data->dbname.str, 0, 0, 0,
- is_schema_db(parse_data->dbname.str)))
+ is_schema_db(parse_data->dbname.str,
+ parse_data->dbname.length)))
DBUG_RETURN(TRUE);
if (new_dbname) /* It's a rename */
@@ -547,7 +555,7 @@ Events::update_event(THD *thd, Event_par
access it.
*/
if (check_access(thd, EVENT_ACL, new_dbname->str, 0, 0, 0,
- is_schema_db(new_dbname->str)))
+ is_schema_db(new_dbname->str, new_dbname->length)))
DBUG_RETURN(TRUE);
/* Check that the target database exists */
@@ -562,8 +570,8 @@ Events::update_event(THD *thd, Event_par
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for UPDATE EVENT command.
*/
- if (thd->current_stmt_binlog_row_based)
- thd->clear_current_stmt_binlog_row_based();
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
+ thd->clear_current_stmt_binlog_row_based();
pthread_mutex_lock(&LOCK_event_metadata);
@@ -595,10 +603,12 @@ Events::update_event(THD *thd, Event_par
new_element);
/* Binlog the alter event. */
DBUG_ASSERT(thd->query() && thd->query_length());
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
}
pthread_mutex_unlock(&LOCK_event_metadata);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(ret);
}
@@ -632,6 +642,7 @@ bool
Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
{
int ret;
+ bool save_binlog_row_based;
DBUG_ENTER("Events::drop_event");
/*
@@ -652,15 +663,15 @@ Events::drop_event(THD *thd, LEX_STRING
DBUG_RETURN(TRUE);
if (check_access(thd, EVENT_ACL, dbname.str, 0, 0, 0,
- is_schema_db(dbname.str)))
+ is_schema_db(dbname.str, dbname.length)))
DBUG_RETURN(TRUE);
/*
Turn off row binlogging of this statement and use statement-based so
that all supporting tables are updated for DROP EVENT command.
*/
- if (thd->current_stmt_binlog_row_based)
- thd->clear_current_stmt_binlog_row_based();
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
+ thd->clear_current_stmt_binlog_row_based();
pthread_mutex_lock(&LOCK_event_metadata);
/* On error conditions my_error() is called so no need to handle here */
@@ -670,9 +681,11 @@ Events::drop_event(THD *thd, LEX_STRING
event_queue->drop_event(thd, dbname, name);
/* Binlog the drop event. */
DBUG_ASSERT(thd->query() && thd->query_length());
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
pthread_mutex_unlock(&LOCK_event_metadata);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(ret);
}
@@ -809,7 +822,7 @@ Events::show_create_event(THD *thd, LEX_
DBUG_RETURN(TRUE);
if (check_access(thd, EVENT_ACL, dbname.str, 0, 0, 0,
- is_schema_db(dbname.str)))
+ is_schema_db(dbname.str, dbname.length)))
DBUG_RETURN(TRUE);
/*
@@ -867,7 +880,7 @@ Events::fill_schema_events(THD *thd, TAB
if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS)
{
DBUG_ASSERT(thd->lex->select_lex.db);
- if (!is_schema_db(thd->lex->select_lex.db) && // There is no events in I_S
+ if (!is_schema_db(thd->lex->select_lex.db) && // There is no events in I_S
check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0, 0))
DBUG_RETURN(1);
db= thd->lex->select_lex.db;
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2009-12-03 11:19:05 +0000
+++ b/sql/field.cc 2010-03-04 08:03:07 +0000
@@ -2487,6 +2487,50 @@ Field_new_decimal::Field_new_decimal(uin
}
+Field *Field_new_decimal::create_from_item (Item *item)
+{
+ uint8 dec= item->decimals;
+ uint8 intg= item->decimal_precision() - dec;
+ uint32 len= item->max_length;
+
+ DBUG_ASSERT (item->result_type() == DECIMAL_RESULT);
+
+ /*
+ Trying to put too many digits overall in a DECIMAL(prec,dec)
+ will always throw a warning. We must limit dec to
+ DECIMAL_MAX_SCALE however to prevent an assert() later.
+ */
+
+ if (dec > 0)
+ {
+ signed int overflow;
+
+ dec= min(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+ we'll throw out decimals rather than integers. This is still
+ bad and of course throws a truncation warning.
+ +1: for decimal point
+ */
+
+ const int required_length=
+ my_decimal_precision_to_length(intg + dec, dec,
+ item->unsigned_flag);
+
+ overflow= required_length - len;
+
+ if (overflow > 0)
+ dec= max(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+ }
+ return new Field_new_decimal(len, item->maybe_null, item->name,
+ dec, item->unsigned_flag);
+}
+
+
int Field_new_decimal::reset(void)
{
store_value(&decimal_zero);
@@ -8243,8 +8287,7 @@ uint Field_blob::is_equal(Create_field *
return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
&& new_field->charset == field_charset &&
- ((Field_blob *)new_field->field)->max_data_length() ==
- max_data_length());
+ new_field->pack_length == pack_length());
}
=== modified file 'sql/field.h'
--- a/sql/field.h 2009-12-03 11:19:05 +0000
+++ b/sql/field.h 2010-03-04 08:03:07 +0000
@@ -807,6 +807,7 @@ public:
uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
+ static Field *create_from_item (Item *);
};
@@ -1925,7 +1926,12 @@ public:
uint32 max_display_length() { return field_length; }
uint size_of() const { return sizeof(*this); }
Item_result result_type () const { return INT_RESULT; }
- int reset(void) { bzero(ptr, bytes_in_rec); return 0; }
+ int reset(void) {
+ bzero(ptr, bytes_in_rec);
+ if (bit_ptr && (bit_len > 0)) // reset odd bits among null bits
+ clr_rec_bits(bit_ptr, bit_ofs, bit_len);
+ return 0;
+ }
int store(const char *to, uint length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc 2009-09-03 14:05:38 +0000
+++ b/sql/filesort.cc 2010-03-04 08:03:07 +0000
@@ -142,6 +142,8 @@ ha_rows filesort(THD *thd, TABLE *table,
error= 1;
bzero((char*) ¶m,sizeof(param));
param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
+ /* filesort cannot handle zero-length records. */
+ DBUG_ASSERT(param.sort_length);
param.ref_length= table->file->ref_length;
param.addon_field= 0;
param.addon_length= 0;
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2009-12-03 11:19:05 +0000
+++ b/sql/ha_ndbcluster.cc 2010-01-06 21:27:53 +0000
@@ -10565,4 +10565,6 @@ mysql_declare_plugin(ndbcluster)
}
mysql_declare_plugin_end;
+#else
+int Sun_ar_require_a_symbol_here= 0;
#endif
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2009-12-03 11:19:05 +0000
+++ b/sql/ha_partition.cc 2010-03-04 08:03:07 +0000
@@ -1215,17 +1215,28 @@ int ha_partition::prepare_new_partition(
partition_element *p_elem)
{
int error;
- bool create_flag= FALSE;
DBUG_ENTER("prepare_new_partition");
if ((error= set_up_table_before_create(tbl, part_name, create_info,
0, p_elem)))
- goto error;
+ goto error_create;
if ((error= file->ha_create(part_name, tbl, create_info)))
- goto error;
- create_flag= TRUE;
+ {
+ /*
+ Added for safety, InnoDB reports HA_ERR_FOUND_DUPP_KEY
+ if the table/partition already exists.
+ If we return that error code, then print_error would try to
+ get_dup_key on a non-existing partition.
+ So return a more reasonable error code.
+ */
+ if (error == HA_ERR_FOUND_DUPP_KEY)
+ error= HA_ERR_TABLE_EXIST;
+ goto error_create;
+ }
+ DBUG_PRINT("info", ("partition %s created", part_name));
if ((error= file->ha_open(tbl, part_name, m_mode, m_open_test_lock)))
- goto error;
+ goto error_open;
+ DBUG_PRINT("info", ("partition %s opened", part_name));
/*
Note: if you plan to add another call that may return failure,
better to do it before external_lock() as cleanup_new_partition()
@@ -1233,12 +1244,15 @@ int ha_partition::prepare_new_partition(
Otherwise see description for cleanup_new_partition().
*/
if ((error= file->ha_external_lock(ha_thd(), m_lock_type)))
- goto error;
+ goto error_external_lock;
+ DBUG_PRINT("info", ("partition %s external locked", part_name));
DBUG_RETURN(0);
-error:
- if (create_flag)
- VOID(file->ha_delete_table(part_name));
+error_external_lock:
+ VOID(file->close());
+error_open:
+ VOID(file->ha_delete_table(part_name));
+error_create:
DBUG_RETURN(error);
}
@@ -1272,19 +1286,23 @@ error:
void ha_partition::cleanup_new_partition(uint part_count)
{
- handler **save_m_file= m_file;
DBUG_ENTER("ha_partition::cleanup_new_partition");
- if (m_added_file && m_added_file[0])
+ if (m_added_file)
{
- m_file= m_added_file;
- m_added_file= NULL;
+ THD *thd= ha_thd();
+ handler **file= m_added_file;
+ while ((part_count > 0) && (*file))
+ {
+ (*file)->ha_external_lock(thd, F_UNLCK);
+ (*file)->close();
- external_lock(ha_thd(), F_UNLCK);
- /* delete_table also needed, a bit more complex */
- close();
+ /* Leave the (*file)->ha_delete_table(part_name) to the ddl-log */
- m_file= save_m_file;
+ file++;
+ part_count--;
+ }
+ m_added_file= NULL;
}
DBUG_VOID_RETURN;
}
@@ -1590,7 +1608,15 @@ int ha_partition::change_partitions(HA_C
part_elem->part_state= PART_TO_BE_DROPPED;
}
m_new_file= new_file_array;
- DBUG_RETURN(copy_partitions(copied, deleted));
+ if ((error= copy_partitions(copied, deleted)))
+ {
+ /*
+ Close and unlock the new temporary partitions.
+ They will later be deleted through the ddl-log.
+ */
+ cleanup_new_partition(part_count);
+ }
+ DBUG_RETURN(error);
}
@@ -1679,6 +1705,7 @@ int ha_partition::copy_partitions(ulongl
}
DBUG_RETURN(FALSE);
error:
+ m_reorged_file[reorg_part]->ha_rnd_end();
DBUG_RETURN(result);
}
@@ -5746,6 +5773,23 @@ const key_map *ha_partition::keys_to_use
DBUG_RETURN(m_file[0]->keys_to_use_for_scanning());
}
+#define MAX_PARTS_FOR_OPTIMIZER_CALLS 10
+/*
+ Prepare start variables for estimating optimizer costs.
+
+ @param[out] num_used_parts Number of partitions after pruning.
+ @param[out] check_min_num Number of partitions to call.
+ @param[out] first first used partition.
+*/
+void ha_partition::partitions_optimizer_call_preparations(uint *first,
+ uint *num_used_parts,
+ uint *check_min_num)
+{
+ *first= bitmap_get_first_set(&(m_part_info->used_partitions));
+ *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
+ *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
+}
+
/*
Return time for a scan of the table
@@ -5759,43 +5803,67 @@ const key_map *ha_partition::keys_to_use
double ha_partition::scan_time()
{
- double scan_time= 0;
- handler **file;
+ double scan_time= 0.0;
+ uint first, part_id, num_used_parts, check_min_num, partitions_called= 0;
DBUG_ENTER("ha_partition::scan_time");
- for (file= m_file; *file; file++)
- if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
- scan_time+= (*file)->scan_time();
+ partitions_optimizer_call_preparations(&first, &num_used_parts, &check_min_num);
+ for (part_id= first; partitions_called < num_used_parts ; part_id++)
+ {
+ if (!bitmap_is_set(&(m_part_info->used_partitions), part_id))
+ continue;
+ scan_time+= m_file[part_id]->scan_time();
+ partitions_called++;
+ if (partitions_called >= check_min_num && scan_time != 0.0)
+ {
+ DBUG_RETURN(scan_time *
+ (double) num_used_parts / (double) partitions_called);
+ }
+ }
DBUG_RETURN(scan_time);
}
/*
- Get time to read
+ Estimate rows for records_in_range or estimate_rows_upper_bound.
- SYNOPSIS
- read_time()
- index Index number used
- ranges Number of ranges
- rows Number of rows
-
- RETURN VALUE
- time for read
+ @param is_records_in_range call records_in_range instead of
+ estimate_rows_upper_bound.
+ @param inx (only for records_in_range) index to use.
+ @param min_key (only for records_in_range) start of range.
+ @param max_key (only for records_in_range) end of range.
- DESCRIPTION
- This will be optimised later to include whether or not the index can
- be used with partitioning. To achieve we need to add another parameter
- that specifies how many of the index fields that are bound in the ranges.
- Possibly added as a new call to handlers.
+ @return Number of rows or HA_POS_ERROR.
*/
-
-double ha_partition::read_time(uint index, uint ranges, ha_rows rows)
+ha_rows ha_partition::estimate_rows(bool is_records_in_range, uint inx,
+ key_range *min_key, key_range *max_key)
{
- DBUG_ENTER("ha_partition::read_time");
+ ha_rows rows, estimated_rows= 0;
+ uint first, part_id, num_used_parts, check_min_num, partitions_called= 0;
+ DBUG_ENTER("ha_partition::records_in_range");
- DBUG_RETURN(m_file[0]->read_time(index, ranges, rows));
+ partitions_optimizer_call_preparations(&first, &num_used_parts, &check_min_num);
+ for (part_id= first; partitions_called < num_used_parts ; part_id++)
+ {
+ if (!bitmap_is_set(&(m_part_info->used_partitions), part_id))
+ continue;
+ if (is_records_in_range)
+ rows= m_file[part_id]->records_in_range(inx, min_key, max_key);
+ else
+ rows= m_file[part_id]->estimate_rows_upper_bound();
+ if (rows == HA_POS_ERROR)
+ DBUG_RETURN(HA_POS_ERROR);
+ estimated_rows+= rows;
+ partitions_called++;
+ if (partitions_called >= check_min_num && estimated_rows)
+ {
+ DBUG_RETURN(estimated_rows * num_used_parts / partitions_called);
+ }
+ }
+ DBUG_RETURN(estimated_rows);
}
+
/*
Find number of records in a range
@@ -5823,22 +5891,9 @@ double ha_partition::read_time(uint inde
ha_rows ha_partition::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
{
- handler **file;
- ha_rows in_range= 0;
DBUG_ENTER("ha_partition::records_in_range");
- file= m_file;
- do
- {
- if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
- {
- ha_rows tmp_in_range= (*file)->records_in_range(inx, min_key, max_key);
- if (tmp_in_range == HA_POS_ERROR)
- DBUG_RETURN(tmp_in_range);
- in_range+= tmp_in_range;
- }
- } while (*(++file));
- DBUG_RETURN(in_range);
+ DBUG_RETURN(estimate_rows(TRUE, inx, min_key, max_key));
}
@@ -5854,22 +5909,36 @@ ha_rows ha_partition::records_in_range(u
ha_rows ha_partition::estimate_rows_upper_bound()
{
- ha_rows rows, tot_rows= 0;
- handler **file;
DBUG_ENTER("ha_partition::estimate_rows_upper_bound");
- file= m_file;
- do
- {
- if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
- {
- rows= (*file)->estimate_rows_upper_bound();
- if (rows == HA_POS_ERROR)
- DBUG_RETURN(HA_POS_ERROR);
- tot_rows+= rows;
- }
- } while (*(++file));
- DBUG_RETURN(tot_rows);
+ DBUG_RETURN(estimate_rows(FALSE, 0, NULL, NULL));
+}
+
+
+/*
+ Get time to read
+
+ SYNOPSIS
+ read_time()
+ index Index number used
+ ranges Number of ranges
+ rows Number of rows
+
+ RETURN VALUE
+ time for read
+
+ DESCRIPTION
+ This will be optimised later to include whether or not the index can
+ be used with partitioning. To achieve we need to add another parameter
+ that specifies how many of the index fields that are bound in the ranges.
+ Possibly added as a new call to handlers.
+*/
+
+double ha_partition::read_time(uint index, uint ranges, ha_rows rows)
+{
+ DBUG_ENTER("ha_partition::read_time");
+
+ DBUG_RETURN(m_file[0]->read_time(index, ranges, rows));
}
=== modified file 'sql/ha_partition.h'
--- a/sql/ha_partition.h 2009-12-03 11:19:05 +0000
+++ b/sql/ha_partition.h 2010-03-04 08:03:07 +0000
@@ -547,6 +547,18 @@ public:
-------------------------------------------------------------------------
*/
+private:
+ /*
+ Helper function to get the minimum number of partitions to use for
+ the optimizer hints/cost calls.
+ */
+ void partitions_optimizer_call_preparations(uint *num_used_parts,
+ uint *check_min_num,
+ uint *first);
+ ha_rows estimate_rows(bool is_records_in_range, uint inx,
+ key_range *min_key, key_range *max_key);
+public:
+
/*
keys_to_use_for_scanning can probably be implemented as the
intersection of all underlying handlers if mixed handlers are used.
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2009-12-16 08:13:18 +0000
+++ b/sql/handler.cc 2010-03-30 12:36:49 +0000
@@ -82,7 +82,7 @@ static plugin_ref ha_default_plugin(THD
{
if (thd->variables.table_plugin)
return thd->variables.table_plugin;
- return my_plugin_lock(thd, &global_system_variables.table_plugin);
+ return my_plugin_lock(thd, global_system_variables.table_plugin);
}
@@ -163,13 +163,8 @@ plugin_ref ha_lock_engine(THD *thd, hand
{
if (hton)
{
- st_plugin_int **plugin= hton2plugin + hton->slot;
-
-#ifdef DBUG_OFF
- return my_plugin_lock(thd, plugin);
-#else
- return my_plugin_lock(thd, &plugin);
-#endif
+ st_plugin_int *plugin= hton2plugin[hton->slot];
+ return my_plugin_lock(thd, plugin_int_to_ref(plugin));
}
return NULL;
}
@@ -4134,7 +4129,7 @@ int handler::read_multi_range_first(KEY_
*/
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
- int result;
+ int result= 0;
DBUG_ENTER("handler::read_multi_range_next");
/* We should not be called after the last call returned EOF. */
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2010-01-04 13:12:53 +0000
+++ b/sql/handler.h 2010-01-14 16:51:00 +0000
@@ -891,9 +891,9 @@ typedef struct {
ulonglong delete_length;
ha_rows records;
ulong mean_rec_length;
- ulong create_time;
- ulong check_time;
- ulong update_time;
+ time_t create_time;
+ time_t check_time;
+ time_t update_time;
ulonglong check_sum;
} PARTITION_INFO;
@@ -1060,9 +1060,9 @@ public:
ha_rows records;
ha_rows deleted; /* Deleted records */
ulong mean_rec_length; /* physical reclength */
- ulong create_time; /* When table was created */
- ulong check_time;
- ulong update_time;
+ time_t create_time; /* When table was created */
+ time_t check_time;
+ time_t update_time;
uint block_size; /* index block size */
ha_statistics():
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2009-12-03 11:19:05 +0000
+++ b/sql/item.cc 2010-03-28 18:10:00 +0000
@@ -4908,9 +4908,7 @@ Field *Item::tmp_table_field_from_field_
switch (field_type()) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
- field= new Field_new_decimal((uchar*) 0, max_length, null_ptr, 0,
- Field::NONE, name, decimals, 0,
- unsigned_flag);
+ field= Field_new_decimal::create_from_item(this);
break;
case MYSQL_TYPE_TINY:
field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
@@ -5152,7 +5150,7 @@ int Item::save_in_field(Field *field, bo
field->set_notnull();
error=field->store(nr, unsigned_flag);
}
- return error;
+ return error ? error : (field->table->in_use->is_error() ? 2 : 0);
}
@@ -6949,9 +6947,24 @@ int stored_field_cmp_to_item(THD *thd, F
Item_cache* Item_cache::get_cache(const Item *item)
{
- switch (item->result_type()) {
+ return get_cache(item, item->result_type());
+}
+
+
+/**
+ Get a cache item of given type.
+
+ @param item value to be cached
+ @param type required type of cache
+
+ @return cache item
+*/
+
+Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
+{
+ switch (type) {
case INT_RESULT:
- return new Item_cache_int();
+ return new Item_cache_int(item->field_type());
case REAL_RESULT:
return new Item_cache_real();
case DECIMAL_RESULT:
@@ -6967,6 +6980,13 @@ Item_cache* Item_cache::get_cache(const
}
}
+void Item_cache::store(Item *item)
+{
+ example= item;
+ if (!item)
+ null_value= TRUE;
+ value_cached= FALSE;
+}
void Item_cache::print(String *str, enum_query_type query_type)
{
@@ -6978,17 +6998,22 @@ void Item_cache::print(String *str, enum
str->append(')');
}
-
-void Item_cache_int::store(Item *item)
+bool Item_cache_int::cache_value()
{
- value= item->val_int_result();
- null_value= item->null_value;
- unsigned_flag= item->unsigned_flag;
+ if (!example)
+ return FALSE;
+ value_cached= TRUE;
+ value= example->val_int_result();
+ null_value= example->null_value;
+ unsigned_flag= example->unsigned_flag;
+ return TRUE;
}
-void Item_cache_int::store(Item *item, longlong val_arg)
+void Item_cache_int::store_longlong(Item *item, longlong val_arg)
{
+ /* An explicit values is given, save it. */
+ value_cached= TRUE;
value= val_arg;
null_value= item->null_value;
unsigned_flag= item->unsigned_flag;
@@ -6998,6 +7023,8 @@ void Item_cache_int::store(Item *item, l
String *Item_cache_int::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return NULL;
str->set(value, default_charset());
return str;
}
@@ -7006,21 +7033,52 @@ String *Item_cache_int::val_str(String *
my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return NULL;
int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_val);
return decimal_val;
}
+double Item_cache_int::val_real()
+{
+ DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return 0.0;
+ return (double) value;
+}
-void Item_cache_real::store(Item *item)
+longlong Item_cache_int::val_int()
{
- value= item->val_result();
- null_value= item->null_value;
+ DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return 0;
+ return value;
}
+bool Item_cache_real::cache_value()
+{
+ if (!example)
+ return FALSE;
+ value_cached= TRUE;
+ value= example->val_result();
+ null_value= example->null_value;
+ return TRUE;
+}
+
+
+double Item_cache_real::val_real()
+{
+ DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return 0.0;
+ return value;
+}
longlong Item_cache_real::val_int()
{
DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return 0;
return (longlong) rint(value);
}
@@ -7028,6 +7086,8 @@ longlong Item_cache_real::val_int()
String* Item_cache_real::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return NULL;
str->set_real(value, decimals, default_charset());
return str;
}
@@ -7036,22 +7096,30 @@ String* Item_cache_real::val_str(String
my_decimal *Item_cache_real::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return NULL;
double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
return decimal_val;
}
-void Item_cache_decimal::store(Item *item)
+bool Item_cache_decimal::cache_value()
{
- my_decimal *val= item->val_decimal_result(&decimal_value);
- if (!(null_value= item->null_value) && val != &decimal_value)
+ if (!example)
+ return FALSE;
+ value_cached= TRUE;
+ my_decimal *val= example->val_decimal_result(&decimal_value);
+ if (!(null_value= example->null_value) && val != &decimal_value)
my_decimal2decimal(val, &decimal_value);
+ return TRUE;
}
double Item_cache_decimal::val_real()
{
DBUG_ASSERT(fixed);
double res;
+ if (!value_cached && !cache_value())
+ return 0.0;
my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res);
return res;
}
@@ -7060,6 +7128,8 @@ longlong Item_cache_decimal::val_int()
{
DBUG_ASSERT(fixed);
longlong res;
+ if (!value_cached && !cache_value())
+ return 0;
my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res);
return res;
}
@@ -7067,6 +7137,8 @@ longlong Item_cache_decimal::val_int()
String* Item_cache_decimal::val_str(String *str)
{
DBUG_ASSERT(fixed);
+ if (!value_cached && !cache_value())
+ return NULL;
my_decimal_round(E_DEC_FATAL_ERROR, &decimal_value, decimals, FALSE,
&decimal_value);
my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, str);
@@ -7076,15 +7148,20 @@ String* Item_cache_decimal::val_str(Stri
my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
{
DBUG_ASSERT(fixed);
+ if (!value_cached && !cache_value())
+ return NULL;
return &decimal_value;
}
-void Item_cache_str::store(Item *item)
+bool Item_cache_str::cache_value()
{
- value_buff.set(buffer, sizeof(buffer), item->collation.collation);
- value= item->str_result(&value_buff);
- if ((null_value= item->null_value))
+ if (!example)
+ return FALSE;
+ value_cached= TRUE;
+ value_buff.set(buffer, sizeof(buffer), example->collation.collation);
+ value= example->str_result(&value_buff);
+ if ((null_value= example->null_value))
value= 0;
else if (value != &value_buff)
{
@@ -7099,6 +7176,7 @@ void Item_cache_str::store(Item *item)
value_buff.copy(*value);
value= &value_buff;
}
+ return TRUE;
}
double Item_cache_str::val_real()
@@ -7106,6 +7184,8 @@ double Item_cache_str::val_real()
DBUG_ASSERT(fixed == 1);
int err_not_used;
char *end_not_used;
+ if (!value_cached && !cache_value())
+ return 0.0;
if (value)
return my_strntod(value->charset(), (char*) value->ptr(),
value->length(), &end_not_used, &err_not_used);
@@ -7117,6 +7197,8 @@ longlong Item_cache_str::val_int()
{
DBUG_ASSERT(fixed == 1);
int err;
+ if (!value_cached && !cache_value())
+ return 0;
if (value)
return my_strntoll(value->charset(), value->ptr(),
value->length(), 10, (char**) 0, &err);
@@ -7124,9 +7206,21 @@ longlong Item_cache_str::val_int()
return (longlong)0;
}
+
+String* Item_cache_str::val_str(String *str)
+{
+ DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return 0;
+ return value;
+}
+
+
my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
+ if (!value_cached && !cache_value())
+ return NULL;
if (value)
string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
else
@@ -7137,6 +7231,8 @@ my_decimal *Item_cache_str::val_decimal(
int Item_cache_str::save_in_field(Field *field, bool no_conversions)
{
+ if (!value_cached && !cache_value())
+ return 0;
int res= Item_cache::save_in_field(field, no_conversions);
return (is_varbinary && field->type() == MYSQL_TYPE_STRING &&
value->length() < field->field_length) ? 1 : res;
@@ -7171,13 +7267,30 @@ bool Item_cache_row::setup(Item * item)
void Item_cache_row::store(Item * item)
{
+ example= item;
+ if (!item)
+ {
+ null_value= TRUE;
+ return;
+ }
+ for (uint i= 0; i < item_count; i++)
+ values[i]->store(item->element_index(i));
+}
+
+
+bool Item_cache_row::cache_value()
+{
+ if (!example)
+ return FALSE;
+ value_cached= TRUE;
null_value= 0;
- item->bring_value();
+ example->bring_value();
for (uint i= 0; i < item_count; i++)
{
- values[i]->store(item->element_index(i));
+ values[i]->cache_value();
null_value|= values[i]->null_value;
}
+ return TRUE;
}
=== modified file 'sql/item.h'
--- a/sql/item.h 2009-12-03 11:19:05 +0000
+++ b/sql/item.h 2010-03-30 12:36:49 +0000
@@ -506,6 +506,13 @@ public:
char * name; /* Name from select */
/* Original item name (if it was renamed)*/
char * orig_name;
+ /**
+ Intrusive list pointer for free list. If not null, points to the next
+ Item on some Query_arena's free list. For instance, stored procedures
+ have their own Query_arena's.
+
+ @see Query_arena::free_list
+ */
Item *next;
uint32 max_length;
uint name_length; /* Length of name */
@@ -963,6 +970,32 @@ public:
virtual Item *equal_fields_propagator(uchar * arg) { return this; }
virtual bool set_no_const_sub(uchar *arg) { return FALSE; }
virtual Item *replace_equal_field(uchar * arg) { return this; }
+ /*
+ Check if an expression value depends on the current timezone. Used by
+ partitioning code to reject timezone-dependent expressions in a
+ (sub)partitioning function.
+ */
+ virtual bool is_timezone_dependent_processor(uchar *bool_arg)
+ {
+ return FALSE;
+ }
+
+ /**
+ Find a function of a given type
+
+ @param arg the function type to search (enum Item_func::Functype)
+ @return
+ @retval TRUE the function type we're searching for is found
+ @retval FALSE the function type wasn't found
+
+ @description
+ This function can be used (together with Item::walk()) to find functions
+ in an item tree fragment.
+ */
+ virtual bool find_function_processor (uchar *arg)
+ {
+ return FALSE;
+ }
/*
For SP local variable returns pointer to Item representing its
@@ -1044,7 +1077,8 @@ class Field_enumerator
{
public:
virtual void visit_field(Field *field)= 0;
- virtual ~Field_enumerator() {}; /* purecov: inspected */
+ virtual ~Field_enumerator() {}; /* purecov: inspected */
+ Field_enumerator() {} /* Remove gcc warning */
};
@@ -1053,7 +1087,11 @@ class sp_head;
class Item_basic_constant :public Item
{
+ table_map used_table_map;
public:
+ Item_basic_constant(): Item(), used_table_map(0) {};
+ void set_used_tables(table_map map) { used_table_map= map; }
+ table_map used_tables() const { return used_table_map; }
/* to prevent drop fixed flag (no need parent cleanup call) */
void cleanup()
{
@@ -1065,7 +1103,6 @@ public:
if (orig_name)
name= orig_name;
}
- Item_basic_constant() {} /* Remove gcc warning */
};
@@ -2165,6 +2202,23 @@ public:
save_in_field(result_field, no_conversions);
}
void cleanup();
+ /*
+ This method is used for debug purposes to print the name of an
+ item to the debug log. The second use of this method is as
+ a helper function of print() and error messages, where it is
+ applicable. To suit both goals it should return a meaningful,
+ distinguishable and sintactically correct string. This method
+ should not be used for runtime type identification, use enum
+ {Sum}Functype and Item_func::functype()/Item_sum::sum_func()
+ instead.
+ Added here, to the parent class of both Item_func and Item_sum_func.
+
+ NOTE: for Items inherited from Item_sum, func_name() return part of
+ function name till first argument (including '(') to make difference in
+ names for functions with 'distinct' clause and without 'distinct' and
+ also to make printing of items inherited from Item_sum uniform.
+ */
+ virtual const char *func_name() const= 0;
};
@@ -2924,15 +2978,25 @@ protected:
*/
Field *cached_field;
enum enum_field_types cached_field_type;
-public:
- Item_cache():
- example(0), used_table_map(0), cached_field(0), cached_field_type(MYSQL_TYPE_STRING)
+ /*
+ TRUE <=> cache holds value of the last stored item (i.e actual value).
+ store() stores item to be cached and sets this flag to FALSE.
+ On the first call of val_xxx function if this flag is set to FALSE the
+ cache_value() will be called to actually cache value of saved item.
+ cache_value() will set this flag to TRUE.
+ */
+ bool value_cached;
+public:
+ Item_cache():
+ example(0), used_table_map(0), cached_field(0), cached_field_type(MYSQL_TYPE_STRING),
+ value_cached(0)
{
fixed= 1;
null_value= 1;
}
Item_cache(enum_field_types field_type_arg):
- example(0), used_table_map(0), cached_field(0), cached_field_type(field_type_arg)
+ example(0), used_table_map(0), cached_field(0), cached_field_type(field_type_arg),
+ value_cached(0)
{
fixed= 1;
null_value= 1;
@@ -2952,10 +3016,10 @@ public:
cached_field= ((Item_field *)item)->field;
return 0;
};
- virtual void store(Item *)= 0;
enum Type type() const { return CACHE_ITEM; }
enum_field_types field_type() const { return cached_field_type; }
static Item_cache* get_cache(const Item *item);
+ static Item_cache* get_cache(const Item* item, const Item_result type);
table_map used_tables() const { return used_table_map; }
virtual void keep_array() {}
virtual void print(String *str, enum_query_type query_type);
@@ -2967,6 +3031,8 @@ public:
{
return this == item;
}
+ virtual void store(Item *item);
+ virtual bool cache_value()= 0;
};
@@ -2975,18 +3041,19 @@ class Item_cache_int: public Item_cache
protected:
longlong value;
public:
- Item_cache_int(): Item_cache(), value(0) {}
+ Item_cache_int(): Item_cache(),
+ value(0) {}
Item_cache_int(enum_field_types field_type_arg):
Item_cache(field_type_arg), value(0) {}
- void store(Item *item);
- void store(Item *item, longlong val_arg);
- double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
- longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
+ void store_longlong(Item *item, longlong val_arg);
+ double val_real();
+ longlong val_int();
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type() const { return INT_RESULT; }
bool result_as_longlong() { return TRUE; }
+ bool cache_value();
};
@@ -2994,14 +3061,15 @@ class Item_cache_real: public Item_cache
{
double value;
public:
- Item_cache_real(): Item_cache(), value(0) {}
+ Item_cache_real(): Item_cache(),
+ value(0) {}
- void store(Item *item);
- double val_real() { DBUG_ASSERT(fixed == 1); return value; }
+ double val_real();
longlong val_int();
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type() const { return REAL_RESULT; }
+ bool cache_value();
};
@@ -3012,12 +3080,12 @@ protected:
public:
Item_cache_decimal(): Item_cache() {}
- void store(Item *item);
double val_real();
longlong val_int();
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type() const { return DECIMAL_RESULT; }
+ bool cache_value();
};
@@ -3035,14 +3103,14 @@ public:
MYSQL_TYPE_VARCHAR &&
!((const Item_field *) item)->field->has_charset())
{}
- void store(Item *item);
double val_real();
longlong val_int();
- String* val_str(String *) { DBUG_ASSERT(fixed == 1); return value; }
+ String* val_str(String *);
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type() const { return STRING_RESULT; }
CHARSET_INFO *charset() const { return value->charset(); };
int save_in_field(Field *field, bool no_conversions);
+ bool cache_value();
};
class Item_cache_row: public Item_cache
@@ -3052,7 +3120,8 @@ class Item_cache_row: public Item_cache
bool save_array;
public:
Item_cache_row()
- :Item_cache(), values(0), item_count(2), save_array(0) {}
+ :Item_cache(), values(0), item_count(2),
+ save_array(0) {}
/*
'allocate' used only in row transformer, to preallocate space for row
@@ -3110,6 +3179,7 @@ public:
values= 0;
DBUG_VOID_RETURN;
}
+ bool cache_value();
};
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2009-12-03 11:19:05 +0000
+++ b/sql/item_cmpfunc.cc 2010-03-28 18:10:00 +0000
@@ -30,6 +30,9 @@
#include "sql_select.h"
static bool convert_constant_item(THD *, Item_field *, Item **);
+static longlong
+get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
+ Item *warn_item, bool *is_null);
static Item_result item_store_type(Item_result a, Item *item,
my_bool unsigned_flag)
@@ -533,11 +536,12 @@ void Item_bool_func2::fix_length_and_dec
}
-int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
+int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type)
{
owner= item;
func= comparator_matrix[type]
- [test(owner->functype() == Item_func::EQUAL_FUNC)];
+ [is_owner_equal_func()];
+
switch (type) {
case ROW_RESULT:
{
@@ -557,7 +561,8 @@ int Arg_comparator::set_compare_func(Ite
my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
return 1;
}
- if (comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i)))
+ if (comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i),
+ set_null))
return 1;
}
break;
@@ -571,7 +576,8 @@ int Arg_comparator::set_compare_func(Ite
if (cmp_collation.set((*a)->collation, (*b)->collation) ||
cmp_collation.derivation == DERIVATION_NONE)
{
- my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
+ my_coll_agg_error((*a)->collation, (*b)->collation,
+ owner->func_name());
return 1;
}
if (cmp_collation.collation == &my_charset_bin)
@@ -785,15 +791,21 @@ Arg_comparator::can_compare_as_dates(Ite
if (cmp_type != CMP_DATE_DFLT)
{
+ THD *thd= current_thd;
/*
Do not cache GET_USER_VAR() function as its const_item() may return TRUE
for the current thread but it still may change during the execution.
+ Don't use cache while in the context analysis mode only (i.e. for
+ EXPLAIN/CREATE VIEW and similar queries). Cache is useless in such
+ cases and can cause problems. For example evaluating subqueries can
+ confuse storage engines since in context analysis mode tables
+ aren't locked.
*/
- if (cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() &&
+ if (!thd->is_context_analysis_only() &&
+ cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() &&
(str_arg->type() != Item::FUNC_ITEM ||
((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
{
- THD *thd= current_thd;
ulonglong value;
bool error;
String tmp, *str_val= 0;
@@ -867,7 +879,7 @@ get_time_value(THD *thd, Item ***item_ar
Item_cache_int *cache= new Item_cache_int();
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
@@ -875,18 +887,20 @@ get_time_value(THD *thd, Item ***item_ar
}
-int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
+int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
Item **a1, Item **a2,
Item_result type)
{
ulonglong const_value= (ulonglong)-1;
+ thd= current_thd;
+ owner= owner_arg;
+ set_null= set_null && owner_arg;
a= a1;
b= a2;
+ thd= current_thd;
if (can_compare_as_dates(*a, *b, &const_value))
{
- thd= current_thd;
- owner= owner_arg;
a_type= (*a)->field_type();
b_type= (*b)->field_type();
a_cache= 0;
@@ -894,38 +908,42 @@ int Arg_comparator::set_cmp_func(Item_bo
if (const_value != (ulonglong)-1)
{
+ /*
+ cache_converted_constant can't be used here because it can't
+ correctly convert a DATETIME value from string to int representation.
+ */
Item_cache_int *cache= new Item_cache_int();
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
if (!(*a)->is_datetime())
{
- cache->store((*a), const_value);
+ cache->store_longlong((*a), const_value);
a_cache= cache;
a= (Item **)&a_cache;
}
else
{
- cache->store((*b), const_value);
+ cache->store_longlong((*b), const_value);
b_cache= cache;
b= (Item **)&b_cache;
}
}
- is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
+ is_nulls_eq= is_owner_equal_func();
func= &Arg_comparator::compare_datetime;
- get_value_func= &get_datetime_value;
+ get_value_a_func= &get_datetime_value;
+ get_value_b_func= &get_datetime_value;
return 0;
}
else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME &&
(*b)->field_type() == MYSQL_TYPE_TIME)
{
/* Compare TIME values as integers. */
- thd= current_thd;
- owner= owner_arg;
a_cache= 0;
b_cache= 0;
- is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
+ is_nulls_eq= is_owner_equal_func();
func= &Arg_comparator::compare_datetime;
- get_value_func= &get_time_value;
+ get_value_a_func= &get_time_value;
+ get_value_b_func= &get_time_value;
return 0;
}
else if (type == STRING_RESULT &&
@@ -934,20 +952,97 @@ int Arg_comparator::set_cmp_func(Item_bo
{
DTCollation coll;
coll.set((*a)->collation.collation);
- if (agg_item_set_converter(coll, owner_arg->func_name(),
+ if (agg_item_set_converter(coll, owner->func_name(),
b, 1, MY_COLL_CMP_CONV, 1))
return 1;
}
+ else if (try_year_cmp_func(type))
+ return 0;
+ a= cache_converted_constant(thd, a, &a_cache, type);
+ b= cache_converted_constant(thd, b, &b_cache, type);
return set_compare_func(owner_arg, type);
}
-void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
+/*
+ Helper function to call from Arg_comparator::set_cmp_func()
+*/
+
+bool Arg_comparator::try_year_cmp_func(Item_result type)
+{
+ if (type == ROW_RESULT)
+ return FALSE;
+
+ bool a_is_year= (*a)->field_type() == MYSQL_TYPE_YEAR;
+ bool b_is_year= (*b)->field_type() == MYSQL_TYPE_YEAR;
+
+ if (!a_is_year && !b_is_year)
+ return FALSE;
+
+ if (a_is_year && b_is_year)
+ {
+ get_value_a_func= &get_year_value;
+ get_value_b_func= &get_year_value;
+ }
+ else if (a_is_year && (*b)->is_datetime())
+ {
+ get_value_a_func= &get_year_value;
+ get_value_b_func= &get_datetime_value;
+ }
+ else if (b_is_year && (*a)->is_datetime())
+ {
+ get_value_b_func= &get_year_value;
+ get_value_a_func= &get_datetime_value;
+ }
+ else
+ return FALSE;
+
+ is_nulls_eq= is_owner_equal_func();
+ func= &Arg_comparator::compare_datetime;
+
+ return TRUE;
+}
+
+/**
+ Convert and cache a constant.
+
+ @param value [in] An item to cache
+ @param cache_item [out] Placeholder for the cache item
+ @param type [in] Comparison type
+
+ @details
+ When given item is a constant and its type differs from comparison type
+ then cache its value to avoid type conversion of this constant on each
+ evaluation. In this case the value is cached and the reference to the cache
+ is returned.
+ Original value is returned otherwise.
+
+ @return cache item or original value.
+*/
+
+Item** Arg_comparator::cache_converted_constant(THD *thd, Item **value,
+ Item **cache_item,
+ Item_result type)
+{
+ /* Don't need cache if doing context analysis only. */
+ if (!thd->is_context_analysis_only() &&
+ (*value)->const_item() && type != (*value)->result_type())
+ {
+ Item_cache *cache= Item_cache::get_cache(*value, type);
+ cache->setup(*value);
+ *cache_item= cache;
+ return cache_item;
+ }
+ return value;
+}
+
+
+void Arg_comparator::set_datetime_cmp_func(Item_result_field *owner_arg,
+ Item **a1, Item **b1)
{
thd= current_thd;
- /* A caller will handle null values by itself. */
- owner= NULL;
+ owner= owner_arg;
a= a1;
b= b1;
a_type= (*a)->field_type();
@@ -956,7 +1051,8 @@ void Arg_comparator::set_datetime_cmp_fu
b_cache= 0;
is_nulls_eq= FALSE;
func= &Arg_comparator::compare_datetime;
- get_value_func= &get_datetime_value;
+ get_value_a_func= &get_datetime_value;
+ get_value_b_func= &get_datetime_value;
}
@@ -1049,13 +1145,63 @@ get_datetime_value(THD *thd, Item ***ite
Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
return value;
}
+
+/*
+ Retrieves YEAR value of 19XX-00-00 00:00:00 form from given item.
+
+ SYNOPSIS
+ get_year_value()
+ thd thread handle
+ item_arg [in/out] item to retrieve YEAR value from
+ cache_arg [in/out] pointer to place to store the caching item to
+ warn_item [in] item for issuing the conversion warning
+ is_null [out] TRUE <=> the item_arg is null
+
+ DESCRIPTION
+ Retrieves the YEAR value of 19XX form from given item for comparison by the
+ compare_datetime() function.
+ Converts year to DATETIME of form YYYY-00-00 00:00:00 for the compatibility
+ with the get_datetime_value function result.
+
+ RETURN
+ obtained value
+*/
+
+static longlong
+get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
+ Item *warn_item, bool *is_null)
+{
+ longlong value= 0;
+ Item *item= **item_arg;
+
+ value= item->val_int();
+ *is_null= item->null_value;
+ if (*is_null)
+ return ~(ulonglong) 0;
+
+ /*
+ Coerce value to the 19XX form in order to correctly compare
+ YEAR(2) & YEAR(4) types.
+ */
+ if (value < 70)
+ value+= 100;
+ if (value <= 1900)
+ value+= 1900;
+
+ /* Convert year to DATETIME of form YYYY-00-00 00:00:00 (YYYY0000000000). */
+ value*= 10000000000LL;
+
+ return value;
+}
+
+
/*
Compare items values as dates.
@@ -1088,25 +1234,25 @@ int Arg_comparator::compare_datetime()
longlong a_value, b_value;
/* Get DATE/DATETIME/TIME value of the 'a' item. */
- a_value= (*get_value_func)(thd, &a, &a_cache, *b, &a_is_null);
+ a_value= (*get_value_a_func)(thd, &a, &a_cache, *b, &a_is_null);
if (!is_nulls_eq && a_is_null)
{
- if (owner)
+ if (set_null)
owner->null_value= 1;
return -1;
}
/* Get DATE/DATETIME/TIME value of the 'b' item. */
- b_value= (*get_value_func)(thd, &b, &b_cache, *a, &b_is_null);
+ b_value= (*get_value_b_func)(thd, &b, &b_cache, *a, &b_is_null);
if (a_is_null || b_is_null)
{
- if (owner)
+ if (set_null)
owner->null_value= is_nulls_eq ? 0 : 1;
return is_nulls_eq ? (a_is_null == b_is_null) : -1;
}
/* Here we have two not-NULL values. */
- if (owner)
+ if (set_null)
owner->null_value= 0;
/* Compare values. */
@@ -1119,15 +1265,17 @@ int Arg_comparator::compare_datetime()
int Arg_comparator::compare_string()
{
String *res1,*res2;
- if ((res1= (*a)->val_str(&owner->tmp_value1)))
+ if ((res1= (*a)->val_str(&value1)))
{
- if ((res2= (*b)->val_str(&owner->tmp_value2)))
+ if ((res2= (*b)->val_str(&value2)))
{
- owner->null_value= 0;
+ if (set_null)
+ owner->null_value= 0;
return sortcmp(res1,res2,cmp_collation.collation);
}
}
- owner->null_value= 1;
+ if (set_null)
+ owner->null_value= 1;
return -1;
}
@@ -1146,18 +1294,20 @@ int Arg_comparator::compare_string()
int Arg_comparator::compare_binary_string()
{
String *res1,*res2;
- if ((res1= (*a)->val_str(&owner->tmp_value1)))
+ if ((res1= (*a)->val_str(&value1)))
{
- if ((res2= (*b)->val_str(&owner->tmp_value2)))
+ if ((res2= (*b)->val_str(&value2)))
{
- owner->null_value= 0;
+ if (set_null)
+ owner->null_value= 0;
uint res1_length= res1->length();
uint res2_length= res2->length();
int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
return cmp ? cmp : (int) (res1_length - res2_length);
}
}
- owner->null_value= 1;
+ if (set_null)
+ owner->null_value= 1;
return -1;
}
@@ -1170,8 +1320,8 @@ int Arg_comparator::compare_binary_strin
int Arg_comparator::compare_e_string()
{
String *res1,*res2;
- res1= (*a)->val_str(&owner->tmp_value1);
- res2= (*b)->val_str(&owner->tmp_value2);
+ res1= (*a)->val_str(&value1);
+ res2= (*b)->val_str(&value2);
if (!res1 || !res2)
return test(res1 == res2);
return test(sortcmp(res1, res2, cmp_collation.collation) == 0);
@@ -1181,8 +1331,8 @@ int Arg_comparator::compare_e_string()
int Arg_comparator::compare_e_binary_string()
{
String *res1,*res2;
- res1= (*a)->val_str(&owner->tmp_value1);
- res2= (*b)->val_str(&owner->tmp_value2);
+ res1= (*a)->val_str(&value1);
+ res2= (*b)->val_str(&value2);
if (!res1 || !res2)
return test(res1 == res2);
return test(stringcmp(res1, res2) == 0);
@@ -1203,13 +1353,15 @@ int Arg_comparator::compare_real()
val2= (*b)->val_real();
if (!(*b)->null_value)
{
- owner->null_value= 0;
+ if (set_null)
+ owner->null_value= 0;
if (val1 < val2) return -1;
if (val1 == val2) return 0;
return 1;
}
}
- owner->null_value= 1;
+ if (set_null)
+ owner->null_value= 1;
return -1;
}
@@ -1223,11 +1375,13 @@ int Arg_comparator::compare_decimal()
my_decimal *val2= (*b)->val_decimal(&value2);
if (!(*b)->null_value)
{
- owner->null_value= 0;
+ if (set_null)
+ owner->null_value= 0;
return my_decimal_cmp(val1, val2);
}
}
- owner->null_value= 1;
+ if (set_null)
+ owner->null_value= 1;
return -1;
}
@@ -1265,7 +1419,8 @@ int Arg_comparator::compare_real_fixed()
val2= (*b)->val_real();
if (!(*b)->null_value)
{
- owner->null_value= 0;
+ if (set_null)
+ owner->null_value= 0;
if (val1 == val2 || fabs(val1 - val2) < precision)
return 0;
if (val1 < val2)
@@ -1273,7 +1428,8 @@ int Arg_comparator::compare_real_fixed()
return 1;
}
}
- owner->null_value= 1;
+ if (set_null)
+ owner->null_value= 1;
return -1;
}
@@ -1296,13 +1452,15 @@ int Arg_comparator::compare_int_signed()
longlong val2= (*b)->val_int();
if (!(*b)->null_value)
{
- owner->null_value= 0;
+ if (set_null)
+ owner->null_value= 0;
if (val1 < val2) return -1;
if (val1 == val2) return 0;
return 1;
}
}
- owner->null_value= 1;
+ if (set_null)
+ owner->null_value= 1;
return -1;
}
@@ -1319,13 +1477,15 @@ int Arg_comparator::compare_int_unsigned
ulonglong val2= (*b)->val_int();
if (!(*b)->null_value)
{
- owner->null_value= 0;
+ if (set_null)
+ owner->null_value= 0;
if (val1 < val2) return -1;
if (val1 == val2) return 0;
return 1;
}
}
- owner->null_value= 1;
+ if (set_null)
+ owner->null_value= 1;
return -1;
}
@@ -1342,7 +1502,8 @@ int Arg_comparator::compare_int_signed_u
ulonglong uval2= (ulonglong)(*b)->val_int();
if (!(*b)->null_value)
{
- owner->null_value= 0;
+ if (set_null)
+ owner->null_value= 0;
if (sval1 < 0 || (ulonglong)sval1 < uval2)
return -1;
if ((ulonglong)sval1 == uval2)
@@ -1350,7 +1511,8 @@ int Arg_comparator::compare_int_signed_u
return 1;
}
}
- owner->null_value= 1;
+ if (set_null)
+ owner->null_value= 1;
return -1;
}
@@ -1367,7 +1529,8 @@ int Arg_comparator::compare_int_unsigned
longlong sval2= (*b)->val_int();
if (!(*b)->null_value)
{
- owner->null_value= 0;
+ if (set_null)
+ owner->null_value= 0;
if (sval2 < 0)
return 1;
if (uval1 < (ulonglong)sval2)
@@ -1377,7 +1540,8 @@ int Arg_comparator::compare_int_unsigned
return 1;
}
}
- owner->null_value= 1;
+ if (set_null)
+ owner->null_value= 1;
return -1;
}
@@ -1413,10 +1577,11 @@ int Arg_comparator::compare_row()
for (uint i= 0; i<n; i++)
{
res= comparators[i].compare();
- if (owner->null_value)
+ /* Aggregate functions don't need special null handling. */
+ if (owner->null_value && owner->type() == Item::FUNC_ITEM)
{
// NULL was compared
- switch (owner->functype()) {
+ switch (((Item_func*)owner)->functype()) {
case Item_func::NE_FUNC:
break; // NE never aborts on NULL even if abort_on_null is set
case Item_func::LT_FUNC:
@@ -1425,7 +1590,7 @@ int Arg_comparator::compare_row()
case Item_func::GE_FUNC:
return -1; // <, <=, > and >= always fail on NULL
default: // EQ_FUNC
- if (owner->abort_on_null)
+ if (((Item_bool_func2*)owner)->abort_on_null)
return -1; // We do not need correct NULL returning
}
was_null= 1;
@@ -1581,6 +1746,7 @@ longlong Item_in_optimizer::val_int()
bool tmp;
DBUG_ASSERT(fixed == 1);
cache->store(args[0]);
+ cache->cache_value();
if (cache->null_value)
{
@@ -1748,8 +1914,8 @@ longlong Item_func_lt::val_int()
longlong Item_func_strcmp::val_int()
{
DBUG_ASSERT(fixed == 1);
- String *a=args[0]->val_str(&tmp_value1);
- String *b=args[1]->val_str(&tmp_value2);
+ String *a=args[0]->val_str(&cmp.value1);
+ String *b=args[1]->val_str(&cmp.value2);
if (!a || !b)
{
null_value=1;
@@ -2032,8 +2198,8 @@ void Item_func_between::fix_length_and_d
if (compare_as_dates)
{
- ge_cmp.set_datetime_cmp_func(args, args + 1);
- le_cmp.set_datetime_cmp_func(args, args + 2);
+ ge_cmp.set_datetime_cmp_func(this, args, args + 1);
+ le_cmp.set_datetime_cmp_func(this, args, args + 2);
}
else if (time_items_found == 3)
{
@@ -4085,7 +4251,7 @@ Item *Item_cond::compile(Item_analyzer a
uchar *arg_v= *arg_p;
Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
if (new_item && new_item != item)
- li.replace(new_item);
+ current_thd->change_item_tree(li.ref(), new_item);
}
return Item_func::transform(transformer, arg_t);
}
@@ -4370,13 +4536,13 @@ void Item_func_isnotnull::print(String *
longlong Item_func_like::val_int()
{
DBUG_ASSERT(fixed == 1);
- String* res = args[0]->val_str(&tmp_value1);
+ String* res = args[0]->val_str(&cmp.value1);
if (args[0]->null_value)
{
null_value=1;
return 0;
}
- String* res2 = args[1]->val_str(&tmp_value2);
+ String* res2 = args[1]->val_str(&cmp.value2);
if (args[1]->null_value)
{
null_value=1;
@@ -4400,7 +4566,7 @@ Item_func::optimize_type Item_func_like:
{
if (args[1]->const_item())
{
- String* res2= args[1]->val_str((String *)&tmp_value2);
+ String* res2= args[1]->val_str((String *)&cmp.value2);
if (!res2)
return OPTIMIZE_NONE;
@@ -4431,7 +4597,7 @@ bool Item_func_like::fix_fields(THD *thd
if (escape_item->const_item())
{
/* If we are on execution stage */
- String *escape_str= escape_item->val_str(&tmp_value1);
+ String *escape_str= escape_item->val_str(&cmp.value1);
if (escape_str)
{
if (escape_used_in_parsing && (
@@ -4486,7 +4652,7 @@ bool Item_func_like::fix_fields(THD *thd
if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
!(specialflag & SPECIAL_NO_NEW_FUNC))
{
- String* res2 = args[1]->val_str(&tmp_value2);
+ String* res2 = args[1]->val_str(&cmp.value2);
if (!res2)
return FALSE; // Null argument
@@ -5086,7 +5252,8 @@ Item *Item_bool_rowready_func2::negated_
}
Item_equal::Item_equal(Item_field *f1, Item_field *f2)
- : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
+ : Item_bool_func(), const_item(0), eval_item(0), cond_false(0),
+ compare_as_dates(FALSE)
{
const_item_cache= 0;
fields.push_back(f1);
@@ -5099,6 +5266,7 @@ Item_equal::Item_equal(Item *c, Item_fie
const_item_cache= 0;
fields.push_back(f);
const_item= c;
+ compare_as_dates= f->is_datetime();
}
@@ -5113,9 +5281,45 @@ Item_equal::Item_equal(Item_equal *item_
fields.push_back(item);
}
const_item= item_equal->const_item;
+ compare_as_dates= item_equal->compare_as_dates;
cond_false= item_equal->cond_false;
}
+
+void Item_equal::compare_const(Item *c)
+{
+ if (compare_as_dates)
+ {
+ cmp.set_datetime_cmp_func(this, &c, &const_item);
+ cond_false= cmp.compare();
+ }
+ else
+ {
+ Item_func_eq *func= new Item_func_eq(c, const_item);
+ func->set_cmp_func();
+ func->quick_fix_field();
+ cond_false= !func->val_int();
+ }
+ if (cond_false)
+ const_item_cache= 1;
+}
+
+
+void Item_equal::add(Item *c, Item_field *f)
+{
+ if (cond_false)
+ return;
+ if (!const_item)
+ {
+ DBUG_ASSERT(f);
+ const_item= c;
+ compare_as_dates= f->is_datetime();
+ return;
+ }
+ compare_const(c);
+}
+
+
void Item_equal::add(Item *c)
{
if (cond_false)
@@ -5125,11 +5329,7 @@ void Item_equal::add(Item *c)
const_item= c;
return;
}
- Item_func_eq *func= new Item_func_eq(c, const_item);
- func->set_cmp_func();
- func->quick_fix_field();
- if ((cond_false= !func->val_int()))
- const_item_cache= 1;
+ compare_const(c);
}
void Item_equal::add(Item_field *f)
=== modified file 'sql/item_cmpfunc.h'
--- a/sql/item_cmpfunc.h 2009-12-03 11:19:05 +0000
+++ b/sql/item_cmpfunc.h 2010-03-04 08:03:07 +0000
@@ -32,7 +32,7 @@ class Arg_comparator: public Sql_alloc
{
Item **a, **b;
arg_cmp_func func;
- Item_bool_func2 *owner;
+ Item_result_field *owner;
Arg_comparator *comparators; // used only for compare_row()
double precision;
/* Fields used in DATE/DATETIME comparison. */
@@ -40,30 +40,40 @@ class Arg_comparator: public Sql_alloc
enum_field_types a_type, b_type; // Types of a and b items
Item *a_cache, *b_cache; // Cached values of a and b items
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
+ bool set_null; // TRUE <=> set owner->null_value
+ // when one of arguments is NULL.
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
- longlong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
- Item *warn_item, bool *is_null);
+ longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg,
+ Item *warn_item, bool *is_null);
+ longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg,
+ Item *warn_item, bool *is_null);
+ bool try_year_cmp_func(Item_result type);
public:
DTCollation cmp_collation;
+ /* Allow owner function to use string buffers. */
+ String value1, value2;
- Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
+ Arg_comparator(): thd(0), a_cache(0), b_cache(0), set_null(TRUE),
+ get_value_a_func(0), get_value_b_func(0) {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
- a_cache(0), b_cache(0) {};
+ a_cache(0), b_cache(0), set_null(TRUE),
+ get_value_a_func(0), get_value_b_func(0) {};
- int set_compare_func(Item_bool_func2 *owner, Item_result type);
- inline int set_compare_func(Item_bool_func2 *owner_arg)
+ int set_compare_func(Item_result_field *owner, Item_result type);
+ inline int set_compare_func(Item_result_field *owner_arg)
{
return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
(*b)->result_type()));
}
- int set_cmp_func(Item_bool_func2 *owner_arg,
+ int set_cmp_func(Item_result_field *owner_arg,
Item **a1, Item **a2,
Item_result type);
- inline int set_cmp_func(Item_bool_func2 *owner_arg,
- Item **a1, Item **a2)
+ inline int set_cmp_func(Item_result_field *owner_arg,
+ Item **a1, Item **a2, bool set_null_arg)
{
+ set_null= set_null_arg;
return set_cmp_func(owner_arg, a1, a2,
item_cmp_type((*a1)->result_type(),
(*a2)->result_type()));
@@ -93,8 +103,15 @@ public:
static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
ulonglong *const_val_arg);
- void set_datetime_cmp_func(Item **a1, Item **b1);
+ Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
+ Item_result type);
+ void set_datetime_cmp_func(Item_result_field *owner_arg, Item **a1, Item **b1);
static arg_cmp_func comparator_matrix [5][2];
+ inline bool is_owner_equal_func()
+ {
+ return (owner->type() == Item::FUNC_ITEM &&
+ ((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
+ }
friend class Item_func;
};
@@ -324,7 +341,6 @@ class Item_bool_func2 :public Item_int_f
{ /* Bool with 2 string args */
protected:
Arg_comparator cmp;
- String tmp_value1,tmp_value2;
bool abort_on_null;
public:
@@ -333,7 +349,7 @@ public:
void fix_length_and_dec();
void set_cmp_func()
{
- cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
+ cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, TRUE);
}
optimize_type select_optimize() const { return OPTIMIZE_OP; }
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
@@ -1564,7 +1580,9 @@ class Item_equal: public Item_bool_func
List<Item_field> fields; /* list of equal field items */
Item *const_item; /* optional constant item equal to fields items */
cmp_item *eval_item;
+ Arg_comparator cmp;
bool cond_false;
+ bool compare_as_dates;
public:
inline Item_equal()
: Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
@@ -1573,6 +1591,8 @@ public:
Item_equal(Item *c, Item_field *f);
Item_equal(Item_equal *item_equal);
inline Item* get_const() { return const_item; }
+ void compare_const(Item *c);
+ void add(Item *c, Item_field *f);
void add(Item *c);
void add(Item_field *f);
uint members();
=== modified file 'sql/item_create.cc'
--- a/sql/item_create.cc 2009-10-15 21:38:29 +0000
+++ b/sql/item_create.cc 2010-03-29 19:07:45 +0000
@@ -76,7 +76,7 @@ public:
@param thd The current thread
@return An item representing the function call
*/
- virtual Item *create(THD *thd) = 0;
+ virtual Item *create_builder(THD *thd) = 0;
protected:
/** Constructor. */
@@ -101,7 +101,7 @@ public:
@param arg1 The first argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1) = 0;
+ virtual Item *create_1_arg(THD *thd, Item *arg1) = 0;
protected:
/** Constructor. */
@@ -127,7 +127,7 @@ public:
@param arg2 The second argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2) = 0;
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) = 0;
protected:
/** Constructor. */
@@ -154,7 +154,7 @@ public:
@param arg3 The third argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
protected:
/** Constructor. */
@@ -171,8 +171,8 @@ protected:
class Create_sp_func : public Create_qfunc
{
public:
- virtual Item *create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list);
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list);
static Create_sp_func s_singleton;
@@ -217,7 +217,7 @@ protected:
class Create_func_abs : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_abs s_singleton;
@@ -230,7 +230,7 @@ protected:
class Create_func_acos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_acos s_singleton;
@@ -243,7 +243,7 @@ protected:
class Create_func_addtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_addtime s_singleton;
@@ -256,7 +256,7 @@ protected:
class Create_func_aes_encrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_encrypt s_singleton;
@@ -269,7 +269,7 @@ protected:
class Create_func_aes_decrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_decrypt s_singleton;
@@ -283,7 +283,7 @@ protected:
class Create_func_area : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_area s_singleton;
@@ -298,7 +298,7 @@ protected:
class Create_func_as_wkb : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkb s_singleton;
@@ -313,7 +313,7 @@ protected:
class Create_func_as_wkt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkt s_singleton;
@@ -327,7 +327,7 @@ protected:
class Create_func_asin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_asin s_singleton;
@@ -353,7 +353,7 @@ protected:
class Create_func_benchmark : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_benchmark s_singleton;
@@ -366,7 +366,7 @@ protected:
class Create_func_bin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bin s_singleton;
@@ -379,7 +379,7 @@ protected:
class Create_func_bit_count : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_count s_singleton;
@@ -392,7 +392,7 @@ protected:
class Create_func_bit_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_length s_singleton;
@@ -405,7 +405,7 @@ protected:
class Create_func_ceiling : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ceiling s_singleton;
@@ -419,7 +419,7 @@ protected:
class Create_func_centroid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_centroid s_singleton;
@@ -433,7 +433,7 @@ protected:
class Create_func_char_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_char_length s_singleton;
@@ -446,7 +446,7 @@ protected:
class Create_func_coercibility : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_coercibility s_singleton;
@@ -459,7 +459,7 @@ protected:
class Create_func_compress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_compress s_singleton;
@@ -498,7 +498,7 @@ protected:
class Create_func_connection_id : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_connection_id s_singleton;
@@ -512,7 +512,7 @@ protected:
class Create_func_contains : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_contains s_singleton;
@@ -526,7 +526,7 @@ protected:
class Create_func_conv : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_conv s_singleton;
@@ -539,7 +539,7 @@ protected:
class Create_func_convert_tz : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_convert_tz s_singleton;
@@ -552,7 +552,7 @@ protected:
class Create_func_cos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cos s_singleton;
@@ -565,7 +565,7 @@ protected:
class Create_func_cot : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cot s_singleton;
@@ -578,7 +578,7 @@ protected:
class Create_func_crc32 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_crc32 s_singleton;
@@ -592,7 +592,7 @@ protected:
class Create_func_crosses : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_crosses s_singleton;
@@ -606,7 +606,7 @@ protected:
class Create_func_date_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_date_format s_singleton;
@@ -619,7 +619,7 @@ protected:
class Create_func_datediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_datediff s_singleton;
@@ -632,7 +632,7 @@ protected:
class Create_func_dayname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayname s_singleton;
@@ -645,7 +645,7 @@ protected:
class Create_func_dayofmonth : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofmonth s_singleton;
@@ -658,7 +658,7 @@ protected:
class Create_func_dayofweek : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofweek s_singleton;
@@ -671,7 +671,7 @@ protected:
class Create_func_dayofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofyear s_singleton;
@@ -684,7 +684,7 @@ protected:
class Create_func_decode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_decode s_singleton;
@@ -697,7 +697,7 @@ protected:
class Create_func_degrees : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_degrees s_singleton;
@@ -737,7 +737,7 @@ protected:
class Create_func_dimension : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dimension s_singleton;
@@ -752,7 +752,7 @@ protected:
class Create_func_disjoint : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_disjoint s_singleton;
@@ -779,7 +779,7 @@ protected:
class Create_func_encode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_encode s_singleton;
@@ -806,7 +806,7 @@ protected:
class Create_func_endpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_endpoint s_singleton;
@@ -821,7 +821,7 @@ protected:
class Create_func_envelope : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_envelope s_singleton;
@@ -836,7 +836,7 @@ protected:
class Create_func_equals : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_equals s_singleton;
@@ -850,7 +850,7 @@ protected:
class Create_func_exp : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exp s_singleton;
@@ -877,7 +877,7 @@ protected:
class Create_func_exteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exteriorring s_singleton;
@@ -904,7 +904,7 @@ protected:
class Create_func_find_in_set : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_find_in_set s_singleton;
@@ -917,7 +917,7 @@ protected:
class Create_func_floor : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_floor s_singleton;
@@ -930,7 +930,7 @@ protected:
class Create_func_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_format s_singleton;
@@ -943,7 +943,7 @@ protected:
class Create_func_found_rows : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_found_rows s_singleton;
@@ -956,7 +956,7 @@ protected:
class Create_func_from_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_from_days s_singleton;
@@ -1013,7 +1013,7 @@ protected:
class Create_func_geometry_type : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_geometry_type s_singleton;
@@ -1028,7 +1028,7 @@ protected:
class Create_func_geometryn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_geometryn s_singleton;
@@ -1042,7 +1042,7 @@ protected:
class Create_func_get_lock : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_get_lock s_singleton;
@@ -1056,7 +1056,7 @@ protected:
class Create_func_glength : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_glength s_singleton;
@@ -1083,7 +1083,7 @@ protected:
class Create_func_hex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_hex s_singleton;
@@ -1096,7 +1096,7 @@ protected:
class Create_func_ifnull : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_ifnull s_singleton;
@@ -1109,7 +1109,7 @@ protected:
class Create_func_inet_ntoa : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_ntoa s_singleton;
@@ -1122,7 +1122,7 @@ protected:
class Create_func_inet_aton : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_aton s_singleton;
@@ -1135,7 +1135,7 @@ protected:
class Create_func_instr : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_instr s_singleton;
@@ -1149,7 +1149,7 @@ protected:
class Create_func_interiorringn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_interiorringn s_singleton;
@@ -1164,7 +1164,7 @@ protected:
class Create_func_intersects : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_intersects s_singleton;
@@ -1178,7 +1178,7 @@ protected:
class Create_func_is_free_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_free_lock s_singleton;
@@ -1191,7 +1191,7 @@ protected:
class Create_func_is_used_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_used_lock s_singleton;
@@ -1205,7 +1205,7 @@ protected:
class Create_func_isclosed : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isclosed s_singleton;
@@ -1220,7 +1220,7 @@ protected:
class Create_func_isempty : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isempty s_singleton;
@@ -1234,7 +1234,7 @@ protected:
class Create_func_isnull : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isnull s_singleton;
@@ -1248,7 +1248,7 @@ protected:
class Create_func_issimple : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_issimple s_singleton;
@@ -1262,7 +1262,7 @@ protected:
class Create_func_last_day : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_last_day s_singleton;
@@ -1288,7 +1288,7 @@ protected:
class Create_func_lcase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_lcase s_singleton;
@@ -1314,7 +1314,7 @@ protected:
class Create_func_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_length s_singleton;
@@ -1327,7 +1327,7 @@ protected:
class Create_func_ln : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ln s_singleton;
@@ -1340,7 +1340,7 @@ protected:
class Create_func_load_file : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_load_file s_singleton;
@@ -1379,7 +1379,7 @@ protected:
class Create_func_log10 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log10 s_singleton;
@@ -1392,7 +1392,7 @@ protected:
class Create_func_log2 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log2 s_singleton;
@@ -1405,7 +1405,7 @@ protected:
class Create_func_lpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_lpad s_singleton;
@@ -1418,7 +1418,7 @@ protected:
class Create_func_ltrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ltrim s_singleton;
@@ -1431,7 +1431,7 @@ protected:
class Create_func_makedate : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_makedate s_singleton;
@@ -1444,7 +1444,7 @@ protected:
class Create_func_maketime : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_maketime s_singleton;
@@ -1483,7 +1483,7 @@ protected:
class Create_func_md5 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_md5 s_singleton;
@@ -1496,7 +1496,7 @@ protected:
class Create_func_monthname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_monthname s_singleton;
@@ -1509,7 +1509,7 @@ protected:
class Create_func_name_const : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_name_const s_singleton;
@@ -1522,7 +1522,7 @@ protected:
class Create_func_nullif : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_nullif s_singleton;
@@ -1536,7 +1536,7 @@ protected:
class Create_func_numgeometries : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numgeometries s_singleton;
@@ -1551,7 +1551,7 @@ protected:
class Create_func_numinteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numinteriorring s_singleton;
@@ -1566,7 +1566,7 @@ protected:
class Create_func_numpoints : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numpoints s_singleton;
@@ -1580,7 +1580,7 @@ protected:
class Create_func_oct : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_oct s_singleton;
@@ -1593,7 +1593,7 @@ protected:
class Create_func_ord : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ord s_singleton;
@@ -1607,7 +1607,7 @@ protected:
class Create_func_overlaps : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_overlaps s_singleton;
@@ -1621,7 +1621,7 @@ protected:
class Create_func_period_add : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_add s_singleton;
@@ -1634,7 +1634,7 @@ protected:
class Create_func_period_diff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_diff s_singleton;
@@ -1647,7 +1647,7 @@ protected:
class Create_func_pi : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_pi s_singleton;
@@ -1661,7 +1661,7 @@ protected:
class Create_func_pointn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pointn s_singleton;
@@ -1675,7 +1675,7 @@ protected:
class Create_func_pow : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pow s_singleton;
@@ -1688,7 +1688,7 @@ protected:
class Create_func_quote : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_quote s_singleton;
@@ -1701,7 +1701,7 @@ protected:
class Create_func_radians : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_radians s_singleton;
@@ -1727,7 +1727,7 @@ protected:
class Create_func_release_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_release_lock s_singleton;
@@ -1740,7 +1740,7 @@ protected:
class Create_func_reverse : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_reverse s_singleton;
@@ -1766,7 +1766,7 @@ protected:
class Create_func_row_count : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_row_count s_singleton;
@@ -1779,7 +1779,7 @@ protected:
class Create_func_rpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_rpad s_singleton;
@@ -1792,7 +1792,7 @@ protected:
class Create_func_rtrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_rtrim s_singleton;
@@ -1805,7 +1805,7 @@ protected:
class Create_func_sec_to_time : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sec_to_time s_singleton;
@@ -1818,7 +1818,7 @@ protected:
class Create_func_sha : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sha s_singleton;
@@ -1831,7 +1831,7 @@ protected:
class Create_func_sign : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sign s_singleton;
@@ -1844,7 +1844,7 @@ protected:
class Create_func_sin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sin s_singleton;
@@ -1857,7 +1857,7 @@ protected:
class Create_func_sleep : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sleep s_singleton;
@@ -1870,7 +1870,7 @@ protected:
class Create_func_soundex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_soundex s_singleton;
@@ -1883,7 +1883,7 @@ protected:
class Create_func_space : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_space s_singleton;
@@ -1896,7 +1896,7 @@ protected:
class Create_func_sqrt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sqrt s_singleton;
@@ -1910,7 +1910,7 @@ protected:
class Create_func_srid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_srid s_singleton;
@@ -1925,7 +1925,7 @@ protected:
class Create_func_startpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_startpoint s_singleton;
@@ -1939,7 +1939,7 @@ protected:
class Create_func_str_to_date : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_str_to_date s_singleton;
@@ -1952,7 +1952,7 @@ protected:
class Create_func_strcmp : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_strcmp s_singleton;
@@ -1965,7 +1965,7 @@ protected:
class Create_func_substr_index : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_substr_index s_singleton;
@@ -1978,7 +1978,7 @@ protected:
class Create_func_subtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_subtime s_singleton;
@@ -1991,7 +1991,7 @@ protected:
class Create_func_tan : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_tan s_singleton;
@@ -2004,7 +2004,7 @@ protected:
class Create_func_time_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_time_format s_singleton;
@@ -2017,7 +2017,7 @@ protected:
class Create_func_time_to_sec : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_time_to_sec s_singleton;
@@ -2030,7 +2030,7 @@ protected:
class Create_func_timediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_timediff s_singleton;
@@ -2043,7 +2043,7 @@ protected:
class Create_func_to_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_to_days s_singleton;
@@ -2057,7 +2057,7 @@ protected:
class Create_func_touches : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_touches s_singleton;
@@ -2071,7 +2071,7 @@ protected:
class Create_func_ucase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ucase s_singleton;
@@ -2084,7 +2084,7 @@ protected:
class Create_func_uncompress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompress s_singleton;
@@ -2097,7 +2097,7 @@ protected:
class Create_func_uncompressed_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompressed_length s_singleton;
@@ -2110,7 +2110,7 @@ protected:
class Create_func_unhex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_unhex s_singleton;
@@ -2136,7 +2136,7 @@ protected:
class Create_func_uuid : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid s_singleton;
@@ -2149,7 +2149,7 @@ protected:
class Create_func_uuid_short : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid_short s_singleton;
@@ -2162,7 +2162,7 @@ protected:
class Create_func_version : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_version s_singleton;
@@ -2175,7 +2175,7 @@ protected:
class Create_func_weekday : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekday s_singleton;
@@ -2188,7 +2188,7 @@ protected:
class Create_func_weekofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekofyear s_singleton;
@@ -2202,7 +2202,7 @@ protected:
class Create_func_within : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_within s_singleton;
@@ -2217,7 +2217,7 @@ protected:
class Create_func_x : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_x s_singleton;
@@ -2231,7 +2231,7 @@ protected:
class Create_func_xml_extractvalue : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_xml_extractvalue s_singleton;
@@ -2244,7 +2244,7 @@ protected:
class Create_func_xml_update : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_xml_update s_singleton;
@@ -2258,7 +2258,7 @@ protected:
class Create_func_y : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_y s_singleton;
@@ -2353,7 +2353,7 @@ Create_qfunc::create(THD *thd, LEX_STRIN
if (thd->lex->copy_db_to(&db.str, &db.length))
return NULL;
- return create(thd, db, name, false, item_list);
+ return create_with_db(thd, db, name, false, item_list);
}
@@ -2470,8 +2470,8 @@ Create_udf_func::create(THD *thd, udf_fu
Create_sp_func Create_sp_func::s_singleton;
Item*
-Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list)
+Create_sp_func::create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list)
{
int arg_count= 0;
Item *func= NULL;
@@ -2538,7 +2538,7 @@ Create_func_arg0::create(THD *thd, LEX_S
return NULL;
}
- return create(thd);
+ return create_builder(thd);
}
@@ -2564,7 +2564,7 @@ Create_func_arg1::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1);
+ return create_1_arg(thd, param_1);
}
@@ -2592,7 +2592,7 @@ Create_func_arg2::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2);
+ return create_2_arg(thd, param_1, param_2);
}
@@ -2622,14 +2622,14 @@ Create_func_arg3::create(THD *thd, LEX_S
return NULL;
}
- return create(thd, param_1, param_2, param_3);
+ return create_3_arg(thd, param_1, param_2, param_3);
}
Create_func_abs Create_func_abs::s_singleton;
Item*
-Create_func_abs::create(THD *thd, Item *arg1)
+Create_func_abs::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_abs(arg1);
}
@@ -2638,7 +2638,7 @@ Create_func_abs::create(THD *thd, Item *
Create_func_acos Create_func_acos::s_singleton;
Item*
-Create_func_acos::create(THD *thd, Item *arg1)
+Create_func_acos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_acos(arg1);
}
@@ -2647,7 +2647,7 @@ Create_func_acos::create(THD *thd, Item
Create_func_addtime Create_func_addtime::s_singleton;
Item*
-Create_func_addtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_addtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 0);
}
@@ -2656,7 +2656,7 @@ Create_func_addtime::create(THD *thd, It
Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton;
Item*
-Create_func_aes_encrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_encrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_encrypt(arg1, arg2);
}
@@ -2665,7 +2665,7 @@ Create_func_aes_encrypt::create(THD *thd
Create_func_aes_decrypt Create_func_aes_decrypt::s_singleton;
Item*
-Create_func_aes_decrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_decrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_decrypt(arg1, arg2);
}
@@ -2675,7 +2675,7 @@ Create_func_aes_decrypt::create(THD *thd
Create_func_area Create_func_area::s_singleton;
Item*
-Create_func_area::create(THD *thd, Item *arg1)
+Create_func_area::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_area(arg1);
}
@@ -2686,7 +2686,7 @@ Create_func_area::create(THD *thd, Item
Create_func_as_wkb Create_func_as_wkb::s_singleton;
Item*
-Create_func_as_wkb::create(THD *thd, Item *arg1)
+Create_func_as_wkb::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkb(arg1);
}
@@ -2697,7 +2697,7 @@ Create_func_as_wkb::create(THD *thd, Ite
Create_func_as_wkt Create_func_as_wkt::s_singleton;
Item*
-Create_func_as_wkt::create(THD *thd, Item *arg1)
+Create_func_as_wkt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkt(arg1);
}
@@ -2707,7 +2707,7 @@ Create_func_as_wkt::create(THD *thd, Ite
Create_func_asin Create_func_asin::s_singleton;
Item*
-Create_func_asin::create(THD *thd, Item *arg1)
+Create_func_asin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_asin(arg1);
}
@@ -2753,7 +2753,7 @@ Create_func_atan::create_native(THD *thd
Create_func_benchmark Create_func_benchmark::s_singleton;
Item*
-Create_func_benchmark::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_benchmark::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_benchmark(arg1, arg2);
@@ -2763,7 +2763,7 @@ Create_func_benchmark::create(THD *thd,
Create_func_bin Create_func_bin::s_singleton;
Item*
-Create_func_bin::create(THD *thd, Item *arg1)
+Create_func_bin::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i2= new (thd->mem_root) Item_int((int32) 2,1);
@@ -2774,7 +2774,7 @@ Create_func_bin::create(THD *thd, Item *
Create_func_bit_count Create_func_bit_count::s_singleton;
Item*
-Create_func_bit_count::create(THD *thd, Item *arg1)
+Create_func_bit_count::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_count(arg1);
}
@@ -2783,7 +2783,7 @@ Create_func_bit_count::create(THD *thd,
Create_func_bit_length Create_func_bit_length::s_singleton;
Item*
-Create_func_bit_length::create(THD *thd, Item *arg1)
+Create_func_bit_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_length(arg1);
}
@@ -2792,7 +2792,7 @@ Create_func_bit_length::create(THD *thd,
Create_func_ceiling Create_func_ceiling::s_singleton;
Item*
-Create_func_ceiling::create(THD *thd, Item *arg1)
+Create_func_ceiling::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ceiling(arg1);
}
@@ -2802,7 +2802,7 @@ Create_func_ceiling::create(THD *thd, It
Create_func_centroid Create_func_centroid::s_singleton;
Item*
-Create_func_centroid::create(THD *thd, Item *arg1)
+Create_func_centroid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_centroid(arg1);
}
@@ -2812,7 +2812,7 @@ Create_func_centroid::create(THD *thd, I
Create_func_char_length Create_func_char_length::s_singleton;
Item*
-Create_func_char_length::create(THD *thd, Item *arg1)
+Create_func_char_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_char_length(arg1);
}
@@ -2821,7 +2821,7 @@ Create_func_char_length::create(THD *thd
Create_func_coercibility Create_func_coercibility::s_singleton;
Item*
-Create_func_coercibility::create(THD *thd, Item *arg1)
+Create_func_coercibility::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_coercibility(arg1);
}
@@ -2873,7 +2873,7 @@ Create_func_concat_ws::create_native(THD
Create_func_compress Create_func_compress::s_singleton;
Item*
-Create_func_compress::create(THD *thd, Item *arg1)
+Create_func_compress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_compress(arg1);
}
@@ -2882,7 +2882,7 @@ Create_func_compress::create(THD *thd, I
Create_func_connection_id Create_func_connection_id::s_singleton;
Item*
-Create_func_connection_id::create(THD *thd)
+Create_func_connection_id::create_builder(THD *thd)
{
thd->lex->safe_to_cache_query= 0;
return new (thd->mem_root) Item_func_connection_id();
@@ -2893,7 +2893,7 @@ Create_func_connection_id::create(THD *t
Create_func_contains Create_func_contains::s_singleton;
Item*
-Create_func_contains::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_contains::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CONTAINS_FUNC);
@@ -2904,7 +2904,7 @@ Create_func_contains::create(THD *thd, I
Create_func_conv Create_func_conv::s_singleton;
Item*
-Create_func_conv::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_conv::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_conv(arg1, arg2, arg3);
}
@@ -2913,7 +2913,7 @@ Create_func_conv::create(THD *thd, Item
Create_func_convert_tz Create_func_convert_tz::s_singleton;
Item*
-Create_func_convert_tz::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_convert_tz::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_convert_tz(arg1, arg2, arg3);
}
@@ -2922,7 +2922,7 @@ Create_func_convert_tz::create(THD *thd,
Create_func_cos Create_func_cos::s_singleton;
Item*
-Create_func_cos::create(THD *thd, Item *arg1)
+Create_func_cos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_cos(arg1);
}
@@ -2931,7 +2931,7 @@ Create_func_cos::create(THD *thd, Item *
Create_func_cot Create_func_cot::s_singleton;
Item*
-Create_func_cot::create(THD *thd, Item *arg1)
+Create_func_cot::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "1", 1, 1);
Item *i2= new (thd->mem_root) Item_func_tan(arg1);
@@ -2942,7 +2942,7 @@ Create_func_cot::create(THD *thd, Item *
Create_func_crc32 Create_func_crc32::s_singleton;
Item*
-Create_func_crc32::create(THD *thd, Item *arg1)
+Create_func_crc32::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_crc32(arg1);
}
@@ -2952,7 +2952,7 @@ Create_func_crc32::create(THD *thd, Item
Create_func_crosses Create_func_crosses::s_singleton;
Item*
-Create_func_crosses::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_crosses::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CROSSES_FUNC);
@@ -2963,7 +2963,7 @@ Create_func_crosses::create(THD *thd, It
Create_func_date_format Create_func_date_format::s_singleton;
Item*
-Create_func_date_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_date_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 0);
}
@@ -2972,7 +2972,7 @@ Create_func_date_format::create(THD *thd
Create_func_datediff Create_func_datediff::s_singleton;
Item*
-Create_func_datediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_datediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
Item *i1= new (thd->mem_root) Item_func_to_days(arg1);
Item *i2= new (thd->mem_root) Item_func_to_days(arg2);
@@ -2984,7 +2984,7 @@ Create_func_datediff::create(THD *thd, I
Create_func_dayname Create_func_dayname::s_singleton;
Item*
-Create_func_dayname::create(THD *thd, Item *arg1)
+Create_func_dayname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayname(arg1);
}
@@ -2993,7 +2993,7 @@ Create_func_dayname::create(THD *thd, It
Create_func_dayofmonth Create_func_dayofmonth::s_singleton;
Item*
-Create_func_dayofmonth::create(THD *thd, Item *arg1)
+Create_func_dayofmonth::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofmonth(arg1);
}
@@ -3002,7 +3002,7 @@ Create_func_dayofmonth::create(THD *thd,
Create_func_dayofweek Create_func_dayofweek::s_singleton;
Item*
-Create_func_dayofweek::create(THD *thd, Item *arg1)
+Create_func_dayofweek::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 1);
}
@@ -3011,7 +3011,7 @@ Create_func_dayofweek::create(THD *thd,
Create_func_dayofyear Create_func_dayofyear::s_singleton;
Item*
-Create_func_dayofyear::create(THD *thd, Item *arg1)
+Create_func_dayofyear::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofyear(arg1);
}
@@ -3020,7 +3020,7 @@ Create_func_dayofyear::create(THD *thd,
Create_func_decode Create_func_decode::s_singleton;
Item*
-Create_func_decode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_decode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_decode(arg1, arg2);
}
@@ -3029,7 +3029,7 @@ Create_func_decode::create(THD *thd, Ite
Create_func_degrees Create_func_degrees::s_singleton;
Item*
-Create_func_degrees::create(THD *thd, Item *arg1)
+Create_func_degrees::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "degrees", arg1,
180/M_PI, 0.0);
@@ -3114,7 +3114,7 @@ Create_func_des_encrypt::create_native(T
Create_func_dimension Create_func_dimension::s_singleton;
Item*
-Create_func_dimension::create(THD *thd, Item *arg1)
+Create_func_dimension::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dimension(arg1);
}
@@ -3125,7 +3125,7 @@ Create_func_dimension::create(THD *thd,
Create_func_disjoint Create_func_disjoint::s_singleton;
Item*
-Create_func_disjoint::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_disjoint::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_DISJOINT_FUNC);
@@ -3157,7 +3157,7 @@ Create_func_elt::create_native(THD *thd,
Create_func_encode Create_func_encode::s_singleton;
Item*
-Create_func_encode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_encode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_encode(arg1, arg2);
}
@@ -3205,7 +3205,7 @@ Create_func_encrypt::create_native(THD *
Create_func_endpoint Create_func_endpoint::s_singleton;
Item*
-Create_func_endpoint::create(THD *thd, Item *arg1)
+Create_func_endpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_ENDPOINT);
@@ -3217,7 +3217,7 @@ Create_func_endpoint::create(THD *thd, I
Create_func_envelope Create_func_envelope::s_singleton;
Item*
-Create_func_envelope::create(THD *thd, Item *arg1)
+Create_func_envelope::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_envelope(arg1);
}
@@ -3228,7 +3228,7 @@ Create_func_envelope::create(THD *thd, I
Create_func_equals Create_func_equals::s_singleton;
Item*
-Create_func_equals::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_equals::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_EQUALS_FUNC);
@@ -3239,7 +3239,7 @@ Create_func_equals::create(THD *thd, Ite
Create_func_exp Create_func_exp::s_singleton;
Item*
-Create_func_exp::create(THD *thd, Item *arg1)
+Create_func_exp::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_exp(arg1);
}
@@ -3302,7 +3302,7 @@ Create_func_export_set::create_native(TH
Create_func_exteriorring Create_func_exteriorring::s_singleton;
Item*
-Create_func_exteriorring::create(THD *thd, Item *arg1)
+Create_func_exteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_EXTERIORRING);
@@ -3334,7 +3334,7 @@ Create_func_field::create_native(THD *th
Create_func_find_in_set Create_func_find_in_set::s_singleton;
Item*
-Create_func_find_in_set::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_find_in_set::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_find_in_set(arg1, arg2);
}
@@ -3343,7 +3343,7 @@ Create_func_find_in_set::create(THD *thd
Create_func_floor Create_func_floor::s_singleton;
Item*
-Create_func_floor::create(THD *thd, Item *arg1)
+Create_func_floor::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_floor(arg1);
}
@@ -3352,7 +3352,7 @@ Create_func_floor::create(THD *thd, Item
Create_func_format Create_func_format::s_singleton;
Item*
-Create_func_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_format(arg1, arg2);
}
@@ -3361,7 +3361,7 @@ Create_func_format::create(THD *thd, Ite
Create_func_found_rows Create_func_found_rows::s_singleton;
Item*
-Create_func_found_rows::create(THD *thd)
+Create_func_found_rows::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -3372,7 +3372,7 @@ Create_func_found_rows::create(THD *thd)
Create_func_from_days Create_func_from_days::s_singleton;
Item*
-Create_func_from_days::create(THD *thd, Item *arg1)
+Create_func_from_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_from_days(arg1);
}
@@ -3500,7 +3500,7 @@ Create_func_geometry_from_wkb::create_na
Create_func_geometry_type Create_func_geometry_type::s_singleton;
Item*
-Create_func_geometry_type::create(THD *thd, Item *arg1)
+Create_func_geometry_type::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_geometry_type(arg1);
}
@@ -3511,7 +3511,7 @@ Create_func_geometry_type::create(THD *t
Create_func_geometryn Create_func_geometryn::s_singleton;
Item*
-Create_func_geometryn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_geometryn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_GEOMETRYN);
@@ -3522,8 +3522,9 @@ Create_func_geometryn::create(THD *thd,
Create_func_get_lock Create_func_get_lock::s_singleton;
Item*
-Create_func_get_lock::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_get_lock::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
+ thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_get_lock(arg1, arg2);
}
@@ -3533,7 +3534,7 @@ Create_func_get_lock::create(THD *thd, I
Create_func_glength Create_func_glength::s_singleton;
Item*
-Create_func_glength::create(THD *thd, Item *arg1)
+Create_func_glength::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_glength(arg1);
}
@@ -3564,7 +3565,7 @@ Create_func_greatest::create_native(THD
Create_func_hex Create_func_hex::s_singleton;
Item*
-Create_func_hex::create(THD *thd, Item *arg1)
+Create_func_hex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_hex(arg1);
}
@@ -3573,7 +3574,7 @@ Create_func_hex::create(THD *thd, Item *
Create_func_ifnull Create_func_ifnull::s_singleton;
Item*
-Create_func_ifnull::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_ifnull::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_ifnull(arg1, arg2);
}
@@ -3582,7 +3583,7 @@ Create_func_ifnull::create(THD *thd, Ite
Create_func_inet_ntoa Create_func_inet_ntoa::s_singleton;
Item*
-Create_func_inet_ntoa::create(THD *thd, Item *arg1)
+Create_func_inet_ntoa::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_ntoa(arg1);
}
@@ -3591,7 +3592,7 @@ Create_func_inet_ntoa::create(THD *thd,
Create_func_inet_aton Create_func_inet_aton::s_singleton;
Item*
-Create_func_inet_aton::create(THD *thd, Item *arg1)
+Create_func_inet_aton::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_aton(arg1);
}
@@ -3600,7 +3601,7 @@ Create_func_inet_aton::create(THD *thd,
Create_func_instr Create_func_instr::s_singleton;
Item*
-Create_func_instr::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_instr::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_locate(arg1, arg2);
}
@@ -3610,7 +3611,7 @@ Create_func_instr::create(THD *thd, Item
Create_func_interiorringn Create_func_interiorringn::s_singleton;
Item*
-Create_func_interiorringn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_interiorringn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_INTERIORRINGN);
@@ -3622,7 +3623,7 @@ Create_func_interiorringn::create(THD *t
Create_func_intersects Create_func_intersects::s_singleton;
Item*
-Create_func_intersects::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_intersects::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_INTERSECTS_FUNC);
@@ -3633,8 +3634,9 @@ Create_func_intersects::create(THD *thd,
Create_func_is_free_lock Create_func_is_free_lock::s_singleton;
Item*
-Create_func_is_free_lock::create(THD *thd, Item *arg1)
+Create_func_is_free_lock::create_1_arg(THD *thd, Item *arg1)
{
+ thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_is_free_lock(arg1);
}
@@ -3643,8 +3645,9 @@ Create_func_is_free_lock::create(THD *th
Create_func_is_used_lock Create_func_is_used_lock::s_singleton;
Item*
-Create_func_is_used_lock::create(THD *thd, Item *arg1)
+Create_func_is_used_lock::create_1_arg(THD *thd, Item *arg1)
{
+ thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_is_used_lock(arg1);
}
@@ -3654,7 +3657,7 @@ Create_func_is_used_lock::create(THD *th
Create_func_isclosed Create_func_isclosed::s_singleton;
Item*
-Create_func_isclosed::create(THD *thd, Item *arg1)
+Create_func_isclosed::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isclosed(arg1);
}
@@ -3665,7 +3668,7 @@ Create_func_isclosed::create(THD *thd, I
Create_func_isempty Create_func_isempty::s_singleton;
Item*
-Create_func_isempty::create(THD *thd, Item *arg1)
+Create_func_isempty::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isempty(arg1);
}
@@ -3675,7 +3678,7 @@ Create_func_isempty::create(THD *thd, It
Create_func_isnull Create_func_isnull::s_singleton;
Item*
-Create_func_isnull::create(THD *thd, Item *arg1)
+Create_func_isnull::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isnull(arg1);
}
@@ -3685,7 +3688,7 @@ Create_func_isnull::create(THD *thd, Ite
Create_func_issimple Create_func_issimple::s_singleton;
Item*
-Create_func_issimple::create(THD *thd, Item *arg1)
+Create_func_issimple::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_issimple(arg1);
}
@@ -3695,7 +3698,7 @@ Create_func_issimple::create(THD *thd, I
Create_func_last_day Create_func_last_day::s_singleton;
Item*
-Create_func_last_day::create(THD *thd, Item *arg1)
+Create_func_last_day::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_last_day(arg1);
}
@@ -3741,7 +3744,7 @@ Create_func_last_insert_id::create_nativ
Create_func_lcase Create_func_lcase::s_singleton;
Item*
-Create_func_lcase::create(THD *thd, Item *arg1)
+Create_func_lcase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_lcase(arg1);
}
@@ -3771,7 +3774,7 @@ Create_func_least::create_native(THD *th
Create_func_length Create_func_length::s_singleton;
Item*
-Create_func_length::create(THD *thd, Item *arg1)
+Create_func_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_length(arg1);
}
@@ -3780,7 +3783,7 @@ Create_func_length::create(THD *thd, Ite
Create_func_ln Create_func_ln::s_singleton;
Item*
-Create_func_ln::create(THD *thd, Item *arg1)
+Create_func_ln::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ln(arg1);
}
@@ -3789,7 +3792,7 @@ Create_func_ln::create(THD *thd, Item *a
Create_func_load_file Create_func_load_file::s_singleton;
Item*
-Create_func_load_file::create(THD *thd, Item *arg1)
+Create_func_load_file::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3878,7 +3881,7 @@ Create_func_log::create_native(THD *thd,
Create_func_log10 Create_func_log10::s_singleton;
Item*
-Create_func_log10::create(THD *thd, Item *arg1)
+Create_func_log10::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log10(arg1);
}
@@ -3887,7 +3890,7 @@ Create_func_log10::create(THD *thd, Item
Create_func_log2 Create_func_log2::s_singleton;
Item*
-Create_func_log2::create(THD *thd, Item *arg1)
+Create_func_log2::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log2(arg1);
}
@@ -3896,7 +3899,7 @@ Create_func_log2::create(THD *thd, Item
Create_func_lpad Create_func_lpad::s_singleton;
Item*
-Create_func_lpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_lpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_lpad(arg1, arg2, arg3);
}
@@ -3905,7 +3908,7 @@ Create_func_lpad::create(THD *thd, Item
Create_func_ltrim Create_func_ltrim::s_singleton;
Item*
-Create_func_ltrim::create(THD *thd, Item *arg1)
+Create_func_ltrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ltrim(arg1);
}
@@ -3914,7 +3917,7 @@ Create_func_ltrim::create(THD *thd, Item
Create_func_makedate Create_func_makedate::s_singleton;
Item*
-Create_func_makedate::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_makedate::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_makedate(arg1, arg2);
}
@@ -3923,7 +3926,7 @@ Create_func_makedate::create(THD *thd, I
Create_func_maketime Create_func_maketime::s_singleton;
Item*
-Create_func_maketime::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_maketime::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_maketime(arg1, arg2, arg3);
}
@@ -3961,6 +3964,8 @@ Create_func_master_pos_wait::create_nati
Item *func= NULL;
int arg_count= 0;
+ thd->lex->set_stmt_unsafe();
+
if (item_list != NULL)
arg_count= item_list->elements;
@@ -3996,7 +4001,7 @@ Create_func_master_pos_wait::create_nati
Create_func_md5 Create_func_md5::s_singleton;
Item*
-Create_func_md5::create(THD *thd, Item *arg1)
+Create_func_md5::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_md5(arg1);
}
@@ -4005,7 +4010,7 @@ Create_func_md5::create(THD *thd, Item *
Create_func_monthname Create_func_monthname::s_singleton;
Item*
-Create_func_monthname::create(THD *thd, Item *arg1)
+Create_func_monthname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_monthname(arg1);
}
@@ -4014,7 +4019,7 @@ Create_func_monthname::create(THD *thd,
Create_func_name_const Create_func_name_const::s_singleton;
Item*
-Create_func_name_const::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_name_const::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_name_const(arg1, arg2);
}
@@ -4023,7 +4028,7 @@ Create_func_name_const::create(THD *thd,
Create_func_nullif Create_func_nullif::s_singleton;
Item*
-Create_func_nullif::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_nullif::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_nullif(arg1, arg2);
}
@@ -4033,7 +4038,7 @@ Create_func_nullif::create(THD *thd, Ite
Create_func_numgeometries Create_func_numgeometries::s_singleton;
Item*
-Create_func_numgeometries::create(THD *thd, Item *arg1)
+Create_func_numgeometries::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numgeometries(arg1);
}
@@ -4044,7 +4049,7 @@ Create_func_numgeometries::create(THD *t
Create_func_numinteriorring Create_func_numinteriorring::s_singleton;
Item*
-Create_func_numinteriorring::create(THD *thd, Item *arg1)
+Create_func_numinteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numinteriorring(arg1);
}
@@ -4055,7 +4060,7 @@ Create_func_numinteriorring::create(THD
Create_func_numpoints Create_func_numpoints::s_singleton;
Item*
-Create_func_numpoints::create(THD *thd, Item *arg1)
+Create_func_numpoints::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numpoints(arg1);
}
@@ -4065,7 +4070,7 @@ Create_func_numpoints::create(THD *thd,
Create_func_oct Create_func_oct::s_singleton;
Item*
-Create_func_oct::create(THD *thd, Item *arg1)
+Create_func_oct::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i8= new (thd->mem_root) Item_int((int32) 8,1);
@@ -4076,7 +4081,7 @@ Create_func_oct::create(THD *thd, Item *
Create_func_ord Create_func_ord::s_singleton;
Item*
-Create_func_ord::create(THD *thd, Item *arg1)
+Create_func_ord::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ord(arg1);
}
@@ -4086,7 +4091,7 @@ Create_func_ord::create(THD *thd, Item *
Create_func_overlaps Create_func_overlaps::s_singleton;
Item*
-Create_func_overlaps::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_overlaps::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_OVERLAPS_FUNC);
@@ -4097,7 +4102,7 @@ Create_func_overlaps::create(THD *thd, I
Create_func_period_add Create_func_period_add::s_singleton;
Item*
-Create_func_period_add::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_add::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_add(arg1, arg2);
}
@@ -4106,7 +4111,7 @@ Create_func_period_add::create(THD *thd,
Create_func_period_diff Create_func_period_diff::s_singleton;
Item*
-Create_func_period_diff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_diff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_diff(arg1, arg2);
}
@@ -4115,7 +4120,7 @@ Create_func_period_diff::create(THD *thd
Create_func_pi Create_func_pi::s_singleton;
Item*
-Create_func_pi::create(THD *thd)
+Create_func_pi::create_builder(THD *thd)
{
return new (thd->mem_root) Item_static_float_func("pi()", M_PI, 6, 8);
}
@@ -4125,7 +4130,7 @@ Create_func_pi::create(THD *thd)
Create_func_pointn Create_func_pointn::s_singleton;
Item*
-Create_func_pointn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pointn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_POINTN);
@@ -4136,7 +4141,7 @@ Create_func_pointn::create(THD *thd, Ite
Create_func_pow Create_func_pow::s_singleton;
Item*
-Create_func_pow::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pow::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_pow(arg1, arg2);
}
@@ -4145,7 +4150,7 @@ Create_func_pow::create(THD *thd, Item *
Create_func_quote Create_func_quote::s_singleton;
Item*
-Create_func_quote::create(THD *thd, Item *arg1)
+Create_func_quote::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_quote(arg1);
}
@@ -4154,7 +4159,7 @@ Create_func_quote::create(THD *thd, Item
Create_func_radians Create_func_radians::s_singleton;
Item*
-Create_func_radians::create(THD *thd, Item *arg1)
+Create_func_radians::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "radians", arg1,
M_PI/180, 0.0);
@@ -4173,6 +4178,16 @@ Create_func_rand::create_native(THD *thd
if (item_list != NULL)
arg_count= item_list->elements;
+ /*
+ When RAND() is binlogged, the seed is binlogged too. So the
+ sequence of random numbers is the same on a replication slave as
+ on the master. However, if several RAND() values are inserted
+ into a table, the order in which the rows are modified may differ
+ between master and slave, because the order is undefined. Hence,
+ the statement is unsafe to log in statement format.
+ */
+ thd->lex->set_stmt_unsafe();
+
switch (arg_count) {
case 0:
{
@@ -4201,8 +4216,9 @@ Create_func_rand::create_native(THD *thd
Create_func_release_lock Create_func_release_lock::s_singleton;
Item*
-Create_func_release_lock::create(THD *thd, Item *arg1)
+Create_func_release_lock::create_1_arg(THD *thd, Item *arg1)
{
+ thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_release_lock(arg1);
}
@@ -4211,7 +4227,7 @@ Create_func_release_lock::create(THD *th
Create_func_reverse Create_func_reverse::s_singleton;
Item*
-Create_func_reverse::create(THD *thd, Item *arg1)
+Create_func_reverse::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_reverse(arg1);
}
@@ -4258,7 +4274,7 @@ Create_func_round::create_native(THD *th
Create_func_row_count Create_func_row_count::s_singleton;
Item*
-Create_func_row_count::create(THD *thd)
+Create_func_row_count::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4269,7 +4285,7 @@ Create_func_row_count::create(THD *thd)
Create_func_rpad Create_func_rpad::s_singleton;
Item*
-Create_func_rpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_rpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_rpad(arg1, arg2, arg3);
}
@@ -4278,7 +4294,7 @@ Create_func_rpad::create(THD *thd, Item
Create_func_rtrim Create_func_rtrim::s_singleton;
Item*
-Create_func_rtrim::create(THD *thd, Item *arg1)
+Create_func_rtrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_rtrim(arg1);
}
@@ -4287,7 +4303,7 @@ Create_func_rtrim::create(THD *thd, Item
Create_func_sec_to_time Create_func_sec_to_time::s_singleton;
Item*
-Create_func_sec_to_time::create(THD *thd, Item *arg1)
+Create_func_sec_to_time::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sec_to_time(arg1);
}
@@ -4296,7 +4312,7 @@ Create_func_sec_to_time::create(THD *thd
Create_func_sha Create_func_sha::s_singleton;
Item*
-Create_func_sha::create(THD *thd, Item *arg1)
+Create_func_sha::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sha(arg1);
}
@@ -4305,7 +4321,7 @@ Create_func_sha::create(THD *thd, Item *
Create_func_sign Create_func_sign::s_singleton;
Item*
-Create_func_sign::create(THD *thd, Item *arg1)
+Create_func_sign::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sign(arg1);
}
@@ -4314,7 +4330,7 @@ Create_func_sign::create(THD *thd, Item
Create_func_sin Create_func_sin::s_singleton;
Item*
-Create_func_sin::create(THD *thd, Item *arg1)
+Create_func_sin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sin(arg1);
}
@@ -4323,8 +4339,9 @@ Create_func_sin::create(THD *thd, Item *
Create_func_sleep Create_func_sleep::s_singleton;
Item*
-Create_func_sleep::create(THD *thd, Item *arg1)
+Create_func_sleep::create_1_arg(THD *thd, Item *arg1)
{
+ thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_sleep(arg1);
}
@@ -4333,7 +4350,7 @@ Create_func_sleep::create(THD *thd, Item
Create_func_soundex Create_func_soundex::s_singleton;
Item*
-Create_func_soundex::create(THD *thd, Item *arg1)
+Create_func_soundex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_soundex(arg1);
}
@@ -4342,7 +4359,7 @@ Create_func_soundex::create(THD *thd, It
Create_func_space Create_func_space::s_singleton;
Item*
-Create_func_space::create(THD *thd, Item *arg1)
+Create_func_space::create_1_arg(THD *thd, Item *arg1)
{
/**
TODO: Fix Bug#23637
@@ -4370,7 +4387,7 @@ Create_func_space::create(THD *thd, Item
Create_func_sqrt Create_func_sqrt::s_singleton;
Item*
-Create_func_sqrt::create(THD *thd, Item *arg1)
+Create_func_sqrt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sqrt(arg1);
}
@@ -4380,7 +4397,7 @@ Create_func_sqrt::create(THD *thd, Item
Create_func_srid Create_func_srid::s_singleton;
Item*
-Create_func_srid::create(THD *thd, Item *arg1)
+Create_func_srid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_srid(arg1);
}
@@ -4391,7 +4408,7 @@ Create_func_srid::create(THD *thd, Item
Create_func_startpoint Create_func_startpoint::s_singleton;
Item*
-Create_func_startpoint::create(THD *thd, Item *arg1)
+Create_func_startpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_STARTPOINT);
@@ -4402,7 +4419,7 @@ Create_func_startpoint::create(THD *thd,
Create_func_str_to_date Create_func_str_to_date::s_singleton;
Item*
-Create_func_str_to_date::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_str_to_date::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_str_to_date(arg1, arg2);
}
@@ -4411,7 +4428,7 @@ Create_func_str_to_date::create(THD *thd
Create_func_strcmp Create_func_strcmp::s_singleton;
Item*
-Create_func_strcmp::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_strcmp::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_strcmp(arg1, arg2);
}
@@ -4420,7 +4437,7 @@ Create_func_strcmp::create(THD *thd, Ite
Create_func_substr_index Create_func_substr_index::s_singleton;
Item*
-Create_func_substr_index::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_substr_index::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_substr_index(arg1, arg2, arg3);
}
@@ -4429,7 +4446,7 @@ Create_func_substr_index::create(THD *th
Create_func_subtime Create_func_subtime::s_singleton;
Item*
-Create_func_subtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_subtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 1);
}
@@ -4438,7 +4455,7 @@ Create_func_subtime::create(THD *thd, It
Create_func_tan Create_func_tan::s_singleton;
Item*
-Create_func_tan::create(THD *thd, Item *arg1)
+Create_func_tan::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_tan(arg1);
}
@@ -4447,7 +4464,7 @@ Create_func_tan::create(THD *thd, Item *
Create_func_time_format Create_func_time_format::s_singleton;
Item*
-Create_func_time_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_time_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 1);
}
@@ -4456,7 +4473,7 @@ Create_func_time_format::create(THD *thd
Create_func_time_to_sec Create_func_time_to_sec::s_singleton;
Item*
-Create_func_time_to_sec::create(THD *thd, Item *arg1)
+Create_func_time_to_sec::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_time_to_sec(arg1);
}
@@ -4465,7 +4482,7 @@ Create_func_time_to_sec::create(THD *thd
Create_func_timediff Create_func_timediff::s_singleton;
Item*
-Create_func_timediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_timediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_timediff(arg1, arg2);
}
@@ -4474,7 +4491,7 @@ Create_func_timediff::create(THD *thd, I
Create_func_to_days Create_func_to_days::s_singleton;
Item*
-Create_func_to_days::create(THD *thd, Item *arg1)
+Create_func_to_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_to_days(arg1);
}
@@ -4484,7 +4501,7 @@ Create_func_to_days::create(THD *thd, It
Create_func_touches Create_func_touches::s_singleton;
Item*
-Create_func_touches::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_touches::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_TOUCHES_FUNC);
@@ -4495,7 +4512,7 @@ Create_func_touches::create(THD *thd, It
Create_func_ucase Create_func_ucase::s_singleton;
Item*
-Create_func_ucase::create(THD *thd, Item *arg1)
+Create_func_ucase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ucase(arg1);
}
@@ -4504,7 +4521,7 @@ Create_func_ucase::create(THD *thd, Item
Create_func_uncompress Create_func_uncompress::s_singleton;
Item*
-Create_func_uncompress::create(THD *thd, Item *arg1)
+Create_func_uncompress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompress(arg1);
}
@@ -4513,7 +4530,7 @@ Create_func_uncompress::create(THD *thd,
Create_func_uncompressed_length Create_func_uncompressed_length::s_singleton;
Item*
-Create_func_uncompressed_length::create(THD *thd, Item *arg1)
+Create_func_uncompressed_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompressed_length(arg1);
}
@@ -4522,7 +4539,7 @@ Create_func_uncompressed_length::create(
Create_func_unhex Create_func_unhex::s_singleton;
Item*
-Create_func_unhex::create(THD *thd, Item *arg1)
+Create_func_unhex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_unhex(arg1);
}
@@ -4567,7 +4584,7 @@ Create_func_unix_timestamp::create_nativ
Create_func_uuid Create_func_uuid::s_singleton;
Item*
-Create_func_uuid::create(THD *thd)
+Create_func_uuid::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4578,7 +4595,7 @@ Create_func_uuid::create(THD *thd)
Create_func_uuid_short Create_func_uuid_short::s_singleton;
Item*
-Create_func_uuid_short::create(THD *thd)
+Create_func_uuid_short::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4589,8 +4606,9 @@ Create_func_uuid_short::create(THD *thd)
Create_func_version Create_func_version::s_singleton;
Item*
-Create_func_version::create(THD *thd)
+Create_func_version::create_builder(THD *thd)
{
+ thd->lex->set_stmt_unsafe();
return new (thd->mem_root) Item_static_string_func("version()",
server_version,
(uint) strlen(server_version),
@@ -4602,7 +4620,7 @@ Create_func_version::create(THD *thd)
Create_func_weekday Create_func_weekday::s_singleton;
Item*
-Create_func_weekday::create(THD *thd, Item *arg1)
+Create_func_weekday::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 0);
}
@@ -4611,7 +4629,7 @@ Create_func_weekday::create(THD *thd, It
Create_func_weekofyear Create_func_weekofyear::s_singleton;
Item*
-Create_func_weekofyear::create(THD *thd, Item *arg1)
+Create_func_weekofyear::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "0", 3, 1);
return new (thd->mem_root) Item_func_week(arg1, i1);
@@ -4622,7 +4640,7 @@ Create_func_weekofyear::create(THD *thd,
Create_func_within Create_func_within::s_singleton;
Item*
-Create_func_within::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_within::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_WITHIN_FUNC);
@@ -4634,7 +4652,7 @@ Create_func_within::create(THD *thd, Ite
Create_func_x Create_func_x::s_singleton;
Item*
-Create_func_x::create(THD *thd, Item *arg1)
+Create_func_x::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_x(arg1);
}
@@ -4644,7 +4662,7 @@ Create_func_x::create(THD *thd, Item *ar
Create_func_xml_extractvalue Create_func_xml_extractvalue::s_singleton;
Item*
-Create_func_xml_extractvalue::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_xml_extractvalue::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_xml_extractvalue(arg1, arg2);
}
@@ -4653,7 +4671,7 @@ Create_func_xml_extractvalue::create(THD
Create_func_xml_update Create_func_xml_update::s_singleton;
Item*
-Create_func_xml_update::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_xml_update::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_xml_update(arg1, arg2, arg3);
}
@@ -4663,7 +4681,7 @@ Create_func_xml_update::create(THD *thd,
Create_func_y Create_func_y::s_singleton;
Item*
-Create_func_y::create(THD *thd, Item *arg1)
+Create_func_y::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_y(arg1);
}
=== modified file 'sql/item_create.h'
--- a/sql/item_create.h 2007-08-15 13:43:08 +0000
+++ b/sql/item_create.h 2010-03-28 18:10:00 +0000
@@ -91,8 +91,9 @@ public:
@param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call
*/
- virtual Item* create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list) = 0;
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name,
+ List<Item> *item_list) = 0;
protected:
/** Constructor. */
=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc 2009-12-03 11:19:05 +0000
+++ b/sql/item_func.cc 2010-03-04 08:03:07 +0000
@@ -450,45 +450,8 @@ Field *Item_func::tmp_table_field(TABLE
case STRING_RESULT:
return make_string_field(table);
case DECIMAL_RESULT:
- {
- uint8 dec= decimals;
- uint8 intg= decimal_precision() - dec;
- uint32 len= max_length;
-
- /*
- Trying to put too many digits overall in a DECIMAL(prec,dec)
- will always throw a warning. We must limit dec to
- DECIMAL_MAX_SCALE however to prevent an assert() later.
- */
-
- if (dec > 0)
- {
- int overflow;
-
- dec= min(dec, DECIMAL_MAX_SCALE);
-
- /*
- If the value still overflows the field with the corrected dec,
- we'll throw out decimals rather than integers. This is still
- bad and of course throws a truncation warning.
- */
-
- const int required_length=
- my_decimal_precision_to_length(intg + dec, dec,
- unsigned_flag);
-
- overflow= required_length - len;
-
- if (overflow > 0)
- dec= max(0, dec - overflow); // too long, discard fract
- else
- /* Corrected value fits. */
- len= required_length;
- }
-
- field= new Field_new_decimal(len, maybe_null, name, dec, unsigned_flag);
+ field= Field_new_decimal::create_from_item(this);
break;
- }
case ROW_RESULT:
default:
// This case should never be chosen
@@ -642,7 +605,7 @@ void Item_func::signal_divide_by_null()
Item *Item_func::get_tmp_table_item(THD *thd)
{
- if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
+ if (!with_sum_func && !const_item())
return new Item_field(result_field);
return copy_or_same(thd);
}
=== modified file 'sql/item_func.h'
--- a/sql/item_func.h 2009-12-03 11:19:05 +0000
+++ b/sql/item_func.h 2010-03-04 08:03:07 +0000
@@ -124,17 +124,6 @@ public:
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
virtual bool have_rev_func() const { return 0; }
virtual Item *key_item() const { return args[0]; }
- /*
- This method is used for debug purposes to print the name of an
- item to the debug log. The second use of this method is as
- a helper function of print(), where it is applicable.
- To suit both goals it should return a meaningful,
- distinguishable and sintactically correct string. This method
- should not be used for runtime type identification, use enum
- {Sum}Functype and Item_func::functype()/Item_sum::sum_func()
- instead.
- */
- virtual const char *func_name() const= 0;
virtual bool const_item() const { return const_item_cache; }
inline Item **arguments() const { return args; }
void set_arguments(List<Item> &list);
@@ -200,6 +189,34 @@ public:
null_value=1;
return 0.0;
}
+ bool has_timestamp_args()
+ {
+ DBUG_ASSERT(fixed == TRUE);
+ for (uint i= 0; i < arg_count; i++)
+ {
+ if (args[i]->type() == Item::FIELD_ITEM &&
+ args[i]->field_type() == MYSQL_TYPE_TIMESTAMP)
+ return TRUE;
+ }
+ return FALSE;
+ }
+ /*
+ We assume the result of any function that has a TIMESTAMP argument to be
+ timezone-dependent, since a TIMESTAMP value in both numeric and string
+ contexts is interpreted according to the current timezone.
+ The only exception is UNIX_TIMESTAMP() which returns the internal
+ representation of a TIMESTAMP argument verbatim, and thus does not depend on
+ the timezone.
+ */
+ virtual bool is_timezone_dependent_processor(uchar *bool_arg)
+ {
+ return has_timestamp_args();
+ }
+
+ virtual bool find_function_processor (uchar *arg)
+ {
+ return functype() == *(Functype *) arg;
+ }
};
=== modified file 'sql/item_geofunc.cc'
--- a/sql/item_geofunc.cc 2009-10-24 06:57:31 +0000
+++ b/sql/item_geofunc.cc 2009-12-08 09:26:11 +0000
@@ -511,8 +511,8 @@ err:
longlong Item_func_spatial_rel::val_int()
{
DBUG_ASSERT(fixed == 1);
- String *res1= args[0]->val_str(&tmp_value1);
- String *res2= args[1]->val_str(&tmp_value2);
+ String *res1= args[0]->val_str(&cmp.value1);
+ String *res2= args[1]->val_str(&cmp.value2);
Geometry_buffer buffer1, buffer2;
Geometry *g1, *g2;
MBR mbr1, mbr2;
=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc 2009-12-03 11:19:05 +0000
+++ b/sql/item_strfunc.cc 2010-03-04 08:03:07 +0000
@@ -42,6 +42,20 @@ C_MODE_END
String my_empty_string("",default_charset_info);
+/*
+ Convert an array of bytes to a hexadecimal representation.
+
+ Used to generate a hexadecimal representation of a message digest.
+*/
+static void array_to_hex(char *to, const char *str, uint len)
+{
+ const char *str_end= str + len;
+ for (; str != str_end; ++str)
+ {
+ *to++= _dig_vec_lower[((uchar) *str) >> 4];
+ *to++= _dig_vec_lower[((uchar) *str) & 0x0F];
+ }
+}
bool Item_str_func::fix_fields(THD *thd, Item **ref)
@@ -114,12 +128,7 @@ String *Item_func_md5::val_str(String *s
null_value=1;
return 0;
}
- sprintf((char *) str->ptr(),
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
- digest[0], digest[1], digest[2], digest[3],
- digest[4], digest[5], digest[6], digest[7],
- digest[8], digest[9], digest[10], digest[11],
- digest[12], digest[13], digest[14], digest[15]);
+ array_to_hex((char *) str->ptr(), (const char*) digest, 16);
str->length((uint) 32);
return str;
}
@@ -160,15 +169,7 @@ String *Item_func_sha::val_str(String *s
if (!( str->alloc(SHA1_HASH_SIZE*2) ||
(mysql_sha1_result(&context,digest))))
{
- sprintf((char *) str->ptr(),
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\
-%02x%02x%02x%02x%02x%02x%02x%02x",
- digest[0], digest[1], digest[2], digest[3],
- digest[4], digest[5], digest[6], digest[7],
- digest[8], digest[9], digest[10], digest[11],
- digest[12], digest[13], digest[14], digest[15],
- digest[16], digest[17], digest[18], digest[19]);
-
+ array_to_hex((char *) str->ptr(), (const char*) digest, SHA1_HASH_SIZE);
str->length((uint) SHA1_HASH_SIZE*2);
null_value=0;
return str;
@@ -678,8 +679,8 @@ String *Item_func_concat_ws::val_str(Str
res->length() + sep_str->length() + res2->length())
{
/* We have room in str; We can't get any errors here */
- if (str == res2)
- { // This is quote uncommon!
+ if (str->ptr() == res2->ptr())
+ { // This is quite uncommon!
str->replace(0,0,*sep_str);
str->replace(0,0,*res);
}
@@ -1721,68 +1722,65 @@ String *Item_func_encrypt::val_str(Strin
#endif /* HAVE_CRYPT */
}
+bool Item_func_encode::seed()
+{
+ char buf[80];
+ ulong rand_nr[2];
+ String *key, tmp(buf, sizeof(buf), system_charset_info);
+
+ if (!(key= args[1]->val_str(&tmp)))
+ return TRUE;
+
+ hash_password(rand_nr, key->ptr(), key->length());
+ sql_crypt.init(rand_nr);
+
+ return FALSE;
+}
+
void Item_func_encode::fix_length_and_dec()
{
max_length=args[0]->max_length;
maybe_null=args[0]->maybe_null || args[1]->maybe_null;
collation.set(&my_charset_bin);
+ /* Precompute the seed state if the item is constant. */
+ seeded= args[1]->const_item() &&
+ (args[1]->result_type() == STRING_RESULT) && !seed();
}
String *Item_func_encode::val_str(String *str)
{
String *res;
- char pw_buff[80];
- String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info);
- String *password;
DBUG_ASSERT(fixed == 1);
if (!(res=args[0]->val_str(str)))
{
- null_value=1; /* purecov: inspected */
- return 0; /* purecov: inspected */
+ null_value= 1;
+ return NULL;
}
- if (!(password=args[1]->val_str(& tmp_pw_value)))
+ if (!seeded && seed())
{
- null_value=1;
- return 0;
+ null_value= 1;
+ return NULL;
}
- null_value=0;
- res=copy_if_not_alloced(str,res,res->length());
- SQL_CRYPT sql_crypt(password->ptr(), password->length());
- sql_crypt.init();
- sql_crypt.encode((char*) res->ptr(),res->length());
- res->set_charset(&my_charset_bin);
+ null_value= 0;
+ res= copy_if_not_alloced(str, res, res->length());
+ crypto_transform(res);
+ sql_crypt.reinit();
+
return res;
}
-String *Item_func_decode::val_str(String *str)
+void Item_func_encode::crypto_transform(String *res)
{
- String *res;
- char pw_buff[80];
- String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info);
- String *password;
- DBUG_ASSERT(fixed == 1);
-
- if (!(res=args[0]->val_str(str)))
- {
- null_value=1; /* purecov: inspected */
- return 0; /* purecov: inspected */
- }
-
- if (!(password=args[1]->val_str(& tmp_pw_value)))
- {
- null_value=1;
- return 0;
- }
+ sql_crypt.encode((char*) res->ptr(),res->length());
+ res->set_charset(&my_charset_bin);
+}
- null_value=0;
- res=copy_if_not_alloced(str,res,res->length());
- SQL_CRYPT sql_crypt(password->ptr(), password->length());
- sql_crypt.init();
+void Item_func_decode::crypto_transform(String *res)
+{
sql_crypt.decode((char*) res->ptr(),res->length());
- return res;
}
@@ -1828,8 +1826,9 @@ String *Item_func_database::val_str(Stri
/**
- @todo
- make USER() replicate properly (currently it is replicated to "")
+ @note USER() is replicated correctly if binlog_format=ROW or (as of
+ BUG#28086) binlog_format=MIXED, but is incorrectly replicated to ''
+ if binlog_format=STATEMENT.
*/
bool Item_func_user::init(const char *user, const char *host)
{
=== modified file 'sql/item_strfunc.h'
--- a/sql/item_strfunc.h 2009-09-07 20:50:10 +0000
+++ b/sql/item_strfunc.h 2010-03-04 08:03:07 +0000
@@ -351,12 +351,22 @@ public:
class Item_func_encode :public Item_str_func
{
+private:
+ /** Whether the PRNG has already been seeded. */
+ bool seeded;
+protected:
+ SQL_CRYPT sql_crypt;
public:
Item_func_encode(Item *a, Item *seed):
Item_str_func(a, seed) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "encode"; }
+protected:
+ virtual void crypto_transform(String *);
+private:
+ /** Provide a seed for the PRNG sequence. */
+ bool seed();
};
@@ -364,8 +374,9 @@ class Item_func_decode :public Item_func
{
public:
Item_func_decode(Item *a, Item *seed): Item_func_encode(a, seed) {}
- String *val_str(String *);
const char *func_name() const { return "decode"; }
+protected:
+ void crypto_transform(String *);
};
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2009-12-03 11:19:05 +0000
+++ b/sql/item_subselect.cc 2010-03-09 19:29:05 +0000
@@ -39,7 +39,8 @@ inline Item * and_items(Item* cond, Item
Item_subselect::Item_subselect():
Item_result_field(), value_assigned(0), thd(0), substitution(0),
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
- const_item_cache(1), in_fix_fields(0), engine_changed(0), changed(0), is_correlated(FALSE)
+ const_item_cache(1), in_fix_fields(0), eliminated(FALSE),
+ engine_changed(0), changed(0), is_correlated(FALSE)
{
with_subselect= 1;
reset();
@@ -431,6 +432,7 @@ void Item_maxmin_subselect::print(String
void Item_singlerow_subselect::reset()
{
+ eliminated= FALSE;
null_value= 1;
if (value)
value->null_value= 1;
@@ -503,6 +505,7 @@ Item_singlerow_subselect::select_transfo
void Item_singlerow_subselect::store(uint i, Item *item)
{
row[i]->store(item);
+ row[i]->cache_value();
}
enum Item_result Item_singlerow_subselect::result_type() const
@@ -1773,6 +1776,10 @@ int subselect_single_select_engine::prep
{
if (prepared)
return 0;
+ if (select_lex->join)
+ {
+ select_lex->cleanup();
+ }
join= new JOIN(thd, select_lex->item_list,
select_lex->options | SELECT_NO_UNLOCK, result);
if (!join || !result)
@@ -1854,6 +1861,7 @@ void subselect_engine::set_row(List<Item
if (!(row[i]= Item_cache::get_cache(sel_item)))
return;
row[i]->setup(sel_item);
+ row[i]->store(sel_item);
}
if (item_list.elements > 1)
res_type= ROW_RESULT;
=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h 2009-08-31 20:02:09 +0000
+++ b/sql/item_subselect.h 2010-03-09 15:03:54 +0000
@@ -90,6 +90,7 @@ public:
void cleanup();
virtual void reset()
{
+ eliminated= FALSE;
null_value= 1;
}
virtual trans_res select_transformer(JOIN *join);
@@ -142,6 +143,7 @@ public:
@return the SELECT_LEX structure associated with this Item
*/
st_select_lex* get_select_lex();
+ const char *func_name() const { DBUG_ASSERT(0); return "subselect"; }
friend class select_subselect;
friend class Item_in_optimizer;
@@ -234,6 +236,7 @@ public:
subs_type substype() { return EXISTS_SUBS; }
void reset()
{
+ eliminated= FALSE;
value= 0;
}
@@ -305,6 +308,7 @@ public:
subs_type substype() { return IN_SUBS; }
void reset()
{
+ eliminated= FALSE;
value= 0;
null_value= 0;
was_null= 0;
=== modified file 'sql/item_sum.cc'
--- a/sql/item_sum.cc 2009-12-03 11:19:05 +0000
+++ b/sql/item_sum.cc 2010-03-28 18:10:00 +0000
@@ -517,8 +517,7 @@ Field *Item_sum::create_tmp_field(bool g
name, table->s, collation.collation);
break;
case DECIMAL_RESULT:
- field= new Field_new_decimal(max_length, maybe_null, name,
- decimals, unsigned_flag);
+ field= Field_new_decimal::create_from_item(this);
break;
case ROW_RESULT:
default:
@@ -610,35 +609,6 @@ Item_sum_num::fix_fields(THD *thd, Item
}
-Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
- :Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
- hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
- was_values(item->was_values)
-{
- /* copy results from old value */
- switch (hybrid_type) {
- case INT_RESULT:
- sum_int= item->sum_int;
- break;
- case DECIMAL_RESULT:
- my_decimal2decimal(&item->sum_dec, &sum_dec);
- break;
- case REAL_RESULT:
- sum= item->sum;
- break;
- case STRING_RESULT:
- /*
- This can happen with ROLLUP. Note that the value is already
- copied at function call.
- */
- break;
- case ROW_RESULT:
- default:
- DBUG_ASSERT(0);
- }
- collation.set(item->collation);
-}
-
bool
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
{
@@ -658,15 +628,12 @@ Item_sum_hybrid::fix_fields(THD *thd, It
switch (hybrid_type= item->result_type()) {
case INT_RESULT:
max_length= 20;
- sum_int= 0;
break;
case DECIMAL_RESULT:
max_length= item->max_length;
- my_decimal_set_zero(&sum_dec);
break;
case REAL_RESULT:
max_length= float_length(decimals);
- sum= 0.0;
break;
case STRING_RESULT:
max_length= item->max_length;
@@ -675,10 +642,10 @@ Item_sum_hybrid::fix_fields(THD *thd, It
default:
DBUG_ASSERT(0);
};
+ setup_item(args[0], NULL);
/* MIN/MAX can return NULL for empty set indepedent of the used column */
maybe_null= 1;
unsigned_flag=item->unsigned_flag;
- collation.set(item->collation);
result_field=0;
null_value=1;
fix_length_and_dec();
@@ -696,6 +663,30 @@ Item_sum_hybrid::fix_fields(THD *thd, It
return FALSE;
}
+
+/**
+ MIN/MAX function setup.
+
+ @param item argument of MIN/MAX function
+ @param value_arg calculated value of MIN/MAX function
+
+ @details
+ Setup cache/comparator of MIN/MAX functions. When called by the
+ copy_or_same function value_arg parameter contains calculated value
+ of the original MIN/MAX object and it is saved in this object's cache.
+*/
+
+void Item_sum_hybrid::setup_item(Item *item, Item *value_arg)
+{
+ value= Item_cache::get_cache(item);
+ value->setup(item);
+ value->store(value_arg);
+ cmp= new Arg_comparator();
+ cmp->set_cmp_func(this, args, (Item**)&value, FALSE);
+ collation.set(item->collation);
+}
+
+
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
uint convert_blob_length)
{
@@ -1265,8 +1256,7 @@ Field *Item_sum_avg::create_tmp_field(bo
0, name, &my_charset_bin);
}
else if (hybrid_type == DECIMAL_RESULT)
- field= new Field_new_decimal(max_length, maybe_null, name,
- decimals, unsigned_flag);
+ field= Field_new_decimal::create_from_item(this);
else
field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
if (field)
@@ -1587,19 +1577,7 @@ void Item_sum_variance::update_field()
void Item_sum_hybrid::clear()
{
- switch (hybrid_type) {
- case INT_RESULT:
- sum_int= 0;
- break;
- case DECIMAL_RESULT:
- my_decimal_set_zero(&sum_dec);
- break;
- case REAL_RESULT:
- sum= 0.0;
- break;
- default:
- value.length(0);
- }
+ value->null_value= 1;
null_value= 1;
}
@@ -1608,30 +1586,7 @@ double Item_sum_hybrid::val_real()
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0.0;
- switch (hybrid_type) {
- case STRING_RESULT:
- {
- char *end_not_used;
- int err_not_used;
- String *res; res=val_str(&str_value);
- return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
- &end_not_used, &err_not_used) : 0.0);
- }
- case INT_RESULT:
- if (unsigned_flag)
- return ulonglong2double(sum_int);
- return (double) sum_int;
- case DECIMAL_RESULT:
- my_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
- return sum;
- case REAL_RESULT:
- return sum;
- case ROW_RESULT:
- default:
- // This case should never be choosen
- DBUG_ASSERT(0);
- return 0;
- }
+ return value->val_real();
}
longlong Item_sum_hybrid::val_int()
@@ -1639,18 +1594,7 @@ longlong Item_sum_hybrid::val_int()
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0;
- switch (hybrid_type) {
- case INT_RESULT:
- return sum_int;
- case DECIMAL_RESULT:
- {
- longlong result;
- my_decimal2int(E_DEC_FATAL_ERROR, &sum_dec, unsigned_flag, &result);
- return sum_int;
- }
- default:
- return (longlong) rint(Item_sum_hybrid::val_real());
- }
+ return value->val_int();
}
@@ -1659,26 +1603,7 @@ my_decimal *Item_sum_hybrid::val_decimal
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0;
- switch (hybrid_type) {
- case STRING_RESULT:
- string2my_decimal(E_DEC_FATAL_ERROR, &value, val);
- break;
- case REAL_RESULT:
- double2my_decimal(E_DEC_FATAL_ERROR, sum, val);
- break;
- case DECIMAL_RESULT:
- val= &sum_dec;
- break;
- case INT_RESULT:
- int2my_decimal(E_DEC_FATAL_ERROR, sum_int, unsigned_flag, val);
- break;
- case ROW_RESULT:
- default:
- // This case should never be choosen
- DBUG_ASSERT(0);
- break;
- }
- return val; // Keep compiler happy
+ return value->val_decimal(val);
}
@@ -1688,25 +1613,7 @@ Item_sum_hybrid::val_str(String *str)
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0;
- switch (hybrid_type) {
- case STRING_RESULT:
- return &value;
- case REAL_RESULT:
- str->set_real(sum,decimals, &my_charset_bin);
- break;
- case DECIMAL_RESULT:
- my_decimal2string(E_DEC_FATAL_ERROR, &sum_dec, 0, 0, 0, str);
- return str;
- case INT_RESULT:
- str->set_int(sum_int, unsigned_flag, &my_charset_bin);
- break;
- case ROW_RESULT:
- default:
- // This case should never be choosen
- DBUG_ASSERT(0);
- break;
- }
- return str; // Keep compiler happy
+ return value->val_str(str);
}
@@ -1715,7 +1622,9 @@ void Item_sum_hybrid::cleanup()
DBUG_ENTER("Item_sum_hybrid::cleanup");
Item_sum::cleanup();
forced_const= FALSE;
-
+ if (cmp)
+ delete cmp;
+ cmp= 0;
/*
by default it is TRUE to avoid TRUE reporting by
Item_func_not_all/Item_func_nop_all if this item was never called.
@@ -1736,63 +1645,22 @@ void Item_sum_hybrid::no_rows_in_result(
Item *Item_sum_min::copy_or_same(THD* thd)
{
- return new (thd->mem_root) Item_sum_min(thd, this);
+ Item_sum_min *item= new (thd->mem_root) Item_sum_min(thd, this);
+ item->setup_item(args[0], value);
+ return item;
}
bool Item_sum_min::add()
{
- switch (hybrid_type) {
- case STRING_RESULT:
+ /* args[0] < value */
+ int res= cmp->compare();
+ if (!args[0]->null_value &&
+ (null_value || res < 0))
{
- String *result=args[0]->val_str(&tmp_value);
- if (!args[0]->null_value &&
- (null_value || sortcmp(&value,result,collation.collation) > 0))
- {
- value.copy(*result);
- null_value=0;
- }
- }
- break;
- case INT_RESULT:
- {
- longlong nr=args[0]->val_int();
- if (!args[0]->null_value && (null_value ||
- (unsigned_flag &&
- (ulonglong) nr < (ulonglong) sum_int) ||
- (!unsigned_flag && nr < sum_int)))
- {
- sum_int=nr;
- null_value=0;
- }
- }
- break;
- case DECIMAL_RESULT:
- {
- my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
- if (!args[0]->null_value &&
- (null_value || (my_decimal_cmp(&sum_dec, val) > 0)))
- {
- my_decimal2decimal(val, &sum_dec);
- null_value= 0;
- }
- }
- break;
- case REAL_RESULT:
- {
- double nr= args[0]->val_real();
- if (!args[0]->null_value && (null_value || nr < sum))
- {
- sum=nr;
- null_value=0;
- }
- }
- break;
- case ROW_RESULT:
- default:
- // This case should never be choosen
- DBUG_ASSERT(0);
- break;
+ value->store(args[0]);
+ value->cache_value();
+ null_value= 0;
}
return 0;
}
@@ -1800,63 +1668,22 @@ bool Item_sum_min::add()
Item *Item_sum_max::copy_or_same(THD* thd)
{
- return new (thd->mem_root) Item_sum_max(thd, this);
+ Item_sum_max *item= new (thd->mem_root) Item_sum_max(thd, this);
+ item->setup_item(args[0], value);
+ return item;
}
bool Item_sum_max::add()
{
- switch (hybrid_type) {
- case STRING_RESULT:
+ /* args[0] > value */
+ int res= cmp->compare();
+ if (!args[0]->null_value &&
+ (null_value || res > 0))
{
- String *result=args[0]->val_str(&tmp_value);
- if (!args[0]->null_value &&
- (null_value || sortcmp(&value,result,collation.collation) < 0))
- {
- value.copy(*result);
- null_value=0;
- }
- }
- break;
- case INT_RESULT:
- {
- longlong nr=args[0]->val_int();
- if (!args[0]->null_value && (null_value ||
- (unsigned_flag &&
- (ulonglong) nr > (ulonglong) sum_int) ||
- (!unsigned_flag && nr > sum_int)))
- {
- sum_int=nr;
- null_value=0;
- }
- }
- break;
- case DECIMAL_RESULT:
- {
- my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
- if (!args[0]->null_value &&
- (null_value || (my_decimal_cmp(val, &sum_dec) > 0)))
- {
- my_decimal2decimal(val, &sum_dec);
- null_value= 0;
- }
- }
- break;
- case REAL_RESULT:
- {
- double nr= args[0]->val_real();
- if (!args[0]->null_value && (null_value || nr > sum))
- {
- sum=nr;
- null_value=0;
- }
- }
- break;
- case ROW_RESULT:
- default:
- // This case should never be choosen
- DBUG_ASSERT(0);
- break;
+ value->store(args[0]);
+ value->cache_value();
+ null_value= 0;
}
return 0;
}
@@ -2221,14 +2048,15 @@ void Item_sum_hybrid::update_field()
void
Item_sum_hybrid::min_max_update_str_field()
{
- String *res_str=args[0]->val_str(&value);
+ DBUG_ASSERT(cmp);
+ String *res_str=args[0]->val_str(&cmp->value1);
if (!args[0]->null_value)
{
- result_field->val_str(&tmp_value);
+ result_field->val_str(&cmp->value2);
if (result_field->is_null() ||
- (cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
+ (cmp_sign * sortcmp(res_str,&cmp->value2,collation.collation)) < 0)
result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
result_field->set_notnull();
}
=== modified file 'sql/item_sum.h'
--- a/sql/item_sum.h 2009-09-15 10:46:35 +0000
+++ b/sql/item_sum.h 2010-03-28 18:10:00 +0000
@@ -329,22 +329,6 @@ public:
virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; }
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
- /*
- This method is used for debug purposes to print the name of an
- item to the debug log. The second use of this method is as
- a helper function of print(), where it is applicable.
- To suit both goals it should return a meaningful,
- distinguishable and sintactically correct string. This method
- should not be used for runtime type identification, use enum
- {Sum}Functype and Item_func::functype()/Item_sum::sum_func()
- instead.
-
- NOTE: for Items inherited from Item_sum, func_name() return part of
- function name till first argument (including '(') to make difference in
- names for functions with 'distinct' clause and without 'distinct' and
- also to make printing of items inherited from Item_sum uniform.
- */
- virtual const char *func_name() const= 0;
virtual Item *result_item(Field *field)
{ return new Item_field(field); }
/*
@@ -679,6 +663,7 @@ public:
}
void fix_length_and_dec() {}
enum Item_result result_type () const { return hybrid_type; }
+ const char *func_name() const { DBUG_ASSERT(0); return "avg_field"; }
};
@@ -747,6 +732,7 @@ public:
}
void fix_length_and_dec() {}
enum Item_result result_type () const { return hybrid_type; }
+ const char *func_name() const { DBUG_ASSERT(0); return "variance_field"; }
};
@@ -822,6 +808,7 @@ public:
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
+ const char *func_name() const { DBUG_ASSERT(0); return "std_field"; }
};
/*
@@ -847,14 +834,13 @@ class Item_sum_std :public Item_sum_vari
};
// This class is a string or number function depending on num_func
-
+class Arg_comparator;
+class Item_cache;
class Item_sum_hybrid :public Item_sum
{
protected:
- String value,tmp_value;
- double sum;
- longlong sum_int;
- my_decimal sum_dec;
+ Item_cache *value;
+ Arg_comparator *cmp;
Item_result hybrid_type;
enum_field_types hybrid_field_type;
int cmp_sign;
@@ -862,12 +848,17 @@ protected:
public:
Item_sum_hybrid(Item *item_par,int sign)
- :Item_sum(item_par), sum(0.0), sum_int(0),
+ :Item_sum(item_par), value(0), cmp(0),
hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG),
cmp_sign(sign), was_values(TRUE)
{ collation.set(&my_charset_bin); }
- Item_sum_hybrid(THD *thd, Item_sum_hybrid *item);
+ Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
+ :Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
+ hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
+ was_values(item->was_values)
+ { }
bool fix_fields(THD *, Item **);
+ void setup_item(Item *item, Item *value_arg);
void clear();
double val_real();
longlong val_int();
=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc 2009-12-03 11:19:05 +0000
+++ b/sql/item_timefunc.cc 2010-03-04 08:03:07 +0000
@@ -391,7 +391,7 @@ static bool extract_date_time(DATE_TIME_
if (tmp - val > 6)
tmp= (char*) val + 6;
l_time->second_part= (int) my_strtoll10(val, &tmp, &error);
- frac_part= 6 - (uint) (tmp - val);
+ frac_part= 6 - (int) (tmp - val);
if (frac_part > 0)
l_time->second_part*= (ulong) log_10_int[frac_part];
val= tmp;
@@ -882,9 +882,9 @@ static bool get_interval_info(const char
value= value*LL(10) + (longlong) (*str - '0');
if (transform_msec && i == count - 1) // microseconds always last
{
- long msec_length= 6 - (uint) (str - start);
+ int msec_length= 6 - (int)(str - start);
if (msec_length > 0)
- value*= (long) log_10_int[msec_length];
+ value*= (long)log_10_int[msec_length];
}
values[i]= value;
while (str != end && !my_isdigit(cs,*str))
@@ -2560,9 +2560,9 @@ void Item_char_typecast::fix_length_and_
from_cs != &my_charset_bin &&
cast_cs != &my_charset_bin);
collation.set(cast_cs, DERIVATION_IMPLICIT);
- char_length= (cast_length >= 0) ?
- cast_length :
- args[0]->max_length / args[0]->collation.collation->mbmaxlen;
+ char_length= (cast_length >= 0) ? cast_length :
+ args[0]->max_length /
+ (cast_cs == &my_charset_bin ? 1 : args[0]->collation.collation->mbmaxlen);
max_length= char_length * cast_cs->mbmaxlen;
}
=== modified file 'sql/item_timefunc.h'
--- a/sql/item_timefunc.h 2009-02-07 15:50:31 +0000
+++ b/sql/item_timefunc.h 2009-12-13 20:29:50 +0000
@@ -305,6 +305,16 @@ public:
Item_func_unix_timestamp(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "unix_timestamp"; }
+ bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+ /*
+ UNIX_TIMESTAMP() depends on the current timezone
+ (and thus may not be used as a partitioning function)
+ when its argument is NOT of the TIMESTAMP type.
+ */
+ bool is_timezone_dependent_processor(uchar *int_arg)
+ {
+ return !has_timestamp_args();
+ }
void fix_length_and_dec()
{
decimals=0;
=== modified file 'sql/item_xmlfunc.cc'
--- a/sql/item_xmlfunc.cc 2009-12-03 11:19:05 +0000
+++ b/sql/item_xmlfunc.cc 2010-01-15 15:27:55 +0000
@@ -941,14 +941,16 @@ static Item *create_comparator(MY_XPATH
in a loop through all of the nodes in the node set.
*/
- Item *fake= new Item_string("", 0, xpath->cs);
+ Item_string *fake= new Item_string("", 0, xpath->cs);
+ /* Don't cache fake because its value will be changed during comparison.*/
+ fake->set_used_tables(RAND_TABLE_BIT);
Item_nodeset_func *nodeset;
Item *scalar, *comp;
if (a->type() == Item::XPATH_NODESET)
{
nodeset= (Item_nodeset_func*) a;
scalar= b;
- comp= eq_func(oper, fake, scalar);
+ comp= eq_func(oper, (Item*)fake, scalar);
}
else
{
=== modified file 'sql/lock.cc'
--- a/sql/lock.cc 2009-10-15 21:38:29 +0000
+++ b/sql/lock.cc 2010-02-10 19:06:24 +0000
@@ -1049,10 +1049,14 @@ int lock_table_name(THD *thd, TABLE_LIST
DBUG_RETURN(-1);
table_list->table=table;
+ table->s->deleting= table_list->deleting;
/* Return 1 if table is in use */
DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
- check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
+ (check_in_use ?
+ RTFC_NO_FLAG :
+ RTFC_WAIT_OTHER_THREAD_FLAG),
+ table_list->deleting)));
}
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2009-12-03 11:19:05 +0000
+++ b/sql/log.cc 2010-03-24 22:12:39 +0000
@@ -1475,7 +1475,7 @@ binlog_end_trans(THD *thd, binlog_trx_da
if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
{
if (trx_data->has_incident())
- mysql_bin_log.write_incident(thd, TRUE);
+ error= mysql_bin_log.write_incident(thd, TRUE);
trx_data->reset();
}
else // ...statement
@@ -1910,6 +1910,22 @@ void MYSQL_LOG::init(enum_log_type log_t
}
+bool MYSQL_LOG::init_and_set_log_file_name(const char *log_name,
+ const char *new_name,
+ enum_log_type log_type_arg,
+ enum cache_type io_cache_type_arg)
+{
+ init(log_type_arg, io_cache_type_arg);
+
+ if (new_name && !strmov(log_file_name, new_name))
+ return TRUE;
+ else if (!new_name && generate_new_name(log_file_name, log_name))
+ return TRUE;
+
+ return FALSE;
+}
+
+
/*
Open a (new) log file.
@@ -1942,17 +1958,14 @@ bool MYSQL_LOG::open(const char *log_nam
write_error= 0;
- init(log_type_arg, io_cache_type_arg);
-
if (!(name= my_strdup(log_name, MYF(MY_WME))))
{
name= (char *)log_name; // for the error message
goto err;
}
- if (new_name)
- strmov(log_file_name, new_name);
- else if (generate_new_name(log_file_name, name))
+ if (init_and_set_log_file_name(name, new_name,
+ log_type_arg, io_cache_type_arg))
goto err;
if (io_cache_type == SEQ_READ_APPEND)
@@ -2440,7 +2453,7 @@ const char *MYSQL_LOG::generate_name(con
{
char *p= fn_ext(log_name);
uint length= (uint) (p - log_name);
- strmake(buff, log_name, min(length, FN_REFLEN));
+ strmake(buff, log_name, min(length, FN_REFLEN-1));
return (const char*)buff;
}
return log_name;
@@ -2462,7 +2475,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG()
*/
index_file_name[0] = 0;
bzero((char*) &index_file, sizeof(index_file));
- bzero((char*) &purge_temp, sizeof(purge_temp));
+ bzero((char*) &purge_index_file, sizeof(purge_index_file));
}
/* this is called only once */
@@ -2511,7 +2524,7 @@ void MYSQL_BIN_LOG::init_pthread_objects
bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
- const char *log_name)
+ const char *log_name, bool need_mutex)
{
File index_file_nr= -1;
DBUG_ASSERT(!my_b_inited(&index_file));
@@ -2536,7 +2549,8 @@ bool MYSQL_BIN_LOG::open_index_file(cons
init_io_cache(&index_file, index_file_nr,
IO_SIZE, WRITE_CACHE,
my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
- 0, MYF(MY_WME | MY_WAIT_IF_FULL)))
+ 0, MYF(MY_WME | MY_WAIT_IF_FULL)) ||
+ DBUG_EVALUATE_IF("fault_injection_openning_index", 1, 0))
{
/*
TODO: all operations creating/deleting the index file or a log, should
@@ -2547,6 +2561,28 @@ bool MYSQL_BIN_LOG::open_index_file(cons
my_close(index_file_nr,MYF(0));
return TRUE;
}
+
+#ifdef HAVE_REPLICATION
+ /*
+ Sync the index by purging any binary log file that is not registered.
+ In other words, either purge binary log files that were removed from
+ the index but not purged from the file system due to a crash or purge
+ any binary log file that was created but not register in the index
+ due to a crash.
+ */
+
+ if (set_purge_index_file_name(index_file_name_arg) ||
+ open_purge_index_file(FALSE) ||
+ purge_index_entry(NULL, NULL, need_mutex) ||
+ close_purge_index_file() ||
+ DBUG_EVALUATE_IF("fault_injection_recovering_index", 1, 0))
+ {
+ sql_print_error("MYSQL_BIN_LOG::open_index_file failed to sync the index "
+ "file.");
+ return TRUE;
+ }
+#endif
+
return FALSE;
}
@@ -2571,17 +2607,44 @@ bool MYSQL_BIN_LOG::open(const char *log
enum cache_type io_cache_type_arg,
bool no_auto_events_arg,
ulong max_size_arg,
- bool null_created_arg)
+ bool null_created_arg,
+ bool need_mutex)
{
File file= -1;
+
DBUG_ENTER("MYSQL_BIN_LOG::open");
DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
- write_error=0;
+ if (init_and_set_log_file_name(log_name, new_name, log_type_arg,
+ io_cache_type_arg))
+ {
+ sql_print_error("MSYQL_BIN_LOG::open failed to generate new file name.");
+ DBUG_RETURN(1);
+ }
+
+#ifdef HAVE_REPLICATION
+ if (open_purge_index_file(TRUE) ||
+ register_create_index_entry(log_file_name) ||
+ sync_purge_index_file() ||
+ DBUG_EVALUATE_IF("fault_injection_registering_index", 1, 0))
+ {
+ sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file.");
+ DBUG_RETURN(1);
+ }
+ DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", abort(););
+#endif
+
+ write_error= 0;
/* open the main log file */
- if (MYSQL_LOG::open(log_name, log_type_arg, new_name, io_cache_type_arg))
+ if (MYSQL_LOG::open(log_name, log_type_arg, new_name,
+ io_cache_type_arg))
+ {
+#ifdef HAVE_REPLICATION
+ close_purge_index_file();
+#endif
DBUG_RETURN(1); /* all warnings issued */
+ }
init(no_auto_events_arg, max_size_arg);
@@ -2607,9 +2670,6 @@ bool MYSQL_BIN_LOG::open(const char *log
write_file_name_to_index_file= 1;
}
- DBUG_ASSERT(my_b_inited(&index_file) != 0);
- reinit_io_cache(&index_file, WRITE_CACHE,
- my_b_filelength(&index_file), 0, 0);
if (need_start_event && !no_auto_events)
{
/*
@@ -2667,23 +2727,44 @@ bool MYSQL_BIN_LOG::open(const char *log
if (write_file_name_to_index_file)
{
+#ifdef HAVE_REPLICATION
+ DBUG_EXECUTE_IF("crash_create_critical_before_update_index", abort(););
+#endif
+
+ DBUG_ASSERT(my_b_inited(&index_file) != 0);
+ reinit_io_cache(&index_file, WRITE_CACHE,
+ my_b_filelength(&index_file), 0, 0);
/*
As this is a new log file, we write the file name to the index
file. As every time we write to the index file, we sync it.
*/
- if (my_b_write(&index_file, (uchar*) log_file_name,
- strlen(log_file_name)) ||
- my_b_write(&index_file, (uchar*) "\n", 1) ||
- flush_io_cache(&index_file) ||
+ if (DBUG_EVALUATE_IF("fault_injection_updating_index", 1, 0) ||
+ my_b_write(&index_file, (uchar*) log_file_name,
+ strlen(log_file_name)) ||
+ my_b_write(&index_file, (uchar*) "\n", 1) ||
+ flush_io_cache(&index_file) ||
my_sync(index_file.file, MYF(MY_WME)))
- goto err;
+ goto err;
+
+#ifdef HAVE_REPLICATION
+ DBUG_EXECUTE_IF("crash_create_after_update_index", abort(););
+#endif
}
}
log_state= LOG_OPENED;
+#ifdef HAVE_REPLICATION
+ close_purge_index_file();
+#endif
+
DBUG_RETURN(0);
err:
+#ifdef HAVE_REPLICATION
+ if (is_inited_purge_index_file())
+ purge_index_entry(NULL, NULL, need_mutex);
+ close_purge_index_file();
+#endif
sql_print_error("Could not use %s for logging (error %d). \
Turning logging off for the whole duration of the MySQL server process. \
To turn it on again: fix the cause, \
@@ -2940,8 +3021,15 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
name=0; // Protect against free
close(LOG_CLOSE_TO_BE_OPENED);
- /* First delete all old log files */
+ /*
+ First delete all old log files and then update the index file.
+ As we first delete the log files and do not use sort of logging,
+ a crash may lead to an inconsistent state where the index has
+ references to non-existent files.
+ We need to invert the steps and use the purge_index_file methods
+ in order to make the operation safe.
+ */
if (find_log_pos(&linfo, NullS, 0))
{
error=1;
@@ -2964,7 +3052,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
}
else
{
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with deleting %s; "
"consider examining correspondence "
@@ -2995,7 +3083,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
}
else
{
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with deleting %s; "
"consider examining correspondence "
@@ -3008,8 +3096,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
}
if (!thd->slave_thread)
need_start_event=1;
- if (!open_index_file(index_file_name, 0))
- open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0);
+ if (!open_index_file(index_file_name, 0, FALSE))
+ open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE);
my_free((uchar*) save_name, MYF(0));
err:
@@ -3196,7 +3284,7 @@ int MYSQL_BIN_LOG::purge_logs(const char
bool need_update_threads,
ulonglong *decrease_log_space)
{
- int error;
+ int error= 0;
bool exit_loop= 0;
LOG_INFO log_info;
THD *thd= current_thd;
@@ -3207,33 +3295,15 @@ int MYSQL_BIN_LOG::purge_logs(const char
pthread_mutex_lock(&LOCK_index);
if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/)))
{
- sql_print_error("MYSQL_LOG::purge_logs was called with file %s not "
+ sql_print_error("MYSQL_BIN_LOG::purge_logs was called with file %s not "
"listed in the index.", to_log);
goto err;
}
- /*
- For crash recovery reasons the index needs to be updated before
- any files are deleted. Move files to be deleted into a temp file
- to be processed after the index is updated.
- */
- if (!my_b_inited(&purge_temp))
- {
- if ((error=open_cached_file(&purge_temp, mysql_tmpdir, TEMP_PREFIX,
- DISK_BUFFER_SIZE, MYF(MY_WME))))
- {
- sql_print_error("MYSQL_LOG::purge_logs failed to open purge_temp");
- goto err;
- }
- }
- else
+ if ((error= open_purge_index_file(TRUE)))
{
- if ((error=reinit_io_cache(&purge_temp, WRITE_CACHE, 0, 0, 1)))
- {
- sql_print_error("MYSQL_LOG::purge_logs failed to reinit purge_temp "
- "for write");
- goto err;
- }
+ sql_print_error("MYSQL_BIN_LOG::purge_logs failed to sync the index file.");
+ goto err;
}
/*
@@ -3243,51 +3313,177 @@ int MYSQL_BIN_LOG::purge_logs(const char
if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
goto err;
while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
+ !is_active(log_info.log_file_name) &&
!log_in_use(log_info.log_file_name))
{
- if ((error=my_b_write(&purge_temp, (const uchar*)log_info.log_file_name,
- strlen(log_info.log_file_name))) ||
- (error=my_b_write(&purge_temp, (const uchar*)"\n", 1)))
+ if ((error= register_purge_index_entry(log_info.log_file_name)))
{
- sql_print_error("MYSQL_LOG::purge_logs failed to copy %s to purge_temp",
+ sql_print_error("MYSQL_BIN_LOG::purge_logs failed to copy %s to register file.",
log_info.log_file_name);
goto err;
}
if (find_next_log(&log_info, 0) || exit_loop)
break;
- }
+ }
+
+ DBUG_EXECUTE_IF("crash_purge_before_update_index", abort(););
+
+ if ((error= sync_purge_index_file()))
+ {
+ sql_print_error("MSYQL_BIN_LOG::purge_logs failed to flush register file.");
+ goto err;
+ }
/* We know how many files to delete. Update index file. */
if ((error=update_log_index(&log_info, need_update_threads)))
{
- sql_print_error("MSYQL_LOG::purge_logs failed to update the index file");
+ sql_print_error("MSYQL_BIN_LOG::purge_logs failed to update the index file");
goto err;
}
- DBUG_EXECUTE_IF("crash_after_update_index", abort(););
+ DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", abort(););
+
+err:
+ /* Read each entry from purge_index_file and delete the file. */
+ if (is_inited_purge_index_file() &&
+ (error= purge_index_entry(thd, decrease_log_space, FALSE)))
+ sql_print_error("MSYQL_BIN_LOG::purge_logs failed to process registered files"
+ " that would be purged.");
+ close_purge_index_file();
+
+ DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", abort(););
+
+ if (need_mutex)
+ pthread_mutex_unlock(&LOCK_index);
+ DBUG_RETURN(error);
+}
+
+int MYSQL_BIN_LOG::set_purge_index_file_name(const char *base_file_name)
+{
+ int error= 0;
+ DBUG_ENTER("MYSQL_BIN_LOG::set_purge_index_file_name");
+ if (fn_format(purge_index_file_name, base_file_name, mysql_data_home,
+ ".~rec~", MYF(MY_UNPACK_FILENAME | MY_SAFE_PATH |
+ MY_REPLACE_EXT)) == NULL)
+ {
+ error= 1;
+ sql_print_error("MYSQL_BIN_LOG::set_purge_index_file_name failed to set "
+ "file name.");
+ }
+ DBUG_RETURN(error);
+}
+
+int MYSQL_BIN_LOG::open_purge_index_file(bool destroy)
+{
+ int error= 0;
+ File file= -1;
+
+ DBUG_ENTER("MYSQL_BIN_LOG::open_purge_index_file");
+
+ if (destroy)
+ close_purge_index_file();
+
+ if (!my_b_inited(&purge_index_file))
+ {
+ if ((file= my_open(purge_index_file_name, O_RDWR | O_CREAT | O_BINARY,
+ MYF(MY_WME | ME_WAITTANG))) < 0 ||
+ init_io_cache(&purge_index_file, file, IO_SIZE,
+ (destroy ? WRITE_CACHE : READ_CACHE),
+ 0, 0, MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)))
+ {
+ error= 1;
+ sql_print_error("MYSQL_BIN_LOG::open_purge_index_file failed to open register "
+ " file.");
+ }
+ }
+ DBUG_RETURN(error);
+}
+
+int MYSQL_BIN_LOG::close_purge_index_file()
+{
+ int error= 0;
- /* Switch purge_temp for read. */
- if ((error=reinit_io_cache(&purge_temp, READ_CACHE, 0, 0, 0)))
+ DBUG_ENTER("MYSQL_BIN_LOG::close_purge_index_file");
+
+ if (my_b_inited(&purge_index_file))
{
- sql_print_error("MSYQL_LOG::purge_logs failed to reinit purge_temp "
+ end_io_cache(&purge_index_file);
+ error= my_close(purge_index_file.file, MYF(0));
+ }
+ my_delete(purge_index_file_name, MYF(0));
+ bzero((char*) &purge_index_file, sizeof(purge_index_file));
+
+ DBUG_RETURN(error);
+}
+
+bool MYSQL_BIN_LOG::is_inited_purge_index_file()
+{
+ DBUG_ENTER("MYSQL_BIN_LOG::is_inited_purge_index_file");
+ DBUG_RETURN (my_b_inited(&purge_index_file));
+}
+
+int MYSQL_BIN_LOG::sync_purge_index_file()
+{
+ int error= 0;
+ DBUG_ENTER("MYSQL_BIN_LOG::sync_purge_index_file");
+
+ if ((error= flush_io_cache(&purge_index_file)) ||
+ (error= my_sync(purge_index_file.file, MYF(MY_WME))))
+ DBUG_RETURN(error);
+
+ DBUG_RETURN(error);
+}
+
+int MYSQL_BIN_LOG::register_purge_index_entry(const char *entry)
+{
+ int error= 0;
+ DBUG_ENTER("MYSQL_BIN_LOG::register_purge_index_entry");
+
+ if ((error=my_b_write(&purge_index_file, (const uchar*)entry, strlen(entry))) ||
+ (error=my_b_write(&purge_index_file, (const uchar*)"\n", 1)))
+ DBUG_RETURN (error);
+
+ DBUG_RETURN(error);
+}
+
+int MYSQL_BIN_LOG::register_create_index_entry(const char *entry)
+{
+ DBUG_ENTER("MYSQL_BIN_LOG::register_create_index_entry");
+ DBUG_RETURN(register_purge_index_entry(entry));
+}
+
+int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
+ bool need_mutex)
+{
+ MY_STAT s;
+ int error= 0;
+ LOG_INFO log_info;
+ LOG_INFO check_log_info;
+
+ DBUG_ENTER("MYSQL_BIN_LOG:purge_index_entry");
+
+ DBUG_ASSERT(my_b_inited(&purge_index_file));
+
+ if ((error=reinit_io_cache(&purge_index_file, READ_CACHE, 0, 0, 0)))
+ {
+ sql_print_error("MSYQL_BIN_LOG::purge_index_entry failed to reinit register file "
"for read");
goto err;
}
- /* Read each entry from purge_temp and delete the file. */
for (;;)
{
uint length;
- if ((length=my_b_gets(&purge_temp, log_info.log_file_name,
+ if ((length=my_b_gets(&purge_index_file, log_info.log_file_name,
FN_REFLEN)) <= 1)
{
- if (purge_temp.error)
+ if (purge_index_file.error)
{
- error= purge_temp.error;
- sql_print_error("MSYQL_LOG::purge_logs error %d reading from "
- "purge_temp", error);
+ error= purge_index_file.error;
+ sql_print_error("MSYQL_BIN_LOG::purge_index_entry error %d reading from "
+ "register file.", error);
goto err;
}
@@ -3298,9 +3494,6 @@ int MYSQL_BIN_LOG::purge_logs(const char
/* Get rid of the trailing '\n' */
log_info.log_file_name[length-1]= 0;
- ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
-
- MY_STAT s;
if (!my_stat(log_info.log_file_name, &s, MYF(0)))
{
if (my_errno == ENOENT)
@@ -3326,7 +3519,7 @@ int MYSQL_BIN_LOG::purge_logs(const char
*/
if (thd)
{
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with getting info on being purged %s; "
"consider examining correspondence "
@@ -3348,64 +3541,92 @@ int MYSQL_BIN_LOG::purge_logs(const char
}
else
{
- DBUG_PRINT("info",("purging %s",log_info.log_file_name));
- if (!my_delete(log_info.log_file_name, MYF(0)))
+ if ((error= find_log_pos(&check_log_info, log_info.log_file_name, need_mutex)))
{
- if (decrease_log_space)
- *decrease_log_space-= s.st_size;
- }
- else
- {
- if (my_errno == ENOENT)
+ if (error != LOG_INFO_EOF)
{
if (thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+ ER_BINLOG_PURGE_FATAL_ERR,
+ "a problem with deleting %s and "
+ "reading the binlog index file",
log_info.log_file_name);
}
- sql_print_information("Failed to delete file '%s'",
- log_info.log_file_name);
- my_errno= 0;
+ else
+ {
+ sql_print_information("Failed to delete file '%s' and "
+ "read the binlog index file",
+ log_info.log_file_name);
+ }
+ goto err;
+ }
+
+ error= 0;
+ if (!need_mutex)
+ {
+ /*
+ This is to avoid triggering an error in NDB.
+ */
+ ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
+ }
+
+ DBUG_PRINT("info",("purging %s",log_info.log_file_name));
+ if (!my_delete(log_info.log_file_name, MYF(0)))
+ {
+ if (decrease_log_space)
+ *decrease_log_space-= s.st_size;
}
else
{
- if (thd)
+ if (my_errno == ENOENT)
{
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_BINLOG_PURGE_FATAL_ERR,
- "a problem with deleting %s; "
- "consider examining correspondence "
- "of your binlog index file "
- "to the actual binlog files",
- log_info.log_file_name);
+ if (thd)
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+ log_info.log_file_name);
+ }
+ sql_print_information("Failed to delete file '%s'",
+ log_info.log_file_name);
+ my_errno= 0;
}
else
{
- sql_print_information("Failed to delete file '%s'; "
+ if (thd)
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_BINLOG_PURGE_FATAL_ERR,
+ "a problem with deleting %s; "
"consider examining correspondence "
"of your binlog index file "
"to the actual binlog files",
log_info.log_file_name);
- }
- if (my_errno == EMFILE)
- {
- DBUG_PRINT("info",
- ("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
- error= LOG_INFO_EMFILE;
+ }
+ else
+ {
+ sql_print_information("Failed to delete file '%s'; "
+ "consider examining correspondence "
+ "of your binlog index file "
+ "to the actual binlog files",
+ log_info.log_file_name);
+ }
+ if (my_errno == EMFILE)
+ {
+ DBUG_PRINT("info",
+ ("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
+ error= LOG_INFO_EMFILE;
+ goto err;
+ }
+ error= LOG_INFO_FATAL;
goto err;
}
- error= LOG_INFO_FATAL;
- goto err;
}
}
}
}
err:
- close_cached_file(&purge_temp);
- if (need_mutex)
- pthread_mutex_unlock(&LOCK_index);
DBUG_RETURN(error);
}
@@ -3445,7 +3666,8 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
goto err;
while (strcmp(log_file_name, log_info.log_file_name) &&
- !log_in_use(log_info.log_file_name))
+ !is_active(log_info.log_file_name) &&
+ !log_in_use(log_info.log_file_name))
{
if (!my_stat(log_info.log_file_name, &stat_area, MYF(0)))
{
@@ -3454,14 +3676,6 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
/*
It's not fatal if we can't stat a log file that does not exist.
*/
- if (thd)
- {
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
- log_info.log_file_name);
- }
- sql_print_information("Failed to execute my_stat on file '%s'",
- log_info.log_file_name);
my_errno= 0;
}
else
@@ -3471,7 +3685,7 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
*/
if (thd)
{
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BINLOG_PURGE_FATAL_ERR,
"a problem with getting info on being purged %s; "
"consider examining correspondence "
@@ -3493,7 +3707,7 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
if (stat_area.st_mtime < purge_time)
strmake(to_log,
log_info.log_file_name,
- sizeof(log_info.log_file_name));
+ sizeof(log_info.log_file_name) - 1);
else
break;
}
@@ -3656,9 +3870,9 @@ void MYSQL_BIN_LOG::new_file_impl(bool n
*/
/* reopen index binlog file, BUG#34582 */
- if (!open_index_file(index_file_name, 0))
- open(old_name, log_type, new_name_ptr,
- io_cache_type, no_auto_events, max_size, 1);
+ if (!open_index_file(index_file_name, 0, FALSE))
+ open(old_name, log_type, new_name_ptr,
+ io_cache_type, no_auto_events, max_size, 1, FALSE);
my_free(old_name,MYF(0));
end:
@@ -4108,12 +4322,20 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
#if defined(USING_TRANSACTIONS)
/*
Should we write to the binlog cache or to the binlog on disk?
+
Write to the binlog cache if:
- - it is already not empty (meaning we're in a transaction; note that the
- present event could be about a non-transactional table, but still we need
- to write to the binlog cache in that case to handle updates to mixed
- trans/non-trans table types the best possible in binlogging)
- - or if the event asks for it (cache_stmt == TRUE).
+ 1 - a transactional engine/table is updated (stmt_has_updated_trans_table == TRUE);
+ 2 - or the event asks for it (cache_stmt == TRUE);
+ 3 - or the cache is already not empty (meaning we're in a transaction;
+ note that the present event could be about a non-transactional table, but
+ still we need to write to the binlog cache in that case to handle updates
+ to mixed trans/non-trans table types).
+
+ Write to the binlog on disk if only a non-transactional engine is
+ updated and:
+ 1 - the binlog cache is empty or;
+ 2 - --binlog-direct-non-transactional-updates is set and we are about to
+ use the statement format. When using the row format (cache_stmt == TRUE).
*/
if (opt_using_transactions && thd)
{
@@ -4124,8 +4346,9 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
IO_CACHE *trans_log= &trx_data->trans_log;
my_off_t trans_log_pos= my_b_tell(trans_log);
- if (event_info->get_cache_stmt() || trans_log_pos != 0 ||
- stmt_has_updated_trans_table(thd))
+ if (event_info->get_cache_stmt() || stmt_has_updated_trans_table(thd) ||
+ (!thd->variables.binlog_direct_non_trans_update &&
+ trans_log_pos != 0))
{
DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu",
event_info->get_cache_stmt(),
@@ -4305,6 +4528,9 @@ bool general_log_write(THD *thd, enum en
void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
{
+#ifdef HAVE_REPLICATION
+ bool check_purge= false;
+#endif
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
pthread_mutex_lock(&LOCK_log);
if ((flags & RP_FORCE_ROTATE) ||
@@ -4312,16 +4538,24 @@ void MYSQL_BIN_LOG::rotate_and_purge(uin
{
new_file_without_locking();
#ifdef HAVE_REPLICATION
- if (expire_logs_days)
- {
- time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
- if (purge_time >= 0)
- purge_logs_before_date(purge_time);
- }
+ check_purge= true;
#endif
}
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
pthread_mutex_unlock(&LOCK_log);
+
+#ifdef HAVE_REPLICATION
+ /*
+ NOTE: Run purge_logs wo/ holding LOCK_log
+ as it otherwise will deadlock in ndbcluster_binlog_index_purge_file
+ */
+ if (check_purge && expire_logs_days)
+ {
+ time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
+ if (purge_time >= 0)
+ purge_logs_before_date(purge_time);
+ }
+#endif
}
uint MYSQL_BIN_LOG::next_file_id()
@@ -4514,7 +4748,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *
Incident_log_event ev(thd, incident, write_error_msg);
if (lock)
pthread_mutex_lock(&LOCK_log);
- ev.write(&log_file);
+ error= ev.write(&log_file);
if (lock)
{
if (!error && !(error= flush_and_sync()))
@@ -4834,11 +5068,11 @@ bool flush_error_log()
if (opt_error_log)
{
char err_renamed[FN_REFLEN], *end;
- end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
+ end= strmake(err_renamed,log_error_file,FN_REFLEN-5);
strmov(end, "-old");
VOID(pthread_mutex_lock(&LOCK_error_log));
#ifdef __WIN__
- char err_temp[FN_REFLEN+4];
+ char err_temp[FN_REFLEN+5];
/*
On Windows is necessary a temporary file for to rename
the current error file.
@@ -5153,9 +5387,9 @@ int TC_LOG_MMAP::open(const char *opt_na
pg->state=POOL;
pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST);
pthread_cond_init (&pg->cond, 0);
- pg->start=(my_xid *)(data + i*tc_log_page_size);
- pg->end=(my_xid *)(pg->start + tc_log_page_size);
+ pg->ptr= pg->start=(my_xid *)(data + i*tc_log_page_size);
pg->size=pg->free=tc_log_page_size/sizeof(my_xid);
+ pg->end=pg->start + pg->size;
}
pages[0].size=pages[0].free=
(tc_log_page_size-TC_LOG_HEADER_SIZE)/sizeof(my_xid);
@@ -5388,7 +5622,15 @@ int TC_LOG_MMAP::sync()
/* marking 'syncing' slot free */
pthread_mutex_lock(&LOCK_sync);
syncing=0;
- pthread_cond_signal(&active->cond); // wake up a new syncer
+ /*
+ we check the "active" pointer without LOCK_active. Still, it's safe -
+ "active" can change from NULL to not NULL any time, but it
+ will take LOCK_sync before waiting on active->cond. That is, it can never
+ miss a signal.
+ And "active" can change to NULL only after LOCK_sync, so this is safe too.
+ */
+ if (active)
+ pthread_cond_signal(&active->cond); // wake up a new syncer
pthread_mutex_unlock(&LOCK_sync);
return err;
}
@@ -5563,7 +5805,7 @@ int TC_LOG_BINLOG::open(const char *opt_
if (using_heuristic_recover())
{
/* generate a new binlog to mask a corrupted one */
- open(opt_name, LOG_BIN, 0, WRITE_CACHE, 0, max_binlog_size, 0);
+ open(opt_name, LOG_BIN, 0, WRITE_CACHE, 0, max_binlog_size, 0, TRUE);
cleanup();
return 1;
}
@@ -5691,9 +5933,8 @@ int TC_LOG_BINLOG::recover(IO_CACHE *log
Xid_log_event *xev=(Xid_log_event *)ev;
uchar *x= (uchar *) memdup_root(&mem_root, (uchar*) &xev->xid,
sizeof(xev->xid));
- if (! x)
+ if (!x || my_hash_insert(&xids, x))
goto err2;
- my_hash_insert(&xids, x);
}
delete ev;
}
=== modified file 'sql/log.h'
--- a/sql/log.h 2009-06-18 13:52:46 +0000
+++ b/sql/log.h 2009-12-04 14:40:42 +0000
@@ -172,6 +172,10 @@ public:
enum_log_type log_type,
const char *new_name,
enum cache_type io_cache_type_arg);
+ bool init_and_set_log_file_name(const char *log_name,
+ const char *new_name,
+ enum_log_type log_type_arg,
+ enum cache_type io_cache_type_arg);
void init(enum_log_type log_type_arg,
enum cache_type io_cache_type_arg);
void close(uint exiting);
@@ -233,14 +237,15 @@ class MYSQL_BIN_LOG: public TC_LOG, priv
pthread_cond_t update_cond;
ulonglong bytes_written;
IO_CACHE index_file;
+ char index_file_name[FN_REFLEN];
/*
- purge_temp is a temp file used in purge_logs so that the index file
+ purge_file is a temp file used in purge_logs so that the index file
can be updated before deleting files from disk, yielding better crash
recovery. It is created on demand the first time purge_logs is called
and then reused for subsequent calls. It is cleaned up in cleanup().
*/
- IO_CACHE purge_temp;
- char index_file_name[FN_REFLEN];
+ IO_CACHE purge_index_file;
+ char purge_index_file_name[FN_REFLEN];
/*
The max size before rotation (usable only if log_type == LOG_BIN: binary
logs and relay logs).
@@ -349,9 +354,10 @@ public:
const char *new_name,
enum cache_type io_cache_type_arg,
bool no_auto_events_arg, ulong max_size,
- bool null_created);
+ bool null_created,
+ bool need_mutex);
bool open_index_file(const char *index_file_name_arg,
- const char *log_name);
+ const char *log_name, bool need_mutex);
/* Use this to start writing a new log file */
void new_file();
@@ -384,6 +390,16 @@ public:
ulonglong *decrease_log_space);
int purge_logs_before_date(time_t purge_time);
int purge_first_log(Relay_log_info* rli, bool included);
+ int set_purge_index_file_name(const char *base_file_name);
+ int open_purge_index_file(bool destroy);
+ bool is_inited_purge_index_file();
+ int close_purge_index_file();
+ int clean_purge_index_file();
+ int sync_purge_index_file();
+ int register_purge_index_entry(const char* entry);
+ int register_create_index_entry(const char* entry);
+ int purge_index_entry(THD *thd, ulonglong *decrease_log_space,
+ bool need_mutex);
bool reset_logs(THD* thd);
void close(uint exiting);
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2009-12-03 11:34:11 +0000
+++ b/sql/log_event.cc 2010-03-04 08:03:07 +0000
@@ -2294,10 +2294,22 @@ bool Query_log_event::write(IO_CACHE* fi
int8store(start, table_map_for_update);
start+= 8;
}
+ if (master_data_written != 0)
+ {
+ /*
+ Q_MASTER_DATA_WRITTEN_CODE only exists in relay logs where the master
+ has binlog_version<4 and the slave has binlog_version=4. See comment
+ for master_data_written in log_event.h for details.
+ */
+ *start++= Q_MASTER_DATA_WRITTEN_CODE;
+ int4store(start, master_data_written);
+ start+= 4;
+ }
+
/*
NOTE: When adding new status vars, please don't forget to update
- the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update function
- code_name in this file.
+ the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
+ code_name() in this file.
Here there could be code like
if (command-line-option-which-says-"log_this_variable" && inited)
@@ -2373,7 +2385,8 @@ Query_log_event::Query_log_event(THD* th
auto_increment_offset(thd_arg->variables.auto_increment_offset),
lc_time_names_number(thd_arg->variables.lc_time_names->number),
charset_database_number(0),
- table_map_for_update((ulonglong)thd_arg->table_map_for_update)
+ table_map_for_update((ulonglong)thd_arg->table_map_for_update),
+ master_data_written(0)
{
time_t end_time;
@@ -2497,6 +2510,7 @@ code_name(int code)
case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
+ case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
}
sprintf(buf, "CODE#%d", code);
return buf;
@@ -2534,7 +2548,7 @@ Query_log_event::Query_log_event(const c
flags2_inited(0), sql_mode_inited(0), charset_inited(0),
auto_increment_increment(1), auto_increment_offset(1),
time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
- table_map_for_update(0)
+ table_map_for_update(0), master_data_written(0)
{
ulong data_len;
uint32 tmp;
@@ -2590,6 +2604,18 @@ Query_log_event::Query_log_event(const c
DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
(uint) status_vars_len));
tmp-= 2;
+ }
+ else
+ {
+ /*
+ server version < 5.0 / binlog_version < 4 master's event is
+ relay-logged with storing the original size of the event in
+ Q_MASTER_DATA_WRITTEN_CODE status variable.
+ The size is to be restored at reading Q_MASTER_DATA_WRITTEN_CODE-marked
+ event from the relay log.
+ */
+ DBUG_ASSERT(description_event->binlog_version < 4);
+ master_data_written= data_written;
}
/*
We have parsed everything we know in the post header for QUERY_EVENT,
@@ -2681,6 +2707,11 @@ Query_log_event::Query_log_event(const c
table_map_for_update= uint8korr(pos);
pos+= 8;
break;
+ case Q_MASTER_DATA_WRITTEN_CODE:
+ CHECK_SPACE(pos, end, 4);
+ data_written= master_data_written= uint4korr(pos);
+ pos+= 4;
+ break;
default:
/* That's why you must write status vars in growing order of code */
DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
@@ -3170,7 +3201,18 @@ START SLAVE; . Query: '%s'", expected_er
compare_errors:
- /*
+ /*
+ In the slave thread, we may sometimes execute some DROP / * 40005
+ TEMPORARY * / TABLE that come from parts of binlogs (likely if we
+ use RESET SLAVE or CHANGE MASTER TO), while the temporary table
+ has already been dropped. To ignore such irrelevant "table does
+ not exist errors", we silently clear the error if TEMPORARY was used.
+ */
+ if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary &&
+ thd->is_error() && thd->main_da.sql_errno() == ER_BAD_TABLE_ERROR &&
+ !expected_error)
+ thd->main_da.reset_diagnostics_area();
+ /*
If we expected a non-zero error code, and we don't get the same error
code, and it should be ignored or is related to a concurrency issue.
*/
@@ -4005,6 +4047,7 @@ uint Load_log_event::get_query_buffer_le
return
5 + db_len + 3 + // "use DB; "
18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
+ 11 + // "CONCURRENT "
7 + // LOCAL
9 + // " REPLACE or IGNORE "
13 + table_name_len*2 + // "INTO TABLE `table`"
@@ -4032,6 +4075,9 @@ void Load_log_event::print_query(bool ne
pos= strmov(pos, "LOAD DATA ");
+ if (thd->lex->lock_option == TL_WRITE_CONCURRENT_INSERT)
+ pos= strmov(pos, "CONCURRENT ");
+
if (fn_start)
*fn_start= pos;
@@ -5851,7 +5897,7 @@ Slave_log_event::Slave_log_event(const c
int Slave_log_event::do_apply_event(Relay_log_info const *rli)
{
if (mysql_bin_log.is_open())
- mysql_bin_log.write(this);
+ return mysql_bin_log.write(this);
return 0;
}
#endif /* !MYSQL_CLIENT */
@@ -7598,7 +7644,7 @@ static int rows_event_stmt_cleanup(Relay
(assume the last master's transaction is ignored by the slave because of
replicate-ignore rules).
*/
- thd->binlog_flush_pending_rows_event(true);
+ error= thd->binlog_flush_pending_rows_event(true);
/*
If this event is not in a transaction, the call below will, if some
@@ -7609,7 +7655,7 @@ static int rows_event_stmt_cleanup(Relay
are involved, commit the transaction and flush the pending event to the
binlog.
*/
- error= ha_autocommit_or_rollback(thd, 0);
+ error|= ha_autocommit_or_rollback(thd, error);
/*
Now what if this is not a transactional engine? we still need to
@@ -7913,10 +7959,10 @@ Table_map_log_event::Table_map_log_event
plus one or three bytes (see pack.c:net_store_length) for number of
elements in the field metadata array.
*/
- if (m_field_metadata_size > 255)
- m_data_size+= m_field_metadata_size + 3;
- else
+ if (m_field_metadata_size < 251)
m_data_size+= m_field_metadata_size + 1;
+ else
+ m_data_size+= m_field_metadata_size + 3;
bzero(m_null_bits, num_null_bytes);
for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
@@ -8453,13 +8499,17 @@ Rows_log_event::write_row(const Relay_lo
auto_afree_ptr<char> key(NULL);
/* fill table->record[0] with default values */
-
+ bool abort_on_warnings= (rli->sql_thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
if ((error= prepare_record(table, m_width,
- TRUE /* check if columns have def. values */)))
+ table->file->ht->db_type != DB_TYPE_NDBCLUSTER,
+ abort_on_warnings, m_curr_row == m_rows_buf)))
DBUG_RETURN(error);
/* unpack row into table->record[0] */
- error= unpack_current_row(rli); // TODO: how to handle errors?
+ if ((error= unpack_current_row(rli, abort_on_warnings)))
+ DBUG_RETURN(error);
+
if (m_curr_row == m_rows_buf)
{
/* this is the first row to be inserted, we estimate the rows with
@@ -9256,8 +9306,12 @@ Update_rows_log_event::do_exec_row(const
store_record(m_table,record[1]);
+ bool abort_on_warnings= (rli->sql_thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
m_curr_row= m_curr_row_end;
- error= unpack_current_row(rli); // this also updates m_curr_row_end
+ /* this also updates m_curr_row_end */
+ if ((error= unpack_current_row(rli, abort_on_warnings)))
+ return error;
/*
Now we have the right row to update. The old row (the one we're
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2009-12-03 11:19:05 +0000
+++ b/sql/log_event.h 2010-03-04 08:03:07 +0000
@@ -263,7 +263,8 @@ struct sql_ex_info
1 + 1 + 255 /* type, length, time_zone */ + \
1 + 2 /* type, lc_time_names_number */ + \
1 + 2 /* type, charset_database_number */ + \
- 1 + 8 /* type, table_map_for_update */)
+ 1 + 8 /* type, table_map_for_update */ + \
+ 1 + 4 /* type, master_data_written */)
#define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \
LOG_EVENT_HEADER_LEN + /* write_header */ \
QUERY_HEADER_LEN + /* write_data */ \
@@ -330,6 +331,10 @@ struct sql_ex_info
#define Q_TABLE_MAP_FOR_UPDATE_CODE 9
+#define Q_MASTER_DATA_WRITTEN_CODE 10
+
+/* Intvar event post-header */
+
/* Intvar event data */
#define I_TYPE_OFFSET 0
#define I_VAL_OFFSET 1
@@ -1620,6 +1625,16 @@ public:
statement, for other query statements, this will be zero.
*/
ulonglong table_map_for_update;
+ /*
+ Holds the original length of a Query_log_event that comes from a
+ master of version < 5.0 (i.e., binlog_version < 4). When the IO
+ thread writes the relay log, it augments the Query_log_event with a
+ Q_MASTER_DATA_WRITTEN_CODE status_var that holds the original event
+ length. This field is initialized to non-zero in the SQL thread when
+ it reads this augmented event. SQL thread does not write
+ Q_MASTER_DATA_WRITTEN_CODE to the slave's server binlog.
+ */
+ uint32 master_data_written;
#ifndef MYSQL_CLIENT
@@ -1766,7 +1781,7 @@ private:
@verbatim
(1) USE db;
- (2) LOAD DATA [LOCAL] INFILE 'file_name'
+ (2) LOAD DATA [CONCURRENT] [LOCAL] INFILE 'file_name'
(3) [REPLACE | IGNORE]
(4) INTO TABLE 'table_name'
(5) [FIELDS
@@ -3541,12 +3556,16 @@ protected:
int write_row(const Relay_log_info *const, const bool);
// Unpack the current row into m_table->record[0]
- int unpack_current_row(const Relay_log_info *const rli)
+ int unpack_current_row(const Relay_log_info *const rli,
+ const bool abort_on_warning= TRUE)
{
DBUG_ASSERT(m_table);
+
+ bool first_row= (m_curr_row == m_rows_buf);
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
- &m_curr_row_end, &m_master_reclength);
+ &m_curr_row_end, &m_master_reclength,
+ abort_on_warning, first_row);
if (m_curr_row_end > m_rows_end)
my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
=== modified file 'sql/log_event_old.cc'
--- a/sql/log_event_old.cc 2009-12-03 11:19:05 +0000
+++ b/sql/log_event_old.cc 2010-03-04 08:03:07 +0000
@@ -1541,7 +1541,15 @@ int Old_rows_log_event::do_apply_event(R
NOTE: For this new scheme there should be no pending event:
need to add code to assert that is the case.
*/
- thd->binlog_flush_pending_rows_event(false);
+ error= thd->binlog_flush_pending_rows_event(false);
+ if (error)
+ {
+ rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER(ER_SLAVE_FATAL_ERROR),
+ "call to binlog_flush_pending_rows_event() failed");
+ thd->is_slave_error= 1;
+ DBUG_RETURN(error);
+ }
TABLE_LIST *tables= rli->tables_to_lock;
close_tables_for_reopen(thd, &tables);
@@ -1831,7 +1839,7 @@ int Old_rows_log_event::do_apply_event(R
(assume the last master's transaction is ignored by the slave because of
replicate-ignore rules).
*/
- thd->binlog_flush_pending_rows_event(true);
+ int binlog_error= thd->binlog_flush_pending_rows_event(true);
/*
If this event is not in a transaction, the call below will, if some
@@ -1842,12 +1850,13 @@ int Old_rows_log_event::do_apply_event(R
are involved, commit the transaction and flush the pending event to the
binlog.
*/
- if ((error= ha_autocommit_or_rollback(thd, 0)))
+ if ((error= ha_autocommit_or_rollback(thd, binlog_error)))
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
get_type_str(), m_table->s->db.str,
m_table->s->table_name.str);
+ error|= binlog_error;
/*
Now what if this is not a transactional engine? we still need to
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2009-12-03 11:19:05 +0000
+++ b/sql/mysql_priv.h 2010-03-04 08:03:07 +0000
@@ -112,6 +112,10 @@ char* query_table_status(THD *thd,const
#define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1))
#define all_bits_set(A,B) ((A) & (B) != (B))
+/* Version numbers for deprecation messages */
+#define VER_BETONY "5.5"
+#define VER_CELOSIA "5.6"
+
#define WARN_DEPRECATED(Thd,Ver,Old,New) \
do { \
DBUG_ASSERT(strncmp(Ver, MYSQL_SERVER_VERSION, sizeof(Ver)-1) > 0); \
@@ -121,7 +125,7 @@ char* query_table_status(THD *thd,const
(Old), (Ver), (New)); \
else \
sql_print_warning("The syntax '%s' is deprecated and will be removed " \
- "in MySQL %s. Please use %s instead.", (Old), (Ver), (New)); \
+ "in a future release. Please use %s instead.", (Old), (New)); \
} while(0)
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info;
@@ -1045,8 +1049,8 @@ check_and_unset_inject_value(int value)
#endif
-void write_bin_log(THD *thd, bool clear_error,
- char const *query, ulong query_length);
+int write_bin_log(THD *thd, bool clear_error,
+ char const *query, ulong query_length);
/* sql_connect.cc */
int check_user(THD *thd, enum enum_server_command command,
@@ -1434,8 +1438,18 @@ bool get_schema_tables_result(JOIN *join
enum enum_schema_table_state executed_place);
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table);
-#define is_schema_db(X) \
- !my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, (X))
+inline bool is_schema_db(const char *name, size_t len)
+{
+ return (INFORMATION_SCHEMA_NAME.length == len &&
+ !my_strcasecmp(system_charset_info,
+ INFORMATION_SCHEMA_NAME.str, name));
+}
+
+inline bool is_schema_db(const char *name)
+{
+ return !my_strcasecmp(system_charset_info,
+ INFORMATION_SCHEMA_NAME.str, name);
+}
/* sql_prepare.cc */
@@ -1636,7 +1650,7 @@ uint prep_alter_part_table(THD *thd, TAB
#define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002
#define RTFC_CHECK_KILLED_FLAG 0x0004
bool remove_table_from_cache(THD *thd, const char *db, const char *table,
- uint flags);
+ uint flags, my_bool deleting);
#define NORMAL_PART_NAME 0
#define TEMP_PART_NAME 1
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-12-04 15:12:22 +0000
+++ b/sql/mysqld.cc 2010-03-30 12:36:49 +0000
@@ -598,6 +598,7 @@ char *mysqld_unix_port, *opt_mysql_tmpdi
const char **errmesg; /**< Error messages */
const char *myisam_recover_options_str="OFF";
const char *myisam_stats_method_str="nulls_unequal";
+const char *opt_thread_handling= thread_handling_typelib.type_names[0];
/** name of reference on left espression in rewritten IN subquery */
const char *in_left_expr_name= "<left expr>";
@@ -1173,11 +1174,14 @@ static void __cdecl kill_server(int sig_
/*
Send event to smem_event_connect_request for aborting
*/
- if (!SetEvent(smem_event_connect_request))
+ if (opt_enable_shared_memory)
{
- DBUG_PRINT("error",
- ("Got error: %ld from SetEvent of smem_event_connect_request",
- GetLastError()));
+ if (!SetEvent(smem_event_connect_request))
+ {
+ DBUG_PRINT("error",
+ ("Got error: %ld from SetEvent of smem_event_connect_request",
+ GetLastError()));
+ }
}
#endif
@@ -1318,7 +1322,6 @@ void clean_up(bool print_message)
lex_free(); /* Free some memory */
item_create_cleanup();
set_var_free();
- free_charsets();
if (!opt_noacl)
{
#ifdef HAVE_DLOPEN
@@ -2029,10 +2032,10 @@ bool one_thread_per_connection_end(THD *
/* It's safe to broadcast outside a lock (COND... is not deleted here) */
DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
+ DBUG_LEAVE; // Must match DBUG_ENTER()
my_thread_end();
(void) pthread_cond_broadcast(&COND_thread_count);
- DBUG_LEAVE; // Must match DBUG_ENTER()
pthread_exit(0);
return 0; // Avoid compiler warnings
}
@@ -2704,7 +2707,7 @@ static void init_signals(void)
{
/* Change limits so that we will get a core file */
STRUCT_RLIMIT rl;
- rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
+ rl.rlim_cur = rl.rlim_max = (rlim_t) RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals");
}
@@ -4005,6 +4008,27 @@ server.");
if (opt_bin_log)
{
+ /* Reports an error and aborts, if the --log-bin's path
+ is a directory.*/
+ if (opt_bin_logname &&
+ opt_bin_logname[strlen(opt_bin_logname) - 1] == FN_LIBCHAR)
+ {
+ sql_print_error("Path '%s' is a directory name, please specify \
+a file name for --log-bin option", opt_bin_logname);
+ unireg_abort(1);
+ }
+
+ /* Reports an error and aborts, if the --log-bin-index's path
+ is a directory.*/
+ if (opt_binlog_index_name &&
+ opt_binlog_index_name[strlen(opt_binlog_index_name) - 1]
+ == FN_LIBCHAR)
+ {
+ sql_print_error("Path '%s' is a directory name, please specify \
+a file name for --log-bin-index option", opt_binlog_index_name);
+ unireg_abort(1);
+ }
+
char buf[FN_REFLEN];
const char *ln;
ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
@@ -4028,7 +4052,7 @@ server.");
my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
opt_bin_logname=my_strdup(buf, MYF(0));
}
- if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln))
+ if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
{
unireg_abort(1);
}
@@ -4200,7 +4224,7 @@ server.");
}
if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
- WRITE_CACHE, 0, max_binlog_size, 0))
+ WRITE_CACHE, 0, max_binlog_size, 0, TRUE))
unireg_abort(1);
#ifdef HAVE_REPLICATION
@@ -5355,12 +5379,16 @@ pthread_handler_t handle_connections_soc
pthread_handler_t handle_connections_namedpipes(void *arg)
{
HANDLE hConnectedPipe;
- OVERLAPPED connectOverlapped = {0};
+ OVERLAPPED connectOverlapped= {0};
THD *thd;
my_thread_init();
DBUG_ENTER("handle_connections_namedpipes");
- connectOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
+ connectOverlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (!connectOverlapped.hEvent)
+ {
+ sql_print_error("Can't create event, last error=%u", GetLastError());
+ unireg_abort(1);
+ }
DBUG_PRINT("general",("Waiting for named pipe connections."));
while (!abort_loop)
{
@@ -5383,7 +5411,8 @@ pthread_handler_t handle_connections_nam
{
CloseHandle(hPipe);
if ((hPipe= CreateNamedPipe(pipe_name,
- PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
+ PIPE_ACCESS_DUPLEX |
+ FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
@@ -5403,7 +5432,8 @@ pthread_handler_t handle_connections_nam
hConnectedPipe = hPipe;
/* create new pipe for new connection */
if ((hPipe = CreateNamedPipe(pipe_name,
- PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
+ PIPE_ACCESS_DUPLEX |
+ FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
@@ -5730,6 +5760,7 @@ enum options_mysqld
OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER,
OPT_ABORT_SLAVE_EVENT_COUNT,
OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
+ OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD,
OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING,
OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS,
OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
@@ -5779,6 +5810,7 @@ enum options_mysqld
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
+ OPT_MYISAM_MMAP_SIZE,
OPT_MYISAM_STATS_METHOD,
OPT_PAGECACHE_BUFFER_SIZE,
@@ -5814,6 +5846,7 @@ enum options_mysqld
OPT_EXPIRE_LOGS_DAYS,
OPT_GROUP_CONCAT_MAX_LEN,
OPT_DEFAULT_COLLATION,
+ OPT_DEFAULT_COLLATION_OLD,
OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
OPT_CHARACTER_SET_FILESYSTEM,
OPT_LC_TIME_NAMES,
@@ -5840,6 +5873,9 @@ enum options_mysqld
OPT_TABLE_LOCK_WAIT_TIMEOUT,
OPT_PLUGIN_LOAD,
OPT_PLUGIN_DIR,
+ OPT_SYMBOLIC_LINKS,
+ OPT_WARNINGS,
+ OPT_RECORD_BUFFER_OLD,
OPT_LOG_OUTPUT,
OPT_PORT_OPEN_TIMEOUT,
OPT_PROFILING,
@@ -5866,7 +5902,9 @@ enum options_mysqld
OPT_LOG_SLOW_FILTER,
OPT_GENERAL_LOG_FILE,
OPT_SLOW_QUERY_LOG_FILE,
- OPT_IGNORE_BUILTIN_INNODB
+ OPT_IGNORE_BUILTIN_INNODB,
+ OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
+ OPT_DEFAULT_CHARACTER_SET_OLD
};
@@ -6019,10 +6057,11 @@ struct my_option my_long_options[] =
{"debug-flush", OPT_DEBUG_FLUSH, "Default debug log with flush after write",
(uchar**) 0, (uchar**) 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).",
+ {"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD,
+ "Set the default character set (deprecated option, use --character-set-server instead).",
(uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- {"default-collation", OPT_DEFAULT_COLLATION, "Set the default collation (deprecated option, use --collation-server instead).",
+ {"default-collation", OPT_DEFAULT_COLLATION_OLD, "Set the default collation (deprecated option, use --collation-server instead).",
(uchar**) &default_collation_name, (uchar**) &default_collation_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"default-storage-engine", OPT_STORAGE_ENGINE,
@@ -6121,7 +6160,8 @@ Disable with --skip-large-pages.",
#endif
{"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master",
+ {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed by a slave server \
+each time the SQL thread starts.",
(uchar**) &opt_init_slave, (uchar**) &opt_init_slave, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"language", 'L',
@@ -6161,7 +6201,7 @@ Disable with --skip-large-pages.",
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,
+ {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD,
"(deprecated) Use log-bin-trust-function-creators.",
(uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -6714,7 +6754,7 @@ log and this option does nothing anymore
{"transaction-isolation", OPT_TX_ISOLATION,
"Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
0, 0, 0, 0, 0},
- {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; use --symbolic-links instead.",
+ {"use-symbolic-links", OPT_SYMBOLIC_LINKS, "Enable symbolic link support. Deprecated option; use --symbolic-links instead.",
(uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
IF_VALGRIND(0,1), 0, 0, 0, 0, 0},
{"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
@@ -6724,7 +6764,7 @@ log and this option does nothing anymore
0, 0},
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
- {"warnings", 'W', "Deprecated; use --log-warnings instead.",
+ {"warnings", OPT_WARNINGS, "Deprecated; use --log-warnings instead.",
(uchar**) &global_system_variables.log_warnings,
(uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG,
1, 0, (longlong) ULONG_MAX, 0, 0, 0},
@@ -7002,6 +7042,10 @@ The minimum value for this variable is 4
(uchar**) &max_system_variables.myisam_max_sort_file_size, 0,
GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE,
0, 1024*1024, 0},
+ {"myisam_mmap_size", OPT_MYISAM_MMAP_SIZE,
+ "Can be used to restrict the total memory used for memory mmaping of myisam files",
+ (uchar**) &myisam_mmap_size, (uchar**) &myisam_mmap_size, 0,
+ GET_ULL, REQUIRED_ARG, SIZE_T_MAX, MEMMAP_EXTRA_MARGIN, SIZE_T_MAX, 0, 1, 0},
{"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS,
"Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.",
(uchar**) &global_system_variables.myisam_repair_threads,
@@ -7149,8 +7193,8 @@ The minimum value for this variable is 4
(uchar**) &max_system_variables.read_rnd_buff_size, 0,
GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
- {"record_buffer", OPT_RECORD_BUFFER,
- "Alias for read_buffer_size",
+ {"record_buffer", OPT_RECORD_BUFFER_OLD,
+ "Alias for read_buffer_size. This variable is deprecated and will be removed in a future release.",
(uchar**) &global_system_variables.read_buff_size,
(uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
@@ -7242,10 +7286,10 @@ The minimum value for this variable is 4
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"tmp_table_size", OPT_TMP_TABLE_SIZE,
"If an internal in-memory temporary table exceeds this size, MySQL will"
- " automatically convert it to an on-disk MyISAM table.",
+ " automatically convert it to an on-disk MyISAM/Maria table.",
(uchar**) &global_system_variables.tmp_table_size,
(uchar**) &max_system_variables.tmp_table_size, 0, GET_ULL,
- REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
+ REQUIRED_ARG, 16*1024*1024L, 0, MAX_MEM_TABLE_SIZE, 0, 1, 0},
{"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
"Allocation block size for transactions to be stored in binary log",
(uchar**) &global_system_variables.trans_alloc_block_size,
@@ -7260,7 +7304,8 @@ The minimum value for this variable is 4
1024, 0},
{"thread_handling", OPT_THREAD_HANDLING,
"Define threads usage for handling queries: "
- "one-thread-per-connection or no-threads", 0, 0,
+ "one-thread-per-connection or no-threads",
+ (uchar**) &opt_thread_handling, (uchar**) &opt_thread_handling,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT,
"1 = YES = Don't issue an error message (warning only) if a VIEW without presence of a key of the underlying table is used in queries with a LIMIT clause for updating. 0 = NO = Prohibit update of a VIEW, which does not contain a key of the underlying table and the query uses a LIMIT clause (usually get from GUI tools).",
@@ -7273,6 +7318,10 @@ The minimum value for this variable is 4
(uchar**) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
0, 1, 0},
+ {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
+ "Causes updates to non-transactional engines using statement format to be written directly to binary log. Before using this option make sure that there are no dependencies between transactional and non-transactional tables such as in the statement INSERT INTO t_myisam SELECT * FROM t_innodb; otherwise, slaves may diverge from the master.",
+ (uchar**) &global_system_variables.binlog_direct_non_trans_update, (uchar**) &max_system_variables.binlog_direct_non_trans_update, 0, GET_BOOL, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -7746,6 +7795,7 @@ SHOW_VAR status_vars[]= {
{"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_FUNC},
{"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC},
#endif /* HAVE_OPENSSL */
+ {"Syncs", (char*) &my_sync_count, SHOW_LONG_NOFLUSH},
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
#ifdef HAVE_MMAP
@@ -7932,7 +7982,13 @@ static int mysql_init_variables(void)
refresh_version= 1L; /* Increments on each reload */
global_query_id= thread_id= 1L;
strmov(server_version, MYSQL_SERVER_VERSION);
- myisam_recover_options_str= sql_mode_str= "OFF";
+ sql_mode_str= "";
+
+ /* By default, auto-repair MyISAM tables after crash */
+ myisam_recover_options_str= "DEFAULT";
+ myisam_recover_options= HA_RECOVER_DEFAULT;
+ ha_open_options|= HA_OPEN_ABORT_IF_CRASHED;
+
myisam_stats_method_str= "nulls_unequal";
my_bind_addr = htonl(INADDR_ANY);
threads.empty();
@@ -8154,6 +8210,9 @@ mysqld_get_one_option(int optid,
opt_endinfo=1; /* unireg: memory allocation */
break;
#endif
+ case '0':
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-long-format", "--log-short-format");
+ break;
case 'a':
global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI);
global_system_variables.tx_isolation= ISO_SERIALIZABLE;
@@ -8161,6 +8220,11 @@ mysqld_get_one_option(int optid,
case 'b':
strmake(mysql_home,argument,sizeof(mysql_home)-1);
break;
+ case OPT_DEFAULT_CHARACTER_SET_OLD: // --default-character-set
+ WARN_DEPRECATED(NULL, VER_CELOSIA,
+ "--default-character-set",
+ "--character-set-server");
+ /* Fall through */
case 'C':
if (default_collation_name == compiled_default_collation_name)
default_collation_name= 0;
@@ -8184,6 +8248,9 @@ mysqld_get_one_option(int optid,
case 'L':
strmake(language, argument, sizeof(language)-1);
break;
+ case 'O':
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--set-variable", "--variable-name=value");
+ break;
#ifdef HAVE_REPLICATION
case OPT_SLAVE_SKIP_ERRORS:
init_slave_skip_errors(argument);
@@ -8206,6 +8273,9 @@ mysqld_get_one_option(int optid,
print_version();
exit(0);
#endif /*EMBEDDED_LIBRARY*/
+ case OPT_WARNINGS:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--warnings", "--log-warnings");
+ /* Note: fall-through to 'W' */
case 'W':
if (!argument)
global_system_variables.log_warnings++;
@@ -8218,6 +8288,18 @@ mysqld_get_one_option(int optid,
test_flags= argument ? (uint) atoi(argument) : 0;
opt_endinfo=1;
break;
+ case (int) OPT_DEFAULT_COLLATION_OLD:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--default-collation", "--collation-server");
+ break;
+ case (int) OPT_SAFE_SHOW_DB:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--safe-show-database", "GRANT SHOW DATABASES");
+ break;
+ case (int) OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-bin-trust-routine-creators", "--log-bin-trust-function-creators");
+ break;
+ case (int) OPT_ENABLE_LOCK:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--enable-locking", "--external-locking");
+ break;
case (int) OPT_BIG_TABLES:
thd_startup_options|=OPTION_BIG_TABLES;
break;
@@ -8228,6 +8310,7 @@ mysqld_get_one_option(int optid,
opt_myisam_log=1;
break;
case (int) OPT_UPDATE_LOG:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-update", "--log-bin");
opt_update_log=1;
break;
case (int) OPT_BIN_LOG:
@@ -8240,6 +8323,8 @@ mysqld_get_one_option(int optid,
case (int) OPT_INIT_RPL_ROLE:
{
int role;
+ LINT_INIT(role);
+
if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role))
{
rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
@@ -8295,6 +8380,8 @@ mysqld_get_one_option(int optid,
case OPT_BINLOG_FORMAT:
{
int id;
+ LINT_INIT(id);
+
if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id))
{
global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
@@ -8399,8 +8486,18 @@ mysqld_get_one_option(int optid,
"give threads different priorities.");
break;
case (int) OPT_SKIP_LOCK:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-locking", "--skip-external-locking");
opt_external_locking=0;
break;
+ case (int) OPT_SQL_BIN_UPDATE_SAME:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--sql-bin-update-same", "the binary log");
+ break;
+ case (int) OPT_RECORD_BUFFER_OLD:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "record_buffer", "read_buffer_size");
+ break;
+ case (int) OPT_SYMBOLIC_LINKS:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--use-symbolic-links", "--symbolic-links");
+ break;
case (int) OPT_SKIP_HOST_CACHE:
opt_specialflag|= SPECIAL_NO_HOST_CACHE;
break;
@@ -8426,6 +8523,7 @@ mysqld_get_one_option(int optid,
test_flags|=TEST_NO_STACKTRACE;
break;
case (int) OPT_SKIP_SYMLINKS:
+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-symlink", "--skip-symbolic-links");
my_use_symdir=0;
break;
case (int) OPT_BIND_ADDRESS:
@@ -8520,6 +8618,9 @@ mysqld_get_one_option(int optid,
server_id_supplied = 1;
break;
case OPT_DELAY_KEY_WRITE_ALL:
+ WARN_DEPRECATED(NULL, VER_CELOSIA,
+ "--delay-key-write-for-all-tables",
+ "--delay-key-write=ALL");
if (argument != disabled_my_option)
argument= (char*) "ALL";
/* Fall through */
@@ -8531,6 +8632,8 @@ mysqld_get_one_option(int optid,
else
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type))
delay_key_write_options= (uint) type-1;
}
@@ -8542,6 +8645,8 @@ mysqld_get_one_option(int optid,
case OPT_TX_ISOLATION:
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type))
global_system_variables.tx_isolation= (type-1);
break;
@@ -8586,26 +8691,31 @@ mysqld_get_one_option(int optid,
#endif
case OPT_MYISAM_RECOVER:
{
- if (!argument)
- {
- myisam_recover_options= HA_RECOVER_DEFAULT;
- myisam_recover_options_str= myisam_recover_typelib.type_names[0];
- }
- else if (!argument[0])
+ if (argument && (!argument[0] ||
+ my_strcasecmp(system_charset_info, argument, "OFF") == 0))
{
myisam_recover_options= HA_RECOVER_NONE;
myisam_recover_options_str= "OFF";
+ ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
}
else
{
- myisam_recover_options_str=argument;
- myisam_recover_options=
- find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
- &error);
- if (error)
- return 1;
+ if (!argument)
+ {
+ myisam_recover_options= HA_RECOVER_DEFAULT;
+ myisam_recover_options_str= myisam_recover_typelib.type_names[0];
+ }
+ else
+ {
+ myisam_recover_options_str=argument;
+ myisam_recover_options=
+ find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
+ &error);
+ if (error)
+ return 1;
+ }
+ ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
}
- ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
break;
}
case OPT_CONCURRENT_INSERT:
@@ -8624,6 +8734,7 @@ mysqld_get_one_option(int optid,
ulong method_conv;
int method;
LINT_INIT(method_conv);
+ LINT_INIT(method);
myisam_stats_method_str= argument;
if (!find_opt_type(argument, &myisam_stats_method_typelib,
@@ -8680,14 +8791,16 @@ mysqld_get_one_option(int optid,
break;
}
case OPT_ONE_THREAD:
- global_system_variables.thread_handling=
- SCHEDULER_ONE_THREAD_PER_CONNECTION;
+ global_system_variables.thread_handling= SCHEDULER_NO_THREADS;
+ opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];
break;
case OPT_THREAD_HANDLING:
{
int id;
+ LINT_INIT(id);
if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id))
global_system_variables.thread_handling= id - 1;
+ opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];
break;
}
case OPT_FT_BOOLEAN_SYNTAX:
@@ -8974,14 +9087,8 @@ static int fix_paths(void)
pos[0]= FN_LIBCHAR;
pos[1]= 0;
}
- convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
- my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
- mysql_unpacked_real_data_home_len= strlen(mysql_unpacked_real_data_home);
- if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
- --mysql_unpacked_real_data_home_len;
-
-
convert_dirname(language,language,NullS);
+ convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
(void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
@@ -8989,6 +9096,12 @@ static int fix_paths(void)
get_relative_path(PLUGINDIR), mysql_home);
opt_plugin_dir_ptr= opt_plugin_dir;
+ my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
+ mysql_unpacked_real_data_home_len=
+ (int) strlen(mysql_unpacked_real_data_home);
+ if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
+ --mysql_unpacked_real_data_home_len;
+
char *sharedir=get_relative_path(SHAREDIR);
if (test_if_hard_path(sharedir))
strmake(buff,sharedir,sizeof(buff)-1); /* purecov: tested */
@@ -9019,8 +9132,8 @@ static int fix_paths(void)
/*
Convert the secure-file-priv option to system format, allowing
a quick strcmp to check if read or write is in an allowed dir
- */
- if (opt_secure_file_priv)
+ */
+ if (opt_secure_file_priv && opt_secure_file_priv[0])
{
convert_dirname(buff, opt_secure_file_priv, NullS);
my_free(opt_secure_file_priv, MYF(0));
=== modified file 'sql/net_serv.cc'
--- a/sql/net_serv.cc 2009-09-07 20:50:10 +0000
+++ b/sql/net_serv.cc 2010-03-29 19:07:45 +0000
@@ -130,6 +130,7 @@ my_bool my_net_init(NET *net, Vio* vio)
net->last_error[0]=0;
net->compress=0; net->reading_or_writing=0;
net->where_b = net->remain_in_buf=0;
+ net->net_skip_rest_factor= 0;
net->last_errno=0;
#ifdef USE_QUERY_CACHE
query_cache_init_query(net);
@@ -219,7 +220,7 @@ my_bool net_realloc(NET *net, size_t len
-1 Don't know if data is ready or not
*/
-#if !defined(EMBEDDED_LIBRARY)
+#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
static int net_data_is_ready(my_socket sd)
{
@@ -278,15 +279,20 @@ static int net_data_is_ready(my_socket s
@param clear_buffer if <> 0, then clear all data from comm buff
*/
-void net_clear(NET *net, my_bool clear_buffer)
+void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
-#if !defined(EMBEDDED_LIBRARY)
+#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
size_t count;
int ready;
#endif
DBUG_ENTER("net_clear");
-#if !defined(EMBEDDED_LIBRARY)
+/*
+ We don't do a clear in case of DBUG_OFF to catch bugs
+ in the protocol handling
+*/
+
+#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
if (clear_buffer)
{
while ((ready= net_data_is_ready(net->vio->sd)) > 0)
@@ -738,6 +744,7 @@ static my_bool net_safe_read(NET *net, u
static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
ALARM *alarm_buff)
{
+ longlong limit= net->max_packet_size*net->net_skip_rest_factor;
uint32 old=remain;
DBUG_ENTER("my_net_skip_rest");
DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain));
@@ -761,11 +768,15 @@ static my_bool my_net_skip_rest(NET *net
DBUG_RETURN(1);
update_statistics(thd_increment_bytes_received(length));
remain -= (uint32) length;
+ limit-= length;
+ if (limit < 0)
+ DBUG_RETURN(1);
}
if (old != MAX_PACKET_LENGTH)
break;
if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed))
DBUG_RETURN(1);
+ limit-= NET_HEADER_SIZE;
old=remain= uint3korr(net->buff);
net->pkt_nr++;
}
=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc 2009-12-03 11:19:05 +0000
+++ b/sql/opt_range.cc 2010-01-15 15:27:55 +0000
@@ -446,9 +446,9 @@ public:
range_key, *range_key_flag);
*range_key_flag|= key_tree->min_flag;
if (key_tree->next_key_part &&
+ key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
key_tree->next_key_part->part == key_tree->part+1 &&
- !(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
- key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
+ !(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)))
res+= key_tree->next_key_part->store_min_key(key, range_key,
range_key_flag);
return res;
@@ -462,9 +462,9 @@ public:
range_key, *range_key_flag);
(*range_key_flag)|= key_tree->max_flag;
if (key_tree->next_key_part &&
+ key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
key_tree->next_key_part->part == key_tree->part+1 &&
- !(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
- key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
+ !(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
res+= key_tree->next_key_part->store_max_key(key, range_key,
range_key_flag);
return res;
@@ -1700,6 +1700,7 @@ SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM
tmp->prev= *next_arg; // Link into next/prev chain
(*next_arg)->next=tmp;
(*next_arg)= tmp;
+ tmp->part= this->part;
}
else
{
@@ -6672,6 +6673,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *
else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
{ // Found tmp.max < key2.min
SEL_ARG *next=tmp->next;
+ /* key1 on the left of key2 non-overlapping */
if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{
// Join near ranges like tmp.max < 0 and key2.min >= 0
@@ -6700,6 +6702,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *
int tmp_cmp;
if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
{
+ /* tmp is on the right of key2 non-overlapping */
if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{ // ranges are connected
tmp->copy_min_to_min(key2);
@@ -6734,25 +6737,52 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *
}
}
- // tmp.max >= key2.min && tmp.min <= key.max (overlapping ranges)
+ /*
+ tmp.min >= key2.min && tmp.min <= key.max (overlapping ranges)
+ key2.min <= tmp.min <= key2.max
+ */
if (eq_tree(tmp->next_key_part,key2->next_key_part))
{
if (tmp->is_same(key2))
{
+ /*
+ Found exact match of key2 inside key1.
+ Use the relevant range in key1.
+ */
tmp->merge_flags(key2); // Copy maybe flags
key2->increment_use_count(-1); // Free not used tree
}
else
{
SEL_ARG *last=tmp;
+ SEL_ARG *first=tmp;
+ /*
+ Find the last range in tmp that overlaps key2 and has the same
+ condition on the rest of the keyparts.
+ */
while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
eq_tree(last->next->next_key_part,key2->next_key_part))
{
+ /*
+ We've found the last overlapping key1 range in last.
+ This means that the ranges between (and including) the
+ first overlapping range (tmp) and the last overlapping range
+ (last) are fully nested into the current range of key2
+ and can safely be discarded. We just need the minimum endpoint
+ of the first overlapping range (tmp) so we can compare it with
+ the minimum endpoint of the enclosing key2 range.
+ */
SEL_ARG *save=last;
last=last->next;
key1=key1->tree_delete(save);
}
- last->copy_min(tmp);
+ /*
+ The tmp range (the first overlapping range) could have been discarded
+ by the previous loop. We should re-direct tmp to the new united range
+ that's taking its place.
+ */
+ tmp= last;
+ last->copy_min(first);
bool full_range= last->copy_min(key2);
if (!full_range)
{
@@ -7262,27 +7292,25 @@ int test_rb_tree(SEL_ARG *element,SEL_AR
}
-/*
- Count how many times SEL_ARG graph "root" refers to its part "key"
+/**
+ Count how many times SEL_ARG graph "root" refers to its part "key" via
+ transitive closure.
- SYNOPSIS
- count_key_part_usage()
- root An RB-Root node in a SEL_ARG graph.
- key Another RB-Root node in that SEL_ARG graph.
+ @param root An RB-Root node in a SEL_ARG graph.
+ @param key Another RB-Root node in that SEL_ARG graph.
- DESCRIPTION
- The passed "root" node may refer to "key" node via root->next_key_part,
- root->next->n
+ The passed "root" node may refer to "key" node via root->next_key_part,
+ root->next->n
- This function counts how many times the node "key" is referred (via
- SEL_ARG::next_key_part) by
- - intervals of RB-tree pointed by "root",
- - intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
- intervals of RB-tree pointed by "root",
- - and so on.
+ This function counts how many times the node "key" is referred (via
+ SEL_ARG::next_key_part) by
+ - intervals of RB-tree pointed by "root",
+ - intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
+ intervals of RB-tree pointed by "root",
+ - and so on.
- Here is an example (horizontal links represent next_key_part pointers,
- vertical links - next/prev prev pointers):
+ Here is an example (horizontal links represent next_key_part pointers,
+ vertical links - next/prev prev pointers):
+----+ $
|root|-----------------+
@@ -7302,8 +7330,8 @@ int test_rb_tree(SEL_ARG *element,SEL_AR
... +---+ $ |
| |------------+
+---+ $
- RETURN
- Number of links to "key" from nodes reachable from "root".
+ @return
+ Number of links to "key" from nodes reachable from "root".
*/
static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key)
@@ -7558,8 +7586,8 @@ check_quick_keys(PARAM *param, uint idx,
param->first_null_comp= key_tree->part+1;
if (key_tree->next_key_part &&
- key_tree->next_key_part->part == key_tree->part+1 &&
- key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
+ key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
+ key_tree->next_key_part->part == key_tree->part+1)
{ // const key as prefix
if (min_key_length == max_key_length &&
!memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
@@ -7840,8 +7868,8 @@ get_quick_keys(PARAM *param,QUICK_RANGE_
&tmp_max_key,max_key_flag);
if (key_tree->next_key_part &&
- key_tree->next_key_part->part == key_tree->part+1 &&
- key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
+ key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
+ key_tree->next_key_part->part == key_tree->part+1)
{ // const key as prefix
if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
memcmp(min_key, max_key, (uint)(tmp_max_key - max_key))==0 &&
@@ -9823,7 +9851,11 @@ check_group_min_max_predicates(COND *con
}
else if (cur_arg->const_item())
{
- DBUG_RETURN(TRUE);
+ /*
+ For predicates of the form "const OP expr" we also have to check 'expr'
+ to make a decision.
+ */
+ continue;
}
else
DBUG_RETURN(FALSE);
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-09-16 19:05:03 +0000
+++ b/sql/opt_table_elimination.cc 2010-02-18 12:03:52 +0000
@@ -1220,8 +1220,16 @@ void build_eq_mods_for_cond(Dep_analysis
bound_item= item;
}
}
- exchange_sort<Dep_value_field>(fvl, compare_field_values, NULL);
- add_module_expr(ctx, eq_mod, *and_level, NULL, bound_item, fvl);
+ /*
+ Multiple equality is only useful if it includes at least one field from
+ the table that we could potentially eliminate:
+ */
+ if (fvl->elements)
+ {
+
+ exchange_sort<Dep_value_field>(fvl, compare_field_values, NULL);
+ add_module_expr(ctx, eq_mod, *and_level, NULL, bound_item, fvl);
+ }
break;
}
default:
=== modified file 'sql/repl_failsafe.cc'
--- a/sql/repl_failsafe.cc 2009-09-23 13:10:23 +0000
+++ b/sql/repl_failsafe.cc 2010-01-22 10:58:21 +0000
@@ -559,7 +559,12 @@ HOSTS";
goto err;
}
si->server_id = log_server_id;
- my_hash_insert(&slave_list, (uchar*)si);
+ if (my_hash_insert(&slave_list, (uchar*)si))
+ {
+ error= "the slave is out of memory";
+ pthread_mutex_unlock(&LOCK_slave_list);
+ goto err;
+ }
}
strmake(si->host, row[1], sizeof(si->host)-1);
si->port = atoi(row[port_ind]);
=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc 2008-04-28 16:24:05 +0000
+++ b/sql/rpl_injector.cc 2010-03-04 08:03:07 +0000
@@ -59,10 +59,14 @@ injector::transaction::~transaction()
my_free(the_memory, MYF(0));
}
+/**
+ @retval 0 transaction committed
+ @retval 1 transaction rolled back
+ */
int injector::transaction::commit()
{
DBUG_ENTER("injector::transaction::commit()");
- m_thd->binlog_flush_pending_rows_event(true);
+ int error= m_thd->binlog_flush_pending_rows_event(true);
/*
Cluster replication does not preserve statement or
transaction boundaries of the master. Instead, a new
@@ -82,9 +86,9 @@ int injector::transaction::commit()
is committed by committing the statement transaction
explicitly.
*/
- ha_autocommit_or_rollback(m_thd, 0);
- end_trans(m_thd, COMMIT);
- DBUG_RETURN(0);
+ error |= ha_autocommit_or_rollback(m_thd, error);
+ end_trans(m_thd, error ? ROLLBACK : COMMIT);
+ DBUG_RETURN(error);
}
int injector::transaction::use_table(server_id_type sid, table tbl)
@@ -110,16 +114,17 @@ int injector::transaction::write_row (se
record_type record)
{
DBUG_ENTER("injector::transaction::write_row(...)");
-
- if (int error= check_state(ROW_STATE))
+
+ int error= check_state(ROW_STATE);
+ if (error)
DBUG_RETURN(error);
server_id_type save_id= m_thd->server_id;
m_thd->set_server_id(sid);
- m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(),
- cols, colcnt, record);
+ error= m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(),
+ cols, colcnt, record);
m_thd->set_server_id(save_id);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
@@ -129,15 +134,16 @@ int injector::transaction::delete_row(se
{
DBUG_ENTER("injector::transaction::delete_row(...)");
- if (int error= check_state(ROW_STATE))
+ int error= check_state(ROW_STATE);
+ if (error)
DBUG_RETURN(error);
server_id_type save_id= m_thd->server_id;
m_thd->set_server_id(sid);
- m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(),
- cols, colcnt, record);
+ error= m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(),
+ cols, colcnt, record);
m_thd->set_server_id(save_id);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
@@ -147,15 +153,16 @@ int injector::transaction::update_row(se
{
DBUG_ENTER("injector::transaction::update_row(...)");
- if (int error= check_state(ROW_STATE))
+ int error= check_state(ROW_STATE);
+ if (error)
DBUG_RETURN(error);
server_id_type save_id= m_thd->server_id;
m_thd->set_server_id(sid);
- m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(),
- cols, colcnt, before, after);
+ error= m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(),
+ cols, colcnt, before, after);
m_thd->set_server_id(save_id);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
=== modified file 'sql/rpl_record.cc'
--- a/sql/rpl_record.cc 2009-03-05 19:54:53 +0000
+++ b/sql/rpl_record.cc 2010-03-04 08:03:07 +0000
@@ -180,7 +180,8 @@ int
unpack_row(Relay_log_info const *rli,
TABLE *table, uint const colcnt,
uchar const *const row_data, MY_BITMAP const *cols,
- uchar const **const row_end, ulong *const master_reclength)
+ uchar const **const row_end, ulong *const master_reclength,
+ const bool abort_on_warning, const bool first_row)
{
DBUG_ENTER("unpack_row");
DBUG_ASSERT(row_data);
@@ -224,8 +225,51 @@ unpack_row(Relay_log_info const *rli,
/* Field...::unpack() cannot return 0 */
DBUG_ASSERT(pack_ptr != NULL);
- if ((null_bits & null_mask) && f->maybe_null())
- f->set_null();
+ if (null_bits & null_mask)
+ {
+ if (f->maybe_null())
+ {
+ DBUG_PRINT("debug", ("Was NULL; null mask: 0x%x; null bits: 0x%x",
+ null_mask, null_bits));
+ /**
+ Calling reset just in case one is unpacking on top a
+ record with data.
+
+ This could probably go into set_null() but doing so,
+ (i) triggers assertion in other parts of the code at
+ the moment; (ii) it would make us reset the field,
+ always when setting null, which right now doesn't seem
+ needed anywhere else except here.
+
+ TODO: maybe in the future we should consider moving
+ the reset to make it part of set_null. But then
+ the assertions triggered need to be
+ addressed/revisited.
+ */
+ f->reset();
+ f->set_null();
+ }
+ else
+ {
+ MYSQL_ERROR::enum_warning_level error_type=
+ MYSQL_ERROR::WARN_LEVEL_NOTE;
+ if (abort_on_warning && (table->file->has_transactions() ||
+ first_row))
+ {
+ error = HA_ERR_ROWS_EVENT_APPLY;
+ error_type= MYSQL_ERROR::WARN_LEVEL_ERROR;
+ }
+ else
+ {
+ f->set_default();
+ error_type= MYSQL_ERROR::WARN_LEVEL_WARN;
+ }
+ push_warning_printf(current_thd, error_type,
+ ER_BAD_NULL_ERROR,
+ ER(ER_BAD_NULL_ERROR),
+ f->field_name);
+ }
+ }
else
{
f->set_notnull();
@@ -305,13 +349,17 @@ unpack_row(Relay_log_info const *rli,
@param table Table whose record[0] buffer is prepared.
@param skip Number of columns for which default/nullable check
should be skipped.
- @param check Indicates if errors should be raised when checking
- default/nullable field properties.
+ @param check Specifies if lack of default error needs checking.
+ @param abort_on_warning
+ Controls how to react on lack of a field's default.
+ The parameter mimics the master side one for
+ @c check_that_all_fields_are_given_values.
@returns 0 on success or a handler level error code
*/
int prepare_record(TABLE *const table,
- const uint skip, const bool check)
+ const uint skip, const bool check,
+ const bool abort_on_warning, const bool first_row)
{
DBUG_ENTER("prepare_record");
@@ -326,17 +374,36 @@ int prepare_record(TABLE *const table,
if (skip >= table->s->fields || !check)
DBUG_RETURN(0);
- /* Checking if exists default/nullable fields in the default values. */
-
- for (Field **field_ptr= table->field+skip ; *field_ptr ; ++field_ptr)
+ /*
+ For fields the extra fields on the slave, we check if they have a default.
+ The check follows the same rules as the INSERT query without specifying an
+ explicit value for a field not having the explicit default
+ (@c check_that_all_fields_are_given_values()).
+ */
+ for (Field **field_ptr= table->field+skip; *field_ptr; ++field_ptr)
{
- uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
Field *const f= *field_ptr;
-
- if (((f->flags & mask) == mask))
+ if ((f->flags & NO_DEFAULT_VALUE_FLAG) &&
+ (f->real_type() != MYSQL_TYPE_ENUM))
{
- my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
- error = HA_ERR_ROWS_EVENT_APPLY;
+
+ MYSQL_ERROR::enum_warning_level error_type=
+ MYSQL_ERROR::WARN_LEVEL_NOTE;
+ if (abort_on_warning && (table->file->has_transactions() ||
+ first_row))
+ {
+ error= HA_ERR_ROWS_EVENT_APPLY;
+ error_type= MYSQL_ERROR::WARN_LEVEL_ERROR;
+ }
+ else
+ {
+ f->set_default();
+ error_type= MYSQL_ERROR::WARN_LEVEL_WARN;
+ }
+ push_warning_printf(current_thd, error_type,
+ ER_NO_DEFAULT_FOR_FIELD,
+ ER(ER_NO_DEFAULT_FOR_FIELD),
+ f->field_name);
}
}
=== modified file 'sql/rpl_record.h'
--- a/sql/rpl_record.h 2008-01-31 12:54:03 +0000
+++ b/sql/rpl_record.h 2009-10-22 00:15:45 +0000
@@ -27,10 +27,13 @@ size_t pack_row(TABLE* table, MY_BITMAP
int unpack_row(Relay_log_info const *rli,
TABLE *table, uint const colcnt,
uchar const *const row_data, MY_BITMAP const *cols,
- uchar const **const row_end, ulong *const master_reclength);
+ uchar const **const row_end, ulong *const master_reclength,
+ const bool abort_on_warning= TRUE, const bool first_row= TRUE);
// Fill table's record[0] with default values.
-int prepare_record(TABLE *const, const uint =0, const bool =FALSE);
+int prepare_record(TABLE *const table, const uint skip, const bool check,
+ const bool abort_on_warning= TRUE,
+ const bool first_row= TRUE);
#endif
#endif
=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc 2009-12-03 11:19:05 +0000
+++ b/sql/rpl_rli.cc 2010-03-04 08:03:07 +0000
@@ -100,7 +100,8 @@ int init_relay_log_info(Relay_log_info*
rli->tables_to_lock_count= 0;
char pattern[FN_REFLEN];
- if (fn_format(pattern, PREFIX_SQL_LOAD, slave_load_tmpdir, "",
+ (void) my_realpath(pattern, slave_load_tmpdir, 0);
+ if (fn_format(pattern, PREFIX_SQL_LOAD, pattern, "",
MY_SAFE_PATH | MY_RETURN_REAL_PATH) == NullS)
{
pthread_mutex_unlock(&rli->data_lock);
@@ -127,6 +128,29 @@ int init_relay_log_info(Relay_log_info*
rli->relay_log.max_size (and mysql_bin_log.max_size).
*/
{
+ /* Reports an error and returns, if the --relay-log's path
+ is a directory.*/
+ if (opt_relay_logname &&
+ opt_relay_logname[strlen(opt_relay_logname) - 1] == FN_LIBCHAR)
+ {
+ pthread_mutex_unlock(&rli->data_lock);
+ sql_print_error("Path '%s' is a directory name, please specify \
+a file name for --relay-log option", opt_relay_logname);
+ DBUG_RETURN(1);
+ }
+
+ /* Reports an error and returns, if the --relay-log-index's path
+ is a directory.*/
+ if (opt_relaylog_index_name &&
+ opt_relaylog_index_name[strlen(opt_relaylog_index_name) - 1]
+ == FN_LIBCHAR)
+ {
+ pthread_mutex_unlock(&rli->data_lock);
+ sql_print_error("Path '%s' is a directory name, please specify \
+a file name for --relay-log-index option", opt_relaylog_index_name);
+ DBUG_RETURN(1);
+ }
+
char buf[FN_REFLEN];
const char *ln;
static bool name_warning_sent= 0;
@@ -153,10 +177,10 @@ int init_relay_log_info(Relay_log_info*
note, that if open() fails, we'll still have index file open
but a destructor will take care of that
*/
- if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln) ||
+ if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE) ||
rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
(max_relay_log_size ? max_relay_log_size :
- max_binlog_size), 1))
+ max_binlog_size), 1, TRUE))
{
pthread_mutex_unlock(&rli->data_lock);
sql_print_error("Failed in open_log() called from init_relay_log_info()");
@@ -993,7 +1017,7 @@ err:
false - condition not met
*/
-bool Relay_log_info::is_until_satisfied(my_off_t master_beg_pos)
+bool Relay_log_info::is_until_satisfied(THD *thd, Log_event *ev)
{
const char *log_name;
ulonglong log_pos;
@@ -1003,8 +1027,12 @@ bool Relay_log_info::is_until_satisfied(
if (until_condition == UNTIL_MASTER_POS)
{
+ if (ev && ev->server_id == (uint32) ::server_id && !replicate_same_server_id)
+ DBUG_RETURN(FALSE);
log_name= group_master_log_name;
- log_pos= master_beg_pos;
+ log_pos= (!ev)? group_master_log_pos :
+ ((thd->options & OPTION_BEGIN || !ev->log_pos) ?
+ group_master_log_pos : ev->log_pos - ev->data_written);
}
else
{ /* until_condition == UNTIL_RELAY_POS */
=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h 2009-05-19 09:28:05 +0000
+++ b/sql/rpl_rli.h 2010-03-04 08:03:07 +0000
@@ -303,7 +303,7 @@ public:
void close_temporary_tables();
/* Check if UNTIL condition is satisfied. See slave.cc for more. */
- bool is_until_satisfied(my_off_t master_beg_pos);
+ bool is_until_satisfied(THD *thd, Log_event *ev);
inline ulonglong until_pos()
{
return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos :
=== modified file 'sql/rpl_tblmap.cc'
--- a/sql/rpl_tblmap.cc 2008-08-20 14:06:31 +0000
+++ b/sql/rpl_tblmap.cc 2009-11-20 15:18:01 +0000
@@ -119,7 +119,13 @@ int table_mapping::set_table(ulong table
}
e->table_id= table_id;
e->table= table;
- my_hash_insert(&m_table_ids,(uchar *)e);
+ if (my_hash_insert(&m_table_ids,(uchar *)e))
+ {
+ /* we add this entry to the chain of free (free for use) entries */
+ e->next= m_free;
+ m_free= e;
+ DBUG_RETURN(ERR_MEMORY_ALLOCATION);
+ }
DBUG_PRINT("info", ("tid %lu -> table 0x%lx (%s)",
table_id, (long) e->table,
=== modified file 'sql/rpl_utility.h'
--- a/sql/rpl_utility.h 2009-03-25 10:53:56 +0000
+++ b/sql/rpl_utility.h 2010-01-05 06:25:29 +0000
@@ -95,6 +95,7 @@ public:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_GEOMETRY:
{
/*
These types store a single byte.
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2009-12-03 11:19:05 +0000
+++ b/sql/set_var.cc 2010-03-28 18:10:00 +0000
@@ -58,6 +58,9 @@
#include <my_getopt.h>
#include <thr_alarm.h>
#include <myisam.h>
+#ifdef WITH_MARIA_STORAGE_ENGINE
+#include <maria.h>
+#endif
#include <my_dir.h>
#include <waiting_threads.h>
#include "events.h"
@@ -148,6 +151,7 @@ static void sys_default_general_log_path
static bool sys_update_slow_log_path(THD *thd, set_var * var);
static void sys_default_slow_log_path(THD *thd, enum_var_type type);
static void fix_sys_log_slow_filter(THD *thd, enum_var_type);
+static uchar *get_myisam_mmap_size(THD *thd);
/*
Variable definition list
@@ -181,6 +185,8 @@ static sys_var_long_ptr sys_binlog_cache
&binlog_cache_size);
static sys_var_thd_binlog_format sys_binlog_format(&vars, "binlog_format",
&SV::binlog_format);
+static sys_var_thd_bool sys_binlog_direct_non_trans_update(&vars, "binlog_direct_non_transactional_updates",
+ &SV::binlog_direct_non_trans_update);
static sys_var_thd_ulong sys_bulk_insert_buff_size(&vars, "bulk_insert_buffer_size",
&SV::bulk_insert_buff_size);
static sys_var_const_os sys_character_sets_dir(&vars,
@@ -936,6 +942,10 @@ sys_var_str sys_var_slow_log_path(&vars,
opt_slow_logname);
static sys_var_log_output sys_var_log_output_state(&vars, "log_output", &log_output_options,
&log_output_typelib, 0);
+static sys_var_readonly sys_myisam_mmap_size(&vars, "myisam_mmap_size",
+ OPT_GLOBAL,
+ SHOW_LONGLONG,
+ get_myisam_mmap_size);
bool sys_var::check(THD *thd, set_var *var)
@@ -1253,16 +1263,16 @@ uchar *sys_var_set::value_ptr(THD *thd,
void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
{
- slave_exec_mode_options= 0;
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ slave_exec_mode_options= (ULL(1) << SLAVE_EXEC_MODE_STRICT);
}
bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
{
bool rc= sys_var_set::check(thd, var);
if (!rc &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ test_all_bits(var->save_result.ulong_value,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
rc= true;
my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
@@ -1284,15 +1294,16 @@ void fix_slave_exec_mode(enum_var_type t
DBUG_ENTER("fix_slave_exec_mode");
compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT
> SLAVE_EXEC_MODE_LAST_BIT - 1);
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
+ if (test_all_bits(slave_exec_mode_options,
+ ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
+ (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
{
sql_print_error("Ambiguous slave modes combination."
" STRICT will be used");
- bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT);
+ slave_exec_mode_options&= ~(ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT);
}
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
+ if (!(slave_exec_mode_options & (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT)))
+ slave_exec_mode_options|= (ULL(1)<< SLAVE_EXEC_MODE_STRICT);
DBUG_VOID_RETURN;
}
@@ -3272,6 +3283,12 @@ static uchar *get_tmpdir(THD *thd)
return (uchar*)mysql_tmpdir;
}
+static uchar *get_myisam_mmap_size(THD *thd)
+{
+ return (uchar *)&myisam_mmap_size;
+}
+
+
/****************************************************************************
Main handling of variables:
- Initialisation
@@ -3842,7 +3859,7 @@ uchar *sys_var_thd_storage_engine::value
LEX_STRING *engine_name;
plugin_ref plugin= thd->variables.*offset;
if (type == OPT_GLOBAL)
- plugin= my_plugin_lock(thd, &(global_system_variables.*offset));
+ plugin= my_plugin_lock(thd, global_system_variables.*offset);
hton= plugin_data(plugin, handlerton*);
engine_name= hton_name(hton);
result= (uchar *) thd->strmake(engine_name->str, engine_name->length);
@@ -3863,7 +3880,7 @@ void sys_var_thd_storage_engine::set_def
else
{
value= &(thd->variables.*offset);
- new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
+ new_value= my_plugin_lock(NULL, global_system_variables.*offset);
}
DBUG_ASSERT(new_value);
old_value= *value;
@@ -3880,7 +3897,7 @@ bool sys_var_thd_storage_engine::update(
old_value= *value;
if (old_value != var->save_result.plugin)
{
- *value= my_plugin_lock(NULL, &var->save_result.plugin);
+ *value= my_plugin_lock(NULL, var->save_result.plugin);
plugin_unlock(NULL, old_value);
}
return 0;
@@ -4180,7 +4197,7 @@ bool process_key_caches(process_key_cach
void sys_var_trust_routine_creators::warn_deprecated(THD *thd)
{
- WARN_DEPRECATED(thd, "6.0", "@@log_bin_trust_routine_creators",
+ WARN_DEPRECATED(thd, VER_CELOSIA, "@@log_bin_trust_routine_creators",
"'@@log_bin_trust_function_creators'");
}
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2009-12-06 17:26:12 +0000
+++ b/sql/share/errmsg.txt 2010-03-04 08:03:07 +0000
@@ -5138,11 +5138,11 @@ ER_SP_BADSTATEMENT 0A000
eng "%s is not allowed in stored procedures"
ger "%s ist in gespeicherten Prozeduren nicht erlaubt"
ER_UPDATE_LOG_DEPRECATED_IGNORED 42000
- eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored"
- ger "Das Update-Log ist veraltet und wurde durch das Bin�Log ersetzt. SET SQL_LOG_UPDATE wird ignoriert"
+ eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored. This option will be removed in MySQL 5.6."
+ ger "Das Update-Log ist veraltet und wurde durch das Bin�Log ersetzt. SET SQL_LOG_UPDATE wird ignoriert. Diese Option wird in MySQL 5.6 entfernt."
ER_UPDATE_LOG_DEPRECATED_TRANSLATED 42000
- eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN"
- ger "Das Update-Log ist veraltet und wurde durch das Bin�Log ersetzt. SET SQL_LOG_UPDATE wurde in SET SQL_LOG_BIN �tzt"
+ eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN. This option will be removed in MySQL 5.6."
+ ger "Das Update-Log ist veraltet und wurde durch das Bin�Log ersetzt. SET SQL_LOG_UPDATE wurde in SET SQL_LOG_BIN �tzt. Diese Option wird in MySQL 5.6 entfernt."
ER_QUERY_INTERRUPTED 70100
eng "Query execution was interrupted"
ger "Ausf� der Abfrage wurde unterbrochen"
@@ -5696,8 +5696,8 @@ ER_PARTITION_WRONG_NO_SUBPART_ERROR
eng "Wrong number of subpartitions defined, mismatch with previous setting"
ger "Falsche Anzahl von Unterpartitionen definiert, stimmt nicht mit vorherigen Einstellungen �n"
swe "Antal subpartitioner definierade och antal subpartitioner �inte lika"
-ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR
- eng "Constant/Random expression in (sub)partitioning function is not allowed"
+ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ eng "Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed"
ger "Konstante oder Random-Ausdr�n (Unter-)Partitionsfunktionen sind nicht erlaubt"
swe "Konstanta uttryck eller slumpm�iga uttryck �inte till�a (sub)partitioneringsfunktioner"
ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR
=== modified file 'sql/slave.cc'
--- a/sql/slave.cc 2009-12-06 17:51:48 +0000
+++ b/sql/slave.cc 2010-03-04 08:03:07 +0000
@@ -2218,9 +2218,7 @@ static int exec_relay_log_event(THD* thd
hits the UNTIL barrier.
*/
if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
- rli->is_until_satisfied((rli->is_in_group() || !ev->log_pos) ?
- rli->group_master_log_pos :
- ev->log_pos - ev->data_written))
+ rli->is_until_satisfied(thd, ev))
{
char buf[22];
sql_print_information("Slave SQL thread stopped because it reached its"
@@ -2963,7 +2961,7 @@ log '%s' at position %s, relay log '%s'
*/
pthread_mutex_lock(&rli->data_lock);
if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
- rli->is_until_satisfied(rli->group_master_log_pos))
+ rli->is_until_satisfied(thd, NULL))
{
char buf[22];
sql_print_information("Slave SQL thread stopped because it reached its"
@@ -3803,10 +3801,11 @@ static int connect_to_master(THD* thd, M
suppress_warnings= 0;
mi->report(ERROR_LEVEL, last_errno,
"error %s to master '%s@%s:%d'"
- " - retry-time: %d retries: %lu",
+ " - retry-time: %d retries: %lu message: %s",
(reconnect ? "reconnecting" : "connecting"),
mi->user, mi->host, mi->port,
- mi->connect_retry, master_retry_count);
+ mi->connect_retry, master_retry_count,
+ mysql_error(mysql));
}
/*
By default we try forever. The reason is that failure will trigger
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2009-10-16 10:29:42 +0000
+++ b/sql/sp.cc 2010-01-25 02:55:05 +0000
@@ -70,6 +70,122 @@ enum
MYSQL_PROC_FIELD_COUNT
};
+static const
+TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
+{
+ {
+ { C_STRING_WITH_LEN("db") },
+ { C_STRING_WITH_LEN("char(64)") },
+ { C_STRING_WITH_LEN("utf8") }
+ },
+ {
+ { C_STRING_WITH_LEN("name") },
+ { C_STRING_WITH_LEN("char(64)") },
+ { C_STRING_WITH_LEN("utf8") }
+ },
+ {
+ { C_STRING_WITH_LEN("type") },
+ { C_STRING_WITH_LEN("enum('FUNCTION','PROCEDURE')") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("specific_name") },
+ { C_STRING_WITH_LEN("char(64)") },
+ { C_STRING_WITH_LEN("utf8") }
+ },
+ {
+ { C_STRING_WITH_LEN("language") },
+ { C_STRING_WITH_LEN("enum('SQL')") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("sql_data_access") },
+ { C_STRING_WITH_LEN("enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("is_deterministic") },
+ { C_STRING_WITH_LEN("enum('YES','NO')") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("security_type") },
+ { C_STRING_WITH_LEN("enum('INVOKER','DEFINER')") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("param_list") },
+ { C_STRING_WITH_LEN("blob") },
+ { NULL, 0 }
+ },
+
+ {
+ { C_STRING_WITH_LEN("returns") },
+ { C_STRING_WITH_LEN("longblob") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("body") },
+ { C_STRING_WITH_LEN("longblob") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("definer") },
+ { C_STRING_WITH_LEN("char(77)") },
+ { C_STRING_WITH_LEN("utf8") }
+ },
+ {
+ { C_STRING_WITH_LEN("created") },
+ { C_STRING_WITH_LEN("timestamp") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("modified") },
+ { C_STRING_WITH_LEN("timestamp") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("sql_mode") },
+ { C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
+ "'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
+ "'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
+ "'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
+ "'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
+ "'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
+ "'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
+ "'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')") },
+ { NULL, 0 }
+ },
+ {
+ { C_STRING_WITH_LEN("comment") },
+ { C_STRING_WITH_LEN("char(64)") },
+ { C_STRING_WITH_LEN("utf8") }
+ },
+ {
+ { C_STRING_WITH_LEN("character_set_client") },
+ { C_STRING_WITH_LEN("char(32)") },
+ { C_STRING_WITH_LEN("utf8") }
+ },
+ {
+ { C_STRING_WITH_LEN("collation_connection") },
+ { C_STRING_WITH_LEN("char(32)") },
+ { C_STRING_WITH_LEN("utf8") }
+ },
+ {
+ { C_STRING_WITH_LEN("db_collation") },
+ { C_STRING_WITH_LEN("char(32)") },
+ { C_STRING_WITH_LEN("utf8") }
+ },
+ {
+ { C_STRING_WITH_LEN("body_utf8") },
+ { C_STRING_WITH_LEN("longblob") },
+ { NULL, 0 }
+ }
+};
+
+static const TABLE_FIELD_DEF
+ proc_table_def= {MYSQL_PROC_FIELD_COUNT, proc_table_fields};
+
/*************************************************************************/
/**
@@ -247,6 +363,50 @@ Stored_routine_creation_ctx::load_from_d
/*************************************************************************/
+class Proc_table_intact : public Table_check_intact
+{
+private:
+ bool m_print_once;
+
+public:
+ Proc_table_intact() : m_print_once(TRUE) {}
+
+protected:
+ void report_error(uint code, const char *fmt, ...);
+};
+
+
+/**
+ Report failure to validate the mysql.proc table definition.
+ Print a message to the error log only once.
+*/
+
+void Proc_table_intact::report_error(uint code, const char *fmt, ...)
+{
+ va_list args;
+ char buf[512];
+
+ va_start(args, fmt);
+ my_vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ if (code)
+ my_message(code, buf, MYF(0));
+ else
+ my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "proc");
+
+ if (m_print_once)
+ {
+ m_print_once= FALSE;
+ sql_print_error("%s", buf);
+ }
+};
+
+
+/** Single instance used to control printing to the error log. */
+static Proc_table_intact proc_table_intact;
+
+
/**
Open the mysql.proc table for read.
@@ -266,15 +426,17 @@ TABLE *open_proc_table_for_read(THD *thd
DBUG_ENTER("open_proc_table_for_read");
TABLE_LIST table;
- bzero((char*) &table, sizeof(table));
- table.db= (char*) "mysql";
- table.table_name= table.alias= (char*)"proc";
- table.lock_type= TL_READ;
+ table.init_one_table("mysql", "proc", TL_READ);
+
+ if (open_system_tables_for_read(thd, &table, backup))
+ DBUG_RETURN(NULL);
- if (!open_system_tables_for_read(thd, &table, backup))
+ if (!proc_table_intact.check(table.table, &proc_table_def))
DBUG_RETURN(table.table);
- else
- DBUG_RETURN(0);
+
+ close_system_tables(thd, backup);
+
+ DBUG_RETURN(NULL);
}
@@ -296,13 +458,19 @@ static TABLE *open_proc_table_for_update
{
DBUG_ENTER("open_proc_table_for_update");
- TABLE_LIST table;
- bzero((char*) &table, sizeof(table));
- table.db= (char*) "mysql";
- table.table_name= table.alias= (char*)"proc";
- table.lock_type= TL_WRITE;
+ TABLE *table;
+ TABLE_LIST table_list;
+ table_list.init_one_table("mysql", "proc", TL_WRITE);
- DBUG_RETURN(open_system_table_for_update(thd, &table));
+ if (!(table= open_system_table_for_update(thd, &table_list)))
+ DBUG_RETURN(NULL);
+
+ if (!proc_table_intact.check(table, &proc_table_def))
+ DBUG_RETURN(table);
+
+ close_thread_tables(thd);
+
+ DBUG_RETURN(NULL);
}
@@ -728,10 +896,13 @@ sp_create_routine(THD *thd, int type, sp
bool store_failed= FALSE;
+ bool save_binlog_row_based;
+
DBUG_ENTER("sp_create_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length,
sp->m_name.str));
String retstr(64);
+ retstr.set_charset(system_charset_info);
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
type == TYPE_ENUM_FUNCTION);
@@ -744,6 +915,7 @@ sp_create_routine(THD *thd, int type, sp
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
saved_count_cuted_fields= thd->count_cuted_fields;
@@ -936,9 +1108,10 @@ sp_create_routine(THD *thd, int type, sp
/* restore sql_mode when binloging */
thd->variables.sql_mode= saved_mode;
/* Such a statement can always go directly to binlog, no trans cache */
- thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- log_query.c_ptr(), log_query.length(),
- FALSE, FALSE, 0);
+ if (thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ log_query.c_ptr(), log_query.length(),
+ FALSE, FALSE, 0))
+ ret= SP_INTERNAL_ERROR;
thd->variables.sql_mode= 0;
}
@@ -949,6 +1122,8 @@ done:
thd->variables.sql_mode= saved_mode;
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(ret);
}
@@ -973,6 +1148,7 @@ sp_drop_routine(THD *thd, int type, sp_n
{
TABLE *table;
int ret;
+ bool save_binlog_row_based;
DBUG_ENTER("sp_drop_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",
type, (int) name->m_name.length, name->m_name.str));
@@ -985,6 +1161,7 @@ sp_drop_routine(THD *thd, int type, sp_n
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
if (!(table= open_proc_table_for_update(thd)))
@@ -997,11 +1174,14 @@ sp_drop_routine(THD *thd, int type, sp_n
if (ret == SP_OK)
{
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ ret= SP_INTERNAL_ERROR;
sp_cache_invalidate();
}
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(ret);
}
@@ -1028,6 +1208,7 @@ sp_update_routine(THD *thd, int type, sp
{
TABLE *table;
int ret;
+ bool save_binlog_row_based;
DBUG_ENTER("sp_update_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",
type, (int) name->m_name.length, name->m_name.str));
@@ -1039,6 +1220,7 @@ sp_update_routine(THD *thd, int type, sp
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
if (!(table= open_proc_table_for_update(thd)))
@@ -1067,11 +1249,14 @@ sp_update_routine(THD *thd, int type, sp
if (ret == SP_OK)
{
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ ret= SP_INTERNAL_ERROR;
sp_cache_invalidate();
}
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(ret);
}
@@ -1235,6 +1420,7 @@ sp_find_routine(THD *thd, int type, sp_n
64 -- size of "returns" column of mysql.proc.
*/
String retstr(64);
+ retstr.set_charset(sp->get_creation_ctx()->get_client_cs());
DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp));
if (sp->m_first_free_instance)
@@ -1506,7 +1692,8 @@ static bool add_used_routine(LEX *lex, Q
rn->key.length= key->length;
rn->key.str= (char *)rn + sizeof(Sroutine_hash_entry);
memcpy(rn->key.str, key->str, key->length + 1);
- my_hash_insert(&lex->sroutines, (uchar *)rn);
+ if (my_hash_insert(&lex->sroutines, (uchar *)rn))
+ return FALSE;
lex->sroutines_list.link_in_list((uchar *)rn, (uchar **)&rn->next);
rn->belong_to_view= belong_to_view;
return TRUE;
@@ -1584,16 +1771,24 @@ void sp_remove_not_own_routines(LEX *lex
dependant on time of life of elements from source hash. It also
won't touch lists linking elements in source and destination
hashes.
+
+ @returns
+ @return TRUE Failure
+ @return FALSE Success
*/
-void sp_update_sp_used_routines(HASH *dst, HASH *src)
+bool sp_update_sp_used_routines(HASH *dst, HASH *src)
{
for (uint i=0 ; i < src->records ; i++)
{
Sroutine_hash_entry *rt= (Sroutine_hash_entry *)hash_element(src, i);
if (!hash_search(dst, (uchar *)rt->key.str, rt->key.length))
- my_hash_insert(dst, (uchar *)rt);
+ {
+ if (my_hash_insert(dst, (uchar *)rt))
+ return TRUE;
+ }
}
+ return FALSE;
}
=== modified file 'sql/sp.h'
--- a/sql/sp.h 2009-07-28 17:44:38 +0000
+++ b/sql/sp.h 2009-11-20 15:18:01 +0000
@@ -69,7 +69,7 @@ void sp_get_prelocking_info(THD *thd, bo
void sp_add_used_routine(LEX *lex, Query_arena *arena,
sp_name *rt, char rt_type);
void sp_remove_not_own_routines(LEX *lex);
-void sp_update_sp_used_routines(HASH *dst, HASH *src);
+bool sp_update_sp_used_routines(HASH *dst, HASH *src);
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
bool first_no_prelock);
int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
=== modified file 'sql/sp_cache.cc'
--- a/sql/sp_cache.cc 2008-12-02 22:02:52 +0000
+++ b/sql/sp_cache.cc 2010-01-15 15:27:55 +0000
@@ -36,10 +36,16 @@ public:
sp_cache();
~sp_cache();
- inline void insert(sp_head *sp)
+ /**
+ Inserts a sp_head object into a hash table.
+
+ @returns Success status
+ @return TRUE Failure
+ @return FALSE Success
+ */
+ inline bool insert(sp_head *sp)
{
- /* TODO: why don't we check return value? */
- my_hash_insert(&m_hashtable, (const uchar *)sp);
+ return my_hash_insert(&m_hashtable, (const uchar *)sp);
}
inline sp_head *lookup(char *name, uint namelen)
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2009-12-03 11:34:11 +0000
+++ b/sql/sp_head.cc 2010-03-04 08:03:07 +0000
@@ -1790,6 +1790,7 @@ sp_head::execute_function(THD *thd, Item
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
"Invoked ROUTINE modified a transactional table but MySQL "
"failed to reflect this change in the binary log");
+ err_status= TRUE;
}
reset_dynamic(&thd->user_var_events);
/* Forget those values, in case more function calls are binlogged: */
@@ -2090,8 +2091,18 @@ sp_head::reset_lex(THD *thd)
DBUG_RETURN(FALSE);
}
-/// Restore lex during parsing, after we have parsed a sub statement.
-void
+
+/**
+ Restore lex during parsing, after we have parsed a sub statement.
+
+ @param thd Thread handle
+
+ @return
+ @retval TRUE failure
+ @retval FALSE success
+*/
+
+bool
sp_head::restore_lex(THD *thd)
{
DBUG_ENTER("sp_head::restore_lex");
@@ -2102,7 +2113,7 @@ sp_head::restore_lex(THD *thd)
oldlex= (LEX *)m_lex.pop();
if (! oldlex)
- return; // Nothing to restore
+ DBUG_RETURN(FALSE); // Nothing to restore
oldlex->trg_table_fields.push_back(&sublex->trg_table_fields);
@@ -2118,7 +2129,8 @@ sp_head::restore_lex(THD *thd)
Add routines which are used by statement to respective set for
this routine.
*/
- sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines);
+ if (sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines))
+ DBUG_RETURN(TRUE);
/*
Merge tables used by this statement (but not by its functions or
procedures) to multiset of tables used by this routine.
@@ -2130,7 +2142,7 @@ sp_head::restore_lex(THD *thd)
delete sublex;
}
thd->lex= oldlex;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
/**
@@ -2761,8 +2773,15 @@ sp_lex_keeper::reset_lex_and_exec_core(T
m_lex->mark_as_requiring_prelocking(NULL);
}
thd->rollback_item_tree_changes();
- /* Update the state of the active arena. */
- thd->stmt_arena->state= Query_arena::EXECUTED;
+ /*
+ Update the state of the active arena if no errors on
+ open_tables stage.
+ */
+ if (!res || !thd->is_error() ||
+ (thd->main_da.sql_errno() != ER_CANT_REOPEN_TABLE &&
+ thd->main_da.sql_errno() != ER_NO_SUCH_TABLE &&
+ thd->main_da.sql_errno() != ER_UPDATE_TABLE_USED))
+ thd->stmt_arena->state= Query_arena::EXECUTED;
/*
Merge here with the saved parent's values
@@ -3867,7 +3886,8 @@ sp_head::merge_table_list(THD *thd, TABL
tab->lock_type= table->lock_type;
tab->lock_count= tab->query_lock_count= 1;
tab->trg_event_map= table->trg_event_map;
- my_hash_insert(&m_sptabs, (uchar *)tab);
+ if (my_hash_insert(&m_sptabs, (uchar *)tab))
+ return FALSE;
}
}
return TRUE;
=== modified file 'sql/sp_head.h'
--- a/sql/sp_head.h 2009-04-29 02:59:10 +0000
+++ b/sql/sp_head.h 2009-11-20 15:18:01 +0000
@@ -340,7 +340,7 @@ public:
@todo Conflicting comment in sp_head.cc
*/
- void
+ bool
restore_lex(THD *thd);
/// Put the instruction on the backpatch list, associated with the label.
=== modified file 'sql/sp_pcontext.h'
--- a/sql/sp_pcontext.h 2009-04-29 02:59:10 +0000
+++ b/sql/sp_pcontext.h 2009-12-18 18:44:24 +0000
@@ -71,7 +71,7 @@ typedef struct sp_label
typedef struct sp_cond_type
{
enum { number, state, warning, notfound, exception } type;
- char sqlstate[6];
+ char sqlstate[SQLSTATE_LENGTH+1];
uint mysqlerr;
} sp_cond_type_t;
=== modified file 'sql/sp_rcontext.cc'
--- a/sql/sp_rcontext.cc 2008-01-23 22:36:57 +0000
+++ b/sql/sp_rcontext.cc 2009-11-06 19:34:25 +0000
@@ -617,7 +617,7 @@ sp_rcontext::set_case_expr(THD *thd, int
}
m_case_expr_holders[case_expr_id]->store(case_expr_item);
-
+ m_case_expr_holders[case_expr_id]->cache_value();
return FALSE;
}
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_acl.cc 2010-03-04 08:03:07 +0000
@@ -31,9 +31,8 @@
#include "sp_head.h"
#include "sp.h"
-time_t mysql_db_table_last_check= 0L;
-
-TABLE_FIELD_W_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
+static const
+TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
{
{ C_STRING_WITH_LEN("Host") },
{ C_STRING_WITH_LEN("char(60)") },
@@ -146,6 +145,8 @@ TABLE_FIELD_W_TYPE mysql_db_table_fields
}
};
+const TABLE_FIELD_DEF
+ mysql_db_table_def= {MYSQL_DB_FIELD_COUNT, mysql_db_table_fields};
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -309,7 +310,7 @@ static my_bool acl_load(THD *thd, TABLE_
{
TABLE *table;
READ_RECORD read_record_info;
- my_bool return_val= 1;
+ my_bool return_val= TRUE;
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
char tmp_name[NAME_LEN+1];
int password_length;
@@ -622,7 +623,7 @@ static my_bool acl_load(THD *thd, TABLE_
init_check_host();
initialized=1;
- return_val=0;
+ return_val= FALSE;
end:
thd->variables.sql_mode= old_sql_mode;
@@ -673,7 +674,7 @@ my_bool acl_reload(THD *thd)
DYNAMIC_ARRAY old_acl_hosts,old_acl_users,old_acl_dbs;
MEM_ROOT old_mem;
bool old_initialized;
- my_bool return_val= 1;
+ my_bool return_val= TRUE;
DBUG_ENTER("acl_reload");
if (thd->locked_tables)
@@ -700,8 +701,13 @@ my_bool acl_reload(THD *thd)
if (simple_open_n_lock_tables(thd, tables))
{
- sql_print_error("Fatal error: Can't open and lock privilege tables: %s",
- thd->main_da.message());
+ /*
+ Execution might have been interrupted; only print the error message
+ if an error condition has been raised.
+ */
+ if (thd->main_da.is_error())
+ sql_print_error("Fatal error: Can't open and lock privilege tables: %s",
+ thd->main_da.message());
goto end;
}
@@ -1060,7 +1066,7 @@ int acl_getroot(THD *thd, USER_RESOURCES
*mqh= acl_user->user_resource;
if (acl_user->host.hostname)
- strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
+ strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1);
else
*sctx->priv_host= 0;
}
@@ -1161,7 +1167,7 @@ bool acl_getroot_no_password(Security_co
sctx->priv_user= acl_user->user ? user : (char *) "";
if (acl_user->host.hostname)
- strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
+ strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1);
else
*sctx->priv_host= 0;
}
@@ -1654,8 +1660,8 @@ bool change_password(THD *thd, const cha
acl_user->host.hostname ? acl_user->host.hostname : "",
new_password));
thd->clear_error();
- thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length,
- FALSE, FALSE, 0);
+ result= thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length,
+ FALSE, FALSE, 0);
}
end:
close_thread_tables(thd);
@@ -2405,7 +2411,12 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TA
privs = cols = 0; /* purecov: deadcode */
return; /* purecov: deadcode */
}
- my_hash_insert(&hash_columns, (uchar *) mem_check);
+ if (my_hash_insert(&hash_columns, (uchar *) mem_check))
+ {
+ /* Invalidate this entry */
+ privs= cols= 0;
+ return;
+ }
} while (!col_privs->file->index_next(col_privs->record[0]) &&
!key_cmp_if_same(col_privs,key,0,key_prefix_len));
col_privs->file->ha_index_end();
@@ -2439,14 +2450,17 @@ static GRANT_NAME *name_hash_search(HASH
const char *host,const char* ip,
const char *db,
const char *user, const char *tname,
- bool exact)
+ bool exact, bool name_tolower)
{
- char helping [NAME_LEN*2+USERNAME_LENGTH+3];
+ char helping [NAME_LEN*2+USERNAME_LENGTH+3], *name_ptr;
uint len;
GRANT_NAME *grant_name,*found=0;
HASH_SEARCH_STATE state;
- len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1;
+ name_ptr= strmov(strmov(helping, user) + 1, db) + 1;
+ len = (uint) (strmov(name_ptr, tname) - helping) + 1;
+ if (name_tolower)
+ my_casedn_str(files_charset_info, name_ptr);
for (grant_name= (GRANT_NAME*) hash_first(name_hash, (uchar*) helping,
len, &state);
grant_name ;
@@ -2479,7 +2493,7 @@ routine_hash_search(const char *host, co
{
return (GRANT_TABLE*)
name_hash_search(proc ? &proc_priv_hash : &func_priv_hash,
- host, ip, db, user, tname, exact);
+ host, ip, db, user, tname, exact, TRUE);
}
@@ -2488,7 +2502,7 @@ table_hash_search(const char *host, cons
const char *user, const char *tname, bool exact)
{
return (GRANT_TABLE*) name_hash_search(&column_priv_hash, host, ip, db,
- user, tname, exact);
+ user, tname, exact, FALSE);
}
@@ -2610,7 +2624,11 @@ static int replace_column_table(GRANT_TA
goto end; /* purecov: inspected */
}
grant_column= new GRANT_COLUMN(column->column,privileges);
- my_hash_insert(&g_t->hash_columns,(uchar*) grant_column);
+ if (my_hash_insert(&g_t->hash_columns,(uchar*) grant_column))
+ {
+ result= -1;
+ goto end;
+ }
}
}
@@ -2961,6 +2979,7 @@ int mysql_table_grant(THD *thd, TABLE_LI
TABLE_LIST tables[3];
bool create_new_users=0;
char *db_name, *table_name;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_table_grant");
if (!initialized)
@@ -3056,6 +3075,7 @@ int mysql_table_grant(THD *thd, TABLE_LI
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
#ifdef HAVE_REPLICATION
@@ -3071,7 +3091,11 @@ int mysql_table_grant(THD *thd, TABLE_LI
*/
tables[0].updating= tables[1].updating= tables[2].updating= 1;
if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
+ {
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(FALSE);
+ }
}
#endif
@@ -3084,6 +3108,8 @@ int mysql_table_grant(THD *thd, TABLE_LI
if (simple_open_n_lock_tables(thd,tables))
{ // Should never happen
close_thread_tables(thd); /* purecov: deadcode */
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(TRUE); /* purecov: deadcode */
}
@@ -3135,12 +3161,12 @@ int mysql_table_grant(THD *thd, TABLE_LI
Str->user.str, table_name,
rights,
column_priv);
- if (!grant_table) // end of memory
+ if (!grant_table ||
+ my_hash_insert(&column_priv_hash,(uchar*) grant_table))
{
result= TRUE; /* purecov: deadcode */
continue; /* purecov: deadcode */
}
- my_hash_insert(&column_priv_hash,(uchar*) grant_table);
}
/* If revoke_grant, calculate the new column privilege for tables_priv */
@@ -3200,7 +3226,7 @@ int mysql_table_grant(THD *thd, TABLE_LI
if (!result) /* success */
{
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
rw_unlock(&LOCK_grant);
@@ -3210,6 +3236,8 @@ int mysql_table_grant(THD *thd, TABLE_LI
/* Tables are automatically closed */
thd->lex->restore_backup_query_tables_list(&backup);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result);
}
@@ -3238,6 +3266,7 @@ bool mysql_routine_grant(THD *thd, TABLE
TABLE_LIST tables[2];
bool create_new_users=0, result=0;
char *db_name, *table_name;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_routine_grant");
if (!initialized)
@@ -3273,6 +3302,7 @@ bool mysql_routine_grant(THD *thd, TABLE
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
#ifdef HAVE_REPLICATION
@@ -3288,13 +3318,19 @@ bool mysql_routine_grant(THD *thd, TABLE
*/
tables[0].updating= tables[1].updating= 1;
if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
+ {
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(FALSE);
+ }
}
#endif
if (simple_open_n_lock_tables(thd,tables))
{ // Should never happen
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(TRUE);
}
@@ -3344,12 +3380,13 @@ bool mysql_routine_grant(THD *thd, TABLE
grant_name= new GRANT_NAME(Str->host.str, db_name,
Str->user.str, table_name,
rights, TRUE);
- if (!grant_name)
+ if (!grant_name ||
+ my_hash_insert(is_proc ?
+ &proc_priv_hash : &func_priv_hash,(uchar*) grant_name))
{
result= TRUE;
continue;
}
- my_hash_insert(is_proc ? &proc_priv_hash : &func_priv_hash,(uchar*) grant_name);
}
if (replace_routine_table(thd, grant_name, tables[1].table, *Str,
@@ -3365,10 +3402,13 @@ bool mysql_routine_grant(THD *thd, TABLE
if (write_to_binlog)
{
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ if (write_bin_log(thd, FALSE, thd->query(), thd->query_length()))
+ result= TRUE;
}
rw_unlock(&LOCK_grant);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
/* Tables are automatically closed */
DBUG_RETURN(result);
@@ -3383,6 +3423,7 @@ bool mysql_grant(THD *thd, const char *d
char tmp_db[NAME_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_grant");
if (!initialized)
{
@@ -3411,6 +3452,7 @@ bool mysql_grant(THD *thd, const char *d
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
#ifdef HAVE_REPLICATION
@@ -3426,13 +3468,19 @@ bool mysql_grant(THD *thd, const char *d
*/
tables[0].updating= tables[1].updating= 1;
if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
+ {
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(FALSE);
+ }
}
#endif
if (simple_open_n_lock_tables(thd,tables))
{ // This should never happen
close_thread_tables(thd); /* purecov: deadcode */
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(TRUE); /* purecov: deadcode */
}
@@ -3452,6 +3500,13 @@ bool mysql_grant(THD *thd, const char *d
result= TRUE;
continue;
}
+ /*
+ No User, but a password?
+ They did GRANT ... TO CURRENT_USER() IDENTIFIED BY ... !
+ Get the current user, and shallow-copy the new password to them!
+ */
+ if (!tmp_Str->user.str && tmp_Str->password.str)
+ Str->password= tmp_Str->password;
if (replace_user_table(thd, tables[0].table, *Str,
(!db ? rights : 0), revoke_grant, create_new_users,
test(thd->variables.sql_mode &
@@ -3477,7 +3532,7 @@ bool mysql_grant(THD *thd, const char *d
if (!result)
{
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
rw_unlock(&LOCK_grant);
@@ -3485,6 +3540,8 @@ bool mysql_grant(THD *thd, const char *d
if (!result)
my_ok(thd);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result);
}
@@ -3745,11 +3802,11 @@ static my_bool grant_reload_procs_priv(T
DBUG_RETURN(TRUE);
}
+ rw_wrlock(&LOCK_grant);
/* Save a copy of the current hash if we need to undo the grant load */
old_proc_priv_hash= proc_priv_hash;
old_func_priv_hash= func_priv_hash;
- rw_wrlock(&LOCK_grant);
if ((return_val= grant_load_procs_priv(table.table)))
{
/* Error; Reverting to old hash */
@@ -5640,6 +5697,7 @@ bool mysql_create_user(THD *thd, List <L
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
bool some_users_created= FALSE;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_create_user");
/*
@@ -5647,11 +5705,16 @@ bool mysql_create_user(THD *thd, List <L
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
/* CREATE USER may be skipped on replication client. */
if ((result= open_grant_tables(thd, tables)))
+ {
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result != 1);
+ }
rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
@@ -5689,10 +5752,12 @@ bool mysql_create_user(THD *thd, List <L
my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe());
if (some_users_created)
- write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result);
}
@@ -5719,6 +5784,7 @@ bool mysql_drop_user(THD *thd, List <LEX
TABLE_LIST tables[GRANT_TABLES];
bool some_users_deleted= FALSE;
ulong old_sql_mode= thd->variables.sql_mode;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_drop_user");
/*
@@ -5726,11 +5792,16 @@ bool mysql_drop_user(THD *thd, List <LEX
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
/* DROP USER may be skipped on replication client. */
if ((result= open_grant_tables(thd, tables)))
+ {
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result != 1);
+ }
thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
@@ -5762,11 +5833,13 @@ bool mysql_drop_user(THD *thd, List <LEX
my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
if (some_users_deleted)
- write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
thd->variables.sql_mode= old_sql_mode;
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result);
}
@@ -5793,6 +5866,7 @@ bool mysql_rename_user(THD *thd, List <L
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
bool some_users_renamed= FALSE;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_rename_user");
/*
@@ -5800,11 +5874,16 @@ bool mysql_rename_user(THD *thd, List <L
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
/* RENAME USER may be skipped on replication client. */
if ((result= open_grant_tables(thd, tables)))
+ {
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result != 1);
+ }
rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
@@ -5847,10 +5926,12 @@ bool mysql_rename_user(THD *thd, List <L
my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
if (some_users_renamed && mysql_bin_log.is_open())
- write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result);
}
@@ -5875,6 +5956,7 @@ bool mysql_revoke_all(THD *thd, List <L
int result;
ACL_DB *acl_db;
TABLE_LIST tables[GRANT_TABLES];
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_revoke_all");
/*
@@ -5882,10 +5964,15 @@ bool mysql_revoke_all(THD *thd, List <L
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
if ((result= open_grant_tables(thd, tables)))
+ {
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result != 1);
+ }
rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
@@ -6029,15 +6116,19 @@ bool mysql_revoke_all(THD *thd, List <L
VOID(pthread_mutex_unlock(&acl_cache->lock));
- write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ int binlog_error=
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- if (result)
+ /* error for writing binary log has already been reported */
+ if (result && !binlog_error)
my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
- DBUG_RETURN(result);
+ DBUG_RETURN(result || binlog_error);
}
@@ -6119,6 +6210,7 @@ bool sp_revoke_privileges(THD *thd, cons
TABLE_LIST tables[GRANT_TABLES];
HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash;
Silence_routine_definer_errors error_handler;
+ bool save_binlog_row_based;
DBUG_ENTER("sp_revoke_privileges");
if ((result= open_grant_tables(thd, tables)))
@@ -6135,6 +6227,7 @@ bool sp_revoke_privileges(THD *thd, cons
row-based replication. The flag will be reset at the end of the
statement.
*/
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
/* Remove procedure access */
@@ -6171,6 +6264,8 @@ bool sp_revoke_privileges(THD *thd, cons
close_thread_tables(thd);
thd->pop_internal_handler();
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(error_handler.has_errors());
}
=== modified file 'sql/sql_acl.h'
--- a/sql/sql_acl.h 2009-05-29 13:37:54 +0000
+++ b/sql/sql_acl.h 2009-11-21 11:18:21 +0000
@@ -159,8 +159,7 @@ enum mysql_db_table_field
MYSQL_DB_FIELD_COUNT
};
-extern TABLE_FIELD_W_TYPE mysql_db_table_fields[];
-extern time_t mysql_db_table_last_check;
+extern const TABLE_FIELD_DEF mysql_db_table_def;
/* Classes */
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2009-12-04 15:12:22 +0000
+++ b/sql/sql_base.cc 2010-03-04 08:03:07 +0000
@@ -930,7 +930,7 @@ bool close_cached_tables(THD *thd, TABLE
for (TABLE_LIST *table= tables; table; table= table->next_local)
{
if (remove_table_from_cache(thd, table->db, table->table_name,
- RTFC_OWNED_BY_THD_FLAG))
+ RTFC_OWNED_BY_THD_FLAG, table->deleting))
found=1;
}
if (!found)
@@ -1336,7 +1336,7 @@ void close_thread_tables(THD *thd)
handled either before writing a query log event (inside
binlog_query()) or when preparing a pending event.
*/
- thd->binlog_flush_pending_rows_event(TRUE);
+ (void)thd->binlog_flush_pending_rows_event(TRUE);
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
@@ -1550,7 +1550,11 @@ void close_temporary_tables(THD *thd)
qinfo.db= db.ptr();
qinfo.db_len= db.length();
thd->variables.character_set_client= cs_save;
- mysql_bin_log.write(&qinfo);
+ if (mysql_bin_log.write(&qinfo))
+ {
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, MYF(0),
+ "Failed to write the DROP statement for temporary tables to binary log");
+ }
thd->variables.pseudo_thread_id= save_pseudo_thread_id;
}
else
@@ -2938,7 +2942,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *
DBUG_PRINT("info", ("inserting table '%s'.'%s' 0x%lx into the cache",
table->s->db.str, table->s->table_name.str,
(long) table));
- VOID(my_hash_insert(&open_cache,(uchar*) table));
+ if (my_hash_insert(&open_cache,(uchar*) table))
+ {
+ my_free(table, MYF(0));
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ DBUG_RETURN(NULL);
+ }
}
check_unused(); // Debugging call
@@ -4044,9 +4053,13 @@ retry:
end = strxmov(strmov(query, "DELETE FROM `"),
share->db.str,"`.`",share->table_name.str,"`", NullS);
int errcode= query_error_code(thd, TRUE);
- thd->binlog_query(THD::STMT_QUERY_TYPE,
- query, (ulong)(end-query),
- FALSE, FALSE, errcode);
+ if (thd->binlog_query(THD::STMT_QUERY_TYPE,
+ query, (ulong)(end-query),
+ FALSE, FALSE, errcode))
+ {
+ my_free(query, MYF(0));
+ goto err;
+ }
my_free(query, MYF(0));
}
else
@@ -5693,7 +5706,8 @@ find_field_in_view(THD *thd, TABLE_LIST
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
{
// in PS use own arena or data will be freed after prepare
- if (register_tree_change && thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
+ if (register_tree_change &&
+ thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute())
arena= thd->activate_stmt_arena_if_needed(&backup);
/*
create_item() may, or may not create a new Item, depending on
@@ -8399,6 +8413,11 @@ void remove_db_from_cache(const char *db
if (!strcmp(table->s->db.str, db))
{
table->s->version= 0L; /* Free when thread is ready */
+ /*
+ This functions only called from DROP DATABASE code, so we are going
+ to drop all tables so we mark them as deleting
+ */
+ table->s->deleting= TRUE;
if (!table->in_use)
relink_unused(table);
}
@@ -8441,7 +8460,7 @@ void flush_tables()
*/
bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
- uint flags)
+ uint flags, my_bool deleting)
{
char key[MAX_DBKEY_LENGTH];
uint key_length;
@@ -8535,7 +8554,10 @@ bool remove_table_from_cache(THD *thd, c
}
}
while (unused_tables && !unused_tables->s->version)
+ {
+ unused_tables->s->deleting= deleting;
VOID(hash_delete(&open_cache,(uchar*) unused_tables));
+ }
DBUG_PRINT("info", ("Removing table from table_def_cache"));
/* Remove table from table definition cache if it's not in use */
@@ -8729,7 +8751,8 @@ int abort_and_upgrade_lock(ALTER_PARTITI
/* If MERGE child, forward lock handling to parent. */
mysql_lock_abort(lpt->thd, lpt->table->parent ? lpt->table->parent :
lpt->table, TRUE);
- VOID(remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, flags));
+ VOID(remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, flags,
+ FALSE));
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(0);
}
@@ -8754,7 +8777,7 @@ void close_open_tables_and_downgrade(ALT
{
VOID(pthread_mutex_lock(&LOCK_open));
remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name,
- RTFC_WAIT_OTHER_THREAD_FLAG);
+ RTFC_WAIT_OTHER_THREAD_FLAG, FALSE);
VOID(pthread_mutex_unlock(&LOCK_open));
/* If MERGE child, forward lock handling to parent. */
mysql_lock_downgrade_write(lpt->thd, lpt->table->parent ? lpt->table->parent :
=== modified file 'sql/sql_cache.cc'
--- a/sql/sql_cache.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_cache.cc 2010-01-29 10:42:31 +0000
@@ -377,9 +377,11 @@ TODO list:
static void debug_wait_for_kill(const char *info)
{
- DBUG_ENTER("debug_wait_for_kill");
const char *prev_info;
THD *thd;
+ char buff[1024];
+ DBUG_ENTER("debug_wait_for_kill");
+
thd= current_thd;
prev_info= thd->proc_info;
thd->proc_info= info;
@@ -387,8 +389,16 @@ static void debug_wait_for_kill(const ch
while(!thd->killed)
my_sleep(1000);
thd->killed= THD::NOT_KILLED;
+ /*
+ Remove the set debug variable, to ensure we don't get stuck on it again
+ This is needed as for MyISAM, invalidate_table() may be called twice
+ (Once from mysql_delete() and once from mi_update_status())
+ */
+ sprintf(buff, "-d,%s", info);
+ DBUG_SET(buff);
sql_print_information("Exit debug_wait_for_kill");
thd->proc_info= prev_info;
+
DBUG_VOID_RETURN;
}
@@ -421,12 +431,16 @@ TYPELIB query_cache_type_typelib=
effect by another thread. This enables a quick path in execution to skip waits
when the outcome is known.
+ @param use_timeout TRUE if the lock can abort because of a timeout.
+
+ @note use_timeout is optional and default value is FALSE.
+
@return
@retval FALSE An exclusive lock was taken
@retval TRUE The locking attempt failed
*/
-bool Query_cache::try_lock(void)
+bool Query_cache::try_lock(bool use_timeout)
{
bool interrupt= FALSE;
DBUG_ENTER("Query_cache::try_lock");
@@ -456,7 +470,26 @@ bool Query_cache::try_lock(void)
else
{
DBUG_ASSERT(m_cache_lock_status == Query_cache::LOCKED);
- pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
+ /*
+ To prevent send_result_to_client() and query_cache_insert() from
+ blocking execution for too long a timeout is put on the lock.
+ */
+ if (use_timeout)
+ {
+ struct timespec waittime;
+ set_timespec_nsec(waittime,(ulong)(50000000L)); /* Wait for 50 msec */
+ int res= pthread_cond_timedwait(&COND_cache_status_changed,
+ &structure_guard_mutex,&waittime);
+ if (res == ETIMEDOUT)
+ {
+ interrupt= TRUE;
+ break;
+ }
+ }
+ else
+ {
+ pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
+ }
}
}
pthread_mutex_unlock(&structure_guard_mutex);
@@ -891,15 +924,18 @@ void query_cache_insert(NET *net, const
void query_cache_abort(NET *net)
{
+ THD *thd;
DBUG_ENTER("query_cache_abort");
- THD *thd= current_thd;
/* See the comment on double-check locking usage above. */
if (net->query_cache_query == 0)
DBUG_VOID_RETURN;
if (query_cache.try_lock())
+ {
+ net->query_cache_query = 0;
DBUG_VOID_RETURN;
+ }
/*
While we were waiting another thread might have changed the status
@@ -909,6 +945,7 @@ void query_cache_abort(NET *net)
net->query_cache_query);
if (query_block)
{
+ thd= current_thd;
thd_proc_info(thd, "storing result in query cache");
DUMP(&query_cache);
BLOCK_LOCK_WR(query_block);
@@ -918,6 +955,7 @@ void query_cache_abort(NET *net)
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
}
+ DBUG_ASSERT(!net->query_cache_query);
query_cache.unlock();
DBUG_VOID_RETURN;
}
@@ -947,8 +985,12 @@ void query_cache_end_of_result(THD *thd)
#endif
if (query_cache.try_lock())
+ {
+ thd->net.query_cache_query= 0;
DBUG_VOID_RETURN;
+ }
+ /* thd->net.query_cache_query may have changed during resize */
query_block= ((Query_cache_block*) thd->net.query_cache_query);
if (query_block)
{
@@ -974,8 +1016,8 @@ void query_cache_end_of_result(THD *thd)
to this function. In the release version that query should be ignored
and removed from QC.
*/
- DBUG_ASSERT(0);
query_cache.free_query(query_block);
+ thd->net.query_cache_query= 0;
query_cache.unlock();
DBUG_VOID_RETURN;
}
@@ -1190,8 +1232,14 @@ def_week_frmt: %lu, in_trans: %d, autoco
A table- or a full flush operation can potentially take a long time to
finish. We choose not to wait for them and skip caching statements
instead.
+
+ In case the wait time can't be determined there is an upper limit which
+ causes try_lock() to abort with a time out.
+
+ The 'TRUE' parameter indicate that the lock is allowed to timeout
+
*/
- if (try_lock())
+ if (try_lock(TRUE))
DBUG_VOID_RETURN;
if (query_cache_size == 0)
{
@@ -1306,8 +1354,8 @@ end:
to the user.
RESULTS
- 1 Query was not cached.
- 0 The query was cached and user was sent the result.
+ 0 Query was not cached.
+ 1 The query was cached and user was sent the result.
-1 The query was cached but we didn't have rights to use it.
No error is sent to the client yet.
@@ -1388,8 +1436,10 @@ Query_cache::send_result_to_client(THD *
Try to obtain an exclusive lock on the query cache. If the cache is
disabled or if a full cache flush is in progress, the attempt to
get the lock is aborted.
+
+ The 'TRUE' parameter indicate that the lock is allowed to timeout
*/
- if (try_lock())
+ if (try_lock(TRUE))
goto err;
if (query_cache_size == 0)
=== modified file 'sql/sql_cache.h'
--- a/sql/sql_cache.h 2009-06-16 08:34:47 +0000
+++ b/sql/sql_cache.h 2009-11-20 12:49:06 +0000
@@ -485,7 +485,7 @@ protected:
const char *name);
my_bool in_blocks(Query_cache_block * point);
- bool try_lock(void);
+ bool try_lock(bool use_timeout= FALSE);
void lock(void);
void lock_and_suspend(void);
void unlock(void);
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2009-12-04 15:12:22 +0000
+++ b/sql/sql_class.cc 2010-01-15 15:27:55 +0000
@@ -379,6 +379,8 @@ char *thd_security_context(THD *thd, cha
str.append(proc_info);
}
+ pthread_mutex_lock(&thd->LOCK_thd_data);
+
if (thd->query())
{
if (max_query_len < 1)
@@ -388,6 +390,9 @@ char *thd_security_context(THD *thd, cha
str.append('\n');
str.append(thd->query(), len);
}
+
+ pthread_mutex_unlock(&thd->LOCK_thd_data);
+
if (str.c_ptr_safe() == buffer)
return buffer;
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2009-12-03 11:34:11 +0000
+++ b/sql/sql_class.h 2010-03-30 12:36:49 +0000
@@ -63,6 +63,7 @@ public:
bool report_error(THD *thd);
bool is_invalidated() const { return m_invalidated; }
void reset_reprepare_observer() { m_invalidated= FALSE; }
+ Reprepare_observer() {} /* Remove gcc warning */
private:
bool m_invalidated;
};
@@ -359,6 +360,7 @@ struct system_variables
ulong ndb_index_stat_cache_entries;
ulong ndb_index_stat_update_freq;
ulong binlog_format; // binlog format for this thd (see enum_binlog_format)
+ my_bool binlog_direct_non_trans_update;
/*
In slave thread we need to know in behalf of which
thread the query is being run to replicate temp tables properly
@@ -558,6 +560,8 @@ public:
{ return state == INITIALIZED_FOR_SP; }
inline bool is_stmt_prepare_or_first_sp_execute() const
{ return (int)state < (int)PREPARED; }
+ inline bool is_stmt_prepare_or_first_stmt_execute() const
+ { return (int)state <= (int)PREPARED; }
inline bool is_first_stmt_execute() const { return state == PREPARED; }
inline bool is_stmt_execute() const
{ return state == PREPARED || state == EXECUTED; }
@@ -1104,6 +1108,7 @@ public:
/* Ignore error */
return TRUE;
}
+ Dummy_error_handler() {} /* Remove gcc warning */
};
@@ -2636,7 +2641,7 @@ public:
{}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- void binlog_show_create_table(TABLE **tables, uint count);
+ int binlog_show_create_table(TABLE **tables, uint count);
void store_values(List<Item> &values);
void send_error(uint errcode,const char *err);
bool send_eof();
=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_connect.cc 2010-03-04 08:03:07 +0000
@@ -474,7 +474,8 @@ check_user(THD *thd, enum enum_server_co
}
}
my_ok(thd);
- thd->password= test(passwd_len); // remember for error messages
+ thd->net.net_skip_rest_factor= 2; // skip at most 2*max_packet_size
+ thd->password= test(passwd_len); // remember for error messages
/* Ready to handle queries */
DBUG_RETURN(0);
}
@@ -709,7 +710,7 @@ static int check_connection(THD *thd)
ulong server_capabilites;
{
/* buff[] needs to big enough to hold the server_version variable */
- char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
+ char buff[SERVER_VERSION_LENGTH + 1 + SCRAMBLE_LENGTH + 1 + 64];
server_capabilites= CLIENT_BASIC_FLAGS;
if (opt_using_transactions)
@@ -798,6 +799,7 @@ static int check_connection(THD *thd)
DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
if (thd->client_capabilities & CLIENT_SSL)
{
+ char error_string[1024];
/* Do the SSL layering. */
if (!ssl_acceptor_fd)
{
@@ -806,7 +808,7 @@ static int check_connection(THD *thd)
return 1;
}
DBUG_PRINT("info", ("IO layer change in progress..."));
- if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
+ if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, error_string))
{
DBUG_PRINT("error", ("Failed to accept new SSL connection"));
inc_host_errors(&thd->remote.sin_addr);
=== modified file 'sql/sql_crypt.cc'
--- a/sql/sql_crypt.cc 2009-09-07 20:50:10 +0000
+++ b/sql/sql_crypt.cc 2010-03-04 08:03:07 +0000
@@ -28,14 +28,7 @@
#include "mysql_priv.h"
-SQL_CRYPT::SQL_CRYPT(const char *password, uint length)
-{
- ulong rand_nr[2];
- hash_password(rand_nr,password, length);
- crypt_init(rand_nr);
-}
-
-void SQL_CRYPT::crypt_init(ulong *rand_nr)
+void SQL_CRYPT::init(ulong *rand_nr)
{
uint i;
my_rnd_init(&rand,rand_nr[0],rand_nr[1]);
=== modified file 'sql/sql_crypt.h'
--- a/sql/sql_crypt.h 2009-09-07 20:50:10 +0000
+++ b/sql/sql_crypt.h 2010-03-04 08:03:07 +0000
@@ -23,15 +23,15 @@ class SQL_CRYPT :public Sql_alloc
struct my_rnd_struct rand,org_rand;
char decode_buff[256],encode_buff[256];
uint shift;
- void crypt_init(ulong *seed);
public:
- SQL_CRYPT(const char *seed, uint length);
+ SQL_CRYPT() {}
SQL_CRYPT(ulong *seed)
{
- crypt_init(seed);
+ init(seed);
}
~SQL_CRYPT() {}
- void init() { shift=0; rand=org_rand; }
+ void init(ulong *seed);
+ void reinit() { shift=0; rand=org_rand; }
void encode(char *str, uint length);
void decode(char *str, uint length);
};
=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_db.cc 2010-03-04 08:03:07 +0000
@@ -178,13 +178,13 @@ uchar* dboptions_get_key(my_dbopt_t *opt
Helper function to write a query to binlog used by mysql_rm_db()
*/
-static inline void write_to_binlog(THD *thd, char *query, uint q_len,
- char *db, uint db_len)
+static inline int write_to_binlog(THD *thd, char *query, uint q_len,
+ char *db, uint db_len)
{
Query_log_event qinfo(thd, query, q_len, 0, 0, 0);
qinfo.db= db;
qinfo.db_len= db_len;
- mysql_bin_log.write(&qinfo);
+ return mysql_bin_log.write(&qinfo);
}
@@ -618,7 +618,7 @@ int mysql_create_db(THD *thd, char *db,
DBUG_ENTER("mysql_create_db");
/* do not create 'information_schema' db */
- if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
+ if (is_schema_db(db))
{
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
DBUG_RETURN(-1);
@@ -695,6 +695,7 @@ int mysql_create_db(THD *thd, char *db,
file. In this case it's best to just continue as if nothing has
happened. (This is a very unlikely senario)
*/
+ thd->clear_error();
}
not_silent:
@@ -746,7 +747,11 @@ not_silent:
qinfo.db_len = strlen(db);
/* These DDL methods and logging protected with LOCK_mysql_create_db */
- mysql_bin_log.write(&qinfo);
+ if (mysql_bin_log.write(&qinfo))
+ {
+ error= -1;
+ goto exit;
+ }
}
my_ok(thd, result);
}
@@ -810,9 +815,9 @@ bool mysql_alter_db(THD *thd, const char
if (mysql_bin_log.is_open())
{
- int errcode= query_error_code(thd, TRUE);
+ thd->clear_error();
Query_log_event qinfo(thd, thd->query(), thd->query_length(), 0,
- /* suppress_use */ TRUE, errcode);
+ /* suppress_use */ TRUE, 0);
/*
Write should use the database being created as the "current
@@ -822,9 +827,9 @@ bool mysql_alter_db(THD *thd, const char
qinfo.db = db;
qinfo.db_len = strlen(db);
- thd->clear_error();
/* These DDL methods and logging protected with LOCK_mysql_create_db */
- mysql_bin_log.write(&qinfo);
+ if ((error= mysql_bin_log.write(&qinfo)))
+ goto exit;
}
my_ok(thd, result);
@@ -962,9 +967,9 @@ bool mysql_rm_db(THD *thd,char *db,bool
}
if (mysql_bin_log.is_open())
{
- int errcode= query_error_code(thd, TRUE);
+ thd->clear_error();
Query_log_event qinfo(thd, query, query_length, 0,
- /* suppress_use */ TRUE, errcode);
+ /* suppress_use */ TRUE, 0);
/*
Write should use the database being created as the "current
database" and not the threads current database, which is the
@@ -973,9 +978,12 @@ bool mysql_rm_db(THD *thd,char *db,bool
qinfo.db = db;
qinfo.db_len = strlen(db);
- thd->clear_error();
/* These DDL methods and logging protected with LOCK_mysql_create_db */
- mysql_bin_log.write(&qinfo);
+ if (mysql_bin_log.write(&qinfo))
+ {
+ error= -1;
+ goto exit;
+ }
}
thd->clear_error();
thd->server_status|= SERVER_STATUS_DB_DROPPED;
@@ -1003,7 +1011,11 @@ bool mysql_rm_db(THD *thd,char *db,bool
if (query_pos + tbl_name_len + 1 >= query_end)
{
/* These DDL methods and logging protected with LOCK_mysql_create_db */
- write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
+ if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
+ {
+ error= -1;
+ goto exit;
+ }
query_pos= query_data_start;
}
@@ -1016,7 +1028,11 @@ bool mysql_rm_db(THD *thd,char *db,bool
if (query_pos != query_data_start)
{
/* These DDL methods and logging protected with LOCK_mysql_create_db */
- write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
+ if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
+ {
+ error= -1;
+ goto exit;
+ }
}
}
@@ -1554,8 +1570,7 @@ bool mysql_change_db(THD *thd, const LEX
}
}
- if (my_strcasecmp(system_charset_info, new_db_name->str,
- INFORMATION_SCHEMA_NAME.str) == 0)
+ if (is_schema_db(new_db_name->str, new_db_name->length))
{
/* Switch the current database to INFORMATION_SCHEMA. */
@@ -1963,7 +1978,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRI
Query_log_event qinfo(thd, thd->query(), thd->query_length(),
0, TRUE, errcode);
thd->clear_error();
- mysql_bin_log.write(&qinfo);
+ error|= mysql_bin_log.write(&qinfo);
}
/* Step9: Let's do "use newdb" if we renamed the current database */
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2009-12-03 11:34:11 +0000
+++ b/sql/sql_delete.cc 2010-03-10 13:55:40 +0000
@@ -335,8 +335,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *
InnoDB it can fail in a FOREIGN KEY error or an
out-of-tablespace error.
*/
- error= 1;
- break;
+ if (!select_lex->no_error)
+ {
+ error= 1;
+ break;
+ }
}
}
else
@@ -426,7 +429,8 @@ cleanup:
}
DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
free_underlaid_joins(thd, select_lex);
- if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
+ if (error < 0 ||
+ (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error))
{
/*
If a TRUNCATE TABLE was issued, the number of rows should be reported as
@@ -849,9 +853,10 @@ void multi_delete::abort()
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query(), thd->query_length(),
- transactional_tables, FALSE, errcode);
+ /* possible error of writing binary log is ignored deliberately */
+ (void) thd->binlog_query(THD::ROW_QUERY_TYPE,
+ thd->query(), thd->query_length(),
+ transactional_tables, FALSE, errcode);
}
thd->transaction.all.modified_non_trans_table= true;
}
@@ -1087,8 +1092,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST
HA_CREATE_INFO create_info;
char path[FN_REFLEN + 1];
TABLE *table;
+ TABLE_LIST *tbl;
bool error;
uint path_length;
+ bool is_temporary_table= false;
DBUG_ENTER("mysql_truncate");
bzero((char*) &create_info,sizeof(create_info));
@@ -1101,9 +1108,14 @@ bool mysql_truncate(THD *thd, TABLE_LIST
{
TABLE_SHARE *share= table->s;
handlerton *table_type= share->db_type();
+ is_temporary_table= true;
+
if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
goto trunc_by_del;
+ for (tbl= table_list; tbl; tbl= tbl->next_local)
+ tbl->deleting= TRUE; /* to trigger HA_PREPARE_FOR_DROP */
+
table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
create_info.options|= HA_LEX_CREATE_TMP_TABLE;
@@ -1166,12 +1178,11 @@ end:
{
if (!error)
{
- /*
- TRUNCATE must always be statement-based binlogged (not row-based) so
- we don't test current_stmt_binlog_row_based.
- */
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
- my_ok(thd); // This should return record count
+ /* In RBR, the statement is not binlogged if the table is temporary. */
+ if (!is_temporary_table || !thd->current_stmt_binlog_row_based)
+ error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ if (!error)
+ my_ok(thd); // This should return record count
}
VOID(pthread_mutex_lock(&LOCK_open));
unlock_table_name(thd, table_list);
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2009-12-04 15:12:22 +0000
+++ b/sql/sql_insert.cc 2010-03-04 08:03:07 +0000
@@ -521,6 +521,22 @@ bool open_and_lock_for_insert_delayed(TH
DBUG_ENTER("open_and_lock_for_insert_delayed");
#ifndef EMBEDDED_LIBRARY
+ if (thd->locked_tables && thd->global_read_lock)
+ {
+ /*
+ If this connection has the global read lock, the handler thread
+ will not be able to lock the table. It will wait for the global
+ read lock to go away, but this will never happen since the
+ connection thread will be stuck waiting for the handler thread
+ to open and lock the table.
+ If we are not in locked tables mode, INSERT will seek protection
+ against the global read lock (and fail), thus we will only get
+ to this point in locked tables mode.
+ */
+ my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+
if (delayed_get_table(thd, table_list))
DBUG_RETURN(TRUE);
@@ -791,12 +807,21 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
restore_record(table,s->default_values); // Get empty record
else
{
+ TABLE_SHARE *share= table->s;
+
/*
Fix delete marker. No need to restore rest of record since it will
be overwritten by fill_record() anyway (and fill_record() does not
use default values in this case).
*/
- table->record[0][0]= table->s->default_values[0];
+ table->record[0][0]= share->default_values[0];
+
+ /* Fix undefined null_bits. */
+ if (share->null_bytes > 1 && share->last_null_bit_pos)
+ {
+ table->record[0][share->null_bytes - 1]=
+ share->default_values[share->null_bytes - 1];
+ }
}
if (fill_record_n_invoke_before_triggers(thd, table->field, *values, 0,
table->triggers,
@@ -2749,10 +2774,11 @@ bool Delayed_insert::handle_inserts(void
will be binlogged together as one single Table_map event and one
single Rows event.
*/
- thd.binlog_query(THD::ROW_QUERY_TYPE,
- row->query.str, row->query.length,
- FALSE, FALSE, errcode);
-
+ if (thd.binlog_query(THD::ROW_QUERY_TYPE,
+ row->query.str, row->query.length,
+ FALSE, FALSE, errcode))
+ goto err;
+
thd.time_zone_used = backup_time_zone_used;
thd.variables.time_zone = backup_time_zone;
}
@@ -2821,8 +2847,9 @@ bool Delayed_insert::handle_inserts(void
TODO: Move the logging to last in the sequence of rows.
*/
- if (thd.current_stmt_binlog_row_based)
- thd.binlog_flush_pending_rows_event(TRUE);
+ if (thd.current_stmt_binlog_row_based &&
+ thd.binlog_flush_pending_rows_event(TRUE))
+ goto err;
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
{ // This shouldn't happen
@@ -3273,16 +3300,21 @@ bool select_insert::send_eof()
events are in the transaction cache and will be written when
ha_autocommit_or_rollback() is issued below.
*/
- if (mysql_bin_log.is_open())
+ if (mysql_bin_log.is_open() &&
+ (!error || thd->transaction.stmt.modified_non_trans_table))
{
int errcode= 0;
if (!error)
thd->clear_error();
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
- thd->binlog_query(THD::ROW_QUERY_TYPE,
+ if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
- trans_table, FALSE, errcode);
+ trans_table, FALSE, errcode))
+ {
+ table->file->ha_release_auto_increment();
+ DBUG_RETURN(1);
+ }
}
table->file->ha_release_auto_increment();
@@ -3351,9 +3383,10 @@ void select_insert::abort() {
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
- thd->query_length(),
- transactional_table, FALSE, errcode);
+ /* error of writing binary log is ignored */
+ (void) thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
+ thd->query_length(),
+ transactional_table, FALSE, errcode);
}
if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
thd->transaction.all.modified_non_trans_table= TRUE;
@@ -3617,7 +3650,8 @@ select_create::prepare(List<Item> &value
!table->s->tmp_table &&
!ptr->get_create_info()->table_existed)
{
- ptr->binlog_show_create_table(tables, count);
+ if (int error= ptr->binlog_show_create_table(tables, count))
+ return error;
}
return 0;
}
@@ -3724,7 +3758,7 @@ select_create::prepare(List<Item> &value
DBUG_RETURN(0);
}
-void
+int
select_create::binlog_show_create_table(TABLE **tables, uint count)
{
/*
@@ -3763,12 +3797,13 @@ select_create::binlog_show_create_table(
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- thd->binlog_query(THD::STMT_QUERY_TYPE,
- query.ptr(), query.length(),
- /* is_trans */ TRUE,
- /* suppress_use */ FALSE,
- errcode);
+ result= thd->binlog_query(THD::STMT_QUERY_TYPE,
+ query.ptr(), query.length(),
+ /* is_trans */ TRUE,
+ /* suppress_use */ FALSE,
+ errcode);
}
+ return result;
}
void select_create::store_values(List<Item> &values)
@@ -3866,7 +3901,8 @@ void select_create::abort()
select_insert::abort();
thd->transaction.stmt.modified_non_trans_table= FALSE;
reenable_binlog(thd);
- thd->binlog_flush_pending_rows_event(TRUE);
+ /* possible error of writing binary log is ignored deliberately */
+ (void)thd->binlog_flush_pending_rows_event(TRUE);
if (m_plock)
{
=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_lex.cc 2010-03-10 10:32:14 +0000
@@ -1842,13 +1842,15 @@ void st_select_lex_unit::exclude_tree()
void st_select_lex::mark_as_dependent(st_select_lex *last, Item *dependency)
{
SELECT_LEX *next_to_last;
+
+ DBUG_ASSERT(this != last);
+
/*
Mark all selects from resolved to 1 before select where was
found table as depended (of select where was found table)
*/
- for (SELECT_LEX *s= this;
- s && s != last;
- s= s->outer_select())
+ SELECT_LEX *s= this;
+ do
{
if (!(s->uncacheable & UNCACHEABLE_DEPENDENT))
{
@@ -1866,7 +1868,8 @@ void st_select_lex::mark_as_dependent(st
}
}
next_to_last= s;
- }
+ } while ((s= s->outer_select()) != last && s != 0);
+
is_correlated= TRUE;
this->master_unit()->item->is_correlated= TRUE;
if (dependency)
=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_load.cc 2010-03-04 08:03:07 +0000
@@ -122,7 +122,7 @@ int mysql_load(THD *thd,sql_exchange *ex
char name[FN_REFLEN];
File file;
TABLE *table= NULL;
- int error;
+ int error= 0;
String *field_term=ex->field_term,*escaped=ex->escaped;
String *enclosed=ex->enclosed;
bool is_fifo=0;
@@ -304,7 +304,8 @@ int mysql_load(THD *thd,sql_exchange *ex
else
{
(void) fn_format(name, ex->file_name, mysql_real_data_home, "",
- MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
+ MY_RELATIVE_PATH | MY_UNPACK_FILENAME |
+ MY_RETURN_REAL_PATH);
#if !defined(__WIN__) && ! defined(__NETWARE__)
MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(MY_WME)))
@@ -347,12 +348,16 @@ int mysql_load(THD *thd,sql_exchange *ex
DBUG_ASSERT(FALSE);
#endif
}
- else if (opt_secure_file_priv &&
- strncmp(opt_secure_file_priv, name, strlen(opt_secure_file_priv)))
+ else if (opt_secure_file_priv)
{
- /* Read only allowed from within dir specified by secure_file_priv */
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
- DBUG_RETURN(TRUE);
+ char secure_file_real_path[FN_REFLEN];
+ (void) my_realpath(secure_file_real_path, opt_secure_file_priv, 0);
+ if (strncmp(secure_file_real_path, name, strlen(secure_file_real_path)))
+ {
+ /* Read only allowed from within dir specified by secure_file_priv */
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
+ DBUG_RETURN(TRUE);
+ }
}
}
@@ -499,18 +504,20 @@ int mysql_load(THD *thd,sql_exchange *ex
{
int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ /* since there is already an error, the possible error of
+ writing binary log will be ignored */
if (thd->transaction.stmt.modified_non_trans_table)
- write_execute_load_query_log_event(thd, ex,
- table_list->db,
- table_list->table_name,
- handle_duplicates, ignore,
- transactional_table,
- errcode);
+ (void) write_execute_load_query_log_event(thd, ex,
+ table_list->db,
+ table_list->table_name,
+ handle_duplicates, ignore,
+ transactional_table,
+ errcode);
else
{
Delete_file_log_event d(thd, db, transactional_table);
d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
- mysql_bin_log.write(&d);
+ (void) mysql_bin_log.write(&d);
}
}
}
@@ -536,7 +543,7 @@ int mysql_load(THD *thd,sql_exchange *ex
after this point.
*/
if (thd->current_stmt_binlog_row_based)
- thd->binlog_flush_pending_rows_event(true);
+ error= thd->binlog_flush_pending_rows_event(true);
else
{
/*
@@ -548,13 +555,15 @@ int mysql_load(THD *thd,sql_exchange *ex
if (lf_info.wrote_create_file)
{
int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
- write_execute_load_query_log_event(thd, ex,
- table_list->db, table_list->table_name,
- handle_duplicates, ignore,
- transactional_table,
- errcode);
+ error= write_execute_load_query_log_event(thd, ex,
+ table_list->db, table_list->table_name,
+ handle_duplicates, ignore,
+ transactional_table,
+ errcode);
}
}
+ if (error)
+ goto err;
}
#endif /*!EMBEDDED_LIBRARY*/
@@ -635,7 +644,11 @@ static bool write_execute_load_query_log
if (n++)
pfields.append(", ");
if (item->name)
+ {
+ pfields.append("`");
pfields.append(item->name);
+ pfields.append("`");
+ }
else
item->print(&pfields, QT_ORDINARY);
}
@@ -655,7 +668,9 @@ static bool write_execute_load_query_log
val= lv++;
if (n++)
pfields.append(", ");
+ pfields.append("`");
pfields.append(item->name);
+ pfields.append("`");
pfields.append("=");
val->print(&pfields, QT_ORDINARY);
}
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2009-12-03 11:34:11 +0000
+++ b/sql/sql_parse.cc 2010-03-04 08:03:07 +0000
@@ -626,8 +626,10 @@ void free_items(Item *item)
DBUG_VOID_RETURN;
}
-/* This works because items are allocated with sql_alloc() */
-
+/**
+ This works because items are allocated with sql_alloc().
+ @note The function also handles null pointers (empty list).
+*/
void cleanup_items(Item *item)
{
DBUG_ENTER("cleanup_items");
@@ -1252,12 +1254,14 @@ bool dispatch_command(enum enum_server_c
ha_maria::implicit_commit(thd, FALSE);
#endif
- net_end_statement(thd);
- query_cache_end_of_result(thd);
/*
Multiple queries exits, execute them individually
*/
close_thread_tables(thd);
+
+ net_end_statement(thd);
+ query_cache_end_of_result(thd);
+
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
log_slow_statement(thd);
@@ -1321,8 +1325,7 @@ bool dispatch_command(enum enum_server_c
table_list.alias= table_list.table_name= conv_name.str;
packet= arg_end + 1;
- if (!my_strcasecmp(system_charset_info, table_list.db,
- INFORMATION_SCHEMA_NAME.str))
+ if (is_schema_db(table_list.db, table_list.db_length))
{
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
if (schema_table)
@@ -1384,7 +1387,7 @@ bool dispatch_command(enum enum_server_c
break;
}
if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
- is_schema_db(db.str)))
+ is_schema_db(db.str, db.length)))
break;
general_log_print(thd, command, "%.*s", db.length, db.str);
bzero(&create_info, sizeof(create_info));
@@ -1403,7 +1406,8 @@ bool dispatch_command(enum enum_server_c
my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
break;
}
- if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str)))
+ if (check_access(thd, DROP_ACL, db.str, 0, 1, 0,
+ is_schema_db(db.str, db.length)))
break;
if (thd->locked_tables || thd->active_transaction())
{
@@ -1645,13 +1649,22 @@ bool dispatch_command(enum enum_server_c
ha_maria::implicit_commit(thd, FALSE);
#endif
- net_end_statement(thd);
- query_cache_end_of_result(thd);
-
+ if (!(sql_command_flags[thd->lex->sql_command] & CF_CHANGES_DATA))
+ {
+ /* No changes in data; We can send ok at once to the client */
+ net_end_statement(thd);
+ query_cache_end_of_result(thd);
+ }
thd->proc_info= "closing tables";
/* Free tables */
close_thread_tables(thd);
+ if (sql_command_flags[thd->lex->sql_command] & CF_CHANGES_DATA)
+ {
+ net_end_statement(thd);
+ query_cache_end_of_result(thd);
+ }
+
log_slow_statement(thd);
thd_proc_info(thd, "cleaning up");
@@ -2699,6 +2712,8 @@ mysql_execute_command(THD *thd)
{
lex->link_first_table_back(create_table, link_to_local);
create_table->create= TRUE;
+ /* Base table and temporary table are not in the same name space. */
+ create_table->skip_temporary= 1;
}
if (!(res= open_and_lock_tables(thd, lex->query_tables)))
@@ -3030,7 +3045,7 @@ end_with_restore_list:
/*
Presumably, REPAIR and binlog writing doesn't require synchronization
*/
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
@@ -3064,7 +3079,7 @@ end_with_restore_list:
/*
Presumably, ANALYZE and binlog writing doesn't require synchronization
*/
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
@@ -3088,7 +3103,7 @@ end_with_restore_list:
/*
Presumably, OPTIMIZE and binlog writing doesn't require synchronization
*/
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
@@ -3205,7 +3220,7 @@ end_with_restore_list:
if (incident)
{
Incident_log_event ev(thd, incident);
- mysql_bin_log.write(&ev);
+ (void) mysql_bin_log.write(&ev); /* error is ignored */
mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
}
DBUG_PRINT("debug", ("Just after generate_incident()"));
@@ -3398,9 +3413,9 @@ end_with_restore_list:
select_lex->where,
0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
(ORDER *)NULL,
- select_lex->options | thd->options |
+ (select_lex->options | thd->options |
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
- OPTION_SETUP_TABLES_DONE,
+ OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
del_result, unit, select_lex);
res|= thd->is_error();
if (res)
@@ -3423,17 +3438,6 @@ end_with_restore_list:
}
else
{
- /*
- If this is a slave thread, we may sometimes execute some
- DROP / * 40005 TEMPORARY * / TABLE
- that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
- MASTER TO), while the temporary table has already been dropped.
- To not generate such irrelevant "table does not exist errors",
- we silently add IF EXISTS if TEMPORARY was used.
- */
- if (thd->slave_thread)
- lex->drop_if_exists= 1;
-
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
thd->options|= OPTION_KEEP_LOG;
}
@@ -3647,7 +3651,7 @@ end_with_restore_list:
}
#endif
if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
- is_schema_db(lex->name.str)))
+ is_schema_db(lex->name.str, lex->name.length)))
break;
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
lex->name.str), &create_info, 0);
@@ -3682,7 +3686,7 @@ end_with_restore_list:
}
#endif
if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
- is_schema_db(lex->name.str)))
+ is_schema_db(lex->name.str, lex->name.length)))
break;
if (thd->locked_tables || thd->active_transaction())
{
@@ -3716,9 +3720,12 @@ end_with_restore_list:
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
break;
}
- if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)) ||
- check_access(thd, DROP_ACL, db->str, 0, 1, 0, is_schema_db(db->str)) ||
- check_access(thd, CREATE_ACL, db->str, 0, 1, 0, is_schema_db(db->str)))
+ if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
+ is_schema_db(db->str, db->length)) ||
+ check_access(thd, DROP_ACL, db->str, 0, 1, 0,
+ is_schema_db(db->str, db->length)) ||
+ check_access(thd, CREATE_ACL, db->str, 0, 1, 0,
+ is_schema_db(db->str, db->length)))
{
res= 1;
break;
@@ -3761,7 +3768,8 @@ end_with_restore_list:
break;
}
#endif
- if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)))
+ if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
+ is_schema_db(db->str, db->length)))
break;
if (thd->locked_tables || thd->active_transaction())
{
@@ -3917,7 +3925,8 @@ end_with_restore_list:
first_table ? &first_table->grant.privilege : 0,
first_table ? 0 : 1, 0,
first_table ? (bool) first_table->schema_table :
- select_lex->db ? is_schema_db(select_lex->db) : 0))
+ select_lex->db ?
+ is_schema_db(select_lex->db) : 0))
goto error;
if (thd->security_ctx->user) // If not replication
@@ -4040,7 +4049,8 @@ end_with_restore_list:
*/
if (!lex->no_write_to_binlog && write_to_binlog)
{
- write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ if ((res= write_bin_log(thd, FALSE, thd->query(), thd->query_length())))
+ break;
}
my_ok(thd);
}
@@ -4260,7 +4270,8 @@ end_with_restore_list:
}
if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0,
- is_schema_db(lex->sphead->m_db.str)))
+ is_schema_db(lex->sphead->m_db.str,
+ lex->sphead->m_db.length)))
goto create_sp_error;
if (end_active_trans(thd))
@@ -4617,12 +4628,12 @@ create_sp_error:
case SP_KEY_NOT_FOUND:
if (lex->drop_if_exists)
{
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
SP_COM_STRING(lex), lex->spname->m_name.str);
- res= FALSE;
- my_ok(thd);
+ if (!res)
+ my_ok(thd);
break;
}
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
@@ -4915,7 +4926,8 @@ create_sp_error:
res= mysql_xa_recover(thd);
break;
case SQLCOM_ALTER_TABLESPACE:
- if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0, thd->db ? is_schema_db(thd->db) : 0))
+ if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0,
+ thd->db ? is_schema_db(thd->db, thd->db_length) : 0))
break;
if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
my_ok(thd);
@@ -6321,8 +6333,7 @@ TABLE_LIST *st_select_lex::add_table_to_
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
ptr->derived= table->sel;
- if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
- INFORMATION_SCHEMA_NAME.str))
+ if (!ptr->derived && is_schema_db(ptr->db, ptr->db_length))
{
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
if (!schema_table ||
@@ -6850,13 +6861,13 @@ bool reload_acl_and_cache(THD *thd, ulon
thd->store_globals();
lex_start(thd);
}
-
+
if (thd)
{
bool reload_acl_failed= acl_reload(thd);
bool reload_grants_failed= grant_reload(thd);
bool reload_servers_failed= servers_reload(thd);
-
+
if (reload_acl_failed || reload_grants_failed || reload_servers_failed)
{
result= 1;
@@ -7012,7 +7023,10 @@ bool reload_acl_and_cache(THD *thd, ulon
if (options & REFRESH_USER_RESOURCES)
reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
*write_to_binlog= tmp_write_to_binlog;
- return result;
+ /*
+ If the query was killed then this function must fail.
+ */
+ return result || (thd ? thd->killed : 0);
}
@@ -7632,6 +7646,9 @@ void get_default_definer(THD *thd, LEX_U
definer->host.str= (char *) sctx->priv_host;
definer->host.length= strlen(definer->host.str);
+
+ definer->password.str= NULL;
+ definer->password.length= 0;
}
@@ -7683,6 +7700,8 @@ LEX_USER *create_definer(THD *thd, LEX_S
definer->user= *user_name;
definer->host= *host_name;
+ definer->password.str= NULL;
+ definer->password.length= 0;
return definer;
}
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_partition.cc 2010-03-09 15:03:54 +0000
@@ -196,26 +196,27 @@ bool partition_default_handling(TABLE *t
{
DBUG_ENTER("partition_default_handling");
- if (part_info->use_default_no_partitions)
+ if (!is_create_table_ind)
{
- if (!is_create_table_ind &&
- table->file->get_no_parts(normalized_path, &part_info->no_parts))
+ if (part_info->use_default_no_partitions)
{
- DBUG_RETURN(TRUE);
+ if (table->file->get_no_parts(normalized_path, &part_info->no_parts))
+ {
+ DBUG_RETURN(TRUE);
+ }
}
- }
- else if (part_info->is_sub_partitioned() &&
- part_info->use_default_no_subpartitions)
- {
- uint no_parts;
- if (!is_create_table_ind &&
- (table->file->get_no_parts(normalized_path, &no_parts)))
+ else if (part_info->is_sub_partitioned() &&
+ part_info->use_default_no_subpartitions)
{
- DBUG_RETURN(TRUE);
+ uint no_parts;
+ if (table->file->get_no_parts(normalized_path, &no_parts))
+ {
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_ASSERT(part_info->no_parts > 0);
+ DBUG_ASSERT((no_parts % part_info->no_parts) == 0);
+ part_info->no_subparts= no_parts / part_info->no_parts;
}
- DBUG_ASSERT(part_info->no_parts > 0);
- part_info->no_subparts= no_parts / part_info->no_parts;
- DBUG_ASSERT((no_parts % part_info->no_parts) == 0);
}
part_info->set_up_defaults_for_partitioning(table->file,
(ulonglong)0, (uint)0);
@@ -869,6 +870,8 @@ int check_signed_flag(partition_info *pa
part_info Reference to partitioning data structure
is_sub_part Is the table subpartitioned as well
is_field_to_be_setup Flag if we are to set-up field arrays
+ is_create_table_ind Indicator of whether openfrm was called as part of
+ CREATE or ALTER TABLE
RETURN VALUE
TRUE An error occurred, something was wrong with the
@@ -891,8 +894,9 @@ int check_signed_flag(partition_info *pa
on the field object.
*/
-bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
- bool is_sub_part, bool is_field_to_be_setup)
+static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
+ bool is_sub_part, bool is_field_to_be_setup,
+ bool is_create_table_ind)
{
partition_info *part_info= table->part_info;
uint dir_length, home_dir_length;
@@ -905,6 +909,8 @@ bool fix_fields_part_func(THD *thd, Item
char* db_name;
char db_name_string[FN_REFLEN];
bool save_use_only_table_context;
+ uint8 saved_full_group_by_flag;
+ nesting_map saved_allow_sum_func;
DBUG_ENTER("fix_fields_part_func");
if (part_info->fixed)
@@ -974,9 +980,19 @@ bool fix_fields_part_func(THD *thd, Item
save_use_only_table_context= thd->lex->use_only_table_context;
thd->lex->use_only_table_context= TRUE;
thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
+ saved_full_group_by_flag= thd->lex->current_select->full_group_by_flag;
+ saved_allow_sum_func= thd->lex->allow_sum_func;
+ thd->lex->allow_sum_func= 0;
error= func_expr->fix_fields(thd, (Item**)&func_expr);
+ /*
+ Restore full_group_by_flag and allow_sum_func,
+ fix_fields should not affect mysql_select later, see Bug#46923.
+ */
+ thd->lex->current_select->full_group_by_flag= saved_full_group_by_flag;
+ thd->lex->allow_sum_func= saved_allow_sum_func;
+
thd->lex->use_only_table_context= save_use_only_table_context;
context->table_list= save_table_list;
@@ -992,10 +1008,31 @@ bool fix_fields_part_func(THD *thd, Item
thd->where= save_where;
if (unlikely(func_expr->const_item()))
{
- my_error(ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
+ my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
clear_field_flag(table);
goto end;
}
+
+ /*
+ We don't allow creating partitions with timezone-dependent expressions as
+ a (sub)partitioning function, but we want to allow such expressions when
+ opening existing tables for easier maintenance. This exception should be
+ deprecated at some point in future so that we always throw an error.
+ */
+ if (func_expr->walk(&Item::is_timezone_dependent_processor,
+ 0, NULL))
+ {
+ if (is_create_table_ind)
+ {
+ my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
+ goto end;
+ }
+ else
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR,
+ ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
+ }
+
if ((!is_sub_part) && (error= check_signed_flag(part_info)))
goto end;
result= FALSE;
@@ -1603,7 +1640,8 @@ bool fix_partition_func(THD *thd, TABLE
else
{
if (unlikely(fix_fields_part_func(thd, part_info->subpart_expr,
- table, TRUE, TRUE)))
+ table, TRUE, TRUE,
+ is_create_table_ind)))
goto end;
if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT))
{
@@ -1631,7 +1669,8 @@ bool fix_partition_func(THD *thd, TABLE
else
{
if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
- table, FALSE, TRUE)))
+ table, FALSE, TRUE,
+ is_create_table_ind)))
goto end;
if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
{
@@ -1645,7 +1684,8 @@ bool fix_partition_func(THD *thd, TABLE
{
const char *error_str;
if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
- table, FALSE, TRUE)))
+ table, FALSE, TRUE,
+ is_create_table_ind)))
goto end;
if (part_info->part_type == RANGE_PARTITION)
{
@@ -1679,7 +1719,7 @@ bool fix_partition_func(THD *thd, TABLE
if (((part_info->part_type != HASH_PARTITION ||
part_info->list_of_part_fields == FALSE) &&
check_part_func_fields(part_info->part_field_array, TRUE)) ||
- (part_info->list_of_part_fields == FALSE &&
+ (part_info->list_of_subpart_fields == FALSE &&
part_info->is_sub_partitioned() &&
check_part_func_fields(part_info->subpart_field_array, TRUE)))
{
@@ -2838,16 +2878,13 @@ int get_partition_id_range(partition_inf
part_func_value-= 0x8000000000000000ULL;
while (max_part_id > min_part_id)
{
- loc_part_id= (max_part_id + min_part_id + 1) >> 1;
+ loc_part_id= (max_part_id + min_part_id) / 2;
if (range_array[loc_part_id] <= part_func_value)
min_part_id= loc_part_id + 1;
else
- max_part_id= loc_part_id - 1;
+ max_part_id= loc_part_id;
}
loc_part_id= max_part_id;
- if (part_func_value >= range_array[loc_part_id])
- if (loc_part_id != max_partition)
- loc_part_id++;
*part_id= (uint32)loc_part_id;
if (loc_part_id == max_partition &&
part_func_value >= range_array[loc_part_id] &&
@@ -2921,6 +2958,7 @@ uint32 get_partition_id_range_for_endpoi
bool include_endpoint)
{
longlong *range_array= part_info->range_int_array;
+ longlong part_end_val;
uint max_partition= part_info->no_parts - 1;
uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
/* Get the partitioning function value for the endpoint */
@@ -2954,46 +2992,46 @@ uint32 get_partition_id_range_for_endpoi
}
}
-
if (unsigned_flag)
part_func_value-= 0x8000000000000000ULL;
if (left_endpoint && !include_endpoint)
part_func_value++;
+
+ /*
+ Search for the partition containing part_func_value
+ (including the right endpoint).
+ */
while (max_part_id > min_part_id)
{
- loc_part_id= (max_part_id + min_part_id + 1) >> 1;
- if (range_array[loc_part_id] <= part_func_value)
+ loc_part_id= (max_part_id + min_part_id) / 2;
+ if (range_array[loc_part_id] < part_func_value)
min_part_id= loc_part_id + 1;
else
- max_part_id= loc_part_id - 1;
+ max_part_id= loc_part_id;
}
loc_part_id= max_part_id;
- if (loc_part_id < max_partition &&
- part_func_value >= range_array[loc_part_id+1])
- {
- loc_part_id++;
- }
+
+ /* Adjust for endpoints */
+ part_end_val= range_array[loc_part_id];
if (left_endpoint)
{
- longlong bound= range_array[loc_part_id];
/*
In case of PARTITION p VALUES LESS THAN MAXVALUE
the maximum value is in the current partition.
*/
- if (part_func_value > bound ||
- (part_func_value == bound &&
- (!part_info->defined_max_value || loc_part_id < max_partition)))
+ if (part_func_value > part_end_val ||
+ (part_func_value == part_end_val &&
+ (loc_part_id < max_partition || !part_info->defined_max_value)))
loc_part_id++;
}
else
{
- if (loc_part_id < max_partition)
- {
- if (part_func_value == range_array[loc_part_id])
- loc_part_id += test(include_endpoint);
- else if (part_func_value > range_array[loc_part_id])
- loc_part_id++;
- }
+ /* if 'WHERE <= X' and partition is LESS THAN (X) include next partition */
+ if (include_endpoint && loc_part_id < max_partition &&
+ part_func_value == part_end_val)
+ loc_part_id++;
+
+ /* Right endpoint, set end after correct partition */
loc_part_id++;
}
DBUG_RETURN(loc_part_id);
@@ -4076,8 +4114,9 @@ static int fast_end_partition(THD *thd,
}
if ((!is_empty) && (!written_bin_log) &&
- (!thd->lex->no_write_to_binlog))
- write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ (!thd->lex->no_write_to_binlog) &&
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length()))
+ DBUG_RETURN(TRUE);
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
(ulong) (copied + deleted),
@@ -5668,8 +5707,7 @@ static bool write_log_drop_partition(ALT
part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path) - 1, lpt->db,
lpt->table_name, "", 0);
- build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db,
- lpt->table_name, "#", 0);
+ build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE))
@@ -5725,8 +5763,7 @@ static bool write_log_add_change_partiti
build_table_filename(path, sizeof(path) - 1, lpt->db,
lpt->table_name, "", 0);
- build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db,
- lpt->table_name, "#", 0);
+ build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE))
@@ -5951,7 +5988,7 @@ void handle_alter_part_error(ALTER_PARTI
partition_info *part_info= lpt->part_info;
DBUG_ENTER("handle_alter_part_error");
- if (!part_info->first_log_entry &&
+ if (part_info->first_log_entry &&
execute_ddl_log_entry(current_thd,
part_info->first_log_entry->entry_pos))
{
=== modified file 'sql/sql_partition.h'
--- a/sql/sql_partition.h 2007-11-20 10:21:00 +0000
+++ b/sql/sql_partition.h 2009-12-13 20:29:50 +0000
@@ -91,9 +91,6 @@ uint32 get_list_array_idx_for_endpoint(p
uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
bool left_endpoint,
bool include_endpoint);
-bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
- bool is_sub_part, bool is_field_to_be_setup);
-
bool check_part_func_fields(Field **ptr, bool ok_with_charsets);
bool field_is_partition_charset(Field *field);
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2009-12-22 10:33:20 +0000
+++ b/sql/sql_plugin.cc 2010-03-12 19:05:21 +0000
@@ -19,14 +19,6 @@
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
-#ifdef DBUG_OFF
-#define plugin_ref_to_int(A) A
-#define plugin_int_to_ref(A) A
-#else
-#define plugin_ref_to_int(A) (A ? A[0] : NULL)
-#define plugin_int_to_ref(A) &(A)
-#endif
-
extern struct st_mysql_plugin *mysqld_builtins[];
/**
@@ -341,7 +333,7 @@ static inline void free_plugin_mem(struc
dlclose(p->handle);
#endif
my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR));
- if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION)
+ if (p->allocated)
my_free((uchar*)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
}
@@ -462,33 +454,37 @@ static st_plugin_dl *plugin_dl_add(const
#endif
}
- for (i= 0;
- ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- /* no op */;
-
- cur= (struct st_mysql_plugin*)
- my_malloc(i*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
- if (!cur)
+ if (sizeof_st_plugin != sizeof(st_mysql_plugin))
{
- free_plugin_mem(&plugin_dl);
- if (report & REPORT_TO_USER)
- my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
- if (report & REPORT_TO_LOG)
- sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
- DBUG_RETURN(0);
- }
- /*
- All st_plugin fields not initialized in the plugin explicitly, are
- set to 0. It matches C standard behaviour for struct initializers that
- have less values than the struct definition.
- */
- for (i=0;
- (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
+ for (i= 0;
+ ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_mysql_plugin*)
+ my_malloc((i+1)*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(&plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
+ DBUG_RETURN(0);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
- sym= cur;
+ sym= cur;
+ plugin_dl.allocated= true;
+ }
}
plugin_dl.plugins= (struct st_mysql_plugin *)sym;
@@ -630,7 +626,10 @@ static plugin_ref intern_plugin_lock(LEX
{
plugin_ref plugin;
#ifdef DBUG_OFF
- /* built-in plugins don't need ref counting */
+ /*
+ In optimized builds we don't do reference counting for built-in
+ (plugin->plugin_dl == 0) plugins.
+ */
if (!pi->plugin_dl)
DBUG_RETURN(pi);
@@ -658,13 +657,33 @@ static plugin_ref intern_plugin_lock(LEX
}
-plugin_ref plugin_lock(THD *thd, plugin_ref *ptr CALLER_INFO_PROTO)
+plugin_ref plugin_lock(THD *thd, plugin_ref ptr CALLER_INFO_PROTO)
{
LEX *lex= thd ? thd->lex : 0;
plugin_ref rc;
DBUG_ENTER("plugin_lock");
+
+#ifdef DBUG_OFF
+ /*
+ In optimized builds we don't do reference counting for built-in
+ (plugin->plugin_dl == 0) plugins.
+
+ Note that we access plugin->plugin_dl outside of LOCK_plugin, and for
+ dynamic plugins a 'plugin' could correspond to plugin that was unloaded
+ meanwhile! But because st_plugin_int is always allocated on
+ plugin_mem_root, the pointer can never be invalid - the memory is never
+ freed.
+ Of course, the memory that 'plugin' points to can be overwritten by
+ another plugin being loaded, but plugin->plugin_dl can never change
+ from zero to non-zero or vice versa.
+ That is, it's always safe to check for plugin->plugin_dl==0 even
+ without a mutex.
+ */
+ if (! plugin_dlib(ptr))
+ DBUG_RETURN(ptr);
+#endif
pthread_mutex_lock(&LOCK_plugin);
- rc= my_intern_plugin_lock_ci(lex, *ptr);
+ rc= my_intern_plugin_lock_ci(lex, ptr);
pthread_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(rc);
}
@@ -2085,7 +2104,7 @@ static int check_func_set(THD *thd, stru
&error, &error_len, ¬_used);
if (error_len)
{
- strmake(buff, error, min(sizeof(buff), error_len));
+ strmake(buff, error, min(sizeof(buff) - 1, error_len));
strvalue= buff;
goto err;
}
=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h 2009-05-14 12:03:33 +0000
+++ b/sql/sql_plugin.h 2010-03-12 19:05:21 +0000
@@ -63,7 +63,8 @@ struct st_plugin_dl
LEX_STRING dl;
void *handle;
struct st_mysql_plugin *plugins;
- int version;
+ int version;
+ bool allocated;
uint ref_count; /* number of plugins loaded from the library */
};
@@ -89,6 +90,8 @@ struct st_plugin_int
*/
#ifdef DBUG_OFF
typedef struct st_plugin_int *plugin_ref;
+#define plugin_ref_to_int(A) A
+#define plugin_int_to_ref(A) A
#define plugin_decl(pi) ((pi)->plugin)
#define plugin_dlib(pi) ((pi)->plugin_dl)
#define plugin_data(pi,cast) ((cast)((pi)->data))
@@ -97,6 +100,8 @@ typedef struct st_plugin_int *plugin_ref
#define plugin_equals(p1,p2) ((p1) == (p2))
#else
typedef struct st_plugin_int **plugin_ref;
+#define plugin_ref_to_int(A) (A ? A[0] : NULL)
+#define plugin_int_to_ref(A) &(A)
#define plugin_decl(pi) ((pi)[0]->plugin)
#define plugin_dlib(pi) ((pi)[0]->plugin_dl)
#define plugin_data(pi,cast) ((cast)((pi)[0]->data))
@@ -120,7 +125,7 @@ extern bool plugin_is_ready(const LEX_ST
#define my_plugin_lock_by_name_ci(A,B,C) plugin_lock_by_name(A,B,C ORIG_CALLER_INFO)
#define my_plugin_lock(A,B) plugin_lock(A,B CALLER_INFO)
#define my_plugin_lock_ci(A,B) plugin_lock(A,B ORIG_CALLER_INFO)
-extern plugin_ref plugin_lock(THD *thd, plugin_ref *ptr CALLER_INFO_PROTO);
+extern plugin_ref plugin_lock(THD *thd, plugin_ref ptr CALLER_INFO_PROTO);
extern plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name,
int type CALLER_INFO_PROTO);
extern void plugin_unlock(THD *thd, plugin_ref plugin);
=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_prepare.cc 2010-03-04 08:03:07 +0000
@@ -1600,6 +1600,8 @@ static bool mysql_test_create_table(Prep
{
lex->link_first_table_back(create_table, link_to_local);
create_table->create= TRUE;
+ /* Base table and temporary table are not in the same name space. */
+ create_table->skip_temporary= true;
}
if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0))
=== modified file 'sql/sql_profile.cc'
--- a/sql/sql_profile.cc 2009-10-15 21:38:29 +0000
+++ b/sql/sql_profile.cc 2010-01-29 18:42:22 +0000
@@ -131,6 +131,23 @@ int make_profile_table_for_show(THD *thd
#define RUSAGE_USEC(tv) ((tv).tv_sec*1000*1000 + (tv).tv_usec)
#define RUSAGE_DIFF_USEC(tv1, tv2) (RUSAGE_USEC((tv1))-RUSAGE_USEC((tv2)))
+#ifdef __WIN__
+inline ULONGLONG FileTimeToQuadWord(FILETIME *ft)
+{
+ ULONGLONG nrv = 0;
+ nrv |= ft->dwHighDateTime;
+ nrv <<= 32;
+ nrv |= ft->dwLowDateTime;
+ return nrv;
+}
+
+
+// Get time difference between to FILETIME objects in seconds.
+inline double GetTimeDiffInSeconds(FILETIME *a, FILETIME *b)
+{
+ return ((FileTimeToQuadWord(a) - FileTimeToQuadWord(b)) / 1e7);
+}
+#endif /* __WIN__ */
PROF_MEASUREMENT::PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char
*status_arg)
@@ -221,6 +238,11 @@ void PROF_MEASUREMENT::collect()
time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */
#ifdef HAVE_GETRUSAGE
getrusage(RUSAGE_SELF, &rusage);
+#elif defined(__WIN__)
+ FILETIME ftDummy;
+ GetProcessTimes(GetCurrentProcess(), &ftDummy, &ftDummy, &ftKernel, &ftUser);
+ GetProcessIoCounters(GetCurrentProcess(), &io_count);
+ GetProcessMemoryInfo(GetCurrentProcess(), &mem_count, sizeof(mem_count));
#endif
}
@@ -590,6 +612,23 @@ int PROFILING::fill_statistics_info(THD
table->field[5]->store_decimal(&cpu_stime_decimal);
table->field[4]->set_notnull();
table->field[5]->set_notnull();
+#elif defined(__WIN__)
+ my_decimal cpu_utime_decimal, cpu_stime_decimal;
+
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ GetTimeDiffInSeconds(&entry->ftUser,
+ &previous->ftUser),
+ &cpu_utime_decimal);
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ GetTimeDiffInSeconds(&entry->ftKernel,
+ &previous->ftKernel),
+ &cpu_stime_decimal);
+
+ // Store the result.
+ table->field[4]->store_decimal(&cpu_utime_decimal);
+ table->field[5]->store_decimal(&cpu_stime_decimal);
+ table->field[4]->set_notnull();
+ table->field[5]->set_notnull();
#else
/* TODO: Add CPU-usage info for non-BSD systems */
#endif
@@ -612,6 +651,17 @@ int PROFILING::fill_statistics_info(THD
table->field[9]->store((uint32)(entry->rusage.ru_oublock -
previous->rusage.ru_oublock));
table->field[9]->set_notnull();
+#elif defined(__WIN__)
+ ULONGLONG reads_delta = entry->io_count.ReadOperationCount -
+ previous->io_count.ReadOperationCount;
+ ULONGLONG writes_delta = entry->io_count.WriteOperationCount -
+ previous->io_count.WriteOperationCount;
+
+ table->field[8]->store((uint32)reads_delta);
+ table->field[8]->set_notnull();
+
+ table->field[9]->store((uint32)writes_delta);
+ table->field[9]->set_notnull();
#else
/* TODO: Add block IO info for non-BSD systems */
#endif
@@ -634,6 +684,13 @@ int PROFILING::fill_statistics_info(THD
table->field[13]->store((uint32)(entry->rusage.ru_minflt -
previous->rusage.ru_minflt), true);
table->field[13]->set_notnull();
+#elif defined(__WIN__)
+ /* Windows APIs don't easily distinguish between hard and soft page
+ faults, so we just fill the 'major' column and leave the second NULL.
+ */
+ table->field[12]->store((uint32)(entry->mem_count.PageFaultCount -
+ previous->mem_count.PageFaultCount), true);
+ table->field[12]->set_notnull();
#else
/* TODO: Add page fault info for non-BSD systems */
#endif
=== modified file 'sql/sql_profile.h'
--- a/sql/sql_profile.h 2009-09-07 20:50:10 +0000
+++ b/sql/sql_profile.h 2010-01-29 18:42:22 +0000
@@ -36,6 +36,10 @@ int make_profile_table_for_show(THD *thd
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
#include "mysql_priv.h"
+#ifdef __WIN__
+#include <psapi.h>
+#endif
+
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
@@ -165,6 +169,10 @@ private:
char *status;
#ifdef HAVE_GETRUSAGE
struct rusage rusage;
+#elif defined(__WIN__)
+ FILETIME ftKernel, ftUser;
+ IO_COUNTERS io_count;
+ PROCESS_MEMORY_COUNTERS mem_count;
#endif
char *function;
=== modified file 'sql/sql_rename.cc'
--- a/sql/sql_rename.cc 2009-10-16 10:29:42 +0000
+++ b/sql/sql_rename.cc 2010-01-24 07:03:23 +0000
@@ -34,6 +34,7 @@ static TABLE_LIST *reverse_table_list(TA
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
{
bool error= 1;
+ bool binlog_error= 0;
TABLE_LIST *ren_table= 0;
int to_table;
char *rename_log_table[2]= {NULL, NULL};
@@ -174,11 +175,11 @@ bool mysql_rename_tables(THD *thd, TABLE
*/
pthread_mutex_unlock(&LOCK_open);
- /* Lets hope this doesn't fail as the result will be messy */
if (!silent && !error)
{
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
- my_ok(thd);
+ binlog_error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ if (!binlog_error)
+ my_ok(thd);
}
if (!error)
@@ -190,7 +191,7 @@ bool mysql_rename_tables(THD *thd, TABLE
err:
start_waiting_global_read_lock(thd);
- DBUG_RETURN(error);
+ DBUG_RETURN(error || binlog_error);
}
=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_repl.cc 2010-03-04 08:03:07 +0000
@@ -711,11 +711,14 @@ impossible position";
thd_proc_info(thd, "Finished reading one binlog; switching to next binlog");
switch (mysql_bin_log.find_next_log(&linfo, 1)) {
- case LOG_INFO_EOF:
- loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
- break;
case 0:
break;
+ case LOG_INFO_EOF:
+ if (mysql_bin_log.is_active(log_file_name))
+ {
+ loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
+ break;
+ }
default:
errmsg = "could not find next log";
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
@@ -1001,8 +1004,8 @@ int reset_slave(THD *thd, Master_info* m
MY_STAT stat_area;
char fname[FN_REFLEN];
int thread_mask= 0, error= 0;
- uint sql_errno=0;
- const char* errmsg=0;
+ uint sql_errno=ER_UNKNOWN_ERROR;
+ const char* errmsg= "Unknown error occured while reseting slave";
DBUG_ENTER("reset_slave");
lock_slave_threads(mi);
@@ -1668,7 +1671,8 @@ err:
replication events along LOAD DATA processing.
@param file pointer to io-cache
- @return 0
+ @retval 0 success
+ @retval 1 failure
*/
int log_loaded_block(IO_CACHE* file)
{
@@ -1695,7 +1699,8 @@ int log_loaded_block(IO_CACHE* file)
Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
min(block_len, max_event_size),
lf_info->log_delayed);
- mysql_bin_log.write(&a);
+ if (mysql_bin_log.write(&a))
+ DBUG_RETURN(1);
}
else
{
@@ -1703,7 +1708,8 @@ int log_loaded_block(IO_CACHE* file)
buffer,
min(block_len, max_event_size),
lf_info->log_delayed);
- mysql_bin_log.write(&b);
+ if (mysql_bin_log.write(&b))
+ DBUG_RETURN(1);
lf_info->wrote_create_file= 1;
DBUG_SYNC_POINT("debug_lock.created_file_event",10);
}
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2009-12-03 11:34:11 +0000
+++ b/sql/sql_select.cc 2010-03-10 09:12:23 +0000
@@ -529,7 +529,7 @@ JOIN::prepare(Item ***rref_pointer_array
thd->lex->allow_sum_func= save_allow_sum_func;
}
- if (!thd->lex->view_prepare_mode)
+ if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE))
{
Item_subselect *subselect;
/* Is it subselect? */
@@ -549,13 +549,26 @@ JOIN::prepare(Item ***rref_pointer_array
if (order)
{
+ bool real_order= FALSE;
ORDER *ord;
for (ord= order; ord; ord= ord->next)
{
Item *item= *ord->item;
+ /*
+ Disregard sort order if there's only "{VAR}CHAR(0) NOT NULL" fields
+ there. Such fields don't contain any data to sort.
+ */
+ if (!real_order &&
+ (item->type() != Item::FIELD_ITEM ||
+ ((Item_field *) item)->field->maybe_null() ||
+ ((Item_field *) item)->field->sort_length()))
+ real_order= TRUE;
+
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
item->split_sum_func(thd, ref_pointer_array, all_fields);
}
+ if (!real_order)
+ order= NULL;
}
if (having && having->with_sum_func)
@@ -952,6 +965,7 @@ JOIN::optimize()
DBUG_PRINT("info",("Select tables optimized away"));
zero_result_cause= "Select tables optimized away";
tables_list= 0; // All tables resolved
+ const_tables= tables;
/*
Extract all table-independent conditions and replace the WHERE
clause with them. All other conditions were computed by opt_sum_query
@@ -992,14 +1006,20 @@ JOIN::optimize()
DBUG_RETURN(1);
}
- if (select_lex->olap == ROLLUP_TYPE && rollup_process_const_fields())
+ if (rollup.state != ROLLUP::STATE_NONE)
{
- DBUG_PRINT("error", ("Error: rollup_process_fields() failed"));
- DBUG_RETURN(1);
+ if (rollup_process_const_fields())
+ {
+ DBUG_PRINT("error", ("Error: rollup_process_fields() failed"));
+ DBUG_RETURN(1);
+ }
+ }
+ else
+ {
+ /* Remove distinct if only const tables */
+ select_distinct= select_distinct && (const_tables != tables);
}
- /* Remove distinct if only const tables */
- select_distinct= select_distinct && (const_tables != tables);
thd_proc_info(thd, "preparing");
if (result->initialize_tables(this))
{
@@ -1298,11 +1318,14 @@ JOIN::optimize()
- We are using an ORDER BY or GROUP BY on fields not in the first table
- We are using different ORDER BY and GROUP BY orders
- The user wants us to buffer the result.
+ When the WITH ROLLUP modifier is present, we cannot skip temporary table
+ creation for the DISTINCT clause just because there are only const tables.
*/
- need_tmp= (const_tables != tables &&
+ need_tmp= ((const_tables != tables &&
((select_distinct || !simple_order || !simple_group) ||
(group_list && order) ||
- test(select_options & OPTION_BUFFER_RESULT)));
+ test(select_options & OPTION_BUFFER_RESULT))) ||
+ (rollup.state != ROLLUP::STATE_NONE && select_distinct));
// No cache for MATCH
make_join_readinfo(this,
@@ -1623,6 +1646,11 @@ JOIN::reinit()
if (join_tab_save)
memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables);
+ /* need to reset ref access state (see join_read_key) */
+ if (join_tab)
+ for (uint i= 0; i < tables; i++)
+ join_tab[i].ref.key_err= TRUE;
+
if (tmp_join)
restore_tmp();
@@ -2144,17 +2172,13 @@ JOIN::exec()
DBUG_VOID_RETURN;
if (!curr_table->select->cond)
curr_table->select->cond= sort_table_cond;
- else // This should never happen
+ else
{
if (!(curr_table->select->cond=
new Item_cond_and(curr_table->select->cond,
sort_table_cond)))
DBUG_VOID_RETURN;
- /*
- Item_cond_and do not need fix_fields for execution, its parameters
- are fixed or do not need fix_fields, too
- */
- curr_table->select->cond->quick_fix_field();
+ curr_table->select->cond->fix_fields(thd, 0);
}
curr_table->select_cond= curr_table->select->cond;
curr_table->select_cond->top_level_item();
@@ -2557,6 +2581,7 @@ make_join_statistics(JOIN *join, TABLE_L
JOIN_TAB *stat,*stat_end,*s,**stat_ref;
KEYUSE *keyuse,*start_keyuse;
table_map outer_join=0;
+ table_map no_rows_const_tables= 0;
SARGABLE_PARAM *sargables= 0;
JOIN_TAB *stat_vector[MAX_TABLES+1];
DBUG_ENTER("make_join_statistics");
@@ -2617,6 +2642,7 @@ make_join_statistics(JOIN *join, TABLE_L
#endif
{ // Empty table
s->dependent= 0; // Ignore LEFT JOIN depend.
+ no_rows_const_tables |= table->map;
set_position(join,const_count++,s,(KEYUSE*) 0);
continue;
}
@@ -2653,6 +2679,7 @@ make_join_statistics(JOIN *join, TABLE_L
!table->fulltext_searched && !join->no_const_tables)
{
set_position(join,const_count++,s,(KEYUSE*) 0);
+ no_rows_const_tables |= table->map;
}
}
stat_vector[i]=0;
@@ -2698,9 +2725,10 @@ make_join_statistics(JOIN *join, TABLE_L
~outer_join, join->select_lex, &sargables))
goto error;
- join->const_table_map= 0;
+ join->const_table_map= no_rows_const_tables;
join->const_tables= const_count;
eliminate_tables(join);
+ join->const_table_map &= ~no_rows_const_tables;
const_count= join->const_tables;
found_const_table_map= join->const_table_map;
@@ -3713,20 +3741,20 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
cond_func=(Item_func_match *)cond;
else if (func->arg_count == 2)
{
- Item_func *arg0=(Item_func *)(func->arguments()[0]),
- *arg1=(Item_func *)(func->arguments()[1]);
- if (arg1->const_item() &&
- arg0->type() == Item::FUNC_ITEM &&
- arg0->functype() == Item_func::FT_FUNC &&
+ Item *arg0= func->arguments()[0],
+ *arg1= func->arguments()[1];
+ if (arg1->const_item() && arg1->cols() == 1 &&
+ arg0->type() == Item::FUNC_ITEM &&
+ ((Item_func *) arg0)->functype() == Item_func::FT_FUNC &&
((functype == Item_func::GE_FUNC && arg1->val_real() > 0) ||
- (functype == Item_func::GT_FUNC && arg1->val_real() >=0)))
- cond_func=(Item_func_match *) arg0;
- else if (arg0->const_item() &&
- arg1->type() == Item::FUNC_ITEM &&
- arg1->functype() == Item_func::FT_FUNC &&
+ (functype == Item_func::GT_FUNC && arg1->val_real() >= 0)))
+ cond_func= (Item_func_match *) arg0;
+ else if (arg0->const_item() && arg0->cols() == 1 &&
+ arg1->type() == Item::FUNC_ITEM &&
+ ((Item_func *) arg1)->functype() == Item_func::FT_FUNC &&
((functype == Item_func::LE_FUNC && arg0->val_real() > 0) ||
- (functype == Item_func::LT_FUNC && arg0->val_real() >=0)))
- cond_func=(Item_func_match *) arg1;
+ (functype == Item_func::LT_FUNC && arg0->val_real() >= 0)))
+ cond_func= (Item_func_match *) arg1;
}
}
else if (cond->type() == Item::COND_ITEM)
@@ -5941,6 +5969,7 @@ inline void add_cond_and_fix(Item **e1,
{
*e1= res;
res->quick_fix_field();
+ res->update_used_tables();
}
}
else
@@ -6565,6 +6594,56 @@ void rr_unlock_row(st_join_table *tab)
+/**
+ Pick the appropriate access method functions
+
+ Sets the functions for the selected table access method
+
+ @param tab Table reference to put access method
+*/
+
+static void
+pick_table_access_method(JOIN_TAB *tab)
+{
+ switch (tab->type)
+ {
+ case JT_REF:
+ tab->read_first_record= join_read_always_key;
+ tab->read_record.read_record= join_read_next_same;
+ break;
+
+ case JT_REF_OR_NULL:
+ tab->read_first_record= join_read_always_key_or_null;
+ tab->read_record.read_record= join_read_next_same_or_null;
+ break;
+
+ case JT_CONST:
+ tab->read_first_record= join_read_const;
+ tab->read_record.read_record= join_no_more_records;
+ break;
+
+ case JT_EQ_REF:
+ tab->read_first_record= join_read_key;
+ tab->read_record.read_record= join_no_more_records;
+ break;
+
+ case JT_FT:
+ tab->read_first_record= join_ft_read_first;
+ tab->read_record.read_record= join_ft_read_next;
+ break;
+
+ case JT_SYSTEM:
+ tab->read_first_record= join_read_system;
+ tab->read_record.read_record= join_no_more_records;
+ break;
+
+ /* keep gcc happy */
+ default:
+ break;
+ }
+}
+
+
static void
make_join_readinfo(JOIN *join, ulonglong options)
{
@@ -6599,45 +6678,15 @@ make_join_readinfo(JOIN *join, ulonglong
tab->sorted= sorted;
sorted= 0; // only first must be sorted
+ table->status=STATUS_NO_RECORD;
+ pick_table_access_method (tab);
+
switch (tab->type) {
- case JT_SYSTEM: // Only happens with left join
- table->status=STATUS_NO_RECORD;
- tab->read_first_record= join_read_system;
- tab->read_record.read_record= join_no_more_records;
- break;
- case JT_CONST: // Only happens with left join
- table->status=STATUS_NO_RECORD;
- tab->read_first_record= join_read_const;
- tab->read_record.read_record= join_no_more_records;
- if (table->covering_keys.is_set(tab->ref.key) &&
- !table->no_keyread)
- {
- table->key_read=1;
- table->file->extra(HA_EXTRA_KEYREAD);
- }
- break;
case JT_EQ_REF:
- table->status=STATUS_NO_RECORD;
- if (tab->select)
- {
- delete tab->select->quick;
- tab->select->quick=0;
- }
- delete tab->quick;
- tab->quick=0;
- tab->read_first_record= join_read_key;
tab->read_record.unlock_row= join_read_key_unlock_row;
- tab->read_record.read_record= join_no_more_records;
- if (table->covering_keys.is_set(tab->ref.key) &&
- !table->no_keyread)
- {
- table->key_read=1;
- table->file->extra(HA_EXTRA_KEYREAD);
- }
- break;
+ /* fall through */
case JT_REF_OR_NULL:
case JT_REF:
- table->status=STATUS_NO_RECORD;
if (tab->select)
{
delete tab->select->quick;
@@ -6645,34 +6694,20 @@ make_join_readinfo(JOIN *join, ulonglong
}
delete tab->quick;
tab->quick=0;
+ /* fall through */
+ case JT_CONST: // Only happens with left join
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
- if (tab->type == JT_REF)
- {
- tab->read_first_record= join_read_always_key;
- tab->read_record.read_record= join_read_next_same;
- }
- else
- {
- tab->read_first_record= join_read_always_key_or_null;
- tab->read_record.read_record= join_read_next_same_or_null;
- }
- break;
- case JT_FT:
- table->status=STATUS_NO_RECORD;
- tab->read_first_record= join_ft_read_first;
- tab->read_record.read_record= join_ft_read_next;
break;
case JT_ALL:
/*
If previous table use cache
If the incoming data set is already sorted don't use cache.
*/
- table->status=STATUS_NO_RECORD;
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
tab->use_quick != 2 && !tab->first_inner && !ordered_set)
{
@@ -6758,6 +6793,9 @@ make_join_readinfo(JOIN *join, ulonglong
}
}
break;
+ case JT_FT:
+ case JT_SYSTEM:
+ break;
default:
DBUG_PRINT("error",("Table type %d found",tab->type)); /* purecov: deadcode */
break; /* purecov: deadcode */
@@ -7140,6 +7178,7 @@ static void update_depend_map(JOIN *join
table_map depend_map;
order->item[0]->update_used_tables();
order->depend_map=depend_map=order->item[0]->used_tables();
+ order->used= 0;
// Not item_sum(), RAND() and no reference to table outside of sub select
if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT))
&& !order->item[0]->with_sum_func)
@@ -7197,7 +7236,19 @@ remove_const(JOIN *join,ORDER *first_ord
for (order=first_order; order ; order=order->next)
{
table_map order_tables=order->item[0]->used_tables();
- if (order->item[0]->with_sum_func)
+ if (order->item[0]->with_sum_func ||
+ /*
+ If the outer table of an outer join is const (either by itself or
+ after applying WHERE condition), grouping on a field from such a
+ table will be optimized away and filesort without temporary table
+ will be used unless we prevent that now. Filesort is not fit to
+ handle joins and the join condition is not applied. We can't detect
+ the case without an expensive test, however, so we force temporary
+ table for all queries containing more than one table, ROLLUP, and an
+ outer join.
+ */
+ (join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED &&
+ join->outer_join))
*simple_order=0; // Must do a temp table to sort
else if (!(order_tables & not_const_tables))
{
@@ -7605,7 +7656,7 @@ static bool check_simple_equality(Item *
already contains a constant and its value is not equal to
the value of const_item.
*/
- item_equal->add(const_item);
+ item_equal->add(const_item, field_item);
}
else
{
@@ -7909,12 +7960,12 @@ static COND *build_equal_items_for_cond(
{
item_equal->fix_length_and_dec();
item_equal->update_used_tables();
+ set_if_bigger(thd->lex->current_select->max_equal_elems,
+ item_equal->members());
+ return item_equal;
}
- else
- item_equal= (Item_equal *) eq_list.pop();
- set_if_bigger(thd->lex->current_select->max_equal_elems,
- item_equal->members());
- return item_equal;
+
+ return eq_list.pop();
}
else
{
@@ -9552,47 +9603,8 @@ static Field *create_tmp_field_from_item
new_field->set_derivation(item->collation.derivation);
break;
case DECIMAL_RESULT:
- {
- uint8 dec= item->decimals;
- uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
- uint32 len= item->max_length;
-
- /*
- Trying to put too many digits overall in a DECIMAL(prec,dec)
- will always throw a warning. We must limit dec to
- DECIMAL_MAX_SCALE however to prevent an assert() later.
- */
-
- if (dec > 0)
- {
- signed int overflow;
-
- dec= min(dec, DECIMAL_MAX_SCALE);
-
- /*
- If the value still overflows the field with the corrected dec,
- we'll throw out decimals rather than integers. This is still
- bad and of course throws a truncation warning.
- +1: for decimal point
- */
-
- const int required_length=
- my_decimal_precision_to_length(intg + dec, dec,
- item->unsigned_flag);
-
- overflow= required_length - len;
-
- if (overflow > 0)
- dec= max(0, dec - overflow); // too long, discard fract
- else
- /* Corrected value fits. */
- len= required_length;
- }
-
- new_field= new Field_new_decimal(len, maybe_null, item->name,
- dec, item->unsigned_flag);
+ new_field= Field_new_decimal::create_from_item(item);
break;
- }
case ROW_RESULT:
default:
// This case should never be choosen
@@ -10189,7 +10201,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARA
/* future: storage engine selection can be made dynamic? */
if (blob_count || using_unique_constraint ||
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
- OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
+ OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM) ||
+ !thd->variables.tmp_table_size)
{
share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
table->file= get_new_handler(share, &table->mem_root,
@@ -10728,7 +10741,7 @@ static bool create_internal_tmp_table(TA
{
/* Create an unique key */
bzero((char*) &keydef,sizeof(keydef));
- keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
+ keydef.flag=HA_NOSAME;
keydef.keysegs= keyinfo->key_parts;
keydef.seg= seg;
}
@@ -10753,7 +10766,7 @@ static bool create_internal_tmp_table(TA
seg->type= keyinfo->key_part[i].type;
/* Tell handler if it can do suffic space compression */
if (field->real_type() == MYSQL_TYPE_STRING &&
- keyinfo->key_part[i].length > 4)
+ keyinfo->key_part[i].length > 32)
seg->flag|= HA_SPACE_PACK;
}
if (!(field->flags & NOT_NULL_FLAG))
@@ -11035,7 +11048,7 @@ create_internal_tmp_table_from_heap2(THD
delete table->file;
table->file=0;
plugin_unlock(0, table->s->db_plugin);
- share.db_plugin= my_plugin_lock(0, &share.db_plugin);
+ share.db_plugin= my_plugin_lock(0, share.db_plugin);
new_table.s= table->s; // Keep old share
*table= new_table;
*table->s= share;
@@ -13496,6 +13509,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,OR
if (create_ref_for_key(tab->join, tab, keyuse,
tab->join->const_table_map))
DBUG_RETURN(0);
+
+ pick_table_access_method(tab);
}
else
{
@@ -13822,7 +13837,7 @@ check_reverse_order:
select->quick=tmp;
}
}
- else if (tab->type != JT_NEXT &&
+ else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
{
/*
@@ -14305,7 +14320,10 @@ static int remove_dup_with_hash_index(TH
goto err;
}
else
- (void) my_hash_insert(&hash, org_key_pos);
+ {
+ if (my_hash_insert(&hash, org_key_pos))
+ goto err;
+ }
key_pos+=extra_length;
}
my_free((char*) key_buffer,MYF(0));
=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h 2009-12-03 11:19:05 +0000
+++ b/sql/sql_select.h 2010-03-04 08:03:07 +0000
@@ -722,6 +722,12 @@ public:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
table->write_set);
int res= item->save_in_field(to_field, 1);
+ /*
+ Item::save_in_field() may call Item::val_xxx(). And if this is a subquery
+ we need to check for errors executing it and react accordingly
+ */
+ if (!res && table->in_use->is_error())
+ res= 2;
dbug_tmp_restore_column_map(table->write_set, old_map);
null_key= to_field->is_null() || item->null_value;
return (err != 0 || res > 2 ? STORE_KEY_FATAL : (store_key_result) res);
@@ -755,6 +761,12 @@ protected:
if (!err)
err= res;
}
+ /*
+ Item::save_in_field() may call Item::val_xxx(). And if this is a subquery
+ we need to check for errors executing it and react accordingly
+ */
+ if (!err && to_field->table->in_use->is_error())
+ err= 2;
}
null_key= to_field->is_null() || item->null_value;
return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err);
=== modified file 'sql/sql_servers.cc'
--- a/sql/sql_servers.cc 2009-03-20 14:27:53 +0000
+++ b/sql/sql_servers.cc 2010-01-13 11:39:00 +0000
@@ -241,8 +241,14 @@ bool servers_reload(THD *thd)
if (simple_open_n_lock_tables(thd, tables))
{
- sql_print_error("Can't open and lock privilege tables: %s",
- thd->main_da.message());
+ /*
+ Execution might have been interrupted; only print the error message
+ if an error condition has been raised.
+ */
+ if (thd->main_da.is_error())
+ sql_print_error("Can't open and lock privilege tables: %s",
+ thd->main_da.message());
+ return_val= FALSE;
goto end;
}
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2009-12-03 11:34:11 +0000
+++ b/sql/sql_show.cc 2010-03-04 08:03:07 +0000
@@ -721,7 +721,7 @@ mysqld_show_create(THD *thd, TABLE_LIST
thd->push_internal_handler(&view_error_suppressor);
bool error= open_normal_and_derived_tables(thd, table_list, 0);
thd->pop_internal_handler();
- if (error && thd->main_da.is_error())
+ if (error && (thd->killed || thd->main_da.is_error()))
DBUG_RETURN(TRUE);
}
@@ -828,8 +828,7 @@ bool mysqld_show_create_db(THD *thd, cha
DBUG_RETURN(TRUE);
}
#endif
- if (!my_strcasecmp(system_charset_info, dbname,
- INFORMATION_SCHEMA_NAME.str))
+ if (is_schema_db(dbname))
{
dbname= INFORMATION_SCHEMA_NAME.str;
create.default_table_charset= system_charset_info;
@@ -2797,8 +2796,8 @@ int make_db_list(THD *thd, List<LEX_STRI
*/
if (lookup_field_vals->db_value.str)
{
- if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
- lookup_field_vals->db_value.str))
+ if (is_schema_db(lookup_field_vals->db_value.str,
+ lookup_field_vals->db_value.length))
{
*with_i_schema= 1;
if (files->push_back(i_s_name_copy))
@@ -3385,11 +3384,11 @@ int get_all_tables(THD *thd, TABLE_LIST
while ((db_name= it++))
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (!check_access(thd,SELECT_ACL, db_name->str,
- &thd->col_access, 0, 1, with_i_schema) ||
+ if (!(check_access(thd,SELECT_ACL, db_name->str,
+ &thd->col_access, 0, 1, with_i_schema) ||
+ (!thd->col_access && check_grant_db(thd, db_name->str))) ||
sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
- acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
- !check_grant_db(thd, db_name->str))
+ acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0))
#endif
{
thd->no_warnings_for_error= 1;
@@ -5250,7 +5249,7 @@ copy_event_to_schema_table(THD *thd, TAB
*/
if (thd->lex->sql_command != SQLCOM_SHOW_EVENTS &&
check_access(thd, EVENT_ACL, et.dbname.str, 0, 0, 1,
- is_schema_db(et.dbname.str)))
+ is_schema_db(et.dbname.str, et.dbname.length)))
DBUG_RETURN(0);
/* ->field[0] is EVENT_CATALOG and is by default NULL */
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_table.cc 2010-03-30 12:36:49 +0000
@@ -647,7 +647,7 @@ static bool read_ddl_log_file_entry(uint
Write one entry from ddl log file
SYNOPSIS
write_ddl_log_file_entry()
- entry_no Entry number to read
+ entry_no Entry number to write
RETURN VALUES
TRUE Error
FALSE Success
@@ -748,10 +748,10 @@ static uint read_ddl_log_header()
else
successful_open= TRUE;
}
- entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
- global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
if (successful_open)
{
+ entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
+ global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
DBUG_ASSERT(global_ddl_log.io_size <=
sizeof(global_ddl_log.file_entry_buf));
@@ -832,6 +832,7 @@ static bool init_ddl_log()
goto end;
global_ddl_log.io_size= IO_SIZE;
+ global_ddl_log.name_len= FN_LEN;
create_ddl_log_file_name(file_name);
if ((global_ddl_log.file_id= my_create(file_name,
CREATE_MODE,
@@ -884,6 +885,13 @@ static int execute_ddl_log_action(THD *t
{
DBUG_RETURN(FALSE);
}
+ DBUG_PRINT("ddl_log",
+ ("execute type %c next %u name '%s' from_name '%s' handler '%s'",
+ ddl_log_entry->action_type,
+ ddl_log_entry->next_entry,
+ ddl_log_entry->name,
+ ddl_log_entry->from_name,
+ ddl_log_entry->handler_name));
handler_name.str= (char*)ddl_log_entry->handler_name;
handler_name.length= strlen(ddl_log_entry->handler_name);
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
@@ -1091,6 +1099,15 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *
DBUG_RETURN(TRUE);
}
error= FALSE;
+ DBUG_PRINT("ddl_log",
+ ("write type %c next %u name '%s' from_name '%s' handler '%s'",
+ (char) global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS],
+ ddl_log_entry->next_entry,
+ (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
+ (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
+ + FN_LEN],
+ (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
+ + (2*FN_LEN)]));
if (write_ddl_log_file_entry((*active_entry)->entry_pos))
{
error= TRUE;
@@ -1731,9 +1748,10 @@ end:
file
*/
-void write_bin_log(THD *thd, bool clear_error,
- char const *query, ulong query_length)
+int write_bin_log(THD *thd, bool clear_error,
+ char const *query, ulong query_length)
{
+ int error= 0;
if (mysql_bin_log.is_open())
{
int errcode= 0;
@@ -1741,9 +1759,10 @@ void write_bin_log(THD *thd, bool clear_
thd->clear_error();
else
errcode= query_error_code(thd, TRUE);
- thd->binlog_query(THD::STMT_QUERY_TYPE,
- query, query_length, FALSE, FALSE, errcode);
+ error= thd->binlog_query(THD::STMT_QUERY_TYPE,
+ query, query_length, FALSE, FALSE, errcode);
}
+ return error;
}
@@ -1880,6 +1899,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
{
TABLE_SHARE *share;
table->db_type= NULL;
+
if ((share= get_cached_table_share(table->db, table->table_name)))
table->db_type= share->db_type();
@@ -1974,9 +1994,10 @@ int mysql_rm_table_part2(THD *thd, TABLE
{
TABLE *locked_table;
abort_locked_tables(thd, db, table->table_name);
+ table->deleting= TRUE;
remove_table_from_cache(thd, db, table->table_name,
RTFC_WAIT_OTHER_THREAD_FLAG |
- RTFC_CHECK_KILLED_FLAG);
+ RTFC_CHECK_KILLED_FLAG, FALSE);
/*
If the table was used in lock tables, remember it so that
unlock_table_names can free it
@@ -2089,7 +2110,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
tables). In this case, we can write the original query into
the binary log.
*/
- write_bin_log(thd, !error, thd->query(), thd->query_length());
+ error |= write_bin_log(thd, !error, thd->query(), thd->query_length());
}
else if (thd->current_stmt_binlog_row_based &&
tmp_table_deleted)
@@ -2111,7 +2132,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
*/
built_query.chop(); // Chop of the last comma
built_query.append(" /* generated by server */");
- write_bin_log(thd, !error, built_query.ptr(), built_query.length());
+ error|= write_bin_log(thd, !error, built_query.ptr(), built_query.length());
}
/*
@@ -2130,7 +2151,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
*/
built_tmp_query.chop(); // Chop of the last comma
built_tmp_query.append(" /* generated by server */");
- write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length());
+ error|= write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length());
}
}
@@ -2575,7 +2596,7 @@ mysql_prepare_create_table(THD *thd, HA_
!(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
MY_CS_BINSORT,MYF(0))))
{
- char tmp[64];
+ char tmp[65];
strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
STRING_WITH_LEN("_bin"));
my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
@@ -3539,9 +3560,9 @@ void sp_prepare_create_field(THD *thd, C
RETURN VALUES
NONE
*/
-static inline void write_create_table_bin_log(THD *thd,
- const HA_CREATE_INFO *create_info,
- bool internal_tmp_table)
+static inline int write_create_table_bin_log(THD *thd,
+ const HA_CREATE_INFO *create_info,
+ bool internal_tmp_table)
{
/*
Don't write statement if:
@@ -3554,7 +3575,8 @@ static inline void write_create_table_bi
(!thd->current_stmt_binlog_row_based ||
(thd->current_stmt_binlog_row_based &&
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ return write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ return 0;
}
@@ -3821,8 +3843,7 @@ bool mysql_create_table_no_lock(THD *thd
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
alias);
- error= 0;
- write_create_table_bin_log(thd, create_info, internal_tmp_table);
+ error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
goto err;
}
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
@@ -3950,8 +3971,7 @@ bool mysql_create_table_no_lock(THD *thd
thd->thread_specific_used= TRUE;
}
- write_create_table_bin_log(thd, create_info, internal_tmp_table);
- error= FALSE;
+ error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
unlock_and_end:
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -3966,7 +3986,7 @@ warn:
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
alias);
create_info->table_existed= 1; // Mark that table existed
- write_create_table_bin_log(thd, create_info, internal_tmp_table);
+ error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
goto unlock_and_end;
}
@@ -4213,9 +4233,10 @@ void wait_while_table_is_used(THD *thd,T
/* Wait until all there are no other threads that has this table open */
remove_table_from_cache(thd, table->s->db.str,
table->s->table_name.str,
- RTFC_WAIT_OTHER_THREAD_FLAG);
+ RTFC_WAIT_OTHER_THREAD_FLAG, FALSE);
/* extra() call must come only after all instances above are closed */
- VOID(table->file->extra(function));
+ if (function != HA_EXTRA_NOT_USED)
+ VOID(table->file->extra(function));
DBUG_VOID_RETURN;
}
@@ -4717,7 +4738,7 @@ static bool mysql_admin_table(THD* thd,
remove_table_from_cache(thd, table->table->s->db.str,
table->table->s->table_name.str,
RTFC_WAIT_OTHER_THREAD_FLAG |
- RTFC_CHECK_KILLED_FLAG);
+ RTFC_CHECK_KILLED_FLAG, FALSE);
thd->exit_cond(old_message);
DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
if (thd->killed)
@@ -4975,7 +4996,8 @@ send_result_message:
{
pthread_mutex_lock(&LOCK_open);
remove_table_from_cache(thd, table->table->s->db.str,
- table->table->s->table_name.str, RTFC_NO_FLAG);
+ table->table->s->table_name.str,
+ RTFC_NO_FLAG, FALSE);
pthread_mutex_unlock(&LOCK_open);
}
/* May be something modified consequently we have to invalidate cache */
@@ -5428,22 +5450,32 @@ binlog:
}
VOID(pthread_mutex_unlock(&LOCK_open));
- IF_DBUG(int result=)
- store_create_info(thd, table, &query,
- create_info, FALSE /* show_database */);
+ /*
+ The condition avoids a crash as described in BUG#48506. Other
+ binlogging problems related to CREATE TABLE IF NOT EXISTS LIKE
+ when the existing object is a view will be solved by BUG 47442.
+ */
+ if (!table->view)
+ {
+ IF_DBUG(int result=)
+ store_create_info(thd, table, &query,
+ create_info, FALSE /* show_database */);
- DBUG_ASSERT(result == 0); // store_create_info() always return 0
- write_bin_log(thd, TRUE, query.ptr(), query.length());
+ DBUG_ASSERT(result == 0); // store_create_info() always return 0
+ if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
+ goto err;
+ }
}
else // Case 1
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ goto err;
}
/*
Case 3 and 4 does nothing under RBR
*/
}
- else
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ else if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ goto err;
res= FALSE;
@@ -5531,7 +5563,7 @@ mysql_discard_or_import_tablespace(THD *
error=1;
if (error)
goto err;
- write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ error= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
err:
ha_autocommit_or_rollback(thd, error);
@@ -5636,6 +5668,10 @@ compare_tables(TABLE *table,
*/
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
uint db_options= 0; /* not used */
+
+ /* Set default value for return value (to ensure it's always set) */
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+
/* Create the prepared information. */
if (mysql_prepare_create_table(thd, create_info,
&tmp_alter_info,
@@ -5694,7 +5730,6 @@ compare_tables(TABLE *table,
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
{
DBUG_PRINT("info", ("Basic checks -> ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5724,7 +5759,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("NULL behaviour difference in field '%s' -> "
"ALTER_TABLE_DATA_CHANGED", new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5747,7 +5781,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED",
new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
// Clear indexed marker
@@ -5882,7 +5915,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("check_if_incompatible_data() -> "
"ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -6559,11 +6591,13 @@ bool mysql_alter_table(THD *thd,char *ne
thd->clear_error();
Query_log_event qinfo(thd, thd->query(), thd->query_length(),
0, FALSE, 0);
- mysql_bin_log.write(&qinfo);
+ if ((error= mysql_bin_log.write(&qinfo)))
+ goto view_err_unlock;
}
my_ok(thd);
}
+view_err_unlock:
unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
view_err:
@@ -6730,7 +6764,9 @@ view_err:
from concurrent DDL statements.
*/
VOID(pthread_mutex_lock(&LOCK_open));
- wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ wait_while_table_is_used(thd, table,
+ thd->locked_tables ? HA_EXTRA_NOT_USED :
+ HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
@@ -6738,7 +6774,9 @@ view_err:
break;
case DISABLE:
VOID(pthread_mutex_lock(&LOCK_open));
- wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ wait_while_table_is_used(thd, table,
+ thd->locked_tables ? HA_EXTRA_NOT_USED :
+ HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open));
error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */
@@ -6812,8 +6850,9 @@ view_err:
if (!error)
{
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
- my_ok(thd);
+ error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ if (!error)
+ my_ok(thd);
}
else if (error > 0)
{
@@ -7184,7 +7223,9 @@ view_err:
else
{
VOID(pthread_mutex_lock(&LOCK_open));
- wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ wait_while_table_is_used(thd, table,
+ thd->locked_tables ? HA_EXTRA_NOT_USED :
+ HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open));
thd_proc_info(thd, "manage keys");
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
@@ -7304,8 +7345,9 @@ view_err:
if (rename_temporary_table(thd, new_table, new_db, new_name))
goto err1;
/* We don't replicate alter table statement on temporary tables */
- if (!thd->current_stmt_binlog_row_based)
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ if (!thd->current_stmt_binlog_row_based &&
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ DBUG_RETURN(TRUE);
goto end_temporary;
}
@@ -7468,7 +7510,8 @@ view_err:
DBUG_ASSERT(!(mysql_bin_log.is_open() &&
thd->current_stmt_binlog_row_based &&
(create_info->options & HA_LEX_CREATE_TMP_TABLE)));
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ DBUG_RETURN(TRUE);
if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
{
=== modified file 'sql/sql_tablespace.cc'
--- a/sql/sql_tablespace.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_tablespace.cc 2010-03-04 08:03:07 +0000
@@ -67,6 +67,6 @@ int mysql_alter_tablespace(THD *thd, st_
hton_name(hton)->str,
"TABLESPACE or LOGFILE GROUP");
}
- write_bin_log(thd, FALSE, thd->query(), thd->query_length());
- DBUG_RETURN(FALSE);
+ error= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ DBUG_RETURN(error);
}
=== modified file 'sql/sql_test.cc'
--- a/sql/sql_test.cc 2009-09-07 20:50:10 +0000
+++ b/sql/sql_test.cc 2010-03-04 08:03:07 +0000
@@ -168,6 +168,21 @@ TEST_join(JOIN *join)
uint i,ref;
DBUG_ENTER("TEST_join");
+ /*
+ Assemble results of all the calls to full_name() first,
+ in order not to garble the tabular output below.
+ */
+ String ref_key_parts[MAX_TABLES];
+ for (i= 0; i < join->tables; i++)
+ {
+ JOIN_TAB *tab= join->join_tab + i;
+ for (ref= 0; ref < tab->ref.key_parts; ref++)
+ {
+ ref_key_parts[i].append(tab->ref.items[ref]->full_name());
+ ref_key_parts[i].append(" ");
+ }
+ }
+
DBUG_LOCK_FILE;
VOID(fputs("\nInfo about JOIN\n",DBUG_FILE));
for (i=0 ; i < join->tables ; i++)
@@ -199,13 +214,8 @@ TEST_join(JOIN *join)
}
if (tab->ref.key_parts)
{
- VOID(fputs(" refs: ",DBUG_FILE));
- for (ref=0 ; ref < tab->ref.key_parts ; ref++)
- {
- Item *item=tab->ref.items[ref];
- fprintf(DBUG_FILE,"%s ", item->full_name());
- }
- VOID(fputc('\n',DBUG_FILE));
+ fprintf(DBUG_FILE,
+ " refs: %s\n", ref_key_parts[i].ptr());
}
}
DBUG_UNLOCK_FILE;
=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_trigger.cc 2010-03-04 08:03:07 +0000
@@ -507,7 +507,7 @@ end:
if (!result)
{
- write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length());
+ result= write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length());
}
VOID(pthread_mutex_unlock(&LOCK_open));
=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc 2009-10-16 10:29:42 +0000
+++ b/sql/sql_udf.cc 2010-01-25 02:55:05 +0000
@@ -398,6 +398,7 @@ int mysql_create_function(THD *thd,udf_f
TABLE *table;
TABLE_LIST tables;
udf_func *u_d;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_create_function");
if (!initialized)
@@ -437,8 +438,8 @@ int mysql_create_function(THD *thd,udf_f
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for CREATE FUNCTION command.
*/
- if (thd->current_stmt_binlog_row_based)
- thd->clear_current_stmt_binlog_row_based();
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
+ thd->clear_current_stmt_binlog_row_based();
rw_wrlock(&THR_LOCK_udf);
if ((hash_search(&udf_hash,(uchar*) udf->name.str, udf->name.length)))
@@ -506,14 +507,22 @@ int mysql_create_function(THD *thd,udf_f
rw_unlock(&THR_LOCK_udf);
/* Binlog the create function. */
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-
+ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ {
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
+ DBUG_RETURN(1);
+ }
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(0);
err:
if (new_dl)
dlclose(dl);
rw_unlock(&THR_LOCK_udf);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(1);
}
@@ -525,6 +534,7 @@ int mysql_drop_function(THD *thd,const L
udf_func *udf;
char *exact_name_str;
uint exact_name_len;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_drop_function");
if (!initialized)
@@ -540,8 +550,8 @@ int mysql_drop_function(THD *thd,const L
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for DROP FUNCTION command.
*/
- if (thd->current_stmt_binlog_row_based)
- thd->clear_current_stmt_binlog_row_based();
+ save_binlog_row_based= thd->current_stmt_binlog_row_based;
+ thd->clear_current_stmt_binlog_row_based();
rw_wrlock(&THR_LOCK_udf);
if (!(udf=(udf_func*) hash_search(&udf_hash,(uchar*) udf_name->str,
@@ -581,11 +591,19 @@ int mysql_drop_function(THD *thd,const L
rw_unlock(&THR_LOCK_udf);
/* Binlog the drop function. */
- write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-
+ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ {
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
+ DBUG_RETURN(1);
+ }
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(0);
err:
rw_unlock(&THR_LOCK_udf);
+ /* Restore the state of binlog format */
+ thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(1);
}
=== modified file 'sql/sql_union.cc'
--- a/sql/sql_union.cc 2009-09-07 20:50:10 +0000
+++ b/sql/sql_union.cc 2010-03-04 08:03:07 +0000
@@ -335,6 +335,35 @@ bool st_select_lex_unit::prepare(THD *th
}
}
+ /*
+ Disable the usage of fulltext searches in the last union branch.
+ This is a temporary 5.x limitation because of the way the fulltext
+ search functions are handled by the optimizer.
+ This is manifestation of the more general problems of "taking away"
+ parts of a SELECT statement post-fix_fields(). This is generally not
+ doable since various flags are collected in various places (e.g.
+ SELECT_LEX) that carry information about the presence of certain
+ expressions or constructs in the parts of the query.
+ When part of the query is taken away it's not clear how to "divide"
+ the meaning of these accumulated flags and what to carry over to the
+ recipient query (SELECT_LEX).
+ */
+ if (global_parameters->ftfunc_list->elements &&
+ global_parameters->order_list.elements &&
+ global_parameters != fake_select_lex)
+ {
+ ORDER *ord;
+ Item_func::Functype ft= Item_func::FT_FUNC;
+ for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next)
+ if ((*ord->item)->walk (&Item::find_function_processor, FALSE,
+ (uchar *) &ft))
+ {
+ my_error (ER_CANT_USE_OPTION_HERE, MYF(0), "MATCH()");
+ goto err;
+ }
+ }
+
+
create_options= (first_sl->options | thd_arg->options |
TMP_TABLE_ALL_COLUMNS);
/*
@@ -669,7 +698,7 @@ bool st_select_lex_unit::cleanup()
{
ORDER *ord;
for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next)
- (*ord->item)->cleanup();
+ (*ord->item)->walk (&Item::cleanup_processor, 0, 0);
}
}
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_update.cc 2010-03-04 08:03:07 +0000
@@ -23,6 +23,7 @@
#include "sql_select.h"
#include "sp_head.h"
#include "sql_trigger.h"
+#include "debug_sync.h"
/* Return 0 if row hasn't changed */
@@ -828,7 +829,7 @@ int mysql_update(THD *thd,
if (error < 0)
{
- char buff[STRING_BUFFER_USUAL_SIZE];
+ char buff[MYSQL_ERRMSG_SIZE];
my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
(ulong) thd->cuted_fields);
thd->row_count_func=
@@ -1143,8 +1144,11 @@ reopen_tables:
items from 'fields' list, so the cleanup above is necessary to.
*/
cleanup_items(thd->free_list);
-
+ cleanup_items(thd->stmt_arena->free_list);
close_tables_for_reopen(thd, &table_list);
+
+ DEBUG_SYNC(thd, "multi_update_reopen_tables");
+
goto reopen_tables;
}
@@ -1864,9 +1868,10 @@ void multi_update::abort()
into repl event.
*/
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query(), thd->query_length(),
- transactional_tables, FALSE, errcode);
+ /* the error of binary logging is ignored */
+ (void)thd->binlog_query(THD::ROW_QUERY_TYPE,
+ thd->query(), thd->query_length(),
+ transactional_tables, FALSE, errcode);
}
thd->transaction.all.modified_non_trans_table= TRUE;
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2009-12-03 11:19:05 +0000
+++ b/sql/sql_view.cc 2010-03-30 12:36:49 +0000
@@ -268,11 +268,11 @@ bool create_view_precheck(THD *thd, TABL
table (i.e. user will not get some privileges by view creation)
*/
if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege,
- 0, 0, is_schema_db(view->db)) ||
+ 0, 0, is_schema_db(view->db, view->db_length)) ||
check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) ||
(mode != VIEW_CREATE_NEW &&
(check_access(thd, DROP_ACL, view->db, &view->grant.privilege,
- 0, 0, is_schema_db(view->db)) ||
+ 0, 0, is_schema_db(view->db, view->db_length)) ||
check_grant(thd, DROP_ACL, view, 0, 1, 0))))
goto err;
@@ -662,8 +662,9 @@ bool mysql_create_view(THD *thd, TABLE_L
buff.append(views->source.str, views->source.length);
int errcode= query_error_code(thd, TRUE);
- thd->binlog_query(THD::STMT_QUERY_TYPE,
- buff.ptr(), buff.length(), FALSE, FALSE, errcode);
+ if (thd->binlog_query(THD::STMT_QUERY_TYPE,
+ buff.ptr(), buff.length(), FALSE, FALSE, errcode))
+ res= TRUE;
}
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -1033,10 +1034,12 @@ bool mysql_make_view(THD *thd, File_pars
bool parse_status;
bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables);
-
DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
+ LINT_INIT(parse_status);
+ LINT_INIT(view_select);
+
if (table->view)
{
/*
@@ -1652,7 +1655,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
/* if something goes wrong, bin-log with possible error code,
otherwise bin-log with error code cleared.
*/
- write_bin_log(thd, !something_wrong, thd->query(), thd->query_length());
+ if (write_bin_log(thd, !something_wrong, thd->query(), thd->query_length()))
+ something_wrong= 1;
}
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -1771,7 +1775,7 @@ bool check_key_in_view(THD *thd, TABLE_L
if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item))
{
thd->mark_used_columns= save_mark_used_columns;
- return TRUE;
+ DBUG_RETURN(TRUE);
}
}
thd->mark_used_columns= save_mark_used_columns;
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2009-12-03 11:19:05 +0000
+++ b/sql/sql_yacc.yy 2010-03-28 18:10:00 +0000
@@ -389,6 +389,138 @@ void case_stmt_action_end_case(LEX *lex,
lex->sphead->do_cont_backpatch();
}
+
+static bool
+find_sys_var_null_base(THD *thd, struct sys_var_with_base *tmp)
+{
+ tmp->var= find_sys_var(thd, tmp->base_name.str, tmp->base_name.length);
+
+ if (tmp->var == NULL)
+ my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), tmp->base_name.str);
+ else
+ tmp->base_name= null_lex_str;
+
+ return thd->is_error();
+}
+
+
+/**
+ Helper action for a SET statement.
+ Used to push a system variable into the assignment list.
+
+ @param thd the current thread
+ @param tmp the system variable with base name
+ @param var_type the scope of the variable
+ @param val the value being assigned to the variable
+
+ @return TRUE if error, FALSE otherwise.
+*/
+
+static bool
+set_system_variable(THD *thd, struct sys_var_with_base *tmp,
+ enum enum_var_type var_type, Item *val)
+{
+ set_var *var;
+ LEX *lex= thd->lex;
+
+ /* No AUTOCOMMIT from a stored function or trigger. */
+ if (lex->spcont && tmp->var == &sys_autocommit)
+ lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
+
+ if (! (var= new set_var(var_type, tmp->var, &tmp->base_name, val)))
+ return TRUE;
+
+ return lex->var_list.push_back(var);
+}
+
+
+/**
+ Helper action for a SET statement.
+ Used to push a SP local variable into the assignment list.
+
+ @param thd the current thread
+ @param var_type the SP local variable
+ @param val the value being assigned to the variable
+
+ @return TRUE if error, FALSE otherwise.
+*/
+
+static bool
+set_local_variable(THD *thd, sp_variable_t *spv, Item *val)
+{
+ Item *it;
+ LEX *lex= thd->lex;
+ sp_instr_set *sp_set;
+
+ if (val)
+ it= val;
+ else if (spv->dflt)
+ it= spv->dflt;
+ else
+ {
+ it= new (thd->mem_root) Item_null();
+ if (it == NULL)
+ return TRUE;
+ }
+
+ sp_set= new sp_instr_set(lex->sphead->instructions(), lex->spcont,
+ spv->offset, it, spv->type, lex, TRUE);
+
+ return (sp_set == NULL || lex->sphead->add_instr(sp_set));
+}
+
+
+/**
+ Helper action for a SET statement.
+ Used to SET a field of NEW row.
+
+ @param thd the current thread
+ @param name the field name
+ @param val the value being assigned to the row
+
+ @return TRUE if error, FALSE otherwise.
+*/
+
+static bool
+set_trigger_new_row(THD *thd, LEX_STRING *name, Item *val)
+{
+ LEX *lex= thd->lex;
+ Item_trigger_field *trg_fld;
+ sp_instr_set_trigger_field *sp_fld;
+
+ /* QQ: Shouldn't this be field's default value ? */
+ if (! val)
+ val= new Item_null();
+
+ DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE &&
+ (lex->trg_chistics.event == TRG_EVENT_INSERT ||
+ lex->trg_chistics.event == TRG_EVENT_UPDATE));
+
+ trg_fld= new (thd->mem_root)
+ Item_trigger_field(lex->current_context(),
+ Item_trigger_field::NEW_ROW,
+ name->str, UPDATE_ACL, FALSE);
+
+ if (trg_fld == NULL)
+ return TRUE;
+
+ sp_fld= new sp_instr_set_trigger_field(lex->sphead->instructions(),
+ lex->spcont, trg_fld, val, lex);
+
+ if (sp_fld == NULL)
+ return TRUE;
+
+ /*
+ Let us add this item to list of all Item_trigger_field
+ objects in trigger.
+ */
+ lex->trg_table_fields.link_in_list((uchar *) trg_fld,
+ (uchar **) &trg_fld->next_trg_field);
+
+ return lex->sphead->add_instr(sp_fld);
+}
+
+
/**
Helper to resolve the SQL:2003 Syntax exception 1) in <in predicate>.
See SQL:2003, Part 2, section 8.4 <in predicate>, Note 184, page 383.
@@ -464,6 +596,35 @@ Item* handle_sql2003_note184_exception(T
DBUG_RETURN(result);
}
+
+static bool add_create_index_prepare (LEX *lex, Table_ident *table)
+{
+ lex->sql_command= SQLCOM_CREATE_INDEX;
+ if (!lex->current_select->add_table_to_list(lex->thd, table, NULL,
+ TL_OPTION_UPDATING))
+ return TRUE;
+ lex->alter_info.reset();
+ lex->alter_info.flags= ALTER_ADD_INDEX;
+ lex->col_list.empty();
+ lex->change= NullS;
+ return FALSE;
+}
+
+
+static bool add_create_index (LEX *lex, Key::Keytype type, const char *name,
+ KEY_CREATE_INFO *info= NULL, bool generated= 0)
+{
+ Key *key;
+ key= new Key(type, name, info ? info : &lex->key_create_info, generated,
+ lex->col_list);
+ if (key == NULL)
+ return TRUE;
+
+ lex->alter_info.key_list.push_back(key);
+ lex->col_list.empty();
+ return FALSE;
+}
+
%}
%union {
int num;
@@ -1203,7 +1364,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
option_type opt_var_type opt_var_ident_type
%type <key_type>
- key_type opt_unique_or_fulltext constraint_key_type
+ normal_key_type opt_unique constraint_key_type fulltext spatial
%type <key_alg>
btree_or_rtree
@@ -1302,7 +1463,10 @@ bool my_yyoverflow(short **a, YYSTYPE **
view_suid view_tail view_list_opt view_list view_select
view_check_option trigger_tail sp_tail sf_tail udf_tail event_tail
install uninstall partition_entry binlog_base64_event
- init_key_options key_options key_opts key_opt key_using_alg
+ init_key_options normal_key_options normal_key_opts all_key_opt
+ spatial_key_options fulltext_key_options normal_key_opt
+ fulltext_key_opt spatial_key_opt fulltext_key_opts spatial_key_opts
+ key_using_alg
server_def server_options_list server_option
definer_opt no_definer definer
END_OF_INPUT
@@ -1696,35 +1860,37 @@ create:
$5->table.str);
}
}
- | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON
+ | CREATE opt_unique INDEX_SYM ident key_alg ON table_ident
+ {
+ if (add_create_index_prepare(Lex, $7))
+ MYSQL_YYABORT;
+ }
+ '(' key_list ')' normal_key_options
+ {
+ if (add_create_index(Lex, $2, $4.str))
+ MYSQL_YYABORT;
+ }
+ | CREATE fulltext INDEX_SYM ident init_key_options ON
table_ident
{
- LEX *lex=Lex;
- lex->sql_command= SQLCOM_CREATE_INDEX;
- if (!lex->current_select->add_table_to_list(lex->thd, $7,
- NULL,
- TL_OPTION_UPDATING))
+ if (add_create_index_prepare(Lex, $7))
MYSQL_YYABORT;
- lex->alter_info.reset();
- lex->alter_info.flags= ALTER_ADD_INDEX;
- lex->col_list.empty();
- lex->change=NullS;
}
- '(' key_list ')' key_options
+ '(' key_list ')' fulltext_key_options
{
- LEX *lex=Lex;
- Key *key;
- if ($2 != Key::FULLTEXT && lex->key_create_info.parser_name.str)
- {
- my_parse_error(ER(ER_SYNTAX_ERROR));
+ if (add_create_index(Lex, $2, $4.str))
MYSQL_YYABORT;
- }
- key= new Key($2, $4.str, &lex->key_create_info, 0,
- lex->col_list);
- if (key == NULL)
+ }
+ | CREATE spatial INDEX_SYM ident init_key_options ON
+ table_ident
+ {
+ if (add_create_index_prepare(Lex, $7))
+ MYSQL_YYABORT;
+ }
+ '(' key_list ')' spatial_key_options
+ {
+ if (add_create_index(Lex, $2, $4.str))
MYSQL_YYABORT;
- lex->alter_info.key_list.push_back(key);
- lex->col_list.empty();
}
| CREATE DATABASE opt_if_not_exists ident
{
@@ -2335,8 +2501,8 @@ sp_decl:
}
pctx->declare_var_boundary(0);
- lex->sphead->restore_lex(YYTHD);
-
+ if (lex->sphead->restore_lex(YYTHD))
+ MYSQL_YYABORT;
$$.vars= $2;
$$.conds= $$.hndlrs= $$.curs= 0;
}
@@ -2446,7 +2612,8 @@ sp_cursor_stmt:
}
lex->sp_lex_in_use= TRUE;
$$= lex;
- lex->sphead->restore_lex(YYTHD);
+ if (lex->sphead->restore_lex(YYTHD))
+ MYSQL_YYABORT;
}
;
@@ -2665,7 +2832,8 @@ sp_proc_stmt_statement:
sp->add_instr(i))
MYSQL_YYABORT;
}
- sp->restore_lex(thd);
+ if (sp->restore_lex(thd))
+ MYSQL_YYABORT;
}
;
@@ -2693,7 +2861,8 @@ sp_proc_stmt_return:
MYSQL_YYABORT;
sp->m_flags|= sp_head::HAS_RETURN;
}
- sp->restore_lex(YYTHD);
+ if (sp->restore_lex(YYTHD))
+ MYSQL_YYABORT;
}
;
@@ -2933,7 +3102,8 @@ sp_if:
sp->add_cont_backpatch(i) ||
sp->add_instr(i))
MYSQL_YYABORT;
- sp->restore_lex(YYTHD);
+ if (sp->restore_lex(YYTHD))
+ MYSQL_YYABORT;
}
sp_proc_stmts1
{
@@ -2979,7 +3149,9 @@ simple_case_stmt:
if (case_stmt_action_expr(lex, $3))
MYSQL_YYABORT;
- lex->sphead->restore_lex(YYTHD); /* For expr $3 */
+ /* For expr $3 */
+ if (lex->sphead->restore_lex(YYTHD))
+ MYSQL_YYABORT;
}
simple_when_clause_list
else_clause_opt
@@ -3029,7 +3201,9 @@ simple_when_clause:
LEX *lex= Lex;
if (case_stmt_action_when(lex, $3, true))
MYSQL_YYABORT;
- lex->sphead->restore_lex(YYTHD); /* For expr $3 */
+ /* For expr $3 */
+ if (lex->sphead->restore_lex(YYTHD))
+ MYSQL_YYABORT;
}
THEN_SYM
sp_proc_stmts1
@@ -3050,7 +3224,9 @@ searched_when_clause:
LEX *lex= Lex;
if (case_stmt_action_when(lex, $3, false))
MYSQL_YYABORT;
- lex->sphead->restore_lex(YYTHD); /* For expr $3 */
+ /* For expr $3 */
+ if (lex->sphead->restore_lex(YYTHD))
+ MYSQL_YYABORT;
}
THEN_SYM
sp_proc_stmts1
@@ -3227,7 +3403,8 @@ sp_unlabeled_control:
sp->new_cont_backpatch(i) ||
sp->add_instr(i))
MYSQL_YYABORT;
- sp->restore_lex(YYTHD);
+ if (sp->restore_lex(YYTHD))
+ MYSQL_YYABORT;
}
sp_proc_stmts1 END WHILE_SYM
{
@@ -3253,7 +3430,8 @@ sp_unlabeled_control:
if (i == NULL ||
lex->sphead->add_instr(i))
MYSQL_YYABORT;
- lex->sphead->restore_lex(YYTHD);
+ if (lex->sphead->restore_lex(YYTHD))
+ MYSQL_YYABORT;
/* We can shortcut the cont_backpatch here */
i->m_cont_dest= ip+1;
}
@@ -3938,7 +4116,7 @@ part_func_expr:
lex->safe_to_cache_query= 1;
if (not_corr_func)
{
- my_parse_error(ER(ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR));
+ my_parse_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
MYSQL_YYABORT;
}
$$=$1;
@@ -4678,32 +4856,28 @@ column_def:
;
key_def:
- key_type opt_ident key_alg '(' key_list ')' key_options
+ normal_key_type opt_ident key_alg '(' key_list ')' normal_key_options
{
- LEX *lex=Lex;
- if ($1 != Key::FULLTEXT && lex->key_create_info.parser_name.str)
- {
- my_parse_error(ER(ER_SYNTAX_ERROR));
+ if (add_create_index (Lex, $1, $2))
MYSQL_YYABORT;
- }
- Key *key= new Key($1, $2, &lex->key_create_info, 0,
- lex->col_list);
- if (key == NULL)
+ }
+ | fulltext opt_key_or_index opt_ident init_key_options
+ '(' key_list ')' fulltext_key_options
+ {
+ if (add_create_index (Lex, $1, $3))
+ MYSQL_YYABORT;
+ }
+ | spatial opt_key_or_index opt_ident init_key_options
+ '(' key_list ')' spatial_key_options
+ {
+ if (add_create_index (Lex, $1, $3))
MYSQL_YYABORT;
- lex->alter_info.key_list.push_back(key);
- lex->col_list.empty(); /* Alloced by sql_alloc */
}
| opt_constraint constraint_key_type opt_ident key_alg
- '(' key_list ')' key_options
+ '(' key_list ')' normal_key_options
{
- LEX *lex=Lex;
- const char *key_name= $3 ? $3 : $1;
- Key *key= new Key($2, key_name, &lex->key_create_info, 0,
- lex->col_list);
- if (key == NULL)
+ if (add_create_index (Lex, $2, $3 ? $3 : $1))
MYSQL_YYABORT;
- lex->alter_info.key_list.push_back(key);
- lex->col_list.empty(); /* Alloced by sql_alloc */
}
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
{
@@ -4719,13 +4893,9 @@ key_def:
if (key == NULL)
MYSQL_YYABORT;
lex->alter_info.key_list.push_back(key);
- key= new Key(Key::MULTIPLE, key_name,
- &default_key_create_info, 1,
- lex->col_list);
- if (key == NULL)
+ if (add_create_index (lex, Key::MULTIPLE, key_name,
+ &default_key_create_info, 1))
MYSQL_YYABORT;
- lex->alter_info.key_list.push_back(key);
- lex->col_list.empty(); /* Alloced by sql_alloc */
/* Only used for ALTER TABLE. Ignored otherwise. */
lex->alter_info.flags|= ALTER_FOREIGN_KEY;
}
@@ -5293,19 +5463,8 @@ delete_option:
| SET DEFAULT { $$= (int) Foreign_key::FK_OPTION_DEFAULT; }
;
-key_type:
+normal_key_type:
key_or_index { $$= Key::MULTIPLE; }
- | FULLTEXT_SYM opt_key_or_index { $$= Key::FULLTEXT; }
- | SPATIAL_SYM opt_key_or_index
- {
-#ifdef HAVE_SPATIAL
- $$= Key::SPATIAL;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
- MYSQL_YYABORT;
-#endif
- }
;
constraint_key_type:
@@ -5329,11 +5488,17 @@ keys_or_index:
| INDEXES {}
;
-opt_unique_or_fulltext:
+opt_unique:
/* empty */ { $$= Key::MULTIPLE; }
| UNIQUE_SYM { $$= Key::UNIQUE; }
- | FULLTEXT_SYM { $$= Key::FULLTEXT;}
- | SPATIAL_SYM
+ ;
+
+fulltext:
+ FULLTEXT_SYM { $$= Key::FULLTEXT;}
+ ;
+
+spatial:
+ SPATIAL_SYM
{
#ifdef HAVE_SPATIAL
$$= Key::SPATIAL;
@@ -5362,14 +5527,34 @@ key_alg:
| init_key_options key_using_alg
;
-key_options:
+normal_key_options:
+ /* empty */ {}
+ | normal_key_opts
+ ;
+
+fulltext_key_options:
/* empty */ {}
- | key_opts
+ | fulltext_key_opts
;
-key_opts:
- key_opt
- | key_opts key_opt
+spatial_key_options:
+ /* empty */ {}
+ | spatial_key_opts
+ ;
+
+normal_key_opts:
+ normal_key_opt
+ | normal_key_opts normal_key_opt
+ ;
+
+spatial_key_opts:
+ spatial_key_opt
+ | spatial_key_opts spatial_key_opt
+ ;
+
+fulltext_key_opts:
+ fulltext_key_opt
+ | fulltext_key_opts fulltext_key_opt
;
key_using_alg:
@@ -5377,10 +5562,22 @@ key_using_alg:
| TYPE_SYM btree_or_rtree { Lex->key_create_info.algorithm= $2; }
;
-key_opt:
- key_using_alg
- | KEY_BLOCK_SIZE opt_equal ulong_num
+all_key_opt:
+ KEY_BLOCK_SIZE opt_equal ulong_num
{ Lex->key_create_info.block_size= $3; }
+ ;
+
+normal_key_opt:
+ all_key_opt
+ | key_using_alg
+ ;
+
+spatial_key_opt:
+ all_key_opt
+ ;
+
+fulltext_key_opt:
+ all_key_opt
| WITH PARSER_SYM IDENT_sys
{
if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN))
@@ -7539,6 +7736,14 @@ function_call_nonkeyword:
}
| SYSDATE optional_braces
{
+ /*
+ Unlike other time-related functions, SYSDATE() is
+ replication-unsafe because it is not affected by the
+ TIMESTAMP variable. It is unsafe even if
+ sysdate_is_now=1, because the slave may have
+ sysdate_is_now=0.
+ */
+ Lex->set_stmt_unsafe();
if (global_system_variables.sysdate_is_now == 0)
$$= new (YYTHD->mem_root) Item_func_sysdate_local();
else
@@ -7877,7 +8082,7 @@ function_call_generic:
builder= find_qualified_function_builder(thd);
DBUG_ASSERT(builder);
- item= builder->create(thd, $1, $3, true, $5);
+ item= builder->create_with_db(thd, $1, $3, true, $5);
if (! ($$= item))
{
@@ -8743,7 +8948,7 @@ interval_time_stamp:
implementation without changing its
resolution.
*/
- WARN_DEPRECATED(yythd, "6.2", "FRAC_SECOND", "MICROSECOND");
+ WARN_DEPRECATED(yythd, VER_CELOSIA, "FRAC_SECOND", "MICROSECOND");
}
;
@@ -9483,16 +9688,12 @@ replace:
insert_lock_option:
/* empty */
{
-#ifdef HAVE_QUERY_CACHE
/*
- If it is SP we do not allow insert optimisation whan result of
+ If it is SP we do not allow insert optimisation when result of
insert visible only after the table unlocking but everyone can
read table.
*/
$$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
-#else
- $$= TL_WRITE_CONCURRENT_INSERT;
-#endif
}
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
| DELAYED_SYM { $$= TL_WRITE_DELAYED; }
@@ -10515,15 +10716,11 @@ load_data_lock:
/* empty */ { $$= TL_WRITE_DEFAULT; }
| CONCURRENT
{
-#ifdef HAVE_QUERY_CACHE
/*
- Ignore this option in SP to avoid problem with query cache
+ Ignore this option in SP to avoid problem with query cache and
+ triggers with non default priority locks
*/
- if (Lex->sphead != 0)
- $$= TL_WRITE_DEFAULT;
- else
-#endif
- $$= TL_WRITE_CONCURRENT_INSERT;
+ $$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
}
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
;
@@ -11791,7 +11988,8 @@ option_type_value:
if (sp->add_instr(i))
MYSQL_YYABORT;
}
- lex->sphead->restore_lex(thd);
+ if (lex->sphead->restore_lex(thd))
+ MYSQL_YYABORT;
}
}
;
@@ -11831,98 +12029,42 @@ sys_option_value:
option_type internal_variable_name equal set_expr_or_default
{
THD *thd= YYTHD;
- LEX *lex=Lex;
+ LEX *lex= Lex;
+ LEX_STRING *name= &$2.base_name;
if ($2.var == trg_new_row_fake_var)
{
/* We are in trigger and assigning value to field of new row */
- Item *it;
- Item_trigger_field *trg_fld;
- sp_instr_set_trigger_field *sp_fld;
- LINT_INIT(sp_fld);
if ($1)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
- if ($4)
- it= $4;
- else
- {
- /* QQ: Shouldn't this be field's default value ? */
- it= new Item_null();
- }
-
- DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE &&
- (lex->trg_chistics.event == TRG_EVENT_INSERT ||
- lex->trg_chistics.event == TRG_EVENT_UPDATE));
-
- trg_fld= new (thd->mem_root)
- Item_trigger_field(Lex->current_context(),
- Item_trigger_field::NEW_ROW,
- $2.base_name.str,
- UPDATE_ACL, FALSE);
- if (trg_fld == NULL)
- MYSQL_YYABORT;
-
- sp_fld= new sp_instr_set_trigger_field(lex->sphead->
- instructions(),
- lex->spcont,
- trg_fld,
- it, lex);
- if (sp_fld == NULL)
- MYSQL_YYABORT;
-
- /*
- Let us add this item to list of all Item_trigger_field
- objects in trigger.
- */
- lex->trg_table_fields.link_in_list((uchar *)trg_fld,
- (uchar **) &trg_fld->
- next_trg_field);
-
- if (lex->sphead->add_instr(sp_fld))
+ if (set_trigger_new_row(YYTHD, name, $4))
MYSQL_YYABORT;
}
else if ($2.var)
- { /* System variable */
+ {
if ($1)
lex->option_type= $1;
- set_var *var= new set_var(lex->option_type, $2.var,
- &$2.base_name, $4);
- if (var == NULL)
+
+ /* It is a system variable. */
+ if (set_system_variable(thd, &$2, lex->option_type, $4))
MYSQL_YYABORT;
- lex->var_list.push_back(var);
}
else
{
- /* An SP local variable */
- sp_pcontext *ctx= lex->spcont;
- sp_variable_t *spv;
- sp_instr_set *sp_set;
- Item *it;
+ sp_pcontext *spc= lex->spcont;
+ sp_variable_t *spv= spc->find_variable(name);
+
if ($1)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
- spv= ctx->find_variable(&$2.base_name);
-
- if ($4)
- it= $4;
- else if (spv->dflt)
- it= spv->dflt;
- else
- {
- it= new (thd->mem_root) Item_null();
- if (it == NULL)
- MYSQL_YYABORT;
- }
- sp_set= new sp_instr_set(lex->sphead->instructions(), ctx,
- spv->offset, it, spv->type, lex, TRUE);
- if (sp_set == NULL ||
- lex->sphead->add_instr(sp_set))
+ /* It is a local variable. */
+ if (set_local_variable(thd, spv, $4))
MYSQL_YYABORT;
}
}
@@ -11958,11 +12100,16 @@ option_value:
}
| '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
{
- LEX *lex=Lex;
- set_var *var= new set_var($3, $4.var, &$4.base_name, $6);
- if (var == NULL)
+ THD *thd= YYTHD;
+ struct sys_var_with_base tmp= $4;
+ /* Lookup if necessary: must be a system variable. */
+ if (tmp.var == NULL)
+ {
+ if (find_sys_var_null_base(thd, &tmp))
+ MYSQL_YYABORT;
+ }
+ if (set_system_variable(thd, &tmp, $3, $6))
MYSQL_YYABORT;
- lex->var_list.push_back(var);
}
| charset old_or_new_charset_name_or_default
{
@@ -12055,31 +12202,26 @@ internal_variable_name:
ident
{
THD *thd= YYTHD;
- LEX *lex= thd->lex;
- sp_pcontext *spc= lex->spcont;
+ sp_pcontext *spc= thd->lex->spcont;
sp_variable_t *spv;
- /* We have to lookup here since local vars can shadow sysvars */
+ /* Best effort lookup for system variable. */
if (!spc || !(spv = spc->find_variable(&$1)))
{
+ struct sys_var_with_base tmp= {NULL, $1};
+
/* Not an SP local variable */
- sys_var *tmp=find_sys_var(thd, $1.str, $1.length);
- if (!tmp)
+ if (find_sys_var_null_base(thd, &tmp))
MYSQL_YYABORT;
- $$.var= tmp;
- $$.base_name= null_lex_str;
- if (spc && tmp == &sys_autocommit)
- {
- /*
- We don't allow setting AUTOCOMMIT from a stored function
- or trigger.
- */
- lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
- }
+
+ $$= tmp;
}
else
{
- /* An SP local variable */
+ /*
+ Possibly an SP local variable (or a shadowed sysvar).
+ Will depend on the context of the SET statement.
+ */
$$.var= NULL;
$$.base_name= $1;
}
@@ -12237,12 +12379,7 @@ lock_option:
| WRITE_SYM { $$= TL_WRITE_DEFAULT; }
| WRITE_SYM CONCURRENT
{
-#ifdef HAVE_QUERY_CACHE
- if (Lex->sphead != 0)
- $$= TL_WRITE_DEFAULT;
- else
-#endif
- $$= TL_WRITE_CONCURRENT_INSERT;
+ $$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
}
| LOW_PRIORITY WRITE_SYM { $$= TL_WRITE_LOW_PRIORITY; }
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2009-12-03 11:34:11 +0000
+++ b/sql/table.cc 2010-03-10 10:32:14 +0000
@@ -212,10 +212,7 @@ TABLE_CATEGORY get_table_category(const
DBUG_ASSERT(db != NULL);
DBUG_ASSERT(name != NULL);
- if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
- (my_strcasecmp(system_charset_info,
- INFORMATION_SCHEMA_NAME.str,
- db->str) == 0))
+ if (is_schema_db(db->str, db->length))
{
return TABLE_CATEGORY_INFORMATION;
}
@@ -899,7 +896,7 @@ static int open_binary_frm(THD *thd, TAB
replacing it with a globally locked version of tmp_plugin
*/
plugin_unlock(NULL, share->db_plugin);
- share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
+ share->db_plugin= my_plugin_lock(NULL, tmp_plugin);
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
str_db_type_length, next_chunk + 2,
ha_legacy_type(share->db_type())));
@@ -1316,8 +1313,16 @@ static int open_binary_frm(THD *thd, TAB
share->timestamp_field_offset= i;
if (use_hash)
- (void) my_hash_insert(&share->name_hash,
- (uchar*) field_ptr); // never fail
+ if (my_hash_insert(&share->name_hash, (uchar*) field_ptr) )
+ {
+ /*
+ Set return code 8 here to indicate that an error has
+ occurred but that the error message already has been
+ sent (OOM).
+ */
+ error= 8;
+ goto err;
+ }
}
*field_ptr=0; // End marker
@@ -1842,8 +1847,8 @@ int open_table_from_share(THD *thd, TABL
{
if (work_part_info_used)
tmp= fix_partition_func(thd, outparam, is_create_table);
- outparam->part_info->item_free_list= part_func_arena.free_list;
}
+ outparam->part_info->item_free_list= part_func_arena.free_list;
partititon_err:
if (tmp)
{
@@ -1969,7 +1974,11 @@ int closefrm(register TABLE *table, bool
DBUG_PRINT("enter", ("table: 0x%lx", (long) table));
if (table->db_stat)
+ {
+ if (table->s->deleting)
+ table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
error=table->file->close();
+ }
my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
table->alias= 0;
if (table->field)
@@ -2044,6 +2053,8 @@ ulong get_form_pos(File file, uchar *hea
ulong ret_value=0;
DBUG_ENTER("get_form_pos");
+ LINT_INIT(buf);
+
names=uint2korr(head+8);
a_length=(names+2)*sizeof(char *); /* Room for two extra */
@@ -2804,34 +2815,38 @@ bool check_column_name(const char *name)
and such errors never reach the user.
*/
-my_bool
-table_check_intact(TABLE *table, const uint table_f_count,
- const TABLE_FIELD_W_TYPE *table_def)
+bool
+Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
{
uint i;
my_bool error= FALSE;
- my_bool fields_diff_count;
+ const TABLE_FIELD_TYPE *field_def= table_def->field;
DBUG_ENTER("table_check_intact");
DBUG_PRINT("info",("table: %s expected_count: %d",
- table->alias, table_f_count));
+ table->alias, table_def->count));
- fields_diff_count= (table->s->fields != table_f_count);
- if (fields_diff_count)
+ /* Whether the table definition has already been validated. */
+ if (table->s->table_field_def_cache == table_def)
+ DBUG_RETURN(FALSE);
+
+ if (table->s->fields != table_def->count)
{
DBUG_PRINT("info", ("Column count has changed, checking the definition"));
/* previous MySQL version */
if (MYSQL_VERSION_ID > table->s->mysql_version)
{
- sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
- table->alias, table_f_count, table->s->fields,
- table->s->mysql_version, MYSQL_VERSION_ID);
+ report_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE,
+ ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
+ table->alias, table_def->count, table->s->fields,
+ table->s->mysql_version, MYSQL_VERSION_ID);
DBUG_RETURN(TRUE);
}
else if (MYSQL_VERSION_ID == table->s->mysql_version)
{
- sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias,
- table_f_count, table->s->fields);
+ report_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED,
+ ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias,
+ table_def->count, table->s->fields);
DBUG_RETURN(TRUE);
}
/*
@@ -2843,7 +2858,7 @@ table_check_intact(TABLE *table, const u
*/
}
char buffer[STRING_BUFFER_USUAL_SIZE];
- for (i=0 ; i < table_f_count; i++, table_def++)
+ for (i=0 ; i < table_def->count; i++, field_def++)
{
String sql_type(buffer, sizeof(buffer), system_charset_info);
sql_type.length(0);
@@ -2851,18 +2866,18 @@ table_check_intact(TABLE *table, const u
{
Field *field= table->field[i];
- if (strncmp(field->field_name, table_def->name.str,
- table_def->name.length))
+ if (strncmp(field->field_name, field_def->name.str,
+ field_def->name.length))
{
/*
Name changes are not fatal, we use ordinal numbers to access columns.
Still this can be a sign of a tampered table, output an error
to the error log.
*/
- sql_print_error("Incorrect definition of table %s.%s: "
- "expected column '%s' at position %d, found '%s'.",
- table->s->db.str, table->alias, table_def->name.str, i,
- field->field_name);
+ report_error(0, "Incorrect definition of table %s.%s: "
+ "expected column '%s' at position %d, found '%s'.",
+ table->s->db.str, table->alias, field_def->name.str, i,
+ field->field_name);
}
field->sql_type(sql_type);
/*
@@ -2882,47 +2897,51 @@ table_check_intact(TABLE *table, const u
the new table definition is backward compatible with the
original one.
*/
- if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
- table_def->type.length - 1))
+ if (strncmp(sql_type.c_ptr_safe(), field_def->type.str,
+ field_def->type.length - 1))
{
- sql_print_error("Incorrect definition of table %s.%s: "
- "expected column '%s' at position %d to have type "
- "%s, found type %s.", table->s->db.str, table->alias,
- table_def->name.str, i, table_def->type.str,
- sql_type.c_ptr_safe());
+ report_error(0, "Incorrect definition of table %s.%s: "
+ "expected column '%s' at position %d to have type "
+ "%s, found type %s.", table->s->db.str, table->alias,
+ field_def->name.str, i, field_def->type.str,
+ sql_type.c_ptr_safe());
error= TRUE;
}
- else if (table_def->cset.str && !field->has_charset())
+ else if (field_def->cset.str && !field->has_charset())
{
- sql_print_error("Incorrect definition of table %s.%s: "
- "expected the type of column '%s' at position %d "
- "to have character set '%s' but the type has no "
- "character set.", table->s->db.str, table->alias,
- table_def->name.str, i, table_def->cset.str);
+ report_error(0, "Incorrect definition of table %s.%s: "
+ "expected the type of column '%s' at position %d "
+ "to have character set '%s' but the type has no "
+ "character set.", table->s->db.str, table->alias,
+ field_def->name.str, i, field_def->cset.str);
error= TRUE;
}
- else if (table_def->cset.str &&
- strcmp(field->charset()->csname, table_def->cset.str))
+ else if (field_def->cset.str &&
+ strcmp(field->charset()->csname, field_def->cset.str))
{
- sql_print_error("Incorrect definition of table %s.%s: "
- "expected the type of column '%s' at position %d "
- "to have character set '%s' but found "
- "character set '%s'.", table->s->db.str, table->alias,
- table_def->name.str, i, table_def->cset.str,
- field->charset()->csname);
+ report_error(0, "Incorrect definition of table %s.%s: "
+ "expected the type of column '%s' at position %d "
+ "to have character set '%s' but found "
+ "character set '%s'.", table->s->db.str, table->alias,
+ field_def->name.str, i, field_def->cset.str,
+ field->charset()->csname);
error= TRUE;
}
}
else
{
- sql_print_error("Incorrect definition of table %s.%s: "
- "expected column '%s' at position %d to have type %s "
- " but the column is not found.",
- table->s->db.str, table->alias,
- table_def->name.str, i, table_def->type.str);
+ report_error(0, "Incorrect definition of table %s.%s: "
+ "expected column '%s' at position %d to have type %s "
+ " but the column is not found.",
+ table->s->db.str, table->alias,
+ field_def->name.str, i, field_def->type.str);
error= TRUE;
}
}
+
+ if (! error)
+ table->s->table_field_def_cache= table_def;
+
DBUG_RETURN(error);
}
=== modified file 'sql/table.h'
--- a/sql/table.h 2009-12-03 11:19:05 +0000
+++ b/sql/table.h 2010-02-10 19:06:24 +0000
@@ -285,6 +285,36 @@ typedef enum enum_table_category TABLE_C
TABLE_CATEGORY get_table_category(const LEX_STRING *db,
const LEX_STRING *name);
+
+typedef struct st_table_field_type
+{
+ LEX_STRING name;
+ LEX_STRING type;
+ LEX_STRING cset;
+} TABLE_FIELD_TYPE;
+
+
+typedef struct st_table_field_def
+{
+ uint count;
+ const TABLE_FIELD_TYPE *field;
+} TABLE_FIELD_DEF;
+
+
+class Table_check_intact
+{
+protected:
+ virtual void report_error(uint code, const char *fmt, ...)= 0;
+
+public:
+ Table_check_intact() {}
+ virtual ~Table_check_intact() {}
+
+ /** Checks whether a table is intact. */
+ bool check(TABLE *table, const TABLE_FIELD_DEF *table_def);
+};
+
+
/*
This structure is shared between different table objects. There is one
instance of table share per one table in the database.
@@ -401,6 +431,7 @@ typedef struct st_table_share
bool is_view;
bool name_lock, replace_with_name_lock;
bool waiting_on_cond; /* Protection against free */
+ bool deleting; /* going to delete this table */
ulong table_map_id; /* for row-based replication */
ulonglong table_map_version;
@@ -423,6 +454,18 @@ typedef struct st_table_share
handlerton *default_part_db_type;
#endif
+ /**
+ Cache the checked structure of this table.
+
+ The pointer data is used to describe the structure that
+ a instance of the table must have. Each element of the
+ array specifies a field that must exist on the table.
+
+ The pointer is cached in order to perform the check only
+ once -- when the table is loaded from the disk.
+ */
+ const TABLE_FIELD_DEF *table_field_def_cache;
+
/** place to store storage engine specific data */
void *ha_data;
@@ -1337,7 +1380,7 @@ struct TABLE_LIST
*/
bool create;
bool internal_tmp_table;
-
+ bool deleting; /* going to delete this table */
/* View creation context. */
@@ -1674,17 +1717,6 @@ typedef struct st_open_table_list{
uint32 in_use,locked;
} OPEN_TABLE_LIST;
-typedef struct st_table_field_w_type
-{
- LEX_STRING name;
- LEX_STRING type;
- LEX_STRING cset;
-} TABLE_FIELD_W_TYPE;
-
-
-my_bool
-table_check_intact(TABLE *table, const uint table_f_count,
- const TABLE_FIELD_W_TYPE *table_def);
static inline my_bitmap_map *tmp_use_all_columns(TABLE *table,
MY_BITMAP *bitmap)
=== modified file 'sql/udf_example.def'
--- a/sql/udf_example.def 2007-10-29 14:01:40 +0000
+++ b/sql/udf_example.def 2010-01-29 18:42:22 +0000
@@ -3,8 +3,10 @@ VERSION 1.0
EXPORTS
lookup
lookup_init
+ lookup_deinit
reverse_lookup
reverse_lookup_init
+ reverse_lookup_deinit
metaphon_init
metaphon_deinit
metaphon
=== modified file 'storage/archive/CMakeLists.txt' (properties changed: -x to +x)
--- a/storage/archive/CMakeLists.txt 2009-06-10 08:59:49 +0000
+++ b/storage/archive/CMakeLists.txt 2009-11-10 19:41:43 +0000
@@ -13,6 +13,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
SET(ARCHIVE_SOURCES azio.c ha_archive.cc ha_archive.h)
MYSQL_STORAGE_ENGINE(ARCHIVE)
=== modified file 'storage/archive/azio.c'
--- a/storage/archive/azio.c 2009-05-22 12:38:50 +0000
+++ b/storage/archive/azio.c 2010-01-15 15:27:55 +0000
@@ -71,7 +71,8 @@ int az_open (azio_stream *s, const char
s->transparent = 0;
s->mode = 'r';
s->version = (unsigned char)az_magic[1]; /* this needs to be a define to version */
- s->version = (unsigned char)az_magic[2]; /* minor version */
+ s->minor_version= (unsigned char) az_magic[2]; /* minor version */
+ s->dirty= AZ_STATE_CLEAN;
/*
We do our own version of append by nature.
@@ -354,10 +355,19 @@ void read_header(azio_stream *s, unsigne
s->comment_length= (unsigned int)uint4korr(buffer + AZ_COMMENT_LENGTH_POS);
s->dirty= (unsigned int)buffer[AZ_DIRTY_POS];
}
- else
+ else if (buffer[0] == gz_magic[0] && buffer[1] == gz_magic[1])
{
- DBUG_ASSERT(buffer[0] == az_magic[0] && buffer[1] == az_magic[1]);
- return;
+ /*
+ Set version number to previous version (2).
+ */
+ s->version= (unsigned char) 2;
+ } else {
+ /*
+ Unknown version.
+ Most probably due to a corrupt archive.
+ */
+ s->dirty= AZ_STATE_DIRTY;
+ s->z_err= Z_VERSION_ERROR;
}
}
=== modified file 'storage/archive/azlib.h'
--- a/storage/archive/azlib.h 2009-02-13 16:41:47 +0000
+++ b/storage/archive/azlib.h 2010-01-06 21:27:53 +0000
@@ -33,10 +33,9 @@
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
*/
-#include <zlib.h>
-
#include "../../mysys/mysys_priv.h"
#include <my_dir.h>
+#include <zlib.h>
#ifdef __cplusplus
extern "C" {
=== modified file 'storage/archive/ha_archive.cc'
--- a/storage/archive/ha_archive.cc 2009-12-03 11:19:05 +0000
+++ b/storage/archive/ha_archive.cc 2010-03-04 08:03:07 +0000
@@ -360,6 +360,12 @@ ARCHIVE_SHARE *ha_archive::get_share(con
stats.auto_increment_value= archive_tmp.auto_increment + 1;
share->rows_recorded= (ha_rows)archive_tmp.rows;
share->crashed= archive_tmp.dirty;
+ /*
+ If archive version is less than 3, It should be upgraded before
+ use.
+ */
+ if (archive_tmp.version < ARCHIVE_VERSION)
+ *rc= HA_ERR_TABLE_NEEDS_UPGRADE;
azclose(&archive_tmp);
VOID(my_hash_insert(&archive_open_tables, (uchar*) share));
@@ -491,7 +497,15 @@ int ha_archive::open(const char *name, i
(open_options & HA_OPEN_FOR_REPAIR) ? "yes" : "no"));
share= get_share(name, &rc);
- if (rc == HA_ERR_CRASHED_ON_USAGE && !(open_options & HA_OPEN_FOR_REPAIR))
+ /*
+ Allow open on crashed table in repair mode only.
+ Block open on 5.0 ARCHIVE table. Though we have almost all
+ routines to access these tables, they were not well tested.
+ For now we have to refuse to open such table to avoid
+ potential data loss.
+ */
+ if ((rc == HA_ERR_CRASHED_ON_USAGE && !(open_options & HA_OPEN_FOR_REPAIR))
+ || rc == HA_ERR_TABLE_NEEDS_UPGRADE)
{
/* purecov: begin inspected */
free_share();
@@ -1476,7 +1490,7 @@ int ha_archive::info(uint flag)
stats.create_time= (ulong) file_stat.st_ctime;
stats.update_time= (ulong) file_stat.st_mtime;
stats.mean_rec_length= stats.records ?
- stats.data_file_length / stats.records : table->s->reclength;
+ ulong(stats.data_file_length / stats.records) : table->s->reclength;
stats.max_data_file_length= MAX_FILE_SIZE;
}
stats.delete_length= 0;
=== modified file 'storage/example/ha_example.h'
--- a/storage/example/ha_example.h 2007-08-13 13:11:25 +0000
+++ b/storage/example/ha_example.h 2010-03-28 18:10:00 +0000
@@ -155,7 +155,8 @@ public:
/** @brief
This method will never be called if you do not implement indexes.
*/
- virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
+ virtual double read_time(uint index, uint ranges, ha_rows rows)
+ { return (double) rows / 20.0+1; }
/*
Everything below are methods that we implement in ha_example.cc.
=== modified file 'storage/federated/CMakeLists.txt' (properties changed: -x to +x)
--- a/storage/federated/CMakeLists.txt 2009-06-10 08:59:49 +0000
+++ b/storage/federated/CMakeLists.txt 2009-11-10 19:41:43 +0000
@@ -1,18 +1,21 @@
# Copyright (C) 2006 MySQL AB
-#
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
SET(FEDERATED_SOURCES ha_federated.cc)
MYSQL_STORAGE_ENGINE(FEDERATED)
=== modified file 'storage/federatedx/ha_federatedx.cc'
--- a/storage/federatedx/ha_federatedx.cc 2009-12-03 11:34:11 +0000
+++ b/storage/federatedx/ha_federatedx.cc 2010-03-10 10:32:14 +0000
@@ -1783,7 +1783,7 @@ int ha_federatedx::open(const char *name
int ha_federatedx::close(void)
{
- int retval, error;
+ int retval= 0, error;
THD *thd= current_thd;
DBUG_ENTER("ha_federatedx::close");
=== modified file 'storage/ibmdb2i/db2i_constraints.cc'
--- a/storage/ibmdb2i/db2i_constraints.cc 2009-03-09 21:20:14 +0000
+++ b/storage/ibmdb2i/db2i_constraints.cc 2009-12-11 07:16:57 +0000
@@ -329,7 +329,7 @@ char* ha_ibmdb2i::get_foreign_key_create
/* Process the constraint name. */
- info.strncat(STRING_WITH_LEN(" CONSTRAINT "));
+ info.strncat(STRING_WITH_LEN(",\n CONSTRAINT "));
convNameForCreateInfo(thd, info,
FKCstDef->CstName.Name, FKCstDef->CstName.Len);
@@ -398,7 +398,6 @@ char* ha_ibmdb2i::get_foreign_key_create
if ((i+1) < cstCnt)
{
- info.strcat(',');
tempPtr = (char*)cstHdr + cstHdr->CstLen;
cstHdr = (constraint_hdr_t*)(tempPtr);
}
@@ -671,28 +670,3 @@ uint ha_ibmdb2i::referenced_by_foreign_k
}
DBUG_RETURN(count);
}
-
-
-bool ha_ibmdb2i::check_if_incompatible_data(HA_CREATE_INFO *info,
- uint table_changes)
-{
- DBUG_ENTER("ha_ibmdb2i::check_if_incompatible_data");
- uint i;
- /* Check that auto_increment value and field definitions were
- not changed. */
- if ((info->used_fields & HA_CREATE_USED_AUTO &&
- info->auto_increment_value != 0) ||
- table_changes != IS_EQUAL_YES)
- DBUG_RETURN(COMPATIBLE_DATA_NO);
- /* Check if any fields were renamed. */
- for (i= 0; i < table->s->fields; i++)
- {
- Field *field= table->field[i];
- if (field->flags & FIELD_IS_RENAMED)
- {
- DBUG_PRINT("info", ("Field has been renamed, copy table"));
- DBUG_RETURN(COMPATIBLE_DATA_NO);
- }
- }
- DBUG_RETURN(COMPATIBLE_DATA_YES);
-}
=== modified file 'storage/ibmdb2i/ha_ibmdb2i.cc'
--- a/storage/ibmdb2i/ha_ibmdb2i.cc 2009-07-08 09:10:01 +0000
+++ b/storage/ibmdb2i/ha_ibmdb2i.cc 2009-12-11 07:01:16 +0000
@@ -284,7 +284,7 @@ static int ibmdb2i_init_func(void *p)
was_ILE_inited = false;
ibmdb2i_hton= (handlerton *)p;
VOID(pthread_mutex_init(&ibmdb2i_mutex,MY_MUTEX_INIT_FAST));
- (void) hash_init(&ibmdb2i_open_tables,system_charset_info,32,0,0,
+ (void) hash_init(&ibmdb2i_open_tables,table_alias_charset,32,0,0,
(hash_get_key) ibmdb2i_get_key,0,0);
ibmdb2i_hton->state= SHOW_OPTION_YES;
=== modified file 'storage/innobase/btr/btr0btr.c'
--- a/storage/innobase/btr/btr0btr.c 2007-07-10 14:34:21 +0000
+++ b/storage/innobase/btr/btr0btr.c 2009-11-30 08:50:08 +0000
@@ -709,8 +709,15 @@ btr_create(
} else {
/* It is a non-ibuf tree: create a file segment for leaf
pages */
- fseg_create(space, page_no, PAGE_HEADER + PAGE_BTR_SEG_LEAF,
- mtr);
+ if (!fseg_create(space, page_no,
+ PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
+ /* Not enough space for new segment, free root
+ segment before return. */
+ btr_free_root(space, page_no, mtr);
+
+ return(FIL_NULL);
+ }
+
/* The fseg create acquires a second latch on the page,
therefore we must declare it: */
#ifdef UNIV_SYNC_DEBUG
=== modified file 'storage/innobase/data/data0type.c'
--- a/storage/innobase/data/data0type.c 2007-07-10 11:37:43 +0000
+++ b/storage/innobase/data/data0type.c 2009-11-30 08:53:52 +0000
@@ -252,6 +252,22 @@ dtype_print(
fputs("DATA_SYS", stderr);
break;
+ case DATA_FLOAT:
+ fputs("DATA_FLOAT", stderr);
+ break;
+
+ case DATA_DOUBLE:
+ fputs("DATA_DOUBLE", stderr);
+ break;
+
+ case DATA_DECIMAL:
+ fputs("DATA_DECIMAL", stderr);
+ break;
+
+ case DATA_VARMYSQL:
+ fputs("DATA_VARMYSQL", stderr);
+ break;
+
default:
fprintf(stderr, "type %lu", (ulong) mtype);
break;
=== modified file 'storage/innobase/fil/fil0fil.c'
--- a/storage/innobase/fil/fil0fil.c 2009-07-10 10:40:31 +0000
+++ b/storage/innobase/fil/fil0fil.c 2009-12-21 10:20:32 +0000
@@ -1740,6 +1740,8 @@ fil_op_write_log(
MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
ulint space_id, /* in: space id */
+ ulint log_flags, /* in: redo log flags (stored
+ in the page number field) */
const char* name, /* in: table name in the familiar
'databasename/tablename' format, or
the file path in the case of
@@ -1760,8 +1762,8 @@ fil_op_write_log(
return;
}
- log_ptr = mlog_write_initial_log_record_for_file_op(type, space_id, 0,
- log_ptr, mtr);
+ log_ptr = mlog_write_initial_log_record_for_file_op(
+ type, space_id, log_flags, log_ptr, mtr);
/* Let us store the strings as null-terminated for easier readability
and handling */
@@ -1810,11 +1812,11 @@ fil_op_log_parse_or_replay(
not fir completely between ptr and end_ptr */
byte* end_ptr, /* in: buffer end */
ulint type, /* in: the type of this log record */
- ibool do_replay, /* in: TRUE if we want to replay the
- operation, and not just parse the log record */
- ulint space_id) /* in: if do_replay is TRUE, the space id of
- the tablespace in question; otherwise
- ignored */
+ ulint space_id, /* in: the space id of the tablespace in
+ question, or 0 if the log record should
+ only be parsed but not replayed */
+ ulint log_flags) /* in: redo log flags
+ (stored in the page number parameter) */
{
ulint name_len;
ulint new_name_len;
@@ -1868,7 +1870,7 @@ fil_op_log_parse_or_replay(
printf("new name %s\n", new_name);
}
*/
- if (do_replay == FALSE) {
+ if (!space_id) {
return(ptr);
}
@@ -1917,6 +1919,8 @@ fil_op_log_parse_or_replay(
} else if (fil_get_space_id_for_table(name)
!= ULINT_UNDEFINED) {
/* Do nothing */
+ } else if (log_flags & MLOG_FILE_FLAG_TEMP) {
+ /* Temporary table, do nothing */
} else {
/* Create the database directory for name, if it does
not exist yet */
@@ -2078,7 +2082,7 @@ try_again:
to write any log record */
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_DELETE, id, path, NULL, &mtr);
+ fil_op_write_log(MLOG_FILE_DELETE, id, 0, path, NULL, &mtr);
mtr_commit(&mtr);
#endif
mem_free(path);
@@ -2349,7 +2353,7 @@ retry:
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_RENAME, id, old_name, new_name,
+ fil_op_write_log(MLOG_FILE_RENAME, id, 0, old_name, new_name,
&mtr);
mtr_commit(&mtr);
}
@@ -2525,8 +2529,9 @@ error_exit2:
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_CREATE, *space_id, tablename,
- NULL, &mtr);
+ fil_op_write_log(MLOG_FILE_CREATE, *space_id,
+ is_temp ? MLOG_FILE_FLAG_TEMP : 0,
+ tablename, NULL, &mtr);
mtr_commit(&mtr);
}
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc 2009-12-03 11:19:05 +0000
+++ b/storage/innobase/handler/ha_innodb.cc 2010-03-04 08:03:07 +0000
@@ -40,12 +40,6 @@ have disabled the InnoDB inlining in thi
#include "ha_innodb.h"
#include <mysql/plugin.h>
-#ifndef MYSQL_SERVER
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
-is defined the same in both builds: the MySQL server and the InnoDB plugin. */
-extern pthread_mutex_t LOCK_thread_count;
-#endif /* MYSQL_SERVER */
-
/** to protect innobase_open_files */
static pthread_mutex_t innobase_share_mutex;
/** to force correct commit order in binlog */
@@ -662,6 +656,12 @@ convert_error_code_to_mysql(
} else if (error == (int) DB_DUPLICATE_KEY) {
+ /* Be cautious with returning this error, since
+ mysql could re-enter the storage layer to get
+ duplicated key info, the operation requires a
+ valid table handle and/or transaction information,
+ which might not always be available in the error
+ handling stage. */
return(HA_ERR_FOUND_DUPP_KEY);
} else if (error == (int) DB_FOREIGN_DUPLICATE_KEY) {
@@ -765,35 +765,6 @@ convert_error_code_to_mysql(
}
/*****************************************************************
-If you want to print a thd that is not associated with the current thread,
-you must call this function before reserving the InnoDB kernel_mutex, to
-protect MySQL from setting thd->query NULL. If you print a thd of the current
-thread, we know that MySQL cannot modify thd->query, and it is not necessary
-to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release
-the kernel_mutex.
-NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
-function! */
-extern "C"
-void
-innobase_mysql_prepare_print_arbitrary_thd(void)
-/*============================================*/
-{
- VOID(pthread_mutex_lock(&LOCK_thread_count));
-}
-
-/*****************************************************************
-Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
-NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
-function! */
-extern "C"
-void
-innobase_mysql_end_print_arbitrary_thd(void)
-/*========================================*/
-{
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
-}
-
-/*****************************************************************
Prints info of a THD object (== user session thread) to the given file.
NOTE that /mysql/innobase/trx/trx0trx.c must contain the prototype for
this function! */
@@ -1499,70 +1470,148 @@ innobase_invalidate_query_cache(
#endif
}
-/*********************************************************************
-Display an SQL identifier. */
-extern "C"
-void
-innobase_print_identifier(
-/*======================*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction */
- ibool table_id,/* in: TRUE=print a table name,
- FALSE=print other identifier */
- const char* name, /* in: name to print */
- ulint namelen)/* in: length of name */
-{
- const char* s = name;
- char* qname = NULL;
+/*****************************************************************//**
+Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
+and quote it if needed.
+@return pointer to the end of buf */
+static
+char*
+innobase_convert_identifier(
+/*========================*/
+ char* buf, /*!< out: buffer for converted identifier */
+ ulint buflen, /*!< in: length of buf, in bytes */
+ const char* id, /*!< in: identifier to convert */
+ ulint idlen, /*!< in: length of id, in bytes */
+ void* thd, /*!< in: MySQL connection thread, or NULL */
+ ibool file_id)/*!< in: TRUE=id is a table or database name;
+ FALSE=id is an UTF-8 string */
+{
+ char nz[NAME_LEN + 1];
+#if MYSQL_VERSION_ID >= 50141
+ char nz2[NAME_LEN + 1 + EXPLAIN_FILENAME_MAX_EXTRA_LENGTH];
+#else /* MYSQL_VERSION_ID >= 50141 */
+ char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
+#endif /* MYSQL_VERSION_ID >= 50141 */
+
+ const char* s = id;
int q;
- if (table_id) {
- /* Decode the table name. The filename_to_tablename()
- function expects a NUL-terminated string. The input and
- output strings buffers must not be shared. The function
- only produces more output when the name contains other
- characters than [0-9A-Z_a-z]. */
- char* temp_name = (char*) my_malloc((uint) namelen + 1, MYF(MY_WME));
- uint qnamelen = (uint) (namelen
- + (1 + sizeof srv_mysql50_table_name_prefix));
-
- if (temp_name) {
- qname = (char*) my_malloc(qnamelen, MYF(MY_WME));
- if (qname) {
- memcpy(temp_name, name, namelen);
- temp_name[namelen] = 0;
- s = qname;
- namelen = filename_to_tablename(temp_name,
- qname, qnamelen);
- }
- my_free(temp_name, MYF(0));
- }
+ if (file_id) {
+ /* Decode the table name. The MySQL function expects
+ a NUL-terminated string. The input and output strings
+ buffers must not be shared. */
+
+ if (UNIV_UNLIKELY(idlen > (sizeof nz) - 1)) {
+ idlen = (sizeof nz) - 1;
+ }
+
+ memcpy(nz, id, idlen);
+ nz[idlen] = 0;
+
+ s = nz2;
+#if MYSQL_VERSION_ID >= 50141
+ idlen = explain_filename((THD*) thd, nz, nz2, sizeof nz2,
+ EXPLAIN_PARTITIONS_AS_COMMENT);
+ goto no_quote;
+#else /* MYSQL_VERSION_ID >= 50141 */
+ idlen = filename_to_tablename(nz, nz2, sizeof nz2);
+#endif /* MYSQL_VERSION_ID >= 50141 */
}
- if (!trx || !trx->mysql_thd) {
-
+ /* See if the identifier needs to be quoted. */
+ if (UNIV_UNLIKELY(!thd)) {
q = '"';
} else {
- q = get_quote_char_for_identifier((THD*) trx->mysql_thd,
- s, (int) namelen);
+ q = get_quote_char_for_identifier((THD*) thd, s, (int) idlen);
}
if (q == EOF) {
- fwrite(s, 1, namelen, f);
- } else {
- const char* e = s + namelen;
- putc(q, f);
- while (s < e) {
- int c = *s++;
- if (c == q) {
- putc(c, f);
+#if MYSQL_VERSION_ID >= 50141
+no_quote:
+#endif /* MYSQL_VERSION_ID >= 50141 */
+ if (UNIV_UNLIKELY(idlen > buflen)) {
+ idlen = buflen;
+ }
+ memcpy(buf, s, idlen);
+ return(buf + idlen);
+ }
+
+ /* Quote the identifier. */
+ if (buflen < 2) {
+ return(buf);
+ }
+
+ *buf++ = q;
+ buflen--;
+
+ for (; idlen; idlen--) {
+ int c = *s++;
+ if (UNIV_UNLIKELY(c == q)) {
+ if (UNIV_UNLIKELY(buflen < 3)) {
+ break;
+ }
+
+ *buf++ = c;
+ *buf++ = c;
+ buflen -= 2;
+ } else {
+ if (UNIV_UNLIKELY(buflen < 2)) {
+ break;
}
- putc(c, f);
+
+ *buf++ = c;
+ buflen--;
}
- putc(q, f);
}
- my_free(qname, MYF(MY_ALLOW_ZERO_PTR));
+ *buf++ = q;
+ return(buf);
+}
+
+/*****************************************************************//**
+Convert a table or index name to the MySQL system_charset_info (UTF-8)
+and quote it if needed.
+@return pointer to the end of buf */
+extern "C"
+char*
+innobase_convert_name(
+/*==================*/
+ char* buf, /*!< out: buffer for converted identifier */
+ ulint buflen, /*!< in: length of buf, in bytes */
+ const char* id, /*!< in: identifier to convert */
+ ulint idlen, /*!< in: length of id, in bytes */
+ void* thd, /*!< in: MySQL connection thread, or NULL */
+ ibool table_id)/*!< in: TRUE=id is a table or database name;
+ FALSE=id is an index name */
+{
+ char* s = buf;
+ const char* bufend = buf + buflen;
+
+ if (table_id) {
+ const char* slash = (const char*) memchr(id, '/', idlen);
+ if (!slash) {
+
+ goto no_db_name;
+ }
+
+ /* Print the database name and table name separately. */
+ s = innobase_convert_identifier(s, bufend - s, id, slash - id,
+ thd, TRUE);
+ if (UNIV_LIKELY(s < bufend)) {
+ *s++ = '.';
+ s = innobase_convert_identifier(s, bufend - s,
+ slash + 1, idlen
+ - (slash - id) - 1,
+ thd, TRUE);
+ }
+ } else {
+no_db_name:
+ s = innobase_convert_identifier(buf, buflen, id, idlen,
+ thd, table_id);
+ }
+
+ return(s);
+
}
/**************************************************************************
@@ -2537,57 +2586,150 @@ normalize_table_name(
}
/************************************************************************
+Get the upper limit of the MySQL integral and floating-point type. */
+static
+ulonglong
+innobase_get_int_col_max_value(
+/*===========================*/
+ /* out: maximum allowed value for the field */
+ const Field* field) /* in: MySQL field */
+{
+ ulonglong max_value = 0;
+
+ switch(field->key_type()) {
+ /* TINY */
+ case HA_KEYTYPE_BINARY:
+ max_value = 0xFFULL;
+ break;
+ case HA_KEYTYPE_INT8:
+ max_value = 0x7FULL;
+ break;
+ /* SHORT */
+ case HA_KEYTYPE_USHORT_INT:
+ max_value = 0xFFFFULL;
+ break;
+ case HA_KEYTYPE_SHORT_INT:
+ max_value = 0x7FFFULL;
+ break;
+ /* MEDIUM */
+ case HA_KEYTYPE_UINT24:
+ max_value = 0xFFFFFFULL;
+ break;
+ case HA_KEYTYPE_INT24:
+ max_value = 0x7FFFFFULL;
+ break;
+ /* LONG */
+ case HA_KEYTYPE_ULONG_INT:
+ max_value = 0xFFFFFFFFULL;
+ break;
+ case HA_KEYTYPE_LONG_INT:
+ max_value = 0x7FFFFFFFULL;
+ break;
+ /* BIG */
+ case HA_KEYTYPE_ULONGLONG:
+ max_value = 0xFFFFFFFFFFFFFFFFULL;
+ break;
+ case HA_KEYTYPE_LONGLONG:
+ max_value = 0x7FFFFFFFFFFFFFFFULL;
+ break;
+ case HA_KEYTYPE_FLOAT:
+ /* We use the maximum as per IEEE754-2008 standard, 2^24 */
+ max_value = 0x1000000ULL;
+ break;
+ case HA_KEYTYPE_DOUBLE:
+ /* We use the maximum as per IEEE754-2008 standard, 2^53 */
+ max_value = 0x20000000000000ULL;
+ break;
+ default:
+ ut_error;
+ }
+
+ return(max_value);
+}
+
+/************************************************************************
Set the autoinc column max value. This should only be called once from
ha_innobase::open(). Therefore there's no need for a covering lock. */
-ulong
+void
ha_innobase::innobase_initialize_autoinc()
/*======================================*/
{
- dict_index_t* index;
ulonglong auto_inc;
- const char* col_name;
- ulint error = DB_SUCCESS;
- dict_table_t* innodb_table = prebuilt->table;
+ const Field* field = table->found_next_number_field;
- col_name = table->found_next_number_field->field_name;
- index = innobase_get_index(table->s->next_number_index);
-
- /* Execute SELECT MAX(col_name) FROM TABLE; */
- error = row_search_max_autoinc(index, col_name, &auto_inc);
+ if (field != NULL) {
+ auto_inc = innobase_get_int_col_max_value(field);
+ } else {
+ /* We have no idea what's been passed in to us as the
+ autoinc column. We set it to the MAX_INT of our table
+ autoinc type. */
+ auto_inc = 0xFFFFFFFFFFFFFFFFULL;
- if (error == DB_SUCCESS) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Unable to determine the AUTOINC "
+ "column name\n");
+ }
- /* At the this stage we dont' know the increment
- or the offset, so use default inrement of 1. */
- ++auto_inc;
+ if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
+ /* If the recovery level is set so high that writes
+ are disabled we force the AUTOINC counter to the MAX
+ value effectively disabling writes to the table.
+ Secondly, we avoid reading the table in case the read
+ results in failure due to a corrupted table/index.
+
+ We will not return an error to the client, so that the
+ tables can be dumped with minimal hassle. If an error
+ were returned in this case, the first attempt to read
+ the table would fail and subsequent SELECTs would succeed. */
+ } else if (field == NULL) {
+ my_error(ER_AUTOINC_READ_FAILED, MYF(0));
+ } else {
+ dict_index_t* index;
+ const char* col_name;
+ ulonglong read_auto_inc;
+ ulint err;
- dict_table_autoinc_initialize(innodb_table, auto_inc);
+ update_thd(ha_thd());
+ col_name = field->field_name;
+ index = innobase_get_index(table->s->next_number_index);
- } else if (error == DB_RECORD_NOT_FOUND) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: MySQL and InnoDB data "
- "dictionaries are out of sync.\n"
- "InnoDB: Unable to find the AUTOINC column %s in the "
- "InnoDB table %s.\n"
- "InnoDB: We set the next AUTOINC column value to the "
- "maximum possible value,\n"
- "InnoDB: in effect disabling the AUTOINC next value "
- "generation.\n"
- "InnoDB: You can either set the next AUTOINC value "
- "explicitly using ALTER TABLE\n"
- "InnoDB: or fix the data dictionary by recreating "
- "the table.\n",
- col_name, index->table->name);
+ /* Execute SELECT MAX(col_name) FROM TABLE; */
+ err = row_search_max_autoinc(index, col_name, &read_auto_inc);
- auto_inc = 0xFFFFFFFFFFFFFFFFULL;
+ switch (err) {
+ case DB_SUCCESS:
+ /* At the this stage we do not know the increment
+ or the offset, so use a default increment of 1. */
+ auto_inc = read_auto_inc + 1;
+ break;
- dict_table_autoinc_initialize(innodb_table, auto_inc);
+ case DB_RECORD_NOT_FOUND:
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: MySQL and InnoDB data "
+ "dictionaries are out of sync.\n"
+ "InnoDB: Unable to find the AUTOINC column "
+ "%s in the InnoDB table %s.\n"
+ "InnoDB: We set the next AUTOINC column "
+ "value to the maximum possible value,\n"
+ "InnoDB: in effect disabling the AUTOINC "
+ "next value generation.\n"
+ "InnoDB: You can either set the next "
+ "AUTOINC value explicitly using ALTER TABLE\n"
+ "InnoDB: or fix the data dictionary by "
+ "recreating the table.\n",
+ col_name, index->table->name);
- error = DB_SUCCESS;
- } /* else other errors are still fatal */
+ my_error(ER_AUTOINC_READ_FAILED, MYF(0));
+ break;
+ default:
+ /* row_search_max_autoinc() should only return
+ one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */
+ ut_error;
+ }
+ }
- return(ulong(error));
+ dict_table_autoinc_initialize(prebuilt->table, auto_inc);
}
/*********************************************************************
@@ -2785,8 +2927,6 @@ retry:
/* Only if the table has an AUTOINC column. */
if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
- ulint error;
-
dict_table_autoinc_lock(prebuilt->table);
/* Since a table can already be "open" in InnoDB's internal
@@ -2795,8 +2935,7 @@ retry:
autoinc value from a previous MySQL open. */
if (dict_table_autoinc_read(prebuilt->table) == 0) {
- error = innobase_initialize_autoinc();
- ut_a(error == DB_SUCCESS);
+ innobase_initialize_autoinc();
}
dict_table_autoinc_unlock(prebuilt->table);
@@ -3612,67 +3751,6 @@ skip_field:
}
/************************************************************************
-Get the upper limit of the MySQL integral and floating-point type. */
-
-ulonglong
-ha_innobase::innobase_get_int_col_max_value(
-/*========================================*/
- const Field* field)
-{
- ulonglong max_value = 0;
-
- switch(field->key_type()) {
- /* TINY */
- case HA_KEYTYPE_BINARY:
- max_value = 0xFFULL;
- break;
- case HA_KEYTYPE_INT8:
- max_value = 0x7FULL;
- break;
- /* SHORT */
- case HA_KEYTYPE_USHORT_INT:
- max_value = 0xFFFFULL;
- break;
- case HA_KEYTYPE_SHORT_INT:
- max_value = 0x7FFFULL;
- break;
- /* MEDIUM */
- case HA_KEYTYPE_UINT24:
- max_value = 0xFFFFFFULL;
- break;
- case HA_KEYTYPE_INT24:
- max_value = 0x7FFFFFULL;
- break;
- /* LONG */
- case HA_KEYTYPE_ULONG_INT:
- max_value = 0xFFFFFFFFULL;
- break;
- case HA_KEYTYPE_LONG_INT:
- max_value = 0x7FFFFFFFULL;
- break;
- /* BIG */
- case HA_KEYTYPE_ULONGLONG:
- max_value = 0xFFFFFFFFFFFFFFFFULL;
- break;
- case HA_KEYTYPE_LONGLONG:
- max_value = 0x7FFFFFFFFFFFFFFFULL;
- break;
- case HA_KEYTYPE_FLOAT:
- /* We use the maximum as per IEEE754-2008 standard, 2^24 */
- max_value = 0x1000000ULL;
- break;
- case HA_KEYTYPE_DOUBLE:
- /* We use the maximum as per IEEE754-2008 standard, 2^53 */
- max_value = 0x20000000000000ULL;
- break;
- default:
- ut_error;
- }
-
- return(max_value);
-}
-
-/************************************************************************
This special handling is really to overcome the limitations of MySQL's
binlogging. We need to eliminate the non-determinism that will arise in
INSERT ... SELECT type of statements, since MySQL binlog only stores the
@@ -3986,24 +4064,29 @@ no_commit:
update the table upper limit. Note: last_value
will be 0 if get_auto_increment() was not called.*/
- if (auto_inc <= col_max_value
- && auto_inc >= prebuilt->autoinc_last_value) {
+ if (auto_inc >= prebuilt->autoinc_last_value) {
set_max_autoinc:
- ut_a(prebuilt->autoinc_increment > 0);
-
- ulonglong need;
- ulonglong offset;
-
- offset = prebuilt->autoinc_offset;
- need = prebuilt->autoinc_increment;
-
- auto_inc = innobase_next_autoinc(
- auto_inc, need, offset, col_max_value);
-
- err = innobase_set_max_autoinc(auto_inc);
-
- if (err != DB_SUCCESS) {
- error = err;
+ /* This should filter out the negative
+ values set explicitly by the user. */
+ if (auto_inc <= col_max_value) {
+ ut_a(prebuilt->autoinc_increment > 0);
+
+ ulonglong need;
+ ulonglong offset;
+
+ offset = prebuilt->autoinc_offset;
+ need = prebuilt->autoinc_increment;
+
+ auto_inc = innobase_next_autoinc(
+ auto_inc,
+ need, offset, col_max_value);
+
+ err = innobase_set_max_autoinc(
+ auto_inc);
+
+ if (err != DB_SUCCESS) {
+ error = err;
+ }
}
}
break;
@@ -5970,6 +6053,24 @@ ha_innobase::rename_table(
innobase_commit_low(trx);
trx_free_for_mysql(trx);
+ /* Add a special case to handle the Duplicated Key error
+ and return DB_ERROR instead.
+ This is to avoid a possible SIGSEGV error from mysql error
+ handling code. Currently, mysql handles the Duplicated Key
+ error by re-entering the storage layer and getting dup key
+ info by calling get_dup_key(). This operation requires a valid
+ table handle ('row_prebuilt_t' structure) which could no
+ longer be available in the error handling stage. The suggested
+ solution is to report a 'table exists' error message (since
+ the dup key error here is due to an existing table whose name
+ is the one we are trying to rename to) and return the generic
+ error code. */
+ if (error == (int) DB_DUPLICATE_KEY) {
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
+
+ error = DB_ERROR;
+ }
+
error = convert_error_code_to_mysql(error, NULL);
DBUG_RETURN(error);
@@ -7332,8 +7433,8 @@ innodb_show_status(
mutex_enter_noninline(&srv_monitor_file_mutex);
rewind(srv_monitor_file);
- srv_printf_innodb_monitor(srv_monitor_file,
- &trx_list_start, &trx_list_end);
+ srv_printf_innodb_monitor(srv_monitor_file, FALSE,
+ &trx_list_start, &trx_list_end);
flen = ftell(srv_monitor_file);
os_file_set_eof(srv_monitor_file);
@@ -8204,8 +8305,7 @@ innobase_xa_prepare(
executing XA PREPARE and XA COMMIT commands.
In this case we cannot know how many minutes or hours
will be between XA PREPARE and XA COMMIT, and we don't want
- to block for undefined period of time.
- */
+ to block for undefined period of time. */
pthread_mutex_lock(&prepare_commit_mutex);
trx->active_trans = 2;
}
=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h 2009-09-24 14:52:52 +0000
+++ b/storage/innobase/handler/ha_innodb.h 2010-01-22 09:57:02 +0000
@@ -78,9 +78,8 @@ class ha_innobase: public handler
ulong innobase_reset_autoinc(ulonglong auto_inc);
ulong innobase_get_autoinc(ulonglong* value);
ulong innobase_update_autoinc(ulonglong auto_inc);
- ulong innobase_initialize_autoinc();
+ void innobase_initialize_autoinc();
dict_index_t* innobase_get_index(uint keynr);
- ulonglong innobase_get_int_col_max_value(const Field* field);
/* Init values for the class: */
public:
=== modified file 'storage/innobase/include/fil0fil.h'
--- a/storage/innobase/include/fil0fil.h 2006-06-01 06:34:04 +0000
+++ b/storage/innobase/include/fil0fil.h 2009-12-21 10:20:32 +0000
@@ -330,11 +330,11 @@ fil_op_log_parse_or_replay(
not fir completely between ptr and end_ptr */
byte* end_ptr, /* in: buffer end */
ulint type, /* in: the type of this log record */
- ibool do_replay, /* in: TRUE if we want to replay the
- operation, and not just parse the log record */
- ulint space_id); /* in: if do_replay is TRUE, the space id of
- the tablespace in question; otherwise
- ignored */
+ ulint space_id, /* in: the space id of the tablespace in
+ question, or 0 if the log record should
+ only be parsed but not replayed */
+ ulint log_flags); /* in: redo log flags
+ (stored in the page number parameter) */
/***********************************************************************
Deletes a single-table tablespace. The tablespace must be cached in the
memory cache. */
=== modified file 'storage/innobase/include/ha_prototypes.h'
--- a/storage/innobase/include/ha_prototypes.h 2008-12-14 19:28:19 +0000
+++ b/storage/innobase/include/ha_prototypes.h 2009-11-30 08:26:45 +0000
@@ -24,18 +24,21 @@ innobase_convert_string(
CHARSET_INFO* from_cs,
uint* errors);
-/*********************************************************************
-Display an SQL identifier. */
-
-void
-innobase_print_identifier(
-/*======================*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction */
- ibool table_id,/* in: TRUE=print a table name,
- FALSE=print other identifier */
- const char* name, /* in: name to print */
- ulint namelen);/* in: length of name */
+/*****************************************************************//**
+Convert a table or index name to the MySQL system_charset_info (UTF-8)
+and quote it if needed.
+@return pointer to the end of buf */
+
+char*
+innobase_convert_name(
+/*==================*/
+ char* buf, /*!< out: buffer for converted identifier */
+ ulint buflen, /*!< in: length of buf, in bytes */
+ const char* id, /*!< in: identifier to convert */
+ ulint idlen, /*!< in: length of id, in bytes */
+ void* thd, /*!< in: MySQL connection thread, or NULL */
+ ibool table_id);/*!< in: TRUE=id is a table or database name;
+ FALSE=id is an index name */
/**********************************************************************
Returns true if the thread is the replication thread on the slave
=== modified file 'storage/innobase/include/lock0lock.h'
--- a/storage/innobase/include/lock0lock.h 2008-12-14 20:00:37 +0000
+++ b/storage/innobase/include/lock0lock.h 2009-12-23 06:59:34 +0000
@@ -579,10 +579,15 @@ lock_rec_print(
/*************************************************************************
Prints info of locks for all transactions. */
-void
+ibool
lock_print_info_summary(
/*====================*/
- FILE* file); /* in: file where to print */
+ /* out: FALSE if not able to obtain
+ kernel mutex and exits without
+ printing info */
+ FILE* file, /* in: file where to print */
+ ibool nowait);/* in: whether to wait for the kernel
+ mutex */
/*************************************************************************
Prints info of locks for each transaction. */
=== modified file 'storage/innobase/include/mach0data.h'
--- a/storage/innobase/include/mach0data.h 2008-08-20 00:37:41 +0000
+++ b/storage/innobase/include/mach0data.h 2009-11-30 09:41:38 +0000
@@ -266,8 +266,8 @@ UNIV_INLINE
double
mach_double_read(
/*=============*/
- /* out: double read */
- byte* b); /* in: pointer to memory from where to read */
+ /* out: double read */
+ const byte* b); /* in: pointer to memory from where to read */
/*************************************************************
Writes a double. It is stored in a little-endian format. */
UNIV_INLINE
@@ -282,8 +282,8 @@ UNIV_INLINE
float
mach_float_read(
/*============*/
- /* out: float read */
- byte* b); /* in: pointer to memory from where to read */
+ /* out: float read */
+ const byte* b); /* in: pointer to memory from where to read */
/*************************************************************
Writes a float. It is stored in a little-endian format. */
UNIV_INLINE
=== modified file 'storage/innobase/include/mach0data.ic'
--- a/storage/innobase/include/mach0data.ic 2008-08-20 00:37:41 +0000
+++ b/storage/innobase/include/mach0data.ic 2009-11-30 09:41:38 +0000
@@ -504,8 +504,8 @@ UNIV_INLINE
double
mach_double_read(
/*=============*/
- /* out: double read */
- byte* b) /* in: pointer to memory from where to read */
+ /* out: double read */
+ const byte* b) /* in: pointer to memory from where to read */
{
double d;
ulint i;
@@ -553,8 +553,8 @@ UNIV_INLINE
float
mach_float_read(
/*============*/
- /* out: float read */
- byte* b) /* in: pointer to memory from where to read */
+ /* out: float read */
+ const byte* b) /* in: pointer to memory from where to read */
{
float d;
ulint i;
=== modified file 'storage/innobase/include/mtr0mtr.h'
--- a/storage/innobase/include/mtr0mtr.h 2006-10-20 18:36:15 +0000
+++ b/storage/innobase/include/mtr0mtr.h 2009-12-21 10:20:32 +0000
@@ -134,6 +134,12 @@ flag value must give the length also! */
#define MLOG_BIGGEST_TYPE ((byte)46) /* biggest value (used in
asserts) */
+/* Flags for MLOG_FILE operations (stored in the page number
+parameter, called log_flags in the functions). The page number
+parameter was initially written as 0. */
+#define MLOG_FILE_FLAG_TEMP 1 /* identifies TEMPORARY TABLE in
+ MLOG_FILE_CREATE */
+
/*******************************************************************
Starts a mini-transaction and creates a mini-transaction handle
and buffer in the memory buffer given by the caller. */
=== modified file 'storage/innobase/include/os0file.h'
--- a/storage/innobase/include/os0file.h 2007-07-10 14:34:21 +0000
+++ b/storage/innobase/include/os0file.h 2009-11-30 08:40:31 +0000
@@ -96,6 +96,8 @@ log. */
to become available again */
#define OS_FILE_SHARING_VIOLATION 76
#define OS_FILE_ERROR_NOT_SPECIFIED 77
+ /* 78 is used in the plugin */
+#define OS_FILE_OPERATION_ABORTED 79
/* Types for aio operations */
#define OS_FILE_READ 10
=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h 2009-05-19 08:20:28 +0000
+++ b/storage/innobase/include/srv0srv.h 2009-12-23 06:59:34 +0000
@@ -146,7 +146,8 @@ extern ibool srv_print_innodb_tablespace
extern ibool srv_print_verbose_log;
extern ibool srv_print_innodb_table_monitor;
-extern ibool srv_lock_timeout_and_monitor_active;
+extern ibool srv_lock_timeout_active;
+extern ibool srv_monitor_active;
extern ibool srv_error_monitor_active;
extern ulong srv_n_spin_wait_rounds;
@@ -427,12 +428,21 @@ srv_release_mysql_thread_if_suspended(
que_thr_t* thr); /* in: query thread associated with the
MySQL OS thread */
/*************************************************************************
-A thread which wakes up threads whose lock wait may have lasted too long.
-This also prints the info output by various InnoDB monitors. */
+A thread which wakes up threads whose lock wait may have lasted too
+long. */
os_thread_ret_t
-srv_lock_timeout_and_monitor_thread(
-/*================================*/
+srv_lock_timeout_thread(
+/*====================*/
+ /* out: a dummy parameter */
+ void* arg); /* in: a dummy parameter required by
+ os_thread_create */
+/*************************************************************************
+A thread which prints the info output by various InnoDB monitors. */
+
+os_thread_ret_t
+srv_monitor_thread(
+/*===============*/
/* out: a dummy parameter */
void* arg); /* in: a dummy parameter required by
os_thread_create */
@@ -449,10 +459,14 @@ srv_error_monitor_thread(
/**********************************************************************
Outputs to a file the output of the InnoDB Monitor. */
-void
+ibool
srv_printf_innodb_monitor(
/*======================*/
+ /* out: FALSE if not all information printed
+ due to failure to obtain necessary mutex */
FILE* file, /* in: output stream */
+ ibool nowait, /* in: whether to wait for kernel
+ mutex. */
ulint* trx_start, /* out: file position of the start of
the list of active transactions */
ulint* trx_end); /* out: file position of the end of
=== modified file 'storage/innobase/include/trx0trx.h'
--- a/storage/innobase/include/trx0trx.h 2009-07-10 23:12:13 +0000
+++ b/storage/innobase/include/trx0trx.h 2009-12-01 10:38:40 +0000
@@ -318,9 +318,7 @@ trx_commit_step(
/**************************************************************************
Prints info about a transaction to the given file. The caller must own the
-kernel mutex and must have called
-innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
-or InnoDB cannot meanwhile change the info printed here. */
+kernel mutex. */
void
trx_print(
=== modified file 'storage/innobase/lock/lock0lock.c'
--- a/storage/innobase/lock/lock0lock.c 2009-07-10 23:12:13 +0000
+++ b/storage/innobase/lock/lock0lock.c 2009-12-23 06:59:34 +0000
@@ -22,31 +22,6 @@ Created 5/7/1996 Heikki Tuuri
#include "trx0sys.h"
-/* 2 function prototypes copied from ha_innodb.cc: */
-
-/*****************************************************************
-If you want to print a thd that is not associated with the current thread,
-you must call this function before reserving the InnoDB kernel_mutex, to
-protect MySQL from setting thd->query NULL. If you print a thd of the current
-thread, we know that MySQL cannot modify thd->query, and it is not necessary
-to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release
-the kernel_mutex.
-NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
-function! */
-
-void
-innobase_mysql_prepare_print_arbitrary_thd(void);
-/*============================================*/
-
-/*****************************************************************
-Relases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
-NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
-function! */
-
-void
-innobase_mysql_end_print_arbitrary_thd(void);
-/*========================================*/
-
/* Restricts the length of search we will do in the waits-for
graph of transactions */
#define LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK 1000000
@@ -4217,17 +4192,27 @@ lock_get_n_rec_locks(void)
/*************************************************************************
Prints info of locks for all transactions. */
-void
+ibool
lock_print_info_summary(
/*====================*/
- FILE* file) /* in: file where to print */
+ /* out: FALSE if not able to obtain
+ kernel mutex and exit without
+ printing lock info */
+ FILE* file, /* in: file where to print */
+ ibool nowait) /* in: whether to wait for the kernel
+ mutex */
{
- /* We must protect the MySQL thd->query field with a MySQL mutex, and
- because the MySQL mutex must be reserved before the kernel_mutex of
- InnoDB, we call innobase_mysql_prepare_print_arbitrary_thd() here. */
- innobase_mysql_prepare_print_arbitrary_thd();
- lock_mutex_enter_kernel();
+ /* if nowait is FALSE, wait on the kernel mutex,
+ otherwise return immediately if fail to obtain the
+ mutex. */
+ if (!nowait) {
+ lock_mutex_enter_kernel();
+ } else if (mutex_enter_nowait(&kernel_mutex)) {
+ fputs("FAIL TO OBTAIN KERNEL MUTEX, "
+ "SKIP LOCK INFO PRINTING\n", file);
+ return(FALSE);
+ }
if (lock_deadlock_found) {
fputs("------------------------\n"
@@ -4261,6 +4246,7 @@ lock_print_info_summary(
"Total number of lock structs in row lock hash table %lu\n",
(ulong) lock_get_n_rec_locks());
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
+ return(TRUE);
}
/*************************************************************************
@@ -4314,7 +4300,6 @@ loop:
if (trx == NULL) {
lock_mutex_exit_kernel();
- innobase_mysql_end_print_arbitrary_thd();
ut_ad(lock_validate());
@@ -4386,7 +4371,6 @@ loop:
if (load_page_first) {
lock_mutex_exit_kernel();
- innobase_mysql_end_print_arbitrary_thd();
mtr_start(&mtr);
@@ -4397,7 +4381,6 @@ loop:
load_page_first = FALSE;
- innobase_mysql_prepare_print_arbitrary_thd();
lock_mutex_enter_kernel();
goto loop;
=== modified file 'storage/innobase/log/log0log.c'
--- a/storage/innobase/log/log0log.c 2007-07-10 14:34:21 +0000
+++ b/storage/innobase/log/log0log.c 2009-12-23 06:59:34 +0000
@@ -3045,7 +3045,7 @@ loop:
if (srv_fast_shutdown < 2
&& (srv_error_monitor_active
- || srv_lock_timeout_and_monitor_active)) {
+ || srv_lock_timeout_active || srv_monitor_active)) {
mutex_exit(&kernel_mutex);
=== modified file 'storage/innobase/log/log0recv.c'
--- a/storage/innobase/log/log0recv.c 2007-08-28 00:41:29 +0000
+++ b/storage/innobase/log/log0recv.c 2009-12-21 10:20:32 +0000
@@ -939,8 +939,7 @@ recv_parse_or_apply_log_rec_body(
case MLOG_FILE_CREATE:
case MLOG_FILE_RENAME:
case MLOG_FILE_DELETE:
- ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, FALSE,
- ULINT_UNDEFINED);
+ ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0);
break;
default:
ptr = NULL;
@@ -1938,8 +1937,8 @@ loop:
point to the datadir we should use there */
if (NULL == fil_op_log_parse_or_replay(
- body, end_ptr, type, TRUE,
- space)) {
+ body, end_ptr, type,
+ space, page_no)) {
fprintf(stderr,
"InnoDB: Error: file op"
" log record of type %lu"
=== modified file 'storage/innobase/os/os0file.c'
--- a/storage/innobase/os/os0file.c 2008-12-14 19:15:12 +0000
+++ b/storage/innobase/os/os0file.c 2009-11-30 08:40:31 +0000
@@ -257,6 +257,13 @@ os_file_get_last_error(
" software or another instance\n"
"InnoDB: of MySQL."
" Please close it to get rid of this error.\n");
+ } else if (err == ERROR_OPERATION_ABORTED) {
+ fprintf(stderr,
+ "InnoDB: The error means that the I/O"
+ " operation has been aborted\n"
+ "InnoDB: because of either a thread exit"
+ " or an application request.\n"
+ "InnoDB: Retry attempt is made.\n");
} else {
fprintf(stderr,
"InnoDB: Some operating system error numbers"
@@ -278,6 +285,8 @@ os_file_get_last_error(
} else if (err == ERROR_SHARING_VIOLATION
|| err == ERROR_LOCK_VIOLATION) {
return(OS_FILE_SHARING_VIOLATION);
+ } else if (err == ERROR_OPERATION_ABORTED) {
+ return(OS_FILE_OPERATION_ABORTED);
} else {
return(100 + err);
}
@@ -402,6 +411,10 @@ os_file_handle_error_cond_exit(
os_thread_sleep(10000000); /* 10 sec */
return(TRUE);
+ } else if (err == OS_FILE_OPERATION_ABORTED) {
+
+ os_thread_sleep(100000); /* 100 ms */
+ return(TRUE);
} else {
if (name) {
fprintf(stderr, "InnoDB: File name %s\n", name);
@@ -3692,6 +3705,7 @@ os_aio_windows_handle(
ibool ret_val;
BOOL ret;
DWORD len;
+ BOOL retry = FALSE;
if (segment == ULINT_UNDEFINED) {
array = os_aio_sync_array;
@@ -3745,14 +3759,52 @@ os_aio_windows_handle(
ut_a(TRUE == os_file_flush(slot->file));
}
# endif /* UNIV_DO_FLUSH */
+ } else if (os_file_handle_error(slot->name, "Windows aio")) {
+
+ retry = TRUE;
} else {
- os_file_handle_error(slot->name, "Windows aio");
ret_val = FALSE;
}
os_mutex_exit(array->mutex);
+ if (retry) {
+ /* retry failed read/write operation synchronously.
+ No need to hold array->mutex. */
+
+ switch (slot->type) {
+ case OS_FILE_WRITE:
+ ret = WriteFile(slot->file, slot->buf,
+ slot->len, &len,
+ &(slot->control));
+
+ break;
+ case OS_FILE_READ:
+ ret = ReadFile(slot->file, slot->buf,
+ slot->len, &len,
+ &(slot->control));
+
+ break;
+ default:
+ ut_error;
+ }
+
+ if (!ret && GetLastError() == ERROR_IO_PENDING) {
+ /* aio was queued successfully!
+ We want a synchronous i/o operation on a
+ file where we also use async i/o: in Windows
+ we must use the same wait mechanism as for
+ async i/o */
+
+ ret = GetOverlappedResult(slot->file,
+ &(slot->control),
+ &len, TRUE);
+ }
+
+ ret_val = ret && len == slot->len;
+ }
+
os_aio_array_free_slot(array, slot);
return(ret_val);
=== modified file 'storage/innobase/row/row0mysql.c'
--- a/storage/innobase/row/row0mysql.c 2009-11-02 14:59:19 +0000
+++ b/storage/innobase/row/row0mysql.c 2010-01-22 09:55:50 +0000
@@ -3245,19 +3245,13 @@ check_next_foreign:
"END;\n"
, FALSE, trx);
- if (err != DB_SUCCESS) {
- ut_a(err == DB_OUT_OF_FILE_SPACE);
-
- err = DB_MUST_GET_MORE_FILE_SPACE;
-
- row_mysql_handle_errors(&err, trx, NULL, NULL);
-
- ut_error;
- } else {
+ switch (err) {
ibool is_path;
const char* name_or_path;
mem_heap_t* heap;
+ case DB_SUCCESS:
+
heap = mem_heap_create(200);
/* Clone the name, in case it has been allocated
@@ -3322,7 +3316,27 @@ check_next_foreign:
}
mem_heap_free(heap);
+ break;
+
+ case DB_TOO_MANY_CONCURRENT_TRXS:
+ /* Cannot even find a free slot for the
+ the undo log. We can directly exit here
+ and return the DB_TOO_MANY_CONCURRENT_TRXS
+ error. */
+ break;
+
+ case DB_OUT_OF_FILE_SPACE:
+ err = DB_MUST_GET_MORE_FILE_SPACE;
+
+ row_mysql_handle_errors(&err, trx, NULL, NULL);
+
+ /* Fall through to raise error */
+
+ default:
+ /* No other possible error returns */
+ ut_error;
}
+
funct_exit:
trx_commit_for_mysql(trx);
=== modified file 'storage/innobase/row/row0sel.c'
--- a/storage/innobase/row/row0sel.c 2009-07-10 23:12:13 +0000
+++ b/storage/innobase/row/row0sel.c 2009-11-30 09:41:38 +0000
@@ -4514,6 +4514,7 @@ row_search_autoinc_read_column(
dict_index_t* index, /* in: index to read from */
const rec_t* rec, /* in: current rec */
ulint col_no, /* in: column number */
+ ulint mtype, /*!< in: column main type */
ibool unsigned_type) /* in: signed or unsigned flag */
{
ulint len;
@@ -4535,9 +4536,26 @@ row_search_autoinc_read_column(
data = rec_get_nth_field((rec_t*)rec, offsets, col_no, &len);
ut_a(len != UNIV_SQL_NULL);
- ut_a(len <= sizeof value);
- value = mach_read_int_type(data, len, unsigned_type);
+ switch (mtype) {
+ case DATA_INT:
+ ut_a(len <= sizeof value);
+ value = mach_read_int_type(data, len, unsigned_type);
+ break;
+
+ case DATA_FLOAT:
+ ut_a(len == sizeof(float));
+ value = mach_float_read(data);
+ break;
+
+ case DATA_DOUBLE:
+ ut_a(len == sizeof(double));
+ value = mach_double_read(data);
+ break;
+
+ default:
+ ut_error;
+ }
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@@ -4625,7 +4643,8 @@ row_search_max_autoinc(
dfield->col->prtype & DATA_UNSIGNED);
*value = row_search_autoinc_read_column(
- index, rec, i, unsigned_type);
+ index, rec, i,
+ dfield->col->mtype, unsigned_type);
}
}
=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c 2009-05-19 08:20:28 +0000
+++ b/storage/innobase/srv/srv0srv.c 2009-12-23 06:59:34 +0000
@@ -64,7 +64,8 @@ ulint srv_fatal_semaphore_wait_threshold
in microseconds, in order to reduce the lagging of the purge thread. */
ulint srv_dml_needed_delay = 0;
-ibool srv_lock_timeout_and_monitor_active = FALSE;
+ibool srv_lock_timeout_active = FALSE;
+ibool srv_monitor_active = FALSE;
ibool srv_error_monitor_active = FALSE;
const char* srv_main_thread_op_info = "";
@@ -122,6 +123,16 @@ ulint srv_log_file_size = ULINT_MAX; /*
ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */
ulong srv_flush_log_at_trx_commit = 1;
+/* Maximum number of times allowed to conditionally acquire
+mutex before switching to blocking wait on the mutex */
+#define MAX_MUTEX_NOWAIT 20
+
+/* Check whether the number of failed nonblocking mutex
+acquisition attempts exceeds maximum allowed value. If so,
+srv_printf_innodb_monitor() will request mutex acquisition
+with mutex_enter(), which will wait until it gets the mutex. */
+#define MUTEX_NOWAIT(mutex_skipped) ((mutex_skipped) < MAX_MUTEX_NOWAIT)
+
byte srv_latin1_ordering[256] /* The sort order table of the latin1
character set. The following table is
the MySQL order as of Feb 10th, 2002 */
@@ -1626,10 +1637,13 @@ srv_refresh_innodb_monitor_stats(void)
/**********************************************************************
Outputs to a file the output of the InnoDB Monitor. */
-void
+ibool
srv_printf_innodb_monitor(
/*======================*/
+ /* out: FALSE if not all information printed
+ due to failure to obtain necessary mutex */
FILE* file, /* in: output stream */
+ ibool nowait, /* in: whether to wait for the mutex. */
ulint* trx_start, /* out: file position of the start of
the list of active transactions */
ulint* trx_end) /* out: file position of the end of
@@ -1638,6 +1652,7 @@ srv_printf_innodb_monitor(
double time_elapsed;
time_t current_time;
ulint n_reserved;
+ ibool ret;
mutex_enter(&srv_innodb_monitor_mutex);
@@ -1682,24 +1697,31 @@ srv_printf_innodb_monitor(
mutex_exit(&dict_foreign_err_mutex);
- lock_print_info_summary(file);
- if (trx_start) {
- long t = ftell(file);
- if (t < 0) {
- *trx_start = ULINT_UNDEFINED;
- } else {
- *trx_start = (ulint) t;
+ /* Only if lock_print_info_summary proceeds correctly,
+ before we call the lock_print_info_all_transactions
+ to print all the lock information. */
+ ret = lock_print_info_summary(file, nowait);
+
+ if (ret) {
+ if (trx_start) {
+ long t = ftell(file);
+ if (t < 0) {
+ *trx_start = ULINT_UNDEFINED;
+ } else {
+ *trx_start = (ulint) t;
+ }
}
- }
- lock_print_info_all_transactions(file);
- if (trx_end) {
- long t = ftell(file);
- if (t < 0) {
- *trx_end = ULINT_UNDEFINED;
- } else {
- *trx_end = (ulint) t;
+ lock_print_info_all_transactions(file);
+ if (trx_end) {
+ long t = ftell(file);
+ if (t < 0) {
+ *trx_end = ULINT_UNDEFINED;
+ } else {
+ *trx_end = (ulint) t;
+ }
}
}
+
fputs("--------\n"
"FILE I/O\n"
"--------\n", file);
@@ -1804,6 +1826,8 @@ srv_printf_innodb_monitor(
"============================\n", file);
mutex_exit(&srv_innodb_monitor_mutex);
fflush(file);
+
+ return(ret);
}
/**********************************************************************
@@ -1883,26 +1907,23 @@ srv_export_innodb_status(void)
}
/*************************************************************************
-A thread which wakes up threads whose lock wait may have lasted too long.
-This also prints the info output by various InnoDB monitors. */
+A thread prints the info output by various InnoDB monitors. */
os_thread_ret_t
-srv_lock_timeout_and_monitor_thread(
-/*================================*/
+srv_monitor_thread(
+/*===============*/
/* out: a dummy parameter */
void* arg __attribute__((unused)))
/* in: a dummy parameter required by
os_thread_create */
{
- srv_slot_t* slot;
double time_elapsed;
time_t current_time;
time_t last_table_monitor_time;
time_t last_tablespace_monitor_time;
time_t last_monitor_time;
- ibool some_waits;
- double wait_time;
- ulint i;
+ ulint mutex_skipped;
+ ibool last_srv_print_monitor;
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Lock timeout thread starts, id %lu\n",
@@ -1913,13 +1934,15 @@ srv_lock_timeout_and_monitor_thread(
last_table_monitor_time = time(NULL);
last_tablespace_monitor_time = time(NULL);
last_monitor_time = time(NULL);
+ mutex_skipped = 0;
+ last_srv_print_monitor = srv_print_innodb_monitor;
loop:
- srv_lock_timeout_and_monitor_active = TRUE;
+ srv_monitor_active = TRUE;
- /* When someone is waiting for a lock, we wake up every second
- and check if a timeout has passed for a lock wait */
+ /* Wake up every 5 seconds to see if we need to print
+ monitor information. */
- os_thread_sleep(1000000);
+ os_thread_sleep(5000000);
current_time = time(NULL);
@@ -1929,14 +1952,40 @@ loop:
last_monitor_time = time(NULL);
if (srv_print_innodb_monitor) {
- srv_printf_innodb_monitor(stderr, NULL, NULL);
+ /* Reset mutex_skipped counter everytime
+ srv_print_innodb_monitor changes. This is to
+ ensure we will not be blocked by kernel_mutex
+ for short duration information printing,
+ such as requested by sync_array_print_long_waits() */
+ if (!last_srv_print_monitor) {
+ mutex_skipped = 0;
+ last_srv_print_monitor = TRUE;
+ }
+
+ if (!srv_printf_innodb_monitor(stderr,
+ MUTEX_NOWAIT(mutex_skipped),
+ NULL, NULL)) {
+ mutex_skipped++;
+ } else {
+ /* Reset the counter */
+ mutex_skipped = 0;
+ }
+ } else {
+ last_srv_print_monitor = FALSE;
}
+
if (srv_innodb_status) {
mutex_enter(&srv_monitor_file_mutex);
rewind(srv_monitor_file);
- srv_printf_innodb_monitor(srv_monitor_file, NULL,
- NULL);
+ if (!srv_printf_innodb_monitor(srv_monitor_file,
+ MUTEX_NOWAIT(mutex_skipped),
+ NULL, NULL)) {
+ mutex_skipped++;
+ } else {
+ mutex_skipped = 0;
+ }
+
os_file_set_eof(srv_monitor_file);
mutex_exit(&srv_monitor_file_mutex);
}
@@ -1989,6 +2038,56 @@ loop:
}
}
+ if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
+ goto exit_func;
+ }
+
+ if (srv_print_innodb_monitor
+ || srv_print_innodb_lock_monitor
+ || srv_print_innodb_tablespace_monitor
+ || srv_print_innodb_table_monitor) {
+ goto loop;
+ }
+
+ srv_monitor_active = FALSE;
+
+ goto loop;
+
+exit_func:
+ srv_monitor_active = FALSE;
+
+ /* We count the number of threads in os_thread_exit(). A created
+ thread should always use that to exit and not use return() to exit. */
+
+ os_thread_exit(NULL);
+
+ OS_THREAD_DUMMY_RETURN;
+}
+
+/*************************************************************************
+A thread which wakes up threads whose lock wait may have lasted too long. */
+
+os_thread_ret_t
+srv_lock_timeout_thread(
+/*====================*/
+ /* out: a dummy parameter */
+ void* arg __attribute__((unused)))
+ /* in: a dummy parameter required by
+ os_thread_create */
+{
+ srv_slot_t* slot;
+ ibool some_waits;
+ double wait_time;
+ ulint i;
+
+loop:
+ /* When someone is waiting for a lock, we wake up every second
+ and check if a timeout has passed for a lock wait */
+
+ os_thread_sleep(1000000);
+
+ srv_lock_timeout_active = TRUE;
+
mutex_enter(&kernel_mutex);
some_waits = FALSE;
@@ -2033,17 +2132,11 @@ loop:
goto exit_func;
}
- if (some_waits || srv_print_innodb_monitor
- || srv_print_innodb_lock_monitor
- || srv_print_innodb_tablespace_monitor
- || srv_print_innodb_table_monitor) {
+ if (some_waits) {
goto loop;
}
- /* No one was waiting for a lock and no monitor was active:
- suspend this thread */
-
- srv_lock_timeout_and_monitor_active = FALSE;
+ srv_lock_timeout_active = FALSE;
#if 0
/* The following synchronisation is disabled, since
@@ -2053,7 +2146,7 @@ loop:
goto loop;
exit_func:
- srv_lock_timeout_and_monitor_active = FALSE;
+ srv_lock_timeout_active = FALSE;
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
=== modified file 'storage/innobase/srv/srv0start.c'
--- a/storage/innobase/srv/srv0start.c 2009-05-06 12:03:24 +0000
+++ b/storage/innobase/srv/srv0start.c 2010-03-04 08:03:07 +0000
@@ -87,8 +87,8 @@ static os_file_t files[1000];
static mutex_t ios_mutex;
static ulint ios;
-static ulint n[SRV_MAX_N_IO_THREADS + 5];
-static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5];
+static ulint n[SRV_MAX_N_IO_THREADS + 6];
+static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6];
/* We use this mutex to test the return value of pthread_mutex_trylock
on successful locking. HP-UX does NOT return 0, though Linux et al do. */
@@ -1596,15 +1596,20 @@ innobase_start_or_create_for_mysql(void)
/* fprintf(stderr, "Max allowed record size %lu\n",
page_get_free_space_of_empty() / 2); */
- /* Create the thread which watches the timeouts for lock waits
- and prints InnoDB monitor info */
+ /* Create the thread which watches the timeouts for lock
+ waits */
- os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL,
+ os_thread_create(&srv_lock_timeout_thread, NULL,
thread_ids + 2 + SRV_MAX_N_IO_THREADS);
/* Create the thread which warns of long semaphore waits */
os_thread_create(&srv_error_monitor_thread, NULL,
thread_ids + 3 + SRV_MAX_N_IO_THREADS);
+
+ /* Create the thread which prints InnoDB monitor info */
+ os_thread_create(&srv_monitor_thread, NULL,
+ thread_ids + 4 + SRV_MAX_N_IO_THREADS);
+
srv_was_started = TRUE;
srv_is_being_started = FALSE;
=== modified file 'storage/innobase/trx/trx0trx.c'
--- a/storage/innobase/trx/trx0trx.c 2009-07-10 23:12:13 +0000
+++ b/storage/innobase/trx/trx0trx.c 2009-12-01 10:38:40 +0000
@@ -1652,9 +1652,7 @@ trx_mark_sql_stat_end(
/**************************************************************************
Prints info about a transaction to the given file. The caller must own the
-kernel mutex and must have called
-innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
-or InnoDB cannot meanwhile change the info printed here. */
+kernel mutex. */
void
trx_print(
=== modified file 'storage/innobase/ut/ut0ut.c'
--- a/storage/innobase/ut/ut0ut.c 2008-12-14 19:18:59 +0000
+++ b/storage/innobase/ut/ut0ut.c 2009-11-30 08:26:45 +0000
@@ -19,6 +19,7 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0sort.h"
#include "trx0trx.h"
#include "ha_prototypes.h"
+#include "mysql_com.h" /* NAME_LEN */
ibool ut_always_false = FALSE;
@@ -484,26 +485,17 @@ ut_print_namel(
const char* name, /* in: name to print */
ulint namelen)/* in: length of name */
{
-#ifdef UNIV_HOTBACKUP
- fwrite(name, 1, namelen, f);
-#else
- if (table_id) {
- char* slash = memchr(name, '/', namelen);
- if (!slash) {
-
- goto no_db_name;
- }
+ /* 2 * NAME_LEN for database and table name,
+ and some slack for the #mysql50# prefix and quotes */
+ char buf[3 * NAME_LEN];
+ const char* bufend;
+
+ bufend = innobase_convert_name(buf, sizeof buf,
+ name, namelen,
+ trx ? trx->mysql_thd : NULL,
+ table_id);
- /* Print the database name and table name separately. */
- innobase_print_identifier(f, trx, TRUE, name, slash - name);
- putc('.', f);
- innobase_print_identifier(f, trx, TRUE, slash + 1,
- namelen - (slash - name) - 1);
- } else {
-no_db_name:
- innobase_print_identifier(f, trx, table_id, name, namelen);
- }
-#endif
+ fwrite(buf, 1, bufend - buf, f);
}
/**************************************************************************
=== modified file 'storage/innodb_plugin/ChangeLog'
--- a/storage/innodb_plugin/ChangeLog 2009-11-03 10:34:03 +0000
+++ b/storage/innodb_plugin/ChangeLog 2009-11-30 13:42:26 +0000
@@ -1,3 +1,87 @@
+2009-11-20 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Add a workaround to prevent a crash due to Bug#45961 DDL on
+ partitioned innodb tables leaves data dictionary in an inconsistent
+ state
+
+2009-11-19 The InnoDB Team
+
+ * btr/btr0btr.c:
+ Fix Bug#48469 when innodb tablespace is configured too small, crash
+ and corruption!
+
+2009-11-19 The InnoDB Team
+
+ * data/data0type.c:
+ Fix Bug#48526 Data type for float and double is incorrectly reported
+ in InnoDB table monitor
+
+2009-11-19 The InnoDB Team
+
+ * CMakeLists.txt:
+ Fix Bug#48317 cannot build innodb as static library
+
+2009-11-18 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Fix Bug#48782 On lock wait timeout, CREATE INDEX (creating primary key)
+ attempts DROP TABLE
+
+2009-11-17 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb.result,
+ mysql-test/innodb.test, mysql-test/innodb_bug44369.result,
+ mysql-test/innodb_bug44369.test, mysql-test/patches/innodb-index.diff,
+ row/row0mysql.c:
+ Report duplicate table names to the client connection, not to the
+ error log.
+
+2009-11-12 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/db0err.h, row/row0merge.c,
+ row/row0mysql.c:
+ Allow CREATE INDEX to be interrupted.
+ Also, when CHECK TABLE is interrupted, report ER_QUERY_INTERRUPTED.
+
+2009-11-11 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug47167.result,
+ mysql-test/innodb_bug47167.test, mysql-test/innodb_file_format.result:
+ Fix Bug#47167 "set global innodb_file_format_check" cannot set value
+ by User-Defined Variable
+
+2009-11-11 The InnoDB Team
+
+ * include/os0file.h, os/os0file.c:
+ Fix Bug#3139 Mysql crashes: 'windows error 995' after several selects
+ on a large DB
+
+2009-11-04 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#32430 'show innodb status' causes errors
+ Invalid (old?) table or database name in logs
+
+2009-11-02 The InnoDB Team
+
+ * btr/btr0sea.c, buf/buf0buf.c, dict/dict0dict.c, fil/fil0fil.c,
+ ibuf/ibuf0ibuf.c, include/btr0sea.h, include/dict0dict.h,
+ include/fil0fil.h, include/ibuf0ibuf.h, include/lock0lock.h,
+ include/log0log.h, include/log0recv.h, include/mem0mem.h,
+ include/mem0pool.h, include/os0file.h, include/pars0pars.h,
+ include/srv0srv.h, include/thr0loc.h, include/trx0i_s.h,
+ include/trx0purge.h, include/trx0rseg.h, include/trx0sys.h,
+ include/trx0undo.h, include/usr0sess.h, lock/lock0lock.c,
+ log/log0log.c, log/log0recv.c, mem/mem0dbg.c, mem/mem0pool.c,
+ os/os0file.c, os/os0sync.c, os/os0thread.c, pars/lexyy.c,
+ pars/pars0lex.l, que/que0que.c, srv/srv0srv.c, srv/srv0start.c,
+ sync/sync0arr.c, sync/sync0sync.c, thr/thr0loc.c, trx/trx0i_s.c,
+ trx/trx0purge.c, trx/trx0rseg.c, trx/trx0sys.c, trx/trx0undo.c,
+ usr/usr0sess.c, ut/ut0mem.c:
+ Fix Bug #45992 innodb memory not freed after shutdown
+ Fix Bug #46656 InnoDB plugin: memory leaks (Valgrind)
+
2009-10-29 The InnoDB Team
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
@@ -66,6 +150,12 @@
Fix Bug#47058 Failure to compile innodb_plugin on solaris 10u7 + spro
cc/CC 5.10
+2009-10-13 The InnoDB Team
+
+ * buf/buf0flu.c:
+ Call fsync() on datafiles after a batch of pages is written to disk
+ even when skip_innodb_doublewrite is set.
+
2009-10-05 The InnoDB Team
* buf/buf0buf.c:
=== modified file 'storage/innodb_plugin/btr/btr0btr.c'
--- a/storage/innodb_plugin/btr/btr0btr.c 2009-10-12 12:00:56 +0000
+++ b/storage/innodb_plugin/btr/btr0btr.c 2009-11-30 13:42:26 +0000
@@ -790,8 +790,15 @@ btr_create(
} else {
/* It is a non-ibuf tree: create a file segment for leaf
pages */
- fseg_create(space, page_no,
- PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr);
+ if (!fseg_create(space, page_no,
+ PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
+ /* Not enough space for new segment, free root
+ segment before return. */
+ btr_free_root(space, zip_size, page_no, mtr);
+
+ return(FIL_NULL);
+ }
+
/* The fseg create acquires a second latch on the page,
therefore we must declare it: */
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
=== modified file 'storage/innodb_plugin/btr/btr0sea.c'
--- a/storage/innodb_plugin/btr/btr0sea.c 2009-10-08 11:28:37 +0000
+++ b/storage/innodb_plugin/btr/btr0sea.c 2009-11-30 11:32:05 +0000
@@ -175,6 +175,21 @@ btr_search_sys_create(
btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
}
+/*****************************************************************//**
+Frees the adaptive search system at a database shutdown. */
+UNIV_INTERN
+void
+btr_search_sys_free(void)
+/*=====================*/
+{
+ mem_free(btr_search_latch_temp);
+ btr_search_latch_temp = NULL;
+ mem_heap_free(btr_search_sys->hash_index->heap);
+ hash_table_free(btr_search_sys->hash_index);
+ mem_free(btr_search_sys);
+ btr_search_sys = NULL;
+}
+
/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
UNIV_INTERN
=== modified file 'storage/innodb_plugin/buf/buf0buf.c'
--- a/storage/innodb_plugin/buf/buf0buf.c 2009-11-03 10:26:07 +0000
+++ b/storage/innodb_plugin/buf/buf0buf.c 2009-11-30 11:32:05 +0000
@@ -1020,7 +1020,11 @@ buf_pool_free(void)
os_mem_free_large(chunk->mem, chunk->mem_size);
}
- buf_pool->n_chunks = 0;
+ mem_free(buf_pool->chunks);
+ hash_table_free(buf_pool->page_hash);
+ hash_table_free(buf_pool->zip_hash);
+ mem_free(buf_pool);
+ buf_pool = NULL;
}
/********************************************************************//**
=== modified file 'storage/innodb_plugin/data/data0type.c'
--- a/storage/innodb_plugin/data/data0type.c 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/data/data0type.c 2009-11-30 13:35:20 +0000
@@ -237,6 +237,22 @@ dtype_print(
fputs("DATA_SYS", stderr);
break;
+ case DATA_FLOAT:
+ fputs("DATA_FLOAT", stderr);
+ break;
+
+ case DATA_DOUBLE:
+ fputs("DATA_DOUBLE", stderr);
+ break;
+
+ case DATA_DECIMAL:
+ fputs("DATA_DECIMAL", stderr);
+ break;
+
+ case DATA_VARMYSQL:
+ fputs("DATA_VARMYSQL", stderr);
+ break;
+
default:
fprintf(stderr, "type %lu", (ulong) mtype);
break;
=== modified file 'storage/innodb_plugin/dict/dict0dict.c'
--- a/storage/innodb_plugin/dict/dict0dict.c 2009-10-09 12:52:18 +0000
+++ b/storage/innodb_plugin/dict/dict0dict.c 2009-11-30 11:42:51 +0000
@@ -1200,7 +1200,7 @@ dict_index_too_big_for_undo(
= TRX_UNDO_PAGE_HDR - TRX_UNDO_PAGE_HDR_SIZE
+ 2 /* next record pointer */
+ 1 /* type_cmpl */
- + 11 /* trx->undo_no */ - 11 /* table->id */
+ + 11 /* trx->undo_no */ + 11 /* table->id */
+ 1 /* rec_get_info_bits() */
+ 11 /* DB_TRX_ID */
+ 11 /* DB_ROLL_PTR */
@@ -4652,6 +4652,26 @@ dict_ind_init(void)
dict_ind_redundant->cached = dict_ind_compact->cached = TRUE;
}
+/**********************************************************************//**
+Frees dict_ind_redundant and dict_ind_compact. */
+static
+void
+dict_ind_free(void)
+/*===============*/
+{
+ dict_table_t* table;
+
+ table = dict_ind_compact->table;
+ dict_mem_index_free(dict_ind_compact);
+ dict_ind_compact = NULL;
+ dict_mem_table_free(table);
+
+ table = dict_ind_redundant->table;
+ dict_mem_index_free(dict_ind_redundant);
+ dict_ind_redundant = NULL;
+ dict_mem_table_free(table);
+}
+
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Get index by name
@@ -4777,4 +4797,55 @@ dict_table_check_for_dup_indexes(
}
}
#endif /* UNIV_DEBUG */
+
+/**************************************************************************
+Closes the data dictionary module. */
+UNIV_INTERN
+void
+dict_close(void)
+/*============*/
+{
+ ulint i;
+
+ /* Free the hash elements. We don't remove them from the table
+ because we are going to destroy the table anyway. */
+ for (i = 0; i < hash_get_n_cells(dict_sys->table_hash); i++) {
+ dict_table_t* table;
+
+ table = HASH_GET_FIRST(dict_sys->table_hash, i);
+
+ while (table) {
+ dict_table_t* prev_table = table;
+
+ table = HASH_GET_NEXT(name_hash, prev_table);
+#ifdef UNIV_DEBUG
+ ut_a(prev_table->magic_n == DICT_TABLE_MAGIC_N);
+#endif
+ /* Acquire only because it's a pre-condition. */
+ mutex_enter(&dict_sys->mutex);
+
+ dict_table_remove_from_cache(prev_table);
+
+ mutex_exit(&dict_sys->mutex);
+ }
+ }
+
+ hash_table_free(dict_sys->table_hash);
+
+ /* The elements are the same instance as in dict_sys->table_hash,
+ therefore we don't delete the individual elements. */
+ hash_table_free(dict_sys->table_id_hash);
+
+ dict_ind_free();
+
+ mutex_free(&dict_sys->mutex);
+
+ rw_lock_free(&dict_operation_lock);
+ memset(&dict_operation_lock, 0x0, sizeof(dict_operation_lock));
+
+ mutex_free(&dict_foreign_err_mutex);
+
+ mem_free(dict_sys);
+ dict_sys = NULL;
+}
#endif /* !UNIV_HOTBACKUP */
=== modified file 'storage/innodb_plugin/fil/fil0fil.c'
--- a/storage/innodb_plugin/fil/fil0fil.c 2009-11-03 10:24:21 +0000
+++ b/storage/innodb_plugin/fil/fil0fil.c 2009-11-30 11:32:05 +0000
@@ -321,6 +321,17 @@ fil_get_space_id_for_table(
/*=======================*/
const char* name); /*!< in: table name in the standard
'databasename/tablename' format */
+/*******************************************************************//**
+Frees a space object from the tablespace memory cache. Closes the files in
+the chain but does not delete them. There must not be any pending i/o's or
+flushes on the files. */
+static
+ibool
+fil_space_free(
+/*===========*/
+ /* out: TRUE if success */
+ ulint id, /* in: space id */
+ ibool own_mutex);/* in: TRUE if own system->mutex */
/********************************************************************//**
Reads data from a space to a buffer. Remember that the possible incomplete
blocks at the end of file are ignored: they are not taken into account when
@@ -1144,7 +1155,7 @@ try_again:
mutex_exit(&fil_system->mutex);
- fil_space_free(namesake_id);
+ fil_space_free(namesake_id, FALSE);
goto try_again;
}
@@ -1269,17 +1280,21 @@ Frees a space object from the tablespace
the chain but does not delete them. There must not be any pending i/o's or
flushes on the files.
@return TRUE if success */
-UNIV_INTERN
+static
ibool
fil_space_free(
/*===========*/
- ulint id) /*!< in: space id */
+ /* out: TRUE if success */
+ ulint id, /* in: space id */
+ ibool own_mutex) /* in: TRUE if own system->mutex */
{
fil_space_t* space;
fil_space_t* namespace;
fil_node_t* fil_node;
- mutex_enter(&fil_system->mutex);
+ if (!own_mutex) {
+ mutex_enter(&fil_system->mutex);
+ }
space = fil_space_get_by_id(id);
@@ -1326,7 +1341,9 @@ fil_space_free(
ut_a(0 == UT_LIST_GET_LEN(space->chain));
- mutex_exit(&fil_system->mutex);
+ if (!own_mutex) {
+ mutex_exit(&fil_system->mutex);
+ }
rw_lock_free(&(space->latch));
@@ -1586,6 +1603,8 @@ fil_close_all_files(void)
space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space != NULL) {
+ fil_space_t* prev_space = space;
+
node = UT_LIST_GET_FIRST(space->chain);
while (node != NULL) {
@@ -1595,6 +1614,7 @@ fil_close_all_files(void)
node = UT_LIST_GET_NEXT(chain, node);
}
space = UT_LIST_GET_NEXT(space_list, space);
+ fil_space_free(prev_space->id, TRUE);
}
mutex_exit(&fil_system->mutex);
@@ -2226,7 +2246,7 @@ try_again:
#endif
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
- success = fil_space_free(id);
+ success = fil_space_free(id, FALSE);
if (success) {
success = os_file_delete(path);
@@ -4753,3 +4773,26 @@ fil_page_get_type(
return(mach_read_from_2(page + FIL_PAGE_TYPE));
}
+
+/********************************************************************
+Initializes the tablespace memory cache. */
+UNIV_INTERN
+void
+fil_close(void)
+/*===========*/
+{
+ /* The mutex should already have been freed. */
+ ut_ad(fil_system->mutex.magic_n == 0);
+
+ hash_table_free(fil_system->spaces);
+
+ hash_table_free(fil_system->name_hash);
+
+ ut_a(UT_LIST_GET_LEN(fil_system->LRU) == 0);
+ ut_a(UT_LIST_GET_LEN(fil_system->unflushed_spaces) == 0);
+ ut_a(UT_LIST_GET_LEN(fil_system->space_list) == 0);
+
+ mem_free(fil_system);
+
+ fil_system = NULL;
+}
=== modified file 'storage/innodb_plugin/handler/ha_innodb.cc'
--- a/storage/innodb_plugin/handler/ha_innodb.cc 2009-11-03 10:34:38 +0000
+++ b/storage/innodb_plugin/handler/ha_innodb.cc 2010-01-13 10:28:42 +0000
@@ -110,9 +110,6 @@ extern "C" {
# ifndef MYSQL_PLUGIN_IMPORT
# define MYSQL_PLUGIN_IMPORT /* nothing */
# endif /* MYSQL_PLUGIN_IMPORT */
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
-is defined the same in both builds: the MySQL server and the InnoDB plugin. */
-extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
#if MYSQL_VERSION_ID < 50124
/* this is defined in mysql_priv.h inside #ifdef MYSQL_SERVER
@@ -269,10 +266,10 @@ innobase_file_format_check_on_off(
/************************************************************//**
Validate the file format check config parameters, as a side effect it
sets the srv_check_file_format_at_startup variable.
-@return true if valid config value */
+@return the format_id if valid config value, otherwise, return -1 */
static
-bool
-innobase_file_format_check_validate(
+int
+innobase_file_format_validate_and_set(
/*================================*/
const char* format_check); /*!< in: parameter value */
/****************************************************************//**
@@ -785,11 +782,20 @@ convert_error_code_to_mysql(
case DB_SUCCESS:
return(0);
+ case DB_INTERRUPTED:
+ my_error(ER_QUERY_INTERRUPTED, MYF(0));
+ /* fall through */
case DB_ERROR:
default:
return(-1); /* unspecified error */
case DB_DUPLICATE_KEY:
+ /* Be cautious with returning this error, since
+ mysql could re-enter the storage layer to get
+ duplicated key info, the operation requires a
+ valid table handle and/or transaction information,
+ which might not always be available in the error
+ handling stage. */
return(HA_ERR_FOUND_DUPP_KEY);
case DB_FOREIGN_DUPLICATE_KEY:
@@ -890,36 +896,6 @@ convert_error_code_to_mysql(
}
/*************************************************************//**
-If you want to print a thd that is not associated with the current thread,
-you must call this function before reserving the InnoDB kernel_mutex, to
-protect MySQL from setting thd->query NULL. If you print a thd of the current
-thread, we know that MySQL cannot modify thd->query, and it is not necessary
-to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release
-the kernel_mutex. */
-extern "C" UNIV_INTERN
-void
-innobase_mysql_prepare_print_arbitrary_thd(void)
-/*============================================*/
-{
- ut_ad(!mutex_own(&kernel_mutex));
- VOID(pthread_mutex_lock(&LOCK_thread_count));
-}
-
-/*************************************************************//**
-Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
-In the InnoDB latching order, the mutex sits right above the
-kernel_mutex. In debug builds, we assert that the kernel_mutex is
-released before this function is invoked. */
-extern "C" UNIV_INTERN
-void
-innobase_mysql_end_print_arbitrary_thd(void)
-/*========================================*/
-{
- ut_ad(!mutex_own(&kernel_mutex));
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
-}
-
-/*************************************************************//**
Prints info of a THD object (== user session thread) to the given file. */
extern "C" UNIV_INTERN
void
@@ -1707,15 +1683,19 @@ innobase_convert_identifier(
FALSE=id is an UTF-8 string */
{
char nz[NAME_LEN + 1];
+#if MYSQL_VERSION_ID >= 50141
+ char nz2[NAME_LEN + 1 + EXPLAIN_FILENAME_MAX_EXTRA_LENGTH];
+#else /* MYSQL_VERSION_ID >= 50141 */
char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
+#endif /* MYSQL_VERSION_ID >= 50141 */
const char* s = id;
int q;
if (file_id) {
- /* Decode the table name. The filename_to_tablename()
- function expects a NUL-terminated string. The input and
- output strings buffers must not be shared. */
+ /* Decode the table name. The MySQL function expects
+ a NUL-terminated string. The input and output strings
+ buffers must not be shared. */
if (UNIV_UNLIKELY(idlen > (sizeof nz) - 1)) {
idlen = (sizeof nz) - 1;
@@ -1725,7 +1705,13 @@ innobase_convert_identifier(
nz[idlen] = 0;
s = nz2;
+#if MYSQL_VERSION_ID >= 50141
+ idlen = explain_filename((THD*) thd, nz, nz2, sizeof nz2,
+ EXPLAIN_PARTITIONS_AS_COMMENT);
+ goto no_quote;
+#else /* MYSQL_VERSION_ID >= 50141 */
idlen = filename_to_tablename(nz, nz2, sizeof nz2);
+#endif /* MYSQL_VERSION_ID >= 50141 */
}
/* See if the identifier needs to be quoted. */
@@ -1736,6 +1722,9 @@ innobase_convert_identifier(
}
if (q == EOF) {
+#if MYSQL_VERSION_ID >= 50141
+no_quote:
+#endif /* MYSQL_VERSION_ID >= 50141 */
if (UNIV_UNLIKELY(idlen > buflen)) {
idlen = buflen;
}
@@ -2133,8 +2122,8 @@ mem_free_and_error:
/* Did the user specify a format name that we support ?
As a side effect it will update the variable
srv_check_file_format_at_startup */
- if (!innobase_file_format_check_validate(
- innobase_file_format_check)) {
+ if (innobase_file_format_validate_and_set(
+ innobase_file_format_check) < 0) {
sql_print_error("InnoDB: invalid "
"innodb_file_format_check value: "
@@ -5225,8 +5214,10 @@ ha_innobase::change_active_index(
prebuilt->index);
if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
- sql_print_warning("InnoDB: insufficient history for index %u",
- keynr);
+ push_warning_printf(user_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ HA_ERR_TABLE_DEF_CHANGED,
+ "InnoDB: insufficient history for index %u",
+ keynr);
/* The caller seems to ignore this. Thus, we must check
this again in row_search_for_mysql(). */
DBUG_RETURN(2);
@@ -5713,17 +5704,8 @@ create_table_def(
/* First check whether the column to be added has a
system reserved name. */
if (dict_col_name_is_reserved(field->field_name)){
- push_warning_printf(
- (THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_CANT_CREATE_TABLE,
- "Error creating table '%s' with "
- "column name '%s'. '%s' is a "
- "reserved name. Please try to "
- "re-create the table with a "
- "different column name.",
- table->name, (char*) field->field_name,
- (char*) field->field_name);
+ my_error(ER_WRONG_COLUMN_NAME, MYF(0),
+ field->field_name);
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
@@ -5745,6 +5727,14 @@ create_table_def(
error = row_create_table_for_mysql(table, trx);
+ if (error == DB_DUPLICATE_KEY) {
+ char buf[100];
+ innobase_convert_identifier(buf, sizeof buf,
+ table_name, strlen(table_name),
+ trx->mysql_thd, TRUE);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
+ }
+
error_ret:
error = convert_error_code_to_mysql(error, flags, NULL);
@@ -6798,6 +6788,24 @@ ha_innobase::rename_table(
innobase_commit_low(trx);
trx_free_for_mysql(trx);
+ /* Add a special case to handle the Duplicated Key error
+ and return DB_ERROR instead.
+ This is to avoid a possible SIGSEGV error from mysql error
+ handling code. Currently, mysql handles the Duplicated Key
+ error by re-entering the storage layer and getting dup key
+ info by calling get_dup_key(). This operation requires a valid
+ table handle ('row_prebuilt_t' structure) which could no
+ longer be available in the error handling stage. The suggested
+ solution is to report a 'table exists' error message (since
+ the dup key error here is due to an existing table whose name
+ is the one we are trying to rename to) and return the generic
+ error code. */
+ if (error == (int) DB_DUPLICATE_KEY) {
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
+
+ error = DB_ERROR;
+ }
+
error = convert_error_code_to_mysql(error, 0, NULL);
DBUG_RETURN(error);
@@ -7348,11 +7356,15 @@ ha_innobase::check(
ret = row_check_table_for_mysql(prebuilt);
- if (ret == DB_SUCCESS) {
+ switch (ret) {
+ case DB_SUCCESS:
return(HA_ADMIN_OK);
+ case DB_INTERRUPTED:
+ my_error(ER_QUERY_INTERRUPTED, MYF(0));
+ return(-1);
+ default:
+ return(HA_ADMIN_CORRUPT);
}
-
- return(HA_ADMIN_CORRUPT);
}
/*************************************************************//**
@@ -7899,7 +7911,10 @@ ha_innobase::external_lock(
ulong const tx_isolation = thd_tx_isolation(ha_thd());
if (tx_isolation <= ISO_READ_COMMITTED
&& binlog_format == BINLOG_FORMAT_STMT
- && thd_binlog_filter_ok(thd))
+#if MYSQL_VERSION_ID > 50140
+ && thd_binlog_filter_ok(thd)
+#endif /* MYSQL_VERSION_ID > 50140 */
+ )
{
char buf[256];
my_snprintf(buf, sizeof(buf),
@@ -9148,8 +9163,7 @@ innobase_xa_prepare(
executing XA PREPARE and XA COMMIT commands.
In this case we cannot know how many minutes or hours
will be between XA PREPARE and XA COMMIT, and we don't want
- to block for undefined period of time.
- */
+ to block for undefined period of time. */
pthread_mutex_lock(&prepare_commit_mutex);
trx->active_trans = 2;
}
@@ -9491,25 +9505,24 @@ innobase_file_format_check_on_off(
/************************************************************//**
Validate the file format check config parameters, as a side effect it
sets the srv_check_file_format_at_startup variable.
-@return true if valid config value */
+@return the format_id if valid config value, otherwise, return -1 */
static
-bool
-innobase_file_format_check_validate(
+int
+innobase_file_format_validate_and_set(
/*================================*/
const char* format_check) /*!< in: parameter value */
{
uint format_id;
- bool ret = true;
format_id = innobase_file_format_name_lookup(format_check);
if (format_id < DICT_TF_FORMAT_MAX + 1) {
srv_check_file_format_at_startup = format_id;
+
+ return((int) format_id);
} else {
- ret = false;
+ return(-1);
}
-
- return(ret);
}
/*************************************************************//**
@@ -9544,7 +9557,11 @@ innodb_file_format_name_validate(
if (format_id <= DICT_TF_FORMAT_MAX) {
- *static_cast<const char**>(save) = file_format_input;
+ /* Save a pointer to the name in the
+ 'file_format_name_map' constant array. */
+ *static_cast<const char**>(save) =
+ trx_sys_file_format_id_to_name(format_id);
+
return(0);
}
}
@@ -9607,6 +9624,7 @@ innodb_file_format_check_validate(
const char* file_format_input;
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
+ int format_id;
ut_a(save != NULL);
ut_a(value != NULL);
@@ -9619,24 +9637,35 @@ innodb_file_format_check_validate(
message if they did so. */
if (innobase_file_format_check_on_off(file_format_input)) {
- sql_print_warning(
+ push_warning_printf(thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
"InnoDB: invalid innodb_file_format_check "
"value; on/off can only be set at startup or "
"in the configuration file");
- } else if (innobase_file_format_check_validate(
- file_format_input)) {
+ } else {
+ format_id = innobase_file_format_validate_and_set(
+ file_format_input);
- *static_cast<const char**>(save) = file_format_input;
+ if (format_id >= 0) {
+ /* Save a pointer to the name in the
+ 'file_format_name_map' constant array. */
+ *static_cast<const char**>(save) =
+ trx_sys_file_format_id_to_name(
+ (uint)format_id);
- return(0);
+ return(0);
- } else {
- sql_print_warning(
- "InnoDB: invalid innodb_file_format_check "
- "value; can be any format up to %s "
- "or its equivalent numeric id",
- trx_sys_file_format_id_to_name(
- DICT_TF_FORMAT_MAX));
+ } else {
+ push_warning_printf(thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "InnoDB: invalid innodb_file_format_check "
+ "value; can be any format up to %s "
+ "or its equivalent numeric id",
+ trx_sys_file_format_id_to_name(
+ DICT_TF_FORMAT_MAX));
+ }
}
}
@@ -9906,12 +9935,15 @@ static MYSQL_SYSVAR_STR(file_format, inn
innodb_file_format_name_validate,
innodb_file_format_name_update, "Antelope");
+/* If a new file format is introduced, the file format
+name needs to be updated accordingly. Please refer to
+file_format_name_map[] defined in trx0sys.c for the next
+file format name. */
static MYSQL_SYSVAR_STR(file_format_check, innobase_file_format_check,
PLUGIN_VAR_OPCMDARG,
"The highest file format in the tablespace.",
innodb_file_format_check_validate,
- innodb_file_format_check_update,
- "on");
+ innodb_file_format_check_update, "Barracuda");
static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
PLUGIN_VAR_OPCMDARG,
=== modified file 'storage/innodb_plugin/handler/ha_innodb.h'
--- a/storage/innodb_plugin/handler/ha_innodb.h 2009-11-03 10:07:51 +0000
+++ b/storage/innodb_plugin/handler/ha_innodb.h 2009-11-30 12:11:36 +0000
@@ -258,12 +258,14 @@ int thd_binlog_format(const MYSQL_THD th
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+#if MYSQL_VERSION_ID > 50140
/**
Check if binary logging is filtered for thread's current db.
@param thd Thread handle
@retval 1 the query is not filtered, 0 otherwise.
*/
bool thd_binlog_filter_ok(const MYSQL_THD thd);
+#endif /* MYSQL_VERSION_ID > 50140 */
}
typedef struct trx_struct trx_t;
=== modified file 'storage/innodb_plugin/handler/handler0alter.cc'
--- a/storage/innodb_plugin/handler/handler0alter.cc 2009-11-03 10:07:51 +0000
+++ b/storage/innodb_plugin/handler/handler0alter.cc 2009-11-30 13:42:26 +0000
@@ -765,10 +765,11 @@ err_exit:
ut_ad(error == DB_SUCCESS);
/* Commit the data dictionary transaction in order to release
- the table locks on the system tables. Unfortunately, this
- means that if MySQL crashes while creating a new primary key
- inside row_merge_build_indexes(), indexed_table will not be
- dropped on crash recovery. Thus, it will become orphaned. */
+ the table locks on the system tables. This means that if
+ MySQL crashes while creating a new primary key inside
+ row_merge_build_indexes(), indexed_table will not be dropped
+ by trx_rollback_active(). It will have to be recovered or
+ dropped by the database administrator. */
trx_commit_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
@@ -882,7 +883,9 @@ error:
/* fall through */
default:
if (new_primary) {
- row_merge_drop_table(trx, indexed_table);
+ if (indexed_table != innodb_table) {
+ row_merge_drop_table(trx, indexed_table);
+ }
} else {
if (!dict_locked) {
row_mysql_lock_data_dictionary(trx);
=== modified file 'storage/innodb_plugin/ibuf/ibuf0ibuf.c'
--- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c 2009-11-30 11:32:05 +0000
@@ -390,6 +390,27 @@ ibuf_count_set(
#endif
/******************************************************************//**
+Closes insert buffer and frees the data structures. */
+UNIV_INTERN
+void
+ibuf_close(void)
+/*============*/
+{
+ mutex_free(&ibuf_pessimistic_insert_mutex);
+ memset(&ibuf_pessimistic_insert_mutex,
+ 0x0, sizeof(ibuf_pessimistic_insert_mutex));
+
+ mutex_free(&ibuf_mutex);
+ memset(&ibuf_mutex, 0x0, sizeof(ibuf_mutex));
+
+ mutex_free(&ibuf_bitmap_mutex);
+ memset(&ibuf_bitmap_mutex, 0x0, sizeof(ibuf_mutex));
+
+ mem_free(ibuf);
+ ibuf = NULL;
+}
+
+/******************************************************************//**
Updates the size information of the ibuf, assuming the segment size has not
changed. */
static
=== modified file 'storage/innodb_plugin/include/btr0sea.h'
--- a/storage/innodb_plugin/include/btr0sea.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/btr0sea.h 2009-11-30 11:32:05 +0000
@@ -41,6 +41,12 @@ void
btr_search_sys_create(
/*==================*/
ulint hash_size); /*!< in: hash index hash table size */
+/*****************************************************************//**
+Frees the adaptive search system at a database shutdown. */
+UNIV_INTERN
+void
+btr_search_sys_free(void);
+/*=====================*/
/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
=== modified file 'storage/innodb_plugin/include/db0err.h'
--- a/storage/innodb_plugin/include/db0err.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/db0err.h 2009-11-30 12:24:54 +0000
@@ -32,6 +32,7 @@ enum db_err {
/* The following are error codes */
DB_ERROR,
+ DB_INTERRUPTED,
DB_OUT_OF_MEMORY,
DB_OUT_OF_FILE_SPACE,
DB_LOCK_WAIT,
=== modified file 'storage/innodb_plugin/include/dict0dict.h'
--- a/storage/innodb_plugin/include/dict0dict.h 2009-10-08 11:28:37 +0000
+++ b/storage/innodb_plugin/include/dict0dict.h 2009-11-30 11:32:05 +0000
@@ -1151,6 +1151,13 @@ void
dict_ind_init(void);
/*===============*/
+/**********************************************************************//**
+Closes the data dictionary module. */
+UNIV_INTERN
+void
+dict_close(void);
+/*============*/
+
#ifndef UNIV_NONINL
#include "dict0dict.ic"
#endif
=== modified file 'storage/innodb_plugin/include/fil0fil.h'
--- a/storage/innodb_plugin/include/fil0fil.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/fil0fil.h 2009-11-30 11:32:05 +0000
@@ -224,15 +224,6 @@ fil_space_create(
0 for uncompressed tablespaces */
ulint purpose);/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
/*******************************************************************//**
-Frees a space object from a the tablespace memory cache. Closes the files in
-the chain but does not delete them.
-@return TRUE if success */
-UNIV_INTERN
-ibool
-fil_space_free(
-/*===========*/
- ulint id); /*!< in: space id */
-/*******************************************************************//**
Returns the size of the space in pages. The tablespace must be cached in the
memory cache.
@return space size, 0 if space not found */
@@ -278,6 +269,12 @@ fil_init(
ulint hash_size, /*!< in: hash table size */
ulint max_n_open); /*!< in: max number of open files */
/*******************************************************************//**
+Initializes the tablespace memory cache. */
+UNIV_INTERN
+void
+fil_close(void);
+/*===========*/
+/*******************************************************************//**
Opens all log files and system tablespace data files. They stay open until the
database server shutdown. This should be called at a server startup after the
space objects for the log and the system tablespace have been created. The
=== modified file 'storage/innodb_plugin/include/ha_prototypes.h'
--- a/storage/innodb_plugin/include/ha_prototypes.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/ha_prototypes.h 2009-12-01 10:38:40 +0000
@@ -153,28 +153,6 @@ get_innobase_type_from_mysql_type(
const void* field) /*!< in: MySQL Field */
__attribute__((nonnull));
-/*************************************************************//**
-If you want to print a thd that is not associated with the current thread,
-you must call this function before reserving the InnoDB kernel_mutex, to
-protect MySQL from setting thd->query NULL. If you print a thd of the current
-thread, we know that MySQL cannot modify thd->query, and it is not necessary
-to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release
-the kernel_mutex. */
-UNIV_INTERN
-void
-innobase_mysql_prepare_print_arbitrary_thd(void);
-/*============================================*/
-
-/*************************************************************//**
-Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
-In the InnoDB latching order, the mutex sits right above the
-kernel_mutex. In debug builds, we assert that the kernel_mutex is
-released before this function is invoked. */
-UNIV_INTERN
-void
-innobase_mysql_end_print_arbitrary_thd(void);
-/*========================================*/
-
/******************************************************************//**
Get the variable length bounds of the given character set. */
UNIV_INTERN
=== modified file 'storage/innodb_plugin/include/ibuf0ibuf.h'
--- a/storage/innodb_plugin/include/ibuf0ibuf.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/ibuf0ibuf.h 2009-11-30 11:32:05 +0000
@@ -356,6 +356,12 @@ void
ibuf_print(
/*=======*/
FILE* file); /*!< in: file where to print */
+/******************************************************************//**
+Closes insert buffer and frees the data structures. */
+UNIV_INTERN
+void
+ibuf_close(void);
+/*============*/
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
=== modified file 'storage/innodb_plugin/include/lock0lock.h'
--- a/storage/innodb_plugin/include/lock0lock.h 2009-10-08 12:18:19 +0000
+++ b/storage/innodb_plugin/include/lock0lock.h 2009-11-30 11:32:05 +0000
@@ -59,6 +59,12 @@ lock_sys_create(
/*============*/
ulint n_cells); /*!< in: number of slots in lock hash table */
/*********************************************************************//**
+Closes the lock system at database shutdown. */
+UNIV_INTERN
+void
+lock_sys_close(void);
+/*================*/
+/*********************************************************************//**
Checks if some transaction has an implicit x-lock on a record in a clustered
index.
@return transaction which has the x-lock, or NULL */
=== modified file 'storage/innodb_plugin/include/log0log.h'
--- a/storage/innodb_plugin/include/log0log.h 2009-10-08 12:18:19 +0000
+++ b/storage/innodb_plugin/include/log0log.h 2009-11-30 11:32:05 +0000
@@ -572,6 +572,18 @@ UNIV_INTERN
void
log_refresh_stats(void);
/*===================*/
+/**********************************************************
+Shutdown the log system but do not release all the memory. */
+UNIV_INTERN
+void
+log_shutdown(void);
+/*==============*/
+/**********************************************************
+Free the log system data structures. */
+UNIV_INTERN
+void
+log_mem_free(void);
+/*==============*/
extern log_t* log_sys;
@@ -584,7 +596,7 @@ extern log_t* log_sys;
#define LOG_RECOVER 98887331
/* The counting of lsn's starts from this value: this must be non-zero */
-#define LOG_START_LSN ((ib_uint64_t) (16 * OS_FILE_LOG_BLOCK_SIZE))
+#define LOG_START_LSN ((ib_uint64_t) (16 * OS_FILE_LOG_BLOCK_SIZE))
#define LOG_BUFFER_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE)
#define LOG_ARCHIVE_BUF_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE / 4)
@@ -721,9 +733,12 @@ struct log_group_struct{
ulint lsn_offset; /*!< the offset of the above lsn */
ulint n_pending_writes;/*!< number of currently pending flush
writes for this log group */
+ byte** file_header_bufs_ptr;/*!< unaligned buffers */
byte** file_header_bufs;/*!< buffers for each file
header in the group */
+#ifdef UNIV_LOG_ARCHIVE
/*-----------------------------*/
+ byte** archive_file_header_bufs_ptr;/*!< unaligned buffers */
byte** archive_file_header_bufs;/*!< buffers for each file
header in the group */
ulint archive_space_id;/*!< file space which
@@ -742,10 +757,12 @@ struct log_group_struct{
completion function then sets the new
value to ..._file_no */
ulint next_archived_offset; /*!< like the preceding field */
+#endif /* UNIV_LOG_ARCHIVE */
/*-----------------------------*/
ib_uint64_t scanned_lsn; /*!< used only in recovery: recovery scan
succeeded up to this lsn in this log
group */
+ byte* checkpoint_buf_ptr;/*!< unaligned checkpoint header */
byte* checkpoint_buf; /*!< checkpoint header is written from
this buffer to the group */
UT_LIST_NODE_T(log_group_t)
@@ -763,6 +780,7 @@ struct log_struct{
#ifndef UNIV_HOTBACKUP
mutex_t mutex; /*!< mutex protecting the log */
#endif /* !UNIV_HOTBACKUP */
+ byte* buf_ptr; /* unaligned log buffer */
byte* buf; /*!< log buffer */
ulint buf_size; /*!< log buffer size in bytes */
ulint max_buf_free; /*!< recommended maximum value of
@@ -899,6 +917,7 @@ struct log_struct{
should wait for this without owning
the log mutex */
#endif /* !UNIV_HOTBACKUP */
+ byte* checkpoint_buf_ptr;/* unaligned checkpoint header */
byte* checkpoint_buf; /*!< checkpoint header is read to this
buffer */
/* @} */
=== modified file 'storage/innodb_plugin/include/log0recv.h'
--- a/storage/innodb_plugin/include/log0recv.h 2009-10-09 14:13:15 +0000
+++ b/storage/innodb_plugin/include/log0recv.h 2009-11-30 11:32:05 +0000
@@ -239,6 +239,18 @@ UNIV_INTERN
void
recv_sys_create(void);
/*=================*/
+/**********************************************************//**
+Release recovery system mutexes. */
+UNIV_INTERN
+void
+recv_sys_close(void);
+/*================*/
+/********************************************************//**
+Frees the recovery system memory. */
+UNIV_INTERN
+void
+recv_sys_mem_free(void);
+/*===================*/
/********************************************************//**
Inits the recovery system for a recovery operation. */
UNIV_INTERN
@@ -246,6 +258,12 @@ void
recv_sys_init(
/*==========*/
ulint available_memory); /*!< in: available memory in bytes */
+/********************************************************//**
+Reset the state of the recovery system variables. */
+UNIV_INTERN
+void
+recv_sys_var_init(void);
+/*===================*/
/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
=== modified file 'storage/innodb_plugin/include/mem0mem.h'
--- a/storage/innodb_plugin/include/mem0mem.h 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/mem0mem.h 2009-11-30 11:32:05 +0000
@@ -82,6 +82,13 @@ void
mem_init(
/*=====*/
ulint size); /*!< in: common pool size in bytes */
+/******************************************************************//**
+Closes the memory system. */
+UNIV_INTERN
+void
+mem_close(void);
+/*===========*/
+
/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
=== modified file 'storage/innodb_plugin/include/mem0pool.h'
--- a/storage/innodb_plugin/include/mem0pool.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/mem0pool.h 2009-11-30 11:32:05 +0000
@@ -62,6 +62,13 @@ mem_pool_create(
/*============*/
ulint size); /*!< in: pool size in bytes */
/********************************************************************//**
+Frees a memory pool. */
+UNIV_INTERN
+void
+mem_pool_free(
+/*==========*/
+ mem_pool_t* pool); /*!< in, own: memory pool */
+/********************************************************************//**
Allocates memory from a pool. NOTE: This low-level function should only be
used in mem0mem.*!
@return own: allocated memory buffer */
=== modified file 'storage/innodb_plugin/include/os0file.h'
--- a/storage/innodb_plugin/include/os0file.h 2009-11-03 09:59:06 +0000
+++ b/storage/innodb_plugin/include/os0file.h 2009-11-30 12:04:09 +0000
@@ -158,6 +158,7 @@ log. */
#define OS_FILE_SHARING_VIOLATION 76
#define OS_FILE_ERROR_NOT_SPECIFIED 77
#define OS_FILE_INSUFFICIENT_RESOURCE 78
+#define OS_FILE_OPERATION_ABORTED 79
/* @} */
/** Types for aio operations @{ */
@@ -620,6 +621,13 @@ os_aio_init(
ulint n_write_segs, /*<! in: number of writer threads */
ulint n_slots_sync); /*<! in: number of slots in the sync aio
array */
+/***********************************************************************
+Frees the asynchronous io system. */
+UNIV_INTERN
+void
+os_aio_free(void);
+/*=============*/
+
/*******************************************************************//**
Requests an asynchronous i/o operation.
@return TRUE if request was queued successfully, FALSE if fail */
=== modified file 'storage/innodb_plugin/include/pars0pars.h'
--- a/storage/innodb_plugin/include/pars0pars.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/pars0pars.h 2009-11-30 11:32:05 +0000
@@ -583,6 +583,12 @@ pars_info_get_bound_id(
pars_info_t* info, /*!< in: info struct */
const char* name); /*!< in: bound id name to find */
+/******************************************************************//**
+Release any resources used by the lexer. */
+UNIV_INTERN
+void
+pars_lexer_close(void);
+/*==================*/
/** Extra information supplied for pars_sql(). */
struct pars_info_struct {
=== modified file 'storage/innodb_plugin/include/srv0srv.h'
--- a/storage/innodb_plugin/include/srv0srv.h 2009-10-08 11:28:37 +0000
+++ b/storage/innodb_plugin/include/srv0srv.h 2009-11-30 11:32:05 +0000
@@ -411,7 +411,7 @@ void
srv_init(void);
/*==========*/
/*********************************************************************//**
-Frees the OS fast mutex created in srv_boot(). */
+Frees the data structures created in srv_init(). */
UNIV_INTERN
void
srv_free(void);
=== modified file 'storage/innodb_plugin/include/thr0loc.h'
--- a/storage/innodb_plugin/include/thr0loc.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/thr0loc.h 2009-11-30 11:32:05 +0000
@@ -39,6 +39,12 @@ UNIV_INTERN
void
thr_local_init(void);
/*================*/
+ /****************************************************************//**
+Close the thread local storage module. */
+UNIV_INTERN
+void
+thr_local_close(void);
+/*=================*/
/*******************************************************************//**
Creates a local storage struct for the calling new thread. */
UNIV_INTERN
=== modified file 'storage/innodb_plugin/include/trx0i_s.h'
--- a/storage/innodb_plugin/include/trx0i_s.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/trx0i_s.h 2009-11-30 11:32:05 +0000
@@ -141,6 +141,13 @@ void
trx_i_s_cache_init(
/*===============*/
trx_i_s_cache_t* cache); /*!< out: cache to init */
+/*******************************************************************//**
+Free the INFORMATION SCHEMA trx related cache. */
+UNIV_INTERN
+void
+trx_i_s_cache_free(
+/*===============*/
+ trx_i_s_cache_t* cache); /*!< in/out: cache to free */
/*******************************************************************//**
Issue a shared/read lock on the tables cache. */
=== modified file 'storage/innodb_plugin/include/trx0purge.h'
--- a/storage/innodb_plugin/include/trx0purge.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/trx0purge.h 2009-11-30 11:32:05 +0000
@@ -71,6 +71,12 @@ void
trx_purge_sys_create(void);
/*======================*/
/********************************************************************//**
+Frees the global purge system control structure. */
+UNIV_INTERN
+void
+trx_purge_sys_close(void);
+/*======================*/
+/************************************************************************
Adds the update undo log as the first log in the history list. Removes the
update undo log segment from the rseg slot if it is too big for reuse. */
UNIV_INTERN
=== modified file 'storage/innodb_plugin/include/trx0rseg.h'
--- a/storage/innodb_plugin/include/trx0rseg.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/trx0rseg.h 2009-11-30 11:32:05 +0000
@@ -125,6 +125,13 @@ trx_rseg_create(
ulint max_size, /*!< in: max size in pages */
ulint* id, /*!< out: rseg id */
mtr_t* mtr); /*!< in: mtr */
+/***************************************************************************
+Free's an instance of the rollback segment in memory. */
+UNIV_INTERN
+void
+trx_rseg_mem_free(
+/*==============*/
+ trx_rseg_t* rseg); /* in, own: instance to free */
/* Number of undo log slots in a rollback segment file copy */
=== modified file 'storage/innodb_plugin/include/trx0sys.h'
--- a/storage/innodb_plugin/include/trx0sys.h 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/trx0sys.h 2009-11-30 11:32:05 +0000
@@ -334,6 +334,12 @@ void
trx_sys_file_format_tag_init(void);
/*==============================*/
/*****************************************************************//**
+Shutdown/Close the transaction system. */
+UNIV_INTERN
+void
+trx_sys_close(void);
+/*===============*/
+/*****************************************************************//**
Get the name representation of the file format from its id.
@return pointer to the name */
UNIV_INTERN
=== modified file 'storage/innodb_plugin/include/trx0trx.h'
--- a/storage/innodb_plugin/include/trx0trx.h 2009-10-08 13:05:59 +0000
+++ b/storage/innodb_plugin/include/trx0trx.h 2009-12-01 10:38:40 +0000
@@ -338,9 +338,7 @@ trx_commit_step(
/**********************************************************************//**
Prints info about a transaction to the given file. The caller must own the
-kernel mutex and must have called
-innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
-or InnoDB cannot meanwhile change the info printed here. */
+kernel mutex. */
UNIV_INTERN
void
trx_print(
=== modified file 'storage/innodb_plugin/include/trx0undo.h'
--- a/storage/innodb_plugin/include/trx0undo.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/trx0undo.h 2009-11-30 11:32:05 +0000
@@ -333,6 +333,13 @@ trx_undo_parse_discard_latest(
byte* end_ptr,/*!< in: buffer end */
page_t* page, /*!< in: page or NULL */
mtr_t* mtr); /*!< in: mtr or NULL */
+/************************************************************************
+Frees an undo log memory copy. */
+UNIV_INTERN
+void
+trx_undo_mem_free(
+/*==============*/
+ trx_undo_t* undo); /* in: the undo object to be freed */
/* Types of an undo log segment */
#define TRX_UNDO_INSERT 1 /* contains undo entries for inserts */
=== modified file 'storage/innodb_plugin/include/univ.i'
--- a/storage/innodb_plugin/include/univ.i 2009-11-03 10:26:39 +0000
+++ b/storage/innodb_plugin/include/univ.i 2009-11-30 13:13:34 +0000
@@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
-#define INNODB_VERSION_BUGFIX 5
+#define INNODB_VERSION_BUGFIX 6
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
=== modified file 'storage/innodb_plugin/include/usr0sess.h'
--- a/storage/innodb_plugin/include/usr0sess.h 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/usr0sess.h 2009-11-30 11:32:05 +0000
@@ -44,14 +44,12 @@ sess_t*
sess_open(void);
/*============*/
/*********************************************************************//**
-Closes a session, freeing the memory occupied by it, if it is in a state
-where it should be closed.
-@return TRUE if closed */
+Closes a session, freeing the memory occupied by it. */
UNIV_INTERN
-ibool
-sess_try_close(
-/*===========*/
- sess_t* sess); /*!< in, own: session object */
+void
+sess_close(
+/*=======*/
+ sess_t* sess); /* in, own: session object */
/* The session handle. All fields are protected by the kernel mutex */
struct sess_struct{
=== modified file 'storage/innodb_plugin/lock/lock0lock.c'
--- a/storage/innodb_plugin/lock/lock0lock.c 2009-10-09 14:13:15 +0000
+++ b/storage/innodb_plugin/lock/lock0lock.c 2009-12-01 10:38:40 +0000
@@ -578,6 +578,23 @@ lock_sys_create(
}
/*********************************************************************//**
+Closes the lock system at database shutdown. */
+UNIV_INTERN
+void
+lock_sys_close(void)
+/*================*/
+{
+ if (lock_latest_err_file != NULL) {
+ fclose(lock_latest_err_file);
+ lock_latest_err_file = NULL;
+ }
+
+ hash_table_free(lock_sys->rec_hash);
+ mem_free(lock_sys);
+ lock_sys = NULL;
+}
+
+/*********************************************************************//**
Gets the size of a lock struct.
@return size in bytes */
UNIV_INTERN
@@ -4307,11 +4324,6 @@ lock_print_info_summary(
/*====================*/
FILE* file) /*!< in: file where to print */
{
- /* We must protect the MySQL thd->query field with a MySQL mutex, and
- because the MySQL mutex must be reserved before the kernel_mutex of
- InnoDB, we call innobase_mysql_prepare_print_arbitrary_thd() here. */
-
- innobase_mysql_prepare_print_arbitrary_thd();
lock_mutex_enter_kernel();
if (lock_deadlock_found) {
@@ -4394,7 +4406,6 @@ loop:
if (trx == NULL) {
lock_mutex_exit_kernel();
- innobase_mysql_end_print_arbitrary_thd();
ut_ad(lock_validate());
@@ -4478,7 +4489,6 @@ loop:
}
lock_mutex_exit_kernel();
- innobase_mysql_end_print_arbitrary_thd();
mtr_start(&mtr);
@@ -4489,7 +4499,6 @@ loop:
load_page_first = FALSE;
- innobase_mysql_prepare_print_arbitrary_thd();
lock_mutex_enter_kernel();
goto loop;
=== modified file 'storage/innodb_plugin/log/log0log.c'
--- a/storage/innodb_plugin/log/log0log.c 2009-10-09 14:13:15 +0000
+++ b/storage/innodb_plugin/log/log0log.c 2009-11-30 11:32:05 +0000
@@ -771,8 +771,6 @@ void
log_init(void)
/*==========*/
{
- byte* buf;
-
log_sys = mem_alloc(sizeof(log_t));
mutex_create(&log_sys->mutex, SYNC_LOG);
@@ -787,8 +785,8 @@ log_init(void)
ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE);
ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);
- buf = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
- log_sys->buf = ut_align(buf, OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->buf_ptr = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->buf = ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE);
log_sys->buf_size = LOG_BUFFER_SIZE;
@@ -833,9 +831,9 @@ log_init(void)
rw_lock_create(&log_sys->checkpoint_lock, SYNC_NO_ORDER_CHECK);
- log_sys->checkpoint_buf
- = ut_align(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE),
- OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->checkpoint_buf = ut_align(log_sys->checkpoint_buf_ptr,
+ OS_FILE_LOG_BLOCK_SIZE);
memset(log_sys->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
/*----------------------------*/
@@ -918,23 +916,33 @@ log_group_init(
group->lsn_offset = LOG_FILE_HDR_SIZE;
group->n_pending_writes = 0;
+ group->file_header_bufs_ptr = mem_alloc(sizeof(byte*) * n_files);
group->file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
#ifdef UNIV_LOG_ARCHIVE
+ group->archive_file_header_bufs_ptr = mem_alloc(
+ sizeof(byte*) * n_files);
group->archive_file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
#endif /* UNIV_LOG_ARCHIVE */
for (i = 0; i < n_files; i++) {
- *(group->file_header_bufs + i) = ut_align(
- mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
+ group->file_header_bufs_ptr[i] = mem_alloc(
+ LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
+
+ group->file_header_bufs[i] = ut_align(
+ group->file_header_bufs_ptr[i],
OS_FILE_LOG_BLOCK_SIZE);
memset(*(group->file_header_bufs + i), '\0',
LOG_FILE_HDR_SIZE);
#ifdef UNIV_LOG_ARCHIVE
- *(group->archive_file_header_bufs + i) = ut_align(
- mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
+ group->archive_file_header_bufs_ptr[i] = mem_alloc(
+ LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
+
+ group->archive_file_header_bufs[i] = ut_align(
+ group->archive_file_header_bufs_ptr[i],
OS_FILE_LOG_BLOCK_SIZE);
+
memset(*(group->archive_file_header_bufs + i), '\0',
LOG_FILE_HDR_SIZE);
#endif /* UNIV_LOG_ARCHIVE */
@@ -947,8 +955,9 @@ log_group_init(
group->archived_offset = 0;
#endif /* UNIV_LOG_ARCHIVE */
- group->checkpoint_buf = ut_align(
- mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE);
+ group->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
+ group->checkpoint_buf = ut_align(group->checkpoint_buf_ptr,
+ OS_FILE_LOG_BLOCK_SIZE);
memset(group->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
@@ -3364,4 +3373,95 @@ log_refresh_stats(void)
log_sys->n_log_ios_old = log_sys->n_log_ios;
log_sys->last_printout_time = time(NULL);
}
+
+/**********************************************************************
+Closes a log group. */
+static
+void
+log_group_close(
+/*===========*/
+ log_group_t* group) /* in,own: log group to close */
+{
+ ulint i;
+
+ for (i = 0; i < group->n_files; i++) {
+ mem_free(group->file_header_bufs_ptr[i]);
+#ifdef UNIV_LOG_ARCHIVE
+ mem_free(group->archive_file_header_bufs_ptr[i]);
+#endif /* UNIV_LOG_ARCHIVE */
+ }
+
+ mem_free(group->file_header_bufs_ptr);
+ mem_free(group->file_header_bufs);
+
+#ifdef UNIV_LOG_ARCHIVE
+ mem_free(group->archive_file_header_bufs_ptr);
+ mem_free(group->archive_file_header_bufs);
+#endif /* UNIV_LOG_ARCHIVE */
+
+ mem_free(group->checkpoint_buf_ptr);
+
+ mem_free(group);
+}
+
+/**********************************************************
+Shutdown the log system but do not release all the memory. */
+UNIV_INTERN
+void
+log_shutdown(void)
+/*==============*/
+{
+ log_group_t* group;
+
+ group = UT_LIST_GET_FIRST(log_sys->log_groups);
+
+ while (UT_LIST_GET_LEN(log_sys->log_groups) > 0) {
+ log_group_t* prev_group = group;
+
+ group = UT_LIST_GET_NEXT(log_groups, group);
+ UT_LIST_REMOVE(log_groups, log_sys->log_groups, prev_group);
+
+ log_group_close(prev_group);
+ }
+
+ mem_free(log_sys->buf_ptr);
+ log_sys->buf_ptr = NULL;
+ log_sys->buf = NULL;
+ mem_free(log_sys->checkpoint_buf_ptr);
+ log_sys->checkpoint_buf_ptr = NULL;
+ log_sys->checkpoint_buf = NULL;
+
+ os_event_free(log_sys->no_flush_event);
+ os_event_free(log_sys->one_flushed_event);
+
+ rw_lock_free(&log_sys->checkpoint_lock);
+
+ mutex_free(&log_sys->mutex);
+
+#ifdef UNIV_LOG_ARCHIVE
+ rw_lock_free(&log_sys->archive_lock);
+ os_event_create(log_sys->archiving_on);
+#endif /* UNIV_LOG_ARCHIVE */
+
+#ifdef UNIV_LOG_DEBUG
+ recv_sys_debug_free();
+#endif
+
+ recv_sys_close();
+}
+
+/**********************************************************
+Free the log system data structures. */
+UNIV_INTERN
+void
+log_mem_free(void)
+/*==============*/
+{
+ if (log_sys != NULL) {
+ recv_sys_mem_free();
+ mem_free(log_sys);
+
+ log_sys = NULL;
+ }
+}
#endif /* !UNIV_HOTBACKUP */
=== modified file 'storage/innodb_plugin/log/log0recv.c'
--- a/storage/innodb_plugin/log/log0recv.c 2009-10-09 14:13:15 +0000
+++ b/storage/innodb_plugin/log/log0recv.c 2009-11-30 11:32:05 +0000
@@ -69,15 +69,15 @@ UNIV_INTERN recv_sys_t* recv_sys = NULL;
/** TRUE when applying redo log records during crash recovery; FALSE
otherwise. Note that this is FALSE while a background thread is
rolling back incomplete transactions. */
-UNIV_INTERN ibool recv_recovery_on = FALSE;
+UNIV_INTERN ibool recv_recovery_on;
#ifdef UNIV_LOG_ARCHIVE
/** TRUE when applying redo log records from an archived log file */
-UNIV_INTERN ibool recv_recovery_from_backup_on = FALSE;
+UNIV_INTERN ibool recv_recovery_from_backup_on;
#endif /* UNIV_LOG_ARCHIVE */
#ifndef UNIV_HOTBACKUP
/** TRUE when recv_init_crash_recovery() has been called. */
-UNIV_INTERN ibool recv_needed_recovery = FALSE;
+UNIV_INTERN ibool recv_needed_recovery;
# ifdef UNIV_DEBUG
/** TRUE if writing to the redo log (mtr_commit) is forbidden.
Protected by log_sys->mutex. */
@@ -87,7 +87,7 @@ UNIV_INTERN ibool recv_no_log_write = FA
/** TRUE if buf_page_is_corrupted() should check if the log sequence
number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
recv_recovery_from_checkpoint_start_func(). */
-UNIV_INTERN ibool recv_lsn_checks_on = FALSE;
+UNIV_INTERN ibool recv_lsn_checks_on;
/** There are two conditions under which we scan the logs, the first
is normal startup and the second is when we do a recovery from an
@@ -97,7 +97,7 @@ startup. If we find log entries that wer
we know that the server was not cleanly shutdown. We must then initialize
the crash recovery environment before attempting to store these entries in
the log hash table. */
-static ibool recv_log_scan_is_startup_type = FALSE;
+static ibool recv_log_scan_is_startup_type;
/** If the following is TRUE, the buffer pool file pages must be invalidated
after recovery and no ibuf operations are allowed; this becomes TRUE if
@@ -108,7 +108,7 @@ buffer pool before the pages have been r
TRUE means that recovery is running and no operations on the log files
are allowed yet: the variable name is misleading. */
-UNIV_INTERN ibool recv_no_ibuf_operations = FALSE;
+UNIV_INTERN ibool recv_no_ibuf_operations;
/** TRUE when the redo log is being backed up */
# define recv_is_making_a_backup FALSE
/** TRUE when recovering from a backed up redo log file */
@@ -116,30 +116,30 @@ UNIV_INTERN ibool recv_no_ibuf_operation
#else /* !UNIV_HOTBACKUP */
# define recv_needed_recovery FALSE
/** TRUE when the redo log is being backed up */
-UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
+UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
/** TRUE when recovering from a backed up redo log file */
UNIV_INTERN ibool recv_is_from_backup = FALSE;
# define buf_pool_get_curr_size() (5 * 1024 * 1024)
#endif /* !UNIV_HOTBACKUP */
/** The following counter is used to decide when to print info on
log scan */
-static ulint recv_scan_print_counter = 0;
+static ulint recv_scan_print_counter;
/** The type of the previous parsed redo log record */
-static ulint recv_previous_parsed_rec_type = 999999;
+static ulint recv_previous_parsed_rec_type;
/** The offset of the previous parsed redo log record */
-static ulint recv_previous_parsed_rec_offset = 0;
+static ulint recv_previous_parsed_rec_offset;
/** The 'multi' flag of the previous parsed redo log record */
-static ulint recv_previous_parsed_rec_is_multi = 0;
+static ulint recv_previous_parsed_rec_is_multi;
/** Maximum page number encountered in the redo log */
-UNIV_INTERN ulint recv_max_parsed_page_no = 0;
+UNIV_INTERN ulint recv_max_parsed_page_no;
/** This many frames must be left free in the buffer pool when we scan
the log and store the scanned log records in the buffer pool: we will
use these free frames to read in pages when we start applying the
log records to the database. */
-UNIV_INTERN ulint recv_n_pool_free_frames = 256;
+UNIV_INTERN ulint recv_n_pool_free_frames;
/** The maximum lsn we see for a page during the recovery process. If this
is bigger than the lsn we are able to scan up to, that is an indication that
@@ -170,7 +170,8 @@ recv_sys_create(void)
return;
}
- recv_sys = mem_alloc(sizeof(recv_sys_t));
+ recv_sys = mem_alloc(sizeof(*recv_sys));
+ memset(recv_sys, 0x0, sizeof(*recv_sys));
mutex_create(&recv_sys->mutex, SYNC_RECV);
@@ -179,6 +180,106 @@ recv_sys_create(void)
}
/********************************************************//**
+Release recovery system mutexes. */
+UNIV_INTERN
+void
+recv_sys_close(void)
+/*================*/
+{
+ if (recv_sys != NULL) {
+ if (recv_sys->addr_hash != NULL) {
+ hash_table_free(recv_sys->addr_hash);
+ }
+
+ if (recv_sys->heap != NULL) {
+ mem_heap_free(recv_sys->heap);
+ }
+
+ if (recv_sys->buf != NULL) {
+ ut_free(recv_sys->buf);
+ }
+
+ if (recv_sys->last_block_buf_start != NULL) {
+ mem_free(recv_sys->last_block_buf_start);
+ }
+
+ mutex_free(&recv_sys->mutex);
+
+ mem_free(recv_sys);
+ recv_sys = NULL;
+ }
+}
+
+/********************************************************//**
+Frees the recovery system memory. */
+UNIV_INTERN
+void
+recv_sys_mem_free(void)
+/*===================*/
+{
+ if (recv_sys != NULL) {
+ if (recv_sys->addr_hash != NULL) {
+ hash_table_free(recv_sys->addr_hash);
+ }
+
+ if (recv_sys->heap != NULL) {
+ mem_heap_free(recv_sys->heap);
+ }
+
+ if (recv_sys->buf != NULL) {
+ ut_free(recv_sys->buf);
+ }
+
+ if (recv_sys->last_block_buf_start != NULL) {
+ mem_free(recv_sys->last_block_buf_start);
+ }
+
+ mem_free(recv_sys);
+ recv_sys = NULL;
+ }
+}
+
+/************************************************************
+Reset the state of the recovery system variables. */
+UNIV_INTERN
+void
+recv_sys_var_init(void)
+/*===================*/
+{
+ recv_lsn_checks_on = FALSE;
+
+ recv_n_pool_free_frames = 256;
+
+ recv_recovery_on = FALSE;
+
+#ifdef UNIV_LOG_ARCHIVE
+ recv_recovery_from_backup_on = FALSE;
+#endif /* UNIV_LOG_ARCHIVE */
+
+ recv_needed_recovery = FALSE;
+
+ recv_lsn_checks_on = FALSE;
+
+ recv_log_scan_is_startup_type = FALSE;
+
+ recv_no_ibuf_operations = FALSE;
+
+ recv_scan_print_counter = 0;
+
+ recv_previous_parsed_rec_type = 999999;
+
+ recv_previous_parsed_rec_offset = 0;
+
+ recv_previous_parsed_rec_is_multi = 0;
+
+ recv_max_parsed_page_no = 0;
+
+ recv_n_pool_free_frames = 256;
+
+ recv_max_page_lsn = 0;
+}
+
+/************************************************************
Inits the recovery system for a recovery operation. */
UNIV_INTERN
void
@@ -253,8 +354,8 @@ recv_sys_empty_hash(void)
Frees the recovery system. */
static
void
-recv_sys_free(void)
-/*===============*/
+recv_sys_debug_free(void)
+/*=====================*/
{
mutex_enter(&(recv_sys->mutex));
@@ -263,8 +364,10 @@ recv_sys_free(void)
ut_free(recv_sys->buf);
mem_free(recv_sys->last_block_buf_start);
- recv_sys->addr_hash = NULL;
+ recv_sys->buf = NULL;
recv_sys->heap = NULL;
+ recv_sys->addr_hash = NULL;
+ recv_sys->last_block_buf_start = NULL;
mutex_exit(&(recv_sys->mutex));
}
@@ -3149,7 +3252,7 @@ recv_recovery_from_checkpoint_finish(voi
recv_recovery_on = FALSE;
#ifndef UNIV_LOG_DEBUG
- recv_sys_free();
+ recv_sys_debug_free();
#endif
/* Roll back any recovered data dictionary transactions, so
that the data dictionary tables will be free of any locks.
=== modified file 'storage/innodb_plugin/mem/mem0dbg.c'
--- a/storage/innodb_plugin/mem/mem0dbg.c 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/mem/mem0dbg.c 2009-11-30 11:32:05 +0000
@@ -170,6 +170,17 @@ mem_init(
mem_comm_pool = mem_pool_create(size);
}
+
+/******************************************************************//**
+Closes the memory system. */
+UNIV_INTERN
+void
+mem_close(void)
+/*===========*/
+{
+ mem_pool_free(mem_comm_pool);
+ mem_comm_pool = NULL;
+}
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG
=== modified file 'storage/innodb_plugin/mem/mem0pool.c'
--- a/storage/innodb_plugin/mem/mem0pool.c 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/mem/mem0pool.c 2009-11-30 11:32:05 +0000
@@ -261,6 +261,18 @@ mem_pool_create(
}
/********************************************************************//**
+Frees a memory pool. */
+UNIV_INTERN
+void
+mem_pool_free(
+/*==========*/
+ mem_pool_t* pool) /*!< in, own: memory pool */
+{
+ ut_free(pool->buf);
+ ut_free(pool);
+}
+
+/********************************************************************//**
Fills the specified free list.
@return TRUE if we were able to insert a block to the free list */
static
=== modified file 'storage/innodb_plugin/os/os0file.c'
--- a/storage/innodb_plugin/os/os0file.c 2009-11-03 09:59:31 +0000
+++ b/storage/innodb_plugin/os/os0file.c 2009-11-30 12:04:09 +0000
@@ -323,6 +323,13 @@ os_file_get_last_error(
"InnoDB: The error means that there are no"
" sufficient system resources or quota to"
" complete the operation.\n");
+ } else if (err == ERROR_OPERATION_ABORTED) {
+ fprintf(stderr,
+ "InnoDB: The error means that the I/O"
+ " operation has been aborted\n"
+ "InnoDB: because of either a thread exit"
+ " or an application request.\n"
+ "InnoDB: Retry attempt is made.\n");
} else {
fprintf(stderr,
"InnoDB: Some operating system error numbers"
@@ -347,6 +354,8 @@ os_file_get_last_error(
} else if (err == ERROR_WORKING_SET_QUOTA
|| err == ERROR_NO_SYSTEM_RESOURCES) {
return(OS_FILE_INSUFFICIENT_RESOURCE);
+ } else if (err == ERROR_OPERATION_ABORTED) {
+ return(OS_FILE_OPERATION_ABORTED);
} else {
return(100 + err);
}
@@ -469,6 +478,10 @@ os_file_handle_error_cond_exit(
os_thread_sleep(100000); /* 100 ms */
return(TRUE);
+ } else if (err == OS_FILE_OPERATION_ABORTED) {
+
+ os_thread_sleep(100000); /* 100 ms */
+ return(TRUE);
} else {
if (name) {
fprintf(stderr, "InnoDB: File name %s\n", name);
@@ -3029,6 +3042,34 @@ os_aio_array_create(
return(array);
}
+/************************************************************************//**
+Frees an aio wait array. */
+static
+void
+os_aio_array_free(
+/*==============*/
+ os_aio_array_t* array) /*!< in, own: array to free */
+{
+#ifdef WIN_ASYNC_IO
+ ulint i;
+
+ for (i = 0; i < array->n_slots; i++) {
+ os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i);
+ os_event_free(slot->event);
+ }
+#endif /* WIN_ASYNC_IO */
+
+#ifdef __WIN__
+ ut_free(array->native_events);
+#endif /* __WIN__ */
+ os_mutex_free(array->mutex);
+ os_event_free(array->not_full);
+ os_event_free(array->is_empty);
+
+ ut_free(array->slots);
+ ut_free(array);
+}
+
/***********************************************************************
Initializes the asynchronous io system. Creates one array each for ibuf
and log i/o. Also creates one array each for read and write where each
@@ -3099,6 +3140,35 @@ os_aio_init(
}
+/***********************************************************************
+Frees the asynchronous io system. */
+UNIV_INTERN
+void
+os_aio_free(void)
+/*=============*/
+{
+ ulint i;
+
+ os_aio_array_free(os_aio_ibuf_array);
+ os_aio_ibuf_array = NULL;
+ os_aio_array_free(os_aio_log_array);
+ os_aio_log_array = NULL;
+ os_aio_array_free(os_aio_read_array);
+ os_aio_read_array = NULL;
+ os_aio_array_free(os_aio_write_array);
+ os_aio_write_array = NULL;
+ os_aio_array_free(os_aio_sync_array);
+ os_aio_sync_array = NULL;
+
+ for (i = 0; i < os_aio_n_segments; i++) {
+ os_event_free(os_aio_segment_wait_events[i]);
+ }
+
+ ut_free(os_aio_segment_wait_events);
+ os_aio_segment_wait_events = 0;
+ os_aio_n_segments = 0;
+}
+
#ifdef WIN_ASYNC_IO
/************************************************************************//**
Wakes up all async i/o threads in the array in Windows async i/o at
@@ -3709,6 +3779,7 @@ os_aio_windows_handle(
ibool ret_val;
BOOL ret;
DWORD len;
+ BOOL retry = FALSE;
if (segment == ULINT_UNDEFINED) {
array = os_aio_sync_array;
@@ -3762,14 +3833,52 @@ os_aio_windows_handle(
ut_a(TRUE == os_file_flush(slot->file));
}
#endif /* UNIV_DO_FLUSH */
+ } else if (os_file_handle_error(slot->name, "Windows aio")) {
+
+ retry = TRUE;
} else {
- os_file_handle_error(slot->name, "Windows aio");
ret_val = FALSE;
}
os_mutex_exit(array->mutex);
+ if (retry) {
+ /* retry failed read/write operation synchronously.
+ No need to hold array->mutex. */
+
+ switch (slot->type) {
+ case OS_FILE_WRITE:
+ ret = WriteFile(slot->file, slot->buf,
+ slot->len, &len,
+ &(slot->control));
+
+ break;
+ case OS_FILE_READ:
+ ret = ReadFile(slot->file, slot->buf,
+ slot->len, &len,
+ &(slot->control));
+
+ break;
+ default:
+ ut_error;
+ }
+
+ if (!ret && GetLastError() == ERROR_IO_PENDING) {
+ /* aio was queued successfully!
+ We want a synchronous i/o operation on a
+ file where we also use async i/o: in Windows
+ we must use the same wait mechanism as for
+ async i/o */
+
+ ret = GetOverlappedResult(slot->file,
+ &(slot->control),
+ &len, TRUE);
+ }
+
+ ret_val = ret && len == slot->len;
+ }
+
os_aio_array_free_slot(array, slot);
return(ret_val);
=== modified file 'storage/innodb_plugin/os/os0sync.c'
--- a/storage/innodb_plugin/os/os0sync.c 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/os/os0sync.c 2009-11-30 11:32:05 +0000
@@ -86,6 +86,9 @@ os_sync_init(void)
UT_LIST_INIT(os_event_list);
UT_LIST_INIT(os_mutex_list);
+ os_sync_mutex = NULL;
+ os_sync_mutex_inited = FALSE;
+
os_sync_mutex = os_mutex_create(NULL);
os_sync_mutex_inited = TRUE;
@@ -713,6 +716,7 @@ os_fast_mutex_free(
os_mutex_enter(os_sync_mutex);
}
+ ut_ad(os_fast_mutex_count > 0);
os_fast_mutex_count--;
if (UNIV_LIKELY(os_sync_mutex_inited)) {
=== modified file 'storage/innodb_plugin/os/os0thread.c'
--- a/storage/innodb_plugin/os/os0thread.c 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/os/os0thread.c 2009-11-30 11:32:05 +0000
@@ -233,6 +233,7 @@ os_thread_exit(
#ifdef __WIN__
ExitThread((DWORD)exit_value);
#else
+ pthread_detach(pthread_self());
pthread_exit(exit_value);
#endif
}
=== modified file 'storage/innodb_plugin/pars/lexyy.c'
--- a/storage/innodb_plugin/pars/lexyy.c 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/pars/lexyy.c 2009-11-30 11:32:05 +0000
@@ -2778,3 +2778,16 @@ static void yyfree (void * ptr )
+
+/**********************************************************************
+Release any resources used by the lexer. */
+UNIV_INTERN
+void
+pars_lexer_close(void)
+/*==================*/
+{
+ yylex_destroy();
+ free(stringbuf);
+ stringbuf = NULL;
+ stringbuf_len_alloc = stringbuf_len = 0;
+}
=== modified file 'storage/innodb_plugin/pars/pars0lex.l'
--- a/storage/innodb_plugin/pars/pars0lex.l 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/pars/pars0lex.l 2009-11-30 11:32:05 +0000
@@ -661,3 +661,16 @@ In the state 'id', only two actions are
}
%%
+
+/**********************************************************************
+Release any resources used by the lexer. */
+UNIV_INTERN
+void
+pars_lexer_close(void)
+/*==================*/
+{
+ yylex_destroy();
+ free(stringbuf);
+ stringbuf = NULL;
+ stringbuf_len_alloc = stringbuf_len = 0;
+}
=== modified file 'storage/innodb_plugin/que/que0que.c'
--- a/storage/innodb_plugin/que/que0que.c 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/que/que0que.c 2009-11-30 11:32:05 +0000
@@ -518,6 +518,7 @@ que_graph_free_recursive(
upd_node_t* upd;
tab_node_t* cre_tab;
ind_node_t* cre_ind;
+ purge_node_t* purge;
if (node == NULL) {
@@ -579,6 +580,13 @@ que_graph_free_recursive(
mem_heap_free(ins->entry_sys_heap);
break;
+ case QUE_NODE_PURGE:
+ purge = node;
+
+ mem_heap_free(purge->heap);
+
+ break;
+
case QUE_NODE_UPDATE:
upd = node;
=== modified file 'storage/innodb_plugin/row/row0merge.c'
--- a/storage/innodb_plugin/row/row0merge.c 2009-10-09 14:13:15 +0000
+++ b/storage/innodb_plugin/row/row0merge.c 2009-11-30 12:24:54 +0000
@@ -1200,6 +1200,12 @@ row_merge_read_clustered_index(
in order to release the latch on the old page. */
if (btr_pcur_is_after_last_on_page(&pcur)) {
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ i = 0;
+ err = DB_INTERRUPTED;
+ goto err_exit;
+ }
+
btr_pcur_store_position(&pcur, &mtr);
mtr_commit(&mtr);
mtr_start(&mtr);
@@ -1557,6 +1563,7 @@ static __attribute__((nonnull))
ulint
row_merge(
/*======*/
+ trx_t* trx, /*!< in: transaction */
const dict_index_t* index, /*!< in: index being created */
merge_file_t* file, /*!< in/out: file containing
index entries */
@@ -1590,6 +1597,10 @@ row_merge(
for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
ulint ahalf; /*!< arithmetic half the input file */
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ return(DB_INTERRUPTED);
+ }
+
error = row_merge_blocks(index, file, block,
&foffs0, &foffs1, &of, table);
@@ -1617,6 +1628,10 @@ row_merge(
/* Copy the last blocks, if there are any. */
while (foffs0 < ihalf) {
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ return(DB_INTERRUPTED);
+ }
+
if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
return(DB_CORRUPTION);
}
@@ -1625,6 +1640,10 @@ row_merge(
ut_ad(foffs0 == ihalf);
while (foffs1 < file->offset) {
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ return(DB_INTERRUPTED);
+ }
+
if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
return(DB_CORRUPTION);
}
@@ -1653,6 +1672,7 @@ static
ulint
row_merge_sort(
/*===========*/
+ trx_t* trx, /*!< in: transaction */
const dict_index_t* index, /*!< in: index being created */
merge_file_t* file, /*!< in/out: file containing
index entries */
@@ -1671,7 +1691,8 @@ row_merge_sort(
do {
ulint error;
- error = row_merge(index, file, &half, block, tmpfd, table);
+ error = row_merge(trx, index, file, &half,
+ block, tmpfd, table);
if (error != DB_SUCCESS) {
return(error);
@@ -2490,7 +2511,7 @@ row_merge_build_indexes(
sorting and inserting. */
for (i = 0; i < n_indexes; i++) {
- error = row_merge_sort(indexes[i], &merge_files[i],
+ error = row_merge_sort(trx, indexes[i], &merge_files[i],
block, &tmpfd, table);
if (error == DB_SUCCESS) {
=== modified file 'storage/innodb_plugin/row/row0mysql.c'
--- a/storage/innodb_plugin/row/row0mysql.c 2009-11-03 10:32:33 +0000
+++ b/storage/innodb_plugin/row/row0mysql.c 2009-11-30 13:13:34 +0000
@@ -1880,6 +1880,8 @@ err_exit:
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, NULL);
+ /* TO DO: free table? The code below will dereference
+ table->name, though. */
}
switch (err) {
@@ -1898,31 +1900,6 @@ err_exit:
break;
case DB_DUPLICATE_KEY:
- ut_print_timestamp(stderr);
- fputs(" InnoDB: Error: table ", stderr);
- ut_print_name(stderr, trx, TRUE, table->name);
- fputs(" already exists in InnoDB internal\n"
- "InnoDB: data dictionary. Have you deleted"
- " the .frm file\n"
- "InnoDB: and not used DROP TABLE?"
- " Have you used DROP DATABASE\n"
- "InnoDB: for InnoDB tables in"
- " MySQL version <= 3.23.43?\n"
- "InnoDB: See the Restrictions section"
- " of the InnoDB manual.\n"
- "InnoDB: You can drop the orphaned table"
- " inside InnoDB by\n"
- "InnoDB: creating an InnoDB table with"
- " the same name in another\n"
- "InnoDB: database and copying the .frm file"
- " to the current database.\n"
- "InnoDB: Then MySQL thinks the table exists,"
- " and DROP TABLE will\n"
- "InnoDB: succeed.\n"
- "InnoDB: You can look for further help from\n"
- "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
- stderr);
-
/* We may also get err == DB_ERROR if the .ibd file for the
table already exists */
@@ -4157,6 +4134,7 @@ row_check_table_for_mysql(
}
if (trx_is_interrupted(prebuilt->trx)) {
+ ret = DB_INTERRUPTED;
break;
}
=== modified file 'storage/innodb_plugin/srv/srv0srv.c'
--- a/storage/innodb_plugin/srv/srv0srv.c 2009-10-09 12:19:13 +0000
+++ b/storage/innodb_plugin/srv/srv0srv.c 2009-11-30 11:32:05 +0000
@@ -1006,13 +1006,26 @@ srv_init(void)
}
/*********************************************************************//**
-Frees the OS fast mutex created in srv_init(). */
+Frees the data structures created in srv_init(). */
UNIV_INTERN
void
srv_free(void)
/*==========*/
{
os_fast_mutex_free(&srv_conc_mutex);
+ mem_free(srv_conc_slots);
+ srv_conc_slots = NULL;
+
+ mem_free(srv_sys->threads);
+ mem_free(srv_sys);
+ srv_sys = NULL;
+
+ mem_free(kernel_mutex_temp);
+ kernel_mutex_temp = NULL;
+ mem_free(srv_mysql_table);
+ srv_mysql_table = NULL;
+
+ trx_i_s_cache_free(trx_i_s_cache);
}
/*********************************************************************//**
@@ -1024,6 +1037,8 @@ srv_general_init(void)
/*==================*/
{
ut_mem_init();
+ /* Reset the system variables in the recovery module. */
+ recv_sys_var_init();
os_sync_init();
sync_init();
mem_init(srv_mem_pool_size);
=== modified file 'storage/innodb_plugin/srv/srv0start.c'
--- a/storage/innodb_plugin/srv/srv0start.c 2009-11-03 10:23:22 +0000
+++ b/storage/innodb_plugin/srv/srv0start.c 2009-11-30 11:32:05 +0000
@@ -103,6 +103,7 @@ Created 2/16/1996 Heikki Tuuri
# include "row0row.h"
# include "row0mysql.h"
# include "btr0pcur.h"
+# include "thr0loc.h"
# include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
/** Log sequence number immediately after startup */
@@ -495,6 +496,8 @@ io_handler_thread(
mutex_exit(&ios_mutex);
}
+ thr_local_free(os_thread_get_curr_id());
+
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit.
The thread actually never comes here because it is exited in an
@@ -531,32 +534,6 @@ srv_normalize_path_for_win(
#endif
}
-/*********************************************************************//**
-Adds a slash or a backslash to the end of a string if it is missing
-and the string is not empty.
-@return string which has the separator if the string is not empty */
-UNIV_INTERN
-char*
-srv_add_path_separator_if_needed(
-/*=============================*/
- char* str) /*!< in: null-terminated character string */
-{
- char* out_str;
- ulint len = ut_strlen(str);
-
- if (len == 0 || str[len - 1] == SRV_PATH_SEPARATOR) {
-
- return(str);
- }
-
- out_str = ut_malloc(len + 2);
- memcpy(out_str, str, len);
- out_str[len] = SRV_PATH_SEPARATOR;
- out_str[len + 1] = 0;
-
- return(out_str);
-}
-
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Calculates the low 32 bits when a file size which is given as a number
@@ -605,19 +582,24 @@ open_or_create_log_file(
ulint size;
ulint size_high;
char name[10000];
+ ulint dirnamelen;
UT_NOT_USED(create_new_db);
*log_file_created = FALSE;
srv_normalize_path_for_win(srv_log_group_home_dirs[k]);
- srv_log_group_home_dirs[k] = srv_add_path_separator_if_needed(
- srv_log_group_home_dirs[k]);
- ut_a(strlen(srv_log_group_home_dirs[k])
- < (sizeof name) - 10 - sizeof "ib_logfile");
- sprintf(name, "%s%s%lu", srv_log_group_home_dirs[k],
- "ib_logfile", (ulong) i);
+ dirnamelen = strlen(srv_log_group_home_dirs[k]);
+ ut_a(dirnamelen < (sizeof name) - 10 - sizeof "ib_logfile");
+ memcpy(name, srv_log_group_home_dirs[k], dirnamelen);
+
+ /* Add a path separator if needed. */
+ if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
+ name[dirnamelen++] = SRV_PATH_SEPARATOR;
+ }
+
+ sprintf(name + dirnamelen, "%s%lu", "ib_logfile", (ulong) i);
files[i] = os_file_create(name, OS_FILE_CREATE, OS_FILE_NORMAL,
OS_LOG_FILE, &ret);
@@ -780,14 +762,22 @@ open_or_create_data_files(
*create_new_db = FALSE;
srv_normalize_path_for_win(srv_data_home);
- srv_data_home = srv_add_path_separator_if_needed(srv_data_home);
for (i = 0; i < srv_n_data_files; i++) {
+ ulint dirnamelen;
+
srv_normalize_path_for_win(srv_data_file_names[i]);
+ dirnamelen = strlen(srv_data_home);
- ut_a(strlen(srv_data_home) + strlen(srv_data_file_names[i])
+ ut_a(dirnamelen + strlen(srv_data_file_names[i])
< (sizeof name) - 1);
- sprintf(name, "%s%s", srv_data_home, srv_data_file_names[i]);
+ memcpy(name, srv_data_home, dirnamelen);
+ /* Add a path separator if needed. */
+ if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
+ name[dirnamelen++] = SRV_PATH_SEPARATOR;
+ }
+
+ strcpy(name + dirnamelen, srv_data_file_names[i]);
if (srv_data_file_is_raw_partition[i] == 0) {
@@ -1009,7 +999,7 @@ skip_size_check:
return(DB_SUCCESS);
}
-/****************************************************************//**
+/********************************************************************
Starts InnoDB and creates a new database if database files
are not found and the user wants.
@return DB_SUCCESS or error code */
@@ -1120,7 +1110,7 @@ innobase_start_or_create_for_mysql(void)
if (srv_start_has_been_called) {
fprintf(stderr,
- "InnoDB: Error:startup called second time"
+ "InnoDB: Error: startup called second time"
" during the process lifetime.\n"
"InnoDB: In the MySQL Embedded Server Library"
" you cannot call server_init()\n"
@@ -1959,8 +1949,10 @@ innobase_shutdown_for_mysql(void)
/* All the threads have exited or are just exiting;
NOTE that the threads may not have completed their
exit yet. Should we use pthread_join() to make sure
- they have exited? Now we just sleep 0.1 seconds and
- hope that is enough! */
+ they have exited? If we did, we would have to
+ remove the pthread_detach() from
+ os_thread_exit(). Now we just sleep 0.1
+ seconds and hope that is enough! */
os_mutex_exit(os_sync_mutex);
@@ -1999,37 +1991,41 @@ innobase_shutdown_for_mysql(void)
srv_misc_tmpfile = 0;
}
+ /* This must be disabled before closing the buffer pool
+ and closing the data dictionary. */
+ btr_search_disable();
+
+ ibuf_close();
+ log_shutdown();
+ lock_sys_close();
+ thr_local_close();
trx_sys_file_format_close();
+ trx_sys_close();
mutex_free(&srv_monitor_file_mutex);
mutex_free(&srv_dict_tmpfile_mutex);
mutex_free(&srv_misc_tmpfile_mutex);
+ dict_close();
+ btr_search_sys_free();
/* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
them */
+ os_aio_free();
sync_close();
+ srv_free();
+ fil_close();
/* 4. Free the os_conc_mutex and all os_events and os_mutexes */
- srv_free();
os_sync_free();
- /* Check that all read views are closed except read view owned
- by a purge. */
-
- if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
- fprintf(stderr,
- "InnoDB: Error: all read views were not closed"
- " before shutdown:\n"
- "InnoDB: %lu read views open \n",
- UT_LIST_GET_LEN(trx_sys->view_list) - 1);
- }
-
- /* 5. Free all allocated memory and the os_fast_mutex created in
- ut0mem.c */
+ /* 5. Free all allocated memory */
+ pars_lexer_close();
+ log_mem_free();
buf_pool_free();
ut_free_all_mem();
+ mem_close();
if (os_thread_count != 0
|| os_event_count != 0
@@ -2060,6 +2056,7 @@ innobase_shutdown_for_mysql(void)
}
srv_was_started = FALSE;
+ srv_start_has_been_called = FALSE;
return((int) DB_SUCCESS);
}
=== modified file 'storage/innodb_plugin/sync/sync0arr.c'
--- a/storage/innodb_plugin/sync/sync0arr.c 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/sync/sync0arr.c 2009-11-30 11:32:05 +0000
@@ -227,24 +227,21 @@ sync_array_create(
SYNC_ARRAY_MUTEX: determines the type
of mutex protecting the data structure */
{
+ ulint sz;
sync_array_t* arr;
- sync_cell_t* cell_array;
- sync_cell_t* cell;
- ulint i;
ut_a(n_cells > 0);
/* Allocate memory for the data structures */
arr = ut_malloc(sizeof(sync_array_t));
+ memset(arr, 0x0, sizeof(*arr));
- cell_array = ut_malloc(sizeof(sync_cell_t) * n_cells);
+ sz = sizeof(sync_cell_t) * n_cells;
+ arr->array = ut_malloc(sz);
+ memset(arr->array, 0x0, sz);
arr->n_cells = n_cells;
- arr->n_reserved = 0;
- arr->array = cell_array;
arr->protection = protection;
- arr->sg_count = 0;
- arr->res_count = 0;
/* Then create the mutex to protect the wait array complex */
if (protection == SYNC_ARRAY_OS_MUTEX) {
@@ -255,13 +252,6 @@ sync_array_create(
ut_error;
}
- for (i = 0; i < n_cells; i++) {
- cell = sync_array_get_nth_cell(arr, i);
- cell->wait_object = NULL;
- cell->waiting = FALSE;
- cell->signal_count = 0;
- }
-
return(arr);
}
=== modified file 'storage/innodb_plugin/sync/sync0sync.c'
--- a/storage/innodb_plugin/sync/sync0sync.c 2009-10-12 12:00:56 +0000
+++ b/storage/innodb_plugin/sync/sync0sync.c 2009-11-30 11:32:05 +0000
@@ -1377,7 +1377,12 @@ sync_close(void)
mutex_free(&mutex_list_mutex);
#ifdef UNIV_SYNC_DEBUG
mutex_free(&sync_thread_mutex);
+
+ /* Switch latching order checks on in sync0sync.c */
+ sync_order_checks_on = FALSE;
#endif /* UNIV_SYNC_DEBUG */
+
+ sync_initialized = FALSE;
}
/*******************************************************************//**
=== modified file 'storage/innodb_plugin/thr/thr0loc.c'
--- a/storage/innodb_plugin/thr/thr0loc.c 2009-10-08 10:00:49 +0000
+++ b/storage/innodb_plugin/thr/thr0loc.c 2009-11-30 11:32:05 +0000
@@ -246,3 +246,34 @@ thr_local_init(void)
mutex_create(&thr_local_mutex, SYNC_THR_LOCAL);
}
+
+/********************************************************************
+Close the thread local storage module. */
+UNIV_INTERN
+void
+thr_local_close(void)
+/*=================*/
+{
+ ulint i;
+
+ ut_a(thr_local_hash != NULL);
+
+ /* Free the hash elements. We don't remove them from the table
+ because we are going to destroy the table anyway. */
+ for (i = 0; i < hash_get_n_cells(thr_local_hash); i++) {
+ thr_local_t* local;
+
+ local = HASH_GET_FIRST(thr_local_hash, i);
+
+ while (local) {
+ thr_local_t* prev_local = local;
+
+ local = HASH_GET_NEXT(hash, prev_local);
+ ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N);
+ mem_free(prev_local);
+ }
+ }
+
+ hash_table_free(thr_local_hash);
+ thr_local_hash = NULL;
+}
=== modified file 'storage/innodb_plugin/trx/trx0i_s.c'
--- a/storage/innodb_plugin/trx/trx0i_s.c 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/trx/trx0i_s.c 2009-12-01 10:38:40 +0000
@@ -60,7 +60,7 @@ Created July 17, 2007 Vasil Dimov
/** @brief The maximum number of chunks to allocate for a table cache.
The rows of a table cache are stored in a set of chunks. When a new
-row is added a new chunk is allocated if necessary. Assuming that the
+row is added a new chunk is allocated if necessary. Assuming that the
first one is 1024 rows (TABLE_CACHE_INITIAL_ROWSNUM) and each
subsequent is N/2 where N is the number of rows we have allocated till
now, then 39th chunk would accommodate 1677416425 rows and all chunks
@@ -238,6 +238,27 @@ table_cache_init(
}
/*******************************************************************//**
+Frees a table cache. */
+static
+void
+table_cache_free(
+/*=============*/
+ i_s_table_cache_t* table_cache) /*!< in/out: table cache */
+{
+ ulint i;
+
+ for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) {
+
+ /* the memory is actually allocated in
+ table_cache_create_empty_row() */
+ if (table_cache->chunks[i].base) {
+ mem_free(table_cache->chunks[i].base);
+ table_cache->chunks[i].base = NULL;
+ }
+ }
+}
+
+/*******************************************************************//**
Returns an empty row from a table cache. The row is allocated if no more
empty rows are available. The number of used rows is incremented.
If the memory limit is hit then NULL is returned and nothing is
@@ -1184,9 +1205,6 @@ trx_i_s_possibly_fetch_data_into_cache(
return(1);
}
- /* We are going to access trx->query in all transactions */
- innobase_mysql_prepare_print_arbitrary_thd();
-
/* We need to read trx_sys and record/table lock queues */
mutex_enter(&kernel_mutex);
@@ -1194,8 +1212,6 @@ trx_i_s_possibly_fetch_data_into_cache(
mutex_exit(&kernel_mutex);
- innobase_mysql_end_print_arbitrary_thd();
-
return(0);
}
@@ -1252,6 +1268,22 @@ trx_i_s_cache_init(
}
/*******************************************************************//**
+Free the INFORMATION SCHEMA trx related cache. */
+UNIV_INTERN
+void
+trx_i_s_cache_free(
+/*===============*/
+ trx_i_s_cache_t* cache) /*!< in, own: cache to free */
+{
+ hash_table_free(cache->locks_hash);
+ ha_storage_free(cache->storage);
+ table_cache_free(&cache->innodb_trx);
+ table_cache_free(&cache->innodb_locks);
+ table_cache_free(&cache->innodb_lock_waits);
+ memset(cache, 0, sizeof *cache);
+}
+
+/*******************************************************************//**
Issue a shared/read lock on the tables cache. */
UNIV_INTERN
void
=== modified file 'storage/innodb_plugin/trx/trx0purge.c'
--- a/storage/innodb_plugin/trx/trx0purge.c 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/trx/trx0purge.c 2009-11-30 11:32:05 +0000
@@ -249,6 +249,44 @@ trx_purge_sys_create(void)
purge_sys->heap);
}
+/************************************************************************
+Frees the global purge system control structure. */
+UNIV_INTERN
+void
+trx_purge_sys_close(void)
+/*======================*/
+{
+ ut_ad(!mutex_own(&kernel_mutex));
+
+ que_graph_free(purge_sys->query);
+
+ ut_a(purge_sys->sess->trx->is_purge);
+ purge_sys->sess->trx->conc_state = TRX_NOT_STARTED;
+ sess_close(purge_sys->sess);
+ purge_sys->sess = NULL;
+
+ if (purge_sys->view != NULL) {
+ /* Because acquiring the kernel mutex is a pre-condition
+ of read_view_close(). We don't really need it here. */
+ mutex_enter(&kernel_mutex);
+
+ read_view_close(purge_sys->view);
+ purge_sys->view = NULL;
+
+ mutex_exit(&kernel_mutex);
+ }
+
+ trx_undo_arr_free(purge_sys->arr);
+
+ rw_lock_free(&purge_sys->latch);
+ mutex_free(&purge_sys->mutex);
+
+ mem_heap_free(purge_sys->heap);
+ mem_free(purge_sys);
+
+ purge_sys = NULL;
+}
+
/*================ UNDO LOG HISTORY LIST =============================*/
/********************************************************************//**
=== modified file 'storage/innodb_plugin/trx/trx0rseg.c'
--- a/storage/innodb_plugin/trx/trx0rseg.c 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/trx/trx0rseg.c 2009-11-30 11:32:05 +0000
@@ -132,6 +132,49 @@ trx_rseg_header_create(
}
/***********************************************************************//**
+Free's an instance of the rollback segment in memory. */
+UNIV_INTERN
+void
+trx_rseg_mem_free(
+/*==============*/
+ trx_rseg_t* rseg) /* in, own: instance to free */
+{
+ trx_undo_t* undo;
+
+ mutex_free(&rseg->mutex);
+
+ /* There can't be any active transactions. */
+ ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0);
+ ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0);
+
+ undo = UT_LIST_GET_FIRST(rseg->update_undo_cached);
+
+ while (undo != NULL) {
+ trx_undo_t* prev_undo = undo;
+
+ undo = UT_LIST_GET_NEXT(undo_list, undo);
+ UT_LIST_REMOVE(undo_list, rseg->update_undo_cached, prev_undo);
+
+ trx_undo_mem_free(prev_undo);
+ }
+
+ undo = UT_LIST_GET_FIRST(rseg->insert_undo_cached);
+
+ while (undo != NULL) {
+ trx_undo_t* prev_undo = undo;
+
+ undo = UT_LIST_GET_NEXT(undo_list, undo);
+ UT_LIST_REMOVE(undo_list, rseg->insert_undo_cached, prev_undo);
+
+ trx_undo_mem_free(prev_undo);
+ }
+
+ trx_sys_set_nth_rseg(trx_sys, rseg->id, NULL);
+
+ mem_free(rseg);
+}
+
+/***************************************************************************
Creates and initializes a rollback segment object. The values for the
fields are read from the header. The object is inserted to the rseg
list of the trx system object and a pointer is inserted in the rseg
=== modified file 'storage/innodb_plugin/trx/trx0sys.c'
--- a/storage/innodb_plugin/trx/trx0sys.c 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/trx/trx0sys.c 2009-11-30 11:32:05 +0000
@@ -40,6 +40,7 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0purge.h"
#include "log0log.h"
#include "os0file.h"
+#include "read0read.h"
/** The file format tag structure with id and name. */
struct file_format_struct {
@@ -1533,3 +1534,80 @@ trx_sys_file_format_id_to_name(
}
#endif /* !UNIV_HOTBACKUP */
+
+/*********************************************************************
+Shutdown/Close the transaction system. */
+UNIV_INTERN
+void
+trx_sys_close(void)
+/*===============*/
+{
+ trx_rseg_t* rseg;
+ read_view_t* view;
+
+ ut_ad(trx_sys != NULL);
+
+ /* Check that all read views are closed except read view owned
+ by a purge. */
+
+ if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
+ fprintf(stderr,
+ "InnoDB: Error: all read views were not closed"
+ " before shutdown:\n"
+ "InnoDB: %lu read views open \n",
+ UT_LIST_GET_LEN(trx_sys->view_list) - 1);
+ }
+
+ sess_close(trx_dummy_sess);
+ trx_dummy_sess = NULL;
+
+ trx_purge_sys_close();
+
+ mutex_enter(&kernel_mutex);
+
+ /* Free the double write data structures. */
+ ut_a(trx_doublewrite != NULL);
+ ut_free(trx_doublewrite->write_buf_unaligned);
+ trx_doublewrite->write_buf_unaligned = NULL;
+
+ mem_free(trx_doublewrite->buf_block_arr);
+ trx_doublewrite->buf_block_arr = NULL;
+
+ mutex_free(&trx_doublewrite->mutex);
+ mem_free(trx_doublewrite);
+ trx_doublewrite = NULL;
+
+ /* There can't be any active transactions. */
+ rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
+
+ while (rseg != NULL) {
+ trx_rseg_t* prev_rseg = rseg;
+
+ rseg = UT_LIST_GET_NEXT(rseg_list, prev_rseg);
+ UT_LIST_REMOVE(rseg_list, trx_sys->rseg_list, prev_rseg);
+
+ trx_rseg_mem_free(prev_rseg);
+ }
+
+ view = UT_LIST_GET_FIRST(trx_sys->view_list);
+
+ while (view != NULL) {
+ read_view_t* prev_view = view;
+
+ view = UT_LIST_GET_NEXT(view_list, prev_view);
+
+ /* Views are allocated from the trx_sys->global_read_view_heap.
+ So, we simply remove the element here. */
+ UT_LIST_REMOVE(view_list, trx_sys->view_list, prev_view);
+ }
+
+ ut_a(UT_LIST_GET_LEN(trx_sys->trx_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->rseg_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
+
+ mem_free(trx_sys);
+
+ trx_sys = NULL;
+ mutex_exit(&kernel_mutex);
+}
=== modified file 'storage/innodb_plugin/trx/trx0trx.c'
--- a/storage/innodb_plugin/trx/trx0trx.c 2009-10-09 14:13:15 +0000
+++ b/storage/innodb_plugin/trx/trx0trx.c 2009-12-01 10:38:40 +0000
@@ -1636,9 +1636,7 @@ trx_mark_sql_stat_end(
/**********************************************************************//**
Prints info about a transaction to the given file. The caller must own the
-kernel mutex and must have called
-innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
-or InnoDB cannot meanwhile change the info printed here. */
+kernel mutex. */
UNIV_INTERN
void
trx_print(
=== modified file 'storage/innodb_plugin/trx/trx0undo.c'
--- a/storage/innodb_plugin/trx/trx0undo.c 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/trx/trx0undo.c 2009-11-30 11:32:05 +0000
@@ -1522,7 +1522,7 @@ trx_undo_mem_init_for_reuse(
/********************************************************************//**
Frees an undo log memory copy. */
-static
+UNIV_INTERN
void
trx_undo_mem_free(
/*==============*/
=== modified file 'storage/innodb_plugin/usr/usr0sess.c'
--- a/storage/innodb_plugin/usr/usr0sess.c 2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/usr/usr0sess.c 2009-11-30 11:32:05 +0000
@@ -32,14 +32,6 @@ Created 6/25/1996 Heikki Tuuri
#include "trx0trx.h"
/*********************************************************************//**
-Closes a session, freeing the memory occupied by it. */
-static
-void
-sess_close(
-/*=======*/
- sess_t* sess); /*!< in, own: session object */
-
-/*********************************************************************//**
Opens a session.
@return own: session object */
UNIV_INTERN
@@ -64,35 +56,16 @@ sess_open(void)
/*********************************************************************//**
Closes a session, freeing the memory occupied by it. */
-static
+UNIV_INTERN
void
sess_close(
/*=======*/
sess_t* sess) /*!< in, own: session object */
{
- ut_ad(mutex_own(&kernel_mutex));
- ut_ad(sess->trx == NULL);
-
- mem_free(sess);
-}
-
-/*********************************************************************//**
-Closes a session, freeing the memory occupied by it, if it is in a state
-where it should be closed.
-@return TRUE if closed */
-UNIV_INTERN
-ibool
-sess_try_close(
-/*===========*/
- sess_t* sess) /*!< in, own: session object */
-{
- ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(!mutex_own(&kernel_mutex));
- if (UT_LIST_GET_LEN(sess->graphs) == 0) {
- sess_close(sess);
+ ut_a(UT_LIST_GET_LEN(sess->graphs) == 0);
- return(TRUE);
- }
-
- return(FALSE);
+ trx_free_for_background(sess->trx);
+ mem_free(sess);
}
=== modified file 'storage/innodb_plugin/ut/ut0mem.c'
--- a/storage/innodb_plugin/ut/ut0mem.c 2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/ut/ut0mem.c 2009-11-30 11:32:05 +0000
@@ -433,6 +433,8 @@ ut_free_all_mem(void)
" total allocated memory is %lu\n",
(ulong) ut_total_allocated_memory);
}
+
+ ut_mem_block_list_inited = FALSE;
}
#endif /* !UNIV_HOTBACKUP */
=== modified file 'storage/maria/ft_maria.c'
--- a/storage/maria/ft_maria.c 2007-07-02 17:45:15 +0000
+++ b/storage/maria/ft_maria.c 2010-01-27 21:53:08 +0000
@@ -22,8 +22,8 @@
#include "ma_ftdefs.h"
FT_INFO *maria_ft_init_search(uint flags, void *info, uint keynr,
- uchar *query, uint query_len, CHARSET_INFO *cs,
- uchar *record)
+ uchar *query, size_t query_len,
+ CHARSET_INFO *cs, uchar *record)
{
FT_INFO *res;
if (flags & FT_BOOL)
=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc 2009-12-03 11:34:11 +0000
+++ b/storage/maria/ha_maria.cc 2010-02-12 14:21:13 +0000
@@ -2255,9 +2255,12 @@ int ha_maria::extra(enum ha_extra_functi
extern_lock(F_UNLOCK) (which resets file->trn) followed by maria_close()
without calling commit/rollback in between. If file->trn is not set
we can't remove file->share from the transaction list in the extra() call.
+
+ table->in_use is not set in the case this is a done as part of closefrm()
+ as part of drop table.
*/
- if (!file->trn &&
+ if (file->s->now_transactional && !file->trn && table->in_use &&
(operation == HA_EXTRA_PREPARE_FOR_DROP ||
operation == HA_EXTRA_PREPARE_FOR_RENAME))
{
@@ -3275,11 +3278,11 @@ static struct st_mysql_sys_var* system_v
MYSQL_SYSVAR(block_size),
MYSQL_SYSVAR(checkpoint_interval),
MYSQL_SYSVAR(force_start_after_recovery_failures),
- MYSQL_SYSVAR(page_checksum),
MYSQL_SYSVAR(log_dir_path),
MYSQL_SYSVAR(log_file_size),
MYSQL_SYSVAR(log_purge_type),
MYSQL_SYSVAR(max_sort_file_size),
+ MYSQL_SYSVAR(page_checksum),
MYSQL_SYSVAR(pagecache_age_threshold),
MYSQL_SYSVAR(pagecache_buffer_size),
MYSQL_SYSVAR(pagecache_division_limit),
=== modified file 'storage/maria/ma_blockrec.c'
--- a/storage/maria/ma_blockrec.c 2009-10-03 20:13:58 +0000
+++ b/storage/maria/ma_blockrec.c 2010-02-10 19:06:24 +0000
@@ -430,8 +430,9 @@ my_bool _ma_once_end_block_record(MARIA_
if (share->bitmap.file.file >= 0)
{
if (flush_pagecache_blocks(share->pagecache, &share->bitmap.file,
- share->temporary ? FLUSH_IGNORE_CHANGED :
- FLUSH_RELEASE))
+ ((share->temporary || share->deleting) ?
+ FLUSH_IGNORE_CHANGED :
+ FLUSH_RELEASE)))
res= 1;
/*
File must be synced as it is going out of the maria_open_list and so
@@ -1688,7 +1689,8 @@ static my_bool get_head_or_tail_page(MAR
if (!page_link.changed)
goto crashed;
- DBUG_ASSERT((res->buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == page_type);
+ DBUG_ASSERT((uint) (res->buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) ==
+ page_type);
if (!(dir= find_free_position(page_type == HEAD_PAGE ? info : 0,
res->buff, block_size, &res->rownr,
&res->length, &res->empty_space)))
@@ -6094,7 +6096,7 @@ uint _ma_apply_redo_insert_row_head_or_t
DBUG_RETURN(0);
}
- if (((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != page_type))
+ if (((uint) (buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != page_type))
{
/*
This is a page that has been freed before and now should be
@@ -6241,7 +6243,7 @@ uint _ma_apply_redo_purge_row_head_or_ta
Note that in case the page is not anymore a head or tail page
a future redo will fix the bitmap.
*/
- if ((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == page_type)
+ if ((uint) (buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == page_type)
{
empty_space= uint2korr(buff+EMPTY_SPACE_OFFSET);
if (_ma_bitmap_set(info, page, page_type == HEAD_PAGE,
=== modified file 'storage/maria/ma_check.c'
--- a/storage/maria/ma_check.c 2009-11-29 23:08:56 +0000
+++ b/storage/maria/ma_check.c 2010-01-14 16:51:00 +0000
@@ -6018,7 +6018,7 @@ int maria_update_state_info(HA_CHECK *pa
{
if (update & UPDATE_TIME)
{
- share->state.check_time= (long) time((time_t*) 0);
+ share->state.check_time= time((time_t*) 0);
if (!share->state.create_time)
share->state.create_time= share->state.check_time;
}
=== modified file 'storage/maria/ma_close.c'
--- a/storage/maria/ma_close.c 2009-02-05 22:38:30 +0000
+++ b/storage/maria/ma_close.c 2010-02-10 19:06:24 +0000
@@ -79,7 +79,7 @@ int maria_close(register MARIA_HA *info)
if ((*share->once_end)(share))
error= my_errno;
if (flush_pagecache_blocks(share->pagecache, &share->kfile,
- (share->temporary ?
+ ((share->temporary || share->deleting) ?
FLUSH_IGNORE_CHANGED :
FLUSH_RELEASE)))
error= my_errno;
@@ -177,6 +177,7 @@ int maria_close(register MARIA_HA *info)
{
(void) pthread_mutex_destroy(&share->intern_lock);
(void) pthread_mutex_destroy(&share->close_lock);
+ (void) pthread_cond_destroy(&share->key_del_cond);
my_free((uchar *)share, MYF(0));
/*
If share cannot be freed, it's because checkpoint has previously
=== modified file 'storage/maria/ma_create.c'
--- a/storage/maria/ma_create.c 2009-02-19 09:01:25 +0000
+++ b/storage/maria/ma_create.c 2010-01-14 16:51:00 +0000
@@ -772,7 +772,7 @@ int maria_create(const char *name, enum
share.base.min_block_length= share.base.pack_reclength;
if (! (flags & HA_DONT_TOUCH_DATA))
- share.state.create_time= (long) time((time_t*) 0);
+ share.state.create_time= time((time_t*) 0);
pthread_mutex_lock(&THR_LOCK_maria);
=== modified file 'storage/maria/ma_delete.c'
--- a/storage/maria/ma_delete.c 2009-01-12 11:12:00 +0000
+++ b/storage/maria/ma_delete.c 2010-03-10 10:32:14 +0000
@@ -169,6 +169,8 @@ my_bool _ma_ck_delete(MARIA_HA *info, MA
MARIA_KEY org_key;
DBUG_ENTER("_ma_ck_delete");
+ LINT_INIT_STRUCT(org_key);
+
save_key_data= key->data;
if (share->now_transactional)
{
=== modified file 'storage/maria/ma_extra.c'
--- a/storage/maria/ma_extra.c 2009-10-06 06:13:56 +0000
+++ b/storage/maria/ma_extra.c 2010-02-10 19:06:24 +0000
@@ -305,6 +305,12 @@ int maria_extra(MARIA_HA *info, enum ha_
pthread_mutex_unlock(&THR_LOCK_maria);
break;
case HA_EXTRA_PREPARE_FOR_DROP:
+ /* Signals about intent to delete this table */
+ share->deleting= TRUE;
+ share->global_changed= FALSE; /* force writing changed flag */
+ /* To force repair if reopened */
+ _ma_mark_file_changed(info);
+ /* Fall trough */
case HA_EXTRA_PREPARE_FOR_RENAME:
{
my_bool do_flush= test(function != HA_EXTRA_PREPARE_FOR_DROP);
=== modified file 'storage/maria/ma_key_recover.h'
--- a/storage/maria/ma_key_recover.h 2008-09-01 17:31:40 +0000
+++ b/storage/maria/ma_key_recover.h 2010-03-09 19:22:24 +0000
@@ -63,7 +63,6 @@ extern my_bool write_hook_for_undo_key_i
extern my_bool write_hook_for_undo_key_delete(enum translog_record_type type,
TRN *trn, MARIA_HA *tbl_info,
LSN *lsn, void *hook_arg);
-void _ma_unpin_all_pages(MARIA_HA *info, LSN undo_lsn);
my_bool _ma_log_prefix(MARIA_PAGE *page, uint changed_length, int move_length);
my_bool _ma_log_suffix(MARIA_PAGE *page, uint org_length,
=== modified file 'storage/maria/ma_locking.c'
--- a/storage/maria/ma_locking.c 2009-10-06 06:13:56 +0000
+++ b/storage/maria/ma_locking.c 2010-02-10 19:06:24 +0000
@@ -387,6 +387,9 @@ int _ma_test_if_changed(register MARIA_H
open_count is not maintained on disk for temporary tables.
*/
+#define _MA_ALREADY_MARKED_FILE_CHANGED \
+ ((share->state.changed & STATE_CHANGED) && share->global_changed)
+
int _ma_mark_file_changed(MARIA_HA *info)
{
uchar buff[3];
@@ -394,8 +397,6 @@ int _ma_mark_file_changed(MARIA_HA *info
int error= 1;
DBUG_ENTER("_ma_mark_file_changed");
-#define _MA_ALREADY_MARKED_FILE_CHANGED \
- ((share->state.changed & STATE_CHANGED) && share->global_changed)
if (_MA_ALREADY_MARKED_FILE_CHANGED)
DBUG_RETURN(0);
pthread_mutex_lock(&share->intern_lock); /* recheck under mutex */
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2009-05-19 09:28:05 +0000
+++ b/storage/maria/ma_loghandler.c 2010-03-30 12:36:49 +0000
@@ -1211,6 +1211,8 @@ static my_bool translog_set_lsn_for_file
for (file= from_file; file <= to_file; file++)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT(info.max_lsn);
+
File fd= open_logfile_by_number_no_cache(file);
if ((fd < 0) ||
((translog_read_file_header(&info, fd) ||
@@ -1394,6 +1396,7 @@ LSN translog_get_file_max_lsn_stored(uin
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT_STRUCT(info);
File fd= open_logfile_by_number_no_cache(file);
if ((fd < 0) ||
(translog_read_file_header(&info, fd) | my_close(fd, MYF(MY_WME))))
@@ -2823,8 +2826,8 @@ static my_bool translog_page_validator(u
data->was_recovered= 0;
- if (uint3korr(page) != page_no ||
- uint3korr(page + 3) != data->number)
+ if ((pgcache_page_no_t) uint3korr(page) != page_no ||
+ (uint32) uint3korr(page + 3) != data->number)
{
DBUG_PRINT("error", ("Page (%lu,0x%lx): "
"page address written in the page is incorrect: "
@@ -3844,6 +3847,8 @@ my_bool translog_init_with_table(const c
if (!old_log_was_recovered && old_flags == flags)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT(info.maria_version);
+
/*
Accessing &log_descriptor.open_files without mutex is safe
because it is initialization
=== modified file 'storage/maria/ma_page.c'
--- a/storage/maria/ma_page.c 2009-05-06 12:03:24 +0000
+++ b/storage/maria/ma_page.c 2010-03-09 19:22:24 +0000
@@ -64,6 +64,15 @@ void _ma_page_setup(MARIA_PAGE *page, MA
share->base.key_reflength : 0);
}
+#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
+void page_cleanup(MARIA_SHARE *share, MARIA_PAGE *page)
+{
+ uint length= page->size;
+ DBUG_ASSERT(length <= block_size - KEYPAGE_CHECKSUM_SIZE);
+ bzero(page->buff + length, share->block_size - length);
+}
+#endif
+
/**
Fetch a key-page in memory
@@ -102,8 +111,10 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *pa
if (lock != PAGECACHE_LOCK_LEFT_UNLOCKED)
{
- DBUG_ASSERT(lock == PAGECACHE_LOCK_WRITE);
- page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
+ DBUG_ASSERT(lock == PAGECACHE_LOCK_WRITE || PAGECACHE_LOCK_READ);
+ page_link.unlock= (lock == PAGECACHE_LOCK_WRITE ?
+ PAGECACHE_LOCK_WRITE_UNLOCK :
+ PAGECACHE_LOCK_READ_UNLOCK);
page_link.changed= 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
page->link_offset= info->pinned_pages.elements-1;
@@ -209,14 +220,7 @@ my_bool _ma_write_keypage(MARIA_PAGE *pa
}
#endif
-#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
- {
- uint length= page->size;
- DBUG_ASSERT(length <= block_size - KEYPAGE_CHECKSUM_SIZE);
- bzero(buff + length, block_size - length);
- }
-#endif
-
+ page_cleanup(share, page);
res= pagecache_write(share->pagecache,
&share->kfile,
(pgcache_page_no_t) (page->pos / block_size),
=== modified file 'storage/maria/ma_recovery.c'
--- a/storage/maria/ma_recovery.c 2009-10-26 11:35:42 +0000
+++ b/storage/maria/ma_recovery.c 2010-02-10 19:06:24 +0000
@@ -312,11 +312,14 @@ int maria_apply_log(LSN from_lsn, enum m
now= my_getsystime();
in_redo_phase= TRUE;
+ trnman_init(max_trid_in_control_file);
if (run_redo_phase(from_lsn, apply))
{
ma_message_no_user(0, "Redo phase failed");
+ trnman_destroy();
goto err;
}
+ trnman_destroy();
if ((uncommitted_trans=
end_of_redo_phase(should_run_undo_phase)) == (uint)-1)
=== modified file 'storage/maria/ma_rkey.c'
--- a/storage/maria/ma_rkey.c 2008-06-26 05:18:28 +0000
+++ b/storage/maria/ma_rkey.c 2010-03-09 19:22:24 +0000
@@ -82,6 +82,9 @@ int maria_rkey(MARIA_HA *info, uchar *bu
rw_rdlock(&keyinfo->root_lock);
nextflag= maria_read_vec[search_flag] | key.flag;
+ if (search_flag != HA_READ_KEY_EXACT ||
+ ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME))
+ nextflag|= SEARCH_SAVE_BUFF;
switch (keyinfo->key_alg) {
#ifdef HAVE_RTREE_KEYS
=== modified file 'storage/maria/ma_search.c'
--- a/storage/maria/ma_search.c 2009-05-06 12:03:24 +0000
+++ b/storage/maria/ma_search.c 2010-03-28 18:10:00 +0000
@@ -18,6 +18,10 @@
#include "ma_fulltext.h"
#include "m_ctype.h"
+static int _ma_search_no_save(register MARIA_HA *info, MARIA_KEY *key,
+ uint32 nextflag, register my_off_t pos,
+ MARIA_PINNED_PAGE **res_page_link,
+ uchar **res_page_buff);
static my_bool _ma_get_prev_key(MARIA_KEY *key, MARIA_PAGE *ma_page,
uchar *keypos);
@@ -57,7 +61,51 @@ int _ma_check_index(MARIA_HA *info, int
*/
int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
- register my_off_t pos)
+ my_off_t pos)
+{
+ int error;
+ MARIA_PINNED_PAGE *page_link;
+ uchar *page_buff;
+
+ info->page_changed= 1; /* If page not saved */
+ if (!(error= _ma_search_no_save(info, key, nextflag, pos, &page_link,
+ &page_buff)))
+ {
+ if (nextflag & SEARCH_SAVE_BUFF)
+ {
+ bmove512(info->keyread_buff, page_buff, info->s->block_size);
+
+ /* Save position for a possible read next / previous */
+ info->int_keypos= info->keyread_buff + info->keypos_offset;
+ info->int_maxpos= info->keyread_buff + info->maxpos_offset;
+ info->int_keytree_version= key->keyinfo->version;
+ info->last_search_keypage= info->last_keypage;
+ info->page_changed= 0;
+ info->keyread_buff_used= 0;
+ }
+ }
+ _ma_unpin_all_pages(info, LSN_IMPOSSIBLE);
+ return (error);
+}
+
+/**
+ @breif Search after row by a key
+
+ ret_page_link Will contain pointer to page where we found key
+
+ @note
+ Position to row is stored in info->lastpos
+
+ @return
+ @retval 0 ok (key found)
+ @retval -1 Not found
+ @retval 1 If one should continue search on higher level
+*/
+
+static int _ma_search_no_save(register MARIA_HA *info, MARIA_KEY *key,
+ uint32 nextflag, register my_off_t pos,
+ MARIA_PINNED_PAGE **res_page_link,
+ uchar **res_page_buff)
{
my_bool last_key_not_used;
int error,flag;
@@ -66,6 +114,7 @@ int _ma_search(register MARIA_HA *info,
uchar lastkey[MARIA_MAX_KEY_BUFF];
MARIA_KEYDEF *keyinfo= key->keyinfo;
MARIA_PAGE page;
+ MARIA_PINNED_PAGE *page_link;
DBUG_ENTER("_ma_search");
DBUG_PRINT("enter",("pos: %lu nextflag: %u lastpos: %lu",
(ulong) pos, nextflag, (ulong) info->cur_row.lastpos));
@@ -81,10 +130,11 @@ int _ma_search(register MARIA_HA *info,
}
if (_ma_fetch_keypage(&page, info, keyinfo, pos,
- PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, info->keyread_buff,
- test(!(nextflag & SEARCH_SAVE_BUFF))))
+ PAGECACHE_LOCK_READ, DFLT_INIT_HITS, 0, 0))
goto err;
+ page_link= dynamic_element(&info->pinned_pages,
+ info->pinned_pages.elements-1,
+ MARIA_PINNED_PAGE*);
DBUG_DUMP("page", page.buff, page.size);
flag= (*keyinfo->bin_search)(key, &page, nextflag, &keypos, lastkey,
@@ -98,8 +148,9 @@ int _ma_search(register MARIA_HA *info,
if (flag)
{
- if ((error= _ma_search(info, key, nextflag,
- _ma_kpos(nod_flag,keypos))) <= 0)
+ if ((error= _ma_search_no_save(info, key, nextflag,
+ _ma_kpos(nod_flag,keypos),
+ res_page_link, res_page_buff)) <= 0)
DBUG_RETURN(error);
if (flag >0)
@@ -118,26 +169,15 @@ int _ma_search(register MARIA_HA *info,
((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
(key->flag & SEARCH_PART_KEY) || info->s->base.born_transactional))
{
- if ((error= _ma_search(info, key, (nextflag | SEARCH_FIND) &
- ~(SEARCH_BIGGER | SEARCH_SMALLER | SEARCH_LAST),
- _ma_kpos(nod_flag,keypos))) >= 0 ||
+ if ((error= _ma_search_no_save(info, key, (nextflag | SEARCH_FIND) &
+ ~(SEARCH_BIGGER | SEARCH_SMALLER |
+ SEARCH_LAST),
+ _ma_kpos(nod_flag,keypos),
+ res_page_link, res_page_buff)) >= 0 ||
my_errno != HA_ERR_KEY_NOT_FOUND)
DBUG_RETURN(error);
- info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */
}
}
- if (pos != info->last_keypage)
- {
- uchar *old_buff= page.buff;
- if (_ma_fetch_keypage(&page, info, keyinfo, pos,
- PAGECACHE_LOCK_LEFT_UNLOCKED,DFLT_INIT_HITS,
- info->keyread_buff,
- test(!(nextflag & SEARCH_SAVE_BUFF))))
- goto err;
- /* Restore position if page buffer moved */
- keypos= page.buff + (keypos - old_buff);
- maxpos= page.buff + (maxpos - old_buff);
- }
info->last_key.keyinfo= keyinfo;
if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0)
@@ -172,16 +212,15 @@ int _ma_search(register MARIA_HA *info,
}
info->cur_row.lastpos= _ma_row_pos_from_key(&info->last_key);
info->cur_row.trid= _ma_trid_from_key(&info->last_key);
- /* Save position for a possible read next / previous */
- info->int_keypos= info->keyread_buff + (keypos - page.buff);
- info->int_maxpos= info->keyread_buff + (maxpos - page.buff);
- info->int_nod_flag=nod_flag;
- info->int_keytree_version=keyinfo->version;
- info->last_search_keypage=info->last_keypage;
- info->page_changed=0;
- /* Set marker that buffer was used (Marker for mi_search_next()) */
- info->keyread_buff_used= (info->keyread_buff != page.buff);
+ /* Store offset to key */
+ info->keypos_offset= (uint) (keypos - page.buff);
+ info->maxpos_offset= (uint) (maxpos - page.buff);
+ info->int_nod_flag= nod_flag;
+ info->last_keypage= pos;
+ *res_page_link= page_link;
+ *res_page_buff= page.buff;
+
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
DBUG_RETURN(0);
@@ -190,7 +229,7 @@ err:
info->cur_row.lastpos= HA_OFFSET_ERROR;
info->page_changed=1;
DBUG_RETURN (-1);
-} /* _ma_search */
+}
/*
=== modified file 'storage/maria/ma_test3.c'
--- a/storage/maria/ma_test3.c 2008-01-10 12:21:53 +0000
+++ b/storage/maria/ma_test3.c 2010-01-06 21:27:53 +0000
@@ -180,7 +180,7 @@ void start_test(int id)
if (pagecacheing && rnd(2) == 0)
init_pagecache(maria_pagecache, 65536L, 0, 0, MARIA_KEY_BLOCK_LENGTH,
MY_WME);
- printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
+ printf("Process %d, pid: %ld\n",id,(long) getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
{
@@ -362,7 +362,7 @@ int test_write(MARIA_HA *file,int id,int
maria_extra(file,HA_EXTRA_WRITE_CACHE,0);
}
- sprintf((char*) record.id,"%7d",getpid());
+ sprintf((char*) record.id,"%7ld", (long) getpid());
strnmov((char*) record.text,"Testing...", sizeof(record.text));
tries=(uint) rnd(100)+10;
=== modified file 'storage/maria/ma_write.c'
--- a/storage/maria/ma_write.c 2009-02-19 09:01:25 +0000
+++ b/storage/maria/ma_write.c 2010-03-09 19:22:24 +0000
@@ -587,6 +587,12 @@ my_bool _ma_enlarge_root(MARIA_HA *info,
/*
Search after a position for a key and store it there
+ TODO:
+ Change this to use pagecache directly instead of creating a copy
+ of the page. To do this, we must however change write-key-on-page
+ algorithm to not overwrite the buffer but instead store any overflow
+ key in a separate buffer.
+
@return
@retval -1 error
@retval 0 ok
=== modified file 'storage/maria/maria_def.h'
--- a/storage/maria/maria_def.h 2009-11-29 23:08:56 +0000
+++ b/storage/maria/maria_def.h 2010-03-28 18:10:00 +0000
@@ -390,6 +390,7 @@ typedef struct st_maria_share
my_bool now_transactional;
my_bool have_versioning;
my_bool key_del_used; /* != 0 if key_del is locked */
+ my_bool deleting; /* we are going to delete this table */
#ifdef THREAD
THR_LOCK lock;
void (*lock_restore_status)(void *);
@@ -505,8 +506,10 @@ struct st_maria_handler
uchar *first_mbr_key; /* Searhed spatial key */
uchar *rec_buff; /* Temp buffer for recordpack */
uchar *blob_buff; /* Temp buffer for blobs */
- uchar *int_keypos, /* Save position for next/previous */
- *int_maxpos; /* -""- */
+ uchar *int_keypos; /* Save position for next/previous */
+ uchar *int_maxpos; /* -""- */
+ uint keypos_offset; /* Tmp storage for offset int_keypos */
+ uint maxpos_offset; /* Tmp storage for offset int_maxpos */
uchar *update_field_data; /* Used by update in rows-in-block */
uint int_nod_flag; /* -""- */
uint32 int_keytree_version; /* -""- */
@@ -978,6 +981,11 @@ extern ulonglong transid_get_packed(MARI
#define page_store_info(share, page) \
_ma_store_keypage_flag((share), (page)->buff, (page)->flag); \
_ma_store_page_used((share), (page)->buff, (page)->size);
+#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
+void page_cleanup(MARIA_SHARE *share, MARIA_PAGE *page)
+#else
+#define page_cleanup(A,B) while (0)
+#endif
extern MARIA_KEY *_ma_make_key(MARIA_HA *info, MARIA_KEY *int_key, uint keynr,
uchar *key, const uchar *record,
@@ -1196,7 +1204,7 @@ void _ma_tmp_disable_logging_for_table(M
my_bool log_incomplete);
my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages);
my_bool write_log_record_for_bulk_insert(MARIA_HA *info);
-
+void _ma_unpin_all_pages(MARIA_HA *info, LSN undo_lsn);
#define MARIA_NO_CRC_NORMAL_PAGE 0xffffffff
#define MARIA_NO_CRC_BITMAP_PAGE 0xfffffffe
=== modified file 'storage/myisam/ft_boolean_search.c'
--- a/storage/myisam/ft_boolean_search.c 2009-11-30 13:36:06 +0000
+++ b/storage/myisam/ft_boolean_search.c 2010-01-28 14:49:14 +0000
@@ -299,7 +299,7 @@ static int ftb_parse_query_internal(MYSQ
}
-static int _ftb_parse_query(FTB *ftb, uchar *query, uint len,
+static int _ftb_parse_query(FTB *ftb, uchar *query, mysql_ft_size_t len,
struct st_mysql_ftparser *parser)
{
MYSQL_FTPARSER_PARAM *param;
@@ -321,7 +321,7 @@ static int _ftb_parse_query(FTB *ftb, uc
param->mysql_add_word= ftb_query_add_word;
param->mysql_ftparam= (void *)&ftb_param;
param->cs= ftb->charset;
- param->doc= (char*) query;
+ param->doc= query;
param->length= len;
param->flags= 0;
param->mode= MYSQL_FTPARSER_FULL_BOOLEAN_INFO;
@@ -475,8 +475,7 @@ static void _ftb_init_index_search(FT_IN
int i;
FTB_WORD *ftbw;
- if ((ftb->state != READY && ftb->state !=INDEX_DONE) ||
- ftb->keynr == NO_SUCH_KEY)
+ if (ftb->state == UNINITIALIZED || ftb->keynr == NO_SUCH_KEY)
return;
ftb->state=INDEX_SEARCH;
@@ -541,7 +540,7 @@ static void _ftb_init_index_search(FT_IN
FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, uchar *query,
- uint query_len, CHARSET_INFO *cs)
+ mysql_ft_size_t query_len, CHARSET_INFO *cs)
{
FTB *ftb;
FTB_EXPR *ftbe;
@@ -680,8 +679,9 @@ static int ftb_check_phrase_internal(MYS
-1 is returned if error occurs.
*/
-static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len,
- FTB_EXPR *ftbe, struct st_mysql_ftparser *parser)
+static int _ftb_check_phrase(FTB *ftb, const uchar *document,
+ mysql_ft_size_t len,
+ FTB_EXPR *ftbe, struct st_mysql_ftparser *parser)
{
MY_FTB_PHRASE_PARAM ftb_param;
MYSQL_FTPARSER_PARAM *param;
@@ -702,7 +702,7 @@ static int _ftb_check_phrase(FTB *ftb, c
param->mysql_add_word= ftb_phrase_add_word;
param->mysql_ftparam= (void *)&ftb_param;
param->cs= ftb->charset;
- param->doc= (char *) document;
+ param->doc= document;
param->length= len;
param->flags= 0;
param->mode= MYSQL_FTPARSER_WITH_STOPWORDS;
@@ -1000,7 +1000,7 @@ float ft_boolean_find_relevance(FT_INFO
{
if (!ftsi.pos)
continue;
- param->doc= (char *)ftsi.pos;
+ param->doc= ftsi.pos;
param->length= ftsi.len;
if (unlikely(parser->parse(param)))
return 0;
=== modified file 'storage/myisam/ft_myisam.c'
--- a/storage/myisam/ft_myisam.c 2007-07-02 17:45:15 +0000
+++ b/storage/myisam/ft_myisam.c 2010-01-27 21:53:08 +0000
@@ -23,8 +23,8 @@
#include "ftdefs.h"
FT_INFO *ft_init_search(uint flags, void *info, uint keynr,
- uchar *query, uint query_len, CHARSET_INFO *cs,
- uchar *record)
+ uchar *query, size_t query_len,
+ CHARSET_INFO *cs, uchar *record)
{
FT_INFO *res;
if (flags & FT_BOOL)
=== modified file 'storage/myisam/ft_nlq_search.c'
--- a/storage/myisam/ft_nlq_search.c 2009-11-30 13:36:06 +0000
+++ b/storage/myisam/ft_nlq_search.c 2010-01-27 21:53:08 +0000
@@ -204,7 +204,8 @@ static int FT_DOC_cmp(void *unused __att
FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, uchar *query,
- uint query_len, uint flags, uchar *record)
+ mysql_ft_size_t query_len, uint flags,
+ uchar *record)
{
TREE wtree;
ALL_IN_ONE aio;
=== modified file 'storage/myisam/ft_parser.c'
--- a/storage/myisam/ft_parser.c 2009-11-30 13:36:06 +0000
+++ b/storage/myisam/ft_parser.c 2010-01-28 14:49:14 +0000
@@ -175,7 +175,7 @@ uchar ft_get_word(CHARSET_INFO *cs, cons
if ((param->trunc=(doc<end && *doc == FTB_TRUNC)))
doc++;
- if (((length >= ft_min_word_len && !is_stopword((char*) word->pos,
+ if (((length >= ft_min_word_len && !is_stopword(word->pos,
word->len))
|| param->trunc) && length < ft_max_word_len)
{
@@ -298,13 +298,13 @@ static int ft_parse_internal(MYSQL_FTPAR
DBUG_ENTER("ft_parse_internal");
while (ft_simple_get_word(wtree->custom_arg, &doc, end, &w, TRUE))
- if (param->mysql_add_word(param, (char*) w.pos, w.len, 0))
+ if (param->mysql_add_word(param, w.pos, w.len, 0))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
-int ft_parse(TREE *wtree, const uchar *doc, int doclen,
+int ft_parse(TREE *wtree, const uchar *doc, mysql_ft_size_t doclen,
struct st_mysql_ftparser *parser,
MYSQL_FTPARSER_PARAM *param, MEM_ROOT *mem_root)
{
@@ -319,7 +319,7 @@ int ft_parse(TREE *wtree, const uchar *d
param->mysql_add_word= ft_add_word;
param->mysql_ftparam= &my_param;
param->cs= wtree->custom_arg;
- param->doc= (char*) doc;
+ param->doc= doc;
param->length= doclen;
param->mode= MYSQL_FTPARSER_SIMPLE_MODE;
DBUG_RETURN(parser->parse(param));
=== modified file 'storage/myisam/ft_stopwords.c'
--- a/storage/myisam/ft_stopwords.c 2009-11-29 23:08:56 +0000
+++ b/storage/myisam/ft_stopwords.c 2010-03-28 18:10:00 +0000
@@ -20,8 +20,8 @@
typedef struct st_ft_stopwords
{
- const char * pos;
- uint len;
+ const uchar* pos;
+ size_t len;
} FT_STOPWORD;
static TREE *stopwords3=NULL;
@@ -30,23 +30,24 @@ static int FT_STOPWORD_cmp(void* cmp_arg
FT_STOPWORD *w1, FT_STOPWORD *w2)
{
return ha_compare_text(default_charset_info,
- (uchar *)w1->pos,w1->len,
- (uchar *)w2->pos,w2->len,0,0);
+ w1->pos, w1->len,
+ w2->pos, w2->len, 0, 0);
}
static void FT_STOPWORD_free(FT_STOPWORD *w, TREE_FREE action,
void *arg __attribute__((unused)))
{
if (action == free_free)
- my_free((uchar*) w->pos, MYF(0));
+ my_free((void*) w->pos, MYF(0));
}
static int ft_add_stopword(const char *w)
{
FT_STOPWORD sw;
- return !w ||
- (((sw.len= (uint) strlen(sw.pos=w)) >= ft_min_word_len) &&
- (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL));
+ return (!w ||
+ (((sw.len= (uint) strlen((char*) (sw.pos=(const uchar *)w))) >=
+ ft_min_word_len) &&
+ (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL)));
}
int ft_init_stopwords()
=== modified file 'storage/myisam/ftdefs.h'
--- a/storage/myisam/ftdefs.h 2009-11-29 23:08:56 +0000
+++ b/storage/myisam/ftdefs.h 2010-01-27 21:53:08 +0000
@@ -97,8 +97,8 @@
typedef struct st_ft_word {
const uchar *pos;
- uint len;
double weight;
+ size_t len;
} FT_WORD;
int is_stopword(const uchar *word, size_t len);
@@ -111,7 +111,8 @@ uchar ft_simple_get_word(CHARSET_INFO *,
FT_WORD *, my_bool);
typedef struct _st_ft_seg_iterator {
- uint num, len;
+ uint num;
+ mysql_ft_size_t len;
HA_KEYSEG *seg;
const uchar *rec, *pos;
} FT_SEG_ITERATOR;
@@ -128,8 +129,9 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *,
uint _mi_ft_parse(TREE *, MI_INFO *, uint, const uchar *,
MYSQL_FTPARSER_PARAM *, MEM_ROOT *);
-FT_INFO *ft_init_nlq_search(MI_INFO *, uint, uchar *, uint, uint, uchar *);
-FT_INFO *ft_init_boolean_search(MI_INFO *, uint, uchar *, uint, CHARSET_INFO *);
+FT_INFO *ft_init_nlq_search(MI_INFO *, uint, uchar *, mysql_ft_size_t, uint,
+ uchar *);
+FT_INFO *ft_init_boolean_search(MI_INFO *, uint, uchar *, mysql_ft_size_t, CHARSET_INFO *);
extern const struct _ft_vft _ft_vft_nlq;
int ft_nlq_read_next(FT_INFO *, char *);
=== modified file 'storage/myisam/mi_check.c'
--- a/storage/myisam/mi_check.c 2009-12-03 11:34:11 +0000
+++ b/storage/myisam/mi_check.c 2010-01-14 16:51:00 +0000
@@ -4447,7 +4447,7 @@ int update_state_info(HA_CHECK *param, M
{
if (update & UPDATE_TIME)
{
- share->state.check_time= (long) time((time_t*) 0);
+ share->state.check_time= time((time_t*) 0);
if (!share->state.create_time)
share->state.create_time=share->state.check_time;
}
=== modified file 'storage/myisam/mi_close.c'
--- a/storage/myisam/mi_close.c 2009-09-07 20:50:10 +0000
+++ b/storage/myisam/mi_close.c 2010-02-10 19:06:24 +0000
@@ -64,8 +64,9 @@ int mi_close(register MI_INFO *info)
if (share->kfile >= 0) abort(););
if (share->kfile >= 0 &&
flush_key_blocks(share->key_cache, share->kfile,
- share->temporary ? FLUSH_IGNORE_CHANGED :
- FLUSH_RELEASE))
+ ((share->temporary || share->deleting) ?
+ FLUSH_IGNORE_CHANGED :
+ FLUSH_RELEASE)))
error=my_errno;
if (share->kfile >= 0)
{
=== modified file 'storage/myisam/mi_create.c'
--- a/storage/myisam/mi_create.c 2009-10-15 21:38:29 +0000
+++ b/storage/myisam/mi_create.c 2010-03-12 19:03:37 +0000
@@ -192,6 +192,13 @@ int mi_create(const char *name,uint keys
options|= HA_OPTION_CHECKSUM;
min_pack_length++;
}
+ /*
+ Don't set HA_OPTION_NULL_FIELDS if no checksums, as this flag makes
+ that file incompatible with MySQL. This is ok, as this flag is only
+ used if one specifics table level checksums.
+ */
+ if (!(options & HA_OPTION_CHECKSUM))
+ options&= ~HA_OPTION_NULL_FIELDS;
if (flags & HA_CREATE_DELAY_KEY_WRITE)
options|= HA_OPTION_DELAY_KEY_WRITE;
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
@@ -575,7 +582,7 @@ int mi_create(const char *name,uint keys
max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
MI_EXTEND_BLOCK_LENGTH;
if (! (flags & HA_DONT_TOUCH_DATA))
- share.state.create_time= (long) time((time_t*) 0);
+ share.state.create_time= time((time_t*) 0);
pthread_mutex_lock(&THR_LOCK_myisam);
=== modified file 'storage/myisam/mi_extra.c'
--- a/storage/myisam/mi_extra.c 2009-10-06 06:13:56 +0000
+++ b/storage/myisam/mi_extra.c 2010-02-10 19:06:24 +0000
@@ -256,8 +256,13 @@ int mi_extra(MI_INFO *info, enum ha_extr
share->last_version= 0L; /* Impossible version */
pthread_mutex_unlock(&THR_LOCK_myisam);
break;
- case HA_EXTRA_PREPARE_FOR_RENAME:
case HA_EXTRA_PREPARE_FOR_DROP:
+ /* Signals about intent to delete this table */
+ share->deleting= TRUE;
+ share->global_changed= FALSE; /* force writing changed flag */
+ _mi_mark_file_changed(info);
+ /* Fall trough */
+ case HA_EXTRA_PREPARE_FOR_RENAME:
pthread_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */
pthread_mutex_lock(&share->intern_lock);
=== modified file 'storage/myisam/mi_open.c'
--- a/storage/myisam/mi_open.c 2009-12-03 11:19:05 +0000
+++ b/storage/myisam/mi_open.c 2010-02-10 19:06:24 +0000
@@ -58,6 +58,8 @@ MI_INFO *test_if_reopen(char *filename)
{
MI_INFO *info=(MI_INFO*) pos->data;
MYISAM_SHARE *share=info->s;
+ DBUG_ASSERT(strcmp(share->unique_file_name,filename) ||
+ share->last_version);
if (!strcmp(share->unique_file_name,filename) && share->last_version)
return info;
}
=== modified file 'storage/myisam/mi_packrec.c'
--- a/storage/myisam/mi_packrec.c 2009-10-15 21:38:29 +0000
+++ b/storage/myisam/mi_packrec.c 2010-03-04 08:03:07 +0000
@@ -1493,20 +1493,54 @@ static int _mi_read_rnd_mempack_record(M
my_bool _mi_memmap_file(MI_INFO *info)
{
MYISAM_SHARE *share=info->s;
+ my_bool eom;
+
DBUG_ENTER("mi_memmap_file");
if (!info->s->file_map)
{
+ my_off_t data_file_length= share->state.state.data_file_length;
+
+ if (myisam_mmap_size != SIZE_T_MAX)
+ {
+ pthread_mutex_lock(&THR_LOCK_myisam_mmap);
+ eom= data_file_length > myisam_mmap_size - myisam_mmap_used - MEMMAP_EXTRA_MARGIN;
+ if (!eom)
+ myisam_mmap_used+= data_file_length + MEMMAP_EXTRA_MARGIN;
+ pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
+ }
+ else
+ eom= data_file_length > myisam_mmap_size - MEMMAP_EXTRA_MARGIN;
+
+ if (eom)
+ {
+ DBUG_PRINT("warning", ("File is too large for mmap"));
+ DBUG_RETURN(0);
+ }
if (my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)) <
share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN)
{
DBUG_PRINT("warning",("File isn't extended for memmap"));
+ if (myisam_mmap_size != SIZE_T_MAX)
+ {
+ pthread_mutex_lock(&THR_LOCK_myisam_mmap);
+ myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN;
+ pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
+ }
DBUG_RETURN(0);
}
if (mi_dynmap_file(info,
share->state.state.data_file_length +
MEMMAP_EXTRA_MARGIN))
+ {
+ if (myisam_mmap_size != SIZE_T_MAX)
+ {
+ pthread_mutex_lock(&THR_LOCK_myisam_mmap);
+ myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN;
+ pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
+ }
DBUG_RETURN(0);
+ }
}
info->opt_flag|= MEMMAP_USED;
info->read_record= share->read_record= _mi_read_mempack_record;
@@ -1519,6 +1553,13 @@ void _mi_unmap_file(MI_INFO *info)
{
VOID(my_munmap((char*) info->s->file_map,
(size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN));
+
+ if (myisam_mmap_size != SIZE_T_MAX)
+ {
+ pthread_mutex_lock(&THR_LOCK_myisam_mmap);
+ myisam_mmap_used-= info->s->mmaped_length + MEMMAP_EXTRA_MARGIN;
+ pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
+ }
}
=== modified file 'storage/myisam/mi_static.c'
--- a/storage/myisam/mi_static.c 2009-10-27 13:20:34 +0000
+++ b/storage/myisam/mi_static.c 2009-12-24 06:34:31 +0000
@@ -40,7 +40,7 @@ ulong myisam_concurrent_insert= 0;
my_off_t myisam_max_temp_length= MAX_FILE_SIZE;
ulong myisam_bulk_insert_tree_size=8192*1024;
ulong myisam_data_pointer_size=4;
-
+ulonglong myisam_mmap_size= SIZE_T_MAX, myisam_mmap_used= 0;
static int always_valid(const char *filename __attribute__((unused)))
{
=== modified file 'storage/myisam/mi_test3.c'
--- a/storage/myisam/mi_test3.c 2008-04-28 16:24:05 +0000
+++ b/storage/myisam/mi_test3.c 2010-01-06 21:27:53 +0000
@@ -178,7 +178,8 @@ void start_test(int id)
}
if (key_cacheing && rnd(2) == 0)
init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0);
- printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
+ printf("Process %d, pid: %ld\n", id, (long) getpid());
+ fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
{
@@ -362,7 +363,7 @@ int test_write(MI_INFO *file,int id,int
mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
}
- sprintf((char*) record.id,"%7d",getpid());
+ sprintf((char*) record.id,"%7ld",(long) getpid());
strnmov((char*) record.text,"Testing...", sizeof(record.text));
tries=(uint) rnd(100)+10;
=== modified file 'storage/myisam/mi_write.c'
--- a/storage/myisam/mi_write.c 2009-12-03 11:19:05 +0000
+++ b/storage/myisam/mi_write.c 2010-03-10 10:32:14 +0000
@@ -735,10 +735,12 @@ static uchar *_mi_find_last_pos(MI_KEYDE
}
end=page+length-key_ref_length;
+ DBUG_ASSERT(page < end);
*key='\0';
length=0;
lastpos=page;
- while (page < end)
+
+ do
{
prevpos=lastpos; lastpos=page;
last_length=length;
@@ -749,7 +751,8 @@ static uchar *_mi_find_last_pos(MI_KEYDE
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0);
}
- }
+ } while (page < end);
+
*return_key_length=last_length;
*after_key=lastpos;
DBUG_PRINT("exit",("returns: 0x%lx page: 0x%lx end: 0x%lx",
=== modified file 'storage/myisam/myisamdef.h'
--- a/storage/myisam/myisamdef.h 2009-12-03 11:34:11 +0000
+++ b/storage/myisam/myisamdef.h 2010-03-04 08:03:07 +0000
@@ -221,6 +221,7 @@ typedef struct st_mi_isam_share
my_bool changed, /* If changed since lock */
global_changed, /* If changed since open */
not_flushed, temporary, delay_key_write, concurrent_insert;
+ my_bool deleting; /* we are going to delete this table */
#ifdef THREAD
THR_LOCK lock;
pthread_mutex_t intern_lock; /* Locking for use with _locking */
@@ -391,7 +392,6 @@ struct st_myisam_info
#define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1)))
#define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint32))
-#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */
#define PACK_TYPE_SELECTED 1 /* Bits in field->pack_type */
#define PACK_TYPE_SPACE_FIELDS 2
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2009-10-15 21:38:29 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-03-30 12:36:49 +0000
@@ -382,7 +382,7 @@ static MI_INFO *myisammrg_attach_childre
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
}
DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d",
- (long) myisam, my_errno));
+ my_errno ? 0L : (long) myisam, my_errno));
err:
DBUG_RETURN(my_errno ? NULL : myisam);
=== modified file 'storage/myisammrg/myrg_open.c'
--- a/storage/myisammrg/myrg_open.c 2009-09-23 13:21:29 +0000
+++ b/storage/myisammrg/myrg_open.c 2010-03-30 12:36:49 +0000
@@ -239,6 +239,7 @@ MYRG_INFO *myrg_parent_open(const char *
rc= 1;
errpos= 0;
bzero((char*) &file_cache, sizeof(file_cache));
+ LINT_INIT(m_info);
/* Open MERGE meta file. */
if ((fd= my_open(fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT,
=== modified file 'storage/ndb/plug.in'
--- a/storage/ndb/plug.in 2006-08-19 04:19:19 +0000
+++ b/storage/ndb/plug.in 2009-12-27 13:54:41 +0000
@@ -1,5 +1,5 @@
MYSQL_STORAGE_ENGINE(ndbcluster, ndbcluster, [Cluster Storage Engine],
- [High Availability Clustered tables], [max])
+ [High Availability Clustered tables],)
MYSQL_PLUGIN_DIRECTORY(ndbcluster,[storage/ndb])
MYSQL_PLUGIN_STATIC(ndbcluster, [[\$(ndbcluster_libs) \$(ndbcluster_system_libs) \$(NDB_SCI_LIBS)]])
MYSQL_PLUGIN_ACTIONS(ndbcluster,[MYSQL_SETUP_NDBCLUSTER])
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- a/storage/pbxt/src/ha_pbxt.cc 2009-12-29 11:34:44 +0000
+++ b/storage/pbxt/src/ha_pbxt.cc 2010-01-06 21:27:53 +0000
@@ -1294,7 +1294,7 @@ static int pbxt_init(void *p)
#6 0x000debe1 in THD::THD at sql_class.cc:631
#7 0x00e207a4 in myxt_create_thread at myxt_xt.cc:2666
#8 0x00e3134b in tabc_fr_run_thread at tabcache_xt.cc:982
- #9 0x00e422ca in thr_main at thread_xt.cc:1006
+ #9 0x00e422ca in thr_main_pbxt at thread_xt.cc:1006
#10 0x91ff7c55 in _pthread_start
#11 0x91ff7b12 in thread_start
*
@@ -1557,7 +1557,7 @@ static int pbxt_prepare(handlerton *hton
return err;
}
-static XTThreadPtr ha_temp_open_global_database(handlerton *hton, THD **ret_thd, int *temp_thread, char *thread_name, int *err)
+static XTThreadPtr ha_temp_open_global_database(handlerton *hton, THD **ret_thd, int *temp_thread, const char *thread_name, int *err)
{
THD *thd;
XTThreadPtr self = NULL;
=== modified file 'storage/pbxt/src/restart_xt.cc'
--- a/storage/pbxt/src/restart_xt.cc 2009-11-27 15:37:02 +0000
+++ b/storage/pbxt/src/restart_xt.cc 2010-01-06 21:27:53 +0000
@@ -3314,7 +3314,7 @@ static void *xn_xres_run_recovery_thread
* #7 0x000c0db2 in THD::~THD at sql_class.cc:934
* #8 0x003b025b in myxt_destroy_thread at myxt_xt.cc:2999
* #9 0x003b66b5 in xn_xres_run_recovery_thread at restart_xt.cc:3196
- * #10 0x003cbfbb in thr_main at thread_xt.cc:1020
+ * #10 0x003cbfbb in thr_main_pbxt at thread_xt.cc:1020
*
myxt_destroy_thread(mysql_thread, TRUE);
*/
=== modified file 'storage/pbxt/src/thread_xt.cc'
--- a/storage/pbxt/src/thread_xt.cc 2009-12-22 10:33:20 +0000
+++ b/storage/pbxt/src/thread_xt.cc 2010-01-06 21:27:53 +0000
@@ -1013,7 +1013,7 @@ static xtBool thr_setup_signals(void)
typedef void *(*ThreadMainFunc)(XTThreadPtr self);
-extern "C" void *thr_main(void *data)
+extern "C" void *thr_main_pbxt(void *data)
{
ThreadDataPtr td = (ThreadDataPtr) data;
XTThreadPtr self = td->td_thr;
@@ -1503,10 +1503,10 @@ xtPublic pthread_t xt_run_thread(XTThrea
pthread_attr_t attr = { 0, 0, 0 };
attr.priority = THREAD_PRIORITY_NORMAL;
- err = pthread_create(&child_thread, &attr, thr_main, &data);
+ err = pthread_create(&child_thread, &attr, thr_main_pbxt, &data);
}
#else
- err = pthread_create(&child_thread, NULL, thr_main, &data);
+ err = pthread_create(&child_thread, NULL, thr_main_pbxt, &data);
#endif
if (err) {
xt_free_thread(child);
=== modified file 'storage/pbxt/src/thread_xt.h'
--- a/storage/pbxt/src/thread_xt.h 2009-11-24 10:55:06 +0000
+++ b/storage/pbxt/src/thread_xt.h 2010-01-06 21:27:53 +0000
@@ -536,7 +536,7 @@ extern struct XTThread **xt_thr_array;
* Function prototypes
*/
-extern "C" void *thr_main(void *data);
+extern "C" void *thr_main_pbxt(void *data);
void xt_get_now(char *buffer, size_t len);
xtBool xt_init_logging(void);
=== modified file 'storage/xtradb/CMakeLists.txt'
--- a/storage/xtradb/CMakeLists.txt 2009-11-14 09:53:18 +0000
+++ b/storage/xtradb/CMakeLists.txt 2010-01-15 15:58:25 +0000
@@ -13,36 +13,41 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
- SET(WIN64 TRUE)
-ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
+# This is the CMakeLists for InnoDB Plugin
-# Check type sizes
-include(CheckTypeSize)
-
-# Currently, the checked results are not used.
-CHECK_TYPE_SIZE(int SIZEOF_INT)
-CHECK_TYPE_SIZE(long SIZEOF_LONG)
-CHECK_TYPE_SIZE(void* SIZEOF_VOID_P)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+
+# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin
+# CMakeLists.txt still needs to work with previous versions of MySQL.
+IF (MYSQL_VERSION_ID GREATER "50137")
+ INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+ENDIF (MYSQL_VERSION_ID GREATER "50137")
+
+IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
+ SET(WIN64 TRUE)
+ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
+
ADD_DEFINITIONS(-D_WIN32 -D_LIB -DMYSQL_SERVER)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
- ${CMAKE_SOURCE_DIR}/storage/xtradb/include
- ${CMAKE_SOURCE_DIR}/storage/xtradb/handler
- ${CMAKE_SOURCE_DIR}/sql
- ${CMAKE_SOURCE_DIR}/regex
- ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+# Include directories under innobase
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/xtradb/include
+ ${CMAKE_SOURCE_DIR}/storage/xtradb/handler)
+
+# Include directories under mysql
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/zlib
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include)
# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
-IF(MSVC AND $(WIN64))
+IF (MSVC AND $(WIN64))
SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
PROPERTIES COMPILE_FLAGS -Od)
-ENDIF(MSVC AND $(WIN64))
+ENDIF (MSVC AND $(WIN64))
SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
@@ -77,5 +82,20 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/b
usr/usr0sess.c
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
ut/ut0list.c ut/ut0wqueue.c)
+ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
-MYSQL_STORAGE_ENGINE(INNOBASE)
+IF (MYSQL_VERSION_ID GREATER "50137")
+ MYSQL_STORAGE_ENGINE(INNOBASE)
+ # Use ha_innodb for plugin name, if plugin is built
+ GET_TARGET_PROPERTY(LIB_LOCATION ha_innobase LOCATION)
+ IF(LIB_LOCATION)
+ SET_TARGET_PROPERTIES(ha_innobase PROPERTIES OUTPUT_NAME ha_innodb)
+ ENDIF(LIB_LOCATION)
+ELSE (MYSQL_VERSION_ID GREATER "50137")
+ IF (NOT SOURCE_SUBLIBS)
+ ADD_DEFINITIONS(-D_WIN32 -DMYSQL_SERVER)
+ ADD_LIBRARY(innobase STATIC ${INNOBASE_SOURCES})
+ # Require mysqld_error.h, which is built as part of the GenError
+ ADD_DEPENDENCIES(innobase GenError)
+ ENDIF (NOT SOURCE_SUBLIBS)
+ENDIF (MYSQL_VERSION_ID GREATER "50137")
=== modified file 'storage/xtradb/ChangeLog'
--- a/storage/xtradb/ChangeLog 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/ChangeLog 2010-01-15 15:58:25 +0000
@@ -1,3 +1,319 @@
+2009-11-20 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Add a workaround to prevent a crash due to Bug#45961 DDL on
+ partitioned innodb tables leaves data dictionary in an inconsistent
+ state
+
+2009-11-19 The InnoDB Team
+
+ * btr/btr0btr.c:
+ Fix Bug#48469 when innodb tablespace is configured too small, crash
+ and corruption!
+
+2009-11-19 The InnoDB Team
+
+ * data/data0type.c:
+ Fix Bug#48526 Data type for float and double is incorrectly reported
+ in InnoDB table monitor
+
+2009-11-19 The InnoDB Team
+
+ * CMakeLists.txt:
+ Fix Bug#48317 cannot build innodb as static library
+
+2009-11-18 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Fix Bug#48782 On lock wait timeout, CREATE INDEX (creating primary key)
+ attempts DROP TABLE
+
+2009-11-17 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb.result,
+ mysql-test/innodb.test, mysql-test/innodb_bug44369.result,
+ mysql-test/innodb_bug44369.test, mysql-test/patches/innodb-index.diff,
+ row/row0mysql.c:
+ Report duplicate table names to the client connection, not to the
+ error log.
+
+2009-11-12 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/db0err.h, row/row0merge.c,
+ row/row0mysql.c:
+ Allow CREATE INDEX to be interrupted.
+ Also, when CHECK TABLE is interrupted, report ER_QUERY_INTERRUPTED.
+
+2009-11-11 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug47167.result,
+ mysql-test/innodb_bug47167.test, mysql-test/innodb_file_format.result:
+ Fix Bug#47167 "set global innodb_file_format_check" cannot set value
+ by User-Defined Variable
+
+2009-11-11 The InnoDB Team
+
+ * include/os0file.h, os/os0file.c:
+ Fix Bug#3139 Mysql crashes: 'windows error 995' after several selects
+ on a large DB
+
+2009-11-04 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#32430 'show innodb status' causes errors
+ Invalid (old?) table or database name in logs
+
+2009-11-02 The InnoDB Team
+
+ * btr/btr0sea.c, buf/buf0buf.c, dict/dict0dict.c, fil/fil0fil.c,
+ ibuf/ibuf0ibuf.c, include/btr0sea.h, include/dict0dict.h,
+ include/fil0fil.h, include/ibuf0ibuf.h, include/lock0lock.h,
+ include/log0log.h, include/log0recv.h, include/mem0mem.h,
+ include/mem0pool.h, include/os0file.h, include/pars0pars.h,
+ include/srv0srv.h, include/thr0loc.h, include/trx0i_s.h,
+ include/trx0purge.h, include/trx0rseg.h, include/trx0sys.h,
+ include/trx0undo.h, include/usr0sess.h, lock/lock0lock.c,
+ log/log0log.c, log/log0recv.c, mem/mem0dbg.c, mem/mem0pool.c,
+ os/os0file.c, os/os0sync.c, os/os0thread.c, pars/lexyy.c,
+ pars/pars0lex.l, que/que0que.c, srv/srv0srv.c, srv/srv0start.c,
+ sync/sync0arr.c, sync/sync0sync.c, thr/thr0loc.c, trx/trx0i_s.c,
+ trx/trx0purge.c, trx/trx0rseg.c, trx/trx0sys.c, trx/trx0undo.c,
+ usr/usr0sess.c, ut/ut0mem.c:
+ Fix Bug #45992 innodb memory not freed after shutdown
+ Fix Bug #46656 InnoDB plugin: memory leaks (Valgrind)
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
+ mysql-test/innodb-autoinc.test:
+ Fix Bug#47125 auto_increment start value is ignored if an index is
+ created and engine=innodb
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug47777.result,
+ mysql-test/innodb_bug47777.test:
+ Fix Bug#47777 innodb dies with spatial pk: Failing assertion: buf <=
+ original_buf + buf_len
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#38996 Race condition in ANALYZE TABLE
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix bug#42383: Can't create table 'test.bug39438'
+
+2009-10-29 The InnoDB Team
+
+ * os/os0proc.c:
+ Fix Bug#48237 Error handling in os_mem_alloc_large appears to
+ be incorrect
+
+2009-10-29 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0lru.c, include/buf0buf.h, include/buf0buf.ic:
+ Fix corruption of the buf_pool->LRU_old list and improve debug
+ assertions.
+
+2009-10-28 The InnoDB Team
+
+ * srv/srv0start.c:
+ Fix Bug#41490 After enlargement of InnoDB page size, the error message
+ become inaccurate
+
+2009-10-26 The InnoDB Team
+
+ * row/row0ins.c:
+ When allocating a data tuple, zero out the system fields in order
+ to avoid Valgrind warnings about uninitialized fields in
+ dtuple_validate().
+
+2009-10-22 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-zip.result,
+ mysql-test/innodb-zip.test, mysql-test/innodb_bug44369.result,
+ mysql-test/innodb_bug44369.test:
+ Fix Bug#47233 Innodb calls push_warning(MYSQL_ERROR::WARN_LEVEL_ERROR)
+
+2009-10-19 The InnoDB Team
+
+ * mysql-test/innodb_information_schema.test:
+ Fix Bug#47808 innodb_information_schema.test fails when run under
+ valgrind
+
+2009-10-15 The InnoDB Team
+
+ * include/page0page.ic:
+ Fix Bug#47058 Failure to compile innodb_plugin on solaris 10u7 + spro
+ cc/CC 5.10
+
+2009-10-13 The InnoDB Team
+
+ * buf/buf0flu.c:
+ Call fsync() on datafiles after a batch of pages is written to disk
+ even when skip_innodb_doublewrite is set.
+
+2009-10-05 The InnoDB Team
+
+ * buf/buf0buf.c:
+ Do not invalidate buffer pool while an LRU batch is active. Added code
+ to buf_pool_invalidate() to wait for the running batches to finish.
+
+2009-10-01 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#47763 typo in error message: Failed to open table %s after %lu
+ attemtps.
+
+2009-10-01 The InnoDB Team
+
+ * fsp/fsp0fsp.c, row/row0merge.c:
+ Clean up after a crash during DROP INDEX. When InnoDB crashes
+ while dropping an index, ensure that the index will be completely
+ dropped during crash recovery. The MySQL .frm file may still
+ contain the dropped index, but there is little that we can do
+ about it.
+
+2009-09-28 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ When a secondary index exists in the MySQL .frm file but not in
+ the InnoDB data dictionary, return an error instead of letting an
+ assertion fail in index_read.
+
+2009-09-28 The InnoDB Team
+
+ * btr/btr0btr.c, buf/buf0buf.c, include/page0page.h,
+ include/page0zip.h, page/page0cur.c, page/page0page.c,
+ page/page0zip.c:
+ Do not write to PAGE_INDEX_ID when restoring an uncompressed page
+ after a compression failure. The field should only be written
+ when creating a B-tree page. This fix addresses a race condition
+ in a debug assertion.
+
+2009-09-28 The InnoDB Team
+
+ * fil/fil0fil.c:
+ Try to prevent the reuse of tablespace identifiers after InnoDB
+ has crashed during table creation. Also, refuse to start if files
+ with duplicate tablespace identifiers are encountered.
+
+2009-09-25 The InnoDB Team
+
+ * include/os0file.h, os/os0file.c:
+ Fix Bug#47055 unconditional exit(1) on ERROR_WORKING_SET_QUOTA
+ 1453 (0x5AD) for InnoDB backend
+
+2009-09-19 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-consistent-master.opt,
+ mysql-test/innodb-consistent.result,
+ mysql-test/innodb-consistent.test:
+ Fix Bug#37232 Innodb might get too many read locks for DML with
+ repeatable-read
+
+2009-09-19 The InnoDB Team
+
+ * fsp/fsp0fsp.c:
+ Fix Bug#31183 Tablespace full problems not reported in error log,
+ error message unclear
+
+2009-09-17 The InnoDB Team
+
+ * mysql-test/innodb-zip.result, mysql-test/innodb-zip.test:
+ Make the test pass with zlib 1.2.3.3. Apparently, the definition
+ of compressBound() has changed between zlib versions, and the
+ maximum record size of a table with 1K compressed page size has
+ been reduced by one byte. This is an arbitrary test. In practical
+ applications, for good write performance, the compressed page size
+ should be chosen to be bigger than the absolute minimum.
+
+2009-09-16 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#46256 drop table with unknown collation crashes innodb
+
+2009-09-16 The InnoDB Team
+
+ * dict/dict0dict.c, handler/ha_innodb.cc,
+ mysql-test/innodb_bug44369.result, mysql-test/innodb_bug44369.test,
+ row/row0mysql.c:
+ Fix Bug#44369 InnoDB: Does not uniformly disallow disallowed column
+ names
+
+2009-09-16 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/db0err.h,
+ mysql-test/innodb_bug46000.result, mysql-test/innodb_bug46000.test:
+ Fix Bug#46000 using index called GEN_CLUST_INDEX crashes server
+
+2009-09-02 The InnoDB Team
+
+ * include/lock0lock.h, include/row0mysql.h, lock/lock0lock.c,
+ row/row0mysql.c:
+ Fix a regression introduced by the fix for MySQL bug#26316. We check
+ whether a transaction holds any AUTOINC locks before we acquire
+ the kernel mutex and release those locks.
+
+2009-08-27 The InnoDB Team
+
+ * dict/dict0dict.c, include/dict0dict.h,
+ mysql-test/innodb_bug44571.result, mysql-test/innodb_bug44571.test:
+ Fix Bug#44571 InnoDB Plugin crashes on ADD INDEX
+
+2009-08-27 The InnoDB Team
+
+ * row/row0merge.c:
+ Fix a bug in the merge sort that can corrupt indexes in fast index
+ creation. Add some consistency checks. Check that the number of
+ records remains constant in every merge sort pass.
+
+2009-08-27 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
+ include/buf0buf.h, include/buf0buf.ic, include/buf0lru.h,
+ include/ut0ut.h, ut/ut0ut.c:
+ Make it possible to tune the buffer pool LRU eviction policy to be
+ more resistant against index scans. Introduce the settable global
+ variables innodb_old_blocks_pct and innodb_old_blocks_time for
+ controlling the buffer pool eviction policy. The parameter
+ innodb_old_blocks_pct (5..95) controls the desired amount of "old"
+ blocks in the LRU list. The default is 37, corresponding to the
+ old fixed ratio of 3/8. Each time a block is accessed, it will be
+ moved to the "new" blocks if its first access was at least
+ innodb_old_blocks_time milliseconds ago (default 0, meaning every
+ block). The idea is that in index scans, blocks will be accessed
+ a few times within innodb_old_blocks_time, and they will remain in
+ the "old" section of the LRU list. Thus, when innodb_old_blocks_time
+ is nonzero, blocks retrieved for one-time index scans will be more
+ likely candidates for eviction than blocks that are accessed in
+ random patterns.
+
+2009-08-26 The InnoDB Team
+
+ * handler/ha_innodb.cc, os/os0file.c:
+ Fix Bug#42885 buf_read_ahead_random, buf_read_ahead_linear counters,
+ thread wakeups
+
+2009-08-20 The InnoDB Team
+
+ * lock/lock0lock.c:
+ Fix Bug#46650 Innodb assertion autoinc_lock == lock in
+ lock_table_remove_low on INSERT SELECT
+
+2009-08-13 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Fix Bug#46657 InnoDB plugin: invalid read in index_merge_innodb test
+ (Valgrind)
+
+2009-08-11 The InnoDB Team
+
+ InnoDB Plugin 1.0.4 released
+
2009-07-20 The InnoDB Team
* buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,
=== modified file 'storage/xtradb/Makefile.am'
--- a/storage/xtradb/Makefile.am 2009-11-13 22:53:04 +0000
+++ b/storage/xtradb/Makefile.am 2010-01-15 15:58:25 +0000
@@ -22,7 +22,7 @@ MYSQLLIBdir= $(pkglibdir)
pkgplugindir= $(pkglibdir)/plugin
INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
-I$(top_srcdir)/regex \
- -I$(top_srcdir)/storage/xtradb/include \
+ -I$(srcdir)/include \
-I$(top_srcdir)/sql \
-I$(srcdir) @ZLIB_INCLUDES@
@@ -31,7 +31,6 @@ DEFS= @DEFS@
noinst_HEADERS= \
handler/ha_innodb.h \
- handler/handler0vars.h \
handler/i_s.h \
include/btr0btr.h \
include/btr0btr.ic \
=== modified file 'storage/xtradb/btr/btr0btr.c'
--- a/storage/xtradb/btr/btr0btr.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/btr/btr0btr.c 2010-01-06 12:00:14 +0000
@@ -790,14 +790,21 @@ btr_create(
} else {
/* It is a non-ibuf tree: create a file segment for leaf
pages */
- fseg_create(space, page_no,
- PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr);
+ if (!fseg_create(space, page_no,
+ PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
+ /* Not enough space for new segment, free root
+ segment before return. */
+ btr_free_root(space, zip_size, page_no, mtr);
+
+ return(FIL_NULL);
+ }
+
/* The fseg create acquires a second latch on the page,
therefore we must declare it: */
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
}
- /* Create a new index page on the the allocated segment page */
+ /* Create a new index page on the allocated segment page */
page_zip = buf_block_get_page_zip(block);
if (UNIV_LIKELY_NULL(page_zip)) {
@@ -1011,7 +1018,26 @@ btr_page_reorganize_low(
(!page_zip_compress(page_zip, page, index, NULL))) {
/* Restore the old page and exit. */
- buf_frame_copy(page, temp_page);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ /* Check that the bytes that we skip are identical. */
+ ut_a(!memcmp(page, temp_page, PAGE_HEADER));
+ ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page,
+ PAGE_HEADER + PAGE_N_RECS + temp_page,
+ PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS)));
+ ut_a(!memcmp(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page,
+ UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + temp_page,
+ FIL_PAGE_DATA_END));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+
+ memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page,
+ PAGE_N_RECS - PAGE_N_DIR_SLOTS);
+ memcpy(PAGE_DATA + page, PAGE_DATA + temp_page,
+ UNIV_PAGE_SIZE - PAGE_DATA - FIL_PAGE_DATA_END);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ ut_a(!memcmp(page, temp_page, UNIV_PAGE_SIZE));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
goto func_exit;
}
@@ -1902,7 +1928,7 @@ func_start:
n_uniq, &heap);
/* If the new record is less than the existing record
- the the split in the middle will copy the existing
+ the split in the middle will copy the existing
record to the new node. */
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
split_rec = page_get_middle_rec(page);
=== modified file 'storage/xtradb/btr/btr0cur.c'
--- a/storage/xtradb/btr/btr0cur.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/btr/btr0cur.c 2010-03-10 10:32:14 +0000
@@ -3233,7 +3233,7 @@ btr_estimate_number_of_different_key_val
ulint matched_bytes;
ib_int64_t n_recs = 0;
ib_int64_t* n_diff;
- ib_int64_t* n_not_nulls;
+ ib_int64_t* n_not_nulls= 0;
ullint n_sample_pages; /* number of pages to sample */
ulint not_empty_flag = 0;
ulint total_external_size = 0;
=== modified file 'storage/xtradb/btr/btr0sea.c'
--- a/storage/xtradb/btr/btr0sea.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/btr/btr0sea.c 2010-01-06 12:00:14 +0000
@@ -175,6 +175,21 @@ btr_search_sys_create(
btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
}
+/*****************************************************************//**
+Frees the adaptive search system at a database shutdown. */
+UNIV_INTERN
+void
+btr_search_sys_free(void)
+/*=====================*/
+{
+ mem_free(btr_search_latch_temp);
+ btr_search_latch_temp = NULL;
+ mem_heap_free(btr_search_sys->hash_index->heap);
+ hash_table_free(btr_search_sys->hash_index);
+ mem_free(btr_search_sys);
+ btr_search_sys = NULL;
+}
+
/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
UNIV_INTERN
@@ -957,7 +972,7 @@ btr_search_guess_on_hash(
/* Increment the page get statistics though we did not really
fix the page: for user info only */
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
return(TRUE);
=== modified file 'storage/xtradb/buf/buf0buddy.c'
--- a/storage/xtradb/buf/buf0buddy.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/buf/buf0buddy.c 2010-01-15 15:58:25 +0000
@@ -531,11 +531,10 @@ buf_buddy_relocate(
UNIV_MEM_ASSERT_W(src, size);
mutex = buf_page_get_mutex_enter(bpage);
- ut_a(mutex);
mutex_enter(&zip_free_mutex);
- if (buf_page_can_relocate(bpage)) {
+ if (mutex && buf_page_can_relocate(bpage)) {
/* Relocate the compressed page. */
ut_a(bpage->zip.data == src);
memcpy(dst, src, size);
@@ -563,7 +562,9 @@ success:
rw_lock_x_unlock(&page_hash_latch);
}
- mutex_exit(mutex);
+ if (mutex) {
+ mutex_exit(mutex);
+ }
} else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
/* This must be a buf_page_t object. */
UNIV_MEM_ASSERT_RW(src, size);
=== modified file 'storage/xtradb/buf/buf0buf.c'
--- a/storage/xtradb/buf/buf0buf.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/buf/buf0buf.c 2010-01-28 11:35:10 +0000
@@ -51,6 +51,40 @@ Created 11/5/1995 Heikki Tuuri
#include "dict0dict.h"
#include "log0recv.h"
#include "page0zip.h"
+#include "trx0trx.h"
+
+/* prototypes for new functions added to ha_innodb.cc */
+trx_t* innobase_get_trx();
+
+inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
+{
+ ulint block_hash;
+ ulint block_hash_byte;
+ byte block_hash_offset;
+
+ ut_ad(block);
+
+ if (!innobase_get_slow_log() || !trx || !trx->take_stats)
+ return;
+
+ if (!trx->distinct_page_access_hash) {
+ trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
+ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
+ }
+
+ block_hash = ut_hash_ulint((block->page.space << 20) + block->page.space +
+ block->page.offset, DPAH_SIZE << 3);
+ block_hash_byte = block_hash >> 3;
+ block_hash_offset = (byte) block_hash & 0x07;
+ if (block_hash_byte >= DPAH_SIZE)
+ fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", (unsigned long) block_hash_byte, (unsigned long) block_hash_offset);
+ if (block_hash_offset > 7)
+ fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", (unsigned long) block_hash_byte, (unsigned long) block_hash_offset);
+ if ((trx->distinct_page_access_hash[block_hash_byte] & ((byte) 0x01 << block_hash_offset)) == 0)
+ trx->distinct_page_access++;
+ trx->distinct_page_access_hash[block_hash_byte] |= (byte) 0x01 << block_hash_offset;
+ return;
+}
/*
IMPLEMENTATION OF THE BUFFER POOL
@@ -845,16 +879,35 @@ buf_chunk_not_freed(
block = chunk->blocks;
for (i = chunk->size; i--; block++) {
- mutex_enter(&block->mutex);
-
- if (buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
- && !buf_flush_ready_for_replace(&block->page)) {
+ ibool ready;
+ switch (buf_block_get_state(block)) {
+ case BUF_BLOCK_ZIP_FREE:
+ case BUF_BLOCK_ZIP_PAGE:
+ case BUF_BLOCK_ZIP_DIRTY:
+ /* The uncompressed buffer pool should never
+ contain compressed block descriptors. */
+ ut_error;
+ break;
+ case BUF_BLOCK_NOT_USED:
+ case BUF_BLOCK_READY_FOR_USE:
+ case BUF_BLOCK_MEMORY:
+ case BUF_BLOCK_REMOVE_HASH:
+ /* Skip blocks that are not being used for
+ file pages. */
+ break;
+ case BUF_BLOCK_FILE_PAGE:
+ mutex_enter(&block->mutex);
+ ready = buf_flush_ready_for_replace(&block->page);
mutex_exit(&block->mutex);
- return(block);
- }
- mutex_exit(&block->mutex);
+ if (!ready) {
+
+ return(block);
+ }
+
+ break;
+ }
}
return(NULL);
@@ -985,8 +1038,6 @@ buf_pool_init(void)
buf_pool->no_flush[i] = os_event_create(NULL);
}
- buf_pool->ulint_clock = 1;
-
/* 3. Initialize LRU fields
--------------------------- */
/* All fields are initialized by mem_zalloc(). */
@@ -1024,7 +1075,11 @@ buf_pool_free(void)
os_mem_free_large(chunk->mem, chunk->mem_size);
}
- buf_pool->n_chunks = 0;
+ mem_free(buf_pool->chunks);
+ hash_table_free(buf_pool->page_hash);
+ hash_table_free(buf_pool->zip_hash);
+ mem_free(buf_pool);
+ buf_pool = NULL;
}
/********************************************************************//**
@@ -1171,10 +1226,15 @@ buf_relocate(
#ifdef UNIV_LRU_DEBUG
/* buf_pool->LRU_old must be the first item in the LRU list
whose "old" flag is set. */
+ ut_a(buf_pool->LRU_old->old);
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
+ } else {
+ /* Check that the "old" flag is consistent in
+ the block and its neighbours. */
+ buf_page_set_old(dpage, buf_page_is_old(dpage));
#endif /* UNIV_LRU_DEBUG */
}
@@ -1510,35 +1570,8 @@ buf_pool_resize(void)
}
/********************************************************************//**
-Moves the block to the start of the LRU list if there is a danger
-that the block would drift out of the buffer pool. */
-UNIV_INLINE
-void
-buf_block_make_young(
-/*=================*/
- buf_page_t* bpage) /*!< in: block to make younger */
-{
- ut_ad(!buf_pool_mutex_own());
-
- /* Note that we read freed_page_clock's without holding any mutex:
- this is allowed since the result is used only in heuristics */
-
- if (buf_page_peek_if_too_old(bpage)) {
-
- //buf_pool_mutex_enter();
- mutex_enter(&LRU_list_mutex);
- /* There has been freeing activity in the LRU list:
- best to move to the head of the LRU list */
-
- buf_LRU_make_block_young(bpage);
- //buf_pool_mutex_exit();
- mutex_exit(&LRU_list_mutex);
- }
-}
-
-/********************************************************************//**
Moves a page to the start of the buffer pool LRU list. This high-level
-function can be used to prevent an important page from from slipping out of
+function can be used to prevent an important page from slipping out of
the buffer pool. */
UNIV_INTERN
void
@@ -1558,6 +1591,42 @@ buf_page_make_young(
}
/********************************************************************//**
+Sets the time of the first access of a page and moves a page to the
+start of the buffer pool LRU list if it is too old. This high-level
+function can be used to prevent an important page from slipping
+out of the buffer pool. */
+static
+void
+buf_page_set_accessed_make_young(
+/*=============================*/
+ buf_page_t* bpage, /*!< in/out: buffer block of a
+ file page */
+ unsigned access_time) /*!< in: bpage->access_time
+ read under mutex protection,
+ or 0 if unknown */
+{
+ ut_ad(!buf_pool_mutex_own());
+ ut_a(buf_page_in_file(bpage));
+
+ if (buf_page_peek_if_too_old(bpage)) {
+ //buf_pool_mutex_enter();
+ mutex_enter(&LRU_list_mutex);
+ buf_LRU_make_block_young(bpage);
+ //buf_pool_mutex_exit();
+ mutex_exit(&LRU_list_mutex);
+ } else if (!access_time) {
+ ulint time_ms = ut_time_ms();
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
+ //buf_pool_mutex_enter();
+ if (block_mutex) {
+ buf_page_set_accessed(bpage, time_ms);
+ mutex_exit(block_mutex);
+ }
+ //buf_pool_mutex_exit();
+ }
+}
+
+/********************************************************************//**
Resets the check_index_page_at_flush field of a page if found in the buffer
pool. */
UNIV_INTERN
@@ -1696,11 +1765,20 @@ buf_page_get_zip(
buf_page_t* bpage;
mutex_t* block_mutex;
ibool must_read;
+ unsigned access_time;
+ trx_t* trx = NULL;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t start_time;
+ ib_uint64_t finish_time;
#ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside());
#endif
- buf_pool->n_page_gets++;
+ if (innobase_get_slow_log()) {
+ trx = innobase_get_trx();
+ }
+ buf_pool->stat.n_page_gets++;
for (;;) {
//buf_pool_mutex_enter();
@@ -1716,7 +1794,7 @@ lookup:
//buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
- buf_read_page(space, zip_size, offset);
+ buf_read_page(space, zip_size, offset, trx);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(++buf_dbg_counter % 37 || buf_validate());
@@ -1770,14 +1848,13 @@ err_exit:
got_block:
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
+ access_time = buf_page_is_accessed(bpage);
//buf_pool_mutex_exit();
- buf_page_set_accessed(bpage, TRUE);
-
mutex_exit(block_mutex);
- buf_block_make_young(bpage);
+ buf_page_set_accessed_make_young(bpage, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(!bpage->file_page_was_freed);
@@ -1793,6 +1870,13 @@ got_block:
/* Let us wait until the read operation
completes */
+ if (innobase_get_slow_log() && trx && trx->take_stats)
+ {
+ ut_usectime(&sec, &ms);
+ start_time = (ib_uint64_t)sec * 1000000 + ms;
+ } else {
+ start_time = 0;
+ }
for (;;) {
enum buf_io_fix io_fix;
@@ -1807,6 +1891,12 @@ got_block:
break;
}
}
+ if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
+ }
}
#ifdef UNIV_IBUF_COUNT_DEBUG
@@ -1870,7 +1960,7 @@ buf_zip_decompress(
switch (fil_page_get_type(frame)) {
case FIL_PAGE_INDEX:
if (page_zip_decompress(&block->page.zip,
- block->frame)) {
+ block->frame, TRUE)) {
return(TRUE);
}
@@ -2058,10 +2148,15 @@ buf_page_get_gen(
mtr_t* mtr) /*!< in: mini-transaction */
{
buf_block_t* block;
- ibool accessed;
+ unsigned access_time;
ulint fix_type;
ibool must_read;
mutex_t* block_mutex;
+ trx_t* trx = NULL;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t start_time;
+ ib_uint64_t finish_time;
ut_ad(mtr);
ut_ad((rw_latch == RW_S_LATCH)
@@ -2075,14 +2170,16 @@ buf_page_get_gen(
#ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
#endif
- buf_pool->n_page_gets++;
+ if (innobase_get_slow_log()) {
+ trx = innobase_get_trx();
+ }
+ buf_pool->stat.n_page_gets++;
loop:
block = guess;
//buf_pool_mutex_enter();
if (block) {
block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
- ut_a(block_mutex);
/* If the guess is a compressed page descriptor that
has been allocated by buf_buddy_alloc(), it may have
@@ -2092,7 +2189,9 @@ loop:
the guess may be pointing to a buffer pool chunk that
has been released when resizing the buffer pool. */
- if (!buf_block_is_uncompressed(block)
+ if (!block_mutex) {
+ block = guess = NULL;
+ } else if (!buf_block_is_uncompressed(block)
|| offset != block->page.offset
|| space != block->page.space
|| buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
@@ -2127,7 +2226,7 @@ loop2:
return(NULL);
}
- buf_read_page(space, zip_size, offset);
+ buf_read_page(space, zip_size, offset, trx);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(++buf_dbg_counter % 37 || buf_validate());
@@ -2351,17 +2450,17 @@ wait_until_unfixed:
UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page);
buf_block_buf_fix_inc(block, file, line);
- //buf_pool_mutex_exit();
- /* Check if this is the first access to the page */
+ //mutex_exit(&block->mutex);
- accessed = buf_page_is_accessed(&block->page);
+ /* Check if this is the first access to the page */
- buf_page_set_accessed(&block->page, TRUE);
+ access_time = buf_page_is_accessed(&block->page);
+ //buf_pool_mutex_exit();
mutex_exit(block_mutex);
- buf_block_make_young(&block->page);
+ buf_page_set_accessed_make_young(&block->page, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(!block->page.file_page_was_freed);
@@ -2379,6 +2478,13 @@ wait_until_unfixed:
/* Let us wait until the read operation
completes */
+ if (innobase_get_slow_log() && trx && trx->take_stats)
+ {
+ ut_usectime(&sec, &ms);
+ start_time = (ib_uint64_t)sec * 1000000 + ms;
+ } else {
+ start_time = 0;
+ }
for (;;) {
enum buf_io_fix io_fix;
@@ -2393,6 +2499,12 @@ wait_until_unfixed:
break;
}
}
+ if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
+ }
}
fix_type = MTR_MEMO_BUF_FIX;
@@ -2414,17 +2526,21 @@ wait_until_unfixed:
mtr_memo_push(mtr, block, fix_type);
- if (!accessed) {
+ if (!access_time) {
/* In the case of a first access, try to apply linear
read-ahead */
- buf_read_ahead_linear(space, zip_size, offset);
+ buf_read_ahead_linear(space, zip_size, offset, trx);
}
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0);
#endif
+ if (innobase_get_slow_log()) {
+ _increment_page_get_statistics(block, trx);
+ }
+
return(block);
}
@@ -2444,9 +2560,10 @@ buf_page_optimistic_get_func(
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mini-transaction */
{
- ibool accessed;
+ unsigned access_time;
ibool success;
ulint fix_type;
+ trx_t* trx = NULL;
ut_ad(mtr && block);
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
@@ -2461,14 +2578,16 @@ buf_page_optimistic_get_func(
}
buf_block_buf_fix_inc(block, file, line);
- accessed = buf_page_is_accessed(&block->page);
- buf_page_set_accessed(&block->page, TRUE);
mutex_exit(&block->mutex);
- buf_block_make_young(&block->page);
+ /* Check if this is the first access to the page.
+ We do a dirty read on purpose, to avoid mutex contention.
+ This field is only used for heuristic purposes; it does not
+ affect correctness. */
- /* Check if this is the first access to the page */
+ access_time = buf_page_is_accessed(&block->page);
+ buf_page_set_accessed_make_young(&block->page, access_time);
ut_ad(!ibuf_inside()
|| ibuf_page(buf_block_get_space(block),
@@ -2520,21 +2639,28 @@ buf_page_optimistic_get_func(
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->page.file_page_was_freed == FALSE);
#endif
- if (UNIV_UNLIKELY(!accessed)) {
+ if (innobase_get_slow_log()) {
+ trx = innobase_get_trx();
+ }
+
+ if (UNIV_UNLIKELY(!access_time)) {
/* In the case of a first access, try to apply linear
read-ahead */
buf_read_ahead_linear(buf_block_get_space(block),
buf_block_get_zip_size(block),
- buf_block_get_page_no(block));
+ buf_block_get_page_no(block), trx);
}
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0);
#endif
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
+ if (innobase_get_slow_log()) {
+ _increment_page_get_statistics(block, trx);
+ }
return(TRUE);
}
@@ -2556,6 +2682,7 @@ buf_page_get_known_nowait(
{
ibool success;
ulint fix_type;
+ trx_t* trx = NULL;
ut_ad(mtr);
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
@@ -2581,8 +2708,24 @@ buf_page_get_known_nowait(
mutex_exit(&block->mutex);
- if (mode == BUF_MAKE_YOUNG) {
- buf_block_make_young(&block->page);
+ if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
+ //buf_pool_mutex_enter();
+ mutex_enter(&LRU_list_mutex);
+ buf_LRU_make_block_young(&block->page);
+ //buf_pool_mutex_exit();
+ mutex_exit(&LRU_list_mutex);
+ } else if (!buf_page_is_accessed(&block->page)) {
+ /* Above, we do a dirty read on purpose, to avoid
+ mutex contention. The field buf_page_t::access_time
+ is only used for heuristic purposes. Writes to the
+ field must be protected by mutex, however. */
+ ulint time_ms = ut_time_ms();
+
+ //buf_pool_mutex_enter();
+ mutex_enter(&block->mutex);
+ buf_page_set_accessed(&block->page, time_ms);
+ //buf_pool_mutex_exit();
+ mutex_exit(&block->mutex);
}
ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
@@ -2621,7 +2764,12 @@ buf_page_get_known_nowait(
|| (ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0));
#endif
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
+
+ if (innobase_get_slow_log()) {
+ trx = innobase_get_trx();
+ _increment_page_get_statistics(block, trx);
+ }
return(TRUE);
}
@@ -2700,7 +2848,7 @@ buf_page_try_get_func(
#endif /* UNIV_DEBUG_FILE_ACCESSES */
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(buf_block_get_space(block),
@@ -2719,10 +2867,10 @@ buf_page_init_low(
buf_page_t* bpage) /*!< in: block to init */
{
bpage->flush_type = BUF_FLUSH_LRU;
- bpage->accessed = FALSE;
bpage->io_fix = BUF_IO_NONE;
bpage->buf_fix_count = 0;
bpage->freed_page_clock = 0;
+ bpage->access_time = 0;
bpage->newest_modification = 0;
bpage->oldest_modification = 0;
HASH_INVALIDATE(bpage, hash);
@@ -3044,6 +3192,7 @@ buf_page_create(
buf_frame_t* frame;
buf_block_t* block;
buf_block_t* free_block = NULL;
+ ulint time_ms = ut_time_ms();
ut_ad(mtr);
ut_ad(space || !zip_size);
@@ -3095,7 +3244,7 @@ buf_page_create(
buf_LRU_add_block(&block->page, FALSE);
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
- buf_pool->n_pages_created++;
+ buf_pool->stat.n_pages_created++;
if (zip_size) {
void* data;
@@ -3132,13 +3281,13 @@ buf_page_create(
rw_lock_x_unlock(&block->lock);
}
+ buf_page_set_accessed(&block->page, time_ms);
+
//buf_pool_mutex_exit();
mutex_exit(&LRU_list_mutex);
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
- buf_page_set_accessed(&block->page, TRUE);
-
mutex_exit(&block->mutex);
/* Delete possible entries for the page from the insert buffer:
@@ -3355,7 +3504,7 @@ corrupt:
ut_ad(buf_pool->n_pend_reads > 0);
buf_pool->n_pend_reads--;
- buf_pool->n_pages_read++;
+ buf_pool->stat.n_pages_read++;
if (uncompressed) {
rw_lock_x_unlock_gen(&((buf_block_t*) bpage)->lock,
@@ -3380,7 +3529,7 @@ corrupt:
BUF_IO_WRITE);
}
- buf_pool->n_pages_written++;
+ buf_pool->stat.n_pages_written++;
break;
@@ -3411,7 +3560,32 @@ void
buf_pool_invalidate(void)
/*=====================*/
{
- ibool freed;
+ ibool freed;
+ enum buf_flush i;
+
+ buf_pool_mutex_enter();
+
+ for (i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; i++) {
+
+ /* As this function is called during startup and
+ during redo application phase during recovery, InnoDB
+ is single threaded (apart from IO helper threads) at
+ this stage. No new write batch can be in intialization
+ stage at this point. */
+ ut_ad(buf_pool->init_flush[i] == FALSE);
+
+ /* However, it is possible that a write batch that has
+ been posted earlier is still not complete. For buffer
+ pool invalidation to proceed we must ensure there is NO
+ write activity happening. */
+ if (buf_pool->n_flush[i] > 0) {
+ buf_pool_mutex_exit();
+ buf_flush_wait_batch_end(i);
+ buf_pool_mutex_enter();
+ }
+ }
+
+ buf_pool_mutex_exit();
ut_ad(buf_all_freed());
@@ -3427,6 +3601,14 @@ buf_pool_invalidate(void)
ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
+ buf_pool->freed_page_clock = 0;
+ buf_pool->LRU_old = NULL;
+ buf_pool->LRU_old_len = 0;
+ buf_pool->LRU_flush_ended = 0;
+
+ memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
+ buf_refresh_io_stats();
+
//buf_pool_mutex_exit();
mutex_exit(&LRU_list_mutex);
}
@@ -3706,6 +3888,7 @@ buf_print(void)
"n pending decompressions %lu\n"
"n pending reads %lu\n"
"n pending flush LRU %lu list %lu single page %lu\n"
+ "pages made young %lu, not young %lu\n"
"pages read %lu, created %lu, written %lu\n",
(ulong) size,
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
@@ -3716,8 +3899,11 @@ buf_print(void)
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU],
(ulong) buf_pool->n_flush[BUF_FLUSH_LIST],
(ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE],
- (ulong) buf_pool->n_pages_read, buf_pool->n_pages_created,
- (ulong) buf_pool->n_pages_written);
+ (ulong) buf_pool->stat.n_pages_made_young,
+ (ulong) buf_pool->stat.n_pages_not_made_young,
+ (ulong) buf_pool->stat.n_pages_read,
+ (ulong) buf_pool->stat.n_pages_created,
+ (ulong) buf_pool->stat.n_pages_written);
/* Count the number of blocks belonging to each index in the buffer */
@@ -3927,10 +4113,9 @@ buf_print_io(
{
time_t current_time;
double time_elapsed;
- ulint size;
+ ulint n_gets_diff;
ut_ad(buf_pool);
- size = buf_pool->curr_size;
//buf_pool_mutex_enter();
mutex_enter(&LRU_list_mutex);
@@ -3943,13 +4128,15 @@ buf_print_io(
"Buffer pool size, bytes %lu\n"
"Free buffers %lu\n"
"Database pages %lu\n"
+ "Old database pages %lu\n"
"Modified db pages %lu\n"
"Pending reads %lu\n"
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
- (ulong) size,
- (ulong) size * UNIV_PAGE_SIZE,
+ (ulong) buf_pool->curr_size,
+ (ulong) buf_pool->curr_size * UNIV_PAGE_SIZE,
(ulong) UT_LIST_GET_LEN(buf_pool->free),
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
+ (ulong) buf_pool->LRU_old_len,
(ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
(ulong) buf_pool->n_pend_reads,
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU]
@@ -3961,37 +4148,66 @@ buf_print_io(
current_time = time(NULL);
time_elapsed = 0.001 + difftime(current_time,
buf_pool->last_printout_time);
- buf_pool->last_printout_time = current_time;
fprintf(file,
+ "Pages made young %lu, not young %lu\n"
+ "%.2f youngs/s, %.2f non-youngs/s\n"
"Pages read %lu, created %lu, written %lu\n"
"%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
- (ulong) buf_pool->n_pages_read,
- (ulong) buf_pool->n_pages_created,
- (ulong) buf_pool->n_pages_written,
- (buf_pool->n_pages_read - buf_pool->n_pages_read_old)
+ (ulong) buf_pool->stat.n_pages_made_young,
+ (ulong) buf_pool->stat.n_pages_not_made_young,
+ (buf_pool->stat.n_pages_made_young
+ - buf_pool->old_stat.n_pages_made_young)
+ / time_elapsed,
+ (buf_pool->stat.n_pages_not_made_young
+ - buf_pool->old_stat.n_pages_not_made_young)
/ time_elapsed,
- (buf_pool->n_pages_created - buf_pool->n_pages_created_old)
+ (ulong) buf_pool->stat.n_pages_read,
+ (ulong) buf_pool->stat.n_pages_created,
+ (ulong) buf_pool->stat.n_pages_written,
+ (buf_pool->stat.n_pages_read
+ - buf_pool->old_stat.n_pages_read)
/ time_elapsed,
- (buf_pool->n_pages_written - buf_pool->n_pages_written_old)
+ (buf_pool->stat.n_pages_created
+ - buf_pool->old_stat.n_pages_created)
+ / time_elapsed,
+ (buf_pool->stat.n_pages_written
+ - buf_pool->old_stat.n_pages_written)
/ time_elapsed);
- if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
- fprintf(file, "Buffer pool hit rate %lu / 1000\n",
+ n_gets_diff = buf_pool->stat.n_page_gets - buf_pool->old_stat.n_page_gets;
+
+ if (n_gets_diff) {
+ fprintf(file,
+ "Buffer pool hit rate %lu / 1000,"
+ " young-making rate %lu / 1000 not %lu / 1000\n",
(ulong)
- (1000 - ((1000 * (buf_pool->n_pages_read
- - buf_pool->n_pages_read_old))
- / (buf_pool->n_page_gets
- - buf_pool->n_page_gets_old))));
+ (1000 - ((1000 * (buf_pool->stat.n_pages_read
+ - buf_pool->old_stat.n_pages_read))
+ / (buf_pool->stat.n_page_gets
+ - buf_pool->old_stat.n_page_gets))),
+ (ulong)
+ (1000 * (buf_pool->stat.n_pages_made_young
+ - buf_pool->old_stat.n_pages_made_young)
+ / n_gets_diff),
+ (ulong)
+ (1000 * (buf_pool->stat.n_pages_not_made_young
+ - buf_pool->old_stat.n_pages_not_made_young)
+ / n_gets_diff));
} else {
fputs("No buffer pool page gets since the last printout\n",
file);
}
- buf_pool->n_page_gets_old = buf_pool->n_page_gets;
- buf_pool->n_pages_read_old = buf_pool->n_pages_read;
- buf_pool->n_pages_created_old = buf_pool->n_pages_created;
- buf_pool->n_pages_written_old = buf_pool->n_pages_written;
+ /* Statistics about read ahead algorithm */
+ fprintf(file, "Pages read ahead %.2f/s,"
+ " evicted without access %.2f/s\n",
+ (buf_pool->stat.n_ra_pages_read
+ - buf_pool->old_stat.n_ra_pages_read)
+ / time_elapsed,
+ (buf_pool->stat.n_ra_pages_evicted
+ - buf_pool->old_stat.n_ra_pages_evicted)
+ / time_elapsed);
/* Print some values to help us with visualizing what is
happening with LRU eviction. */
@@ -4003,6 +4219,7 @@ buf_print_io(
buf_LRU_stat_sum.io, buf_LRU_stat_cur.io,
buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
+ buf_refresh_io_stats();
//buf_pool_mutex_exit();
mutex_exit(&LRU_list_mutex);
mutex_exit(&free_list_mutex);
@@ -4018,10 +4235,7 @@ buf_refresh_io_stats(void)
/*======================*/
{
buf_pool->last_printout_time = time(NULL);
- buf_pool->n_page_gets_old = buf_pool->n_page_gets;
- buf_pool->n_pages_read_old = buf_pool->n_pages_read;
- buf_pool->n_pages_created_old = buf_pool->n_pages_created;
- buf_pool->n_pages_written_old = buf_pool->n_pages_written;
+ buf_pool->old_stat = buf_pool->stat;
}
/*********************************************************************//**
=== modified file 'storage/xtradb/buf/buf0flu.c'
--- a/storage/xtradb/buf/buf0flu.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/buf/buf0flu.c 2010-01-15 15:58:25 +0000
@@ -331,6 +331,28 @@ buf_flush_write_complete(
}
/********************************************************************//**
+Flush a batch of writes to the datafiles that have already been
+written by the OS. */
+static
+void
+buf_flush_sync_datafiles(void)
+/*==========================*/
+{
+ /* Wake possible simulated aio thread to actually post the
+ writes to the operating system */
+ os_aio_simulated_wake_handler_threads();
+
+ /* Wait that all async writes to tablespaces have been posted to
+ the OS */
+ os_aio_wait_until_no_pending_writes();
+
+ /* Now we flush the data to disk (for example, with fsync) */
+ fil_flush_file_spaces(FIL_TABLESPACE);
+
+ return;
+}
+
+/********************************************************************//**
Flushes possible buffered writes from the doublewrite memory buffer to disk,
and also wakes up the aio thread if simulated aio is used. It is very
important to call this function after a batch of writes has been posted,
@@ -347,8 +369,8 @@ buf_flush_buffered_writes(void)
ulint i;
if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) {
- os_aio_simulated_wake_handler_threads();
-
+ /* Sync the writes to the disk. */
+ buf_flush_sync_datafiles();
return;
}
@@ -556,22 +578,10 @@ flush:
buf_LRU_stat_inc_io();
}
- /* Wake possible simulated aio thread to actually post the
- writes to the operating system */
-
- os_aio_simulated_wake_handler_threads();
-
- /* Wait that all async writes to tablespaces have been posted to
- the OS */
-
- os_aio_wait_until_no_pending_writes();
-
- /* Now we flush the data to disk (for example, with fsync) */
-
- fil_flush_file_spaces(FIL_TABLESPACE);
+ /* Sync the writes to the disk. */
+ buf_flush_sync_datafiles();
/* We can now reuse the doublewrite memory buffer: */
-
trx_doublewrite->first_free = 0;
mutex_exit(&(trx_doublewrite->mutex));
@@ -994,9 +1004,7 @@ buf_flush_try_neighbors(
|| buf_page_is_old(bpage)) {
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
- ut_a(block_mutex);
-
- if (buf_flush_ready_for_flush(bpage, flush_type)
+ if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)
&& (i == offset || !bpage->buf_fix_count)) {
/* We only try to flush those
neighbors != offset where the buf fix count is
@@ -1012,7 +1020,7 @@ buf_flush_try_neighbors(
//buf_pool_mutex_enter();
rw_lock_s_lock(&page_hash_latch);
- } else {
+ } else if (block_mutex) {
mutex_exit(block_mutex);
}
}
@@ -1050,6 +1058,7 @@ buf_flush_batch(
min_n), otherwise ignored */
{
buf_page_t* bpage;
+ buf_page_t* prev_bpage = NULL;
ulint page_count = 0;
ulint old_page_count;
ulint space;
@@ -1103,6 +1112,9 @@ flush_next:
mutex_enter(&flush_list_mutex);
remaining = UT_LIST_GET_LEN(buf_pool->flush_list);
bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
+ if (bpage) {
+ prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
+ }
mutex_exit(&flush_list_mutex);
if (!bpage
|| bpage->oldest_modification >= lsn_limit) {
@@ -1123,11 +1135,14 @@ flush_next:
mutex_t*block_mutex = buf_page_get_mutex_enter(bpage);
ibool ready;
- ut_a(buf_page_in_file(bpage));
+ //ut_a(buf_page_in_file(bpage));
- ut_a(block_mutex);
- ready = buf_flush_ready_for_flush(bpage, flush_type);
- mutex_exit(block_mutex);
+ if (block_mutex) {
+ ready = buf_flush_ready_for_flush(bpage, flush_type);
+ mutex_exit(block_mutex);
+ } else {
+ ready = FALSE;
+ }
if (ready) {
space = buf_page_get_space(bpage);
@@ -1162,6 +1177,13 @@ flush_next:
mutex_enter(&flush_list_mutex);
bpage = UT_LIST_GET_PREV(flush_list, bpage);
//ut_ad(!bpage || bpage->in_flush_list); /* optimistic */
+ if (bpage != prev_bpage) {
+ /* the search may warp.. retrying */
+ bpage = NULL;
+ }
+ if (bpage) {
+ prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
+ }
mutex_exit(&flush_list_mutex);
remaining--;
}
@@ -1271,13 +1293,13 @@ buf_flush_LRU_recommendation(void)
}
block_mutex = buf_page_get_mutex_enter(bpage);
- ut_a(block_mutex);
-
- if (buf_flush_ready_for_replace(bpage)) {
+ if (block_mutex && buf_flush_ready_for_replace(bpage)) {
n_replaceable++;
}
- mutex_exit(block_mutex);
+ if (block_mutex) {
+ mutex_exit(block_mutex);
+ }
distance++;
=== modified file 'storage/xtradb/buf/buf0lru.c'
--- a/storage/xtradb/buf/buf0lru.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/buf/buf0lru.c 2010-01-06 12:00:14 +0000
@@ -49,18 +49,22 @@ Created 11/5/1995 Heikki Tuuri
#include "log0recv.h"
#include "srv0srv.h"
-/** The number of blocks from the LRU_old pointer onward, including the block
-pointed to, must be 3/8 of the whole LRU list length, except that the
-tolerance defined below is allowed. Note that the tolerance must be small
-enough such that for even the BUF_LRU_OLD_MIN_LEN long LRU list, the
-LRU_old pointer is not allowed to point to either end of the LRU list. */
+/** The number of blocks from the LRU_old pointer onward, including
+the block pointed to, must be buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
+of the whole LRU list length, except that the tolerance defined below
+is allowed. Note that the tolerance must be small enough such that for
+even the BUF_LRU_OLD_MIN_LEN long LRU list, the LRU_old pointer is not
+allowed to point to either end of the LRU list. */
#define BUF_LRU_OLD_TOLERANCE 20
-/** The whole LRU list length is divided by this number to determine an
-initial segment in buf_LRU_get_recent_limit */
-
-#define BUF_LRU_INITIAL_RATIO 8
+/** The minimum amount of non-old blocks when the LRU_old list exists
+(that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks).
+@see buf_LRU_old_adjust_len */
+#define BUF_LRU_NON_OLD_MIN_LEN 5
+#if BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN
+# error "BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN"
+#endif
/** When dropping the search hash index entries before deleting an ibd
file, we build a local array of pages belonging to that tablespace
@@ -107,6 +111,15 @@ UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_
/* @} */
+/** @name Heuristics for detecting index scan @{ */
+/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
+"old" blocks. Protected by buf_pool_mutex. */
+UNIV_INTERN uint buf_LRU_old_ratio;
+/** Move blocks to "new" LRU list only if the first access was at
+least this many milliseconds ago. Not protected by any mutex or latch. */
+UNIV_INTERN uint buf_LRU_old_threshold_ms;
+/* @} */
+
/******************************************************************//**
Takes a block out of the LRU list and page hash table.
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
@@ -255,9 +268,12 @@ scan_again:
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
buf_page_t* prev_bpage;
- ut_a(block_mutex);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
+ if (!block_mutex) {
+ goto next_page;
+ }
+
ut_a(buf_page_in_file(bpage));
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
@@ -360,9 +376,13 @@ scan_again:
ut_a(buf_page_in_file(bpage));
- ut_a(block_mutex);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
+ if (!block_mutex) {
+ bpage = prev_bpage;
+ continue;
+ }
+
if (buf_page_get_space(bpage) == id) {
if (bpage->buf_fix_count > 0
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
@@ -450,45 +470,6 @@ next_page:
}
}
-/******************************************************************//**
-Gets the minimum LRU_position field for the blocks in an initial segment
-(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around.
-@return the limit; zero if could not determine it */
-UNIV_INTERN
-ulint
-buf_LRU_get_recent_limit(void)
-/*==========================*/
-{
- const buf_page_t* bpage;
- ulint len;
- ulint limit;
-
- //buf_pool_mutex_enter();
- mutex_enter(&LRU_list_mutex);
-
- len = UT_LIST_GET_LEN(buf_pool->LRU);
-
- if (len < BUF_LRU_OLD_MIN_LEN) {
- /* The LRU list is too short to do read-ahead */
-
- //buf_pool_mutex_exit();
- mutex_exit(&LRU_list_mutex);
-
- return(0);
- }
-
- bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-
- limit = buf_page_get_LRU_position(bpage);
- len /= BUF_LRU_INITIAL_RATIO;
-
- //buf_pool_mutex_exit();
- mutex_exit(&LRU_list_mutex);
-
- return(limit > len ? (limit - len) : 0);
-}
-
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
@@ -631,10 +612,13 @@ restart:
bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
enum buf_lru_free_block_status freed;
+ unsigned accessed;
mutex_t* block_mutex
= buf_page_get_mutex_enter(bpage);
- ut_a(block_mutex);
+ if (!block_mutex) {
+ goto restart;
+ }
if (!bpage->in_LRU_list
|| !buf_page_in_file(bpage)) {
@@ -645,11 +629,18 @@ restart:
ut_ad(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
+ accessed = buf_page_is_accessed(bpage);
freed = buf_LRU_free_block(bpage, TRUE, NULL, have_LRU_mutex);
mutex_exit(block_mutex);
switch (freed) {
case BUF_LRU_FREED:
+ /* Keep track of pages that are evicted without
+ ever being accessed. This gives us a measure of
+ the effectiveness of readahead */
+ if (!accessed) {
+ ++buf_pool->stat.n_ra_pages_evicted;
+ }
return(TRUE);
case BUF_LRU_NOT_FREED:
@@ -1027,8 +1018,10 @@ buf_LRU_old_adjust_len(void)
ut_a(buf_pool->LRU_old);
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&LRU_list_mutex));
-#if 3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5
-# error "3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5"
+ ut_ad(buf_LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
+ ut_ad(buf_LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
+#if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
+# error "BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)"
#endif
#ifdef UNIV_LRU_DEBUG
/* buf_pool->LRU_old must be the first item in the LRU list
@@ -1040,34 +1033,39 @@ buf_LRU_old_adjust_len(void)
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
#endif /* UNIV_LRU_DEBUG */
+ old_len = buf_pool->LRU_old_len;
+ new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
+ * buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
+ UT_LIST_GET_LEN(buf_pool->LRU)
+ - (BUF_LRU_OLD_TOLERANCE
+ + BUF_LRU_NON_OLD_MIN_LEN));
+
for (;;) {
- old_len = buf_pool->LRU_old_len;
- new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
+ buf_page_t* LRU_old = buf_pool->LRU_old;
- ut_ad(buf_pool->LRU_old->in_LRU_list);
- ut_a(buf_pool->LRU_old);
+ ut_a(LRU_old);
+ ut_ad(LRU_old->in_LRU_list);
#ifdef UNIV_LRU_DEBUG
- ut_a(buf_pool->LRU_old->old);
+ ut_a(LRU_old->old);
#endif /* UNIV_LRU_DEBUG */
/* Update the LRU_old pointer if necessary */
- if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) {
+ if (old_len + BUF_LRU_OLD_TOLERANCE < new_len) {
- buf_pool->LRU_old = UT_LIST_GET_PREV(
- LRU, buf_pool->LRU_old);
+ buf_pool->LRU_old = LRU_old = UT_LIST_GET_PREV(
+ LRU, LRU_old);
#ifdef UNIV_LRU_DEBUG
- ut_a(!buf_pool->LRU_old->old);
+ ut_a(!LRU_old->old);
#endif /* UNIV_LRU_DEBUG */
- buf_page_set_old(buf_pool->LRU_old, TRUE);
- buf_pool->LRU_old_len++;
+ old_len = ++buf_pool->LRU_old_len;
+ buf_page_set_old(LRU_old, TRUE);
} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
- buf_page_set_old(buf_pool->LRU_old, FALSE);
- buf_pool->LRU_old = UT_LIST_GET_NEXT(
- LRU, buf_pool->LRU_old);
- buf_pool->LRU_old_len--;
+ buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU, LRU_old);
+ old_len = --buf_pool->LRU_old_len;
+ buf_page_set_old(LRU_old, FALSE);
} else {
return;
}
@@ -1092,12 +1090,13 @@ buf_LRU_old_init(void)
the adjust function to move the LRU_old pointer to the right
position */
- bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-
- while (bpage != NULL) {
+ for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage != NULL;
+ bpage = UT_LIST_GET_PREV(LRU, bpage)) {
ut_ad(bpage->in_LRU_list);
- buf_page_set_old(bpage, TRUE);
- bpage = UT_LIST_GET_NEXT(LRU, bpage);
+ ut_ad(buf_page_in_file(bpage));
+ /* This loop temporarily violates the
+ assertions of buf_page_set_old(). */
+ bpage->old = TRUE;
}
buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU);
@@ -1152,16 +1151,19 @@ buf_LRU_remove_block(
if (UNIV_UNLIKELY(bpage == buf_pool->LRU_old)) {
- /* Below: the previous block is guaranteed to exist, because
- the LRU_old pointer is only allowed to differ by the
- tolerance value from strict 3/8 of the LRU list length. */
+ /* Below: the previous block is guaranteed to exist,
+ because the LRU_old pointer is only allowed to differ
+ by BUF_LRU_OLD_TOLERANCE from strict
+ buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV of the LRU
+ list length. */
+ buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
- buf_pool->LRU_old = UT_LIST_GET_PREV(LRU, bpage);
- ut_a(buf_pool->LRU_old);
+ ut_a(prev_bpage);
#ifdef UNIV_LRU_DEBUG
- ut_a(!buf_pool->LRU_old->old);
+ ut_a(!prev_bpage->old);
#endif /* UNIV_LRU_DEBUG */
- buf_page_set_old(buf_pool->LRU_old, TRUE);
+ buf_pool->LRU_old = prev_bpage;
+ buf_page_set_old(prev_bpage, TRUE);
buf_pool->LRU_old_len++;
}
@@ -1172,10 +1174,19 @@ buf_LRU_remove_block(
buf_unzip_LRU_remove_block_if_needed(bpage);
- /* If the LRU list is so short that LRU_old not defined, return */
+ /* If the LRU list is so short that LRU_old is not defined,
+ clear the "old" flags and return */
if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
+ for (bpage = UT_LIST_GET_FIRST(buf_pool->LRU); bpage != NULL;
+ bpage = UT_LIST_GET_NEXT(LRU, bpage)) {
+ /* This loop temporarily violates the
+ assertions of buf_page_set_old(). */
+ bpage->old = FALSE;
+ }
+
buf_pool->LRU_old = NULL;
+ buf_pool->LRU_old_len = 0;
return;
}
@@ -1227,8 +1238,6 @@ buf_LRU_add_block_to_end_low(
/*=========================*/
buf_page_t* bpage) /*!< in: control block */
{
- buf_page_t* last_bpage;
-
ut_ad(buf_pool);
ut_ad(bpage);
//ut_ad(buf_pool_mutex_own());
@@ -1236,31 +1245,18 @@ buf_LRU_add_block_to_end_low(
ut_a(buf_page_in_file(bpage));
- last_bpage = UT_LIST_GET_LAST(buf_pool->LRU);
-
- if (last_bpage) {
- bpage->LRU_position = last_bpage->LRU_position;
- } else {
- bpage->LRU_position = buf_pool_clock_tic();
- }
-
ut_ad(!bpage->in_LRU_list);
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
bpage->in_LRU_list = TRUE;
- buf_page_set_old(bpage, TRUE);
-
- if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
-
- buf_pool->LRU_old_len++;
- }
-
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
/* Adjust the length of the old block list if necessary */
+ buf_page_set_old(bpage, TRUE);
+ buf_pool->LRU_old_len++;
buf_LRU_old_adjust_len();
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
@@ -1269,6 +1265,8 @@ buf_LRU_add_block_to_end_low(
defined: init it */
buf_LRU_old_init();
+ } else {
+ buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
}
/* If this is a zipped block with decompressed frame as well
@@ -1302,7 +1300,6 @@ buf_LRU_add_block_low(
UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
- bpage->LRU_position = buf_pool_clock_tic();
bpage->freed_page_clock = buf_pool->freed_page_clock;
} else {
#ifdef UNIV_LRU_DEBUG
@@ -1317,23 +1314,17 @@ buf_LRU_add_block_low(
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
bpage);
buf_pool->LRU_old_len++;
-
- /* We copy the LRU position field of the previous block
- to the new block */
-
- bpage->LRU_position = (buf_pool->LRU_old)->LRU_position;
}
bpage->in_LRU_list = TRUE;
- buf_page_set_old(bpage, old);
-
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
/* Adjust the length of the old block list if necessary */
+ buf_page_set_old(bpage, old);
buf_LRU_old_adjust_len();
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
@@ -1342,6 +1333,8 @@ buf_LRU_add_block_low(
defined: init it */
buf_LRU_old_init();
+ } else {
+ buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
}
/* If this is a zipped block with decompressed frame as well
@@ -1375,6 +1368,13 @@ buf_LRU_make_block_young(
/*=====================*/
buf_page_t* bpage) /*!< in: control block */
{
+ //ut_ad(buf_pool_mutex_own());
+ ut_ad(mutex_own(&LRU_list_mutex));
+
+ if (bpage->old) {
+ buf_pool->stat.n_pages_made_young++;
+ }
+
buf_LRU_remove_block(bpage);
buf_LRU_add_block_low(bpage, FALSE);
}
@@ -1571,15 +1571,6 @@ not_freed:
buf_pool->LRU_old = b;
}
-#ifdef UNIV_LRU_DEBUG
- ut_a(prev_b->old
- || !UT_LIST_GET_NEXT(LRU, b)
- || UT_LIST_GET_NEXT(LRU, b)->old);
- } else {
- ut_a(!prev_b->old
- || !UT_LIST_GET_NEXT(LRU, b)
- || !UT_LIST_GET_NEXT(LRU, b)->old);
-#endif /* UNIV_LRU_DEBUG */
}
lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
@@ -1595,6 +1586,11 @@ not_freed:
defined: init it */
buf_LRU_old_init();
}
+#ifdef UNIV_LRU_DEBUG
+ /* Check that the "old" flag is consistent
+ in the block and its neighbours. */
+ buf_page_set_old(b, buf_page_is_old(b));
+#endif /* UNIV_LRU_DEBUG */
} else {
b->in_LRU_list = FALSE;
buf_LRU_add_block_low(b, buf_page_is_old(b));
@@ -1985,6 +1981,52 @@ buf_LRU_block_free_hashed_page(
buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
}
+/**********************************************************************//**
+Updates buf_LRU_old_ratio.
+@return updated old_pct */
+UNIV_INTERN
+uint
+buf_LRU_old_ratio_update(
+/*=====================*/
+ uint old_pct,/*!< in: Reserve this percentage of
+ the buffer pool for "old" blocks. */
+ ibool adjust) /*!< in: TRUE=adjust the LRU list;
+ FALSE=just assign buf_LRU_old_ratio
+ during the initialization of InnoDB */
+{
+ uint ratio;
+
+ ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100;
+ if (ratio < BUF_LRU_OLD_RATIO_MIN) {
+ ratio = BUF_LRU_OLD_RATIO_MIN;
+ } else if (ratio > BUF_LRU_OLD_RATIO_MAX) {
+ ratio = BUF_LRU_OLD_RATIO_MAX;
+ }
+
+ if (adjust) {
+ //buf_pool_mutex_enter();
+ mutex_enter(&LRU_list_mutex);
+
+ if (ratio != buf_LRU_old_ratio) {
+ buf_LRU_old_ratio = ratio;
+
+ if (UT_LIST_GET_LEN(buf_pool->LRU)
+ >= BUF_LRU_OLD_MIN_LEN) {
+ buf_LRU_old_adjust_len();
+ }
+ }
+
+ //buf_pool_mutex_exit();
+ mutex_exit(&LRU_list_mutex);
+ } else {
+ buf_LRU_old_ratio = ratio;
+ }
+
+ /* the reverse of
+ ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100 */
+ return((uint) (ratio * 100 / (double) BUF_LRU_OLD_RATIO_DIV + 0.5));
+}
+
/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
@@ -2023,6 +2065,218 @@ func_exit:
memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
}
+/********************************************************************//**
+Dump the LRU page list to the specific file. */
+#define LRU_DUMP_FILE "ib_lru_dump"
+
+UNIV_INTERN
+ibool
+buf_LRU_file_dump(void)
+/*===================*/
+{
+ os_file_t dump_file = -1;
+ ibool success;
+ byte* buffer_base = NULL;
+ byte* buffer = NULL;
+ buf_page_t* bpage;
+ ulint buffers;
+ ulint offset;
+ ibool ret = FALSE;
+ ulint i;
+
+ for (i = 0; i < srv_n_data_files; i++) {
+ if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
+ fprintf(stderr,
+ " InnoDB: The name '%s' seems to be used for"
+ " innodb_data_file_path. Dumping LRU list is not"
+ " done for safeness.\n", LRU_DUMP_FILE);
+ goto end;
+ }
+ }
+
+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
+ if (!buffer) {
+ fprintf(stderr,
+ " InnoDB: cannot allocate buffer.\n");
+ goto end;
+ }
+
+ dump_file = os_file_create(LRU_DUMP_FILE, OS_FILE_OVERWRITE,
+ OS_FILE_NORMAL, OS_DATA_FILE, &success);
+ if (!success) {
+ os_file_get_last_error(TRUE);
+ fprintf(stderr,
+ " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
+ goto end;
+ }
+
+ mutex_enter(&LRU_list_mutex);
+ bpage = UT_LIST_GET_LAST(buf_pool->LRU);
+
+ buffers = offset = 0;
+ while (bpage != NULL) {
+ if (offset == 0) {
+ memset(buffer, 0, UNIV_PAGE_SIZE);
+ }
+
+ mach_write_to_4(buffer + offset * 4, bpage->space);
+ offset++;
+ mach_write_to_4(buffer + offset * 4, bpage->offset);
+ offset++;
+
+ if (offset == UNIV_PAGE_SIZE/4) {
+ success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
+ UNIV_PAGE_SIZE);
+ if (!success) {
+ mutex_exit(&LRU_list_mutex);
+ fprintf(stderr,
+ " InnoDB: cannot write page %lu of %s\n",
+ buffers, LRU_DUMP_FILE);
+ goto end;
+ }
+ buffers++;
+ offset = 0;
+ }
+
+ bpage = UT_LIST_GET_PREV(LRU, bpage);
+ }
+ mutex_exit(&LRU_list_mutex);
+
+ if (offset == 0) {
+ memset(buffer, 0, UNIV_PAGE_SIZE);
+ }
+
+ mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
+ offset++;
+ mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
+ offset++;
+
+ success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
+ UNIV_PAGE_SIZE);
+ if (!success) {
+ goto end;
+ }
+
+ ret = TRUE;
+end:
+ if (dump_file != -1)
+ os_file_close(dump_file);
+ if (buffer_base)
+ ut_free(buffer_base);
+
+ return(ret);
+}
+/********************************************************************//**
+Read the pages based on the specific file.*/
+UNIV_INTERN
+ibool
+buf_LRU_file_restore(void)
+/*======================*/
+{
+ os_file_t dump_file = -1;
+ ibool success;
+ byte* buffer_base = NULL;
+ byte* buffer = NULL;
+ ulint buffers;
+ ulint offset;
+ ulint reads = 0;
+ ulint req = 0;
+ ibool terminated = FALSE;
+ ibool ret = FALSE;
+
+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
+ if (!buffer) {
+ fprintf(stderr,
+ " InnoDB: cannot allocate buffer.\n");
+ goto end;
+ }
+
+ dump_file = os_file_create_simple_no_error_handling(
+ LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
+ if (!success) {
+ os_file_get_last_error(TRUE);
+ fprintf(stderr,
+ " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
+ goto end;
+ }
+
+ buffers = 0;
+ while (!terminated) {
+ success = os_file_read(dump_file, buffer,
+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
+ UNIV_PAGE_SIZE);
+ if (!success) {
+ fprintf(stderr,
+ " InnoDB: cannot read page %lu of %s,"
+ " or meet unexpected terminal.",
+ buffers, LRU_DUMP_FILE);
+ goto end;
+ }
+
+ for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
+ ulint space_id, zip_size, page_no;
+ ulint err;
+ ib_int64_t tablespace_version;
+
+ space_id = mach_read_from_4(buffer + offset * 4);
+ page_no = mach_read_from_4(buffer + (offset + 1) * 4);
+ if (space_id == 0xFFFFFFFFUL
+ || page_no == 0xFFFFFFFFUL) {
+ terminated = TRUE;
+ break;
+ }
+
+ if (offset % 16 == 15) {
+ os_aio_simulated_wake_handler_threads();
+ buf_flush_free_margin(FALSE);
+ }
+
+ zip_size = fil_space_get_zip_size(space_id);
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
+ continue;
+ }
+
+ if (fil_area_is_exist(space_id, zip_size, page_no, 0,
+ zip_size ? zip_size : UNIV_PAGE_SIZE)) {
+
+ tablespace_version = fil_space_get_version(space_id);
+
+ req++;
+ reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
+ | OS_AIO_SIMULATED_WAKE_LATER,
+ space_id, zip_size, TRUE,
+ tablespace_version, page_no, NULL);
+ buf_LRU_stat_inc_io();
+ }
+ }
+
+ buffers++;
+ }
+
+ os_aio_simulated_wake_handler_threads();
+ buf_flush_free_margin(FALSE);
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: reading pages based on the dumped LRU list was done."
+ " (requested: %lu, read: %lu)\n", req, reads);
+ ret = TRUE;
+end:
+ if (dump_file != -1)
+ os_file_close(dump_file);
+ if (buffer_base)
+ ut_free(buffer_base);
+
+ return(ret);
+}
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************//**
Validates the LRU list.
@@ -2036,7 +2290,6 @@ buf_LRU_validate(void)
buf_block_t* block;
ulint old_len;
ulint new_len;
- ulint LRU_pos;
ut_ad(buf_pool);
//buf_pool_mutex_enter();
@@ -2046,7 +2299,11 @@ buf_LRU_validate(void)
ut_a(buf_pool->LRU_old);
old_len = buf_pool->LRU_old_len;
- new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
+ new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
+ * buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
+ UT_LIST_GET_LEN(buf_pool->LRU)
+ - (BUF_LRU_OLD_TOLERANCE
+ + BUF_LRU_NON_OLD_MIN_LEN));
ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
}
@@ -2077,28 +2334,24 @@ buf_LRU_validate(void)
}
if (buf_page_is_old(bpage)) {
- old_len++;
- }
+ const buf_page_t* prev
+ = UT_LIST_GET_PREV(LRU, bpage);
+ const buf_page_t* next
+ = UT_LIST_GET_NEXT(LRU, bpage);
- if (buf_pool->LRU_old && (old_len == 1)) {
- ut_a(buf_pool->LRU_old == bpage);
- }
+ if (!old_len++) {
+ ut_a(buf_pool->LRU_old == bpage);
+ } else {
+ ut_a(!prev || buf_page_is_old(prev));
+ }
- LRU_pos = buf_page_get_LRU_position(bpage);
+ ut_a(!next || buf_page_is_old(next));
+ }
bpage = UT_LIST_GET_NEXT(LRU, bpage);
-
- if (bpage) {
- /* If the following assert fails, it may
- not be an error: just the buf_pool clock
- has wrapped around */
- ut_a(LRU_pos >= buf_page_get_LRU_position(bpage));
- }
}
- if (buf_pool->LRU_old) {
- ut_a(buf_pool->LRU_old_len == old_len);
- }
+ ut_a(buf_pool->LRU_old_len == old_len);
mutex_exit(&LRU_list_mutex);
mutex_enter(&free_list_mutex);
@@ -2149,9 +2402,6 @@ buf_LRU_print(void)
//buf_pool_mutex_enter();
mutex_enter(&LRU_list_mutex);
- fprintf(stderr, "Pool ulint clock %lu\n",
- (ulong) buf_pool->ulint_clock);
-
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
while (bpage != NULL) {
@@ -2182,18 +2432,16 @@ buf_LRU_print(void)
const byte* frame;
case BUF_BLOCK_FILE_PAGE:
frame = buf_block_get_frame((buf_block_t*) bpage);
- fprintf(stderr, "\nLRU pos %lu type %lu"
+ fprintf(stderr, "\ntype %lu"
" index id %lu\n",
- (ulong) buf_page_get_LRU_position(bpage),
(ulong) fil_page_get_type(frame),
(ulong) ut_dulint_get_low(
btr_page_get_index_id(frame)));
break;
case BUF_BLOCK_ZIP_PAGE:
frame = bpage->zip.data;
- fprintf(stderr, "\nLRU pos %lu type %lu size %lu"
+ fprintf(stderr, "\ntype %lu size %lu"
" index id %lu\n",
- (ulong) buf_page_get_LRU_position(bpage),
(ulong) fil_page_get_type(frame),
(ulong) buf_page_get_zip_size(bpage),
(ulong) ut_dulint_get_low(
@@ -2201,8 +2449,7 @@ buf_LRU_print(void)
break;
default:
- fprintf(stderr, "\nLRU pos %lu !state %lu!\n",
- (ulong) buf_page_get_LRU_position(bpage),
+ fprintf(stderr, "\n!state %lu!\n",
(ulong) buf_page_get_state(bpage));
break;
}
=== modified file 'storage/xtradb/buf/buf0rea.c'
--- a/storage/xtradb/buf/buf0rea.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/buf/buf0rea.c 2010-01-15 15:58:25 +0000
@@ -38,14 +38,6 @@ Created 11/5/1995 Heikki Tuuri
#include "srv0start.h"
#include "srv0srv.h"
-/** The size in blocks of the area where the random read-ahead algorithm counts
-the accessed pages when deciding whether to read-ahead */
-#define BUF_READ_AHEAD_RANDOM_AREA BUF_READ_AHEAD_AREA
-
-/** There must be at least this many pages in buf_pool in the area to start
-a random read-ahead */
-#define BUF_READ_AHEAD_RANDOM_THRESHOLD (1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
-
/** The linear read-ahead area size */
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
@@ -62,8 +54,9 @@ flag is cleared and the x-lock released
@return 1 if a read request was queued, 0 if the page already resided
in buf_pool, or if the page is in the doublewrite buffer blocks in
which case it is never read into the pool, or if the tablespace does
-not exist or is being dropped */
-static
+not exist or is being dropped
+@return 1 if read request is issued. 0 if it is not */
+UNIV_INTERN
ulint
buf_read_page_low(
/*==============*/
@@ -82,7 +75,8 @@ buf_read_page_low(
treat the tablespace as dropped; this is a timestamp we
use to stop dangling page reads from a tablespace
which we have DISCARDed + IMPORTed back */
- ulint offset) /*!< in: page number */
+ ulint offset, /*!< in: page number */
+ trx_t* trx)
{
buf_page_t* bpage;
ulint wake_later;
@@ -183,15 +177,15 @@ not_to_recover:
ut_ad(buf_page_in_file(bpage));
if (zip_size) {
- *err = fil_io(OS_FILE_READ | wake_later,
+ *err = _fil_io(OS_FILE_READ | wake_later,
sync, space, zip_size, offset, 0, zip_size,
- bpage->zip.data, bpage);
+ bpage->zip.data, bpage, trx);
} else {
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
- *err = fil_io(OS_FILE_READ | wake_later,
+ *err = _fil_io(OS_FILE_READ | wake_later,
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
- ((buf_block_t*) bpage)->frame, bpage);
+ ((buf_block_t*) bpage)->frame, bpage, trx);
}
ut_a(*err == DB_SUCCESS);
@@ -205,206 +199,33 @@ not_to_recover:
}
/********************************************************************//**
-Applies a random read-ahead in buf_pool if there are at least a threshold
-value of accessed pages from the random read-ahead area. Does not read any
-page, not even the one at the position (space, offset), if the read-ahead
-mechanism is not activated. NOTE 1: the calling thread may own latches on
-pages: to avoid deadlocks this function must be written such that it cannot
-end up waiting for these latches! NOTE 2: the calling thread must want
-access to the page given: this rule is set to prevent unintended read-aheads
-performed by ibuf routines, a situation which could result in a deadlock if
-the OS does not support asynchronous i/o.
-@return number of page read requests issued; NOTE that if we read ibuf
-pages, it may happen that the page at the given page number does not
-get read even if we return a positive value! */
-static
-ulint
-buf_read_ahead_random(
-/*==================*/
- ulint space, /*!< in: space id */
- ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
- ulint offset) /*!< in: page number of a page which the current thread
- wants to access */
-{
- ib_int64_t tablespace_version;
- ulint recent_blocks = 0;
- ulint count;
- ulint LRU_recent_limit;
- ulint ibuf_mode;
- ulint low, high;
- ulint err;
- ulint i;
- ulint buf_read_ahead_random_area;
-
-// /* We have currently disabled random readahead */
-// return(0);
-
- if (!(srv_read_ahead & 1)) {
- return(0);
- }
-
- if (srv_startup_is_before_trx_rollback_phase) {
- /* No read-ahead to avoid thread deadlocks */
- return(0);
- }
-
- if (ibuf_bitmap_page(zip_size, offset)
- || trx_sys_hdr_page(space, offset)) {
-
- /* If it is an ibuf bitmap page or trx sys hdr, we do
- no read-ahead, as that could break the ibuf page access
- order */
-
- return(0);
- }
-
- /* Remember the tablespace version before we ask te tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
-
- tablespace_version = fil_space_get_version(space);
-
- buf_read_ahead_random_area = BUF_READ_AHEAD_RANDOM_AREA;
-
- low = (offset / buf_read_ahead_random_area)
- * buf_read_ahead_random_area;
- high = (offset / buf_read_ahead_random_area + 1)
- * buf_read_ahead_random_area;
- if (high > fil_space_get_size(space)) {
-
- high = fil_space_get_size(space);
- }
-
- /* Get the minimum LRU_position field value for an initial segment
- of the LRU list, to determine which blocks have recently been added
- to the start of the list. */
-
- LRU_recent_limit = buf_LRU_get_recent_limit();
-
- //buf_pool_mutex_enter();
- mutex_enter(&buf_pool_mutex);
-
- if (buf_pool->n_pend_reads
- > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
- //buf_pool_mutex_exit();
- mutex_exit(&buf_pool_mutex);
-
- return(0);
- }
- mutex_exit(&buf_pool_mutex);
-
- /* Count how many blocks in the area have been recently accessed,
- that is, reside near the start of the LRU list. */
-
- rw_lock_s_lock(&page_hash_latch);
- for (i = low; i < high; i++) {
- const buf_page_t* bpage = buf_page_hash_get(space, i);
-
- if (bpage
- && buf_page_is_accessed(bpage)
- && (buf_page_get_LRU_position(bpage) > LRU_recent_limit)) {
-
- recent_blocks++;
-
- if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
-
- //buf_pool_mutex_exit();
- rw_lock_s_unlock(&page_hash_latch);
- goto read_ahead;
- }
- }
- }
-
- //buf_pool_mutex_exit();
- rw_lock_s_unlock(&page_hash_latch);
- /* Do nothing */
- return(0);
-
-read_ahead:
- /* Read all the suitable blocks within the area */
-
- if (ibuf_inside()) {
- ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
- } else {
- ibuf_mode = BUF_READ_ANY_PAGE;
- }
-
- count = 0;
-
- for (i = low; i < high; i++) {
- /* It is only sensible to do read-ahead in the non-sync aio
- mode: hence FALSE as the first parameter */
-
- if (!ibuf_bitmap_page(zip_size, i)) {
- count += buf_read_page_low(
- &err, FALSE,
- ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
- space, zip_size, FALSE,
- tablespace_version, i);
- if (err == DB_TABLESPACE_DELETED) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: in random"
- " readahead trying to access\n"
- "InnoDB: tablespace %lu page %lu,\n"
- "InnoDB: but the tablespace does not"
- " exist or is just being dropped.\n",
- (ulong) space, (ulong) i);
- }
- }
- }
-
- /* In simulated aio we wake the aio handler threads only after
- queuing all aio requests, in native aio the following call does
- nothing: */
-
- os_aio_simulated_wake_handler_threads();
-
-#ifdef UNIV_DEBUG
- if (buf_debug_prints && (count > 0)) {
- fprintf(stderr,
- "Random read-ahead space %lu offset %lu pages %lu\n",
- (ulong) space, (ulong) offset,
- (ulong) count);
- }
-#endif /* UNIV_DEBUG */
-
- ++srv_read_ahead_rnd;
- return(count);
-}
-
-/********************************************************************//**
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible.
-@return number of page read requests issued: this can be greater than
-1 if read-ahead occurred */
+released by the i/o-handler thread.
+@return TRUE if page has been read in, FALSE in case of failure */
UNIV_INTERN
-ulint
+ibool
buf_read_page(
/*==========*/
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
- ulint offset) /*!< in: page number */
+ ulint offset, /*!< in: page number */
+ trx_t* trx)
{
ib_int64_t tablespace_version;
ulint count;
- ulint count2;
ulint err;
tablespace_version = fil_space_get_version(space);
- count = buf_read_ahead_random(space, zip_size, offset);
-
/* We do the i/o in the synchronous aio mode to save thread
switches: hence TRUE */
- count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
- zip_size, FALSE,
- tablespace_version, offset);
- srv_buf_pool_reads+= count2;
+ count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
+ zip_size, FALSE,
+ tablespace_version, offset, trx);
+ srv_buf_pool_reads += count;
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -421,14 +242,14 @@ buf_read_page(
/* Increment number of I/O operations used for LRU policy. */
buf_LRU_stat_inc_io();
- return(count + count2);
+ return(count > 0);
}
/********************************************************************//**
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
-that the the algorithm looks at the 'natural' adjacent successor and
+that the algorithm looks at the 'natural' adjacent successor and
predecessor of the page, which on the leaf level of a B-tree are the next
and previous page in the chain of leaves. To know these, the page specified
in (space, offset) must already be present in the buf_pool. Thus, the
@@ -454,8 +275,9 @@ buf_read_ahead_linear(
/*==================*/
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
- ulint offset) /*!< in: page number of a page; NOTE: the current thread
+ ulint offset, /*!< in: page number of a page; NOTE: the current thread
must want access to this page (see NOTE 3 above) */
+ trx_t* trx)
{
ib_int64_t tablespace_version;
buf_page_t* bpage;
@@ -557,9 +379,17 @@ buf_read_ahead_linear(
fail_count++;
} else if (pred_bpage) {
- int res = (ut_ulint_cmp(
- buf_page_get_LRU_position(bpage),
- buf_page_get_LRU_position(pred_bpage)));
+ /* Note that buf_page_is_accessed() returns
+ the time of the first access. If some blocks
+ of the extent existed in the buffer pool at
+ the time of a linear access pattern, the first
+ access times may be nonmonotonic, even though
+ the latest access times were linear. The
+ threshold (srv_read_ahead_factor) should help
+ a little against this. */
+ int res = ut_ulint_cmp(
+ buf_page_is_accessed(bpage),
+ buf_page_is_accessed(pred_bpage));
/* Accesses not in the right order */
if (res != 0 && res != asc_or_desc) {
fail_count++;
@@ -670,7 +500,7 @@ buf_read_ahead_linear(
count += buf_read_page_low(
&err, FALSE,
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
- space, zip_size, FALSE, tablespace_version, i);
+ space, zip_size, FALSE, tablespace_version, i, trx);
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -705,7 +535,7 @@ buf_read_ahead_linear(
LRU policy decision. */
buf_LRU_stat_inc_io();
- ++srv_read_ahead_seq;
+ buf_pool->stat.n_ra_pages_read += count;
return(count);
}
@@ -760,7 +590,7 @@ buf_read_ibuf_merge_pages(
buf_read_page_low(&err, sync && (i + 1 == n_stored),
BUF_READ_ANY_PAGE, space_ids[i],
zip_size, TRUE, space_versions[i],
- page_nos[i]);
+ page_nos[i], NULL);
if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) {
tablespace_deleted:
@@ -857,12 +687,12 @@ buf_read_recv_pages(
if ((i + 1 == n_stored) && sync) {
buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
zip_size, TRUE, tablespace_version,
- page_nos[i]);
+ page_nos[i], NULL);
} else {
buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
| OS_AIO_SIMULATED_WAKE_LATER,
space, zip_size, TRUE,
- tablespace_version, page_nos[i]);
+ tablespace_version, page_nos[i], NULL);
}
}
=== modified file 'storage/xtradb/data/data0type.c'
--- a/storage/xtradb/data/data0type.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/data/data0type.c 2010-01-06 12:00:14 +0000
@@ -237,6 +237,22 @@ dtype_print(
fputs("DATA_SYS", stderr);
break;
+ case DATA_FLOAT:
+ fputs("DATA_FLOAT", stderr);
+ break;
+
+ case DATA_DOUBLE:
+ fputs("DATA_DOUBLE", stderr);
+ break;
+
+ case DATA_DECIMAL:
+ fputs("DATA_DECIMAL", stderr);
+ break;
+
+ case DATA_VARMYSQL:
+ fputs("DATA_VARMYSQL", stderr);
+ break;
+
default:
fprintf(stderr, "type %lu", (ulong) mtype);
break;
=== modified file 'storage/xtradb/dict/dict0crea.c'
--- a/storage/xtradb/dict/dict0crea.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/dict/dict0crea.c 2010-01-06 12:00:14 +0000
@@ -1387,7 +1387,7 @@ dict_create_add_foreign_field_to_diction
Add a single foreign key definition to the data dictionary tables in the
database. We also generate names to constraints that were not named by the
user. A generated constraint has a name of the format
-databasename/tablename_ibfk_<number>, where the numbers start from 1, and
+databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and
are given locally for this table, that is, the number is not global, as in
the old format constraints < 4.0.18 it used to be.
@return error code or DB_SUCCESS */
=== modified file 'storage/xtradb/dict/dict0dict.c'
--- a/storage/xtradb/dict/dict0dict.c 2009-12-03 11:34:11 +0000
+++ b/storage/xtradb/dict/dict0dict.c 2010-01-15 15:58:25 +0000
@@ -82,9 +82,10 @@ static char dict_ibfk[] = "_ibfk_";
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
-index. */
+index.
+@return TRUE if the column names were found */
static
-void
+ibool
dict_index_find_cols(
/*=================*/
dict_table_t* table, /*!< in: table */
@@ -1261,7 +1262,7 @@ dict_index_too_big_for_undo(
= TRX_UNDO_PAGE_HDR - TRX_UNDO_PAGE_HDR_SIZE
+ 2 /* next record pointer */
+ 1 /* type_cmpl */
- + 11 /* trx->undo_no */ - 11 /* table->id */
+ + 11 /* trx->undo_no */ + 11 /* table->id */
+ 1 /* rec_get_info_bits() */
+ 11 /* DB_TRX_ID */
+ 11 /* DB_ROLL_PTR */
@@ -1440,7 +1441,11 @@ dict_index_too_big_for_tree(
goto add_field_size;
}
+ if (srv_relax_table_creation) {
+ field_max_size = dict_col_get_min_size(col);
+ } else {
field_max_size = dict_col_get_max_size(col);
+ }
field_ext_max_size = field_max_size < 256 ? 1 : 2;
if (field->prefix_len) {
@@ -1493,7 +1498,7 @@ add_field_size:
/**********************************************************************//**
Adds an index to the dictionary cache.
-@return DB_SUCCESS or DB_TOO_BIG_RECORD */
+@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
UNIV_INTERN
ulint
dict_index_add_to_cache(
@@ -1519,7 +1524,10 @@ dict_index_add_to_cache(
ut_a(!dict_index_is_clust(index)
|| UT_LIST_GET_LEN(table->indexes) == 0);
- dict_index_find_cols(table, index);
+ if (!dict_index_find_cols(table, index)) {
+
+ return(DB_CORRUPTION);
+ }
/* Build the cache internal representation of the index,
containing also the added system fields */
@@ -1732,9 +1740,10 @@ dict_index_remove_from_cache(
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
-index. */
+index.
+@return TRUE if the column names were found */
static
-void
+ibool
dict_index_find_cols(
/*=================*/
dict_table_t* table, /*!< in: table */
@@ -1759,17 +1768,21 @@ dict_index_find_cols(
}
}
+#ifdef UNIV_DEBUG
/* It is an error not to find a matching column. */
fputs("InnoDB: Error: no matching column for ", stderr);
ut_print_name(stderr, NULL, FALSE, field->name);
fputs(" in ", stderr);
dict_index_name_print(stderr, NULL, index);
fputs("!\n", stderr);
- ut_error;
+#endif /* UNIV_DEBUG */
+ return(FALSE);
found:
;
}
+
+ return(TRUE);
}
#endif /* !UNIV_HOTBACKUP */
@@ -4711,6 +4724,26 @@ dict_ind_init(void)
dict_ind_redundant->cached = dict_ind_compact->cached = TRUE;
}
+/**********************************************************************//**
+Frees dict_ind_redundant and dict_ind_compact. */
+static
+void
+dict_ind_free(void)
+/*===============*/
+{
+ dict_table_t* table;
+
+ table = dict_ind_compact->table;
+ dict_mem_index_free(dict_ind_compact);
+ dict_ind_compact = NULL;
+ dict_mem_table_free(table);
+
+ table = dict_ind_redundant->table;
+ dict_mem_index_free(dict_ind_redundant);
+ dict_ind_redundant = NULL;
+ dict_mem_table_free(table);
+}
+
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Get index by name
@@ -4836,4 +4869,55 @@ dict_table_check_for_dup_indexes(
}
}
#endif /* UNIV_DEBUG */
+
+/**************************************************************************
+Closes the data dictionary module. */
+UNIV_INTERN
+void
+dict_close(void)
+/*============*/
+{
+ ulint i;
+
+ /* Free the hash elements. We don't remove them from the table
+ because we are going to destroy the table anyway. */
+ for (i = 0; i < hash_get_n_cells(dict_sys->table_hash); i++) {
+ dict_table_t* table;
+
+ table = HASH_GET_FIRST(dict_sys->table_hash, i);
+
+ while (table) {
+ dict_table_t* prev_table = table;
+
+ table = HASH_GET_NEXT(name_hash, prev_table);
+#ifdef UNIV_DEBUG
+ ut_a(prev_table->magic_n == DICT_TABLE_MAGIC_N);
+#endif
+ /* Acquire only because it's a pre-condition. */
+ mutex_enter(&dict_sys->mutex);
+
+ dict_table_remove_from_cache(prev_table);
+
+ mutex_exit(&dict_sys->mutex);
+ }
+ }
+
+ hash_table_free(dict_sys->table_hash);
+
+ /* The elements are the same instance as in dict_sys->table_hash,
+ therefore we don't delete the individual elements. */
+ hash_table_free(dict_sys->table_id_hash);
+
+ dict_ind_free();
+
+ mutex_free(&dict_sys->mutex);
+
+ rw_lock_free(&dict_operation_lock);
+ memset(&dict_operation_lock, 0x0, sizeof(dict_operation_lock));
+
+ mutex_free(&dict_foreign_err_mutex);
+
+ mem_free(dict_sys);
+ dict_sys = NULL;
+}
#endif /* !UNIV_HOTBACKUP */
=== modified file 'storage/xtradb/fil/fil0fil.c'
--- a/storage/xtradb/fil/fil0fil.c 2009-11-29 23:08:56 +0000
+++ b/storage/xtradb/fil/fil0fil.c 2010-03-28 18:10:00 +0000
@@ -327,6 +327,17 @@ fil_get_space_id_for_table(
/*=======================*/
const char* name); /*!< in: table name in the standard
'databasename/tablename' format */
+/*******************************************************************//**
+Frees a space object from the tablespace memory cache. Closes the files in
+the chain but does not delete them. There must not be any pending i/o's or
+flushes on the files. */
+static
+ibool
+fil_space_free(
+/*===========*/
+ /* out: TRUE if success */
+ ulint id, /* in: space id */
+ ibool own_mutex);/* in: TRUE if own system->mutex */
/********************************************************************//**
Reads data from a space to a buffer. Remember that the possible incomplete
blocks at the end of file are ignored: they are not taken into account when
@@ -600,6 +611,11 @@ fil_node_create(
UT_LIST_ADD_LAST(chain, space->chain, node);
+ if (id < SRV_LOG_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
+
+ fil_system->max_assigned_id = id;
+ }
+
mutex_exit(&fil_system->mutex);
}
@@ -619,12 +635,10 @@ fil_node_open_file(
ulint size_high;
ibool ret;
ibool success;
-#ifndef UNIV_HOTBACKUP
byte* buf2;
byte* page;
ulint space_id;
ulint flags;
-#endif /* !UNIV_HOTBACKUP */
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->n_pending == 0);
@@ -660,9 +674,12 @@ fil_node_open_file(
size_bytes = (((ib_int64_t)size_high) << 32)
+ (ib_int64_t)size_low;
#ifdef UNIV_HOTBACKUP
- node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
- /* TODO: adjust to zip_size, like below? */
-#else
+ if (space->id == 0) {
+ node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
+ os_file_close(node->handle);
+ goto add_size;
+ }
+#endif /* UNIV_HOTBACKUP */
ut_a(space->purpose != FIL_LOG);
ut_a(space->id != 0);
@@ -741,7 +758,10 @@ fil_node_open_file(
(size_bytes
/ dict_table_flags_to_zip_size(flags));
}
-#endif
+
+#ifdef UNIV_HOTBACKUP
+add_size:
+#endif /* UNIV_HOTBACKUP */
space->size += node->size;
}
@@ -961,7 +981,7 @@ close_more:
" while the maximum\n"
"InnoDB: allowed value would be %lu.\n"
"InnoDB: You may need to raise the value of"
- " innodb_max_files_open in\n"
+ " innodb_open_files in\n"
"InnoDB: my.cnf.\n",
(ulong) fil_system->n_open,
(ulong) fil_system->max_n_open);
@@ -1141,7 +1161,7 @@ try_again:
mutex_exit(&fil_system->mutex);
- fil_space_free(namesake_id);
+ fil_space_free(namesake_id, FALSE);
goto try_again;
}
@@ -1266,17 +1286,21 @@ Frees a space object from the tablespace
the chain but does not delete them. There must not be any pending i/o's or
flushes on the files.
@return TRUE if success */
-UNIV_INTERN
+static
ibool
fil_space_free(
/*===========*/
- ulint id) /*!< in: space id */
+ /* out: TRUE if success */
+ ulint id, /* in: space id */
+ ibool own_mutex) /* in: TRUE if own system->mutex */
{
fil_space_t* space;
fil_space_t* namespace;
fil_node_t* fil_node;
- mutex_enter(&fil_system->mutex);
+ if (!own_mutex) {
+ mutex_enter(&fil_system->mutex);
+ }
space = fil_space_get_by_id(id);
@@ -1323,7 +1347,9 @@ fil_space_free(
ut_a(0 == UT_LIST_GET_LEN(space->chain));
- mutex_exit(&fil_system->mutex);
+ if (!own_mutex) {
+ mutex_exit(&fil_system->mutex);
+ }
rw_lock_free(&(space->latch));
@@ -1541,7 +1567,7 @@ fil_open_log_and_system_tablespace_files
fprintf(stderr,
"InnoDB: Warning: you must"
" raise the value of"
- " innodb_max_open_files in\n"
+ " innodb_open_files in\n"
"InnoDB: my.cnf! Remember that"
" InnoDB keeps all log files"
" and all system\n"
@@ -1583,6 +1609,8 @@ fil_close_all_files(void)
space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space != NULL) {
+ fil_space_t* prev_space = space;
+
node = UT_LIST_GET_FIRST(space->chain);
while (node != NULL) {
@@ -1592,6 +1620,7 @@ fil_close_all_files(void)
node = UT_LIST_GET_NEXT(chain, node);
}
space = UT_LIST_GET_NEXT(space_list, space);
+ fil_space_free(prev_space->id, TRUE);
}
mutex_exit(&fil_system->mutex);
@@ -2223,7 +2252,7 @@ try_again:
#endif
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
- success = fil_space_free(id);
+ success = fil_space_free(id, FALSE);
if (success) {
success = os_file_delete(path);
@@ -2929,7 +2958,6 @@ fil_open_single_table_tablespace(
byte* page;
ulint space_id;
ulint space_flags;
- ibool ret = TRUE;
filepath = fil_make_ibd_name(name, FALSE);
@@ -3140,7 +3168,7 @@ skip_info:
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
for (i = 0; (ulint) i < n_index; i++) {
- if (offset / UNIV_PAGE_SIZE == root_page[i]) {
+ if ((ulint) (offset / UNIV_PAGE_SIZE) == root_page[i]) {
/* this is index root page */
mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
+ FSEG_HDR_SPACE, id);
@@ -3330,7 +3358,7 @@ skip_write:
(ulong) space_id, (ulong) space_flags,
(ulong) id, (ulong) flags);
- ret = FALSE;
+ success = FALSE;
goto func_exit;
}
@@ -3350,7 +3378,7 @@ func_exit:
os_file_close(file);
mem_free(filepath);
- return(ret);
+ return(success);
}
#endif /* !UNIV_HOTBACKUP */
@@ -3566,7 +3594,7 @@ fil_load_single_table_tablespace(
fprintf(stderr,
"InnoDB: Renaming tablespace %s of id %lu,\n"
"InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
- "InnoDB: because its size %lld is too small"
+ "InnoDB: because its size %" PRId64 " is too small"
" (< 4 pages 16 kB each),\n"
"InnoDB: or the space id in the file header"
" is not sensible.\n"
@@ -3628,7 +3656,17 @@ fil_load_single_table_tablespace(
if (!success) {
- goto func_exit;
+ if (srv_force_recovery > 0) {
+ fprintf(stderr,
+ "InnoDB: innodb_force_recovery"
+ " was set to %lu. Continuing crash recovery\n"
+ "InnoDB: even though the tablespace creation"
+ " of this table failed.\n",
+ srv_force_recovery);
+ goto func_exit;
+ }
+
+ exit(1);
}
/* We do not use the size information we have about the file, because
@@ -4163,7 +4201,7 @@ fil_extend_space_to_desired_size(
node->name, node->handle, buf,
offset_low, offset_high,
page_size * n_pages,
- NULL, NULL);
+ NULL, NULL, NULL);
#endif
if (success) {
node->size += n_pages;
@@ -4490,7 +4528,7 @@ Reads or writes data. This operation is
i/o on a tablespace which does not exist */
UNIV_INTERN
ulint
-fil_io(
+_fil_io(
/*===*/
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
@@ -4515,8 +4553,9 @@ fil_io(
void* buf, /*!< in/out: buffer where to store read data
or from where to write; in aio this must be
appropriately aligned */
- void* message) /*!< in: message for aio handler if non-sync
+ void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
+ trx_t* trx)
{
ulint mode;
fil_space_t* space;
@@ -4686,7 +4725,7 @@ fil_io(
#else
/* Queue the aio request */
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
- offset_low, offset_high, len, node, message);
+ offset_low, offset_high, len, node, message, trx);
#endif
ut_a(ret);
@@ -4706,6 +4745,78 @@ fil_io(
return(DB_SUCCESS);
}
+/********************************************************************//**
+Confirm whether the parameters are valid or not */
+UNIV_INTERN
+ibool
+fil_area_is_exist(
+/*==============*/
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
+ 0 for uncompressed pages */
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
+ aio this must be divisible by the OS block
+ size */
+ ulint len) /*!< in: how many bytes to read or write; this
+ must not cross a file boundary; in aio this
+ must be a block size multiple */
+{
+ fil_space_t* space;
+ fil_node_t* node;
+
+ /* Reserve the fil_system mutex and make sure that we can open at
+ least one file while holding it, if the file is not already open */
+
+ fil_mutex_enter_and_prepare_for_io(space_id);
+
+ space = fil_space_get_by_id(space_id);
+
+ if (!space) {
+ mutex_exit(&fil_system->mutex);
+ return(FALSE);
+ }
+
+ node = UT_LIST_GET_FIRST(space->chain);
+
+ for (;;) {
+ if (UNIV_UNLIKELY(node == NULL)) {
+ mutex_exit(&fil_system->mutex);
+ return(FALSE);
+ }
+
+ if (space->id != 0 && node->size == 0) {
+ /* We do not know the size of a single-table tablespace
+ before we open the file */
+
+ break;
+ }
+
+ if (node->size > block_offset) {
+ /* Found! */
+ break;
+ } else {
+ block_offset -= node->size;
+ node = UT_LIST_GET_NEXT(chain, node);
+ }
+ }
+
+ /* Open file if closed */
+ fil_node_prepare_for_io(node, fil_system, space);
+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
+
+ /* Check that at least the start offset is within the bounds of a
+ single-table tablespace */
+ if (UNIV_UNLIKELY(node->size <= block_offset)
+ && space->id != 0 && space->purpose == FIL_TABLESPACE) {
+ mutex_exit(&fil_system->mutex);
+ return(FALSE);
+ }
+
+ mutex_exit(&fil_system->mutex);
+ return(TRUE);
+}
+
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
@@ -5065,6 +5176,29 @@ fil_page_get_type(
return(mach_read_from_2(page + FIL_PAGE_TYPE));
}
+/********************************************************************
+Initializes the tablespace memory cache. */
+UNIV_INTERN
+void
+fil_close(void)
+/*===========*/
+{
+ /* The mutex should already have been freed. */
+ ut_ad(fil_system->mutex.magic_n == 0);
+
+ hash_table_free(fil_system->spaces);
+
+ hash_table_free(fil_system->name_hash);
+
+ ut_a(UT_LIST_GET_LEN(fil_system->LRU) == 0);
+ ut_a(UT_LIST_GET_LEN(fil_system->unflushed_spaces) == 0);
+ ut_a(UT_LIST_GET_LEN(fil_system->space_list) == 0);
+
+ mem_free(fil_system);
+
+ fil_system = NULL;
+}
+
/*************************************************************************
Return local hash table informations. */
=== modified file 'storage/xtradb/fsp/fsp0fsp.c'
--- a/storage/xtradb/fsp/fsp0fsp.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/fsp/fsp0fsp.c 2010-01-06 12:00:14 +0000
@@ -232,6 +232,9 @@ the extent are free and which contain ol
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
#ifndef UNIV_HOTBACKUP
+/* Flag to indicate if we have printed the tablespace full error. */
+static ibool fsp_tbs_full_error_printed = FALSE;
+
/**********************************************************************//**
Returns an extent to the free list of a space. */
static
@@ -1099,7 +1102,7 @@ fsp_header_inc_size(
/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
-means the place of the first page which has never been put to the the
+means the place of the first page which has never been put to the
free list for allocation. The space above that address is initialized
to zero. Sets also the global variable log_fsp_current_free_limit.
@return free limit in megabytes */
@@ -1218,6 +1221,19 @@ fsp_try_extend_data_file(
if (space == 0 && !srv_auto_extend_last_data_file) {
+ /* We print the error message only once to avoid
+ spamming the error log. Note that we don't need
+ to reset the flag to FALSE as dealing with this
+ error requires server restart. */
+ if (fsp_tbs_full_error_printed == FALSE) {
+ fprintf(stderr,
+ "InnoDB: Error: Data file(s) ran"
+ " out of space.\n"
+ "Please add another data file or"
+ " use \'autoextend\' for the last"
+ " data file.\n");
+ fsp_tbs_full_error_printed = TRUE;
+ }
return(FALSE);
}
@@ -1832,6 +1848,8 @@ fsp_seg_inode_page_find_used(
if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
/* This is used */
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
return(i);
}
}
@@ -1863,6 +1881,9 @@ fsp_seg_inode_page_find_free(
return(i);
}
+
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
}
return(ULINT_UNDEFINED);
@@ -1981,6 +2002,8 @@ fsp_alloc_seg_inode(
page + FSEG_INODE_PAGE_NODE, mtr);
}
+ ut_ad(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))
+ || mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
return(inode);
}
@@ -2018,7 +2041,7 @@ fsp_free_seg_inode(
}
mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
- mlog_write_ulint(inode + FSEG_MAGIC_N, 0, MLOG_4BYTES, mtr);
+ mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr);
if (ULINT_UNDEFINED
== fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
@@ -2034,11 +2057,11 @@ fsp_free_seg_inode(
/**********************************************************************//**
Returns the file segment inode, page x-latched.
-@return segment inode, page x-latched */
+@return segment inode, page x-latched; NULL if the inode is free */
static
fseg_inode_t*
-fseg_inode_get(
-/*===========*/
+fseg_inode_try_get(
+/*===============*/
fseg_header_t* header, /*!< in: segment header */
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes
@@ -2054,12 +2077,38 @@ fseg_inode_get(
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
- ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
+ if (UNIV_UNLIKELY
+ (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) {
+
+ inode = NULL;
+ } else {
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
+ }
return(inode);
}
/**********************************************************************//**
+Returns the file segment inode, page x-latched.
+@return segment inode, page x-latched */
+static
+fseg_inode_t*
+fseg_inode_get(
+/*===========*/
+ fseg_header_t* header, /*!< in: segment header */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
+ mtr_t* mtr) /*!< in: mtr handle */
+{
+ fseg_inode_t* inode
+ = fseg_inode_try_get(header, space, zip_size, mtr);
+ ut_a(inode);
+ return(inode);
+}
+
+/**********************************************************************//**
Gets the page number from the nth fragment page slot.
@return page number, FIL_NULL if not in use */
UNIV_INLINE
@@ -2073,6 +2122,7 @@ fseg_get_nth_frag_page_no(
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
return(mach_read_from_4(inode + FSEG_FRAG_ARR
+ n * FSEG_FRAG_SLOT_SIZE));
}
@@ -2091,6 +2141,7 @@ fseg_set_nth_frag_page_no(
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE,
page_no, MLOG_4BYTES, mtr);
@@ -2451,6 +2502,8 @@ fseg_fill_free_list(
xdes_set_state(descr, XDES_FSEG, mtr);
seg_id = mtr_read_dulint(inode + FSEG_ID, mtr);
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
mlog_write_dulint(descr + XDES_ID, seg_id, mtr);
flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
@@ -2479,6 +2532,7 @@ fseg_alloc_free_extent(
fil_addr_t first;
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) {
/* Segment free list is not empty, allocate from it */
@@ -3136,6 +3190,8 @@ fseg_mark_page_used(
ut_ad(seg_inode && mtr);
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
+ ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
descr = xdes_get_descriptor(space, zip_size, page, mtr);
@@ -3373,6 +3429,8 @@ fseg_free_extent(
ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr),
mtr_read_dulint(seg_inode + FSEG_ID, mtr)));
+ ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
@@ -3463,7 +3521,13 @@ fseg_free_step(
ut_a(descr);
ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
- inode = fseg_inode_get(header, space, zip_size, mtr);
+ inode = fseg_inode_try_get(header, space, zip_size, mtr);
+
+ if (UNIV_UNLIKELY(inode == NULL)) {
+ fprintf(stderr, "double free of inode from %u:%u\n",
+ (unsigned) space, (unsigned) header_page);
+ return(TRUE);
+ }
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
@@ -3587,6 +3651,7 @@ fseg_get_first_extent(
ut_ad(inode && mtr);
ut_ad(space == page_get_space_id(page_align(inode)));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
first = fil_addr_null;
@@ -3801,6 +3866,7 @@ fseg_print_low(
(ulong) reserved, (ulong) used, (ulong) n_full,
(ulong) n_frag, (ulong) n_free, (ulong) n_not_full,
(ulong) n_used);
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
}
#ifdef UNIV_BTR_PRINT
=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- a/storage/xtradb/handler/ha_innodb.cc 2009-12-03 11:34:11 +0000
+++ b/storage/xtradb/handler/ha_innodb.cc 2010-01-15 21:12:30 +0000
@@ -61,7 +61,9 @@ with this program; if not, write to the
#pragma implementation // gcc: Class implementation
#endif
+#ifndef MYSQL_SERVER
#define MYSQL_SERVER
+#endif
#include <mysql_priv.h>
#ifdef MYSQL_SERVER
@@ -77,6 +79,7 @@ with this program; if not, write to the
/* Include necessary InnoDB headers */
extern "C" {
#include "univ.i"
+#include "buf0lru.h"
#include "btr0sea.h"
#include "os0file.h"
#include "os0thread.h"
@@ -109,7 +112,6 @@ extern "C" {
#include "ha_innodb.h"
#include "i_s.h"
-#include "handler0vars.h"
#ifdef MYSQL_SERVER
// Defined in trx0sys.c
@@ -120,9 +122,12 @@ extern ib_int64_t trx_sys_mysql_relay_lo
#endif /* MYSQL_SERVER */
#ifndef MYSQL_SERVER
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
+# ifndef MYSQL_PLUGIN_IMPORT
+# define MYSQL_PLUGIN_IMPORT /* nothing */
+# endif /* MYSQL_PLUGIN_IMPORT */
+/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
-extern pthread_mutex_t LOCK_thread_count;
+extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
#if MYSQL_VERSION_ID < 50124
/* this is defined in mysql_priv.h inside #ifdef MYSQL_SERVER
@@ -146,13 +151,9 @@ static bool innodb_inited = 0;
/* In the Windows plugin, the return value of current_thd is
undefined. Map it to NULL. */
-#if defined MYSQL_DYNAMIC_PLUGIN && defined __WIN__
-# undef current_thd
-# define current_thd NULL
-# define EQ_CURRENT_THD(thd) TRUE
-#else /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
-# define EQ_CURRENT_THD(thd) ((thd) == current_thd)
-#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
+
+#define EQ_CURRENT_THD(thd) ((thd) == current_thd)
+
static struct handlerton* innodb_hton_ptr;
@@ -172,6 +173,10 @@ static ulong innobase_write_io_threads;
static my_bool innobase_thread_concurrency_timer_based;
static long long innobase_buffer_pool_size, innobase_log_file_size;
+/** Percentage of the buffer pool to reserve for 'old' blocks.
+Connected to buf_LRU_old_ratio. */
+static uint innobase_old_blocks_pct;
+
/* The default values for the following char* start-up parameters
are determined in innobase_init below: */
@@ -186,9 +191,7 @@ file formats in the configuration file,
of the supported file formats during runtime. */
static char* innobase_file_format_check = NULL;
-/* The following has a misleading name: starting from 4.0.5, this also
-affects Windows: */
-static char* innobase_unix_file_flush_method = NULL;
+static char* innobase_file_flush_method = NULL;
/* Below we have boolean-valued start-up parameters, and their default
values */
@@ -202,7 +205,7 @@ static my_bool innobase_use_doublewrite
static my_bool innobase_use_checksums = TRUE;
static my_bool innobase_extra_undoslots = FALSE;
static my_bool innobase_fast_recovery = FALSE;
-static my_bool innobase_use_purge_thread = FALSE;
+static my_bool innobase_recovery_stats = TRUE;
static my_bool innobase_locks_unsafe_for_binlog = FALSE;
static my_bool innobase_overwrite_relay_log_info = FALSE;
static my_bool innobase_rollback_on_timeout = FALSE;
@@ -238,10 +241,10 @@ static void free_share(INNOBASE_SHARE *s
static int innobase_close_connection(handlerton *hton, THD* thd);
static int innobase_commit(handlerton *hton, THD* thd, bool all);
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
-static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
+static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
void *savepoint);
static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
-static int innobase_release_savepoint(handlerton *hton, THD* thd,
+static int innobase_release_savepoint(handlerton *hton, THD* thd,
void *savepoint);
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
@@ -285,10 +288,10 @@ innobase_file_format_check_on_off(
/************************************************************//**
Validate the file format check config parameters, as a side effect it
sets the srv_check_file_format_at_startup variable.
-@return true if valid config value */
+@return the format_id if valid config value, otherwise, return -1 */
static
-bool
-innobase_file_format_check_validate(
+int
+innobase_file_format_validate_and_set(
/*================================*/
const char* format_check); /*!< in: parameter value */
/****************************************************************//**
@@ -519,10 +522,10 @@ static SHOW_VAR innodb_status_variables[
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
{"buffer_pool_pages_total",
(char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
- {"buffer_pool_read_ahead_rnd",
- (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
- {"buffer_pool_read_ahead_seq",
- (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
+ {"buffer_pool_read_ahead",
+ (char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG},
+ {"buffer_pool_read_ahead_evicted",
+ (char*) &export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_LONG},
{"buffer_pool_read_requests",
(char*) &export_vars.innodb_buffer_pool_read_requests, SHOW_LONG},
{"buffer_pool_reads",
@@ -803,11 +806,20 @@ convert_error_code_to_mysql(
case DB_SUCCESS:
return(0);
+ case DB_INTERRUPTED:
+ my_error(ER_QUERY_INTERRUPTED, MYF(0));
+ /* fall through */
case DB_ERROR:
default:
return(-1); /* unspecified error */
case DB_DUPLICATE_KEY:
+ /* Be cautious with returning this error, since
+ mysql could re-enter the storage layer to get
+ duplicated key info, the operation requires a
+ valid table handle and/or transaction information,
+ which might not always be available in the error
+ handling stage. */
return(HA_ERR_FOUND_DUPP_KEY);
case DB_FOREIGN_DUPLICATE_KEY:
@@ -894,17 +906,14 @@ convert_error_code_to_mysql(
return(ER_PRIMARY_CANT_HAVE_NULL);
case DB_TOO_MANY_CONCURRENT_TRXS:
- /* Once MySQL add the appropriate code to errmsg.txt then
- we can get rid of this #ifdef. NOTE: The code checked by
- the #ifdef is the suggested name for the error condition
- and the actual error code name could very well be different.
- This will require some monitoring, ie. the status
- of this request on our part.*/
-#ifdef ER_TOO_MANY_CONCURRENT_TRXS
- return(ER_TOO_MANY_CONCURRENT_TRXS);
-#else
+ /* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
+ available in 5.1.38 and later, but the plugin should still
+ work with previous versions of MySQL. */
+#ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
+ return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
+#else /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
return(HA_ERR_RECORD_FILE_FULL);
-#endif
+#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
case DB_UNSUPPORTED:
return(HA_ERR_UNSUPPORTED);
}
@@ -978,7 +987,23 @@ innobase_get_cset_width(
*mbminlen = cs->mbminlen;
*mbmaxlen = cs->mbmaxlen;
} else {
- ut_a(cset == 0);
+ THD* thd = current_thd;
+
+ if (thd && thd_sql_command(thd) == SQLCOM_DROP_TABLE) {
+
+ /* Fix bug#46256: allow tables to be dropped if the
+ collation is not found, but issue a warning. */
+ if ((global_system_variables.log_warnings)
+ && (cset != 0)){
+
+ sql_print_warning(
+ "Unknown collation #%lu.", cset);
+ }
+ } else {
+
+ ut_a(cset == 0);
+ }
+
*mbminlen = *mbmaxlen = 0;
}
}
@@ -1052,6 +1077,7 @@ innobase_get_charset(
}
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
+extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
/*******************************************************************//**
Map an OS error to an errno value. The OS error number is stored in
_doserrno and the mapped value is stored in errno) */
@@ -1339,6 +1365,16 @@ innobase_trx_init(
trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS);
+#ifdef EXTENDED_SLOWLOG
+ if (thd_log_slow_verbosity(thd) & SLOG_V_INNODB) {
+ trx->take_stats = TRUE;
+ } else {
+ trx->take_stats = FALSE;
+ }
+#else
+ trx->take_stats = FALSE;
+#endif
+
DBUG_VOID_RETURN;
}
@@ -1395,6 +1431,32 @@ check_trx_exists(
}
+/*************************************************************************
+Gets current trx. */
+extern "C"
+trx_t*
+innobase_get_trx()
+{
+ THD *thd=current_thd;
+ if (likely(thd != 0)) {
+ trx_t*& trx = thd_to_trx(thd);
+ return(trx);
+ } else {
+ return(NULL);
+ }
+}
+
+extern "C"
+ibool
+innobase_get_slow_log()
+{
+#ifdef EXTENDED_SLOWLOG
+ return((ibool) thd_opt_slow_log());
+#else
+ return(FALSE);
+#endif
+}
+
/*********************************************************************//**
Construct ha_innobase handler. */
UNIV_INTERN
@@ -1711,15 +1773,19 @@ innobase_convert_identifier(
FALSE=id is an UTF-8 string */
{
char nz[NAME_LEN + 1];
+#if MYSQL_VERSION_ID >= 50141
+ char nz2[NAME_LEN + 1 + EXPLAIN_FILENAME_MAX_EXTRA_LENGTH];
+#else /* MYSQL_VERSION_ID >= 50141 */
char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
+#endif /* MYSQL_VERSION_ID >= 50141 */
const char* s = id;
int q;
if (file_id) {
- /* Decode the table name. The filename_to_tablename()
- function expects a NUL-terminated string. The input and
- output strings buffers must not be shared. */
+ /* Decode the table name. The MySQL function expects
+ a NUL-terminated string. The input and output strings
+ buffers must not be shared. */
if (UNIV_UNLIKELY(idlen > (sizeof nz) - 1)) {
idlen = (sizeof nz) - 1;
@@ -1729,7 +1795,13 @@ innobase_convert_identifier(
nz[idlen] = 0;
s = nz2;
+#if MYSQL_VERSION_ID >= 50141
+ idlen = explain_filename((THD*) thd, nz, nz2, sizeof nz2,
+ EXPLAIN_PARTITIONS_AS_COMMENT);
+ goto no_quote;
+#else /* MYSQL_VERSION_ID >= 50141 */
idlen = filename_to_tablename(nz, nz2, sizeof nz2);
+#endif /* MYSQL_VERSION_ID >= 50141 */
}
/* See if the identifier needs to be quoted. */
@@ -1740,6 +1812,9 @@ innobase_convert_identifier(
}
if (q == EOF) {
+#if MYSQL_VERSION_ID >= 50141
+no_quote:
+#endif /* MYSQL_VERSION_ID >= 50141 */
if (UNIV_UNLIKELY(idlen > buflen)) {
idlen = buflen;
}
@@ -2222,8 +2297,8 @@ mem_free_and_error:
/* Did the user specify a format name that we support ?
As a side effect it will update the variable
srv_check_file_format_at_startup */
- if (!innobase_file_format_check_validate(
- innobase_file_format_check)) {
+ if (innobase_file_format_validate_and_set(
+ innobase_file_format_check) < 0) {
sql_print_error("InnoDB: invalid "
"innodb_file_format_check value: "
@@ -2264,7 +2339,7 @@ innobase_change_buffering_inited_ok:
/* --------------------------------------------------*/
- srv_file_flush_method_str = innobase_unix_file_flush_method;
+ srv_file_flush_method_str = innobase_file_flush_method;
srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
srv_n_log_files = (ulint) innobase_log_files_in_group;
@@ -2292,8 +2367,7 @@ innobase_change_buffering_inited_ok:
srv_force_recovery = (ulint) innobase_force_recovery;
srv_fast_recovery = (ibool) innobase_fast_recovery;
-
- srv_use_purge_thread = (ibool) innobase_use_purge_thread;
+ srv_recovery_stats = (ibool) innobase_recovery_stats;
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
srv_use_checksums = (ibool) innobase_use_checksums;
@@ -2329,6 +2403,9 @@ innobase_change_buffering_inited_ok:
ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
srv_latin1_ordering = my_charset_latin1.sort_order;
+ innobase_old_blocks_pct = buf_LRU_old_ratio_update(
+ innobase_old_blocks_pct, FALSE);
+
innobase_commit_concurrency_init_default();
/* Since we in this module access directly the fields of a trx
@@ -2510,7 +2587,10 @@ innobase_alter_table_flags(
{
return(HA_ONLINE_ADD_INDEX_NO_WRITES
| HA_ONLINE_DROP_INDEX_NO_WRITES
- | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES
+ /* Current InnoDB doesn't sort unique indexes along mysqld's order
+ It is dangerous to use index. So it is disabled until
+ the bug http://bugs.mysql.com/47622 */
+ /* | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES */
| HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES
| HA_ONLINE_ADD_PK_INDEX_NO_WRITES);
}
@@ -2676,6 +2756,19 @@ retry:
}
}
+ /* The following calls to read the MySQL binary log
+ file name and the position return consistent results:
+ 1) Other InnoDB transactions cannot intervene between
+ these calls as we are holding prepare_commit_mutex.
+ 2) Binary logging of other engines is not relevant
+ to InnoDB as all InnoDB requires is that committing
+ InnoDB transactions appear in the same order in the
+ MySQL binary log as they appear in InnoDB logs.
+ 3) A MySQL log file rotation cannot happen because
+ MySQL protects against this by having a counter of
+ transactions in prepared state and it only allows
+ a rotation when the counter drops to zero. See
+ LOCK_prep_xids and COND_prep_xids in log.cc. */
trx->mysql_log_file_name = mysql_bin_log_file_name();
trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
@@ -2761,6 +2854,8 @@ innobase_rollback(
innobase_release_stat_resources(trx);
+ trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
+
/* If we had reserved the auto-inc lock for some table (if
we come here to roll back the latest SQL statement) we
release it now before a possibly lengthy rollback */
@@ -3322,7 +3417,7 @@ retry:
if (is_part) {
sql_print_error("Failed to open table %s after "
- "%lu attemtps.\n", norm_name,
+ "%lu attempts.\n", norm_name,
retries);
}
@@ -3926,7 +4021,6 @@ ha_innobase::store_key_val_for_row(
as BLOB data in innodb. */
|| mysql_type == MYSQL_TYPE_GEOMETRY) {
-
CHARSET_INFO* cs;
ulint key_len;
ulint true_len;
@@ -4648,24 +4742,29 @@ no_commit:
update the table upper limit. Note: last_value
will be 0 if get_auto_increment() was not called.*/
- if (auto_inc <= col_max_value
- && auto_inc >= prebuilt->autoinc_last_value) {
+ if (auto_inc >= prebuilt->autoinc_last_value) {
set_max_autoinc:
- ut_a(prebuilt->autoinc_increment > 0);
-
- ulonglong need;
- ulonglong offset;
-
- offset = prebuilt->autoinc_offset;
- need = prebuilt->autoinc_increment;
-
- auto_inc = innobase_next_autoinc(
- auto_inc, need, offset, col_max_value);
-
- err = innobase_set_max_autoinc(auto_inc);
-
- if (err != DB_SUCCESS) {
- error = err;
+ /* This should filter out the negative
+ values set explicitly by the user. */
+ if (auto_inc <= col_max_value) {
+ ut_a(prebuilt->autoinc_increment > 0);
+
+ ulonglong need;
+ ulonglong offset;
+
+ offset = prebuilt->autoinc_offset;
+ need = prebuilt->autoinc_increment;
+
+ auto_inc = innobase_next_autoinc(
+ auto_inc,
+ need, offset, col_max_value);
+
+ err = innobase_set_max_autoinc(
+ auto_inc);
+
+ if (err != DB_SUCCESS) {
+ error = err;
+ }
}
}
break;
@@ -5227,6 +5326,11 @@ ha_innobase::index_read(
index = prebuilt->index;
+ if (UNIV_UNLIKELY(index == NULL)) {
+ prebuilt->index_usable = FALSE;
+ DBUG_RETURN(HA_ERR_CRASHED);
+ }
+
/* Note that if the index for which the search template is built is not
necessarily prebuilt->index, but can also be the clustered index */
@@ -5386,6 +5490,7 @@ ha_innobase::change_active_index(
if (UNIV_UNLIKELY(!prebuilt->index)) {
sql_print_warning("InnoDB: change_active_index(%u) failed",
keynr);
+ prebuilt->index_usable = FALSE;
DBUG_RETURN(1);
}
@@ -5393,8 +5498,10 @@ ha_innobase::change_active_index(
prebuilt->index);
if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
- sql_print_warning("InnoDB: insufficient history for index %u",
- keynr);
+ push_warning_printf(user_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ HA_ERR_TABLE_DEF_CHANGED,
+ "InnoDB: insufficient history for index %u",
+ keynr);
/* The caller seems to ignore this. Thus, we must check
this again in row_search_for_mysql(). */
DBUG_RETURN(convert_error_code_to_mysql(DB_MISSING_HISTORY,
@@ -5850,7 +5957,7 @@ create_table_def(
number fits in one byte in prtype */
push_warning_printf(
(THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CANT_CREATE_TABLE,
"In InnoDB, charset-collation codes"
" must be below 256."
@@ -5882,17 +5989,8 @@ create_table_def(
/* First check whether the column to be added has a
system reserved name. */
if (dict_col_name_is_reserved(field->field_name)){
- push_warning_printf(
- (THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_CANT_CREATE_TABLE,
- "Error creating table '%s' with "
- "column name '%s'. '%s' is a "
- "reserved name. Please try to "
- "re-create the table with a "
- "different column name.",
- table->name, (char*) field->field_name,
- (char*) field->field_name);
+ my_error(ER_WRONG_COLUMN_NAME, MYF(0),
+ field->field_name);
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
@@ -5914,6 +6012,14 @@ create_table_def(
error = row_create_table_for_mysql(table, trx);
+ if (error == DB_DUPLICATE_KEY) {
+ char buf[100];
+ innobase_convert_identifier(buf, sizeof buf,
+ table_name, strlen(table_name),
+ trx->mysql_thd, TRUE);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
+ }
+
error_ret:
error = convert_error_code_to_mysql(error, flags, NULL);
@@ -6064,7 +6170,6 @@ create_clustered_index_when_no_primary(
/* We pass 0 as the space id, and determine at a lower level the space
id where to store the table */
-
index = dict_mem_index_create(table_name,
innobase_index_reserve_name,
0, DICT_CLUSTERED, 0);
@@ -6119,7 +6224,7 @@ create_options_are_valid(
/* Valid value. */
break;
default:
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: invalid"
" KEY_BLOCK_SIZE = %lu."
@@ -6133,7 +6238,7 @@ create_options_are_valid(
/* If KEY_BLOCK_SIZE was specified, check for its
dependencies. */
if (kbs_specified && !srv_file_per_table) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_per_table.");
@@ -6141,7 +6246,7 @@ create_options_are_valid(
}
if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_format >"
@@ -6165,7 +6270,7 @@ create_options_are_valid(
if (!srv_file_per_table) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_per_table.",
@@ -6177,7 +6282,7 @@ create_options_are_valid(
if (srv_file_format < DICT_TF_FORMAT_ZIP) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_format >"
@@ -6194,7 +6299,7 @@ create_options_are_valid(
&& form->s->row_type == ROW_TYPE_DYNAMIC) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: cannot specify"
" ROW_FORMAT = DYNAMIC with"
@@ -6218,7 +6323,7 @@ create_options_are_valid(
if (kbs_specified) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: cannot specify"
" ROW_FORMAT = %s with"
@@ -6231,7 +6336,7 @@ create_options_are_valid(
default:
push_warning(thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: invalid ROW_FORMAT specifier.");
ret = FALSE;
@@ -6295,13 +6400,15 @@ ha_innobase::create(
1. <database_name>/<table_name>: for normal table creation
2. full path: for temp table creation, or sym link
- When srv_file_per_table is on, check for full path pattern, i.e.
+ When srv_file_per_table is on and mysqld_embedded is off,
+ check for full path pattern, i.e.
X:\dir\..., X is a driver letter, or
\\dir1\dir2\..., UNC path
returns error if it is in full path format, but not creating a temp.
table. Currently InnoDB does not support symbolic link on Windows. */
if (srv_file_per_table
+ && !mysqld_embedded
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
if ((name[1] == ':')
@@ -6519,6 +6626,7 @@ ha_innobase::create(
goto cleanup;
}
+
/* Create the keys */
if (form->s->keys == 0 || primary_key_no == -1) {
@@ -6967,6 +7075,24 @@ ha_innobase::rename_table(
innobase_commit_low(trx);
trx_free_for_mysql(trx);
+ /* Add a special case to handle the Duplicated Key error
+ and return DB_ERROR instead.
+ This is to avoid a possible SIGSEGV error from mysql error
+ handling code. Currently, mysql handles the Duplicated Key
+ error by re-entering the storage layer and getting dup key
+ info by calling get_dup_key(). This operation requires a valid
+ table handle ('row_prebuilt_t' structure) which could no
+ longer be available in the error handling stage. The suggested
+ solution is to report a 'table exists' error message (since
+ the dup key error here is due to an existing table whose name
+ is the one we are trying to rename to) and return the generic
+ error code. */
+ if (error == (int) DB_DUPLICATE_KEY) {
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
+
+ error = DB_ERROR;
+ }
+
error = convert_error_code_to_mysql(error, 0, NULL);
DBUG_RETURN(error);
@@ -7519,11 +7645,15 @@ ha_innobase::check(
ret = row_check_table_for_mysql(prebuilt);
- if (ret == DB_SUCCESS) {
+ switch (ret) {
+ case DB_SUCCESS:
return(HA_ADMIN_OK);
+ case DB_INTERRUPTED:
+ my_error(ER_QUERY_INTERRUPTED, MYF(0));
+ return(-1);
+ default:
+ return(HA_ADMIN_CORRUPT);
}
-
- return(HA_ADMIN_CORRUPT);
}
/*************************************************************//**
@@ -8069,8 +8199,11 @@ ha_innobase::external_lock(
ulong const binlog_format= thd_binlog_format(thd);
ulong const tx_isolation = thd_tx_isolation(ha_thd());
if (tx_isolation <= ISO_READ_COMMITTED
- && binlog_format == BINLOG_FORMAT_STMT
- && thd_binlog_filter_ok(thd))
+ && binlog_format == BINLOG_FORMAT_STMT
+#if MYSQL_VERSION_ID > 50140
+ && thd_binlog_filter_ok(thd)
+#endif /* MYSQL_VERSION_ID > 50140 */
+ )
{
char buf[256];
my_snprintf(buf, sizeof(buf),
@@ -8183,6 +8316,23 @@ ha_innobase::external_lock(
statement has ended */
if (trx->n_mysql_tables_in_use == 0) {
+#ifdef EXTENDED_SLOWLOG
+ increment_thd_innodb_stats(thd, trx->io_reads,
+ trx->io_read,
+ trx->io_reads_wait_timer,
+ trx->lock_que_wait_timer,
+ trx->innodb_que_wait_timer,
+ trx->distinct_page_access);
+
+ trx->io_reads = 0;
+ trx->io_read = 0;
+ trx->io_reads_wait_timer = 0;
+ trx->lock_que_wait_timer = 0;
+ trx->innodb_que_wait_timer = 0;
+ trx->distinct_page_access = 0;
+ if (trx->distinct_page_access_hash)
+ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
+#endif
trx->mysql_n_tables_locked = 0;
prebuilt->used_in_HANDLER = FALSE;
@@ -8470,8 +8620,8 @@ innodb_mutex_show_status(
rw_lock_wait_time += mutex->lspent_time;
}
#else /* UNIV_DEBUG */
- buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s:%lu",
- mutex->cfile_name, (ulong) mutex->cline);
+ buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s",
+ mutex->cmutex_name);
buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
mutex->count_os_wait);
@@ -8496,8 +8646,8 @@ next_mutex:
while (lock != NULL) {
if (lock->count_os_wait
&& !buf_pool_is_block_lock(lock)) {
- buf1len= my_snprintf(buf1, sizeof(buf1), "%s:%lu",
- lock->cfile_name, (ulong) lock->cline);
+ buf1len= my_snprintf(buf1, sizeof(buf1), "%s",
+ lock->lock_name);
buf2len= my_snprintf(buf2, sizeof(buf2),
"os_waits=%lu", lock->count_os_wait);
@@ -8718,6 +8868,7 @@ ha_innobase::store_lock(
&& isolation_level != TRX_ISO_SERIALIZABLE
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
&& (sql_command == SQLCOM_INSERT_SELECT
+ || sql_command == SQLCOM_REPLACE_SELECT
|| sql_command == SQLCOM_UPDATE
|| sql_command == SQLCOM_CREATE_TABLE)) {
@@ -8725,10 +8876,11 @@ ha_innobase::store_lock(
option set or this session is using READ COMMITTED
isolation level and isolation level of the transaction
is not set to serializable and MySQL is doing
- INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
- CREATE ... SELECT... without FOR UPDATE or
- IN SHARE MODE in select, then we use consistent
- read for select. */
+ INSERT INTO...SELECT or REPLACE INTO...SELECT
+ or UPDATE ... = (SELECT ...) or CREATE ...
+ SELECT... without FOR UPDATE or IN SHARE
+ MODE in select, then we use consistent read
+ for select. */
prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = LOCK_NONE;
@@ -8957,8 +9109,7 @@ ha_innobase::get_auto_increment(
col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
- current = *first_value > col_max_value ? autoinc : *first_value;
-
+ current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
@@ -9322,8 +9473,7 @@ innobase_xa_prepare(
executing XA PREPARE and XA COMMIT commands.
In this case we cannot know how many minutes or hours
will be between XA PREPARE and XA COMMIT, and we don't want
- to block for undefined period of time.
- */
+ to block for undefined period of time. */
pthread_mutex_lock(&prepare_commit_mutex);
trx->active_trans = 2;
}
@@ -9575,6 +9725,20 @@ ha_innobase::check_if_incompatible_data(
DBUG_RETURN(COMPATIBLE_DATA_NO);
}
+ /* Renaming column asynchronizes dictionary between mysqld and InnoDB...
+ If not synchronized, treat as COMPATIBLE_DATA_NO
+ until the bug http://bugs.mysql.com/47621 is fixed officialily */
+ {
+ uint i;
+ for (i = 0; i < table->s->fields; i++) {
+ if (table->field[i]->flags & FIELD_IN_ADD_INDEX
+ && innobase_strcasecmp(table->field[i]->field_name,
+ dict_table_get_col_name(prebuilt->table, i))) {
+ DBUG_RETURN(COMPATIBLE_DATA_NO);
+ }
+ }
+ }
+
/* Check if a column participating in a foreign key is being renamed.
There is no mechanism for updating InnoDB foreign key definitions. */
if (foreign_key_column_is_being_renamed(prebuilt, table)) {
@@ -9683,25 +9847,24 @@ innobase_file_format_check_on_off(
/************************************************************//**
Validate the file format check config parameters, as a side effect it
sets the srv_check_file_format_at_startup variable.
-@return true if valid config value */
+@return the format_id if valid config value, otherwise, return -1 */
static
-bool
-innobase_file_format_check_validate(
+int
+innobase_file_format_validate_and_set(
/*================================*/
const char* format_check) /*!< in: parameter value */
{
uint format_id;
- bool ret = true;
format_id = innobase_file_format_name_lookup(format_check);
if (format_id < DICT_TF_FORMAT_MAX + 1) {
srv_check_file_format_at_startup = format_id;
+
+ return((int) format_id);
} else {
- ret = false;
+ return(-1);
}
-
- return(ret);
}
/*************************************************************//**
@@ -9720,7 +9883,6 @@ innodb_file_format_name_validate(
struct st_mysql_value* value) /*!< in: incoming string */
{
const char* file_format_input;
- char* file_format_input_strdup;
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
@@ -9737,18 +9899,12 @@ innodb_file_format_name_validate(
if (format_id <= DICT_TF_FORMAT_MAX) {
- /* Copy out from stack-allocated memory (which will not
- survive return from this function). The memory will be
- freed in innodb_file_format_check_update(). */
- file_format_input_strdup = thd_strmake(thd, file_format_input, len);
+ /* Save a pointer to the name in the
+ 'file_format_name_map' constant array. */
+ *static_cast<const char**>(save) =
+ trx_sys_file_format_id_to_name(format_id);
- *static_cast<char**>(save) = file_format_input_strdup;
-
- if (file_format_input_strdup == NULL) {
- return(1);
- } else {
- return(0);
- }
+ return(0);
}
}
@@ -9808,9 +9964,9 @@ innodb_file_format_check_validate(
struct st_mysql_value* value) /*!< in: incoming string */
{
const char* file_format_input;
- char* file_format_input_strdup;
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
+ int format_id;
ut_a(save != NULL);
ut_a(value != NULL);
@@ -9823,33 +9979,35 @@ innodb_file_format_check_validate(
message if they did so. */
if (innobase_file_format_check_on_off(file_format_input)) {
- sql_print_warning(
+ push_warning_printf(thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
"InnoDB: invalid innodb_file_format_check "
"value; on/off can only be set at startup or "
"in the configuration file");
- } else if (innobase_file_format_check_validate(
- file_format_input)) {
+ } else {
+ format_id = innobase_file_format_validate_and_set(
+ file_format_input);
- /* Copy out from stack-allocated memory (which will not
- survive return from this function). The memory will be
- freed in innodb_file_format_check_update(). */
- file_format_input_strdup = thd_strmake(thd, file_format_input, len);
+ if (format_id >= 0) {
+ /* Save a pointer to the name in the
+ 'file_format_name_map' constant array. */
+ *static_cast<const char**>(save) =
+ trx_sys_file_format_id_to_name(
+ (uint)format_id);
- *static_cast<char**>(save) = file_format_input_strdup;
+ return(0);
- if (file_format_input_strdup == NULL) {
- return(1);
} else {
- return(0);
+ push_warning_printf(thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "InnoDB: invalid innodb_file_format_check "
+ "value; can be any format up to %s "
+ "or its equivalent numeric id",
+ trx_sys_file_format_id_to_name(
+ DICT_TF_FORMAT_MAX));
}
-
- } else {
- sql_print_warning(
- "InnoDB: invalid innodb_file_format_check "
- "value; can be any format up to %s "
- "or its equivalent numeric id",
- trx_sys_file_format_id_to_name(
- DICT_TF_FORMAT_MAX));
}
}
@@ -9880,6 +10038,7 @@ innodb_file_format_check_update(
ut_a(var_ptr != NULL);
format_name_in = *static_cast<const char*const*>(save);
+
if (!format_name_in) {
return;
@@ -9929,6 +10088,25 @@ innodb_adaptive_hash_index_update(
}
}
+/****************************************************************//**
+Update the system variable innodb_old_blocks_pct using the "saved"
+value. This function is registered as a callback with MySQL. */
+static
+void
+innodb_old_blocks_pct_update(
+/*=========================*/
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
+ system variable */
+ void* var_ptr,/*!< out: where the
+ formal string goes */
+ const void* save) /*!< in: immediate result
+ from check function */
+{
+ innobase_old_blocks_pct = buf_LRU_old_ratio_update(
+ *static_cast<const uint*>(save), TRUE);
+}
+
/*************************************************************//**
Check if it is a valid value of innodb_change_buffering. This function is
registered as a callback with MySQL.
@@ -10075,13 +10253,18 @@ static MYSQL_SYSVAR_BOOL(extra_undoslots
static MYSQL_SYSVAR_BOOL(fast_recovery, innobase_fast_recovery,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"Enable to use speed hack of recovery avoiding flush list sorting.",
- NULL, NULL, FALSE);
+ NULL, NULL, TRUE);
-static MYSQL_SYSVAR_BOOL(use_purge_thread, innobase_use_purge_thread,
+static MYSQL_SYSVAR_BOOL(recovery_stats, innobase_recovery_stats,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
- "Enable to use purge devoted thread.",
+ "Output statistics of recovery process after it.",
NULL, NULL, FALSE);
+static MYSQL_SYSVAR_ULONG(use_purge_thread, srv_use_purge_thread,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of purge devoted threads. #### over 1 is EXPERIMENTAL ####",
+ NULL, NULL, 1, 0, 64, 0);
+
static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"During InnoDB crash recovery on slave overwrite relay-log.info "
@@ -10122,12 +10305,15 @@ static MYSQL_SYSVAR_STR(file_format, inn
innodb_file_format_name_validate,
innodb_file_format_name_update, "Antelope");
+/* If a new file format is introduced, the file format
+name needs to be updated accordingly. Please refer to
+file_format_name_map[] defined in trx0sys.c for the next
+file format name. */
static MYSQL_SYSVAR_STR(file_format_check, innobase_file_format_check,
PLUGIN_VAR_OPCMDARG,
"The highest file format in the tablespace.",
innodb_file_format_check_validate,
- innodb_file_format_check_update,
- "on");
+ innodb_file_format_check_update, "Barracuda");
static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
PLUGIN_VAR_OPCMDARG,
@@ -10136,7 +10322,7 @@ static MYSQL_SYSVAR_ULONG(flush_log_at_t
" or 2 (write at commit, flush once per second).",
NULL, NULL, 1, 0, 2, 0);
-static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
+static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"With which method to flush data.", NULL, NULL, NULL);
@@ -10177,7 +10363,7 @@ static MYSQL_SYSVAR_ULONG(max_dirty_page
static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
PLUGIN_VAR_NOCMDARG,
"Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
- NULL, NULL, TRUE);
+ NULL, NULL, FALSE);
static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
PLUGIN_VAR_RQCMDARG,
@@ -10273,7 +10459,7 @@ static MYSQL_SYSVAR_ULONG(concurrency_ti
NULL, NULL, 500L, 1L, ~0L, 0);
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
"Number of file I/O threads in InnoDB.",
NULL, NULL, 4, 4, 64, 0);
@@ -10312,6 +10498,18 @@ static MYSQL_SYSVAR_LONG(mirrored_log_gr
"Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
NULL, NULL, 1, 1, 10, 0);
+static MYSQL_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
+ PLUGIN_VAR_RQCMDARG,
+ "Percentage of the buffer pool to reserve for 'old' blocks.",
+ NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
+
+static MYSQL_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
+ PLUGIN_VAR_RQCMDARG,
+ "Move blocks to the 'new' end of the buffer pool if the first access"
+ " was at least this many milliseconds ago."
+ " The timeout is disabled if 0 (the default).",
+ NULL, NULL, 0, 0, UINT_MAX32, 0);
+
static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"How many files at the maximum InnoDB keeps open at the same time.",
@@ -10390,13 +10588,18 @@ static MYSQL_SYSVAR_LONGLONG(ibuf_max_si
static MYSQL_SYSVAR_ULONG(ibuf_active_contract, srv_ibuf_active_contract,
PLUGIN_VAR_RQCMDARG,
"Enable/Disable active_contract of insert buffer. 0:disable 1:enable",
- NULL, NULL, 0, 0, 1, 0);
+ NULL, NULL, 1, 0, 1, 0);
static MYSQL_SYSVAR_ULONG(ibuf_accel_rate, srv_ibuf_accel_rate,
PLUGIN_VAR_RQCMDARG,
"Tunes amount of insert buffer processing of background, in addition to innodb_io_capacity. (in percentage)",
NULL, NULL, 100, 100, 999999999, 0);
+static MYSQL_SYSVAR_ULONG(checkpoint_age_target, srv_checkpoint_age_target,
+ PLUGIN_VAR_RQCMDARG,
+ "Control soft limit of checkpoint age. (0 : not control)",
+ NULL, NULL, 0, 0, ~0UL, 0);
+
static MYSQL_SYSVAR_ULONG(flush_neighbor_pages, srv_flush_neighbor_pages,
PLUGIN_VAR_RQCMDARG,
"Enable/Disable flushing also neighbor pages. 0:disable 1:enable",
@@ -10432,7 +10635,7 @@ TYPELIB read_ahead_typelib=
};
static MYSQL_SYSVAR_ENUM(read_ahead, srv_read_ahead,
PLUGIN_VAR_RQCMDARG,
- "Control read ahead activity. (none, random, [linear], both)",
+ "Control read ahead activity (none, random, [linear], both). [from 1.0.5: random read ahead is ignored]",
NULL, innodb_read_ahead_update, 2, &read_ahead_typelib);
static
@@ -10463,8 +10666,8 @@ TYPELIB adaptive_checkpoint_typelib=
};
static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
PLUGIN_VAR_RQCMDARG,
- "Enable/Disable flushing along modified age. ([none], reflex, estimate)",
- NULL, innodb_adaptive_checkpoint_update, 0, &adaptive_checkpoint_typelib);
+ "Enable/Disable flushing along modified age. (none, reflex, [estimate])",
+ NULL, innodb_adaptive_checkpoint_update, 2, &adaptive_checkpoint_typelib);
static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_enable_unsafe_group_commit,
PLUGIN_VAR_RQCMDARG,
@@ -10486,6 +10689,11 @@ static MYSQL_SYSVAR_ULONG(dict_size_limi
"Limit the allocated memory for dictionary cache. (0: unlimited)",
NULL, NULL, 0, 0, LONG_MAX, 0);
+static MYSQL_SYSVAR_ULONG(relax_table_creation, srv_relax_table_creation,
+ PLUGIN_VAR_RQCMDARG,
+ "Relax limitation of column size at table creation as builtin InnoDB.",
+ NULL, NULL, 0, 0, 1, 0);
+
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
@@ -10498,6 +10706,7 @@ static struct st_mysql_sys_var* innobase
MYSQL_SYSVAR(doublewrite),
MYSQL_SYSVAR(extra_undoslots),
MYSQL_SYSVAR(fast_recovery),
+ MYSQL_SYSVAR(recovery_stats),
MYSQL_SYSVAR(fast_shutdown),
MYSQL_SYSVAR(file_io_threads),
MYSQL_SYSVAR(read_io_threads),
@@ -10522,6 +10731,8 @@ static struct st_mysql_sys_var* innobase
MYSQL_SYSVAR(adaptive_flushing),
MYSQL_SYSVAR(max_purge_lag),
MYSQL_SYSVAR(mirrored_log_groups),
+ MYSQL_SYSVAR(old_blocks_pct),
+ MYSQL_SYSVAR(old_blocks_time),
MYSQL_SYSVAR(open_files),
MYSQL_SYSVAR(overwrite_relay_log_info),
MYSQL_SYSVAR(rollback_on_timeout),
@@ -10548,6 +10759,7 @@ static struct st_mysql_sys_var* innobase
MYSQL_SYSVAR(ibuf_max_size),
MYSQL_SYSVAR(ibuf_active_contract),
MYSQL_SYSVAR(ibuf_accel_rate),
+ MYSQL_SYSVAR(checkpoint_age_target),
MYSQL_SYSVAR(flush_neighbor_pages),
MYSQL_SYSVAR(read_ahead),
MYSQL_SYSVAR(adaptive_checkpoint),
@@ -10560,6 +10772,7 @@ static struct st_mysql_sys_var* innobase
MYSQL_SYSVAR(read_ahead_threshold),
MYSQL_SYSVAR(io_capacity),
MYSQL_SYSVAR(use_purge_thread),
+ MYSQL_SYSVAR(relax_table_creation),
NULL
};
@@ -10591,6 +10804,7 @@ i_s_innodb_cmpmem,
i_s_innodb_cmpmem_reset,
i_s_innodb_table_stats,
i_s_innodb_index_stats,
+i_s_innodb_admin_command,
i_s_innodb_patches
mysql_declare_plugin_end;
=== modified file 'storage/xtradb/handler/ha_innodb.h'
--- a/storage/xtradb/handler/ha_innodb.h 2009-12-03 11:34:11 +0000
+++ b/storage/xtradb/handler/ha_innodb.h 2010-01-15 15:58:25 +0000
@@ -258,12 +258,14 @@ int thd_binlog_format(const MYSQL_THD th
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+#if MYSQL_VERSION_ID > 50140
/**
Check if binary logging is filtered for thread's current db.
@param thd Thread handle
@retval 1 the query is not filtered, 0 otherwise.
*/
bool thd_binlog_filter_ok(const MYSQL_THD thd);
+#endif /* MYSQL_VERSION_ID > 50140 */
}
typedef struct trx_struct trx_t;
@@ -289,6 +291,8 @@ trx_t*
innobase_trx_allocate(
/*==================*/
MYSQL_THD thd); /*!< in: user thread handle */
+
+
/*********************************************************************//**
This function checks each index name for a table against reserved
system default primary index name 'GEN_CLUST_INDEX'. If a name
=== modified file 'storage/xtradb/handler/handler0alter.cc'
--- a/storage/xtradb/handler/handler0alter.cc 2009-12-03 11:34:11 +0000
+++ b/storage/xtradb/handler/handler0alter.cc 2010-01-15 15:58:25 +0000
@@ -35,7 +35,6 @@ extern "C" {
}
#include "ha_innodb.h"
-#include "handler0vars.h"
/*************************************************************//**
Copies an InnoDB column to a MySQL field. This function is
@@ -629,7 +628,7 @@ ha_innobase::add_index(
ulint num_created = 0;
ibool dict_locked = FALSE;
ulint new_primary;
- ulint error;
+ int error;
DBUG_ENTER("ha_innobase::add_index");
ut_a(table);
@@ -668,7 +667,7 @@ ha_innobase::add_index(
if (UNIV_UNLIKELY(error)) {
err_exit:
mem_heap_free(heap);
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx_free_for_mysql(trx);
trx_commit_for_mysql(prebuilt->trx);
DBUG_RETURN(error);
@@ -766,10 +765,11 @@ err_exit:
ut_ad(error == DB_SUCCESS);
/* Commit the data dictionary transaction in order to release
- the table locks on the system tables. Unfortunately, this
- means that if MySQL crashes while creating a new primary key
- inside row_merge_build_indexes(), indexed_table will not be
- dropped on crash recovery. Thus, it will become orphaned. */
+ the table locks on the system tables. This means that if
+ MySQL crashes while creating a new primary key inside
+ row_merge_build_indexes(), indexed_table will not be dropped
+ by trx_rollback_active(). It will have to be recovered or
+ dropped by the database administrator. */
trx_commit_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
@@ -806,7 +806,7 @@ error_handling:
alter table t drop index b, add index (b);
The fix will have to parse the SQL and note that the index
- being added has the same name as the the one being dropped and
+ being added has the same name as the one being dropped and
ignore that in the dup index check.*/
//dict_table_check_for_dup_indexes(prebuilt->table);
#endif
@@ -868,6 +868,7 @@ error_handling:
indexed_table->n_mysql_handles_opened++;
error = row_merge_drop_table(trx, innodb_table);
+ innodb_table = indexed_table;
goto convert_error;
case DB_TOO_BIG_RECORD:
@@ -882,7 +883,9 @@ error:
/* fall through */
default:
if (new_primary) {
- row_merge_drop_table(trx, indexed_table);
+ if (indexed_table != innodb_table) {
+ row_merge_drop_table(trx, indexed_table);
+ }
} else {
if (!dict_locked) {
row_mysql_lock_data_dictionary(trx);
=== removed file 'storage/xtradb/handler/handler0vars.h'
--- a/storage/xtradb/handler/handler0vars.h 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/handler/handler0vars.h 1970-01-01 00:00:00 +0000
@@ -1,73 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2008, 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/*******************************************************************//**
-@file handler/handler0vars.h
-This file contains accessor functions for dynamic plugin on Windows.
-***********************************************************************/
-
-#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
-/*******************************************************************//**
-This is a list of externals that can not be resolved by delay loading.
-They have to be resolved indirectly via their addresses in the .map file.
-All of them are external variables. */
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_bin;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_latin1;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO* system_charset_info;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO* default_charset_info;
-//extern MYSQL_PLUGIN_IMPORT CHARSET_INFO** all_charsets;
-extern MYSQL_PLUGIN_IMPORT system_variables global_system_variables;
-//extern MYSQL_PLUGIN_IMPORT char* mysql_real_data_home;
-extern MYSQL_PLUGIN_IMPORT char* mysql_data_home;
-//extern MYSQL_PLUGIN_IMPORT char** tx_isolation_names;
-//extern MYSQL_PLUGIN_IMPORT char** binlog_format_names;
-//extern MYSQL_PLUGIN_IMPORT char reg_ext;
-extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
-extern MYSQL_PLUGIN_IMPORT key_map key_map_full;
-extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
-extern MYSQL_PLUGIN_IMPORT bool mysqld_embedded;
-extern MYSQL_PLUGIN_IMPORT uint lower_case_table_names;
-extern MYSQL_PLUGIN_IMPORT ulong specialflag;
-extern MYSQL_PLUGIN_IMPORT int my_umask;
-
-extern MYSQL_PLUGIN_IMPORT char *relay_log_info_file;
-
-/*
-#define my_charset_bin (*wdl_my_charset_bin)
-#define my_charset_latin1 (*wdl_my_charset_latin1)
-#define my_charset_filename (*wdl_my_charset_filename)
-#define system_charset_info (*wdl_system_charset_info)
-#define default_charset_info (*wdl_default_charset_info)
-#define all_charsets (wdl_all_charsets)
-#define global_system_variables (*wdl_global_system_variables)
-#define mysql_real_data_home (wdl_mysql_real_data_home)
-#define mysql_data_home (*wdl_mysql_data_home)
-#define tx_isolation_names (wdl_tx_isolation_names)
-#define binlog_format_names (wdl_binlog_format_names)
-#define reg_ext (wdl_reg_ext)
-#define LOCK_thread_count (*wdl_LOCK_thread_count)
-#define key_map_full (*wdl_key_map_full)
-#define mysql_tmpdir_list (*wdl_mysql_tmpdir_list)
-#define mysqld_embedded (*wdl_mysqld_embedded)
-*/
-//#define lower_case_table_names (*wdl_lower_case_table_names)
-//#define specialflag (*wdl_specialflag)
-//#define my_umask (*wdl_my_umask)
-
-#endif
=== modified file 'storage/xtradb/handler/i_s.cc'
--- a/storage/xtradb/handler/i_s.cc 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/handler/i_s.cc 2010-01-28 11:35:10 +0000
@@ -47,6 +47,7 @@ extern "C" {
#include "trx0rseg.h" /* for trx_rseg_struct */
#include "trx0sys.h" /* for trx_sys */
#include "dict0dict.h" /* for dict_sys */
+#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
/* from buf0buf.c */
struct buf_chunk_struct{
ulint mem_size; /* allocated size of the chunk */
@@ -56,7 +57,6 @@ struct buf_chunk_struct{
buf_block_t* blocks; /* array of buffer control blocks */
};
}
-#include "handler0vars.h"
static const char plugin_author[] = "Innobase Oy";
@@ -84,14 +84,16 @@ do { \
#define STRUCT_FLD(name, value) value
#endif
-static const ST_FIELD_INFO END_OF_ST_FIELD_INFO =
- {STRUCT_FLD(field_name, NULL),
- STRUCT_FLD(field_length, 0),
- STRUCT_FLD(field_type, MYSQL_TYPE_NULL),
- STRUCT_FLD(value, 0),
- STRUCT_FLD(field_flags, 0),
- STRUCT_FLD(old_name, ""),
- STRUCT_FLD(open_method, SKIP_OPEN_TABLE)};
+/* Don't use a static const variable here, as some C++ compilers (notably
+HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
+#define END_OF_ST_FIELD_INFO \
+ {STRUCT_FLD(field_name, NULL), \
+ STRUCT_FLD(field_length, 0), \
+ STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
+ STRUCT_FLD(value, 0), \
+ STRUCT_FLD(field_flags, 0), \
+ STRUCT_FLD(old_name, ""), \
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
/*
Use the following types mapping:
@@ -511,7 +513,7 @@ static ST_FIELD_INFO i_s_innodb_buffer_p
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
- {STRUCT_FLD(field_name, "accessed"),
+ {STRUCT_FLD(field_name, "access_time"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
@@ -728,7 +730,7 @@ i_s_innodb_buffer_pool_pages_fill(
field_store_string(table->field[0], page_type);
table->field[1]->store(block->page.space);
table->field[2]->store(block->page.offset);
- table->field[3]->store(block->page.LRU_position);
+ table->field[3]->store(0);
table->field[4]->store(block->page.buf_fix_count);
table->field[5]->store(block->page.flush_type);
@@ -817,11 +819,11 @@ i_s_innodb_buffer_pool_pages_index_fill(
table->field[5]->store(page_get_n_recs(frame));
table->field[6]->store(page_get_data_size(frame));
table->field[7]->store(block->is_hashed);
- table->field[8]->store(block->page.accessed);
+ table->field[8]->store(block->page.access_time);
table->field[9]->store(block->page.newest_modification != 0);
table->field[10]->store(block->page.oldest_modification != 0);
table->field[11]->store(block->page.old);
- table->field[12]->store(block->page.LRU_position);
+ table->field[12]->store(0);
table->field[13]->store(block->page.buf_fix_count);
table->field[14]->store(block->page.flush_type);
@@ -915,7 +917,7 @@ i_s_innodb_buffer_pool_pages_blob_fill(
table->field[4]->store(block->page.offset);
}
- table->field[5]->store(block->page.LRU_position);
+ table->field[5]->store(0);
table->field[6]->store(block->page.buf_fix_count);
table->field[7]->store(block->page.flush_type);
@@ -2953,3 +2955,170 @@ UNIV_INTERN struct st_mysql_plugin i_s_i
STRUCT_FLD(system_vars, NULL),
STRUCT_FLD(__reserved1, NULL)
};
+
+/***********************************************************************
+*/
+static ST_FIELD_INFO i_s_innodb_admin_command_info[] =
+{
+ {STRUCT_FLD(field_name, "result_message"),
+ STRUCT_FLD(field_length, 1024),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ END_OF_ST_FIELD_INFO
+};
+
+#ifndef INNODB_COMPATIBILITY_HOOKS
+#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS
+#endif
+
+extern "C" {
+char **thd_query(MYSQL_THD thd);
+}
+
+static
+int
+i_s_innodb_admin_command_fill(
+/*==========================*/
+ THD* thd,
+ TABLE_LIST* tables,
+ COND* cond)
+{
+ TABLE* i_s_table = (TABLE *) tables->table;
+ CHARSET_INFO *cs= system_charset_info;
+ char** query_str;
+ char* ptr;
+ char quote = '\0';
+ const char* command_head = "XTRA_";
+
+ DBUG_ENTER("i_s_innodb_admin_command_fill");
+
+ /* deny access to non-superusers */
+ if (check_global_access(thd, PROCESS_ACL)) {
+ DBUG_RETURN(0);
+ }
+
+ if(thd_sql_command(thd) != SQLCOM_SELECT) {
+ field_store_string(i_s_table->field[0],
+ "SELECT command is only accepted.");
+ goto end_func;
+ }
+
+ query_str = thd_query(thd);
+ ptr = *query_str;
+
+ for (; *ptr; ptr++) {
+ if (*ptr == quote) {
+ quote = '\0';
+ } else if (quote) {
+ } else if (*ptr == '`' || *ptr == '"') {
+ quote = *ptr;
+ } else {
+ long i;
+ for (i = 0; command_head[i]; i++) {
+ if (toupper((int)(unsigned char)(ptr[i]))
+ != toupper((int)(unsigned char)
+ (command_head[i]))) {
+ goto nomatch;
+ }
+ }
+ break;
+nomatch:
+ ;
+ }
+ }
+
+ if (!*ptr) {
+ field_store_string(i_s_table->field[0],
+ "No XTRA_* command in the SQL statement."
+ " Please add /*!XTRA_xxxx*/ to the SQL.");
+ goto end_func;
+ }
+
+ if (!strncasecmp("XTRA_HELLO", ptr, 10)) {
+ /* This is example command XTRA_HELLO */
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: administration command test for XtraDB"
+ " 'XTRA_HELLO' was detected.\n");
+
+ field_store_string(i_s_table->field[0],
+ "Hello!");
+ goto end_func;
+ }
+ else if (!strncasecmp("XTRA_LRU_DUMP", ptr, 13)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_DUMP'"
+ " was detected.\n");
+
+ if (buf_LRU_file_dump()) {
+ field_store_string(i_s_table->field[0],
+ "XTRA_LRU_DUMP was succeeded.");
+ } else {
+ field_store_string(i_s_table->field[0],
+ "XTRA_LRU_DUMP was failed.");
+ }
+
+ goto end_func;
+ }
+ else if (!strncasecmp("XTRA_LRU_RESTORE", ptr, 16)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_RESTORE'"
+ " was detected.\n");
+
+ if (buf_LRU_file_restore()) {
+ field_store_string(i_s_table->field[0],
+ "XTRA_LRU_RESTORE was succeeded.");
+ } else {
+ field_store_string(i_s_table->field[0],
+ "XTRA_LRU_RESTORE was failed.");
+ }
+
+ goto end_func;
+ }
+
+ field_store_string(i_s_table->field[0],
+ "Undefined XTRA_* command.");
+ goto end_func;
+
+end_func:
+ if (schema_table_store_record(thd, i_s_table)) {
+ DBUG_RETURN(1);
+ } else {
+ DBUG_RETURN(0);
+ }
+}
+
+static
+int
+i_s_innodb_admin_command_init(
+/*==========================*/
+ void* p)
+{
+ DBUG_ENTER("i_s_innodb_admin_command_init");
+ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
+
+ schema->fields_info = i_s_innodb_admin_command_info;
+ schema->fill_table = i_s_innodb_admin_command_fill;
+
+ DBUG_RETURN(0);
+}
+
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_admin_command =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "XtraDB specific command acceptor"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_admin_command_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(__reserved1, NULL)
+};
=== modified file 'storage/xtradb/handler/i_s.h'
--- a/storage/xtradb/handler/i_s.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/handler/i_s.h 2009-11-04 20:11:12 +0000
@@ -40,5 +40,6 @@ extern struct st_mysql_plugin i_s_innodb
extern struct st_mysql_plugin i_s_innodb_rseg;
extern struct st_mysql_plugin i_s_innodb_table_stats;
extern struct st_mysql_plugin i_s_innodb_index_stats;
+extern struct st_mysql_plugin i_s_innodb_admin_command;
#endif /* i_s_h */
=== modified file 'storage/xtradb/handler/innodb_patch_info.h'
--- a/storage/xtradb/handler/innodb_patch_info.h 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/handler/innodb_patch_info.h 2010-01-15 15:58:25 +0000
@@ -38,5 +38,10 @@ struct innodb_enhancement {
{"innodb_stats","Additional features about InnoDB statistics/optimizer","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_relax_table_creation","Relax limitation of column size at table creation as builtin InnoDB.","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
{NULL, NULL, NULL, NULL}
};
=== removed file 'storage/xtradb/handler/win_delay_loader.cc'
--- a/storage/xtradb/handler/win_delay_loader.cc 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/handler/win_delay_loader.cc 1970-01-01 00:00:00 +0000
@@ -1,1024 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2008, 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/*******************************************************************//**
-@file handler/win_delay_loader.cc
-This file contains functions that implement the delay loader on Windows.
-
-This is a customized version of delay loader with limited functionalities.
-It does not support:
-
-* (manual) unloading
-* multiple delay loaded DLLs
-* multiple loading of the same DLL
-
-This delay loader is used only by the InnoDB plugin. Other components (DLLs)
-can still use the default delay loader, provided by MSVC.
-
-Several acronyms used by Microsoft:
- * IAT: import address table
- * INT: import name table
- * RVA: Relative Virtual Address
-
-See http://msdn.microsoft.com/en-us/magazine/bb985992.aspx for details of
-PE format.
-***********************************************************************/
-#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# include <delayimp.h>
-# include <mysql_priv.h>
-
-extern "C" {
-# include "univ.i"
-# include "hash0hash.h"
-}
-
-/*******************************************************************//**
-This following contains a list of externals that can not be resolved by
-delay loading. They have to be resolved indirectly via their addresses
-in the .map file. All of them are external variables. */
-CHARSET_INFO* wdl_my_charset_bin;
-CHARSET_INFO* wdl_my_charset_latin1;
-CHARSET_INFO* wdl_my_charset_filename;
-CHARSET_INFO** wdl_system_charset_info;
-CHARSET_INFO** wdl_default_charset_info;
-CHARSET_INFO** wdl_all_charsets;
-system_variables* wdl_global_system_variables;
-char* wdl_mysql_real_data_home;
-char** wdl_mysql_data_home;
-char** wdl_tx_isolation_names;
-char** wdl_binlog_format_names;
-char* wdl_reg_ext;
-pthread_mutex_t* wdl_LOCK_thread_count;
-key_map* wdl_key_map_full;
-MY_TMPDIR* wdl_mysql_tmpdir_list;
-bool* wdl_mysqld_embedded;
-uint* wdl_lower_case_table_names;
-ulong* wdl_specialflag;
-int* wdl_my_umask;
-
-/*******************************************************************//**
-The preferred load-address defined in PE (portable executable format). */
-#if defined(_M_IA64)
-#pragma section(".base", long, read)
-extern "C"
-__declspec(allocate(".base"))
-const IMAGE_DOS_HEADER __ImageBase;
-#else
-extern "C"
-const IMAGE_DOS_HEADER __ImageBase;
-#endif
-
-/*******************************************************************//**
-A template function for converting a relative address (RVA) to an
-absolute address (VA). This is due to the pointers in the delay
-descriptor (ImgDelayDescr in delayimp.h) have been changed from
-VAs to RVAs to work on both 32- and 64-bit platforms.
-@return absolute virtual address */
-template <class X>
-X PFromRva(
-/*=======*/
- RVA rva) /*!< in: relative virtual address */
-{
- return X(PBYTE(&__ImageBase) + rva);
-}
-
-/*******************************************************************//**
-Convert to the old format for convenience. The structure as well as its
-element names follow the definition of ImgDelayDescr in delayimp.h. */
-struct InternalImgDelayDescr
-{
- DWORD grAttrs; /*!< attributes */
- LPCSTR szName; /*!< pointer to dll name */
- HMODULE* phmod; /*!< address of module handle */
- PImgThunkData pIAT; /*!< address of the IAT */
- PCImgThunkData pINT; /*!< address of the INT */
- PCImgThunkData pBoundIAT; /*!< address of the optional bound IAT */
- PCImgThunkData pUnloadIAT; /*!< address of optional copy of
- original IAT */
- DWORD dwTimeStamp; /*!< 0 if not bound,
- otherwise date/time stamp of DLL
- bound to (Old BIND) */
-};
-
-typedef struct map_hash_chain_struct map_hash_chain_t;
-
-struct map_hash_chain_struct {
- char* symbol; /*!< pointer to a symbol */
- ulint value; /*!< address of the symbol */
- map_hash_chain_t* next; /*!< pointer to the next cell
- in the same folder. */
- map_hash_chain_t* chain; /*!< a linear chain used for
- cleanup. */
-};
-
-static HMODULE my_hmod = 0;
-static struct hash_table_struct* m_htbl = NULL ;
-static map_hash_chain_t* chain_header = NULL;
-static ibool wdl_init = FALSE;
-const ulint MAP_HASH_CELLS_NUM = 10000;
-
-#ifndef DBUG_OFF
-/*******************************************************************//**
-In the dynamic plugin, it is required to call the following dbug functions
-in the server:
- _db_pargs_
- _db_doprnt_
- _db_enter_
- _db_return_
- _db_dump_
-
-The plugin will get those function pointers during the initialization. */
-typedef void (__cdecl* pfn_db_enter_)(
- const char* _func_,
- const char* _file_,
- uint _line_,
- const char** _sfunc_,
- const char** _sfile_,
- uint* _slevel_,
- char***);
-
-typedef void (__cdecl* pfn_db_return_)(
- uint _line_,
- const char** _sfunc_,
- const char** _sfile_,
- uint* _slevel_);
-
-typedef void (__cdecl* pfn_db_pargs_)(
- uint _line_,
- const char* keyword);
-
-typedef void (__cdecl* pfn_db_doprnt_)(
- const char* format,
- ...);
-
-typedef void (__cdecl* pfn_db_dump_)(
- uint _line_,
- const char* keyword,
- const unsigned char* memory,
- size_t length);
-
-static pfn_db_enter_ wdl_db_enter_;
-static pfn_db_return_ wdl_db_return_;
-static pfn_db_pargs_ wdl_db_pargs_;
-static pfn_db_doprnt_ wdl_db_doprnt_;
-static pfn_db_dump_ wdl_db_dump_;
-#endif /* !DBUG_OFF */
-
-/*************************************************************//**
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n.
-
-This is the same function as hash_create in hash0hash.c, except the
-memory allocation. This function is invoked before the engine is
-initialized, and buffer pools are not ready yet.
-@return own: created hash table */
-static
-hash_table_t*
-wdl_hash_create(
-/*============*/
- ulint n) /*!< in: number of array cells */
-{
- hash_cell_t* array;
- ulint prime;
- hash_table_t* table;
-
- prime = ut_find_prime(n);
-
- table = (hash_table_t*) malloc(sizeof(hash_table_t));
- if (table == NULL) {
- return(NULL);
- }
-
- array = (hash_cell_t*) malloc(sizeof(hash_cell_t) * prime);
- if (array == NULL) {
- free(table);
- return(NULL);
- }
-
- table->array = array;
- table->n_cells = prime;
- table->n_mutexes = 0;
- table->mutexes = NULL;
- table->heaps = NULL;
- table->heap = NULL;
- table->magic_n = HASH_TABLE_MAGIC_N;
-
- /* Initialize the cell array */
- hash_table_clear(table);
-
- return(table);
-}
-
-/*************************************************************//**
-Frees a hash table. */
-static
-void
-wdl_hash_table_free(
-/*================*/
- hash_table_t* table) /*!< in, own: hash table */
-{
- ut_a(table != NULL);
- ut_a(table->mutexes == NULL);
-
- free(table->array);
- free(table);
-}
-
-/*******************************************************************//**
-Function for calculating the count of imports given the base of the IAT.
-@return number of imports */
-static
-ulint
-wdl_import_count(
-/*=============*/
- PCImgThunkData pitd_base) /*!< in: base of the IAT */
-{
- ulint ret = 0;
- PCImgThunkData pitd = pitd_base;
-
- while (pitd->u1.Function) {
- pitd++;
- ret++;
- }
-
- return(ret);
-}
-
-/*******************************************************************//**
-Read Mapfile to a hashtable for faster access
-@return TRUE if the mapfile is loaded successfully. */
-static
-ibool
-wdl_load_mapfile(
-/*=============*/
- const char* filename) /*!< in: name of the mapfile. */
-{
- FILE* fp;
- const size_t nSize = 256;
- char tmp_buf[nSize];
- char* func_name;
- char* func_addr;
- ulint load_addr = 0;
- ibool valid_load_addr = FALSE;
-#ifdef _WIN64
- const char* tmp_string = " Preferred load address is %16llx";
-#else
- const char* tmp_string = " Preferred load address is %08x";
-#endif
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
-
- return(FALSE);
- }
-
- /* Check whether to create the hashtable */
- if (m_htbl == NULL) {
-
- m_htbl = wdl_hash_create(MAP_HASH_CELLS_NUM);
-
- if (m_htbl == NULL) {
-
- fclose(fp);
- return(FALSE);
- }
- }
-
- /* Search start of symbol list and get the preferred load address */
- while (fgets(tmp_buf, sizeof(tmp_buf), fp)) {
-
- if (sscanf(tmp_buf, tmp_string, &load_addr) == 1) {
-
- valid_load_addr = TRUE;
- }
-
- if (strstr(tmp_buf, "Rva+Base") != NULL) {
-
- break;
- }
- }
-
- if (valid_load_addr == FALSE) {
-
- /* No "Preferred load address", the map file is wrong. */
- fclose(fp);
- return(FALSE);
- }
-
- /* Read symbol list */
- while (fgets(tmp_buf, sizeof(tmp_buf), fp))
- {
- map_hash_chain_t* map_cell;
- ulint map_fold;
-
- if (*tmp_buf == 0) {
-
- continue;
- }
-
- func_name = strtok(tmp_buf, " ");
- func_name = strtok(NULL, " ");
- func_addr = strtok(NULL, " ");
-
- if (func_name && func_addr) {
-
- ut_snprintf(tmp_buf, nSize, "0x%s", func_addr);
- if (*func_name == '_') {
-
- func_name++;
- }
-
- map_cell = (map_hash_chain_t*)
- malloc(sizeof(map_hash_chain_t));
- if (map_cell == NULL) {
- return(FALSE);
- }
-
- /* Chain all cells together */
- map_cell->chain = chain_header;
- chain_header = map_cell;
-
- map_cell->symbol = strdup(func_name);
- map_cell->value = (ulint) _strtoui64(tmp_buf, NULL, 0)
- - load_addr;
- map_fold = ut_fold_string(map_cell->symbol);
-
- HASH_INSERT(map_hash_chain_t,
- next,
- m_htbl,
- map_fold,
- map_cell);
- }
- }
-
- fclose(fp);
-
- return(TRUE);
-}
-
-/*************************************************************//**
-Cleanup.during DLL unload */
-static
-void
-wdl_cleanup(void)
-/*=============*/
-{
- while (chain_header != NULL) {
- map_hash_chain_t* tmp;
-
- tmp = chain_header->chain;
- free(chain_header->symbol);
- free(chain_header);
- chain_header = tmp;
- }
-
- if (m_htbl != NULL) {
-
- wdl_hash_table_free(m_htbl);
- }
-}
-
-/*******************************************************************//**
-Load the mapfile mysqld.map.
-@return the module handle */
-static
-HMODULE
-wdl_get_mysqld_mapfile(void)
-/*========================*/
-{
- char file_name[MAX_PATH];
- char* ext;
- ulint err;
-
- if (my_hmod == 0) {
-
- size_t nSize = MAX_PATH - strlen(".map") -1;
-
- /* First find out the name of current executable */
- my_hmod = GetModuleHandle(NULL);
- if (my_hmod == 0) {
-
- return(my_hmod);
- }
-
- err = GetModuleFileName(my_hmod, file_name, nSize);
- if (err == 0) {
-
- my_hmod = 0;
- return(my_hmod);
- }
-
- ext = strrchr(file_name, '.');
- if (ext != NULL) {
-
- *ext = 0;
- strcat(file_name, ".map");
-
- err = wdl_load_mapfile(file_name);
- if (err == 0) {
-
- my_hmod = 0;
- }
- } else {
-
- my_hmod = 0;
- }
- }
-
- return(my_hmod);
-}
-
-/*******************************************************************//**
-Retrieves the address of an exported function. It follows the convention
-of GetProcAddress().
-@return address of exported function. */
-static
-FARPROC
-wdl_get_procaddr_from_map(
-/*======================*/
- HANDLE m_handle, /*!< in: module handle */
- const char* import_proc) /*!< in: procedure name */
-{
- map_hash_chain_t* hash_chain;
- ulint map_fold;
-
- map_fold = ut_fold_string(import_proc);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
- if (hash_chain == NULL) {
-
-#ifdef _WIN64
- /* On Win64, the leading '_' may not be taken out. In this
- case, search again without the leading '_'. */
- if (*import_proc == '_') {
-
- import_proc++;
- }
-
- map_fold = ut_fold_string(import_proc);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
- if (hash_chain == NULL) {
-#endif
- if (wdl_init == TRUE) {
-
- sql_print_error(
- "InnoDB: the procedure pointer of %s"
- " is not found.",
- import_proc);
- }
-
- return(0);
-#ifdef _WIN64
- }
-#endif
- }
-
- return((FARPROC) ((ulint) m_handle + hash_chain->value));
-}
-
-/*******************************************************************//**
-Retrieves the address of an exported variable.
-Note: It does not follow the Windows call convention FARPROC.
-@return address of exported variable. */
-static
-void*
-wdl_get_varaddr_from_map(
-/*=====================*/
- HANDLE m_handle, /*!< in: module handle */
- const char* import_variable) /*!< in: variable name */
-{
- map_hash_chain_t* hash_chain;
- ulint map_fold;
-
- map_fold = ut_fold_string(import_variable);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
- if (hash_chain == NULL) {
-
-#ifdef _WIN64
- /* On Win64, the leading '_' may not be taken out. In this
- case, search again without the leading '_'. */
- if (*import_variable == '_') {
-
- import_variable++;
- }
-
- map_fold = ut_fold_string(import_variable);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
- if (hash_chain == NULL) {
-#endif
- if (wdl_init == TRUE) {
-
- sql_print_error(
- "InnoDB: the variable address of %s"
- " is not found.",
- import_variable);
- }
-
- return(0);
-#ifdef _WIN64
- }
-#endif
- }
-
- return((void*) ((ulint) m_handle + hash_chain->value));
-}
-
-/*******************************************************************//**
-Bind all unresolved external variables from the MySQL executable.
-@return TRUE if successful */
-static
-bool
-wdl_get_external_variables(void)
-/*============================*/
-{
- HMODULE hmod = wdl_get_mysqld_mapfile();
-
- if (hmod == 0) {
-
- return(FALSE);
- }
-
-#define GET_SYM(sym, var, type) \
- var = (type*) wdl_get_varaddr_from_map(hmod, sym); \
- if (var == NULL) return(FALSE)
-#ifdef _WIN64
-#define GET_SYM2(sym1, sym2, var, type) \
- var = (type*) wdl_get_varaddr_from_map(hmod, sym1); \
- if (var == NULL) return(FALSE)
-#else
-#define GET_SYM2(sym1, sym2, var, type) \
- var = (type*) wdl_get_varaddr_from_map(hmod, sym2); \
- if (var == NULL) return(FALSE)
-#endif // (_WIN64)
-#define GET_C_SYM(sym, type) GET_SYM(#sym, wdl_##sym, type)
-#define GET_PROC_ADDR(sym) \
- wdl##sym = (pfn##sym) wdl_get_procaddr_from_map(hmod, #sym)
-
- GET_C_SYM(my_charset_bin, CHARSET_INFO);
- GET_C_SYM(my_charset_latin1, CHARSET_INFO);
- GET_C_SYM(my_charset_filename, CHARSET_INFO);
- GET_C_SYM(default_charset_info, CHARSET_INFO*);
- GET_C_SYM(all_charsets, CHARSET_INFO*);
- GET_C_SYM(my_umask, int);
-
- GET_SYM("?global_system_variables@@3Usystem_variables@@A",
- wdl_global_system_variables, struct system_variables);
- GET_SYM("?mysql_real_data_home@@3PADA",
- wdl_mysql_real_data_home, char);
- GET_SYM("?reg_ext@@3PADA", wdl_reg_ext, char);
- GET_SYM("?LOCK_thread_count@@3U_RTL_CRITICAL_SECTION@@A",
- wdl_LOCK_thread_count, pthread_mutex_t);
- GET_SYM("?key_map_full@@3V?$Bitmap@$0EA@@@A",
- wdl_key_map_full, key_map);
- GET_SYM("?mysql_tmpdir_list@@3Ust_my_tmpdir@@A",
- wdl_mysql_tmpdir_list, MY_TMPDIR);
- GET_SYM("?mysqld_embedded@@3_NA",
- wdl_mysqld_embedded, bool);
- GET_SYM("?lower_case_table_names@@3IA",
- wdl_lower_case_table_names, uint);
- GET_SYM("?specialflag@@3KA", wdl_specialflag, ulong);
-
- GET_SYM2("?system_charset_info@@3PEAUcharset_info_st@@EA",
- "?system_charset_info@@3PAUcharset_info_st@@A",
- wdl_system_charset_info, CHARSET_INFO*);
- GET_SYM2("?mysql_data_home@@3PEADEA",
- "?mysql_data_home@@3PADA",
- wdl_mysql_data_home, char*);
- GET_SYM2("?tx_isolation_names@@3PAPEBDA",
- "?tx_isolation_names@@3PAPBDA",
- wdl_tx_isolation_names, char*);
- GET_SYM2("?binlog_format_names@@3PAPEBDA",
- "?binlog_format_names@@3PAPBDA",
- wdl_binlog_format_names, char*);
-
-#ifndef DBUG_OFF
- GET_PROC_ADDR(_db_enter_);
- GET_PROC_ADDR(_db_return_);
- GET_PROC_ADDR(_db_pargs_);
- GET_PROC_ADDR(_db_doprnt_);
- GET_PROC_ADDR(_db_dump_);
-
- /* If any of the dbug functions is not available, just make them
- all invalid. This is the case when working with a non-debug
- version of the server. */
- if (wdl_db_enter_ == NULL || wdl_db_return_ == NULL
- || wdl_db_pargs_ == NULL || wdl_db_doprnt_ == NULL
- || wdl_db_dump_ == NULL) {
-
- wdl_db_enter_ = NULL;
- wdl_db_return_ = NULL;
- wdl_db_pargs_ = NULL;
- wdl_db_doprnt_ = NULL;
- wdl_db_dump_ = NULL;
- }
-#endif /* !DBUG_OFF */
-
- wdl_init = TRUE;
- return(TRUE);
-
-#undef GET_SYM
-#undef GET_SYM2
-#undef GET_C_SYM
-#undef GET_PROC_ADDR
-}
-
-/*******************************************************************//**
-The DLL Delayed Loading Helper Function for resolving externals.
-
-The function may fail due to one of the three reasons:
-
-* Invalid parameter, which happens if the attributes in pidd aren't
- specified correctly.
-* Failed to load the map file mysqld.map.
-* Failed to find an external name in the map file mysqld.map.
-
-Note: this function is called by run-time as well as __HrLoadAllImportsForDll.
-So, it has to follow Windows call convention.
-@return the address of the imported function */
-extern "C"
-FARPROC WINAPI
-__delayLoadHelper2(
-/*===============*/
- PCImgDelayDescr pidd, /*!< in: a const pointer to a
- ImgDelayDescr, see delayimp.h. */
- FARPROC* iat_entry) /*!< in/out: A pointer to the slot in
- the delay load import address table
- to be updated with the address of the
- imported function. */
-{
- ulint iIAT, iINT;
- HMODULE hmod;
- PCImgThunkData pitd;
- FARPROC fun = NULL;
-
- /* Set up data used for the hook procs */
- InternalImgDelayDescr idd = {
- pidd->grAttrs,
- PFromRva<LPCSTR>(pidd->rvaDLLName),
- PFromRva<HMODULE*>(pidd->rvaHmod),
- PFromRva<PImgThunkData>(pidd->rvaIAT),
- PFromRva<PCImgThunkData>(pidd->rvaINT),
- PFromRva<PCImgThunkData>(pidd->rvaBoundIAT),
- PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT),
- pidd->dwTimeStamp
- };
-
- DelayLoadInfo dli = {
- sizeof(DelayLoadInfo),
- pidd,
- iat_entry,
- idd.szName,
- {0},
- 0,
- 0,
- 0
- };
-
- /* Check the Delay Load Attributes, log an error of invalid
- parameter, which happens if the attributes in pidd are not
- specified correctly. */
- if ((idd.grAttrs & dlattrRva) == 0) {
-
- sql_print_error("InnoDB: invalid parameter for delay loader.");
- return(0);
- }
-
- hmod = *idd.phmod;
-
- /* Calculate the index for the IAT entry in the import address table.
- The INT entries are ordered the same as the IAT entries so the
- calculation can be done on the IAT side. */
- iIAT = (PCImgThunkData) iat_entry - idd.pIAT;
- iINT = iIAT;
-
- pitd = &(idd.pINT[iINT]);
-
- dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal);
-
- if (dli.dlp.fImportByName) {
-
- dli.dlp.szProcName = (LPCSTR) (PFromRva<PIMAGE_IMPORT_BY_NAME>
- ((RVA) ((UINT_PTR) pitd->u1.AddressOfData))->Name);
- } else {
-
- dli.dlp.dwOrdinal = (ulint) IMAGE_ORDINAL(pitd->u1.Ordinal);
- }
-
- /* Now, load the mapfile, if it has not been done yet */
- if (hmod == 0) {
-
- hmod = wdl_get_mysqld_mapfile();
- }
-
- if (hmod == 0) {
- /* LoadLibrary failed. */
- PDelayLoadInfo rgpdli[1] = {&dli};
-
- dli.dwLastError = ::GetLastError();
-
- sql_print_error(
- "InnoDB: failed to load mysqld.map with error %d.",
- dli.dwLastError);
-
- return(0);
- }
-
- /* Store the library handle. */
- idd.phmod = &hmod;
-
- /* Go for the procedure now. */
- dli.hmodCur = hmod;
-
- if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
-
- /* Bound imports exist, check the timestamp from the target
- image */
- PIMAGE_NT_HEADERS pinh;
-
- pinh = (PIMAGE_NT_HEADERS) ((byte*) hmod
- + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
-
- if (pinh->Signature == IMAGE_NT_SIGNATURE
- && pinh->FileHeader.TimeDateStamp == idd.dwTimeStamp
- && (DWORD) hmod == pinh->OptionalHeader.ImageBase) {
-
- /* We have a decent address in the bound IAT. */
- fun = (FARPROC) (UINT_PTR)
- idd.pBoundIAT[iIAT].u1.Function;
-
- if (fun) {
-
- *iat_entry = fun;
- return(fun);
- }
- }
- }
-
- fun = wdl_get_procaddr_from_map(hmod, dli.dlp.szProcName);
-
- if (fun == 0) {
-
- return(0);
- }
-
- *iat_entry = fun;
- return(fun);
-}
-
-/*******************************************************************//**
-Unload a DLL that was delay loaded. This function is called by run-time.
-@return TRUE is returned if the DLL is found and the IAT matches the
-original one. */
-extern "C"
-BOOL WINAPI
-__FUnloadDelayLoadedDLL2(
-/*=====================*/
- LPCSTR module_name) /*!< in: DLL name */
-{
- return(TRUE);
-}
-
-/**************************************************************//**
-Load all imports from a DLL that was specified with the /delayload linker
-option.
-Note: this function is called by run-time. So, it has to follow Windows call
-convention.
-@return S_OK if the DLL matches, otherwise ERROR_MOD_NOT_FOUND is returned. */
-extern "C"
-HRESULT WINAPI
-__HrLoadAllImportsForDll(
-/*=====================*/
- LPCSTR module_name) /*!< in: DLL name */
-{
- PIMAGE_NT_HEADERS img;
- PCImgDelayDescr pidd;
- IMAGE_DATA_DIRECTORY* image_data;
- LPCSTR current_module;
- HRESULT ret = ERROR_MOD_NOT_FOUND;
- HMODULE hmod = (HMODULE) &__ImageBase;
-
- img = (PIMAGE_NT_HEADERS) ((byte*) hmod
- + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
- image_data =
- &img->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
-
- /* Scan the delay load IAT/INT for the DLL */
- if (image_data->Size) {
-
- pidd = PFromRva<PCImgDelayDescr>(image_data->VirtualAddress);
-
- /* Check all of the listed DLLs we want to load. */
- while (pidd->rvaDLLName) {
-
- current_module = PFromRva<LPCSTR>(pidd->rvaDLLName);
-
- if (stricmp(module_name, current_module) == 0) {
-
- /* Found it, break out with pidd and
- current_module set appropriately */
- break;
- }
-
- /* To the next delay import descriptor */
- pidd++;
- }
-
- if (pidd->rvaDLLName) {
-
- /* Found a matching DLL, now process it. */
- FARPROC* iat_entry;
- size_t count;
-
- iat_entry = PFromRva<FARPROC*>(pidd->rvaIAT);
- count = wdl_import_count((PCImgThunkData) iat_entry);
-
- /* now load all the imports from the DLL */
- while (count > 0) {
-
- /* No need to check the return value */
- __delayLoadHelper2(pidd, iat_entry);
- iat_entry++;
- count--;
- }
-
- ret = S_OK;
- }
- }
-
- return ret;
-}
-
-/**************************************************************//**
-The main function of a DLL
-@return TRUE if the call succeeds */
-BOOL
-WINAPI
-DllMain(
-/*====*/
- HINSTANCE hinstDLL, /*!< in: handle to the DLL module */
- DWORD fdwReason, /*!< Reason code that indicates why the
- DLL entry-point function is being
- called.*/
- LPVOID lpvReserved) /*!< in: additional parameter based on
- fdwReason */
-{
- BOOL success = TRUE;
-
- switch (fdwReason) {
-
- case DLL_PROCESS_ATTACH:
- success = wdl_get_external_variables();
- break;
-
- case DLL_PROCESS_DETACH:
- wdl_cleanup();
- break;
- }
-
- return(success);
-}
-
-#ifndef DBUG_OFF
-/**************************************************************//**
-Process entry point to user function. It makes the call to _db_enter_
-in mysqld.exe. The DBUG functions are defined in my_dbug.h. */
-extern "C" UNIV_INTERN
-void
-_db_enter_(
- const char* _func_, /*!< in: current function name */
- const char* _file_, /*!< in: current file name */
- uint _line_, /*!< in: current source line number */
- const char** _sfunc_, /*!< out: previous _func_ */
- const char** _sfile_, /*!< out: previous _file_ */
- uint* _slevel_, /*!< out: previous nesting level */
- char*** _sframep_) /*!< out: previous frame pointer */
-{
- if (wdl_db_enter_ != NULL) {
-
- wdl_db_enter_(_func_, _file_, _line_, _sfunc_, _sfile_,
- _slevel_, _sframep_);
- }
-}
-
-/**************************************************************//**
-Process exit from user function. It makes the call to _db_return_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_return_(
- uint _line_, /*!< in: current source line number */
- const char** _sfunc_, /*!< out: previous _func_ */
- const char** _sfile_, /*!< out: previous _file_ */
- uint* _slevel_) /*!< out: previous level */
-{
- if (wdl_db_return_ != NULL) {
-
- wdl_db_return_(_line_, _sfunc_, _sfile_, _slevel_);
- }
-}
-
-/**************************************************************//**
-Log arguments for subsequent use. It makes the call to _db_pargs_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_pargs_(
- uint _line_, /*!< in: current source line number */
- const char* keyword) /*!< in: keyword for current macro */
-{
- if (wdl_db_pargs_ != NULL) {
-
- wdl_db_pargs_(_line_, keyword);
- }
-}
-
-/**************************************************************//**
-Handle print of debug lines. It saves the text into a buffer first,
-then makes the call to _db_doprnt_() in the server. The text is
-truncated to the size of buffer. */
-extern "C" UNIV_INTERN
-void
-_db_doprnt_(
- const char* format, /*!< in: the format string */
- ...) /*!< in: list of arguments */
-{
- va_list argp;
- char buffer[512];
-
- if (wdl_db_doprnt_ != NULL) {
-
- va_start(argp, format);
- /* it is ok to ignore the trunction. */
- _vsnprintf(buffer, sizeof(buffer), format, argp);
- wdl_db_doprnt_(buffer);
- va_end(argp);
- }
-}
-
-/**************************************************************//**
-Dump a string in hex. It makes the call to _db_dump_() in the server. */
-extern "C" UNIV_INTERN
-void
-_db_dump_(
- uint _line_, /*!< in: current source line
- number */
- const char* keyword, /*!< in: keyword list */
- const unsigned char* memory, /*!< in: memory to dump */
- size_t length) /*!< in: bytes to dump */
-{
- if (wdl_db_dump_ != NULL) {
-
- wdl_db_dump_(_line_, keyword, memory, length);
- }
-}
-
-#endif /* !DBUG_OFF */
-#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
=== modified file 'storage/xtradb/ibuf/ibuf0ibuf.c'
--- a/storage/xtradb/ibuf/ibuf0ibuf.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/ibuf/ibuf0ibuf.c 2010-01-15 15:58:25 +0000
@@ -390,6 +390,27 @@ ibuf_count_set(
#endif
/******************************************************************//**
+Closes insert buffer and frees the data structures. */
+UNIV_INTERN
+void
+ibuf_close(void)
+/*============*/
+{
+ mutex_free(&ibuf_pessimistic_insert_mutex);
+ memset(&ibuf_pessimistic_insert_mutex,
+ 0x0, sizeof(ibuf_pessimistic_insert_mutex));
+
+ mutex_free(&ibuf_mutex);
+ memset(&ibuf_mutex, 0x0, sizeof(ibuf_mutex));
+
+ mutex_free(&ibuf_bitmap_mutex);
+ memset(&ibuf_bitmap_mutex, 0x0, sizeof(ibuf_mutex));
+
+ mem_free(ibuf);
+ ibuf = NULL;
+}
+
+/******************************************************************//**
Updates the size information of the ibuf, assuming the segment size has not
changed. */
static
=== modified file 'storage/xtradb/include/btr0cur.h'
--- a/storage/xtradb/include/btr0cur.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/btr0cur.h 2010-01-06 12:00:14 +0000
@@ -618,7 +618,7 @@ enum btr_cur_method {
hash_node, and might be necessary to
update */
BTR_CUR_BINARY, /*!< success using the binary search */
- BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to
+ BTR_CUR_INSERT_TO_IBUF /*!< performed the intended insert to
the insert buffer */
};
=== modified file 'storage/xtradb/include/btr0sea.h'
--- a/storage/xtradb/include/btr0sea.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/btr0sea.h 2010-01-06 12:00:14 +0000
@@ -41,6 +41,12 @@ void
btr_search_sys_create(
/*==================*/
ulint hash_size); /*!< in: hash index hash table size */
+/*****************************************************************//**
+Frees the adaptive search system at a database shutdown. */
+UNIV_INTERN
+void
+btr_search_sys_free(void);
+/*=====================*/
/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
=== modified file 'storage/xtradb/include/buf0buf.h'
--- a/storage/xtradb/include/buf0buf.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/buf0buf.h 2010-01-06 12:00:14 +0000
@@ -346,7 +346,7 @@ buf_page_release(
mtr_t* mtr); /*!< in: mtr */
/********************************************************************//**
Moves a page to the start of the buffer pool LRU list. This high-level
-function can be used to prevent an important page from from slipping out of
+function can be used to prevent an important page from slipping out of
the buffer pool. */
UNIV_INTERN
void
@@ -707,15 +707,6 @@ buf_page_belongs_to_unzip_LRU(
/*==========================*/
const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
-/*********************************************************************//**
-Determine the approximate LRU list position of a block.
-@return LRU list position */
-UNIV_INLINE
-ulint
-buf_page_get_LRU_position(
-/*======================*/
- const buf_page_t* bpage) /*!< in: control block */
- __attribute__((pure));
/*********************************************************************//**
Gets the mutex of a block.
@@ -825,14 +816,14 @@ buf_page_set_old(
buf_page_t* bpage, /*!< in/out: control block */
ibool old); /*!< in: old */
/*********************************************************************//**
-Determine if a block has been accessed in the buffer pool.
-@return TRUE if accessed */
+Determine the time of first access of a block in the buffer pool.
+@return ut_time_ms() at the time of first access, 0 if not accessed */
UNIV_INLINE
-ibool
+unsigned
buf_page_is_accessed(
/*=================*/
const buf_page_t* bpage) /*!< in: control block */
- __attribute__((pure));
+ __attribute__((nonnull, pure));
/*********************************************************************//**
Flag a block accessed. */
UNIV_INLINE
@@ -840,7 +831,8 @@ void
buf_page_set_accessed(
/*==================*/
buf_page_t* bpage, /*!< in/out: control block */
- ibool accessed); /*!< in: accessed */
+ ulint time_ms) /*!< in: ut_time_ms() */
+ __attribute__((nonnull));
/*********************************************************************//**
Gets the buf_block_t handle of a buffered file block if an uncompressed
page frame exists, or NULL.
@@ -1026,14 +1018,6 @@ buf_block_hash_get(
/*===============*/
ulint space, /*!< in: space id */
ulint offset);/*!< in: offset of the page within space */
-/*******************************************************************//**
-Increments the pool clock by one and returns its new value. Remember that
-in the 32 bit version the clock wraps around at 4 billion!
-@return new clock value */
-UNIV_INLINE
-ulint
-buf_pool_clock_tic(void);
-/*====================*/
/*********************************************************************//**
Gets the current length of the free list of buffer blocks.
@return length of the free list */
@@ -1073,16 +1057,10 @@ struct buf_page_struct{
flushed to disk, this tells the
flush_type.
@see enum buf_flush */
- unsigned accessed:1; /*!< TRUE if the page has been accessed
- while in the buffer pool: read-ahead
- may read in pages which have not been
- accessed yet; a thread is allowed to
- read this for heuristic purposes
- without holding any mutex or latch */
unsigned io_fix:2; /*!< type of pending I/O operation;
also protected by buf_pool_mutex
@see enum buf_io_fix */
- unsigned buf_fix_count:24;/*!< count of how manyfold this block
+ unsigned buf_fix_count:25;/*!< count of how manyfold this block
is currently bufferfixed */
/* @} */
#endif /* !UNIV_HOTBACKUP */
@@ -1112,7 +1090,16 @@ struct buf_page_struct{
- BUF_BLOCK_FILE_PAGE: flush_list
- BUF_BLOCK_ZIP_DIRTY: flush_list
- BUF_BLOCK_ZIP_PAGE: zip_clean
- - BUF_BLOCK_ZIP_FREE: zip_free[] */
+ - BUF_BLOCK_ZIP_FREE: zip_free[]
+
+ The contents of the list node
+ is undefined if !in_flush_list
+ && state == BUF_BLOCK_FILE_PAGE,
+ or if state is one of
+ BUF_BLOCK_MEMORY,
+ BUF_BLOCK_REMOVE_HASH or
+ BUF_BLOCK_READY_IN_USE. */
+
/* resplit for optimistic use */
UT_LIST_NODE_T(buf_page_t) free;
UT_LIST_NODE_T(buf_page_t) flush_list;
@@ -1155,18 +1142,8 @@ struct buf_page_struct{
debugging */
//#endif /* UNIV_DEBUG */
unsigned old:1; /*!< TRUE if the block is in the old
- blocks in the LRU list */
- unsigned LRU_position:31;/*!< value which monotonically
- decreases (or may stay
- constant if old==TRUE) toward
- the end of the LRU list, if
- buf_pool->ulint_clock has not
- wrapped around: NOTE that this
- value can only be used in
- heuristic algorithms, because
- of the possibility of a
- wrap-around! */
- unsigned freed_page_clock:32;/*!< the value of
+ blocks in buf_pool->LRU_old */
+ unsigned freed_page_clock:31;/*!< the value of
buf_pool->freed_page_clock
when this block was the last
time put to the head of the
@@ -1174,6 +1151,9 @@ struct buf_page_struct{
to read this for heuristic
purposes without holding any
mutex or latch */
+ unsigned access_time:32; /*!< time of first access, or
+ 0 if the block was never accessed
+ in the buffer pool */
/* @} */
# ifdef UNIV_DEBUG_FILE_ACCESSES
ibool file_page_was_freed;
@@ -1318,6 +1298,31 @@ Compute the hash fold value for blocks i
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
/* @} */
+/** @brief The buffer pool statistics structure. */
+struct buf_pool_stat_struct{
+ ulint n_page_gets; /*!< number of page gets performed;
+ also successful searches through
+ the adaptive hash index are
+ counted as page gets; this field
+ is NOT protected by the buffer
+ pool mutex */
+ ulint n_pages_read; /*!< number read operations */
+ ulint n_pages_written;/*!< number write operations */
+ ulint n_pages_created;/*!< number of pages created
+ in the pool with no read */
+ ulint n_ra_pages_read;/*!< number of pages read in
+ as part of read ahead */
+ ulint n_ra_pages_evicted;/*!< number of read ahead
+ pages that are evicted without
+ being accessed */
+ ulint n_pages_made_young; /*!< number of pages made young, in
+ calls to buf_LRU_make_block_young() */
+ ulint n_pages_not_made_young; /*!< number of pages not made
+ young because the first access
+ was not long enough ago, in
+ buf_page_peek_if_too_old() */
+};
+
/** @brief The buffer pool structure.
NOTE! The definition appears here only for other modules of this
@@ -1342,28 +1347,16 @@ struct buf_pool_struct{
ulint n_pend_reads; /*!< number of pending read operations */
ulint n_pend_unzip; /*!< number of pending decompressions */
- time_t last_printout_time; /*!< when buf_print was last time
+ time_t last_printout_time;
+ /*!< when buf_print_io was last time
called */
- ulint n_pages_read; /*!< number read operations */
- ulint n_pages_written;/*!< number write operations */
- ulint n_pages_created;/*!< number of pages created
- in the pool with no read */
- ulint n_page_gets; /*!< number of page gets performed;
- also successful searches through
- the adaptive hash index are
- counted as page gets; this field
- is NOT protected by the buffer
- pool mutex */
- ulint n_page_gets_old;/*!< n_page_gets when buf_print was
- last time called: used to calculate
- hit rate */
- ulint n_pages_read_old;/*!< n_pages_read when buf_print was
- last time called */
- ulint n_pages_written_old;/*!< number write operations */
- ulint n_pages_created_old;/*!< number of pages created in
- the pool with no read */
+ buf_pool_stat_t stat; /*!< current statistics */
+ buf_pool_stat_t old_stat; /*!< old statistics */
+
/* @} */
+
/** @name Page flushing algorithm fields */
+
/* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
@@ -1379,10 +1372,6 @@ struct buf_pool_struct{
/*!< this is in the set state
when there is no flush batch
of the given type running */
- ulint ulint_clock; /*!< a sequence number used to count
- time. NOTE! This counter wraps
- around at 4 billion (if ulint ==
- 32 bits)! */
ulint freed_page_clock;/*!< a sequence number used
to count the number of buffer
blocks removed from the end of
@@ -1406,17 +1395,18 @@ struct buf_pool_struct{
block list */
UT_LIST_BASE_NODE_T(buf_page_t) LRU;
/*!< base node of the LRU list */
- buf_page_t* LRU_old; /*!< pointer to the about 3/8 oldest
- blocks in the LRU list; NULL if LRU
- length less than BUF_LRU_OLD_MIN_LEN;
+ buf_page_t* LRU_old; /*!< pointer to the about
+ buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
+ oldest blocks in the LRU list;
+ NULL if LRU length less than
+ BUF_LRU_OLD_MIN_LEN;
NOTE: when LRU_old != NULL, its length
should always equal LRU_old_len */
ulint LRU_old_len; /*!< length of the LRU list from
the block to which LRU_old points
onward, including that block;
see buf0lru.c for the restrictions
- on this value; not defined if
- LRU_old == NULL;
+ on this value; 0 if LRU_old == NULL;
NOTE: LRU_old_len must be adjusted
whenever LRU_old shrinks or grows! */
=== modified file 'storage/xtradb/include/buf0buf.ic'
--- a/storage/xtradb/include/buf0buf.ic 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/include/buf0buf.ic 2010-01-15 15:58:25 +0000
@@ -72,9 +72,30 @@ buf_page_peek_if_too_old(
/*=====================*/
const buf_page_t* bpage) /*!< in: block to make younger */
{
- return(buf_pool->freed_page_clock
- >= buf_page_get_freed_page_clock(bpage)
- + 1 + (buf_pool->curr_size / 4));
+ if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
+ /* If eviction has not started yet, do not update the
+ statistics or move blocks in the LRU list. This is
+ either the warm-up phase or an in-memory workload. */
+ return(FALSE);
+ } else if (buf_LRU_old_threshold_ms && bpage->old) {
+ unsigned access_time = buf_page_is_accessed(bpage);
+
+ if (access_time > 0
+ && (ut_time_ms() - access_time)
+ >= buf_LRU_old_threshold_ms) {
+ return(TRUE);
+ }
+
+ buf_pool->stat.n_pages_not_made_young++;
+ return(FALSE);
+ } else {
+ /* FIXME: bpage->freed_page_clock is 31 bits */
+ return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
+ > ((ulint) bpage->freed_page_clock
+ + (buf_pool->curr_size
+ * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio)
+ / (BUF_LRU_OLD_RATIO_DIV * 4))));
+ }
}
/*********************************************************************//**
@@ -125,23 +146,6 @@ try_again:
return(lsn);
}
-
-/*******************************************************************//**
-Increments the buf_pool clock by one and returns its new value. Remember
-that in the 32 bit version the clock wraps around at 4 billion!
-@return new clock value */
-UNIV_INLINE
-ulint
-buf_pool_clock_tic(void)
-/*====================*/
-{
- //ut_ad(buf_pool_mutex_own());
- ut_ad(mutex_own(&LRU_list_mutex));
-
- buf_pool->ulint_clock++;
-
- return(buf_pool->ulint_clock);
-}
#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
@@ -288,21 +292,6 @@ buf_page_belongs_to_unzip_LRU(
}
/*********************************************************************//**
-Determine the approximate LRU list position of a block.
-@return LRU list position */
-UNIV_INLINE
-ulint
-buf_page_get_LRU_position(
-/*======================*/
- const buf_page_t* bpage) /*!< in: control block */
-{
- ut_ad(buf_page_in_file(bpage));
- //ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
-
- return(bpage->LRU_position);
-}
-
-/*********************************************************************//**
Gets the mutex of a block.
@return pointer to mutex protecting bpage */
UNIV_INLINE
@@ -508,10 +497,19 @@ buf_page_set_old(
ut_ad(bpage->in_LRU_list);
#ifdef UNIV_LRU_DEBUG
- if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)
- && UT_LIST_GET_PREV(LRU, bpage)->old
- == UT_LIST_GET_NEXT(LRU, bpage)->old) {
- ut_a(UT_LIST_GET_PREV(LRU, bpage)->old == old);
+ ut_a((buf_pool->LRU_old_len == 0) == (buf_pool->LRU_old == NULL));
+ /* If a block is flagged "old", the LRU_old list must exist. */
+ ut_a(!old || buf_pool->LRU_old);
+
+ if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)) {
+ const buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
+ const buf_page_t* next = UT_LIST_GET_NEXT(LRU, bpage);
+ if (prev->old == next->old) {
+ ut_a(prev->old == old);
+ } else {
+ ut_a(!prev->old);
+ ut_a(buf_pool->LRU_old == (old ? bpage : next));
+ }
}
#endif /* UNIV_LRU_DEBUG */
@@ -519,17 +517,17 @@ buf_page_set_old(
}
/*********************************************************************//**
-Determine if a block has been accessed in the buffer pool.
-@return TRUE if accessed */
+Determine the time of first access of a block in the buffer pool.
+@return ut_time_ms() at the time of first access, 0 if not accessed */
UNIV_INLINE
-ibool
+unsigned
buf_page_is_accessed(
/*=================*/
const buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_page_in_file(bpage));
- return(bpage->accessed);
+ return(bpage->access_time);
}
/*********************************************************************//**
@@ -539,12 +537,16 @@ void
buf_page_set_accessed(
/*==================*/
buf_page_t* bpage, /*!< in/out: control block */
- ibool accessed) /*!< in: accessed */
+ ulint time_ms) /*!< in: ut_time_ms() */
{
ut_a(buf_page_in_file(bpage));
+ //ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
- bpage->accessed = accessed;
+ if (!bpage->access_time) {
+ /* Make this the time of the first access. */
+ bpage->access_time = time_ms;
+ }
}
/*********************************************************************//**
@@ -825,15 +827,15 @@ buf_page_get_newest_modification(
ib_uint64_t lsn;
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
- ut_a(block_mutex);
-
- if (buf_page_in_file(bpage)) {
+ if (block_mutex && buf_page_in_file(bpage)) {
lsn = bpage->newest_modification;
} else {
lsn = 0;
}
- mutex_exit(block_mutex);
+ if (block_mutex) {
+ mutex_exit(block_mutex);
+ }
return(lsn);
}
=== modified file 'storage/xtradb/include/buf0lru.h'
--- a/storage/xtradb/include/buf0lru.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/buf0lru.h 2010-01-06 12:00:14 +0000
@@ -69,7 +69,7 @@ These are low-level functions
#########################################################################*/
/** Minimum LRU list length for which the LRU_old pointer is defined */
-#define BUF_LRU_OLD_MIN_LEN 80
+#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
/** Maximum LRU list search length in buf_flush_LRU_recommendation() */
#define BUF_LRU_FREE_SEARCH_LEN (5 + 2 * BUF_READ_AHEAD_AREA)
@@ -84,15 +84,6 @@ void
buf_LRU_invalidate_tablespace(
/*==========================*/
ulint id); /*!< in: space id */
-/******************************************************************//**
-Gets the minimum LRU_position field for the blocks in an initial segment
-(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around.
-@return the limit; zero if could not determine it */
-UNIV_INTERN
-ulint
-buf_LRU_get_recent_limit(void);
-/*==========================*/
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
@@ -203,6 +194,18 @@ void
buf_LRU_make_block_old(
/*===================*/
buf_page_t* bpage); /*!< in: control block */
+/**********************************************************************//**
+Updates buf_LRU_old_ratio.
+@return updated old_pct */
+UNIV_INTERN
+uint
+buf_LRU_old_ratio_update(
+/*=====================*/
+ uint old_pct,/*!< in: Reserve this percentage of
+ the buffer pool for "old" blocks. */
+ ibool adjust);/*!< in: TRUE=adjust the LRU list;
+ FALSE=just assign buf_LRU_old_ratio
+ during the initialization of InnoDB */
/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
@@ -210,6 +213,18 @@ UNIV_INTERN
void
buf_LRU_stat_update(void);
/*=====================*/
+/********************************************************************//**
+Dump the LRU page list to the specific file. */
+UNIV_INTERN
+ibool
+buf_LRU_file_dump(void);
+/*===================*/
+/********************************************************************//**
+Read the pages based on the specific file.*/
+UNIV_INTERN
+ibool
+buf_LRU_file_restore(void);
+/*======================*/
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************//**
@@ -229,6 +244,35 @@ buf_LRU_print(void);
/*===============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
+/** @name Heuristics for detecting index scan @{ */
+/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
+"old" blocks. Protected by buf_pool_mutex. */
+extern uint buf_LRU_old_ratio;
+/** The denominator of buf_LRU_old_ratio. */
+#define BUF_LRU_OLD_RATIO_DIV 1024
+/** Maximum value of buf_LRU_old_ratio.
+@see buf_LRU_old_adjust_len
+@see buf_LRU_old_ratio_update */
+#define BUF_LRU_OLD_RATIO_MAX BUF_LRU_OLD_RATIO_DIV
+/** Minimum value of buf_LRU_old_ratio.
+@see buf_LRU_old_adjust_len
+@see buf_LRU_old_ratio_update
+The minimum must exceed
+(BUF_LRU_OLD_TOLERANCE + 5) * BUF_LRU_OLD_RATIO_DIV / BUF_LRU_OLD_MIN_LEN. */
+#define BUF_LRU_OLD_RATIO_MIN 51
+
+#if BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX
+# error "BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX"
+#endif
+#if BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV
+# error "BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV"
+#endif
+
+/** Move blocks to "new" LRU list only if the first access was at
+least this many milliseconds ago. Not protected by any mutex or latch. */
+extern uint buf_LRU_old_threshold_ms;
+/* @} */
+
/** @brief Statistics for selecting the LRU list for eviction.
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
=== modified file 'storage/xtradb/include/buf0rea.h'
--- a/storage/xtradb/include/buf0rea.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/buf0rea.h 2010-01-06 12:00:14 +0000
@@ -27,28 +27,59 @@ Created 11/5/1995 Heikki Tuuri
#define buf0rea_h
#include "univ.i"
+#include "trx0types.h"
#include "buf0types.h"
/********************************************************************//**
+Low-level function which reads a page asynchronously from a file to the
+buffer buf_pool if it is not already there, in which case does nothing.
+Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
+flag is cleared and the x-lock released by an i/o-handler thread.
+@return 1 if a read request was queued, 0 if the page already resided
+in buf_pool, or if the page is in the doublewrite buffer blocks in
+which case it is never read into the pool, or if the tablespace does
+not exist or is being dropped
+@return 1 if read request is issued. 0 if it is not */
+UNIV_INTERN
+ulint
+buf_read_page_low(
+/*==============*/
+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
+ trying to read from a non-existent tablespace, or a
+ tablespace which is just now being dropped */
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
+ ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
+ at read-ahead functions) */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ ibool unzip, /*!< in: TRUE=request uncompressed page */
+ ib_int64_t tablespace_version, /*!< in: if the space memory object has
+ this timestamp different from what we are giving here,
+ treat the tablespace as dropped; this is a timestamp we
+ use to stop dangling page reads from a tablespace
+ which we have DISCARDed + IMPORTed back */
+ ulint offset, /*!< in: page number */
+ trx_t* trx);
+/********************************************************************//**
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible.
-@return number of page read requests issued: this can be greater than
-1 if read-ahead occurred */
+released by the i/o-handler thread.
+@return TRUE if page has been read in, FALSE in case of failure */
UNIV_INTERN
-ulint
+ibool
buf_read_page(
/*==========*/
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
- ulint offset);/*!< in: page number */
+ ulint offset, /*!< in: page number */
+ trx_t* trx);
/********************************************************************//**
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
-that the the algorithm looks at the 'natural' adjacent successor and
+that the algorithm looks at the 'natural' adjacent successor and
predecessor of the page, which on the leaf level of a B-tree are the next
and previous page in the chain of leaves. To know these, the page specified
in (space, offset) must already be present in the buf_pool. Thus, the
@@ -74,8 +105,9 @@ buf_read_ahead_linear(
/*==================*/
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
- ulint offset);/*!< in: page number of a page; NOTE: the current thread
+ ulint offset, /*!< in: page number of a page; NOTE: the current thread
must want access to this page (see NOTE 3 above) */
+ trx_t* trx);
/********************************************************************//**
Issues read requests for pages which the ibuf module wants to read in, in
order to contract the insert buffer tree. Technically, this function is like
=== modified file 'storage/xtradb/include/buf0types.h'
--- a/storage/xtradb/include/buf0types.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/buf0types.h 2010-01-06 12:00:14 +0000
@@ -34,6 +34,8 @@ typedef struct buf_block_struct buf_blo
typedef struct buf_chunk_struct buf_chunk_t;
/** Buffer pool comprising buf_chunk_t */
typedef struct buf_pool_struct buf_pool_t;
+/** Buffer pool statistics struct */
+typedef struct buf_pool_stat_struct buf_pool_stat_t;
/** A buffer frame. @see page_t */
typedef byte buf_frame_t;
=== modified file 'storage/xtradb/include/db0err.h'
--- a/storage/xtradb/include/db0err.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/db0err.h 2010-01-06 12:00:14 +0000
@@ -32,6 +32,7 @@ enum db_err {
/* The following are error codes */
DB_ERROR,
+ DB_INTERRUPTED,
DB_OUT_OF_MEMORY,
DB_OUT_OF_FILE_SPACE,
DB_LOCK_WAIT,
=== modified file 'storage/xtradb/include/dict0crea.h'
--- a/storage/xtradb/include/dict0crea.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/dict0crea.h 2010-01-06 12:00:14 +0000
@@ -110,7 +110,7 @@ dict_create_or_check_foreign_constraint_
Adds foreign key definitions to data dictionary tables in the database. We
look at table->foreign_list, and also generate names to constraints that were
not named by the user. A generated constraint has a name of the format
-databasename/tablename_ibfk_<number>, where the numbers start from 1, and are
+databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and are
given locally for this table, that is, the number is not global, as in the
old format constraints < 4.0.18 it used to be.
@return error code or DB_SUCCESS */
=== modified file 'storage/xtradb/include/dict0dict.h'
--- a/storage/xtradb/include/dict0dict.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/dict0dict.h 2010-01-06 12:00:14 +0000
@@ -712,7 +712,7 @@ dict_index_find_on_id_low(
dulint id); /*!< in: index id */
/**********************************************************************//**
Adds an index to the dictionary cache.
-@return DB_SUCCESS or error code */
+@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
UNIV_INTERN
ulint
dict_index_add_to_cache(
@@ -1157,6 +1157,13 @@ void
dict_ind_init(void);
/*===============*/
+/**********************************************************************//**
+Closes the data dictionary module. */
+UNIV_INTERN
+void
+dict_close(void);
+/*============*/
+
#ifndef UNIV_NONINL
#include "dict0dict.ic"
#endif
=== modified file 'storage/xtradb/include/dict0mem.h'
--- a/storage/xtradb/include/dict0mem.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/dict0mem.h 2010-01-06 12:00:14 +0000
@@ -317,7 +317,7 @@ struct dict_foreign_struct{
char* id; /*!< id of the constraint as a
null-terminated string */
unsigned n_fields:10; /*!< number of indexes' first fields
- for which the the foreign key
+ for which the foreign key
constraint is defined: we allow the
indexes to contain more fields than
mentioned in the constraint, as long
=== modified file 'storage/xtradb/include/fil0fil.h'
--- a/storage/xtradb/include/fil0fil.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/fil0fil.h 2010-01-06 12:00:14 +0000
@@ -224,15 +224,6 @@ fil_space_create(
0 for uncompressed tablespaces */
ulint purpose);/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
/*******************************************************************//**
-Frees a space object from a the tablespace memory cache. Closes the files in
-the chain but does not delete them.
-@return TRUE if success */
-UNIV_INTERN
-ibool
-fil_space_free(
-/*===========*/
- ulint id); /*!< in: space id */
-/*******************************************************************//**
Returns the size of the space in pages. The tablespace must be cached in the
memory cache.
@return space size, 0 if space not found */
@@ -278,6 +269,12 @@ fil_init(
ulint hash_size, /*!< in: hash table size */
ulint max_n_open); /*!< in: max number of open files */
/*******************************************************************//**
+Initializes the tablespace memory cache. */
+UNIV_INTERN
+void
+fil_close(void);
+/*===========*/
+/*******************************************************************//**
Opens all log files and system tablespace data files. They stay open until the
database server shutdown. This should be called at a server startup after the
space objects for the log and the system tablespace have been created. The
@@ -614,9 +611,12 @@ fil_space_get_n_reserved_extents(
Reads or writes data. This operation is asynchronous (aio).
@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
i/o on a tablespace which does not exist */
+#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message) \
+ _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, NULL)
+
UNIV_INTERN
ulint
-fil_io(
+_fil_io(
/*===*/
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
@@ -641,8 +641,25 @@ fil_io(
void* buf, /*!< in/out: buffer where to store read data
or from where to write; in aio this must be
appropriately aligned */
- void* message); /*!< in: message for aio handler if non-sync
+ void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
+ trx_t* trx);
+/********************************************************************//**
+Confirm whether the parameters are valid or not */
+UNIV_INTERN
+ibool
+fil_area_is_exist(
+/*==============*/
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
+ 0 for uncompressed pages */
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
+ aio this must be divisible by the OS block
+ size */
+ ulint len); /*!< in: how many bytes to read or write; this
+ must not cross a file boundary; in aio this
+ must be a block size multiple */
/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
handler for completed requests. The aio array of pending requests is divided
=== modified file 'storage/xtradb/include/fsp0fsp.h'
--- a/storage/xtradb/include/fsp0fsp.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/fsp0fsp.h 2010-01-06 12:00:14 +0000
@@ -42,7 +42,7 @@ fsp_init(void);
/*==========*/
/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
-means the place of the first page which has never been put to the the
+means the place of the first page which has never been put to the
free list for allocation. The space above that address is initialized
to zero. Sets also the global variable log_fsp_current_free_limit.
@return free limit in megabytes */
=== modified file 'storage/xtradb/include/ibuf0ibuf.h'
--- a/storage/xtradb/include/ibuf0ibuf.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ibuf0ibuf.h 2010-01-06 12:00:14 +0000
@@ -356,6 +356,12 @@ void
ibuf_print(
/*=======*/
FILE* file); /*!< in: file where to print */
+/******************************************************************//**
+Closes insert buffer and frees the data structures. */
+UNIV_INTERN
+void
+ibuf_close(void);
+/*============*/
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
=== modified file 'storage/xtradb/include/lock0lock.h'
--- a/storage/xtradb/include/lock0lock.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/lock0lock.h 2010-01-06 12:00:14 +0000
@@ -59,6 +59,12 @@ lock_sys_create(
/*============*/
ulint n_cells); /*!< in: number of slots in lock hash table */
/*********************************************************************//**
+Closes the lock system at database shutdown. */
+UNIV_INTERN
+void
+lock_sys_close(void);
+/*================*/
+/*********************************************************************//**
Checks if some transaction has an implicit x-lock on a record in a clustered
index.
@return transaction which has the x-lock, or NULL */
@@ -630,6 +636,14 @@ lock_number_of_rows_locked(
/*=======================*/
trx_t* trx); /*!< in: transaction */
/*******************************************************************//**
+Check if a transaction holds any autoinc locks.
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+ const trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
void
=== modified file 'storage/xtradb/include/log0log.h'
--- a/storage/xtradb/include/log0log.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/log0log.h 2010-01-06 12:00:14 +0000
@@ -118,10 +118,9 @@ UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
- byte* str, /*!< in: string */
+ const void* str, /*!< in: string */
ulint len, /*!< in: string length */
- ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
- ibool* success);/*!< out: TRUE if success */
+ ib_uint64_t* start_lsn);/*!< out: start lsn of the log record */
/***********************************************************************//**
Releases the log mutex. */
UNIV_INLINE
@@ -283,7 +282,7 @@ log_make_checkpoint_at(
later lsn, if IB_ULONGLONG_MAX, makes
a checkpoint at the latest lsn */
ibool write_always); /*!< in: the function normally checks if
- the the new checkpoint would have a
+ the new checkpoint would have a
greater lsn than the previous one: if
not, then no physical write is done;
by setting this parameter TRUE, a
@@ -573,6 +572,18 @@ UNIV_INTERN
void
log_refresh_stats(void);
/*===================*/
+/**********************************************************
+Shutdown the log system but do not release all the memory. */
+UNIV_INTERN
+void
+log_shutdown(void);
+/*==============*/
+/**********************************************************
+Free the log system data structures. */
+UNIV_INTERN
+void
+log_mem_free(void);
+/*==============*/
extern log_t* log_sys;
@@ -585,7 +596,7 @@ extern log_t* log_sys;
#define LOG_RECOVER 98887331
/* The counting of lsn's starts from this value: this must be non-zero */
-#define LOG_START_LSN ((ib_uint64_t) (16 * OS_FILE_LOG_BLOCK_SIZE))
+#define LOG_START_LSN ((ib_uint64_t) (16 * OS_FILE_LOG_BLOCK_SIZE))
#define LOG_BUFFER_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE)
#define LOG_ARCHIVE_BUF_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE / 4)
@@ -722,9 +733,12 @@ struct log_group_struct{
ulint lsn_offset; /*!< the offset of the above lsn */
ulint n_pending_writes;/*!< number of currently pending flush
writes for this log group */
+ byte** file_header_bufs_ptr;/*!< unaligned buffers */
byte** file_header_bufs;/*!< buffers for each file
header in the group */
+#ifdef UNIV_LOG_ARCHIVE
/*-----------------------------*/
+ byte** archive_file_header_bufs_ptr;/*!< unaligned buffers */
byte** archive_file_header_bufs;/*!< buffers for each file
header in the group */
ulint archive_space_id;/*!< file space which
@@ -743,10 +757,12 @@ struct log_group_struct{
completion function then sets the new
value to ..._file_no */
ulint next_archived_offset; /*!< like the preceding field */
+#endif /* UNIV_LOG_ARCHIVE */
/*-----------------------------*/
ib_uint64_t scanned_lsn; /*!< used only in recovery: recovery scan
succeeded up to this lsn in this log
group */
+ byte* checkpoint_buf_ptr;/*!< unaligned checkpoint header */
byte* checkpoint_buf; /*!< checkpoint header is written from
this buffer to the group */
UT_LIST_NODE_T(log_group_t)
@@ -764,6 +780,7 @@ struct log_struct{
#ifndef UNIV_HOTBACKUP
mutex_t mutex; /*!< mutex protecting the log */
#endif /* !UNIV_HOTBACKUP */
+ byte* buf_ptr; /* unaligned log buffer */
byte* buf; /*!< log buffer */
ulint buf_size; /*!< log buffer size in bytes */
ulint max_buf_free; /*!< recommended maximum value of
@@ -900,6 +917,7 @@ struct log_struct{
should wait for this without owning
the log mutex */
#endif /* !UNIV_HOTBACKUP */
+ byte* checkpoint_buf_ptr;/* unaligned checkpoint header */
byte* checkpoint_buf; /*!< checkpoint header is read to this
buffer */
/* @} */
=== modified file 'storage/xtradb/include/log0log.ic'
--- a/storage/xtradb/include/log0log.ic 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/log0log.ic 2010-01-06 12:00:14 +0000
@@ -27,6 +27,7 @@ Created 12/9/1995 Heikki Tuuri
#include "mach0data.h"
#include "mtr0mtr.h"
+#ifdef UNIV_LOG_DEBUG
/******************************************************//**
Checks by parsing that the catenated log segment for a single mtr is
consistent. */
@@ -34,11 +35,12 @@ UNIV_INTERN
ibool
log_check_log_recs(
/*===============*/
- byte* buf, /*!< in: pointer to the start of
+ const byte* buf, /*!< in: pointer to the start of
the log segment in the
log_sys->buf log buffer */
ulint len, /*!< in: segment length in bytes */
ib_uint64_t buf_start_lsn); /*!< in: buffer start lsn */
+#endif /* UNIV_LOG_DEBUG */
/************************************************************//**
Gets a log block flush bit.
@@ -305,55 +307,76 @@ UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
- byte* str, /*!< in: string */
+ const void* str, /*!< in: string */
ulint len, /*!< in: string length */
- ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
- ibool* success)/*!< out: TRUE if success */
+ ib_uint64_t* start_lsn)/*!< out: start lsn of the log record */
{
- log_t* log = log_sys;
ulint data_len;
- ib_uint64_t lsn;
-
- *success = TRUE;
-
- mutex_enter(&(log->mutex));
-
- data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
+#ifdef UNIV_LOG_LSN_DEBUG
+ /* length of the LSN pseudo-record */
+ ulint lsn_len = 1
+ + mach_get_compressed_size(log_sys->lsn >> 32)
+ + mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
+#endif /* UNIV_LOG_LSN_DEBUG */
+
+ mutex_enter(&log_sys->mutex);
+
+ data_len = len
+#ifdef UNIV_LOG_LSN_DEBUG
+ + lsn_len
+#endif /* UNIV_LOG_LSN_DEBUG */
+ + log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE;
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
/* The string does not fit within the current log block
or the log block would become full */
- *success = FALSE;
-
- mutex_exit(&(log->mutex));
+ mutex_exit(&log_sys->mutex);
return(0);
}
- *start_lsn = log->lsn;
+ *start_lsn = log_sys->lsn;
+
+#ifdef UNIV_LOG_LSN_DEBUG
+ {
+ /* Write the LSN pseudo-record. */
+ byte* b = &log_sys->buf[log_sys->buf_free];
+ *b++ = MLOG_LSN | (MLOG_SINGLE_REC_FLAG & *(const byte*) str);
+ /* Write the LSN in two parts,
+ as a pseudo page number and space id. */
+ b += mach_write_compressed(b, log_sys->lsn >> 32);
+ b += mach_write_compressed(b, log_sys->lsn & 0xFFFFFFFFUL);
+ ut_a(b - lsn_len == &log_sys->buf[log_sys->buf_free]);
- ut_memcpy(log->buf + log->buf_free, str, len);
+ memcpy(b, str, len);
+ len += lsn_len;
+ }
+#else /* UNIV_LOG_LSN_DEBUG */
+ memcpy(log_sys->buf + log_sys->buf_free, str, len);
+#endif /* UNIV_LOG_LSN_DEBUG */
- log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
+ log_block_set_data_len((byte*) ut_align_down(log_sys->buf
+ + log_sys->buf_free,
OS_FILE_LOG_BLOCK_SIZE),
data_len);
#ifdef UNIV_LOG_DEBUG
- log->old_buf_free = log->buf_free;
- log->old_lsn = log->lsn;
+ log_sys->old_buf_free = log_sys->buf_free;
+ log_sys->old_lsn = log_sys->lsn;
#endif
- log->buf_free += len;
+ log_sys->buf_free += len;
- ut_ad(log->buf_free <= log->buf_size);
+ ut_ad(log_sys->buf_free <= log_sys->buf_size);
- lsn = log->lsn += len;
+ log_sys->lsn += len;
#ifdef UNIV_LOG_DEBUG
- log_check_log_recs(log->buf + log->old_buf_free,
- log->buf_free - log->old_buf_free, log->old_lsn);
+ log_check_log_recs(log_sys->buf + log_sys->old_buf_free,
+ log_sys->buf_free - log_sys->old_buf_free,
+ log_sys->old_lsn);
#endif
- return(lsn);
+ return(log_sys->lsn);
}
/***********************************************************************//**
=== modified file 'storage/xtradb/include/log0recv.h'
--- a/storage/xtradb/include/log0recv.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/log0recv.h 2010-01-06 12:00:14 +0000
@@ -239,6 +239,18 @@ UNIV_INTERN
void
recv_sys_create(void);
/*=================*/
+/**********************************************************//**
+Release recovery system mutexes. */
+UNIV_INTERN
+void
+recv_sys_close(void);
+/*================*/
+/********************************************************//**
+Frees the recovery system memory. */
+UNIV_INTERN
+void
+recv_sys_mem_free(void);
+/*===================*/
/********************************************************//**
Inits the recovery system for a recovery operation. */
UNIV_INTERN
@@ -246,6 +258,12 @@ void
recv_sys_init(
/*==========*/
ulint available_memory); /*!< in: available memory in bytes */
+/********************************************************//**
+Reset the state of the recovery system variables. */
+UNIV_INTERN
+void
+recv_sys_var_init(void);
+/*===================*/
/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
@@ -412,6 +430,39 @@ struct recv_sys_struct{
hash_table_t* addr_hash;/*!< hash table of file addresses of pages */
ulint n_addrs;/*!< number of not processed hashed file
addresses in the hash table */
+
+/* If you modified the following defines at original file,
+ You should also modify them. */
+/* defined in os0file.c */
+#define OS_AIO_MERGE_N_CONSECUTIVE 64
+/* defined in log0recv.c */
+#define RECV_READ_AHEAD_AREA 32
+ time_t stats_recv_start_time;
+ ulint stats_recv_turns;
+
+ ulint stats_read_requested_pages;
+ ulint stats_read_in_area[RECV_READ_AHEAD_AREA];
+
+ ulint stats_read_io_pages;
+ ulint stats_read_io_consecutive[OS_AIO_MERGE_N_CONSECUTIVE];
+ ulint stats_write_io_pages;
+ ulint stats_write_io_consecutive[OS_AIO_MERGE_N_CONSECUTIVE];
+
+ ulint stats_doublewrite_check_pages;
+ ulint stats_doublewrite_overwrite_pages;
+
+ ulint stats_recover_pages_with_read;
+ ulint stats_recover_pages_without_read;
+
+ ulint stats_log_recs;
+ ulint stats_log_len_sum;
+
+ ulint stats_applied_log_recs;
+ ulint stats_applied_log_len_sum;
+ ulint stats_pages_already_new;
+
+ ib_uint64_t stats_oldest_modified_lsn;
+ ib_uint64_t stats_newest_modified_lsn;
};
/** The recovery system */
@@ -433,6 +484,11 @@ are allowed yet: the variable name is mi
extern ibool recv_no_ibuf_operations;
/** TRUE when recv_init_crash_recovery() has been called. */
extern ibool recv_needed_recovery;
+#ifdef UNIV_DEBUG
+/** TRUE if writing to the redo log (mtr_commit) is forbidden.
+Protected by log_sys->mutex. */
+extern ibool recv_no_log_write;
+#endif /* UNIV_DEBUG */
/** TRUE if buf_page_is_corrupted() should check if the log sequence
number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
=== modified file 'storage/xtradb/include/mem0mem.h'
--- a/storage/xtradb/include/mem0mem.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/mem0mem.h 2010-01-06 12:00:14 +0000
@@ -82,6 +82,13 @@ void
mem_init(
/*=====*/
ulint size); /*!< in: common pool size in bytes */
+/******************************************************************//**
+Closes the memory system. */
+UNIV_INTERN
+void
+mem_close(void);
+/*===========*/
+
/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
=== modified file 'storage/xtradb/include/mem0pool.h'
--- a/storage/xtradb/include/mem0pool.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/mem0pool.h 2010-01-06 12:00:14 +0000
@@ -62,6 +62,13 @@ mem_pool_create(
/*============*/
ulint size); /*!< in: pool size in bytes */
/********************************************************************//**
+Frees a memory pool. */
+UNIV_INTERN
+void
+mem_pool_free(
+/*==========*/
+ mem_pool_t* pool); /*!< in, own: memory pool */
+/********************************************************************//**
Allocates memory from a pool. NOTE: This low-level function should only be
used in mem0mem.*!
@return own: allocated memory buffer */
=== modified file 'storage/xtradb/include/mtr0mtr.h'
--- a/storage/xtradb/include/mtr0mtr.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/mtr0mtr.h 2010-01-06 12:00:14 +0000
@@ -106,6 +106,9 @@ For 1 - 8 bytes, the flag value must giv
#define MLOG_IBUF_BITMAP_INIT ((byte)27) /*!< initialize an
ibuf bitmap page */
/*#define MLOG_FULL_PAGE ((byte)28) full contents of a page */
+#ifdef UNIV_LOG_LSN_DEBUG
+# define MLOG_LSN ((byte)28) /* current LSN */
+#endif
#define MLOG_INIT_FILE_PAGE ((byte)29) /*!< this means that a
file page is taken
into use and the prior
@@ -118,7 +121,7 @@ For 1 - 8 bytes, the flag value must giv
#define MLOG_WRITE_STRING ((byte)30) /*!< write a string to
a page */
#define MLOG_MULTI_REC_END ((byte)31) /*!< if a single mtr writes
- log records for several pages,
+ several log records,
this log record ends the
sequence of these records */
#define MLOG_DUMMY_RECORD ((byte)32) /*!< dummy log record used to
=== modified file 'storage/xtradb/include/os0file.h'
--- a/storage/xtradb/include/os0file.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/os0file.h 2010-01-06 12:00:14 +0000
@@ -53,6 +53,7 @@ Created 10/21/1995 Heikki Tuuri
#define os0file_h
#include "univ.i"
+#include "trx0types.h"
#ifndef __WIN__
#include <dirent.h>
@@ -157,6 +158,8 @@ log. */
to become available again */
#define OS_FILE_SHARING_VIOLATION 76
#define OS_FILE_ERROR_NOT_SPECIFIED 77
+#define OS_FILE_INSUFFICIENT_RESOURCE 78
+#define OS_FILE_OPERATION_ABORTED 79
/* @} */
/** Types for aio operations @{ */
@@ -497,9 +500,12 @@ os_file_get_last_error(
/*******************************************************************//**
Requests a synchronous read operation.
@return TRUE if request was successful, FALSE if fail */
+#define os_file_read(file, buf, offset, offset_high, n) \
+ _os_file_read(file, buf, offset, offset_high, n, NULL)
+
UNIV_INTERN
ibool
-os_file_read(
+_os_file_read(
/*=========*/
os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
@@ -507,7 +513,8 @@ os_file_read(
offset where to read */
ulint offset_high,/*!< in: most significant 32 bits of
offset */
- ulint n); /*!< in: number of bytes to read */
+ ulint n, /*!< in: number of bytes to read */
+ trx_t* trx);
/*******************************************************************//**
Rewind file to its start, read at most size - 1 bytes from it to str, and
NUL-terminate str. All errors are silently ignored. This function is
@@ -619,6 +626,13 @@ os_aio_init(
ulint n_write_segs, /*<! in: number of writer threads */
ulint n_slots_sync); /*<! in: number of slots in the sync aio
array */
+/***********************************************************************
+Frees the asynchronous io system. */
+UNIV_INTERN
+void
+os_aio_free(void);
+/*=============*/
+
/*******************************************************************//**
Requests an asynchronous i/o operation.
@return TRUE if request was queued successfully, FALSE if fail */
@@ -654,10 +668,11 @@ os_aio(
(can be used to identify a completed
aio operation); ignored if mode is
OS_AIO_SYNC */
- void* message2);/*!< in: message for the aio handler
+ void* message2,/*!< in: message for the aio handler
(can be used to identify a completed
aio operation); ignored if mode is
OS_AIO_SYNC */
+ trx_t* trx);
/************************************************************************//**
Wakes up all async i/o threads so that they know to exit themselves in
shutdown. */
=== modified file 'storage/xtradb/include/os0sync.h'
--- a/storage/xtradb/include/os0sync.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/os0sync.h 2010-01-06 12:00:14 +0000
@@ -285,44 +285,74 @@ os_fast_mutex_free(
/**********************************************************//**
Atomic compare-and-swap and increment for InnoDB. */
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
+#if defined(HAVE_IB_GCC_ATOMIC_BUILTINS)
+
+#define HAVE_ATOMIC_BUILTINS
+
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
+
# define os_compare_and_swap(ptr, old_val, new_val) \
__sync_bool_compare_and_swap(ptr, old_val, new_val)
+
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
+
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
-# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+
+# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use GCC atomic builtins"
+# else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes use GCC atomic builtins, rw_locks do not"
+# endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
+
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
+
# define os_atomic_increment(ptr, amount) \
__sync_add_and_fetch(ptr, amount)
+
# define os_atomic_increment_lint(ptr, amount) \
os_atomic_increment(ptr, amount)
+
# define os_atomic_increment_ulint(ptr, amount) \
os_atomic_increment(ptr, amount)
+
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val */
+
# define os_atomic_test_and_set_byte(ptr, new_val) \
__sync_lock_test_and_set(ptr, new_val)
+
+#elif defined(HAVE_IB_SOLARIS_ATOMICS)
+
+#define HAVE_ATOMIC_BUILTINS
+
/* If not compiling with GCC or GCC doesn't support the atomic
intrinsics and running on Solaris >= 10 use Solaris atomics */
-#elif defined(HAVE_SOLARIS_ATOMICS)
+
#include <atomic.h>
+
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
+
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
(atomic_cas_ulong(ptr, old_val, new_val) == old_val)
+
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
-# if SIZEOF_PTHREAD_T == 4
+
+# ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
+# if SIZEOF_PTHREAD_T == 4
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
# elif SIZEOF_PTHREAD_T == 8
@@ -331,21 +361,35 @@ compare to, new_val is the value to swap
# else
# error "SIZEOF_PTHREAD_T != 4 or 8"
# endif /* SIZEOF_PTHREAD_T CHECK */
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use Solaris atomic functions"
+# else /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes use Solaris atomic functions, rw_locks do not"
+# endif /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
+
# define os_atomic_increment_lint(ptr, amount) \
atomic_add_long_nv((ulong_t*) ptr, amount)
+
# define os_atomic_increment_ulint(ptr, amount) \
atomic_add_long_nv(ptr, amount)
+
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val */
+
# define os_atomic_test_and_set_byte(ptr, new_val) \
atomic_swap_uchar(ptr, new_val)
-/* On Windows, use Windows atomics / interlocked */
+
#elif defined(HAVE_WINDOWS_ATOMICS)
+
+#define HAVE_ATOMIC_BUILTINS
+
+/* On Windows, use Windows atomics / interlocked */
# ifdef _WIN64
# define win_cmp_and_xchg InterlockedCompareExchange64
# define win_xchg_and_add InterlockedExchangeAdd64
@@ -353,31 +397,46 @@ Returns the old value of *ptr, atomicall
# define win_cmp_and_xchg InterlockedCompareExchange
# define win_xchg_and_add InterlockedExchangeAdd
# endif
+
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
+
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
+
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
-# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+
+/* windows thread objects can always be passed to windows atomic functions */
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
(InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use Windows interlocked functions"
+
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
+
# define os_atomic_increment_lint(ptr, amount) \
(win_xchg_and_add(ptr, amount) + amount)
+
# define os_atomic_increment_ulint(ptr, amount) \
((ulint) (win_xchg_and_add(ptr, amount) + amount))
+
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val.
InterlockedExchange() operates on LONG, and the LONG will be
clobbered */
+
# define os_atomic_test_and_set_byte(ptr, new_val) \
((byte) InterlockedExchange(ptr, new_val))
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
+
+#else
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use InnoDB's own implementation"
+#endif
#ifndef UNIV_NONINL
#include "os0sync.ic"
=== modified file 'storage/xtradb/include/page0page.h'
--- a/storage/xtradb/include/page0page.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/page0page.h 2010-03-28 18:10:00 +0000
@@ -76,8 +76,11 @@ typedef byte page_header_t;
header which are set in a page create */
/*----*/
#define PAGE_LEVEL 26 /* level of the node in an index tree; the
- leaf level is the level 0 */
-#define PAGE_INDEX_ID 28 /* index id where the page belongs */
+ leaf level is the level 0. This field should
+ not be written to after page creation. */
+#define PAGE_INDEX_ID 28 /* index id where the page belongs.
+ This field should not be written to after
+ page creation. */
#define PAGE_BTR_SEG_LEAF 36 /* file segment header for the leaf pages in
a B-tree: defined only on the root page of a
B-tree, but not in the root of an ibuf tree */
@@ -514,7 +517,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec); /*!< in: pointer to record */
+ const rec_t* rec); /*!< in: pointer to record */
/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
=== modified file 'storage/xtradb/include/page0page.ic'
--- a/storage/xtradb/include/page0page.ic 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/page0page.ic 2010-03-28 18:10:00 +0000
@@ -731,7 +731,7 @@ UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- rec_t* rec) /*!< in: pointer to record */
+ const rec_t* rec) /*!< in: pointer to record */
{
return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
}
@@ -907,7 +907,7 @@ page_get_data_size(
/************************************************************//**
Allocates a block of memory from the free list of an index page. */
-UNIV_INTERN
+UNIV_INLINE
void
page_mem_alloc_free(
/*================*/
=== modified file 'storage/xtradb/include/page0zip.h'
--- a/storage/xtradb/include/page0zip.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/page0zip.h 2010-01-06 12:00:14 +0000
@@ -127,8 +127,12 @@ page_zip_decompress(
/*================*/
page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
- page_t* page) /*!< out: uncompressed page, may be trashed */
- __attribute__((nonnull));
+ page_t* page, /*!< out: uncompressed page, may be trashed */
+ ibool all) /*!< in: TRUE=decompress the whole page;
+ FALSE=verify but do not copy some
+ page header fields that should not change
+ after page creation */
+ __attribute__((nonnull(1,2)));
#ifdef UNIV_DEBUG
/**********************************************************************//**
@@ -385,8 +389,8 @@ IMPORTANT: if page_zip_reorganize() is i
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
will be redo-logged.
-@return TRUE on success, FALSE on failure; page and page_zip will be
-left intact on failure. */
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure, but page will be overwritten. */
UNIV_INTERN
ibool
page_zip_reorganize(
=== modified file 'storage/xtradb/include/pars0pars.h'
--- a/storage/xtradb/include/pars0pars.h 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/include/pars0pars.h 2010-01-15 15:58:25 +0000
@@ -583,6 +583,12 @@ pars_info_get_bound_id(
pars_info_t* info, /*!< in: info struct */
const char* name); /*!< in: bound id name to find */
+/******************************************************************//**
+Release any resources used by the lexer. */
+UNIV_INTERN
+void
+pars_lexer_close(void);
+/*==================*/
/** Extra information supplied for pars_sql(). */
struct pars_info_struct {
=== modified file 'storage/xtradb/include/rem0cmp.h'
--- a/storage/xtradb/include/rem0cmp.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/rem0cmp.h 2010-01-06 12:00:14 +0000
@@ -89,7 +89,7 @@ cmp_dfield_dfield(
/*************************************************************//**
This function is used to compare a data tuple to a physical record.
Only dtuple->n_fields_cmp first fields are taken into account for
-the the data tuple! If we denote by n = n_fields_cmp, then rec must
+the data tuple! If we denote by n = n_fields_cmp, then rec must
have either m >= n fields, or it must differ from dtuple in some of
the m fields rec has. If rec has an externally stored field we do not
compare it but return with value 0 if such a comparison should be
=== modified file 'storage/xtradb/include/rem0rec.ic'
--- a/storage/xtradb/include/rem0rec.ic 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/rem0rec.ic 2010-01-06 12:00:14 +0000
@@ -65,7 +65,7 @@ most significant bytes and bits are writ
- offset_of_this_record) mod 64Ki,
where mod is the modulo as a non-negative
number;
- we can calculate the the offset of the next
+ we can calculate the offset of the next
record with the formula:
relative_offset + offset_of_this_record
mod UNIV_PAGE_SIZE
=== modified file 'storage/xtradb/include/row0ins.h'
--- a/storage/xtradb/include/row0ins.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/row0ins.h 2010-01-06 12:00:14 +0000
@@ -45,7 +45,7 @@ row_ins_check_foreign_constraint(
/*=============================*/
ibool check_ref,/*!< in: TRUE If we want to check that
the referenced table is ok, FALSE if we
- want to to check the foreign key table */
+ want to check the foreign key table */
dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
tables mentioned in it must be in the
dictionary cache if they exist at all */
=== modified file 'storage/xtradb/include/row0mysql.h'
--- a/storage/xtradb/include/row0mysql.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/row0mysql.h 2010-01-06 12:00:14 +0000
@@ -177,7 +177,9 @@ row_update_prebuilt_trx(
in MySQL handle */
trx_t* trx); /*!< in: transaction handle */
/*********************************************************************//**
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
UNIV_INTERN
void
row_unlock_table_autoinc_for_mysql(
@@ -754,8 +756,6 @@ struct row_prebuilt_struct {
store it here so that we can return
it to MySQL */
/*----------------------*/
- UT_LIST_NODE_T(row_prebuilt_t) prebuilts;
- /*!< list node of table->prebuilts */
ulint magic_n2; /*!< this should be the same as
magic_n */
};
=== modified file 'storage/xtradb/include/srv0srv.h'
--- a/storage/xtradb/include/srv0srv.h 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/include/srv0srv.h 2010-01-15 15:58:25 +0000
@@ -80,6 +80,9 @@ at a time */
#define SRV_AUTO_EXTEND_INCREMENT \
(srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
+/* prototypes for new functions added to ha_innodb.cc */
+ibool innobase_get_slow_log();
+
/* This is set to TRUE if the MySQL user has set it in MySQL */
extern ibool srv_lower_case_table_names;
@@ -133,8 +136,9 @@ extern ulint* srv_data_file_is_raw_parti
extern ibool srv_extra_undoslots;
extern ibool srv_fast_recovery;
+extern ibool srv_recovery_stats;
-extern ibool srv_use_purge_thread;
+extern ulint srv_use_purge_thread;
extern ibool srv_auto_extend_last_data_file;
extern ulint srv_last_file_size_max;
@@ -235,12 +239,14 @@ extern ulong srv_replication_delay;
extern long long srv_ibuf_max_size;
extern ulong srv_ibuf_active_contract;
extern ulong srv_ibuf_accel_rate;
+extern ulint srv_checkpoint_age_target;
extern ulong srv_flush_neighbor_pages;
extern ulong srv_enable_unsafe_group_commit;
extern ulong srv_read_ahead;
extern ulong srv_adaptive_checkpoint;
extern ulong srv_expand_import;
+extern ulint srv_relax_table_creation;
extern ulong srv_extra_rsegments;
extern ulong srv_dict_size_limit;
@@ -345,10 +351,6 @@ extern ulint srv_buf_pool_flushed;
/** Number of buffer pool reads that led to the
reading of a disk page */
extern ulint srv_buf_pool_reads;
-/** Number of sequential read-aheads */
-extern ulint srv_read_ahead_seq;
-/** Number of random read-aheads */
-extern ulint srv_read_ahead_rnd;
/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
@@ -428,6 +430,7 @@ enum srv_thread_type {
SRV_INSERT, /**< thread flushing the insert buffer to disk */
#endif
SRV_PURGE, /* thread purging undo records */
+ SRV_PURGE_WORKER, /* thread purging undo records */
SRV_MASTER /**< the master thread, (whose type number must
be biggest) */
};
@@ -446,7 +449,7 @@ void
srv_init(void);
/*==========*/
/*********************************************************************//**
-Frees the OS fast mutex created in srv_boot(). */
+Frees the data structures created in srv_init(). */
UNIV_INTERN
void
srv_free(void);
@@ -509,6 +512,13 @@ srv_purge_thread(
/*=============*/
void* arg); /* in: a dummy parameter required by
os_thread_create */
+/*************************************************************************
+The undo purge thread. */
+UNIV_INTERN
+os_thread_ret_t
+srv_purge_worker_thread(
+/*====================*/
+ void* arg);
/*******************************************************************//**
Tells the Innobase server that there has been activity in the database
and wakes up the master thread if it is suspended (not sleeping). Used
@@ -645,13 +655,13 @@ struct export_var_struct{
#ifdef UNIV_DEBUG
ulint innodb_buffer_pool_pages_latched; /*!< Latched pages */
#endif /* UNIV_DEBUG */
- ulint innodb_buffer_pool_read_requests; /*!< buf_pool->n_page_gets */
+ ulint innodb_buffer_pool_read_requests; /*!< buf_pool->stat.n_page_gets */
ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */
ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */
ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */
ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
- ulint innodb_buffer_pool_read_ahead_seq;/*!< srv_read_ahead_seq */
- ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */
+ ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */
+ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
@@ -663,9 +673,9 @@ struct export_var_struct{
ulint innodb_os_log_pending_writes; /*!< srv_os_log_pending_writes */
ulint innodb_os_log_pending_fsyncs; /*!< fil_n_pending_log_flushes */
ulint innodb_page_size; /*!< UNIV_PAGE_SIZE */
- ulint innodb_pages_created; /*!< buf_pool->n_pages_created */
- ulint innodb_pages_read; /*!< buf_pool->n_pages_read */
- ulint innodb_pages_written; /*!< buf_pool->n_pages_written */
+ ulint innodb_pages_created; /*!< buf_pool->stat.n_pages_created */
+ ulint innodb_pages_read; /*!< buf_pool->stat.n_pages_read */
+ ulint innodb_pages_written; /*!< buf_pool->stat.n_pages_written */
ulint innodb_row_lock_waits; /*!< srv_n_lock_wait_count */
ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */
ib_int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time
=== modified file 'storage/xtradb/include/sync0rw.h'
--- a/storage/xtradb/include/sync0rw.h 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/include/sync0rw.h 2010-01-15 15:58:25 +0000
@@ -120,7 +120,7 @@ is necessary only if the memory block co
# endif /* UNIV_SYNC_DEBUG */
#else /* UNIV_DEBUG */
# define rw_lock_create(L, level) \
- rw_lock_create_func((L), __FILE__, __LINE__)
+ rw_lock_create_func((L), #L, NULL, 0)
#endif /* UNIV_DEBUG */
/******************************************************************//**
@@ -137,8 +137,8 @@ rw_lock_create_func(
# ifdef UNIV_SYNC_DEBUG
ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
- const char* cmutex_name, /*!< in: mutex name */
#endif /* UNIV_DEBUG */
+ const char* cmutex_name, /*!< in: mutex name */
const char* cfile_name, /*!< in: file name where created */
ulint cline); /*!< in: file line where created */
/******************************************************************//**
@@ -540,7 +540,8 @@ struct rw_lock_struct {
ulint level; /*!< Level in the global latching order. */
#endif /* UNIV_SYNC_DEBUG */
ulint count_os_wait; /*!< Count of os_waits. May not be accurate */
- const char* cfile_name;/*!< File name where lock created */
+ //const char* cfile_name;/*!< File name where lock created */
+ const char* lock_name;/*!< lock name */
/* last s-lock file/line is not guaranteed to be correct */
const char* last_s_file_name;/*!< File name where last s-locked */
const char* last_x_file_name;/*!< File name where last x-locked */
@@ -551,7 +552,7 @@ struct rw_lock_struct {
are at the start of this struct, thus we can
peek this field without causing much memory
bus traffic */
- unsigned cline:14; /*!< Line where created */
+ //unsigned cline:14; /*!< Line where created */
unsigned last_s_line:14; /*!< Line number where last time s-locked */
unsigned last_x_line:14; /*!< Line number where last time x-locked */
ulint magic_n; /*!< RW_LOCK_MAGIC_N */
=== modified file 'storage/xtradb/include/sync0sync.h'
--- a/storage/xtradb/include/sync0sync.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/sync0sync.h 2010-01-06 12:00:14 +0000
@@ -80,7 +80,7 @@ necessary only if the memory block conta
# endif
#else
# define mutex_create(M, level) \
- mutex_create_func((M), __FILE__, __LINE__)
+ mutex_create_func((M), #M, NULL, 0)
#endif
/******************************************************************//**
@@ -93,8 +93,8 @@ void
mutex_create_func(
/*==============*/
mutex_t* mutex, /*!< in: pointer to memory */
-#ifdef UNIV_DEBUG
const char* cmutex_name, /*!< in: mutex name */
+#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
@@ -513,7 +513,7 @@ struct mutex_struct {
os_fast_mutex; /*!< We use this OS mutex in place of lock_word
when atomic operations are not enabled */
#endif
- ulint waiters; /*!< This ulint is set to 1 if there are (or
+ volatile ulint waiters; /*!< This ulint is set to 1 if there are (or
may be) threads waiting in the global wait
array for this mutex to be released.
Otherwise, this is 0. */
@@ -524,9 +524,9 @@ struct mutex_struct {
ulint line; /*!< Line where the mutex was locked */
ulint level; /*!< Level in the global latching order */
#endif /* UNIV_SYNC_DEBUG */
+#ifdef UNIV_DEBUG
const char* cfile_name;/*!< File name where mutex created */
ulint cline; /*!< Line where created */
-#ifdef UNIV_DEBUG
os_thread_id_t thread_id; /*!< The thread id of the thread
which locked the mutex. */
ulint magic_n; /*!< MUTEX_MAGIC_N */
@@ -541,9 +541,9 @@ struct mutex_struct {
ulong count_os_yield; /*!< count of os_wait */
ulonglong lspent_time; /*!< mutex os_wait timer msec */
ulonglong lmax_spent_time;/*!< mutex os_wait timer msec */
- const char* cmutex_name; /*!< mutex name */
ulint mutex_type; /*!< 0=usual mutex, 1=rw_lock mutex */
#endif /* UNIV_DEBUG */
+ const char* cmutex_name; /*!< mutex name */
};
/** The global array of wait cells for implementation of the databases own
=== modified file 'storage/xtradb/include/thr0loc.h'
--- a/storage/xtradb/include/thr0loc.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/thr0loc.h 2010-01-06 12:00:14 +0000
@@ -39,6 +39,12 @@ UNIV_INTERN
void
thr_local_init(void);
/*================*/
+ /****************************************************************//**
+Close the thread local storage module. */
+UNIV_INTERN
+void
+thr_local_close(void);
+/*=================*/
/*******************************************************************//**
Creates a local storage struct for the calling new thread. */
UNIV_INTERN
=== modified file 'storage/xtradb/include/trx0i_s.h'
--- a/storage/xtradb/include/trx0i_s.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0i_s.h 2010-01-06 12:00:14 +0000
@@ -141,6 +141,13 @@ void
trx_i_s_cache_init(
/*===============*/
trx_i_s_cache_t* cache); /*!< out: cache to init */
+/*******************************************************************//**
+Free the INFORMATION SCHEMA trx related cache. */
+UNIV_INTERN
+void
+trx_i_s_cache_free(
+/*===============*/
+ trx_i_s_cache_t* cache); /*!< in/out: cache to free */
/*******************************************************************//**
Issue a shared/read lock on the tables cache. */
=== modified file 'storage/xtradb/include/trx0purge.h'
--- a/storage/xtradb/include/trx0purge.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0purge.h 2010-01-06 12:00:14 +0000
@@ -71,6 +71,12 @@ void
trx_purge_sys_create(void);
/*======================*/
/********************************************************************//**
+Frees the global purge system control structure. */
+UNIV_INTERN
+void
+trx_purge_sys_close(void);
+/*======================*/
+/************************************************************************
Adds the update undo log as the first log in the history list. Removes the
update undo log segment from the rseg slot if it is too big for reuse. */
UNIV_INTERN
@@ -108,6 +114,25 @@ UNIV_INTERN
ulint
trx_purge(void);
/*===========*/
+/**********************************************************************
+This function runs a purge worker batch */
+UNIV_INTERN
+void
+trx_purge_worker(
+/*=============*/
+ ulint worker_id);
+/**********************************************************************
+This function waits the event for worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wait(void);
+/*========================*/
+/**********************************************************************
+This function wakes the waiting worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wake(void);
+/*========================*/
/******************************************************************//**
Prints information of the purge system to stderr. */
UNIV_INTERN
@@ -125,6 +150,11 @@ struct trx_purge_struct{
of the trx system and it never ends */
que_t* query; /*!< The query graph which will do the
parallelized purge operation */
+ ulint n_worker;
+ os_event_t worker_event;
+ sess_t** sess_arr;
+ trx_t** trx_arr;
+ que_t** query_arr;
rw_lock_t latch; /*!< The latch protecting the purge view.
A purge operation must acquire an
x-latch here for the instant at which
=== modified file 'storage/xtradb/include/trx0rec.h'
--- a/storage/xtradb/include/trx0rec.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0rec.h 2010-01-06 12:00:14 +0000
@@ -44,8 +44,8 @@ UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
- trx_undo_rec_t* undo_rec, /*!< in: undo log record */
- mem_heap_t* heap); /*!< in: heap where copied */
+ const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ mem_heap_t* heap); /*!< in: heap where copied */
/**********************************************************************//**
Reads the undo log record type.
@return record type */
=== modified file 'storage/xtradb/include/trx0rec.ic'
--- a/storage/xtradb/include/trx0rec.ic 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0rec.ic 2010-01-06 12:00:14 +0000
@@ -100,8 +100,8 @@ UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
- trx_undo_rec_t* undo_rec, /*!< in: undo log record */
- mem_heap_t* heap) /*!< in: heap where copied */
+ const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ mem_heap_t* heap) /*!< in: heap where copied */
{
ulint len;
=== modified file 'storage/xtradb/include/trx0roll.h'
--- a/storage/xtradb/include/trx0roll.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0roll.h 2010-01-06 12:00:14 +0000
@@ -133,6 +133,17 @@ trx_rollback(
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
+transaction was not yet committed, then we roll it back. */
+UNIV_INTERN
+void
+trx_rollback_or_clean_recovered(
+/*============================*/
+ ibool all); /*!< in: FALSE=roll back dictionary transactions;
+ TRUE=roll back all non-PREPARED transactions */
+/*******************************************************************//**
+Rollback or clean up any incomplete transactions which were
+encountered in crash recovery. If the transaction already was
+committed, then we clean up a possible insert undo log. If the
transaction was not yet committed, then we roll it back.
Note: this is done in a background thread.
@return a dummy parameter */
@@ -208,9 +219,9 @@ int
trx_general_rollback_for_mysql(
/*===========================*/
trx_t* trx, /*!< in: transaction handle */
- ibool partial,/*!< in: TRUE if partial rollback requested */
trx_savept_t* savept);/*!< in: pointer to savepoint undo number, if
- partial rollback requested */
+ partial rollback requested, or NULL for
+ complete rollback */
/*******************************************************************//**
Rolls back a transaction back to a named savepoint. Modifications after the
savepoint are undone but InnoDB does NOT release the corresponding locks
=== modified file 'storage/xtradb/include/trx0rseg.h'
--- a/storage/xtradb/include/trx0rseg.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0rseg.h 2010-01-06 12:00:14 +0000
@@ -125,6 +125,13 @@ trx_rseg_create(
ulint max_size, /*!< in: max size in pages */
ulint* id, /*!< out: rseg id */
mtr_t* mtr); /*!< in: mtr */
+/***************************************************************************
+Free's an instance of the rollback segment in memory. */
+UNIV_INTERN
+void
+trx_rseg_mem_free(
+/*==============*/
+ trx_rseg_t* rseg); /* in, own: instance to free */
/* Real max value may be 4076 in usual. But reserve 4 slot for safety or etc... */
=== modified file 'storage/xtradb/include/trx0sys.h'
--- a/storage/xtradb/include/trx0sys.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0sys.h 2010-01-06 12:00:14 +0000
@@ -344,6 +344,12 @@ void
trx_sys_file_format_tag_init(void);
/*==============================*/
/*****************************************************************//**
+Shutdown/Close the transaction system. */
+UNIV_INTERN
+void
+trx_sys_close(void);
+/*===============*/
+/*****************************************************************//**
Get the name representation of the file format from its id.
@return pointer to the name */
UNIV_INTERN
=== modified file 'storage/xtradb/include/trx0sys.ic'
--- a/storage/xtradb/include/trx0sys.ic 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0sys.ic 2010-01-06 12:00:14 +0000
@@ -34,11 +34,11 @@ typedef byte trx_sysf_rseg_t;
/* Rollback segment specification slot offsets */
/*-------------------------------------------------------------*/
-#define TRX_SYS_RSEG_SPACE 0 /* space where the the segment
+#define TRX_SYS_RSEG_SPACE 0 /* space where the segment
header is placed; starting with
MySQL/InnoDB 5.1.7, this is
UNIV_UNDEFINED if the slot is unused */
-#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the the segment
+#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the segment
header is placed; this is FIL_NULL
if the slot is unused */
/*-------------------------------------------------------------*/
=== modified file 'storage/xtradb/include/trx0trx.h'
--- a/storage/xtradb/include/trx0trx.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0trx.h 2010-01-06 12:00:14 +0000
@@ -179,7 +179,7 @@ trx_commit_off_kernel(
/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
-crashed, andf we cannot roll it back. */
+crashed, and we cannot roll it back. */
UNIV_INTERN
void
trx_cleanup_at_db_startup(
@@ -360,7 +360,7 @@ enum trx_dict_op {
operation modes in crash recovery. */
TRX_DICT_OP_TABLE = 1,
/** The transaction is creating or dropping an index in an
- existing table. In crash recovery, the the data dictionary
+ existing table. In crash recovery, the data dictionary
must be locked, but the table must not be dropped. */
TRX_DICT_OP_INDEX = 2
};
@@ -729,6 +729,17 @@ struct trx_struct{
/*------------------------------*/
char detailed_error[256]; /*!< detailed error message for last
error, or empty. */
+ /*------------------------------*/
+ ulint io_reads;
+ ib_uint64_t io_read;
+ ulint io_reads_wait_timer;
+ ib_uint64_t lock_que_wait_ustarted;
+ ulint lock_que_wait_timer;
+ ulint innodb_que_wait_timer;
+ ulint distinct_page_access;
+#define DPAH_SIZE 8192
+ byte* distinct_page_access_hash;
+ ibool take_stats;
};
#define TRX_MAX_N_THREADS 32 /* maximum number of
=== modified file 'storage/xtradb/include/trx0types.h'
--- a/storage/xtradb/include/trx0types.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0types.h 2010-01-06 12:00:14 +0000
@@ -70,7 +70,7 @@ typedef struct trx_named_savept_struct t
enum trx_rb_ctx {
RB_NONE = 0, /*!< no rollback */
RB_NORMAL, /*!< normal rollback */
- RB_RECOVERY, /*!< rolling back an incomplete transaction,
+ RB_RECOVERY /*!< rolling back an incomplete transaction,
in crash recovery */
};
=== modified file 'storage/xtradb/include/trx0undo.h'
--- a/storage/xtradb/include/trx0undo.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/trx0undo.h 2010-01-06 12:00:14 +0000
@@ -333,6 +333,13 @@ trx_undo_parse_discard_latest(
byte* end_ptr,/*!< in: buffer end */
page_t* page, /*!< in: page or NULL */
mtr_t* mtr); /*!< in: mtr or NULL */
+/************************************************************************
+Frees an undo log memory copy. */
+UNIV_INTERN
+void
+trx_undo_mem_free(
+/*==============*/
+ trx_undo_t* undo); /* in: the undo object to be freed */
/* Types of an undo log segment */
#define TRX_UNDO_INSERT 1 /* contains undo entries for inserts */
=== modified file 'storage/xtradb/include/univ.i'
--- a/storage/xtradb/include/univ.i 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/include/univ.i 2010-01-15 15:58:25 +0000
@@ -46,12 +46,12 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
-#define INNODB_VERSION_BUGFIX 4
-#define PERCONA_INNODB_VERSION 8
+#define INNODB_VERSION_BUGFIX 6
+#define PERCONA_INNODB_VERSION 9
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
-calculated in in make_version_string() in sql/sql_show.cc like this:
+calculated in make_version_string() in sql/sql_show.cc like this:
"version >> 8" . "version & 0xff"
because the version is shown with only one dot, we skip the last
component, i.e. we show M.N.P as M.N */
@@ -59,13 +59,14 @@ component, i.e. we show M.N.P as M.N */
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
/* auxiliary macros to help creating the version as string */
-#define __INNODB_VERSION(a, b, c, d) (#a "." #b "." #c "-" #d)
-#define _INNODB_VERSION(a, b, c, d) __INNODB_VERSION(a, b, c, d)
+#define __INNODB_VERSION(a, b, c, d) (#a "." #b "." #c "-" #d)
+#define _INNODB_VERSION(a, b, c, d) __INNODB_VERSION(a, b, c, d)
+
#define INNODB_VERSION_STR \
_INNODB_VERSION(INNODB_VERSION_MAJOR, \
INNODB_VERSION_MINOR, \
- INNODB_VERSION_BUGFIX, \
+ INNODB_VERSION_BUGFIX, \
PERCONA_INNODB_VERSION)
#define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/"
@@ -80,17 +81,25 @@ the virtual method table (vtable) in GCC
# define ha_innobase ha_innodb
#endif /* MYSQL_DYNAMIC_PLUGIN */
+/* if any of the following macros is defined at this point this means
+that the code from the "right" plug.in was executed and we do not
+need to include ut0auxconf.h which would either define the same macros
+or will be empty */
+#if !defined(HAVE_IB_GCC_ATOMIC_BUILTINS) \
+ && !defined(HAVE_IB_ATOMIC_PTHREAD_T_GCC) \
+ && !defined(HAVE_IB_SOLARIS_ATOMICS) \
+ && !defined(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) \
+ && !defined(SIZEOF_PTHREAD_T) \
+ && !defined(HAVE_IB_PAUSE_INSTRUCTION)
+# include "ut0auxconf.h"
+#endif
+
#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__)
# undef __WIN__
# define __WIN__
# include <windows.h>
-# if defined(HAVE_WINDOWS_ATOMICS)
-/* If atomics are defined we use them in InnoDB mutex implementation */
-# define HAVE_ATOMIC_BUILTINS
-# endif /* HAVE_WINDOWS_ATOMICS */
-
# ifdef _NT_
# define __NT__
# endif
@@ -113,45 +122,17 @@ if we are compiling on Windows. */
# include <sys/mman.h> /* mmap() for os0proc.c */
# endif
-# undef PACKAGE
-# undef VERSION
-
/* Include the header file generated by GNU autoconf */
# ifndef __WIN__
-#ifndef UNIV_HOTBACKUP
-# include "config.h"
-#endif /* UNIV_HOTBACKUP */
+# ifndef UNIV_HOTBACKUP
+# include "config.h"
+# endif /* UNIV_HOTBACKUP */
# endif
# ifdef HAVE_SCHED_H
# include <sched.h>
# endif
-# if defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_SOLARIS_ATOMICS) \
- || defined(HAVE_WINDOWS_ATOMICS)
-/* If atomics are defined we use them in InnoDB mutex implementation */
-# define HAVE_ATOMIC_BUILTINS
-# endif /* (HAVE_GCC_ATOMIC_BUILTINS) || (HAVE_SOLARIS_ATOMICS)
- || (HAVE_WINDOWS_ATOMICS) */
-
-/* For InnoDB rw_locks to work with atomics we need the thread_id
-to be no more than machine word wide. The following enables using
-atomics for InnoDB rw_locks where these conditions are met. */
-#ifdef HAVE_ATOMIC_BUILTINS
-/* if HAVE_ATOMIC_PTHREAD_T is defined at this point that means that
-the code from plug.in has defined it and we do not need to include
-ut0auxconf.h which would either define HAVE_ATOMIC_PTHREAD_T or will
-be empty */
-# ifndef HAVE_ATOMIC_PTHREAD_T
-# include "ut0auxconf.h"
-# endif /* HAVE_ATOMIC_PTHREAD_T */
-/* now HAVE_ATOMIC_PTHREAD_T is eventually defined either by plug.in or
-from Makefile.in->ut0auxconf.h */
-# ifdef HAVE_ATOMIC_PTHREAD_T
-# define INNODB_RW_LOCKS_USE_ATOMICS
-# endif /* HAVE_ATOMIC_PTHREAD_T */
-#endif /* HAVE_ATOMIC_BUILTINS */
-
/* We only try to do explicit inlining of functions with gcc and
Sun Studio */
@@ -198,12 +179,18 @@ command. Not tested on Windows. */
debugging without UNIV_DEBUG */
#define UNIV_DEBUG /* Enable ut_ad() assertions
and disable UNIV_INLINE */
+#define UNIV_DEBUG_LOCK_VALIDATE /* Enable
+ ut_ad(lock_rec_validate_page())
+ assertions. */
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
(field file_page_was_freed
in buf_page_t) */
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
+#define UNIV_LOG_LSN_DEBUG /* write LSN to the redo log;
+this will break redo log file compatibility, but it may be useful when
+debugging redo log application problems. */
#define UNIV_MEM_DEBUG /* detect memory leaks etc */
#define UNIV_IBUF_DEBUG /* debug the insert buffer */
#define UNIV_IBUF_COUNT_DEBUG /* debug the insert buffer;
@@ -253,7 +240,7 @@ by one. */
/* Linkage specifier for non-static InnoDB symbols (variables and functions)
that are only referenced from within InnoDB, not from MySQL */
-#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(UNIV_HOTBACKUP)
+#if defined(__GNUC__) && (__GNUC__ >= 4) || defined(__INTEL_COMPILER)
# define UNIV_INTERN __attribute__((visibility ("hidden")))
#else
# define UNIV_INTERN
@@ -410,7 +397,9 @@ it is read. */
/* Minimize cache-miss latency by moving data at addr into a cache before
it is read or written. */
# define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
-#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+/* Sun Studio includes sun_prefetch.h as of version 5.9 */
+#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) \
+ || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
# include <sun_prefetch.h>
#if __SUNPRO_C >= 0x550
# undef UNIV_INTERN
=== modified file 'storage/xtradb/include/usr0sess.h'
--- a/storage/xtradb/include/usr0sess.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/usr0sess.h 2010-01-06 12:00:14 +0000
@@ -44,14 +44,12 @@ sess_t*
sess_open(void);
/*============*/
/*********************************************************************//**
-Closes a session, freeing the memory occupied by it, if it is in a state
-where it should be closed.
-@return TRUE if closed */
+Closes a session, freeing the memory occupied by it. */
UNIV_INTERN
-ibool
-sess_try_close(
-/*===========*/
- sess_t* sess); /*!< in, own: session object */
+void
+sess_close(
+/*=======*/
+ sess_t* sess); /* in, own: session object */
/* The session handle. All fields are protected by the kernel mutex */
struct sess_struct{
=== modified file 'storage/xtradb/include/ut0auxconf.h'
--- a/storage/xtradb/include/ut0auxconf.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0auxconf.h 2010-01-06 12:00:14 +0000
@@ -1,14 +1,14 @@
/* Do not remove this file even though it is empty.
This file is included in univ.i and will cause compilation failure
if not present.
-A custom check has been added in the generated
+A custom checks have been added in the generated
storage/innobase/Makefile.in that is shipped with the InnoDB Plugin
-source archive. This check tries to compile a test program and if
-successful then adds "#define HAVE_ATOMIC_PTHREAD_T" to this file.
-This is a hack that has been developed in order to check for pthread_t
-atomicity without the need to regenerate the ./configure script that is
+source archive. These checks eventually define some macros and put
+them in this file.
+This is a hack that has been developed in order to deploy new compile
+time checks without the need to regenerate the ./configure script that is
distributed in the MySQL 5.1 official source archives.
If by any chance Makefile.in and ./configure are regenerated and thus
-the hack from Makefile.in wiped away then the "real" check from plug.in
+the hack from Makefile.in wiped away then the "real" checks from plug.in
will take over.
*/
=== modified file 'storage/xtradb/include/ut0byte.h'
--- a/storage/xtradb/include/ut0byte.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0byte.h 2010-01-06 12:00:14 +0000
@@ -219,8 +219,8 @@ UNIV_INLINE
void*
ut_align(
/*=====*/
- void* ptr, /*!< in: pointer */
- ulint align_no); /*!< in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no); /*!< in: align by this number */
/*********************************************************//**
The following function rounds down a pointer to the nearest
aligned address.
=== modified file 'storage/xtradb/include/ut0byte.ic'
--- a/storage/xtradb/include/ut0byte.ic 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0byte.ic 2010-01-06 12:00:14 +0000
@@ -319,8 +319,8 @@ UNIV_INLINE
void*
ut_align(
/*=====*/
- void* ptr, /*!< in: pointer */
- ulint align_no) /*!< in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
{
ut_ad(align_no > 0);
ut_ad(((align_no - 1) & align_no) == 0);
=== modified file 'storage/xtradb/include/ut0lst.h'
--- a/storage/xtradb/include/ut0lst.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0lst.h 2010-03-30 12:36:49 +0000
@@ -158,7 +158,7 @@ Inserts a NODE2 after NODE1 in a list.
/** Invalidate the pointers in a list node.
@param NAME list name
@param N pointer to the node that was removed */
-# define UT_LIST_REMOVE_CLEAR(NAME, N) while (0)
+# define UT_LIST_REMOVE_CLEAR(NAME, N) {} while (0)
#endif
/*******************************************************************//**
=== modified file 'storage/xtradb/include/ut0ut.h'
--- a/storage/xtradb/include/ut0ut.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0ut.h 2010-01-06 12:00:14 +0000
@@ -34,6 +34,11 @@ Created 1/20/1994 Heikki Tuuri
#define ut0ut_h
#include "univ.i"
+
+#ifndef UNIV_HOTBACKUP
+# include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
+#endif /* UNIV_HOTBACKUP */
+
#include <time.h>
#ifndef MYSQL_SERVER
#include <ctype.h>
@@ -47,7 +52,8 @@ Created 1/20/1994 Heikki Tuuri
/** Time stamp */
typedef time_t ib_time_t;
-#if defined(IB_HAVE_PAUSE_INSTRUCTION)
+#ifndef UNIV_HOTBACKUP
+#if defined(HAVE_IB_PAUSE_INSTRUCTION)
# ifdef WIN32
/* In the Win32 API, the x86 PAUSE instruction is executed by calling
the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
@@ -84,6 +90,7 @@ do { \
os_thread_sleep(2000 /* 2 ms */); \
} \
} while (0)
+#endif /* !UNIV_HOTBACKUP */
/********************************************************//**
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
@@ -216,6 +223,7 @@ UNIV_INTERN
ib_time_t
ut_time(void);
/*=========*/
+#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
@@ -239,6 +247,16 @@ ullint
ut_time_us(
/*=======*/
ullint* tloc); /*!< out: us since epoch, if non-NULL */
+/**********************************************************//**
+Returns the number of milliseconds since some epoch. The
+value may wrap around. It should only be used for heuristic
+purposes.
+@return ms since epoch */
+UNIV_INTERN
+ulint
+ut_time_ms(void);
+/*============*/
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************//**
Returns the difference of two times in seconds.
=== modified file 'storage/xtradb/lock/lock0lock.c'
--- a/storage/xtradb/lock/lock0lock.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/lock/lock0lock.c 2010-01-06 12:00:14 +0000
@@ -214,7 +214,7 @@ a waiting s-lock request on the next rec
by a read cursor moving in the ascending order in the index, we cannot
do the insert immediately, because when we finally commit our transaction,
the read cursor should see also the new inserted record. So we should
-move the read cursor backward from the the next record for it to pass over
+move the read cursor backward from the next record for it to pass over
the new inserted record. This move backward may be too cumbersome to
implement. If we in this situation just enqueue a second x-lock request
for our transaction on the next record, then the deadlock mechanism
@@ -360,10 +360,9 @@ ibool
lock_rec_validate_page(
/*===================*/
ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
ulint page_no);/*!< in: page number */
-
-/* Define the following in order to enable lock_rec_validate_page() checks. */
-# undef UNIV_DEBUG_LOCK_VALIDATE
#endif /* UNIV_DEBUG */
/* The lock system */
@@ -579,6 +578,23 @@ lock_sys_create(
}
/*********************************************************************//**
+Closes the lock system at database shutdown. */
+UNIV_INTERN
+void
+lock_sys_close(void)
+/*================*/
+{
+ if (lock_latest_err_file != NULL) {
+ fclose(lock_latest_err_file);
+ lock_latest_err_file = NULL;
+ }
+
+ hash_table_free(lock_sys->rec_hash);
+ mem_free(lock_sys);
+ lock_sys = NULL;
+}
+
+/*********************************************************************//**
Gets the size of a lock struct.
@return size in bytes */
UNIV_INTERN
@@ -1739,6 +1755,8 @@ lock_rec_enqueue_waiting(
{
lock_t* lock;
trx_t* trx;
+ ulint sec;
+ ulint ms;
ut_ad(mutex_own(&kernel_mutex));
@@ -1797,6 +1815,10 @@ lock_rec_enqueue_waiting(
trx->que_state = TRX_QUE_LOCK_WAIT;
trx->was_chosen_as_deadlock_victim = FALSE;
trx->wait_started = time(NULL);
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
+ }
ut_a(que_thr_stop(thr));
@@ -2622,6 +2644,7 @@ lock_move_reorganize_page(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
#endif
}
@@ -2711,8 +2734,10 @@ lock_move_rec_list_end(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
ut_ad(lock_rec_validate_page(buf_block_get_space(new_block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(new_block)));
#endif
}
@@ -2822,6 +2847,7 @@ lock_move_rec_list_start(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
#endif
}
@@ -3574,7 +3600,8 @@ lock_table_remove_low(
and lock_grant()). Therefore it can be empty and we
need to check for that. */
- if (!ib_vector_is_empty(trx->autoinc_locks)) {
+ if (!lock_get_wait(lock)
+ && !ib_vector_is_empty(trx->autoinc_locks)) {
lock_t* autoinc_lock;
autoinc_lock = ib_vector_pop(trx->autoinc_locks);
@@ -3607,6 +3634,8 @@ lock_table_enqueue_waiting(
{
lock_t* lock;
trx_t* trx;
+ ulint sec;
+ ulint ms;
ut_ad(mutex_own(&kernel_mutex));
@@ -3647,8 +3676,10 @@ lock_table_enqueue_waiting(
if (lock_deadlock_occurs(lock, trx)) {
- lock_reset_lock_and_trx_wait(lock);
+ /* The order here is important, we don't want to
+ lose the state of the lock before calling remove. */
lock_table_remove_low(lock);
+ lock_reset_lock_and_trx_wait(lock);
return(DB_DEADLOCK);
}
@@ -3660,6 +3691,10 @@ lock_table_enqueue_waiting(
return(DB_SUCCESS);
}
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
+ }
trx->que_state = TRX_QUE_LOCK_WAIT;
trx->was_chosen_as_deadlock_victim = FALSE;
trx->wait_started = time(NULL);
@@ -4627,6 +4662,10 @@ lock_rec_queue_validate(
next function call: we have to release lock table mutex
to obey the latching order */
+ /* If this thread is holding the file space latch
+ (fil_space_t::latch), the following check WILL break
+ latching order and may cause a deadlock of threads. */
+
impl_trx = lock_sec_rec_some_has_impl_off_kernel(
rec, index, offsets);
@@ -4684,6 +4723,8 @@ ibool
lock_rec_validate_page(
/*===================*/
ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
ulint page_no)/*!< in: page number */
{
dict_index_t* index;
@@ -4694,7 +4735,6 @@ lock_rec_validate_page(
ulint nth_lock = 0;
ulint nth_bit = 0;
ulint i;
- ulint zip_size;
mtr_t mtr;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -4705,7 +4745,6 @@ lock_rec_validate_page(
mtr_start(&mtr);
- zip_size = fil_space_get_zip_size(space);
ut_ad(zip_size != ULINT_UNDEFINED);
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
@@ -4750,6 +4789,11 @@ loop:
lock_mutex_exit_kernel();
+ /* If this thread is holding the file space
+ latch (fil_space_t::latch), the following
+ check WILL break the latching order and may
+ cause a deadlock of threads. */
+
lock_rec_queue_validate(block, rec, index, offsets);
lock_mutex_enter_kernel();
@@ -4840,7 +4884,9 @@ lock_validate(void)
lock_mutex_exit_kernel();
- lock_rec_validate_page(space, page_no);
+ lock_rec_validate_page(space,
+ fil_space_get_zip_size(space),
+ page_no);
lock_mutex_enter_kernel();
@@ -5364,6 +5410,20 @@ lock_release_autoinc_last_lock(
}
/*******************************************************************//**
+Check if a transaction holds any autoinc locks.
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+ const trx_t* trx) /*!< in: transaction */
+{
+ ut_a(trx->autoinc_locks != NULL);
+
+ return(!ib_vector_is_empty(trx->autoinc_locks));
+}
+
+/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
void
=== modified file 'storage/xtradb/log/log0log.c'
--- a/storage/xtradb/log/log0log.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/log/log0log.c 2010-01-06 12:00:14 +0000
@@ -241,6 +241,7 @@ log_reserve_and_open(
ut_a(len < log->buf_size / 2);
loop:
mutex_enter(&(log->mutex));
+ ut_ad(!recv_no_log_write);
/* Calculate an upper limit for the space the string may take in the
log buffer */
@@ -309,6 +310,7 @@ log_write_low(
ut_ad(mutex_own(&(log->mutex)));
part_loop:
+ ut_ad(!recv_no_log_write);
/* Calculate a part length */
data_len = (log->buf_free % OS_FILE_LOG_BLOCK_SIZE) + str_len;
@@ -362,6 +364,33 @@ part_loop:
}
/************************************************************//**
+*/
+UNIV_INLINE
+ulint
+log_max_modified_age_async()
+{
+ if (srv_checkpoint_age_target) {
+ return(ut_min(log_sys->max_modified_age_async,
+ srv_checkpoint_age_target
+ - srv_checkpoint_age_target / 8));
+ } else {
+ return(log_sys->max_modified_age_async);
+ }
+}
+
+UNIV_INLINE
+ulint
+log_max_checkpoint_age_async()
+{
+ if (srv_checkpoint_age_target) {
+ return(ut_min(log_sys->max_checkpoint_age_async,
+ srv_checkpoint_age_target));
+ } else {
+ return(log_sys->max_checkpoint_age_async);
+ }
+}
+
+/************************************************************//**
Closes the log.
@return lsn */
UNIV_INTERN
@@ -377,6 +406,7 @@ log_close(void)
ib_uint64_t checkpoint_age;
ut_ad(mutex_own(&(log->mutex)));
+ ut_ad(!recv_no_log_write);
lsn = log->lsn;
@@ -429,7 +459,7 @@ log_close(void)
}
}
- if (checkpoint_age <= log->max_modified_age_async) {
+ if (checkpoint_age <= log_max_modified_age_async()) {
goto function_exit;
}
@@ -437,8 +467,8 @@ log_close(void)
oldest_lsn = buf_pool_get_oldest_modification();
if (!oldest_lsn
- || lsn - oldest_lsn > log->max_modified_age_async
- || checkpoint_age > log->max_checkpoint_age_async) {
+ || lsn - oldest_lsn > log_max_modified_age_async()
+ || checkpoint_age > log_max_checkpoint_age_async()) {
log->check_flush_or_checkpoint = TRUE;
}
@@ -668,8 +698,6 @@ log_calc_max_ages(void)
ulint archive_margin;
ulint smallest_archive_margin;
- ut_ad(!mutex_own(&(log_sys->mutex)));
-
mutex_enter(&(log_sys->mutex));
group = UT_LIST_GET_FIRST(log_sys->log_groups);
@@ -770,8 +798,6 @@ void
log_init(void)
/*==========*/
{
- byte* buf;
-
log_sys = mem_alloc(sizeof(log_t));
mutex_create(&log_sys->mutex, SYNC_LOG);
@@ -786,8 +812,8 @@ log_init(void)
ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE);
ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);
- buf = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
- log_sys->buf = ut_align(buf, OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->buf_ptr = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->buf = ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE);
log_sys->buf_size = LOG_BUFFER_SIZE;
@@ -832,9 +858,9 @@ log_init(void)
rw_lock_create(&log_sys->checkpoint_lock, SYNC_NO_ORDER_CHECK);
- log_sys->checkpoint_buf
- = ut_align(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE),
- OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
+ log_sys->checkpoint_buf = ut_align(log_sys->checkpoint_buf_ptr,
+ OS_FILE_LOG_BLOCK_SIZE);
memset(log_sys->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
/*----------------------------*/
@@ -917,23 +943,33 @@ log_group_init(
group->lsn_offset = LOG_FILE_HDR_SIZE;
group->n_pending_writes = 0;
+ group->file_header_bufs_ptr = mem_alloc(sizeof(byte*) * n_files);
group->file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
#ifdef UNIV_LOG_ARCHIVE
+ group->archive_file_header_bufs_ptr = mem_alloc(
+ sizeof(byte*) * n_files);
group->archive_file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
#endif /* UNIV_LOG_ARCHIVE */
for (i = 0; i < n_files; i++) {
- *(group->file_header_bufs + i) = ut_align(
- mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
+ group->file_header_bufs_ptr[i] = mem_alloc(
+ LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
+
+ group->file_header_bufs[i] = ut_align(
+ group->file_header_bufs_ptr[i],
OS_FILE_LOG_BLOCK_SIZE);
memset(*(group->file_header_bufs + i), '\0',
LOG_FILE_HDR_SIZE);
#ifdef UNIV_LOG_ARCHIVE
- *(group->archive_file_header_bufs + i) = ut_align(
- mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
+ group->archive_file_header_bufs_ptr[i] = mem_alloc(
+ LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
+
+ group->archive_file_header_bufs[i] = ut_align(
+ group->archive_file_header_bufs_ptr[i],
OS_FILE_LOG_BLOCK_SIZE);
+
memset(*(group->archive_file_header_bufs + i), '\0',
LOG_FILE_HDR_SIZE);
#endif /* UNIV_LOG_ARCHIVE */
@@ -946,8 +982,9 @@ log_group_init(
group->archived_offset = 0;
#endif /* UNIV_LOG_ARCHIVE */
- group->checkpoint_buf = ut_align(
- mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE);
+ group->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
+ group->checkpoint_buf = ut_align(group->checkpoint_buf_ptr,
+ OS_FILE_LOG_BLOCK_SIZE);
memset(group->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
@@ -1117,6 +1154,7 @@ log_io_complete(
}
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
ut_a(group->n_pending_writes > 0);
ut_a(log_sys->n_pending_writes > 0);
@@ -1148,6 +1186,7 @@ log_group_file_header_flush(
ulint dest_offset;
ut_ad(mutex_own(&(log_sys->mutex)));
+ ut_ad(!recv_no_log_write);
ut_a(nth_file < group->n_files);
buf = *(group->file_header_bufs + nth_file);
@@ -1219,6 +1258,7 @@ log_group_write_buf(
ulint i;
ut_ad(mutex_own(&(log_sys->mutex)));
+ ut_ad(!recv_no_log_write);
ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a(((ulint) start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
@@ -1361,6 +1401,7 @@ loop:
#endif
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
if (flush_to_disk
&& log_sys->flushed_to_disk_lsn >= lsn) {
@@ -1974,6 +2015,7 @@ log_checkpoint(
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
oldest_lsn = log_buf_pool_get_oldest_modification();
mutex_exit(&(log_sys->mutex));
@@ -2047,7 +2089,7 @@ log_make_checkpoint_at(
later lsn, if IB_ULONGLONG_MAX, makes
a checkpoint at the latest lsn */
ibool write_always) /*!< in: the function normally checks if
- the the new checkpoint would have a
+ the new checkpoint would have a
greater lsn than the previous one: if
not, then no physical write is done;
by setting this parameter TRUE, a
@@ -2086,6 +2128,7 @@ loop:
do_checkpoint = FALSE;
mutex_enter(&(log->mutex));
+ ut_ad(!recv_no_log_write);
if (log->check_flush_or_checkpoint == FALSE) {
mutex_exit(&(log->mutex));
@@ -2103,10 +2146,10 @@ loop:
sync = TRUE;
advance = 2 * (age - log->max_modified_age_sync);
- } else if (age > log->max_modified_age_async) {
+ } else if (age > log_max_modified_age_async()) {
/* A flush is not urgent: we do an asynchronous preflush */
- advance = age - log->max_modified_age_async;
+ advance = age - log_max_modified_age_async();
} else {
advance = 0;
}
@@ -2120,7 +2163,7 @@ loop:
do_checkpoint = TRUE;
- } else if (checkpoint_age > log->max_checkpoint_age_async) {
+ } else if (checkpoint_age > log_max_checkpoint_age_async()) {
/* A checkpoint is not urgent: do it asynchronously */
do_checkpoint = TRUE;
@@ -3035,6 +3078,7 @@ loop:
#endif /* UNIV_LOG_ARCHIVE */
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
if (log_sys->check_flush_or_checkpoint) {
@@ -3120,6 +3164,16 @@ loop:
goto loop;
}
+ /* Check that the purge threads ended */
+ if (srv_use_purge_thread
+ && (srv_n_threads_active[SRV_PURGE] != 0
+ || srv_n_threads_active[SRV_PURGE_WORKER] != 0)) {
+
+ mutex_exit(&kernel_mutex);
+
+ goto loop;
+ }
+
mutex_exit(&kernel_mutex);
mutex_enter(&(log_sys->mutex));
@@ -3234,6 +3288,7 @@ loop:
ut_a(lsn == log_sys->lsn);
}
+#ifdef UNIV_LOG_DEBUG
/******************************************************//**
Checks by parsing that the catenated log segment for a single mtr is
consistent. */
@@ -3241,7 +3296,7 @@ UNIV_INTERN
ibool
log_check_log_recs(
/*===============*/
- byte* buf, /*!< in: pointer to the start of
+ const byte* buf, /*!< in: pointer to the start of
the log segment in the
log_sys->buf log buffer */
ulint len, /*!< in: segment length in bytes */
@@ -3249,8 +3304,8 @@ log_check_log_recs(
{
ib_uint64_t contiguous_lsn;
ib_uint64_t scanned_lsn;
- byte* start;
- byte* end;
+ const byte* start;
+ const byte* end;
byte* buf1;
byte* scan_buf;
@@ -3283,6 +3338,7 @@ log_check_log_recs(
return(TRUE);
}
+#endif /* UNIV_LOG_DEBUG */
/******************************************************//**
Peeks the current lsn.
@@ -3326,10 +3382,12 @@ log_print(
log_sys->last_checkpoint_lsn);
fprintf(file,
- "Max checkpoint age %lu\n"
- "Modified age %lu\n"
- "Checkpoint age %lu\n",
+ "Max checkpoint age %lu\n"
+ "Checkpoint age target %lu\n"
+ "Modified age %lu\n"
+ "Checkpoint age %lu\n",
(ulong) log_sys->max_checkpoint_age,
+ (ulong) log_max_checkpoint_age_async(),
(ulong) (log_sys->lsn -
log_buf_pool_get_oldest_modification()),
(ulong) (log_sys->lsn - log_sys->last_checkpoint_lsn));
@@ -3363,4 +3421,95 @@ log_refresh_stats(void)
log_sys->n_log_ios_old = log_sys->n_log_ios;
log_sys->last_printout_time = time(NULL);
}
+
+/**********************************************************************
+Closes a log group. */
+static
+void
+log_group_close(
+/*===========*/
+ log_group_t* group) /* in,own: log group to close */
+{
+ ulint i;
+
+ for (i = 0; i < group->n_files; i++) {
+ mem_free(group->file_header_bufs_ptr[i]);
+#ifdef UNIV_LOG_ARCHIVE
+ mem_free(group->archive_file_header_bufs_ptr[i]);
+#endif /* UNIV_LOG_ARCHIVE */
+ }
+
+ mem_free(group->file_header_bufs_ptr);
+ mem_free(group->file_header_bufs);
+
+#ifdef UNIV_LOG_ARCHIVE
+ mem_free(group->archive_file_header_bufs_ptr);
+ mem_free(group->archive_file_header_bufs);
+#endif /* UNIV_LOG_ARCHIVE */
+
+ mem_free(group->checkpoint_buf_ptr);
+
+ mem_free(group);
+}
+
+/**********************************************************
+Shutdown the log system but do not release all the memory. */
+UNIV_INTERN
+void
+log_shutdown(void)
+/*==============*/
+{
+ log_group_t* group;
+
+ group = UT_LIST_GET_FIRST(log_sys->log_groups);
+
+ while (UT_LIST_GET_LEN(log_sys->log_groups) > 0) {
+ log_group_t* prev_group = group;
+
+ group = UT_LIST_GET_NEXT(log_groups, group);
+ UT_LIST_REMOVE(log_groups, log_sys->log_groups, prev_group);
+
+ log_group_close(prev_group);
+ }
+
+ mem_free(log_sys->buf_ptr);
+ log_sys->buf_ptr = NULL;
+ log_sys->buf = NULL;
+ mem_free(log_sys->checkpoint_buf_ptr);
+ log_sys->checkpoint_buf_ptr = NULL;
+ log_sys->checkpoint_buf = NULL;
+
+ os_event_free(log_sys->no_flush_event);
+ os_event_free(log_sys->one_flushed_event);
+
+ rw_lock_free(&log_sys->checkpoint_lock);
+
+ mutex_free(&log_sys->mutex);
+
+#ifdef UNIV_LOG_ARCHIVE
+ rw_lock_free(&log_sys->archive_lock);
+ os_event_create(log_sys->archiving_on);
+#endif /* UNIV_LOG_ARCHIVE */
+
+#ifdef UNIV_LOG_DEBUG
+ recv_sys_debug_free();
+#endif
+
+ recv_sys_close();
+}
+
+/**********************************************************
+Free the log system data structures. */
+UNIV_INTERN
+void
+log_mem_free(void)
+/*==============*/
+{
+ if (log_sys != NULL) {
+ recv_sys_mem_free();
+ mem_free(log_sys);
+
+ log_sys = NULL;
+ }
+}
#endif /* !UNIV_HOTBACKUP */
=== modified file 'storage/xtradb/log/log0recv.c'
--- a/storage/xtradb/log/log0recv.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/log/log0recv.c 2010-01-15 15:58:25 +0000
@@ -69,20 +69,25 @@ UNIV_INTERN recv_sys_t* recv_sys = NULL;
/** TRUE when applying redo log records during crash recovery; FALSE
otherwise. Note that this is FALSE while a background thread is
rolling back incomplete transactions. */
-UNIV_INTERN ibool recv_recovery_on = FALSE;
+UNIV_INTERN ibool recv_recovery_on;
#ifdef UNIV_LOG_ARCHIVE
/** TRUE when applying redo log records from an archived log file */
-UNIV_INTERN ibool recv_recovery_from_backup_on = FALSE;
+UNIV_INTERN ibool recv_recovery_from_backup_on;
#endif /* UNIV_LOG_ARCHIVE */
#ifndef UNIV_HOTBACKUP
/** TRUE when recv_init_crash_recovery() has been called. */
-UNIV_INTERN ibool recv_needed_recovery = FALSE;
+UNIV_INTERN ibool recv_needed_recovery;
+# ifdef UNIV_DEBUG
+/** TRUE if writing to the redo log (mtr_commit) is forbidden.
+Protected by log_sys->mutex. */
+UNIV_INTERN ibool recv_no_log_write = FALSE;
+# endif /* UNIV_DEBUG */
/** TRUE if buf_page_is_corrupted() should check if the log sequence
number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
recv_recovery_from_checkpoint_start_func(). */
-UNIV_INTERN ibool recv_lsn_checks_on = FALSE;
+UNIV_INTERN ibool recv_lsn_checks_on;
/** There are two conditions under which we scan the logs, the first
is normal startup and the second is when we do a recovery from an
@@ -92,7 +97,7 @@ startup. If we find log entries that wer
we know that the server was not cleanly shutdown. We must then initialize
the crash recovery environment before attempting to store these entries in
the log hash table. */
-static ibool recv_log_scan_is_startup_type = FALSE;
+static ibool recv_log_scan_is_startup_type;
/** If the following is TRUE, the buffer pool file pages must be invalidated
after recovery and no ibuf operations are allowed; this becomes TRUE if
@@ -103,7 +108,7 @@ buffer pool before the pages have been r
TRUE means that recovery is running and no operations on the log files
are allowed yet: the variable name is misleading. */
-UNIV_INTERN ibool recv_no_ibuf_operations = FALSE;
+UNIV_INTERN ibool recv_no_ibuf_operations;
/** TRUE when the redo log is being backed up */
# define recv_is_making_a_backup FALSE
/** TRUE when recovering from a backed up redo log file */
@@ -111,30 +116,30 @@ UNIV_INTERN ibool recv_no_ibuf_operation
#else /* !UNIV_HOTBACKUP */
# define recv_needed_recovery FALSE
/** TRUE when the redo log is being backed up */
-UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
+UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
/** TRUE when recovering from a backed up redo log file */
UNIV_INTERN ibool recv_is_from_backup = FALSE;
# define buf_pool_get_curr_size() (5 * 1024 * 1024)
#endif /* !UNIV_HOTBACKUP */
/** The following counter is used to decide when to print info on
log scan */
-static ulint recv_scan_print_counter = 0;
+static ulint recv_scan_print_counter;
/** The type of the previous parsed redo log record */
-static ulint recv_previous_parsed_rec_type = 999999;
+static ulint recv_previous_parsed_rec_type;
/** The offset of the previous parsed redo log record */
-static ulint recv_previous_parsed_rec_offset = 0;
+static ulint recv_previous_parsed_rec_offset;
/** The 'multi' flag of the previous parsed redo log record */
-static ulint recv_previous_parsed_rec_is_multi = 0;
+static ulint recv_previous_parsed_rec_is_multi;
/** Maximum page number encountered in the redo log */
-UNIV_INTERN ulint recv_max_parsed_page_no = 0;
+UNIV_INTERN ulint recv_max_parsed_page_no;
/** This many frames must be left free in the buffer pool when we scan
the log and store the scanned log records in the buffer pool: we will
use these free frames to read in pages when we start applying the
log records to the database. */
-UNIV_INTERN ulint recv_n_pool_free_frames = 1024;
+UNIV_INTERN ulint recv_n_pool_free_frames;
/** The maximum lsn we see for a page during the recovery process. If this
is bigger than the lsn we are able to scan up to, that is an indication that
@@ -165,15 +170,119 @@ recv_sys_create(void)
return;
}
- recv_sys = mem_alloc(sizeof(recv_sys_t));
+ recv_sys = mem_alloc(sizeof(*recv_sys));
+ memset(recv_sys, 0x0, sizeof(*recv_sys));
mutex_create(&recv_sys->mutex, SYNC_RECV);
recv_sys->heap = NULL;
recv_sys->addr_hash = NULL;
+
+ recv_sys->stats_recv_start_time = time(NULL);
+ recv_sys->stats_oldest_modified_lsn = IB_ULONGLONG_MAX;
}
/********************************************************//**
+Release recovery system mutexes. */
+UNIV_INTERN
+void
+recv_sys_close(void)
+/*================*/
+{
+ if (recv_sys != NULL) {
+ if (recv_sys->addr_hash != NULL) {
+ hash_table_free(recv_sys->addr_hash);
+ }
+
+ if (recv_sys->heap != NULL) {
+ mem_heap_free(recv_sys->heap);
+ }
+
+ if (recv_sys->buf != NULL) {
+ ut_free(recv_sys->buf);
+ }
+
+ if (recv_sys->last_block_buf_start != NULL) {
+ mem_free(recv_sys->last_block_buf_start);
+ }
+
+ mutex_free(&recv_sys->mutex);
+
+ mem_free(recv_sys);
+ recv_sys = NULL;
+ }
+}
+
+/********************************************************//**
+Frees the recovery system memory. */
+UNIV_INTERN
+void
+recv_sys_mem_free(void)
+/*===================*/
+{
+ if (recv_sys != NULL) {
+ if (recv_sys->addr_hash != NULL) {
+ hash_table_free(recv_sys->addr_hash);
+ }
+
+ if (recv_sys->heap != NULL) {
+ mem_heap_free(recv_sys->heap);
+ }
+
+ if (recv_sys->buf != NULL) {
+ ut_free(recv_sys->buf);
+ }
+
+ if (recv_sys->last_block_buf_start != NULL) {
+ mem_free(recv_sys->last_block_buf_start);
+ }
+
+ mem_free(recv_sys);
+ recv_sys = NULL;
+ }
+}
+
+/************************************************************
+Reset the state of the recovery system variables. */
+UNIV_INTERN
+void
+recv_sys_var_init(void)
+/*===================*/
+{
+ recv_lsn_checks_on = FALSE;
+
+ recv_n_pool_free_frames = 1024;
+
+ recv_recovery_on = FALSE;
+
+#ifdef UNIV_LOG_ARCHIVE
+ recv_recovery_from_backup_on = FALSE;
+#endif /* UNIV_LOG_ARCHIVE */
+
+ recv_needed_recovery = FALSE;
+
+ recv_lsn_checks_on = FALSE;
+
+ recv_log_scan_is_startup_type = FALSE;
+
+ recv_no_ibuf_operations = FALSE;
+
+ recv_scan_print_counter = 0;
+
+ recv_previous_parsed_rec_type = 999999;
+
+ recv_previous_parsed_rec_offset = 0;
+
+ recv_previous_parsed_rec_is_multi = 0;
+
+ recv_max_parsed_page_no = 0;
+
+ recv_n_pool_free_frames = 1024;
+
+ recv_max_page_lsn = 0;
+}
+
+/************************************************************
Inits the recovery system for a recovery operation. */
UNIV_INTERN
void
@@ -248,8 +357,8 @@ recv_sys_empty_hash(void)
Frees the recovery system. */
static
void
-recv_sys_free(void)
-/*===============*/
+recv_sys_debug_free(void)
+/*=====================*/
{
mutex_enter(&(recv_sys->mutex));
@@ -258,8 +367,10 @@ recv_sys_free(void)
ut_free(recv_sys->buf);
mem_free(recv_sys->last_block_buf_start);
- recv_sys->addr_hash = NULL;
+ recv_sys->buf = NULL;
recv_sys->heap = NULL;
+ recv_sys->addr_hash = NULL;
+ recv_sys->last_block_buf_start = NULL;
mutex_exit(&(recv_sys->mutex));
}
@@ -853,6 +964,11 @@ recv_parse_or_apply_log_rec_body(
}
switch (type) {
+#ifdef UNIV_LOG_LSN_DEBUG
+ case MLOG_LSN:
+ /* The LSN is checked in recv_parse_log_rec(). */
+ break;
+#endif /* UNIV_LOG_LSN_DEBUG */
case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES:
#ifdef UNIV_DEBUG
if (page && page_type == FIL_PAGE_TYPE_ALLOCATED
@@ -1223,6 +1339,11 @@ recv_add_to_hash_table(
len = rec_end - body;
+ if (srv_recovery_stats) {
+ recv_sys->stats_log_recs++;
+ recv_sys->stats_log_len_sum += len;
+ }
+
recv = mem_heap_alloc(recv_sys->heap, sizeof(recv_t));
recv->type = type;
recv->len = rec_end - body;
@@ -1269,7 +1390,7 @@ recv_add_to_hash_table(
sizeof(recv_data_t) + len);
*prev_field = recv_data;
- ut_memcpy(((byte*)recv_data) + sizeof(recv_data_t), body, len);
+ memcpy(recv_data + 1, body, len);
prev_field = &(recv_data->next);
@@ -1327,12 +1448,14 @@ recv_recover_page_func(
buf_block_t* block) /*!< in/out: buffer block */
{
page_t* page;
+ page_zip_des_t* page_zip;
recv_addr_t* recv_addr;
recv_t* recv;
byte* buf;
ib_uint64_t start_lsn;
ib_uint64_t end_lsn;
ib_uint64_t page_lsn;
+ ib_uint64_t page_lsn_orig;
ib_uint64_t page_newest_lsn;
ibool modification_to_page;
#ifndef UNIV_HOTBACKUP
@@ -1372,12 +1495,21 @@ recv_recover_page_func(
recv_addr->state = RECV_BEING_PROCESSED;
+ if (srv_recovery_stats) {
+ if (just_read_in) {
+ recv_sys->stats_recover_pages_with_read++;
+ } else {
+ recv_sys->stats_recover_pages_without_read++;
+ }
+ }
+
mutex_exit(&(recv_sys->mutex));
mtr_start(&mtr);
mtr_set_log_mode(&mtr, MTR_LOG_NONE);
page = block->frame;
+ page_zip = buf_block_get_page_zip(block);
#ifndef UNIV_HOTBACKUP
if (just_read_in) {
@@ -1400,6 +1532,7 @@ recv_recover_page_func(
/* Read the newest modification lsn from the page */
page_lsn = mach_read_ull(page + FIL_PAGE_LSN);
+ page_lsn_orig = page_lsn;
#ifndef UNIV_HOTBACKUP
/* It may be that the page has been modified in the buffer
@@ -1419,6 +1552,21 @@ recv_recover_page_func(
modification_to_page = FALSE;
start_lsn = end_lsn = 0;
+ if (srv_recovery_stats) {
+ mutex_enter(&(recv_sys->mutex));
+ if (page_lsn_orig && recv_sys->stats_oldest_modified_lsn > page_lsn_orig) {
+ recv_sys->stats_oldest_modified_lsn = page_lsn_orig;
+ }
+ if (page_lsn_orig && recv_sys->stats_newest_modified_lsn < page_lsn_orig) {
+ recv_sys->stats_newest_modified_lsn = page_lsn_orig;
+ }
+ if (UT_LIST_GET_LAST(recv_addr->rec_list)->start_lsn
+ < page_lsn_orig) {
+ recv_sys->stats_pages_already_new++;
+ }
+ mutex_exit(&(recv_sys->mutex));
+ }
+
recv = UT_LIST_GET_FIRST(recv_addr->rec_list);
while (recv) {
@@ -1438,13 +1586,19 @@ recv_recover_page_func(
if (recv->type == MLOG_INIT_FILE_PAGE) {
page_lsn = page_newest_lsn;
- mach_write_ull(page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM, 0);
- mach_write_ull(page + FIL_PAGE_LSN, 0);
+ memset(FIL_PAGE_LSN + page, 0, 8);
+ memset(UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM
+ + page, 0, 8);
+
+ if (page_zip) {
+ memset(FIL_PAGE_LSN + page_zip->data, 0, 8);
+ }
}
if (recv->start_lsn >= page_lsn) {
+ ib_uint64_t end_lsn;
+
if (!modification_to_page) {
modification_to_page = TRUE;
@@ -1466,11 +1620,24 @@ recv_recover_page_func(
recv_parse_or_apply_log_rec_body(recv->type, buf,
buf + recv->len,
block, &mtr);
- mach_write_ull(page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM,
- recv->start_lsn + recv->len);
- mach_write_ull(page + FIL_PAGE_LSN,
- recv->start_lsn + recv->len);
+
+ if (srv_recovery_stats) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_applied_log_recs++;
+ recv_sys->stats_applied_log_len_sum += recv->len;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
+ end_lsn = recv->start_lsn + recv->len;
+ mach_write_ull(FIL_PAGE_LSN + page, end_lsn);
+ mach_write_ull(UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM
+ + page, end_lsn);
+
+ if (page_zip) {
+ mach_write_ull(FIL_PAGE_LSN
+ + page_zip->data, end_lsn);
+ }
}
if (recv->len > RECV_DATA_BLOCK_SIZE) {
@@ -1561,6 +1728,13 @@ recv_read_in_area(
}
}
+ if (srv_recovery_stats && n) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_read_requested_pages += n;
+ recv_sys->stats_read_in_area[n - 1]++;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
buf_read_recv_pages(FALSE, space, zip_size, page_nos, n);
/*
fprintf(stderr, "Recv pages at %lu n %lu\n", page_nos[0], n);
@@ -1688,6 +1862,7 @@ loop:
/* Flush all the file pages to disk and invalidate them in
the buffer pool */
+ ut_d(recv_no_log_write = TRUE);
mutex_exit(&(recv_sys->mutex));
mutex_exit(&(log_sys->mutex));
@@ -1701,6 +1876,7 @@ loop:
mutex_enter(&(log_sys->mutex));
mutex_enter(&(recv_sys->mutex));
+ ut_d(recv_no_log_write = FALSE);
recv_no_ibuf_operations = FALSE;
}
@@ -1712,6 +1888,10 @@ loop:
if (has_printed) {
fprintf(stderr, "InnoDB: Apply batch completed\n");
+
+ if (srv_recovery_stats) {
+ recv_sys->stats_recv_turns++;
+ }
}
mutex_exit(&(recv_sys->mutex));
@@ -1912,6 +2092,17 @@ recv_parse_log_rec(
return(0);
}
+#ifdef UNIV_LOG_LSN_DEBUG
+ if (*type == MLOG_LSN) {
+ ib_uint64_t lsn = (ib_uint64_t) *space << 32 | *page_no;
+# ifdef UNIV_LOG_DEBUG
+ ut_a(lsn == log_sys->old_lsn);
+# else /* UNIV_LOG_DEBUG */
+ ut_a(lsn == recv_sys->recovered_lsn);
+# endif /* UNIV_LOG_DEBUG */
+ }
+#endif /* UNIV_LOG_LSN_DEBUG */
+
/* Check that page_no is sensible */
if (UNIV_UNLIKELY(*page_no > 0x8FFFFFFFUL)) {
@@ -2169,6 +2360,12 @@ loop:
#endif
/* In normal mysqld crash recovery we do not try to
replay file operations */
+#ifdef UNIV_LOG_LSN_DEBUG
+ } else if (type == MLOG_LSN) {
+ /* Do not add these records to the hash table.
+ The page number and space id fields are misused
+ for something else. */
+#endif /* UNIV_LOG_LSN_DEBUG */
} else {
recv_add_to_hash_table(type, space, page_no, body,
ptr + len, old_lsn,
@@ -2200,11 +2397,11 @@ loop:
= recv_sys->recovered_offset + total_len;
recv_previous_parsed_rec_is_multi = 1;
- if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
#ifdef UNIV_LOG_DEBUG
+ if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
recv_check_incomplete_log_recs(ptr, len);
-#endif /* UNIV_LOG_DEBUG */
}
+#endif /* UNIV_LOG_DEBUG */
#ifdef UNIV_DEBUG
if (log_debug_writes) {
@@ -2268,7 +2465,11 @@ loop:
break;
}
- if (store_to_hash) {
+ if (store_to_hash
+#ifdef UNIV_LOG_LSN_DEBUG
+ && type != MLOG_LSN
+#endif /* UNIV_LOG_LSN_DEBUG */
+ ) {
recv_add_to_hash_table(type, space, page_no,
body, ptr + len,
old_lsn,
@@ -2417,8 +2618,7 @@ recv_scan_log_recs(
scanned_lsn = start_lsn;
more_data = FALSE;
- while (log_block < buf + len && !finished) {
-
+ do {
no = log_block_get_hdr_no(log_block);
/*
fprintf(stderr, "Log block header no %lu\n", no);
@@ -2548,10 +2748,11 @@ recv_scan_log_recs(
/* Log data for this group ends here */
finished = TRUE;
+ break;
} else {
log_block += OS_FILE_LOG_BLOCK_SIZE;
}
- }
+ } while (log_block < buf + len && !finished);
*group_scanned_lsn = scanned_lsn;
@@ -3078,6 +3279,84 @@ recv_recovery_from_checkpoint_finish(voi
}
#endif /* UNIV_DEBUG */
+ if (recv_needed_recovery && srv_recovery_stats) {
+ FILE* file = stderr;
+ ulint i;
+
+ fprintf(stderr,
+ "InnoDB: Applying log records was done. Its statistics are followings.\n");
+
+ fprintf(stderr,
+ "============================================================\n"
+ "-------------------\n"
+ "RECOVERY STATISTICS\n"
+ "-------------------\n");
+ fprintf(stderr,
+ "Recovery time: %g sec. (%lu turns)\n",
+ difftime(time(NULL), recv_sys->stats_recv_start_time),
+ recv_sys->stats_recv_turns);
+
+ fprintf(stderr,
+ "\n"
+ "Data page IO statistics\n"
+ " Requested pages: %lu\n"
+ " Read pages: %lu\n"
+ " Written pages: %lu\n"
+ " (Dirty blocks): %lu\n",
+ recv_sys->stats_read_requested_pages,
+ recv_sys->stats_read_io_pages,
+ recv_sys->stats_write_io_pages,
+ UT_LIST_GET_LEN(buf_pool->flush_list));
+
+ fprintf(stderr,
+ " Grouping IO [times]:\n"
+ "\tnumber of pages,\n"
+ "\t\tread request neighbors (in %d pages chunk),\n"
+ "\t\t\tcombined read IO,\n"
+ "\t\t\t\tcombined write IO\n",
+ RECV_READ_AHEAD_AREA);
+ for (i = 0; i < ut_max(RECV_READ_AHEAD_AREA,
+ OS_AIO_MERGE_N_CONSECUTIVE); i++) {
+ fprintf(stderr,
+ "\t%3lu,\t%lu,\t%lu,\t%lu\n", i + 1,
+ (i < RECV_READ_AHEAD_AREA) ?
+ recv_sys->stats_read_in_area[i] : 0,
+ (i < OS_AIO_MERGE_N_CONSECUTIVE) ?
+ recv_sys->stats_read_io_consecutive[i] : 0,
+ (i < OS_AIO_MERGE_N_CONSECUTIVE) ?
+ recv_sys->stats_write_io_consecutive[i] : 0);
+ }
+
+ fprintf(stderr,
+ "\n"
+ "Recovery process statistics\n"
+ " Checked pages by doublewrite buffer: %lu\n"
+ " Overwritten pages from doublewrite: %lu\n"
+ " Recovered pages by io_thread: %lu\n"
+ " Recovered pages by main thread: %lu\n"
+ " Parsed log records to apply: %lu\n"
+ " Sum of the length: %lu\n"
+ " Applied log records: %lu\n"
+ " Sum of the length: %lu\n"
+ " Pages which are already new enough: %lu (It may not be accurate, if turns > 1)\n"
+ " Oldest page's LSN: %llu\n"
+ " Newest page's LSN: %llu\n",
+ recv_sys->stats_doublewrite_check_pages,
+ recv_sys->stats_doublewrite_overwrite_pages,
+ recv_sys->stats_recover_pages_with_read,
+ recv_sys->stats_recover_pages_without_read,
+ recv_sys->stats_log_recs,
+ recv_sys->stats_log_len_sum,
+ recv_sys->stats_applied_log_recs,
+ recv_sys->stats_applied_log_len_sum,
+ recv_sys->stats_pages_already_new,
+ recv_sys->stats_oldest_modified_lsn,
+ recv_sys->stats_newest_modified_lsn);
+
+ fprintf(stderr,
+ "============================================================\n");
+ }
+
if (recv_needed_recovery) {
trx_sys_print_mysql_master_log_pos();
trx_sys_print_mysql_binlog_offset();
@@ -3104,8 +3383,13 @@ recv_recovery_from_checkpoint_finish(voi
recv_recovery_on = FALSE;
#ifndef UNIV_LOG_DEBUG
- recv_sys_free();
+ recv_sys_debug_free();
#endif
+ /* Roll back any recovered data dictionary transactions, so
+ that the data dictionary tables will be free of any locks.
+ The data dictionary latch should guarantee that there is at
+ most one data dictionary transaction active at a time. */
+ trx_rollback_or_clean_recovered(FALSE);
/* Drop partially created indexes. */
row_merge_drop_temp_indexes();
=== modified file 'storage/xtradb/mem/mem0dbg.c'
--- a/storage/xtradb/mem/mem0dbg.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/mem/mem0dbg.c 2010-01-06 12:00:14 +0000
@@ -170,6 +170,17 @@ mem_init(
mem_comm_pool = mem_pool_create(size);
}
+
+/******************************************************************//**
+Closes the memory system. */
+UNIV_INTERN
+void
+mem_close(void)
+/*===========*/
+{
+ mem_pool_free(mem_comm_pool);
+ mem_comm_pool = NULL;
+}
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG
=== modified file 'storage/xtradb/mem/mem0mem.c'
--- a/storage/xtradb/mem/mem0mem.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/mem/mem0mem.c 2010-01-06 12:00:14 +0000
@@ -475,16 +475,18 @@ mem_heap_block_free(
len = block->len;
block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
+#ifndef UNIV_HOTBACKUP
+ if (!srv_use_sys_malloc) {
#ifdef UNIV_MEM_DEBUG
- /* In the debug version we set the memory to a random combination
- of hex 0xDE and 0xAD. */
+ /* In the debug version we set the memory to a random
+ combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*)block, len);
+ mem_erase_buf((byte*)block, len);
#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ UNIV_MEM_ASSERT_AND_FREE(block, len);
#endif /* UNIV_MEM_DEBUG */
-#ifndef UNIV_HOTBACKUP
+ }
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
ut_ad(!buf_block);
@@ -495,6 +497,14 @@ mem_heap_block_free(
buf_block_free(buf_block);
}
#else /* !UNIV_HOTBACKUP */
+#ifdef UNIV_MEM_DEBUG
+ /* In the debug version we set the memory to a random
+ combination of hex 0xDE and 0xAD. */
+
+ mem_erase_buf((byte*)block, len);
+#else /* UNIV_MEM_DEBUG */
+ UNIV_MEM_ASSERT_AND_FREE(block, len);
+#endif /* UNIV_MEM_DEBUG */
ut_free(block);
#endif /* !UNIV_HOTBACKUP */
}
=== modified file 'storage/xtradb/mem/mem0pool.c'
--- a/storage/xtradb/mem/mem0pool.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/mem/mem0pool.c 2010-01-06 12:00:14 +0000
@@ -261,6 +261,18 @@ mem_pool_create(
}
/********************************************************************//**
+Frees a memory pool. */
+UNIV_INTERN
+void
+mem_pool_free(
+/*==========*/
+ mem_pool_t* pool) /*!< in, own: memory pool */
+{
+ ut_free(pool->buf);
+ ut_free(pool);
+}
+
+/********************************************************************//**
Fills the specified free list.
@return TRUE if we were able to insert a block to the free list */
static
=== modified file 'storage/xtradb/mtr/mtr0mtr.c'
--- a/storage/xtradb/mtr/mtr0mtr.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/mtr/mtr0mtr.c 2010-01-15 15:58:25 +0000
@@ -36,6 +36,7 @@ Created 11/26/1995 Heikki Tuuri
#include "buf0flu.h"
#ifndef UNIV_HOTBACKUP
+# include "log0recv.h"
/*****************************************************************//**
Releases the item in the slot given. */
UNIV_INLINE
@@ -148,7 +149,6 @@ mtr_log_reserve_and_write(
dyn_array_t* mlog;
dyn_block_t* block;
ulint data_size;
- ibool success;
byte* first_data;
ut_ad(mtr);
@@ -167,8 +167,8 @@ mtr_log_reserve_and_write(
if (mlog->heap == NULL) {
mtr->end_lsn = log_reserve_and_write_fast(
first_data, dyn_block_get_used(mlog),
- &(mtr->start_lsn), &success);
- if (success) {
+ &mtr->start_lsn);
+ if (mtr->end_lsn) {
return;
}
@@ -215,6 +215,8 @@ mtr_commit(
ut_d(mtr->state = MTR_COMMITTING);
#ifndef UNIV_HOTBACKUP
+ /* This is a dirty read, for debugging. */
+ ut_ad(!recv_no_log_write);
write_log = mtr->modifications && mtr->n_log_recs;
if (write_log) {
=== modified file 'storage/xtradb/os/os0file.c'
--- a/storage/xtradb/os/os0file.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/os/os0file.c 2010-01-06 12:00:14 +0000
@@ -55,6 +55,9 @@ Created 10/21/1995 Heikki Tuuri
#include "srv0start.h"
#include "fil0fil.h"
#include "buf0buf.h"
+#include "trx0sys.h"
+#include "trx0trx.h"
+#include "log0recv.h"
#ifndef UNIV_HOTBACKUP
# include "os0sync.h"
# include "os0thread.h"
@@ -88,7 +91,9 @@ UNIV_INTERN ibool os_do_not_call_flush_a
/* We do not call os_file_flush in every os_file_write. */
#endif /* UNIV_DO_FLUSH */
-#ifndef UNIV_HOTBACKUP
+#ifdef UNIV_HOTBACKUP
+# define os_aio_use_native_aio FALSE
+#else /* UNIV_HOTBACKUP */
/* We use these mutexes to protect lseek + file i/o operation, if the
OS does not provide an atomic pread or pwrite, or similar */
#define OS_FILE_N_SEEK_MUTEXES 16
@@ -235,7 +240,7 @@ static ulint os_aio_n_segments = ULINT_U
/** If the following is TRUE, read i/o handler threads try to
wait until a batch of new read requests have been posted */
static volatile ibool os_aio_recommend_sleep_for_read_threads = FALSE;
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_HOTBACKUP */
UNIV_INTERN ulint os_n_file_reads = 0;
UNIV_INTERN ulint os_bytes_read_since_printout = 0;
@@ -352,6 +357,19 @@ os_file_get_last_error(
" software or another instance\n"
"InnoDB: of MySQL."
" Please close it to get rid of this error.\n");
+ } else if (err == ERROR_WORKING_SET_QUOTA
+ || err == ERROR_NO_SYSTEM_RESOURCES) {
+ fprintf(stderr,
+ "InnoDB: The error means that there are no"
+ " sufficient system resources or quota to"
+ " complete the operation.\n");
+ } else if (err == ERROR_OPERATION_ABORTED) {
+ fprintf(stderr,
+ "InnoDB: The error means that the I/O"
+ " operation has been aborted\n"
+ "InnoDB: because of either a thread exit"
+ " or an application request.\n"
+ "InnoDB: Retry attempt is made.\n");
} else {
fprintf(stderr,
"InnoDB: Some operating system error numbers"
@@ -373,6 +391,11 @@ os_file_get_last_error(
} else if (err == ERROR_SHARING_VIOLATION
|| err == ERROR_LOCK_VIOLATION) {
return(OS_FILE_SHARING_VIOLATION);
+ } else if (err == ERROR_WORKING_SET_QUOTA
+ || err == ERROR_NO_SYSTEM_RESOURCES) {
+ return(OS_FILE_INSUFFICIENT_RESOURCE);
+ } else if (err == ERROR_OPERATION_ABORTED) {
+ return(OS_FILE_OPERATION_ABORTED);
} else {
return(100 + err);
}
@@ -491,6 +514,14 @@ os_file_handle_error_cond_exit(
os_thread_sleep(10000000); /* 10 sec */
return(TRUE);
+ } else if (err == OS_FILE_INSUFFICIENT_RESOURCE) {
+
+ os_thread_sleep(100000); /* 100 ms */
+ return(TRUE);
+ } else if (err == OS_FILE_OPERATION_ABORTED) {
+
+ os_thread_sleep(100000); /* 100 ms */
+ return(TRUE);
} else {
if (name) {
fprintf(stderr, "InnoDB: File name %s\n", name);
@@ -854,6 +885,23 @@ next_file:
ret = stat(full_path, &statinfo);
if (ret) {
+
+ if (errno == ENOENT) {
+ /* readdir() returned a file that does not exist,
+ it must have been deleted in the meantime. Do what
+ would have happened if the file was deleted before
+ readdir() - ignore and go to the next entry.
+ If this is the last entry then info->name will still
+ contain the name of the deleted file when this
+ function returns, but this is not an issue since the
+ caller shouldn't be looking at info when end of
+ directory is returned. */
+
+ ut_free(full_path);
+
+ goto next_file;
+ }
+
os_file_handle_error_no_exit(full_path, "stat");
ut_free(full_path);
@@ -1282,6 +1330,7 @@ try_again:
}
#endif
#ifdef UNIV_NON_BUFFERED_IO
+# ifndef UNIV_HOTBACKUP
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
/* Do not use unbuffered i/o to log files because
value 2 denotes that we do not flush the log at every
@@ -1290,10 +1339,14 @@ try_again:
== SRV_WIN_IO_UNBUFFERED) {
attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
-#endif
+# else /* !UNIV_HOTBACKUP */
+ attributes = attributes | FILE_FLAG_NO_BUFFERING;
+# endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_NON_BUFFERED_IO */
} else if (purpose == OS_FILE_NORMAL) {
attributes = 0;
#ifdef UNIV_NON_BUFFERED_IO
+# ifndef UNIV_HOTBACKUP
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
/* Do not use unbuffered i/o to log files because
value 2 denotes that we do not flush the log at every
@@ -1302,7 +1355,10 @@ try_again:
== SRV_WIN_IO_UNBUFFERED) {
attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
-#endif
+# else /* !UNIV_HOTBACKUP */
+ attributes = attributes | FILE_FLAG_NO_BUFFERING;
+# endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_NON_BUFFERED_IO */
} else {
attributes = 0;
ut_error;
@@ -2046,20 +2102,30 @@ os_file_flush(
/*******************************************************************//**
Does a synchronous read operation in Posix.
@return number of bytes read, -1 if error */
+#define os_file_pread(file, buf, n, offset, offset_high) \
+ _os_file_pread(file, buf, n, offset, offset_high, NULL);
+
static
ssize_t
-os_file_pread(
+_os_file_pread(
/*==========*/
os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
ulint n, /*!< in: number of bytes to read */
ulint offset, /*!< in: least significant 32 bits of file
offset from where to read */
- ulint offset_high) /*!< in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
+ trx_t* trx)
{
off_t offs;
+#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
ssize_t n_bytes;
+#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
+ ulint sec;
+ ulint ms;
+ ib_uint64_t start_time;
+ ib_uint64_t finish_time;
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2080,6 +2146,15 @@ os_file_pread(
os_n_file_reads++;
+ if (innobase_get_slow_log() && trx && trx->take_stats)
+ {
+ trx->io_reads++;
+ trx->io_read += n;
+ ut_usectime(&sec, &ms);
+ start_time = (ib_uint64_t)sec * 1000000 + ms;
+ } else {
+ start_time = 0;
+ }
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
os_mutex_enter(os_file_count_mutex);
os_file_n_pending_preads++;
@@ -2093,21 +2168,32 @@ os_file_pread(
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
+ if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
+ }
+
return(n_bytes);
#else
{
off_t ret_offset;
ssize_t ret;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret_offset = lseek(file, offs, SEEK_SET);
@@ -2117,12 +2203,21 @@ os_file_pread(
ret = read(file, buf, (ssize_t)n);
}
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
+ if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
+ }
+
return(ret);
}
#endif
@@ -2195,16 +2290,20 @@ os_file_pwrite(
#else
{
off_t ret_offset;
+# ifndef UNIV_HOTBACKUP
ulint i;
+# endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
+# ifndef UNIV_HOTBACKUP
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+# endif /* UNIV_HOTBACKUP */
ret_offset = lseek(file, offs, SEEK_SET);
@@ -2230,7 +2329,9 @@ os_file_pwrite(
# endif /* UNIV_DO_FLUSH */
func_exit:
+# ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+# endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
@@ -2247,7 +2348,7 @@ Requests a synchronous positioned read o
@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
-os_file_read(
+_os_file_read(
/*=========*/
os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
@@ -2255,7 +2356,8 @@ os_file_read(
offset where to read */
ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n) /*!< in: number of bytes to read */
+ ulint n, /*!< in: number of bytes to read */
+ trx_t* trx)
{
#ifdef __WIN__
BOOL ret;
@@ -2264,7 +2366,9 @@ os_file_read(
DWORD low;
DWORD high;
ibool retry;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2283,16 +2387,20 @@ try_again:
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2303,7 +2411,9 @@ try_again:
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2312,14 +2422,14 @@ try_again:
if (ret && len == n) {
return(TRUE);
}
-#else
+#else /* __WIN__ */
ibool retry;
ssize_t ret;
os_bytes_read_since_printout += n;
try_again:
- ret = os_file_pread(file, buf, n, offset, offset_high);
+ ret = _os_file_pread(file, buf, n, offset, offset_high, trx);
if ((ulint)ret == n) {
@@ -2331,7 +2441,7 @@ try_again:
"InnoDB: Was only able to read %ld.\n",
(ulong)n, (ulong)offset_high,
(ulong)offset, (long)ret);
-#endif
+#endif /* __WIN__ */
#ifdef __WIN__
error_handling:
#endif
@@ -2380,7 +2490,9 @@ os_file_read_no_error_handling(
DWORD low;
DWORD high;
ibool retry;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2399,16 +2511,20 @@ try_again:
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2419,7 +2535,9 @@ try_again:
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2428,7 +2546,7 @@ try_again:
if (ret && len == n) {
return(TRUE);
}
-#else
+#else /* __WIN__ */
ibool retry;
ssize_t ret;
@@ -2441,7 +2559,7 @@ try_again:
return(TRUE);
}
-#endif
+#endif /* __WIN__ */
#ifdef __WIN__
error_handling:
#endif
@@ -2500,9 +2618,11 @@ os_file_write(
DWORD ret2;
DWORD low;
DWORD high;
- ulint i;
ulint n_retries = 0;
ulint err;
+#ifndef UNIV_HOTBACKUP
+ ulint i;
+#endif /* !UNIV_HOTBACKUP */
ut_a((offset & 0xFFFFFFFF) == offset);
@@ -2519,16 +2639,20 @@ retry:
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
@@ -2562,7 +2686,9 @@ retry:
}
# endif /* UNIV_DO_FLUSH */
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
@@ -2988,6 +3114,34 @@ os_aio_array_create(
return(array);
}
+/************************************************************************//**
+Frees an aio wait array. */
+static
+void
+os_aio_array_free(
+/*==============*/
+ os_aio_array_t* array) /*!< in, own: array to free */
+{
+#ifdef WIN_ASYNC_IO
+ ulint i;
+
+ for (i = 0; i < array->n_slots; i++) {
+ os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i);
+ os_event_free(slot->event);
+ }
+#endif /* WIN_ASYNC_IO */
+
+#ifdef __WIN__
+ ut_free(array->native_events);
+#endif /* __WIN__ */
+ os_mutex_free(array->mutex);
+ os_event_free(array->not_full);
+ os_event_free(array->is_empty);
+
+ ut_free(array->slots);
+ ut_free(array);
+}
+
/***********************************************************************
Initializes the asynchronous io system. Creates one array each for ibuf
and log i/o. Also creates one array each for read and write where each
@@ -3061,6 +3215,35 @@ os_aio_init(
}
+/***********************************************************************
+Frees the asynchronous io system. */
+UNIV_INTERN
+void
+os_aio_free(void)
+/*=============*/
+{
+ ulint i;
+
+ os_aio_array_free(os_aio_ibuf_array);
+ os_aio_ibuf_array = NULL;
+ os_aio_array_free(os_aio_log_array);
+ os_aio_log_array = NULL;
+ os_aio_array_free(os_aio_read_array);
+ os_aio_read_array = NULL;
+ os_aio_array_free(os_aio_write_array);
+ os_aio_write_array = NULL;
+ os_aio_array_free(os_aio_sync_array);
+ os_aio_sync_array = NULL;
+
+ for (i = 0; i < os_aio_n_segments; i++) {
+ os_event_free(os_aio_segment_wait_events[i]);
+ }
+
+ ut_free(os_aio_segment_wait_events);
+ os_aio_segment_wait_events = 0;
+ os_aio_n_segments = 0;
+}
+
#ifdef WIN_ASYNC_IO
/************************************************************************//**
Wakes up all async i/o threads in the array in Windows async i/o at
@@ -3211,7 +3394,8 @@ os_aio_array_reserve_slot(
offset */
ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint len) /*!< in: length of the block to read or write */
+ ulint len, /*!< in: length of the block to read or write */
+ trx_t* trx)
{
os_aio_slot_t* slot;
#ifdef WIN_ASYNC_IO
@@ -3432,9 +3616,21 @@ void
os_aio_simulated_put_read_threads_to_sleep(void)
/*============================================*/
{
+
+/* The idea of putting background IO threads to sleep is only for
+Windows when using simulated AIO. Windows XP seems to schedule
+background threads too eagerly to allow for coalescing during
+readahead requests. */
+#ifdef __WIN__
os_aio_array_t* array;
ulint g;
+ if (os_aio_use_native_aio) {
+ /* We do not use simulated aio: do nothing */
+
+ return;
+ }
+
os_aio_recommend_sleep_for_read_threads = TRUE;
for (g = 0; g < os_aio_n_segments; g++) {
@@ -3445,6 +3641,7 @@ os_aio_simulated_put_read_threads_to_sle
os_event_reset(os_aio_segment_wait_events[g]);
}
}
+#endif /* __WIN__ */
}
/*******************************************************************//**
@@ -3482,10 +3679,11 @@ os_aio(
(can be used to identify a completed
aio operation); ignored if mode is
OS_AIO_SYNC */
- void* message2)/*!< in: message for the aio handler
+ void* message2,/*!< in: message for the aio handler
(can be used to identify a completed
aio operation); ignored if mode is
OS_AIO_SYNC */
+ trx_t* trx)
{
os_aio_array_t* array;
os_aio_slot_t* slot;
@@ -3524,8 +3722,8 @@ os_aio(
wait in the Windows case. */
if (type == OS_FILE_READ) {
- return(os_file_read(file, buf, offset,
- offset_high, n));
+ return(_os_file_read(file, buf, offset,
+ offset_high, n, trx));
}
ut_a(type == OS_FILE_WRITE);
@@ -3558,8 +3756,13 @@ try_again:
ut_error;
}
+ if (trx && type == OS_FILE_READ)
+ {
+ trx->io_reads++;
+ trx->io_read += n;
+ }
slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
- name, buf, offset, offset_high, n);
+ name, buf, offset, offset_high, n, trx);
if (type == OS_FILE_READ) {
if (os_aio_use_native_aio) {
#ifdef WIN_ASYNC_IO
@@ -3679,6 +3882,7 @@ os_aio_windows_handle(
ibool ret_val;
BOOL ret;
DWORD len;
+ BOOL retry = FALSE;
if (segment == ULINT_UNDEFINED) {
array = os_aio_sync_array;
@@ -3732,14 +3936,52 @@ os_aio_windows_handle(
ut_a(TRUE == os_file_flush(slot->file));
}
#endif /* UNIV_DO_FLUSH */
+ } else if (os_file_handle_error(slot->name, "Windows aio")) {
+
+ retry = TRUE;
} else {
- os_file_handle_error(slot->name, "Windows aio");
ret_val = FALSE;
}
os_mutex_exit(array->mutex);
+ if (retry) {
+ /* retry failed read/write operation synchronously.
+ No need to hold array->mutex. */
+
+ switch (slot->type) {
+ case OS_FILE_WRITE:
+ ret = WriteFile(slot->file, slot->buf,
+ slot->len, &len,
+ &(slot->control));
+
+ break;
+ case OS_FILE_READ:
+ ret = ReadFile(slot->file, slot->buf,
+ slot->len, &len,
+ &(slot->control));
+
+ break;
+ default:
+ ut_error;
+ }
+
+ if (!ret && GetLastError() == ERROR_IO_PENDING) {
+ /* aio was queued successfully!
+ We want a synchronous i/o operation on a
+ file where we also use async i/o: in Windows
+ we must use the same wait mechanism as for
+ async i/o */
+
+ ret = GetOverlappedResult(slot->file,
+ &(slot->control),
+ &len, TRUE);
+ }
+
+ ret_val = ret && len == slot->len;
+ }
+
os_aio_array_free_slot(array, slot);
return(ret_val);
@@ -4018,6 +4260,18 @@ consecutive_loop:
}
}
+ if (srv_recovery_stats && recv_recovery_is_on() && n_consecutive) {
+ mutex_enter(&(recv_sys->mutex));
+ if (slot->type == OS_FILE_READ) {
+ recv_sys->stats_read_io_pages += n_consecutive;
+ recv_sys->stats_read_io_consecutive[n_consecutive - 1]++;
+ } else if (slot->type == OS_FILE_WRITE) {
+ recv_sys->stats_write_io_pages += n_consecutive;
+ recv_sys->stats_write_io_consecutive[n_consecutive - 1]++;
+ }
+ mutex_exit(&(recv_sys->mutex));
+ }
+
os_mutex_enter(array->mutex);
/* Mark the i/os done in slots */
=== modified file 'storage/xtradb/os/os0proc.c'
--- a/storage/xtradb/os/os0proc.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/os/os0proc.c 2010-01-06 12:00:14 +0000
@@ -97,6 +97,7 @@ os_mem_alloc_large(
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
" attach shared memory segment, errno %d\n",
errno);
+ ptr = NULL;
}
/* Remove the shared memory segment so that it will be
=== modified file 'storage/xtradb/os/os0sync.c'
--- a/storage/xtradb/os/os0sync.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/os/os0sync.c 2010-01-06 12:00:14 +0000
@@ -86,6 +86,9 @@ os_sync_init(void)
UT_LIST_INIT(os_event_list);
UT_LIST_INIT(os_mutex_list);
+ os_sync_mutex = NULL;
+ os_sync_mutex_inited = FALSE;
+
os_sync_mutex = os_mutex_create(NULL);
os_sync_mutex_inited = TRUE;
@@ -713,6 +716,7 @@ os_fast_mutex_free(
os_mutex_enter(os_sync_mutex);
}
+ ut_ad(os_fast_mutex_count > 0);
os_fast_mutex_count--;
if (UNIV_LIKELY(os_sync_mutex_inited)) {
=== modified file 'storage/xtradb/os/os0thread.c'
--- a/storage/xtradb/os/os0thread.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/os/os0thread.c 2010-01-06 12:00:14 +0000
@@ -233,6 +233,7 @@ os_thread_exit(
#ifdef __WIN__
ExitThread((DWORD)exit_value);
#else
+ pthread_detach(pthread_self());
pthread_exit(exit_value);
#endif
}
=== modified file 'storage/xtradb/page/page0cur.c'
--- a/storage/xtradb/page/page0cur.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/page/page0cur.c 2010-01-06 12:00:14 +0000
@@ -1195,7 +1195,7 @@ page_cur_insert_rec_zip_reorg(
}
/* Out of space: restore the page */
- if (!page_zip_decompress(page_zip, page)) {
+ if (!page_zip_decompress(page_zip, page, FALSE)) {
ut_error; /* Memory corrupted? */
}
ut_ad(page_validate(page, index));
=== modified file 'storage/xtradb/page/page0page.c'
--- a/storage/xtradb/page/page0page.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/page/page0page.c 2010-01-06 12:00:14 +0000
@@ -45,7 +45,7 @@ Created 2/2/1994 Heikki Tuuri
==============
The index page consists of a page header which contains the page's
-id and other information. On top of it are the the index records
+id and other information. On top of it are the index records
in a heap linked into a one way linear list according to alphabetic order.
Just below page end is an array of pointers which we call page directory,
@@ -679,7 +679,7 @@ page_copy_rec_list_end(
if (UNIV_UNLIKELY
(!page_zip_decompress(new_page_zip,
- new_page))) {
+ new_page, FALSE))) {
ut_error;
}
ut_ad(page_validate(new_page, index));
@@ -792,7 +792,7 @@ page_copy_rec_list_start(
if (UNIV_UNLIKELY
(!page_zip_decompress(new_page_zip,
- new_page))) {
+ new_page, FALSE))) {
ut_error;
}
ut_ad(page_validate(new_page, index));
=== modified file 'storage/xtradb/page/page0zip.c'
--- a/storage/xtradb/page/page0zip.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/page/page0zip.c 2010-01-06 12:00:14 +0000
@@ -47,8 +47,10 @@ Created June 2005 by Marko Makela
# define buf_LRU_stat_inc_unzip() ((void) 0)
#endif /* !UNIV_HOTBACKUP */
+#ifndef UNIV_HOTBACKUP
/** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
+#endif /* !UNIV_HOTBACKUP */
/* Please refer to ../include/page0zip.ic for a description of the
compressed page format. */
@@ -1144,7 +1146,9 @@ page_zip_compress(
ulint* offsets = NULL;
ulint n_blobs = 0;
byte* storage;/* storage of uncompressed columns */
+#ifndef UNIV_HOTBACKUP
ullint usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
#ifdef PAGE_ZIP_COMPRESS_DBG
FILE* logfile = NULL;
#endif
@@ -1208,7 +1212,9 @@ page_zip_compress(
}
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
page_zip_stat[page_zip->ssize - 1].compressed++;
+#endif /* !UNIV_HOTBACKUP */
if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
>= page_zip_get_size(page_zip))) {
@@ -1345,8 +1351,10 @@ err_exit:
fclose(logfile);
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
page_zip_stat[page_zip->ssize - 1].compressed_usec
+= ut_time_us(NULL) - usec;
+#endif /* !UNIV_HOTBACKUP */
return(FALSE);
}
@@ -1404,12 +1412,14 @@ err_exit:
fclose(logfile);
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
{
page_zip_stat_t* zip_stat
= &page_zip_stat[page_zip->ssize - 1];
zip_stat->compressed_ok++;
zip_stat->compressed_usec += ut_time_us(NULL) - usec;
}
+#endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
@@ -2811,7 +2821,11 @@ page_zip_decompress(
/*================*/
page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
- page_t* page) /*!< out: uncompressed page, may be trashed */
+ page_t* page, /*!< out: uncompressed page, may be trashed */
+ ibool all) /*!< in: TRUE=decompress the whole page;
+ FALSE=verify but do not copy some
+ page header fields that should not change
+ after page creation */
{
z_stream d_stream;
dict_index_t* index = NULL;
@@ -2820,7 +2834,9 @@ page_zip_decompress(
ulint trx_id_col = ULINT_UNDEFINED;
mem_heap_t* heap;
ulint* offsets;
+#ifndef UNIV_HOTBACKUP
ullint usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
@@ -2839,13 +2855,36 @@ page_zip_decompress(
heap = mem_heap_create(n_dense * (3 * sizeof *recs) + UNIV_PAGE_SIZE);
recs = mem_heap_alloc(heap, n_dense * (2 * sizeof *recs));
+ if (all) {
+ /* Copy the page header. */
+ memcpy(page, page_zip->data, PAGE_DATA);
+ } else {
+ /* Check that the bytes that we skip are identical. */
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ ut_a(!memcmp(FIL_PAGE_TYPE + page,
+ FIL_PAGE_TYPE + page_zip->data,
+ PAGE_HEADER - FIL_PAGE_TYPE));
+ ut_a(!memcmp(PAGE_HEADER + PAGE_LEVEL + page,
+ PAGE_HEADER + PAGE_LEVEL + page_zip->data,
+ PAGE_DATA - (PAGE_HEADER + PAGE_LEVEL)));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+
+ /* Copy the mutable parts of the page header. */
+ memcpy(page, page_zip->data, FIL_PAGE_TYPE);
+ memcpy(PAGE_HEADER + page, PAGE_HEADER + page_zip->data,
+ PAGE_LEVEL - PAGE_N_DIR_SLOTS);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ /* Check that the page headers match after copying. */
+ ut_a(!memcmp(page, page_zip->data, PAGE_DATA));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+ }
+
#ifdef UNIV_ZIP_DEBUG
- /* Clear the page. */
- memset(page, 0x55, UNIV_PAGE_SIZE);
+ /* Clear the uncompressed page, except the header. */
+ memset(PAGE_DATA + page, 0x55, UNIV_PAGE_SIZE - PAGE_DATA);
#endif /* UNIV_ZIP_DEBUG */
- UNIV_MEM_INVALID(page, UNIV_PAGE_SIZE);
- /* Copy the page header. */
- memcpy(page, page_zip->data, PAGE_DATA);
+ UNIV_MEM_INVALID(PAGE_DATA + page, UNIV_PAGE_SIZE - PAGE_DATA);
/* Copy the page directory. */
if (UNIV_UNLIKELY(!page_zip_dir_decode(page_zip, page, recs,
@@ -2976,12 +3015,14 @@ err_exit:
page_zip_fields_free(index);
mem_heap_free(heap);
+#ifndef UNIV_HOTBACKUP
{
page_zip_stat_t* zip_stat
= &page_zip_stat[page_zip->ssize - 1];
zip_stat->decompressed++;
zip_stat->decompressed_usec += ut_time_us(NULL) - usec;
}
+#endif /* !UNIV_HOTBACKUP */
/* Update the stat counter for LRU policy. */
buf_LRU_stat_inc_unzip();
@@ -3084,7 +3125,7 @@ page_zip_validate_low(
#endif /* UNIV_DEBUG_VALGRIND */
temp_page_zip = *page_zip;
- valid = page_zip_decompress(&temp_page_zip, temp_page);
+ valid = page_zip_decompress(&temp_page_zip, temp_page, TRUE);
if (!valid) {
fputs("page_zip_validate(): failed to decompress\n", stderr);
goto func_exit;
@@ -4362,8 +4403,8 @@ IMPORTANT: if page_zip_reorganize() is i
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
will be redo-logged.
-@return TRUE on success, FALSE on failure; page and page_zip will be
-left intact on failure. */
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure, but page will be overwritten. */
UNIV_INTERN
ibool
page_zip_reorganize(
@@ -4428,9 +4469,6 @@ page_zip_reorganize(
if (UNIV_UNLIKELY(!page_zip_compress(page_zip, page, index, mtr))) {
- /* Restore the old page and exit. */
- buf_frame_copy(page, temp_page);
-
#ifndef UNIV_HOTBACKUP
buf_block_free(temp_block);
#endif /* !UNIV_HOTBACKUP */
@@ -4591,7 +4629,8 @@ corrupt:
memcpy(page_zip->data + page_zip_get_size(page_zip)
- trailer_size, ptr + 8 + size, trailer_size);
- if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, page))) {
+ if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, page,
+ TRUE))) {
goto corrupt;
}
=== modified file 'storage/xtradb/pars/lexyy.c'
--- a/storage/xtradb/pars/lexyy.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/pars/lexyy.c 2010-01-17 11:41:32 +0000
@@ -2778,3 +2778,18 @@ static void yyfree (void * ptr )
+
+/**********************************************************************
+Release any resources used by the lexer. */
+UNIV_INTERN
+void
+pars_lexer_close(void)
+/*==================*/
+{
+ if (yy_buffer_stack)
+ yylex_destroy();
+ if (stringbuf)
+ free(stringbuf);
+ stringbuf = NULL;
+ stringbuf_len_alloc = stringbuf_len = 0;
+}
=== modified file 'storage/xtradb/pars/pars0lex.l'
--- a/storage/xtradb/pars/pars0lex.l 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/pars/pars0lex.l 2010-01-17 11:41:32 +0000
@@ -661,3 +661,18 @@ In the state 'id', only two actions are
}
%%
+
+/**********************************************************************
+Release any resources used by the lexer. */
+UNIV_INTERN
+void
+pars_lexer_close(void)
+/*==================*/
+{
+ if (yy_buffer_stack)
+ yylex_destroy();
+ if (stringbuf)
+ free(stringbuf);
+ stringbuf = NULL;
+ stringbuf_len_alloc = stringbuf_len = 0;
+}
=== modified file 'storage/xtradb/plug.in'
--- a/storage/xtradb/plug.in 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/plug.in 2010-01-15 15:58:25 +0000
@@ -40,19 +40,11 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
irix*|osf*|sysv5uw7*|openbsd*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
*solaris*|*SunOS*)
- # Begin Solaris atomic function checks
- AC_CHECK_FUNCS(atomic_cas_ulong atomic_cas_32 \
- atomic_cas_64 atomic_add_long,
- AC_DEFINE(
- [HAVE_SOLARIS_ATOMICS],
- [1],
- [Define to 1 if Solaris supports \
- atomic functions.]))
- ### End Solaris atomic function checks
-
CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
esac
+
INNODB_DYNAMIC_CFLAGS="-DMYSQL_DYNAMIC_PLUGIN"
+
case "$target_cpu" in
x86_64)
# The AMD64 ABI forbids absolute addresses in shared libraries
@@ -63,7 +55,60 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
;;
esac
AC_SUBST(INNODB_DYNAMIC_CFLAGS)
+
+ AC_MSG_CHECKING(whether GCC atomic builtins are available)
+ # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not
+ AC_TRY_RUN(
+ [
+ int main()
+ {
+ long x;
+ long y;
+ long res;
+ char c;
+
+ x = 10;
+ y = 123;
+ res = __sync_bool_compare_and_swap(&x, x, y);
+ if (!res || x != y) {
+ return(1);
+ }
+
+ x = 10;
+ y = 123;
+ res = __sync_bool_compare_and_swap(&x, x + 1, y);
+ if (res || x != 10) {
+ return(1);
+ }
+
+ x = 10;
+ y = 123;
+ res = __sync_add_and_fetch(&x, y);
+ if (res != 123 + 10 || x != 123 + 10) {
+ return(1);
+ }
+
+ c = 10;
+ res = __sync_lock_test_and_set(&c, 123);
+ if (res != 10 || c != 123) {
+ return(1);
+ }
+
+ return(0);
+ }
+ ],
+ [
+ AC_DEFINE([HAVE_IB_GCC_ATOMIC_BUILTINS], [1],
+ [GCC atomic builtins are available])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+ )
+
AC_MSG_CHECKING(whether pthread_t can be used by GCC atomic builtins)
+ # either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not
AC_TRY_RUN(
[
#include <pthread.h>
@@ -84,47 +129,73 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
}
],
[
- AC_DEFINE([HAVE_ATOMIC_PTHREAD_T], [1],
+ AC_DEFINE([HAVE_IB_ATOMIC_PTHREAD_T_GCC], [1],
[pthread_t can be used by GCC atomic builtins])
AC_MSG_RESULT(yes)
],
[
AC_MSG_RESULT(no)
]
- )
+ )
+
+ AC_MSG_CHECKING(whether Solaris libc atomic functions are available)
+ # either define HAVE_IB_SOLARIS_ATOMICS or not
+ AC_CHECK_FUNCS(atomic_add_long \
+ atomic_cas_32 \
+ atomic_cas_64 \
+ atomic_cas_ulong,
+
+ AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1],
+ [Define to 1 if Solaris libc atomic functions \
+ are available])
+ )
+
+ AC_MSG_CHECKING(whether pthread_t can be used by Solaris libc atomic functions)
+ # either define HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS or not
+ AC_TRY_RUN(
+ [
+ #include <pthread.h>
+ #include <string.h>
- # Try using solaris atomics on SunOS if GCC atomics are not available
- AC_CHECK_DECLS(
- [HAVE_ATOMIC_PTHREAD_T],
- [
- AC_MSG_NOTICE(no need to check pthread_t size)
- ],
- [
- AC_CHECK_DECLS(
- [HAVE_SOLARIS_ATOMICS],
- [
- AC_MSG_CHECKING(checking if pthread_t size is integral)
- AC_TRY_RUN(
- [
- #include <pthread.h>
- int main()
- {
- pthread_t x = 0;
- return(0);
- }
- ],
- [
- AC_DEFINE([HAVE_ATOMIC_PTHREAD_T], [1],
+ int main(int argc, char** argv) {
+ pthread_t x1;
+ pthread_t x2;
+ pthread_t x3;
+
+ memset(&x1, 0x0, sizeof(x1));
+ memset(&x2, 0x0, sizeof(x2));
+ memset(&x3, 0x0, sizeof(x3));
+
+ if (sizeof(pthread_t) == 4) {
+
+ atomic_cas_32(&x1, x2, x3);
+
+ } else if (sizeof(pthread_t) == 8) {
+
+ atomic_cas_64(&x1, x2, x3);
+
+ } else {
+
+ return(1);
+ }
+
+ return(0);
+ }
+ ],
+ [
+ AC_DEFINE([HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS], [1],
[pthread_t can be used by solaris atomics])
- AC_MSG_RESULT(yes)
- # size of pthread_t is needed for typed solaris atomics
- AC_CHECK_SIZEOF([pthread_t], [], [#include <pthread.h>])
- ],
- [
- AC_MSG_RESULT(no)
- ])
- ])
- ])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+ )
+
+ # this is needed to know which one of atomic_cas_32() or atomic_cas_64()
+ # to use in the source
+ AC_CHECK_SIZEOF([pthread_t], [], [#include <pthread.h>])
+
# Check for x86 PAUSE instruction
AC_MSG_CHECKING(for x86 PAUSE instruction)
# We have to actually try running the test program, because of a bug
@@ -141,7 +212,7 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
}
],
[
- AC_DEFINE([IB_HAVE_PAUSE_INSTRUCTION], [1], [Does x86 PAUSE instruction exist])
+ AC_DEFINE([HAVE_IB_PAUSE_INSTRUCTION], [1], [Does x86 PAUSE instruction exist])
AC_MSG_RESULT(yes)
],
[
=== modified file 'storage/xtradb/que/que0que.c'
--- a/storage/xtradb/que/que0que.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/que/que0que.c 2010-01-06 12:00:14 +0000
@@ -518,6 +518,7 @@ que_graph_free_recursive(
upd_node_t* upd;
tab_node_t* cre_tab;
ind_node_t* cre_ind;
+ purge_node_t* purge;
if (node == NULL) {
@@ -579,6 +580,13 @@ que_graph_free_recursive(
mem_heap_free(ins->entry_sys_heap);
break;
+ case QUE_NODE_PURGE:
+ purge = node;
+
+ mem_heap_free(purge->heap);
+
+ break;
+
case QUE_NODE_UPDATE:
upd = node;
=== modified file 'storage/xtradb/rem/rem0cmp.c'
--- a/storage/xtradb/rem/rem0cmp.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/rem/rem0cmp.c 2010-01-06 12:00:14 +0000
@@ -36,7 +36,7 @@ Created 7/1/1994 Heikki Tuuri
The records are put into alphabetical order in the following
way: let F be the first field where two records disagree.
-If there is a character in some position n where the the
+If there is a character in some position n where the
records disagree, the order is determined by comparison of
the characters at position n, possibly after
collating transformation. If there is no such character,
@@ -76,7 +76,7 @@ cmp_debug_dtuple_rec_with_match(
/*************************************************************//**
This function is used to compare two data fields for which the data type
is such that we must use MySQL code to compare them. The prototype here
-must be a copy of the the one in ha_innobase.cc!
+must be a copy of the one in ha_innobase.cc!
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
extern
int
@@ -399,7 +399,7 @@ next_byte:
/*************************************************************//**
This function is used to compare a data tuple to a physical record.
Only dtuple->n_fields_cmp first fields are taken into account for
-the the data tuple! If we denote by n = n_fields_cmp, then rec must
+the data tuple! If we denote by n = n_fields_cmp, then rec must
have either m >= n fields, or it must differ from dtuple in some of
the m fields rec has. If rec has an externally stored field we do not
compare it but return with value 0 if such a comparison should be
=== modified file 'storage/xtradb/row/row0ins.c'
--- a/storage/xtradb/row/row0ins.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/row/row0ins.c 2010-01-15 15:58:25 +0000
@@ -141,7 +141,7 @@ row_ins_alloc_sys_fields(
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROW_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROW_ID_LEN);
dfield_set_data(dfield, ptr, DATA_ROW_ID_LEN);
@@ -152,7 +152,7 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_TRX_ID);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_TRX_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_TRX_ID_LEN);
dfield_set_data(dfield, ptr, DATA_TRX_ID_LEN);
@@ -163,7 +163,7 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_ROLL_PTR);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROLL_PTR_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROLL_PTR_LEN);
dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
}
@@ -1191,7 +1191,7 @@ row_ins_check_foreign_constraint(
/*=============================*/
ibool check_ref,/*!< in: TRUE if we want to check that
the referenced table is ok, FALSE if we
- want to to check the foreign key table */
+ want to check the foreign key table */
dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
tables mentioned in it must be in the
dictionary cache if they exist at all */
=== modified file 'storage/xtradb/row/row0merge.c'
--- a/storage/xtradb/row/row0merge.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/row/row0merge.c 2010-01-06 12:00:14 +0000
@@ -60,9 +60,19 @@ Completed by Sunny Bains and Marko Makel
#ifdef UNIV_DEBUG
/** Set these in order ot enable debug printout. */
/* @{ */
+/** Log the outcome of each row_merge_cmp() call, comparing records. */
static ibool row_merge_print_cmp;
+/** Log each record read from temporary file. */
static ibool row_merge_print_read;
+/** Log each record write to temporary file. */
static ibool row_merge_print_write;
+/** Log each row_merge_blocks() call, merging two blocks of records to
+a bigger one. */
+static ibool row_merge_print_block;
+/** Log each block read from temporary file. */
+static ibool row_merge_print_block_read;
+/** Log each block read from temporary file. */
+static ibool row_merge_print_block_write;
/* @} */
#endif /* UNIV_DEBUG */
@@ -109,8 +119,9 @@ typedef struct row_merge_buf_struct row_
/** Information about temporary files used in merge sort */
struct merge_file_struct {
- int fd; /*!< file descriptor */
- ulint offset; /*!< file offset */
+ int fd; /*!< file descriptor */
+ ulint offset; /*!< file offset (end of file) */
+ ib_uint64_t n_rec; /*!< number of records in the file */
};
/** Information about temporary files used in merge sort */
@@ -682,6 +693,13 @@ row_merge_read(
ib_uint64_t ofs = ((ib_uint64_t) offset) * sizeof *buf;
ibool success;
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block_read) {
+ fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n",
+ fd, (ulong) offset);
+ }
+#endif /* UNIV_DEBUG */
+
success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
@@ -709,6 +727,13 @@ row_merge_write(
ib_uint64_t ofs = ((ib_uint64_t) offset)
* sizeof(row_merge_block_t);
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block_write) {
+ fprintf(stderr, "row_merge_write fd=%d ofs=%lu\n",
+ fd, (ulong) offset);
+ }
+#endif /* UNIV_DEBUG */
+
return(UNIV_LIKELY(os_file_write("(merge)", OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
@@ -718,7 +743,7 @@ row_merge_write(
/********************************************************************//**
Read a merge record.
@return pointer to next record, or NULL on I/O error or end of list */
-static
+static __attribute__((nonnull))
const byte*
row_merge_read_rec(
/*===============*/
@@ -1070,7 +1095,7 @@ row_merge_cmp(
Reads clustered index of the table and create temporary files
containing the index entries for the indexes to be built.
@return DB_SUCCESS or error */
-static
+static __attribute__((nonnull))
ulint
row_merge_read_clustered_index(
/*===========================*/
@@ -1175,6 +1200,12 @@ row_merge_read_clustered_index(
in order to release the latch on the old page. */
if (btr_pcur_is_after_last_on_page(&pcur)) {
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ i = 0;
+ err = DB_INTERRUPTED;
+ goto err_exit;
+ }
+
btr_pcur_store_position(&pcur, &mtr);
mtr_commit(&mtr);
mtr_start(&mtr);
@@ -1233,6 +1264,7 @@ row_merge_read_clustered_index(
if (UNIV_LIKELY
(row && row_merge_buf_add(buf, row, ext))) {
+ file->n_rec++;
continue;
}
@@ -1274,14 +1306,19 @@ err_exit:
UNIV_MEM_INVALID(block[0], sizeof block[0]);
merge_buf[i] = row_merge_buf_empty(buf);
- /* Try writing the record again, now that
- the buffer has been written out and emptied. */
+ if (UNIV_LIKELY(row != NULL)) {
+ /* Try writing the record again, now
+ that the buffer has been written out
+ and emptied. */
+
+ if (UNIV_UNLIKELY
+ (!row_merge_buf_add(buf, row, ext))) {
+ /* An empty buffer should have enough
+ room for at least one record. */
+ ut_error;
+ }
- if (UNIV_UNLIKELY
- (row && !row_merge_buf_add(buf, row, ext))) {
- /* An empty buffer should have enough
- room for at least one record. */
- ut_error;
+ file->n_rec++;
}
}
@@ -1320,7 +1357,7 @@ func_exit:
b2 = row_merge_write_rec(&block[2], &buf[2], b2, \
of->fd, &of->offset, \
mrec##N, offsets##N); \
- if (UNIV_UNLIKELY(!b2)) { \
+ if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
goto corrupt; \
} \
b##N = row_merge_read_rec(&block[N], &buf[N], \
@@ -1336,14 +1373,14 @@ func_exit:
} while (0)
/*************************************************************//**
-Merge two blocks of linked lists on disk and write a bigger block.
+Merge two blocks of records on disk and write a bigger block.
@return DB_SUCCESS or error code */
static
ulint
row_merge_blocks(
/*=============*/
const dict_index_t* index, /*!< in: index being created */
- merge_file_t* file, /*!< in/out: file containing
+ const merge_file_t* file, /*!< in: file containing
index entries */
row_merge_block_t* block, /*!< in/out: 3 buffers */
ulint* foffs0, /*!< in/out: offset of first
@@ -1366,6 +1403,17 @@ row_merge_blocks(
ulint* offsets0;/* offsets of mrec0 */
ulint* offsets1;/* offsets of mrec1 */
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block) {
+ fprintf(stderr,
+ "row_merge_blocks fd=%d ofs=%lu + fd=%d ofs=%lu"
+ " = fd=%d ofs=%lu\n",
+ file->fd, (ulong) *foffs0,
+ file->fd, (ulong) *foffs1,
+ of->fd, (ulong) of->offset);
+ }
+#endif /* UNIV_DEBUG */
+
heap = row_merge_heap_create(index, &offsets0, &offsets1);
/* Write a record and read the next record. Split the output
@@ -1438,16 +1486,88 @@ done1:
}
/*************************************************************//**
+Copy a block of index entries.
+@return TRUE on success, FALSE on failure */
+static __attribute__((nonnull))
+ibool
+row_merge_blocks_copy(
+/*==================*/
+ const dict_index_t* index, /*!< in: index being created */
+ const merge_file_t* file, /*!< in: input file */
+ row_merge_block_t* block, /*!< in/out: 3 buffers */
+ ulint* foffs0, /*!< in/out: input file offset */
+ merge_file_t* of) /*!< in/out: output file */
+{
+ mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
+
+ mrec_buf_t buf[3]; /*!< buffer for handling
+ split mrec in block[] */
+ const byte* b0; /*!< pointer to block[0] */
+ byte* b2; /*!< pointer to block[2] */
+ const mrec_t* mrec0; /*!< merge rec, points to block[0] */
+ ulint* offsets0;/* offsets of mrec0 */
+ ulint* offsets1;/* dummy offsets */
+
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block) {
+ fprintf(stderr,
+ "row_merge_blocks_copy fd=%d ofs=%lu"
+ " = fd=%d ofs=%lu\n",
+ file->fd, (ulong) foffs0,
+ of->fd, (ulong) of->offset);
+ }
+#endif /* UNIV_DEBUG */
+
+ heap = row_merge_heap_create(index, &offsets0, &offsets1);
+
+ /* Write a record and read the next record. Split the output
+ file in two halves, which can be merged on the following pass. */
+
+ if (!row_merge_read(file->fd, *foffs0, &block[0])) {
+corrupt:
+ mem_heap_free(heap);
+ return(FALSE);
+ }
+
+ b0 = block[0];
+ b2 = block[2];
+
+ b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->fd,
+ foffs0, &mrec0, offsets0);
+ if (UNIV_UNLIKELY(!b0 && mrec0)) {
+
+ goto corrupt;
+ }
+
+ if (mrec0) {
+ /* append all mrec0 to output */
+ for (;;) {
+ ROW_MERGE_WRITE_GET_NEXT(0, goto done0);
+ }
+ }
+done0:
+
+ /* The file offset points to the beginning of the last page
+ that has been read. Update it to point to the next block. */
+ (*foffs0)++;
+
+ mem_heap_free(heap);
+ return(row_merge_write_eof(&block[2], b2, of->fd, &of->offset)
+ != NULL);
+}
+
+/*************************************************************//**
Merge disk files.
@return DB_SUCCESS or error code */
-static
+static __attribute__((nonnull))
ulint
row_merge(
/*======*/
+ trx_t* trx, /*!< in: transaction */
const dict_index_t* index, /*!< in: index being created */
merge_file_t* file, /*!< in/out: file containing
index entries */
- ulint half, /*!< in: half the file */
+ ulint* half, /*!< in/out: half the file */
row_merge_block_t* block, /*!< in/out: 3 buffers */
int* tmpfd, /*!< in/out: temporary file handle */
TABLE* table) /*!< in/out: MySQL table, for
@@ -1458,43 +1578,87 @@ row_merge(
ulint foffs1; /*!< second input offset */
ulint error; /*!< error code */
merge_file_t of; /*!< output file */
+ const ulint ihalf = *half;
+ /*!< half the input file */
+ ulint ohalf; /*!< half the output file */
UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]);
- ut_ad(half > 0);
+ ut_ad(ihalf < file->offset);
of.fd = *tmpfd;
of.offset = 0;
+ of.n_rec = 0;
/* Merge blocks to the output file. */
+ ohalf = 0;
foffs0 = 0;
- foffs1 = half;
+ foffs1 = ihalf;
+
+ for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
+ ulint ahalf; /*!< arithmetic half the input file */
+
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ return(DB_INTERRUPTED);
+ }
- for (; foffs0 < half && foffs1 < file->offset; foffs0++, foffs1++) {
error = row_merge_blocks(index, file, block,
&foffs0, &foffs1, &of, table);
if (error != DB_SUCCESS) {
return(error);
}
+
+ /* Record the offset of the output file when
+ approximately half the output has been generated. In
+ this way, the next invocation of row_merge() will
+ spend most of the time in this loop. The initial
+ estimate is ohalf==0. */
+ ahalf = file->offset / 2;
+ ut_ad(ohalf <= of.offset);
+
+ /* Improve the estimate until reaching half the input
+ file size, or we can not get any closer to it. All
+ comparands should be non-negative when !(ohalf < ahalf)
+ because ohalf <= of.offset. */
+ if (ohalf < ahalf || of.offset - ahalf < ohalf - ahalf) {
+ ohalf = of.offset;
+ }
}
- /* Copy the last block, if there is one. */
- while (foffs0 < half) {
- if (!row_merge_read(file->fd, foffs0++, block)
- || !row_merge_write(of.fd, of.offset++, block)) {
+ /* Copy the last blocks, if there are any. */
+
+ while (foffs0 < ihalf) {
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ return(DB_INTERRUPTED);
+ }
+
+ if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
return(DB_CORRUPTION);
}
}
+
+ ut_ad(foffs0 == ihalf);
+
while (foffs1 < file->offset) {
- if (!row_merge_read(file->fd, foffs1++, block)
- || !row_merge_write(of.fd, of.offset++, block)) {
+ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
+ return(DB_INTERRUPTED);
+ }
+
+ if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
return(DB_CORRUPTION);
}
}
+ ut_ad(foffs1 == file->offset);
+
+ if (UNIV_UNLIKELY(of.n_rec != file->n_rec)) {
+ return(DB_CORRUPTION);
+ }
+
/* Swap file descriptors for the next pass. */
*tmpfd = file->fd;
*file = of;
+ *half = ohalf;
UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]);
@@ -1508,6 +1672,7 @@ static
ulint
row_merge_sort(
/*===========*/
+ trx_t* trx, /*!< in: transaction */
const dict_index_t* index, /*!< in: index being created */
merge_file_t* file, /*!< in/out: file containing
index entries */
@@ -1517,20 +1682,26 @@ row_merge_sort(
reporting erroneous key value
if applicable */
{
- ulint blksz; /*!< block size */
+ ulint half = file->offset / 2;
+
+ /* The file should always contain at least one byte (the end
+ of file marker). Thus, it must be at least one block. */
+ ut_ad(file->offset > 0);
- for (blksz = 1; blksz < file->offset; blksz *= 2) {
- ulint half;
+ do {
ulint error;
- ut_ad(ut_is_2pow(blksz));
- half = ut_2pow_round((file->offset + (blksz - 1)) / 2, blksz);
- error = row_merge(index, file, half, block, tmpfd, table);
+ error = row_merge(trx, index, file, &half,
+ block, tmpfd, table);
if (error != DB_SUCCESS) {
return(error);
}
- }
+
+ /* half > 0 should hold except when the file consists
+ of one block. No need to merge further then. */
+ ut_ad(half > 0 || file->offset == 1);
+ } while (half < file->offset && half > 0);
return(DB_SUCCESS);
}
@@ -1797,7 +1968,15 @@ row_merge_drop_index(
static const char str1[] =
"PROCEDURE DROP_INDEX_PROC () IS\n"
"BEGIN\n"
+ /* Rename the index, so that it will be dropped by
+ row_merge_drop_temp_indexes() at crash recovery
+ if the server crashes before this trx is committed. */
+ "UPDATE SYS_INDEXES SET NAME=CONCAT('"
+ TEMP_INDEX_PREFIX_STR "', NAME) WHERE ID = :indexid;\n"
+ "COMMIT WORK;\n"
+ /* Drop the field definitions of the index. */
"DELETE FROM SYS_FIELDS WHERE INDEX_ID = :indexid;\n"
+ /* Drop the index definition and the B-tree. */
"DELETE FROM SYS_INDEXES WHERE ID = :indexid\n"
" AND TABLE_ID = :tableid;\n"
"END;\n";
@@ -1909,6 +2088,7 @@ row_merge_file_create(
{
merge_file->fd = innobase_mysql_tmpfile();
merge_file->offset = 0;
+ merge_file->n_rec = 0;
}
/*********************************************************************//**
@@ -2129,7 +2309,7 @@ row_merge_rename_tables(
if (err != DB_SUCCESS) {
err_exit:
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
}
@@ -2331,7 +2511,7 @@ row_merge_build_indexes(
sorting and inserting. */
for (i = 0; i < n_indexes; i++) {
- error = row_merge_sort(indexes[i], &merge_files[i],
+ error = row_merge_sort(trx, indexes[i], &merge_files[i],
block, &tmpfd, table);
if (error == DB_SUCCESS) {
=== modified file 'storage/xtradb/row/row0mysql.c'
--- a/storage/xtradb/row/row0mysql.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/row/row0mysql.c 2010-01-06 12:00:14 +0000
@@ -510,7 +510,7 @@ handle_new_error:
switch (err) {
case DB_LOCK_WAIT_TIMEOUT:
if (row_rollback_on_timeout) {
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
break;
}
/* fall through */
@@ -526,7 +526,7 @@ handle_new_error:
/* Roll back the latest, possibly incomplete
insertion or update */
- trx_general_rollback_for_mysql(trx, TRUE, savept);
+ trx_general_rollback_for_mysql(trx, savept);
}
/* MySQL will roll back the latest SQL statement */
break;
@@ -548,7 +548,7 @@ handle_new_error:
/* Roll back the whole transaction; this resolution was added
to version 3.23.43 */
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
break;
case DB_MUST_GET_MORE_FILE_SPACE:
@@ -869,18 +869,22 @@ row_update_statistics_if_needed(
}
/*********************************************************************//**
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
UNIV_INTERN
void
row_unlock_table_autoinc_for_mysql(
/*===============================*/
trx_t* trx) /*!< in/out: transaction */
{
- mutex_enter(&kernel_mutex);
+ if (lock_trx_holds_autoinc_locks(trx)) {
+ mutex_enter(&kernel_mutex);
- lock_release_autoinc_locks(trx);
+ lock_release_autoinc_locks(trx);
- mutex_exit(&kernel_mutex);
+ mutex_exit(&kernel_mutex);
+ }
}
/*********************************************************************//**
@@ -1770,7 +1774,6 @@ row_create_table_for_mysql(
const char* table_name;
ulint table_name_len;
ulint err;
- ulint i;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
#ifdef UNIV_SYNC_DEBUG
@@ -1805,15 +1808,6 @@ err_exit:
goto err_exit;
}
- /* Check that no reserved column names are used. */
- for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
- if (dict_col_name_is_reserved(
- dict_table_get_col_name(table, i))) {
-
- goto err_exit;
- }
- }
-
trx_start_if_not_started(trx);
/* The table name is prefixed with the database name and a '/'.
@@ -1888,7 +1882,9 @@ err_exit:
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
+ /* TO DO: free table? The code below will dereference
+ table->name, though. */
}
switch (err) {
@@ -1907,31 +1903,6 @@ err_exit:
break;
case DB_DUPLICATE_KEY:
- ut_print_timestamp(stderr);
- fputs(" InnoDB: Error: table ", stderr);
- ut_print_name(stderr, trx, TRUE, table->name);
- fputs(" already exists in InnoDB internal\n"
- "InnoDB: data dictionary. Have you deleted"
- " the .frm file\n"
- "InnoDB: and not used DROP TABLE?"
- " Have you used DROP DATABASE\n"
- "InnoDB: for InnoDB tables in"
- " MySQL version <= 3.23.43?\n"
- "InnoDB: See the Restrictions section"
- " of the InnoDB manual.\n"
- "InnoDB: You can drop the orphaned table"
- " inside InnoDB by\n"
- "InnoDB: creating an InnoDB table with"
- " the same name in another\n"
- "InnoDB: database and copying the .frm file"
- " to the current database.\n"
- "InnoDB: Then MySQL thinks the table exists,"
- " and DROP TABLE will\n"
- "InnoDB: succeed.\n"
- "InnoDB: You can look for further help from\n"
- "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
- stderr);
-
/* We may also get err == DB_ERROR if the .ibd file for the
table already exists */
@@ -2056,7 +2027,7 @@ error_handling:
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
row_drop_table_for_mysql(table_name, trx, FALSE);
@@ -2077,7 +2048,7 @@ Scans a table create SQL string and adds
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
Each foreign key constraint must be accompanied with indexes in
-bot participating tables. The indexes are allowed to contain more
+both participating tables. The indexes are allowed to contain more
fields than mentioned in the constraint. Check also that foreign key
constraints which reference this table are ok.
@return error code or DB_SUCCESS */
@@ -2124,7 +2095,7 @@ row_table_add_foreign_constraints(
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
row_drop_table_for_mysql(name, trx, FALSE);
@@ -2491,7 +2462,7 @@ row_discard_tablespace_for_mysql(
if (err != DB_SUCCESS) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
} else {
dict_table_change_id_in_cache(table, new_id);
@@ -2500,7 +2471,7 @@ row_discard_tablespace_for_mysql(
if (!success) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
err = DB_ERROR;
@@ -2952,7 +2923,7 @@ next_rec:
if (err != DB_SUCCESS) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
ut_print_timestamp(stderr);
fputs(" InnoDB: Unable to assign a new identifier to table ",
@@ -3593,7 +3564,7 @@ row_delete_constraint(
if ((err == DB_SUCCESS) && !strchr(id, '/')) {
/* Old format < 4.0.18 constraints have constraint ids
- <number>_<number>. We only try deleting them if the
+ NUMBER_NUMBER. We only try deleting them if the
constraint name does not contain a '/' character, otherwise
deleting a new format constraint named 'foo/bar' from
database 'baz' would remove constraint 'bar' from database
@@ -3857,7 +3828,7 @@ end:
"InnoDB: succeed.\n", stderr);
}
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
} else {
/* The following call will also rename the .ibd data file if
@@ -3866,7 +3837,7 @@ end:
if (!dict_table_rename_in_cache(table, new_name,
!new_is_tmp)) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
goto funct_exit;
}
@@ -3906,7 +3877,7 @@ end:
ut_a(dict_table_rename_in_cache(table,
old_name, FALSE));
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
}
}
@@ -4166,6 +4137,7 @@ row_check_table_for_mysql(
}
if (trx_is_interrupted(prebuilt->trx)) {
+ ret = DB_INTERRUPTED;
break;
}
=== modified file 'storage/xtradb/row/row0sel.c'
--- a/storage/xtradb/row/row0sel.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/row/row0sel.c 2010-01-15 21:12:30 +0000
@@ -4616,6 +4616,7 @@ row_search_autoinc_read_column(
dict_index_t* index, /*!< in: index to read from */
const rec_t* rec, /*!< in: current rec */
ulint col_no, /*!< in: column number */
+ ulint mtype, /*!< in: column main type */
ibool unsigned_type) /*!< in: signed or unsigned flag */
{
ulint len;
@@ -4632,10 +4633,27 @@ row_search_autoinc_read_column(
data = rec_get_nth_field(rec, offsets, col_no, &len);
ut_a(len != UNIV_SQL_NULL);
- ut_a(len <= sizeof value);
/* we assume AUTOINC value cannot be negative */
- value = mach_read_int_type(data, len, unsigned_type);
+ switch (mtype) {
+ case DATA_INT:
+ ut_a(len <= sizeof value);
+ value = mach_read_int_type(data, len, unsigned_type);
+ break;
+
+ case DATA_FLOAT:
+ ut_a(len == sizeof(float));
+ value = mach_float_read(data);
+ break;
+
+ case DATA_DOUBLE:
+ ut_a(len == sizeof(double));
+ value = mach_double_read(data);
+ break;
+
+ default:
+ ut_error;
+ }
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@@ -4721,7 +4739,8 @@ row_search_max_autoinc(
dfield->col->prtype & DATA_UNSIGNED);
*value = row_search_autoinc_read_column(
- index, rec, i, unsigned_type);
+ index, rec, i,
+ dfield->col->mtype, unsigned_type);
}
}
=== modified file 'storage/xtradb/scripts/install_innodb_plugins.sql'
--- a/storage/xtradb/scripts/install_innodb_plugins.sql 2009-06-25 01:43:25 +0000
+++ b/storage/xtradb/scripts/install_innodb_plugins.sql 2010-01-06 12:00:14 +0000
@@ -14,3 +14,4 @@ INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_
INSTALL PLUGIN innodb_rseg SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_table_stats SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_index_stats SONAME 'ha_innodb.so';
+INSTALL PLUGIN xtradb_admin_command SONAME 'ha_innodb.so';
=== modified file 'storage/xtradb/scripts/install_innodb_plugins_win.sql'
--- a/storage/xtradb/scripts/install_innodb_plugins_win.sql 2008-12-03 05:06:00 +0000
+++ b/storage/xtradb/scripts/install_innodb_plugins_win.sql 2010-01-06 12:00:14 +0000
@@ -7,3 +7,11 @@ INSTALL PLUGIN innodb_cmp SONAME 'ha_inn
INSTALL PLUGIN innodb_cmp_reset SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmpmem SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmpmem_reset SONAME 'ha_innodb.dll';
+INSTALL PLUGIN XTRADB_ENHANCEMENTS SONAME 'ha_innodb.dll';
+INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES SONAME 'ha_innodb.dll';
+INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_BLOB SONAME 'ha_innodb.dll';
+INSTALL PLUGIN INNODB_BUFFER_POOL_PAGES_INDEX SONAME 'ha_innodb.dll';
+INSTALL PLUGIN innodb_rseg SONAME 'ha_innodb.dll';
+INSTALL PLUGIN innodb_table_stats SONAME 'ha_innodb.dll';
+INSTALL PLUGIN innodb_index_stats SONAME 'ha_innodb.dll';
+INSTALL PLUGIN xtradb_admin_command SONAME 'ha_innodb.dll';
=== modified file 'storage/xtradb/srv/srv0srv.c'
--- a/storage/xtradb/srv/srv0srv.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/srv/srv0srv.c 2010-01-15 19:48:33 +0000
@@ -102,6 +102,10 @@ Created 10/8/1995 Heikki Tuuri
#include "row0mysql.h"
#include "ha_prototypes.h"
#include "trx0i_s.h"
+#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
+
+/* prototypes for new functions added to ha_innodb.cc */
+ibool innobase_get_slow_log();
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
affects only FOREIGN KEY definition parsing */
@@ -161,8 +165,9 @@ UNIV_INTERN ulint* srv_data_file_sizes =
UNIV_INTERN ibool srv_extra_undoslots = FALSE;
UNIV_INTERN ibool srv_fast_recovery = FALSE;
+UNIV_INTERN ibool srv_recovery_stats = FALSE;
-UNIV_INTERN ibool srv_use_purge_thread = FALSE;
+UNIV_INTERN ulint srv_use_purge_thread = 0;
/* if TRUE, then we auto-extend the last data file */
UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE;
@@ -302,12 +307,6 @@ UNIV_INTERN ulint srv_buf_pool_flushed =
reading of a disk page */
UNIV_INTERN ulint srv_buf_pool_reads = 0;
-/** Number of sequential read-aheads */
-UNIV_INTERN ulint srv_read_ahead_seq = 0;
-
-/** Number of random read-aheads */
-UNIV_INTERN ulint srv_read_ahead_rnd = 0;
-
/* structure to pass status variables to MySQL */
UNIV_INTERN export_struc export_vars;
@@ -398,6 +397,7 @@ UNIV_INTERN ulong srv_ibuf_active_contra
UNIV_INTERN ulong srv_ibuf_accel_rate = 100;
#define PCT_IBUF_IO(pct) ((ulint) (srv_io_capacity * srv_ibuf_accel_rate * ((double) pct / 10000.0)))
+UNIV_INTERN ulint srv_checkpoint_age_target = 0;
UNIV_INTERN ulong srv_flush_neighbor_pages = 1; /* 0:disable 1:enable */
UNIV_INTERN ulong srv_enable_unsafe_group_commit = 0; /* 0:disable 1:enable */
@@ -405,6 +405,7 @@ UNIV_INTERN ulong srv_read_ahead = 3; /*
UNIV_INTERN ulong srv_adaptive_checkpoint = 0; /* 0: none 1: reflex 2: estimate */
UNIV_INTERN ulong srv_expand_import = 0; /* 0:disable 1:enable */
+UNIV_INTERN ulint srv_relax_table_creation = 0; /* 0:disable 1:enable */
UNIV_INTERN ulong srv_extra_rsegments = 0; /* extra rseg for users */
UNIV_INTERN ulong srv_dict_size_limit = 0;
@@ -493,8 +494,6 @@ static ulint srv_main_background_loops
static ulint srv_main_flush_loops = 0;
/* Log writes involving flush. */
static ulint srv_log_writes_and_flush = 0;
-/* Log writes not including flush. */
-static ulint srv_log_buffer_writes = 0;
/* This is only ever touched by the master thread. It records the
time when the last flush of log file has happened. The master
@@ -643,7 +642,7 @@ future, but at the moment we plan to imp
which could be called a global priority inheritance. If a thread
has to wait for a long time, say 300 milliseconds, for a resource,
we just guess that it may be waiting for a resource owned by a background
-thread, and boost the the priority of all runnable background threads
+thread, and boost the priority of all runnable background threads
to the normal level. The background threads then themselves adjust
their fixed priority back to background after releasing all resources
they had (or, at some fixed points in their program code).
@@ -743,9 +742,8 @@ srv_print_master_thread_info(
srv_main_1_second_loops, srv_main_sleeps,
srv_main_10_second_loops, srv_main_background_loops,
srv_main_flush_loops);
- fprintf(file, "srv_master_thread log flush and writes: %lu "
- " log writes only: %lu\n",
- srv_log_writes_and_flush, srv_log_buffer_writes);
+ fprintf(file, "srv_master_thread log flush and writes: %lu\n",
+ srv_log_writes_and_flush);
}
/*********************************************************************//**
@@ -1043,13 +1041,26 @@ srv_init(void)
}
/*********************************************************************//**
-Frees the OS fast mutex created in srv_init(). */
+Frees the data structures created in srv_init(). */
UNIV_INTERN
void
srv_free(void)
/*==========*/
{
os_fast_mutex_free(&srv_conc_mutex);
+ mem_free(srv_conc_slots);
+ srv_conc_slots = NULL;
+
+ mem_free(srv_sys->threads);
+ mem_free(srv_sys);
+ srv_sys = NULL;
+
+ mem_free(kernel_mutex_temp);
+ kernel_mutex_temp = NULL;
+ mem_free(srv_mysql_table);
+ srv_mysql_table = NULL;
+
+ trx_i_s_cache_free(trx_i_s_cache);
}
/*********************************************************************//**
@@ -1061,6 +1072,8 @@ srv_general_init(void)
/*==================*/
{
ut_mem_init();
+ /* Reset the system variables in the recovery module. */
+ recv_sys_var_init();
os_sync_init();
sync_init();
mem_init(srv_mem_pool_size);
@@ -1076,7 +1089,7 @@ UNIV_INTERN ulong srv_max_purge_lag = 0
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+#ifdef HAVE_ATOMIC_BUILTINS
static void
enter_innodb_with_tickets(trx_t* trx)
{
@@ -1102,12 +1115,12 @@ srv_conc_enter_innodb_timer_based(trx_t*
}
retry:
if (srv_conc_n_threads < (lint) srv_thread_concurrency) {
- conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
+ conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
if (conc_n_threads <= (lint) srv_thread_concurrency) {
enter_innodb_with_tickets(trx);
return;
}
- __sync_add_and_fetch(&srv_conc_n_threads, -1);
+ os_atomic_increment_lint(&srv_conc_n_threads, -1);
}
if (!has_yielded)
{
@@ -1118,7 +1131,7 @@ retry:
if (trx->has_search_latch
|| NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {
- conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
+ conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
enter_innodb_with_tickets(trx);
return;
}
@@ -1129,7 +1142,7 @@ retry:
trx->op_info = "";
has_slept++;
}
- conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
+ conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
enter_innodb_with_tickets(trx);
return;
}
@@ -1137,7 +1150,7 @@ retry:
static void
srv_conc_exit_innodb_timer_based(trx_t* trx)
{
- __sync_add_and_fetch(&srv_conc_n_threads, -1);
+ os_atomic_increment_lint(&srv_conc_n_threads, -1);
trx->declared_to_be_inside_innodb = FALSE;
trx->n_tickets_to_enter_innodb = 0;
return;
@@ -1154,6 +1167,10 @@ srv_conc_enter_innodb(
ibool has_slept = FALSE;
srv_conc_slot_t* slot = NULL;
ulint i;
+ ib_uint64_t start_time = 0L;
+ ib_uint64_t finish_time = 0L;
+ ulint sec;
+ ulint ms;
if (trx->mysql_thd != NULL
&& thd_is_replication_slave_thread(trx->mysql_thd)) {
@@ -1174,7 +1191,7 @@ srv_conc_enter_innodb(
return;
}
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+#ifdef HAVE_ATOMIC_BUILTINS
if (srv_thread_concurrency_timer_based) {
srv_conc_enter_innodb_timer_based(trx);
return;
@@ -1230,6 +1247,7 @@ retry:
switches. */
if (SRV_THREAD_SLEEP_DELAY > 0) {
os_thread_sleep(SRV_THREAD_SLEEP_DELAY);
+ trx->innodb_que_wait_timer += SRV_THREAD_SLEEP_DELAY;
}
trx->op_info = "";
@@ -1285,12 +1303,25 @@ retry:
/* Go to wait for the event; when a thread leaves InnoDB it will
release this thread */
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ start_time = (ib_uint64_t)sec * 1000000 + ms;
+ } else {
+ start_time = 0;
+ }
+
trx->op_info = "waiting in InnoDB queue";
os_event_wait(slot->event);
trx->op_info = "";
+ if (innobase_get_slow_log() && trx->take_stats && start_time) {
+ ut_usectime(&sec, &ms);
+ finish_time = (ib_uint64_t)sec * 1000000 + ms;
+ trx->innodb_que_wait_timer += (ulint)(finish_time - start_time);
+ }
+
os_fast_mutex_lock(&srv_conc_mutex);
srv_conc_n_waiting_threads--;
@@ -1324,9 +1355,9 @@ srv_conc_force_enter_innodb(
}
ut_ad(srv_conc_n_threads >= 0);
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+#ifdef HAVE_ATOMIC_BUILTINS
if (srv_thread_concurrency_timer_based) {
- __sync_add_and_fetch(&srv_conc_n_threads, 1);
+ os_atomic_increment_lint(&srv_conc_n_threads, 1);
trx->declared_to_be_inside_innodb = TRUE;
trx->n_tickets_to_enter_innodb = 1;
return;
@@ -1365,7 +1396,7 @@ srv_conc_force_exit_innodb(
return;
}
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+#ifdef HAVE_ATOMIC_BUILTINS
if (srv_thread_concurrency_timer_based) {
srv_conc_exit_innodb_timer_based(trx);
return;
@@ -2080,14 +2111,16 @@ srv_export_innodb_status(void)
export_vars.innodb_data_writes = os_n_file_writes;
export_vars.innodb_data_written = srv_data_written;
export_vars.innodb_dict_tables= (dict_sys ? UT_LIST_GET_LEN(dict_sys->table_LRU) : 0);
- export_vars.innodb_buffer_pool_read_requests = buf_pool->n_page_gets;
+ export_vars.innodb_buffer_pool_read_requests = buf_pool->stat.n_page_gets;
export_vars.innodb_buffer_pool_write_requests
= srv_buf_pool_write_requests;
export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
- export_vars.innodb_buffer_pool_read_ahead_rnd = srv_read_ahead_rnd;
- export_vars.innodb_buffer_pool_read_ahead_seq = srv_read_ahead_seq;
+ export_vars.innodb_buffer_pool_read_ahead
+ = buf_pool->stat.n_ra_pages_read;
+ export_vars.innodb_buffer_pool_read_ahead_evicted
+ = buf_pool->stat.n_ra_pages_evicted;
export_vars.innodb_buffer_pool_pages_data
= UT_LIST_GET_LEN(buf_pool->LRU);
export_vars.innodb_buffer_pool_pages_dirty
@@ -2118,9 +2151,9 @@ srv_export_innodb_status(void)
export_vars.innodb_log_writes = srv_log_writes;
export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
export_vars.innodb_dblwr_writes = srv_dblwr_writes;
- export_vars.innodb_pages_created = buf_pool->n_pages_created;
- export_vars.innodb_pages_read = buf_pool->n_pages_read;
- export_vars.innodb_pages_written = buf_pool->n_pages_written;
+ export_vars.innodb_pages_created = buf_pool->stat.n_pages_created;
+ export_vars.innodb_pages_read = buf_pool->stat.n_pages_read;
+ export_vars.innodb_pages_written = buf_pool->stat.n_pages_written;
export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
export_vars.innodb_row_lock_current_waits
= srv_n_lock_wait_current_count;
@@ -2487,12 +2520,6 @@ srv_sync_log_buffer_in_background(void)
log_buffer_sync_in_background(TRUE);
srv_last_log_flush_time = current_time;
srv_log_writes_and_flush++;
- } else {
- /* Actually we don't need to write logs here.
- We are just being extra safe here by forcing
- the log buffer to log file. */
- log_buffer_sync_in_background(FALSE);
- srv_log_buffer_writes++;
}
}
@@ -2532,10 +2559,9 @@ srv_master_thread(
srv_main_thread_process_no = os_proc_get_number();
srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
- srv_table_reserve_slot(SRV_MASTER);
-
mutex_enter(&kernel_mutex);
+ srv_table_reserve_slot(SRV_MASTER);
srv_n_threads_active[SRV_MASTER]++;
mutex_exit(&kernel_mutex);
@@ -2550,8 +2576,8 @@ loop:
srv_main_thread_op_info = "reserving kernel mutex";
- n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios_very_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
mutex_enter(&kernel_mutex);
/* Store the user activity counter at the start of this loop */
@@ -2571,8 +2597,8 @@ loop:
skip_sleep = FALSE;
for (i = 0; i < 10; i++) {
- n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
srv_main_thread_op_info = "sleeping";
srv_main_1_second_loops++;
@@ -2624,8 +2650,8 @@ loop:
n_pend_ios = buf_get_n_pending_ios()
+ log_sys->n_pending_writes;
- n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
if (n_pend_ios < SRV_PEND_IO_THRESHOLD
&& (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
srv_main_thread_op_info = "doing insert buffer merge";
@@ -2641,6 +2667,8 @@ loop:
/* Try to keep the number of modified pages in the
buffer pool under the limit wished by the user */
+ srv_main_thread_op_info =
+ "flushing buffer pool pages";
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
PCT_IO(100),
IB_ULONGLONG_MAX);
@@ -2663,6 +2691,8 @@ loop:
ulint n_flush = buf_flush_get_desired_flush_rate();
if (n_flush) {
+ srv_main_thread_op_info =
+ "flushing buffer pool pages";
n_flush = ut_min(PCT_IO(100), n_flush);
n_pages_flushed =
buf_flush_batch(
@@ -2834,8 +2864,8 @@ retry_flush_batch:
are not required, and may be disabled. */
n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
- n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
srv_main_10_second_loops++;
if (n_pend_ios < SRV_PEND_IO_THRESHOLD
@@ -3129,20 +3159,34 @@ srv_purge_thread(
ulint n_pages_purged_sum = 1; /* dummy */
ulint history_len;
ulint sleep_ms= 10000; /* initial: 10 sec. */
+ ibool can_be_last = FALSE;
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Purge thread starts, id %lu\n",
os_thread_pf(os_thread_get_curr_id()));
#endif
- srv_table_reserve_slot(SRV_PURGE);
mutex_enter(&kernel_mutex);
+ srv_table_reserve_slot(SRV_PURGE);
srv_n_threads_active[SRV_PURGE]++;
mutex_exit(&kernel_mutex);
loop:
- if (srv_fast_shutdown && srv_shutdown_state > 0) {
- goto exit_func;
+ if (srv_shutdown_state > 0) {
+ if (srv_fast_shutdown) {
+ /* someone other should wait the end of the workers */
+ goto exit_func;
+ }
+
+ mutex_enter(&kernel_mutex);
+ if (srv_n_threads_active[SRV_PURGE_WORKER]) {
+ can_be_last = FALSE;
+ } else {
+ can_be_last = TRUE;
+ }
+ mutex_exit(&kernel_mutex);
+
+ sleep_ms = 10;
}
os_thread_sleep( sleep_ms * 1000 );
@@ -3163,6 +3207,15 @@ loop:
n_pages_purged_sum += n_pages_purged;
} while (n_pages_purged);
+ if (srv_shutdown_state > 0 && can_be_last) {
+ /* the last trx_purge() is executed without workers */
+ goto exit_func;
+ }
+
+ if (n_pages_purged_sum) {
+ srv_active_wake_master_thread();
+ }
+
if (n_pages_purged_sum == 0)
sleep_ms *= 10;
if (sleep_ms > 10000)
@@ -3171,9 +3224,62 @@ loop:
goto loop;
exit_func:
- /* We count the number of threads in os_thread_exit(). A created
- thread should always use that to exit and not use return() to exit. */
+ trx_purge_worker_wake(); /* It may not make sense. for safety only */
+ /* wake master thread to flush the pages */
+ srv_wake_master_thread();
+
+ mutex_enter(&kernel_mutex);
+ srv_n_threads_active[SRV_PURGE]--;
+ mutex_exit(&kernel_mutex);
+ os_thread_exit(NULL);
+
+ OS_THREAD_DUMMY_RETURN;
+}
+
+/*************************************************************************
+A thread which is devoted to purge, for take over the master thread's
+purging */
+UNIV_INTERN
+os_thread_ret_t
+srv_purge_worker_thread(
+/*====================*/
+ void* arg)
+{
+ ulint worker_id; /* index for array */
+
+ worker_id = *((ulint*)arg);
+
+#ifdef UNIV_DEBUG_THREAD_CREATION
+ fprintf(stderr, "Purge worker thread starts, id %lu\n",
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
+ mutex_enter(&kernel_mutex);
+ srv_table_reserve_slot(SRV_PURGE_WORKER);
+ srv_n_threads_active[SRV_PURGE_WORKER]++;
+ mutex_exit(&kernel_mutex);
+
+loop:
+ /* purge worker threads only works when srv_shutdown_state==0 */
+ /* for safety and exactness. */
+ if (srv_shutdown_state > 0) {
+ goto exit_func;
+ }
+
+ trx_purge_worker_wait();
+
+ if (srv_shutdown_state > 0) {
+ goto exit_func;
+ }
+
+ trx_purge_worker(worker_id);
+
+ goto loop;
+
+exit_func:
+ mutex_enter(&kernel_mutex);
+ srv_n_threads_active[SRV_PURGE_WORKER]--;
+ mutex_exit(&kernel_mutex);
os_thread_exit(NULL);
OS_THREAD_DUMMY_RETURN;
=== modified file 'storage/xtradb/srv/srv0start.c'
--- a/storage/xtradb/srv/srv0start.c 2009-11-13 21:26:08 +0000
+++ b/storage/xtradb/srv/srv0start.c 2010-01-17 08:41:43 +0000
@@ -103,6 +103,8 @@ Created 2/16/1996 Heikki Tuuri
# include "row0row.h"
# include "row0mysql.h"
# include "btr0pcur.h"
+# include "thr0loc.h"
+# include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
/** Log sequence number immediately after startup */
UNIV_INTERN ib_uint64_t srv_start_lsn;
@@ -141,9 +143,9 @@ static mutex_t ios_mutex;
static ulint ios;
/** io_handler_thread parameters for thread identification */
-static ulint n[SRV_MAX_N_IO_THREADS + 5];
+static ulint n[SRV_MAX_N_IO_THREADS + 5 + 64];
/** io_handler_thread identifiers */
-static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5];
+static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5 + 64];
/** We use this mutex to test the return value of pthread_mutex_trylock
on successful locking. HP-UX does NOT return 0, though Linux et al do. */
@@ -494,6 +496,8 @@ io_handler_thread(
mutex_exit(&ios_mutex);
}
+ thr_local_free(os_thread_get_curr_id());
+
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit.
The thread actually never comes here because it is exited in an
@@ -530,32 +534,6 @@ srv_normalize_path_for_win(
#endif
}
-/*********************************************************************//**
-Adds a slash or a backslash to the end of a string if it is missing
-and the string is not empty.
-@return string which has the separator if the string is not empty */
-UNIV_INTERN
-char*
-srv_add_path_separator_if_needed(
-/*=============================*/
- char* str) /*!< in: null-terminated character string */
-{
- char* out_str;
- ulint len = ut_strlen(str);
-
- if (len == 0 || str[len - 1] == SRV_PATH_SEPARATOR) {
-
- return(str);
- }
-
- out_str = ut_malloc(len + 2);
- memcpy(out_str, str, len);
- out_str[len] = SRV_PATH_SEPARATOR;
- out_str[len + 1] = 0;
-
- return(out_str);
-}
-
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Calculates the low 32 bits when a file size which is given as a number
@@ -604,19 +582,24 @@ open_or_create_log_file(
ulint size;
ulint size_high;
char name[10000];
+ ulint dirnamelen;
UT_NOT_USED(create_new_db);
*log_file_created = FALSE;
srv_normalize_path_for_win(srv_log_group_home_dirs[k]);
- srv_log_group_home_dirs[k] = srv_add_path_separator_if_needed(
- srv_log_group_home_dirs[k]);
- ut_a(strlen(srv_log_group_home_dirs[k])
- < (sizeof name) - 10 - sizeof "ib_logfile");
- sprintf(name, "%s%s%lu", srv_log_group_home_dirs[k],
- "ib_logfile", (ulong) i);
+ dirnamelen = strlen(srv_log_group_home_dirs[k]);
+ ut_a(dirnamelen < (sizeof name) - 10 - sizeof "ib_logfile");
+ memcpy(name, srv_log_group_home_dirs[k], dirnamelen);
+
+ /* Add a path separator if needed. */
+ if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
+ name[dirnamelen++] = SRV_PATH_SEPARATOR;
+ }
+
+ sprintf(name + dirnamelen, "%s%lu", "ib_logfile", (ulong) i);
files[i] = os_file_create(name, OS_FILE_CREATE, OS_FILE_NORMAL,
OS_LOG_FILE, &ret);
@@ -779,14 +762,22 @@ open_or_create_data_files(
*create_new_db = FALSE;
srv_normalize_path_for_win(srv_data_home);
- srv_data_home = srv_add_path_separator_if_needed(srv_data_home);
for (i = 0; i < srv_n_data_files; i++) {
+ ulint dirnamelen;
+
srv_normalize_path_for_win(srv_data_file_names[i]);
+ dirnamelen = strlen(srv_data_home);
- ut_a(strlen(srv_data_home) + strlen(srv_data_file_names[i])
+ ut_a(dirnamelen + strlen(srv_data_file_names[i])
< (sizeof name) - 1);
- sprintf(name, "%s%s", srv_data_home, srv_data_file_names[i]);
+ memcpy(name, srv_data_home, dirnamelen);
+ /* Add a path separator if needed. */
+ if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
+ name[dirnamelen++] = SRV_PATH_SEPARATOR;
+ }
+
+ strcpy(name + dirnamelen, srv_data_file_names[i]);
if (srv_data_file_is_raw_partition[i] == 0) {
@@ -1008,7 +999,7 @@ skip_size_check:
return(DB_SUCCESS);
}
-/****************************************************************//**
+/********************************************************************
Starts InnoDB and creates a new database if database files
are not found and the user wants.
@return DB_SUCCESS or error code */
@@ -1096,6 +1087,10 @@ innobase_start_or_create_for_mysql(void)
"InnoDB: !!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!\n");
#endif
+#ifdef UNIV_LOG_LSN_DEBUG
+ fprintf(stderr,
+ "InnoDB: !!!!!!!! UNIV_LOG_LSN_DEBUG switched on !!!!!!!!!\n");
+#endif /* UNIV_LOG_LSN_DEBUG */
#ifdef UNIV_MEM_DEBUG
fprintf(stderr,
"InnoDB: !!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!\n");
@@ -1106,34 +1101,7 @@ innobase_start_or_create_for_mysql(void)
"InnoDB: The InnoDB memory heap is disabled\n");
}
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
- fprintf(stderr,
- "InnoDB: Mutexes and rw_locks use GCC atomic builtins.\n");
-# else /* INNODB_RW_LOCKS_USE_ATOMICS */
- fprintf(stderr,
- "InnoDB: Mutexes use GCC atomic builtins, rw_locks do not.\n");
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#elif defined(HAVE_SOLARIS_ATOMICS)
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
- fprintf(stderr,
- "InnoDB: Mutexes and rw_locks use Solaris atomic functions.\n");
-# else
- fprintf(stderr,
- "InnoDB: Mutexes use Solaris atomic functions.\n");
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#elif HAVE_WINDOWS_ATOMICS
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
- fprintf(stderr,
- "InnoDB: Mutexes and rw_locks use Windows interlocked functions.\n");
-# else
- fprintf(stderr,
- "InnoDB: Mutexes use Windows interlocked functions.\n");
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#else /* HAVE_GCC_ATOMIC_BUILTINS */
- fprintf(stderr,
- "InnoDB: Neither mutexes nor rw_locks use GCC atomic builtins.\n");
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
+ fprintf(stderr, "InnoDB: %s\n", IB_ATOMICS_STARTUP_MSG);
/* Since InnoDB does not currently clean up all its internal data
structures in MySQL Embedded Server Library server_end(), we
@@ -1142,7 +1110,7 @@ innobase_start_or_create_for_mysql(void)
if (srv_start_has_been_called) {
fprintf(stderr,
- "InnoDB: Error:startup called second time"
+ "InnoDB: Error: startup called second time"
" during the process lifetime.\n"
"InnoDB: In the MySQL Embedded Server Library"
" you cannot call server_init()\n"
@@ -1409,7 +1377,7 @@ innobase_start_or_create_for_mysql(void)
sum_of_new_sizes += srv_data_file_sizes[i];
}
- if (sum_of_new_sizes < 640) {
+ if (sum_of_new_sizes < 10485760 / UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Error: tablespace size must be"
" at least 10 MB\n");
@@ -1739,8 +1707,17 @@ innobase_start_or_create_for_mysql(void)
+ (1 + SRV_MAX_N_IO_THREADS));
if (srv_use_purge_thread) {
+ ulint i;
+
os_thread_create(&srv_purge_thread, NULL, thread_ids
+ (4 + SRV_MAX_N_IO_THREADS));
+
+ for (i = 0; i < srv_use_purge_thread - 1; i++) {
+ n[5 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */
+ os_thread_create(&srv_purge_worker_thread,
+ n + (5 + i + SRV_MAX_N_IO_THREADS),
+ thread_ids + (5 + i + SRV_MAX_N_IO_THREADS));
+ }
}
#ifdef UNIV_DEBUG
/* buf_debug_prints = TRUE; */
@@ -1853,7 +1830,7 @@ innobase_start_or_create_for_mysql(void)
/* Actually, we did not change the undo log format between
4.0 and 4.1.1, and we would not need to run purge to
completion. Note also that the purge algorithm in 4.1.1
- can process the the history list again even after a full
+ can process the history list again even after a full
purge, because our algorithm does not cut the end of the
history list in all cases so that it would become empty
after a full purge. That mean that we may purge 4.0 type
@@ -2005,8 +1982,10 @@ innobase_shutdown_for_mysql(void)
/* All the threads have exited or are just exiting;
NOTE that the threads may not have completed their
exit yet. Should we use pthread_join() to make sure
- they have exited? Now we just sleep 0.1 seconds and
- hope that is enough! */
+ they have exited? If we did, we would have to
+ remove the pthread_detach() from
+ os_thread_exit(). Now we just sleep 0.1
+ seconds and hope that is enough! */
os_mutex_exit(os_sync_mutex);
@@ -2045,36 +2024,40 @@ innobase_shutdown_for_mysql(void)
srv_misc_tmpfile = 0;
}
+ /* This must be disabled before closing the buffer pool
+ and closing the data dictionary. */
+ btr_search_disable();
+
+ ibuf_close();
+ log_shutdown();
+ lock_sys_close();
+ thr_local_close();
trx_sys_file_format_close();
+ trx_sys_close();
mutex_free(&srv_monitor_file_mutex);
mutex_free(&srv_dict_tmpfile_mutex);
mutex_free(&srv_misc_tmpfile_mutex);
+ dict_close();
+ btr_search_sys_free();
/* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
them */
+ os_aio_free();
sync_close();
+ srv_free();
+ fil_close();
/* 4. Free the os_conc_mutex and all os_events and os_mutexes */
- srv_free();
os_sync_free();
- /* Check that all read views are closed except read view owned
- by a purge. */
-
- if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
- fprintf(stderr,
- "InnoDB: Error: all read views were not closed"
- " before shutdown:\n"
- "InnoDB: %lu read views open \n",
- UT_LIST_GET_LEN(trx_sys->view_list) - 1);
- }
-
- /* 5. Free all allocated memory and the os_fast_mutex created in
- ut0mem.c */
+ /* 5. Free all allocated memory */
+ pars_lexer_close();
+ log_mem_free();
buf_pool_free();
+ mem_close();
ut_free_all_mem();
if (os_thread_count != 0
@@ -2106,6 +2089,7 @@ innobase_shutdown_for_mysql(void)
}
srv_was_started = FALSE;
+ srv_start_has_been_called = FALSE;
return((int) DB_SUCCESS);
}
=== modified file 'storage/xtradb/sync/sync0arr.c'
--- a/storage/xtradb/sync/sync0arr.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/sync/sync0arr.c 2010-01-06 12:00:14 +0000
@@ -227,24 +227,21 @@ sync_array_create(
SYNC_ARRAY_MUTEX: determines the type
of mutex protecting the data structure */
{
+ ulint sz;
sync_array_t* arr;
- sync_cell_t* cell_array;
- sync_cell_t* cell;
- ulint i;
ut_a(n_cells > 0);
/* Allocate memory for the data structures */
arr = ut_malloc(sizeof(sync_array_t));
+ memset(arr, 0x0, sizeof(*arr));
- cell_array = ut_malloc(sizeof(sync_cell_t) * n_cells);
+ sz = sizeof(sync_cell_t) * n_cells;
+ arr->array = ut_malloc(sz);
+ memset(arr->array, 0x0, sz);
arr->n_cells = n_cells;
- arr->n_reserved = 0;
- arr->array = cell_array;
arr->protection = protection;
- arr->sg_count = 0;
- arr->res_count = 0;
/* Then create the mutex to protect the wait array complex */
if (protection == SYNC_ARRAY_OS_MUTEX) {
@@ -255,13 +252,6 @@ sync_array_create(
ut_error;
}
- for (i = 0; i < n_cells; i++) {
- cell = sync_array_get_nth_cell(arr, i);
- cell->wait_object = NULL;
- cell->waiting = FALSE;
- cell->signal_count = 0;
- }
-
return(arr);
}
@@ -492,12 +482,12 @@ sync_array_cell_print(
mutex = cell->old_wait_mutex;
fprintf(file,
- "Mutex at %p created file %s line %lu, lock var %lu\n"
+ "Mutex at %p '%s', lock var %lu\n"
#ifdef UNIV_SYNC_DEBUG
"Last time reserved in file %s line %lu, "
#endif /* UNIV_SYNC_DEBUG */
"waiters flag %lu\n",
- (void*) mutex, mutex->cfile_name, (ulong) mutex->cline,
+ (void*) mutex, mutex->cmutex_name,
(ulong) mutex->lock_word,
#ifdef UNIV_SYNC_DEBUG
mutex->file_name, (ulong) mutex->line,
@@ -513,9 +503,8 @@ sync_array_cell_print(
rwlock = cell->old_wait_rw_lock;
fprintf(file,
- " RW-latch at %p created in file %s line %lu\n",
- (void*) rwlock, rwlock->cfile_name,
- (ulong) rwlock->cline);
+ " RW-latch at %p '%s'\n",
+ (void*) rwlock, rwlock->lock_name);
writer = rw_lock_get_writer(rwlock);
if (writer != RW_LOCK_NOT_LOCKED) {
fprintf(file,
=== modified file 'storage/xtradb/sync/sync0rw.c'
--- a/storage/xtradb/sync/sync0rw.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/sync/sync0rw.c 2010-01-06 12:00:14 +0000
@@ -38,6 +38,7 @@ Created 9/11/1995 Heikki Tuuri
#include "os0thread.h"
#include "mem0mem.h"
#include "srv0srv.h"
+#include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
/*
IMPLEMENTATION OF THE RW_LOCK
@@ -230,8 +231,8 @@ rw_lock_create_func(
# ifdef UNIV_SYNC_DEBUG
ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
- const char* cmutex_name, /*!< in: mutex name */
#endif /* UNIV_DEBUG */
+ const char* cmutex_name, /*!< in: mutex name */
const char* cfile_name, /*!< in: file name where created */
ulint cline) /*!< in: file line where created */
{
@@ -241,14 +242,15 @@ rw_lock_create_func(
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
- lock->mutex.cfile_name = cfile_name;
- lock->mutex.cline = cline;
+ ut_d(lock->mutex.cfile_name = cfile_name);
+ ut_d(lock->mutex.cline = cline);
- ut_d(lock->mutex.cmutex_name = cmutex_name);
+ lock->mutex.cmutex_name = cmutex_name;
ut_d(lock->mutex.mutex_type = 1);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
# ifdef UNIV_DEBUG
- UT_NOT_USED(cmutex_name);
+ UT_NOT_USED(cfile_name);
+ UT_NOT_USED(cline);
# endif
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
@@ -268,8 +270,7 @@ rw_lock_create_func(
lock->magic_n = RW_LOCK_MAGIC_N;
- lock->cfile_name = cfile_name;
- lock->cline = (unsigned int) cline;
+ lock->lock_name = cmutex_name;
lock->count_os_wait = 0;
lock->last_s_file_name = "not yet reserved";
@@ -304,8 +305,6 @@ rw_lock_free(
ut_ad(rw_lock_validate(lock));
ut_a(lock->lock_word == X_LOCK_DECR);
- lock->magic_n = 0;
-
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
mutex_free(rw_lock_get_mutex(lock));
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
@@ -325,6 +324,8 @@ rw_lock_free(
UT_LIST_REMOVE(list, rw_lock_list, lock);
mutex_exit(&rw_lock_list_mutex);
+
+ lock->magic_n = 0;
}
#ifdef UNIV_DEBUG
@@ -390,10 +391,10 @@ lock_loop:
if (srv_print_latch_waits) {
fprintf(stderr,
"Thread %lu spin wait rw-s-lock at %p"
- " cfile %s cline %lu rnds %lu\n",
+ " '%s' rnds %lu\n",
(ulong) os_thread_pf(os_thread_get_curr_id()),
(void*) lock,
- lock->cfile_name, (ulong) lock->cline, (ulong) i);
+ lock->lock_name, (ulong) i);
}
/* We try once again to obtain the lock */
@@ -426,10 +427,9 @@ lock_loop:
if (srv_print_latch_waits) {
fprintf(stderr,
"Thread %lu OS wait rw-s-lock at %p"
- " cfile %s cline %lu\n",
+ " '%s'\n",
os_thread_pf(os_thread_get_curr_id()),
- (void*) lock, lock->cfile_name,
- (ulong) lock->cline);
+ (void*) lock, lock->lock_name);
}
/* these stats may not be accurate */
@@ -648,9 +648,9 @@ lock_loop:
if (srv_print_latch_waits) {
fprintf(stderr,
"Thread %lu spin wait rw-x-lock at %p"
- " cfile %s cline %lu rnds %lu\n",
+ " '%s' rnds %lu\n",
os_thread_pf(os_thread_get_curr_id()), (void*) lock,
- lock->cfile_name, (ulong) lock->cline, (ulong) i);
+ lock->lock_name, (ulong) i);
}
sync_array_reserve_cell(sync_primary_wait_array,
@@ -671,9 +671,9 @@ lock_loop:
if (srv_print_latch_waits) {
fprintf(stderr,
"Thread %lu OS wait for rw-x-lock at %p"
- " cfile %s cline %lu\n",
+ " '%s'\n",
os_thread_pf(os_thread_get_curr_id()), (void*) lock,
- lock->cfile_name, (ulong) lock->cline);
+ lock->lock_name);
}
/* these stats may not be accurate */
=== modified file 'storage/xtradb/sync/sync0sync.c'
--- a/storage/xtradb/sync/sync0sync.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/sync/sync0sync.c 2010-01-06 12:00:14 +0000
@@ -39,6 +39,7 @@ Created 9/5/1995 Heikki Tuuri
#include "buf0buf.h"
#include "srv0srv.h"
#include "buf0types.h"
+#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
/*
REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
@@ -237,8 +238,8 @@ void
mutex_create_func(
/*==============*/
mutex_t* mutex, /*!< in: pointer to memory */
-#ifdef UNIV_DEBUG
const char* cmutex_name, /*!< in: mutex name */
+#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
@@ -253,7 +254,7 @@ mutex_create_func(
mutex->lock_word = 0;
#endif
mutex->event = os_event_create(NULL);
- mutex_set_waiters(mutex, 0);
+ mutex->waiters = 0;
#ifdef UNIV_DEBUG
mutex->magic_n = MUTEX_MAGIC_N;
#endif /* UNIV_DEBUG */
@@ -262,11 +263,13 @@ mutex_create_func(
mutex->file_name = "not yet reserved";
mutex->level = level;
#endif /* UNIV_SYNC_DEBUG */
+#ifdef UNIV_DEBUG
mutex->cfile_name = cfile_name;
mutex->cline = cline;
+#endif /* UNIV_DEBUG */
mutex->count_os_wait = 0;
-#ifdef UNIV_DEBUG
mutex->cmutex_name= cmutex_name;
+#ifdef UNIV_DEBUG
mutex->count_using= 0;
mutex->mutex_type= 0;
mutex->lspent_time= 0;
@@ -424,10 +427,18 @@ mutex_set_waiters(
the value is stored to memory */
ut_ad(mutex);
+#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+ if (n) {
+ os_compare_and_swap_ulint(&mutex->waiters, 0, 1);
+ } else {
+ os_compare_and_swap_ulint(&mutex->waiters, 1, 0);
+ }
+#else
ptr = &(mutex->waiters);
*ptr = n; /* Here we assume that the write of a single
word in memory is atomic */
+#endif
}
/******************************************************************//**
@@ -498,9 +509,9 @@ spin_loop:
#ifdef UNIV_SRV_PRINT_LATCH_WAITS
fprintf(stderr,
"Thread %lu spin wait mutex at %p"
- " cfile %s cline %lu rnds %lu\n",
+ " '%s' rnds %lu\n",
(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
- mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
+ mutex->cmutex_name, (ulong) i);
#endif
mutex_spin_round_count += i;
@@ -575,9 +586,9 @@ spin_loop:
#ifdef UNIV_SRV_PRINT_LATCH_WAITS
fprintf(stderr,
- "Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n",
+ "Thread %lu OS wait mutex at %p '%s' rnds %lu\n",
(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
- mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
+ mutex->cmutex_name, (ulong) i);
#endif
mutex_os_wait_count++;
@@ -849,7 +860,8 @@ sync_thread_levels_g(
/*=================*/
sync_level_t* arr, /*!< in: pointer to level array for an OS
thread */
- ulint limit) /*!< in: level limit */
+ ulint limit, /*!< in: level limit */
+ ulint warn) /*!< in: TRUE=display a diagnostic message */
{
sync_level_t* slot;
rw_lock_t* lock;
@@ -863,6 +875,11 @@ sync_thread_levels_g(
if (slot->latch != NULL) {
if (slot->level <= limit) {
+ if (!warn) {
+
+ return(FALSE);
+ }
+
lock = slot->latch;
mutex = slot->latch;
@@ -873,9 +890,8 @@ sync_thread_levels_g(
if (mutex->magic_n == MUTEX_MAGIC_N) {
fprintf(stderr,
- "Mutex created at %s %lu\n",
- mutex->cfile_name,
- (ulong) mutex->cline);
+ "Mutex '%s'\n",
+ mutex->cmutex_name);
if (mutex_get_lock_word(mutex) != 0) {
const char* file_name;
@@ -1106,7 +1122,7 @@ sync_thread_add_level(
case SYNC_DICT_HEADER:
case SYNC_TRX_I_S_RWLOCK:
case SYNC_TRX_I_S_LAST_READ:
- if (!sync_thread_levels_g(array, level)) {
+ if (!sync_thread_levels_g(array, level, TRUE)) {
fprintf(stderr,
"InnoDB: sync_thread_levels_g(array, %lu)"
" does not hold!\n", level);
@@ -1117,36 +1133,44 @@ sync_thread_add_level(
/* Either the thread must own the buffer pool mutex
(buf_pool_mutex), or it is allowed to latch only ONE
buffer block (block->mutex or buf_pool_zip_mutex). */
- if (!sync_thread_levels_g(array, level)) {
- ut_a(sync_thread_levels_g(array, level - 1));
+ if (!sync_thread_levels_g(array, level, FALSE)) {
+ ut_a(sync_thread_levels_g(array, level - 1, TRUE));
ut_a(sync_thread_levels_contain(array, SYNC_BUF_LRU_LIST));
}
break;
case SYNC_REC_LOCK:
- ut_a((sync_thread_levels_contain(array, SYNC_KERNEL)
- && sync_thread_levels_g(array, SYNC_REC_LOCK - 1))
- || sync_thread_levels_g(array, SYNC_REC_LOCK));
+ if (sync_thread_levels_contain(array, SYNC_KERNEL)) {
+ ut_a(sync_thread_levels_g(array, SYNC_REC_LOCK - 1,
+ TRUE));
+ } else {
+ ut_a(sync_thread_levels_g(array, SYNC_REC_LOCK, TRUE));
+ }
break;
case SYNC_IBUF_BITMAP:
/* Either the thread must own the master mutex to all
the bitmap pages, or it is allowed to latch only ONE
bitmap page. */
- ut_a((sync_thread_levels_contain(array, SYNC_IBUF_BITMAP_MUTEX)
- && sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1))
- || sync_thread_levels_g(array, SYNC_IBUF_BITMAP));
+ if (sync_thread_levels_contain(array,
+ SYNC_IBUF_BITMAP_MUTEX)) {
+ ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1,
+ TRUE));
+ } else {
+ ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP,
+ TRUE));
+ }
break;
case SYNC_FSP_PAGE:
ut_a(sync_thread_levels_contain(array, SYNC_FSP));
break;
case SYNC_FSP:
ut_a(sync_thread_levels_contain(array, SYNC_FSP)
- || sync_thread_levels_g(array, SYNC_FSP));
+ || sync_thread_levels_g(array, SYNC_FSP, TRUE));
break;
case SYNC_TRX_UNDO_PAGE:
ut_a(sync_thread_levels_contain(array, SYNC_TRX_UNDO)
|| sync_thread_levels_contain(array, SYNC_RSEG)
|| sync_thread_levels_contain(array, SYNC_PURGE_SYS)
- || sync_thread_levels_g(array, SYNC_TRX_UNDO_PAGE));
+ || sync_thread_levels_g(array, SYNC_TRX_UNDO_PAGE, TRUE));
break;
case SYNC_RSEG_HEADER:
ut_a(sync_thread_levels_contain(array, SYNC_RSEG));
@@ -1158,37 +1182,41 @@ sync_thread_add_level(
case SYNC_TREE_NODE:
ut_a(sync_thread_levels_contain(array, SYNC_INDEX_TREE)
|| sync_thread_levels_contain(array, SYNC_DICT_OPERATION)
- || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
+ || sync_thread_levels_g(array, SYNC_TREE_NODE - 1, TRUE));
break;
case SYNC_TREE_NODE_NEW:
ut_a(sync_thread_levels_contain(array, SYNC_FSP_PAGE)
|| sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
break;
case SYNC_INDEX_TREE:
- ut_a((sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
- && sync_thread_levels_contain(array, SYNC_FSP)
- && sync_thread_levels_g(array, SYNC_FSP_PAGE - 1))
- || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
+ if (sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
+ && sync_thread_levels_contain(array, SYNC_FSP)) {
+ ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1,
+ TRUE));
+ } else {
+ ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1,
+ TRUE));
+ }
break;
case SYNC_IBUF_MUTEX:
- ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1));
+ ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1, TRUE));
break;
case SYNC_IBUF_PESS_INSERT_MUTEX:
- ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
- && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+ ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
+ ut_a(!sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
break;
case SYNC_IBUF_HEADER:
- ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
- && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
- && !sync_thread_levels_contain(
- array, SYNC_IBUF_PESS_INSERT_MUTEX));
+ ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
+ ut_a(!sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+ ut_a(!sync_thread_levels_contain(array,
+ SYNC_IBUF_PESS_INSERT_MUTEX));
break;
case SYNC_DICT:
#ifdef UNIV_DEBUG
ut_a(buf_debug_prints
- || sync_thread_levels_g(array, SYNC_DICT));
+ || sync_thread_levels_g(array, SYNC_DICT, TRUE));
#else /* UNIV_DEBUG */
- ut_a(sync_thread_levels_g(array, SYNC_DICT));
+ ut_a(sync_thread_levels_g(array, SYNC_DICT, TRUE));
#endif /* UNIV_DEBUG */
break;
default:
@@ -1364,7 +1392,12 @@ sync_close(void)
mutex_free(&mutex_list_mutex);
#ifdef UNIV_SYNC_DEBUG
mutex_free(&sync_thread_mutex);
+
+ /* Switch latching order checks on in sync0sync.c */
+ sync_order_checks_on = FALSE;
#endif /* UNIV_SYNC_DEBUG */
+
+ sync_initialized = FALSE;
}
/*******************************************************************//**
=== modified file 'storage/xtradb/thr/thr0loc.c'
--- a/storage/xtradb/thr/thr0loc.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/thr/thr0loc.c 2010-01-06 12:00:14 +0000
@@ -63,7 +63,7 @@ struct thr_local_struct{
os_thread_t handle; /*!< operating system handle to the thread */
ulint slot_no;/*!< the index of the slot in the thread table
for this thread */
- ibool in_ibuf;/*!< TRUE if the the thread is doing an ibuf
+ ibool in_ibuf;/*!< TRUE if the thread is doing an ibuf
operation */
hash_node_t hash; /*!< hash chain node */
ulint magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */
@@ -250,6 +250,37 @@ thr_local_init(void)
mutex_create(&thr_local_mutex, SYNC_THR_LOCAL);
}
+/********************************************************************
+Close the thread local storage module. */
+UNIV_INTERN
+void
+thr_local_close(void)
+/*=================*/
+{
+ ulint i;
+
+ ut_a(thr_local_hash != NULL);
+
+ /* Free the hash elements. We don't remove them from the table
+ because we are going to destroy the table anyway. */
+ for (i = 0; i < hash_get_n_cells(thr_local_hash); i++) {
+ thr_local_t* local;
+
+ local = HASH_GET_FIRST(thr_local_hash, i);
+
+ while (local) {
+ thr_local_t* prev_local = local;
+
+ local = HASH_GET_NEXT(hash, prev_local);
+ ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N);
+ mem_free(prev_local);
+ }
+ }
+
+ hash_table_free(thr_local_hash);
+ thr_local_hash = NULL;
+}
+
/*************************************************************************
Return local hash table informations. */
=== modified file 'storage/xtradb/trx/trx0i_s.c'
--- a/storage/xtradb/trx/trx0i_s.c 2009-11-29 23:08:56 +0000
+++ b/storage/xtradb/trx/trx0i_s.c 2010-01-15 15:58:25 +0000
@@ -60,7 +60,7 @@ Created July 17, 2007 Vasil Dimov
/** @brief The maximum number of chunks to allocate for a table cache.
The rows of a table cache are stored in a set of chunks. When a new
-row is added a new chunk is allocated if necessary. Assuming that the
+row is added a new chunk is allocated if necessary. Assuming that the
first one is 1024 rows (TABLE_CACHE_INITIAL_ROWSNUM) and each
subsequent is N/2 where N is the number of rows we have allocated till
now, then 39th chunk would accommodate 1677416425 rows and all chunks
@@ -238,6 +238,27 @@ table_cache_init(
}
/*******************************************************************//**
+Frees a table cache. */
+static
+void
+table_cache_free(
+/*=============*/
+ i_s_table_cache_t* table_cache) /*!< in/out: table cache */
+{
+ ulint i;
+
+ for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) {
+
+ /* the memory is actually allocated in
+ table_cache_create_empty_row() */
+ if (table_cache->chunks[i].base) {
+ mem_free(table_cache->chunks[i].base);
+ table_cache->chunks[i].base = NULL;
+ }
+ }
+}
+
+/*******************************************************************//**
Returns an empty row from a table cache. The row is allocated if no more
empty rows are available. The number of used rows is incremented.
If the memory limit is hit then NULL is returned and nothing is
@@ -1252,6 +1273,22 @@ trx_i_s_cache_init(
}
/*******************************************************************//**
+Free the INFORMATION SCHEMA trx related cache. */
+UNIV_INTERN
+void
+trx_i_s_cache_free(
+/*===============*/
+ trx_i_s_cache_t* cache) /*!< in, own: cache to free */
+{
+ hash_table_free(cache->locks_hash);
+ ha_storage_free(cache->storage);
+ table_cache_free(&cache->innodb_trx);
+ table_cache_free(&cache->innodb_locks);
+ table_cache_free(&cache->innodb_lock_waits);
+ memset(cache, 0, sizeof *cache);
+}
+
+/*******************************************************************//**
Issue a shared/read lock on the tables cache. */
UNIV_INTERN
void
=== modified file 'storage/xtradb/trx/trx0purge.c'
--- a/storage/xtradb/trx/trx0purge.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/trx/trx0purge.c 2010-01-06 12:00:14 +0000
@@ -184,8 +184,9 @@ this query graph.
@return own: the query graph */
static
que_t*
-trx_purge_graph_build(void)
+trx_purge_graph_build(
/*=======================*/
+ trx_t* trx)
{
mem_heap_t* heap;
que_fork_t* fork;
@@ -194,7 +195,7 @@ trx_purge_graph_build(void)
heap = mem_heap_create(512);
fork = que_fork_create(NULL, NULL, QUE_FORK_PURGE, heap);
- fork->trx = purge_sys->trx;
+ fork->trx = trx;
thr = que_thr_create(fork, heap);
@@ -243,10 +244,73 @@ trx_purge_sys_create(void)
ut_a(trx_start_low(purge_sys->trx, ULINT_UNDEFINED));
- purge_sys->query = trx_purge_graph_build();
+ purge_sys->query = trx_purge_graph_build(purge_sys->trx);
purge_sys->view = read_view_oldest_copy_or_open_new(ut_dulint_zero,
purge_sys->heap);
+
+ purge_sys->n_worker = 0;
+ if (srv_use_purge_thread > 1) {
+ /* Use worker threads */
+ ulint i;
+
+ purge_sys->n_worker = srv_use_purge_thread - 1;
+
+ purge_sys->sess_arr = mem_alloc(sizeof(sess_t*) * purge_sys->n_worker);
+ purge_sys->trx_arr = mem_alloc(sizeof(trx_t*) * purge_sys->n_worker);
+ purge_sys->query_arr = mem_alloc(sizeof(que_t*) * purge_sys->n_worker);
+
+ purge_sys->worker_event = os_event_create(NULL);
+ os_event_reset(purge_sys->worker_event);
+
+ for (i = 0; i < purge_sys->n_worker; i++) {
+ purge_sys->sess_arr[i] = sess_open();
+
+ purge_sys->trx_arr[i] = purge_sys->sess_arr[i]->trx;
+ purge_sys->trx_arr[i]->is_purge = 1;
+ ut_a(trx_start_low(purge_sys->trx_arr[i], ULINT_UNDEFINED));
+
+ purge_sys->query_arr[i] = trx_purge_graph_build(purge_sys->trx_arr[i]);
+ }
+ }
+}
+
+/************************************************************************
+Frees the global purge system control structure. */
+UNIV_INTERN
+void
+trx_purge_sys_close(void)
+/*======================*/
+{
+ ut_ad(!mutex_own(&kernel_mutex));
+
+ que_graph_free(purge_sys->query);
+
+ ut_a(purge_sys->sess->trx->is_purge);
+ purge_sys->sess->trx->conc_state = TRX_NOT_STARTED;
+ sess_close(purge_sys->sess);
+ purge_sys->sess = NULL;
+
+ if (purge_sys->view != NULL) {
+ /* Because acquiring the kernel mutex is a pre-condition
+ of read_view_close(). We don't really need it here. */
+ mutex_enter(&kernel_mutex);
+
+ read_view_close(purge_sys->view);
+ purge_sys->view = NULL;
+
+ mutex_exit(&kernel_mutex);
+ }
+
+ trx_undo_arr_free(purge_sys->arr);
+
+ rw_lock_free(&purge_sys->latch);
+ mutex_free(&purge_sys->mutex);
+
+ mem_heap_free(purge_sys->heap);
+ mem_free(purge_sys);
+
+ purge_sys = NULL;
}
/*================ UNDO LOG HISTORY LIST =============================*/
@@ -1110,7 +1174,7 @@ trx_purge(void)
/* Handle at most 20 undo log pages in one purge batch */
- purge_sys->handle_limit = purge_sys->n_pages_handled + 20;
+ purge_sys->handle_limit = purge_sys->n_pages_handled + 20 * (srv_use_purge_thread + 1);
old_pages_handled = purge_sys->n_pages_handled;
@@ -1129,6 +1193,9 @@ trx_purge(void)
mutex_exit(&kernel_mutex);
+ if (purge_sys->n_worker)
+ os_event_set(purge_sys->worker_event);
+
/* srv_que_task_enqueue(thr2); */
if (srv_print_thread_releases) {
@@ -1138,6 +1205,9 @@ trx_purge(void)
que_run_threads(thr);
+ if (purge_sys->n_worker)
+ os_event_reset(purge_sys->worker_event);
+
if (srv_print_thread_releases) {
fprintf(stderr,
@@ -1148,6 +1218,52 @@ trx_purge(void)
return(purge_sys->n_pages_handled - old_pages_handled);
}
+/**********************************************************************
+This function runs a purge worker batch */
+UNIV_INTERN
+void
+trx_purge_worker(
+/*=============*/
+ ulint worker_id)
+{
+ que_thr_t* thr;
+
+ mutex_enter(&kernel_mutex);
+
+ thr = que_fork_start_command(purge_sys->query_arr[worker_id]);
+
+ ut_ad(thr);
+
+ mutex_exit(&kernel_mutex);
+
+ que_run_threads(thr);
+
+ if (purge_sys->state == TRX_STOP_PURGE) { /* optimistic */
+ os_event_reset(purge_sys->worker_event);
+ }
+}
+
+/**********************************************************************
+This function waits the event for worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wait(void)
+/*=======================*/
+{
+ os_event_wait(purge_sys->worker_event);
+}
+
+/**********************************************************************
+This function wakes the waiting worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wake(void)
+/*=======================*/
+{
+ if (purge_sys->n_worker)
+ os_event_set(purge_sys->worker_event);
+}
+
/******************************************************************//**
Prints information of the purge system to stderr. */
UNIV_INTERN
=== modified file 'storage/xtradb/trx/trx0rec.c'
--- a/storage/xtradb/trx/trx0rec.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/trx/trx0rec.c 2010-01-06 12:00:14 +0000
@@ -1333,7 +1333,7 @@ trx_undo_get_undo_rec_low(
ulint rseg_id;
ulint page_no;
ulint offset;
- page_t* undo_page;
+ const page_t* undo_page;
trx_rseg_t* rseg;
ibool is_insert;
mtr_t mtr;
@@ -1572,7 +1572,7 @@ trx_undo_prev_version_build(
/* We have to set the appropriate extern storage bits in the
old version of the record: the extern bits in rec for those
- fields that update does NOT update, as well as the the bits for
+ fields that update does NOT update, as well as the bits for
those fields that update updates to become externally stored
fields. Store the info: */
=== modified file 'storage/xtradb/trx/trx0roll.c'
--- a/storage/xtradb/trx/trx0roll.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/trx/trx0roll.c 2010-01-06 12:00:14 +0000
@@ -66,9 +66,9 @@ int
trx_general_rollback_for_mysql(
/*===========================*/
trx_t* trx, /*!< in: transaction handle */
- ibool partial,/*!< in: TRUE if partial rollback requested */
trx_savept_t* savept) /*!< in: pointer to savepoint undo number, if
- partial rollback requested */
+ partial rollback requested, or NULL for
+ complete rollback */
{
mem_heap_t* heap;
que_thr_t* thr;
@@ -85,9 +85,8 @@ trx_general_rollback_for_mysql(
roll_node = roll_node_create(heap);
- roll_node->partial = partial;
-
- if (partial) {
+ if (savept) {
+ roll_node->partial = TRUE;
roll_node->savept = *savept;
}
@@ -145,7 +144,7 @@ trx_rollback_for_mysql(
the transaction object does not have an InnoDB session object, and we
set a dummy session that we use for all MySQL transactions. */
- err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ err = trx_general_rollback_for_mysql(trx, NULL);
trx->op_info = "";
@@ -170,8 +169,7 @@ trx_rollback_last_sql_stat_for_mysql(
trx->op_info = "rollback of SQL statement";
- err = trx_general_rollback_for_mysql(trx, TRUE,
- &(trx->last_sql_stat_start));
+ err = trx_general_rollback_for_mysql(trx, &trx->last_sql_stat_start);
/* The following call should not be needed, but we play safe: */
trx_mark_sql_stat_end(trx);
@@ -282,7 +280,7 @@ trx_rollback_to_savepoint_for_mysql(
trx->op_info = "rollback to a savepoint";
- err = trx_general_rollback_for_mysql(trx, TRUE, &(savep->savept));
+ err = trx_general_rollback_for_mysql(trx, &savep->savept);
/* Store the current undo_no of the transaction so that we know where
to roll back if we have to roll back the next SQL statement: */
@@ -534,28 +532,26 @@ trx_rollback_active(
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
-transaction was not yet committed, then we roll it back.
-Note: this is done in a background thread.
-@return a dummy parameter */
+transaction was not yet committed, then we roll it back. */
UNIV_INTERN
-os_thread_ret_t
-trx_rollback_or_clean_all_recovered(
-/*================================*/
- void* arg __attribute__((unused)))
- /*!< in: a dummy parameter required by
- os_thread_create */
+void
+trx_rollback_or_clean_recovered(
+/*============================*/
+ ibool all) /*!< in: FALSE=roll back dictionary transactions;
+ TRUE=roll back all non-PREPARED transactions */
{
trx_t* trx;
mutex_enter(&kernel_mutex);
- if (UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+ if (!UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+ goto leave_function;
+ }
+ if (all) {
fprintf(stderr,
"InnoDB: Starting in background the rollback"
" of uncommitted transactions\n");
- } else {
- goto leave_function;
}
mutex_exit(&kernel_mutex);
@@ -584,18 +580,42 @@ loop:
goto loop;
case TRX_ACTIVE:
- mutex_exit(&kernel_mutex);
- trx_rollback_active(trx);
- goto loop;
+ if (all || trx_get_dict_operation(trx)
+ != TRX_DICT_OP_NONE) {
+ mutex_exit(&kernel_mutex);
+ trx_rollback_active(trx);
+ goto loop;
+ }
}
}
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Rollback of non-prepared transactions completed\n");
+ if (all) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Rollback of non-prepared"
+ " transactions completed\n");
+ }
leave_function:
mutex_exit(&kernel_mutex);
+}
+
+/*******************************************************************//**
+Rollback or clean up any incomplete transactions which were
+encountered in crash recovery. If the transaction already was
+committed, then we clean up a possible insert undo log. If the
+transaction was not yet committed, then we roll it back.
+Note: this is done in a background thread.
+@return a dummy parameter */
+UNIV_INTERN
+os_thread_ret_t
+trx_rollback_or_clean_all_recovered(
+/*================================*/
+ void* arg __attribute__((unused)))
+ /*!< in: a dummy parameter required by
+ os_thread_create */
+{
+ trx_rollback_or_clean_recovered(TRUE);
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
=== modified file 'storage/xtradb/trx/trx0rseg.c'
--- a/storage/xtradb/trx/trx0rseg.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/trx/trx0rseg.c 2010-01-06 12:00:14 +0000
@@ -132,6 +132,49 @@ trx_rseg_header_create(
}
/***********************************************************************//**
+Free's an instance of the rollback segment in memory. */
+UNIV_INTERN
+void
+trx_rseg_mem_free(
+/*==============*/
+ trx_rseg_t* rseg) /* in, own: instance to free */
+{
+ trx_undo_t* undo;
+
+ mutex_free(&rseg->mutex);
+
+ /* There can't be any active transactions. */
+ ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0);
+ ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0);
+
+ undo = UT_LIST_GET_FIRST(rseg->update_undo_cached);
+
+ while (undo != NULL) {
+ trx_undo_t* prev_undo = undo;
+
+ undo = UT_LIST_GET_NEXT(undo_list, undo);
+ UT_LIST_REMOVE(undo_list, rseg->update_undo_cached, prev_undo);
+
+ trx_undo_mem_free(prev_undo);
+ }
+
+ undo = UT_LIST_GET_FIRST(rseg->insert_undo_cached);
+
+ while (undo != NULL) {
+ trx_undo_t* prev_undo = undo;
+
+ undo = UT_LIST_GET_NEXT(undo_list, undo);
+ UT_LIST_REMOVE(undo_list, rseg->insert_undo_cached, prev_undo);
+
+ trx_undo_mem_free(prev_undo);
+ }
+
+ trx_sys_set_nth_rseg(trx_sys, rseg->id, NULL);
+
+ mem_free(rseg);
+}
+
+/***************************************************************************
Creates and initializes a rollback segment object. The values for the
fields are read from the header. The object is inserted to the rseg
list of the trx system object and a pointer is inserted in the rseg
=== modified file 'storage/xtradb/trx/trx0sys.c'
--- a/storage/xtradb/trx/trx0sys.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/trx/trx0sys.c 2010-01-06 12:00:14 +0000
@@ -39,7 +39,9 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0srv.h"
#include "trx0purge.h"
#include "log0log.h"
+#include "log0recv.h"
#include "os0file.h"
+#include "read0read.h"
/** The file format tag structure with id and name. */
struct file_format_struct {
@@ -552,6 +554,12 @@ trx_sys_doublewrite_init_or_restore_page
zip_size ? zip_size : UNIV_PAGE_SIZE,
read_buf, NULL);
+ if (srv_recovery_stats && recv_recovery_is_on()) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_doublewrite_check_pages++;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
/* Check if the page is corrupt */
if (UNIV_UNLIKELY
@@ -599,6 +607,13 @@ trx_sys_doublewrite_init_or_restore_page
zip_size, page_no, 0,
zip_size ? zip_size : UNIV_PAGE_SIZE,
page, NULL);
+
+ if (srv_recovery_stats && recv_recovery_is_on()) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_doublewrite_overwrite_pages++;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
fprintf(stderr,
"InnoDB: Recovered the page from"
" the doublewrite buffer.\n");
@@ -1592,3 +1607,80 @@ trx_sys_file_format_id_to_name(
}
#endif /* !UNIV_HOTBACKUP */
+
+/*********************************************************************
+Shutdown/Close the transaction system. */
+UNIV_INTERN
+void
+trx_sys_close(void)
+/*===============*/
+{
+ trx_rseg_t* rseg;
+ read_view_t* view;
+
+ ut_ad(trx_sys != NULL);
+
+ /* Check that all read views are closed except read view owned
+ by a purge. */
+
+ if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
+ fprintf(stderr,
+ "InnoDB: Error: all read views were not closed"
+ " before shutdown:\n"
+ "InnoDB: %lu read views open \n",
+ UT_LIST_GET_LEN(trx_sys->view_list) - 1);
+ }
+
+ sess_close(trx_dummy_sess);
+ trx_dummy_sess = NULL;
+
+ trx_purge_sys_close();
+
+ mutex_enter(&kernel_mutex);
+
+ /* Free the double write data structures. */
+ ut_a(trx_doublewrite != NULL);
+ ut_free(trx_doublewrite->write_buf_unaligned);
+ trx_doublewrite->write_buf_unaligned = NULL;
+
+ mem_free(trx_doublewrite->buf_block_arr);
+ trx_doublewrite->buf_block_arr = NULL;
+
+ mutex_free(&trx_doublewrite->mutex);
+ mem_free(trx_doublewrite);
+ trx_doublewrite = NULL;
+
+ /* There can't be any active transactions. */
+ rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
+
+ while (rseg != NULL) {
+ trx_rseg_t* prev_rseg = rseg;
+
+ rseg = UT_LIST_GET_NEXT(rseg_list, prev_rseg);
+ UT_LIST_REMOVE(rseg_list, trx_sys->rseg_list, prev_rseg);
+
+ trx_rseg_mem_free(prev_rseg);
+ }
+
+ view = UT_LIST_GET_FIRST(trx_sys->view_list);
+
+ while (view != NULL) {
+ read_view_t* prev_view = view;
+
+ view = UT_LIST_GET_NEXT(view_list, prev_view);
+
+ /* Views are allocated from the trx_sys->global_read_view_heap.
+ So, we simply remove the element here. */
+ UT_LIST_REMOVE(view_list, trx_sys->view_list, prev_view);
+ }
+
+ ut_a(UT_LIST_GET_LEN(trx_sys->trx_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->rseg_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
+
+ mem_free(trx_sys);
+
+ trx_sys = NULL;
+ mutex_exit(&kernel_mutex);
+}
=== modified file 'storage/xtradb/trx/trx0trx.c'
--- a/storage/xtradb/trx/trx0trx.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/trx/trx0trx.c 2010-01-06 12:00:14 +0000
@@ -178,6 +178,15 @@ trx_create(
trx->global_read_view = NULL;
trx->read_view = NULL;
+ trx->io_reads = 0;
+ trx->io_read = 0;
+ trx->io_reads_wait_timer = 0;
+ trx->lock_que_wait_timer = 0;
+ trx->innodb_que_wait_timer = 0;
+ trx->distinct_page_access = 0;
+ trx->distinct_page_access_hash = NULL;
+ trx->take_stats = FALSE;
+
/* Set X/Open XA transaction identification to NULL */
memset(&trx->xid, 0, sizeof(trx->xid));
trx->xid.formatID = -1;
@@ -215,6 +224,11 @@ trx_allocate_for_mysql(void)
trx->mysql_process_no = os_proc_get_number();
+ if (innobase_get_slow_log() && trx->take_stats) {
+ trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
+ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
+ }
+
return(trx);
}
@@ -346,6 +360,12 @@ trx_free_for_mysql(
/*===============*/
trx_t* trx) /*!< in, own: trx object */
{
+ if (trx->distinct_page_access_hash)
+ {
+ mem_free(trx->distinct_page_access_hash);
+ trx->distinct_page_access_hash= NULL;
+ }
+
mutex_enter(&kernel_mutex);
UT_LIST_REMOVE(mysql_trx_list, trx_sys->mysql_trx_list, trx);
@@ -367,6 +387,12 @@ trx_free_for_background(
/*====================*/
trx_t* trx) /*!< in, own: trx object */
{
+ if (trx->distinct_page_access_hash)
+ {
+ mem_free(trx->distinct_page_access_hash);
+ trx->distinct_page_access_hash= NULL;
+ }
+
mutex_enter(&kernel_mutex);
trx_free(trx);
@@ -820,7 +846,7 @@ trx_commit_off_kernel(
in exactly the same order as commit lsn's, if the transactions
have different rollback segments. To get exactly the same
order we should hold the kernel mutex up to this point,
- adding to to the contention of the kernel mutex. However, if
+ adding to the contention of the kernel mutex. However, if
a transaction T2 is able to see modifications made by
a transaction T1, T2 will always get a bigger transaction
number and a bigger commit lsn than T1. */
@@ -967,7 +993,7 @@ trx_commit_off_kernel(
/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
-crashed, andf we cannot roll it back. */
+crashed, and we cannot roll it back. */
UNIV_INTERN
void
trx_cleanup_at_db_startup(
@@ -1072,6 +1098,9 @@ trx_end_lock_wait(
trx_t* trx) /*!< in: transaction */
{
que_thr_t* thr;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t now;
ut_ad(mutex_own(&kernel_mutex));
ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
@@ -1086,6 +1115,11 @@ trx_end_lock_wait(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ now = (ib_uint64_t)sec * 1000000 + ms;
+ trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
+ }
trx->que_state = TRX_QUE_RUNNING;
}
@@ -1099,6 +1133,9 @@ trx_lock_wait_to_suspended(
trx_t* trx) /*!< in: transaction in the TRX_QUE_LOCK_WAIT state */
{
que_thr_t* thr;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t now;
ut_ad(mutex_own(&kernel_mutex));
ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
@@ -1113,6 +1150,11 @@ trx_lock_wait_to_suspended(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ now = (ib_uint64_t)sec * 1000000 + ms;
+ trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
+ }
trx->que_state = TRX_QUE_RUNNING;
}
=== modified file 'storage/xtradb/trx/trx0undo.c'
--- a/storage/xtradb/trx/trx0undo.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/trx/trx0undo.c 2010-01-06 12:00:14 +0000
@@ -1560,7 +1560,7 @@ trx_undo_mem_init_for_reuse(
/********************************************************************//**
Frees an undo log memory copy. */
-static
+UNIV_INTERN
void
trx_undo_mem_free(
/*==============*/
=== modified file 'storage/xtradb/usr/usr0sess.c'
--- a/storage/xtradb/usr/usr0sess.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/usr/usr0sess.c 2010-01-06 12:00:14 +0000
@@ -32,14 +32,6 @@ Created 6/25/1996 Heikki Tuuri
#include "trx0trx.h"
/*********************************************************************//**
-Closes a session, freeing the memory occupied by it. */
-static
-void
-sess_close(
-/*=======*/
- sess_t* sess); /*!< in, own: session object */
-
-/*********************************************************************//**
Opens a session.
@return own: session object */
UNIV_INTERN
@@ -64,35 +56,16 @@ sess_open(void)
/*********************************************************************//**
Closes a session, freeing the memory occupied by it. */
-static
+UNIV_INTERN
void
sess_close(
/*=======*/
sess_t* sess) /*!< in, own: session object */
{
- ut_ad(mutex_own(&kernel_mutex));
- ut_ad(sess->trx == NULL);
-
- mem_free(sess);
-}
-
-/*********************************************************************//**
-Closes a session, freeing the memory occupied by it, if it is in a state
-where it should be closed.
-@return TRUE if closed */
-UNIV_INTERN
-ibool
-sess_try_close(
-/*===========*/
- sess_t* sess) /*!< in, own: session object */
-{
- ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(!mutex_own(&kernel_mutex));
- if (UT_LIST_GET_LEN(sess->graphs) == 0) {
- sess_close(sess);
+ ut_a(UT_LIST_GET_LEN(sess->graphs) == 0);
- return(TRUE);
- }
-
- return(FALSE);
+ trx_free_for_background(sess->trx);
+ mem_free(sess);
}
=== modified file 'storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c'
--- a/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c 2009-09-23 00:06:02 +0000
+++ b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c 2010-01-06 12:00:14 +0000
@@ -17,18 +17,38 @@ Place, Suite 330, Boston, MA 02111-1307
*****************************************************************************/
/*****************************************************************************
-If this program compiles, then pthread_t objects can be used as arguments
-to Solaris libc atomic functions.
+If this program compiles and returns 0, then pthread_t objects can be used as
+arguments to Solaris libc atomic functions.
Created April 18, 2009 Vasil Dimov
*****************************************************************************/
#include <pthread.h>
+#include <string.h>
int
main(int argc, char** argv)
{
- pthread_t x = 0;
+ pthread_t x1;
+ pthread_t x2;
+ pthread_t x3;
+
+ memset(&x1, 0x0, sizeof(x1));
+ memset(&x2, 0x0, sizeof(x2));
+ memset(&x3, 0x0, sizeof(x3));
+
+ if (sizeof(pthread_t) == 4) {
+
+ atomic_cas_32(&x1, x2, x3);
+
+ } else if (sizeof(pthread_t) == 8) {
+
+ atomic_cas_64(&x1, x2, x3);
+
+ } else {
+
+ return(1);
+ }
return(0);
}
=== added file 'storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c'
--- a/storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c 1970-01-01 00:00:00 +0000
+++ b/storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c 2010-01-06 12:00:14 +0000
@@ -0,0 +1,61 @@
+/*****************************************************************************
+
+Copyright (c) 2009, Innobase Oy. All Rights Reserved.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
+
+/*****************************************************************************
+If this program compiles and returns 0, then GCC atomic funcions are available.
+
+Created September 12, 2009 Vasil Dimov
+*****************************************************************************/
+
+int
+main(int argc, char** argv)
+{
+ long x;
+ long y;
+ long res;
+ char c;
+
+ x = 10;
+ y = 123;
+ res = __sync_bool_compare_and_swap(&x, x, y);
+ if (!res || x != y) {
+ return(1);
+ }
+
+ x = 10;
+ y = 123;
+ res = __sync_bool_compare_and_swap(&x, x + 1, y);
+ if (res || x != 10) {
+ return(1);
+ }
+
+ x = 10;
+ y = 123;
+ res = __sync_add_and_fetch(&x, y);
+ if (res != 123 + 10 || x != 123 + 10) {
+ return(1);
+ }
+
+ c = 10;
+ res = __sync_lock_test_and_set(&c, 123);
+ if (res != 10 || c != 123) {
+ return(1);
+ }
+
+ return(0);
+}
=== modified file 'storage/xtradb/ut/ut0mem.c'
--- a/storage/xtradb/ut/ut0mem.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/ut/ut0mem.c 2010-01-06 12:00:14 +0000
@@ -433,6 +433,8 @@ ut_free_all_mem(void)
" total allocated memory is %lu\n",
(ulong) ut_total_allocated_memory);
}
+
+ ut_mem_block_list_inited = FALSE;
}
#endif /* !UNIV_HOTBACKUP */
=== modified file 'storage/xtradb/ut/ut0ut.c'
--- a/storage/xtradb/ut/ut0ut.c 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/ut/ut0ut.c 2010-01-06 12:00:14 +0000
@@ -132,6 +132,7 @@ ut_time(void)
return(time(NULL));
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
@@ -200,6 +201,24 @@ ut_time_us(
}
/**********************************************************//**
+Returns the number of milliseconds since some epoch. The
+value may wrap around. It should only be used for heuristic
+purposes.
+@return ms since epoch */
+UNIV_INTERN
+ulint
+ut_time_ms(void)
+/*============*/
+{
+ struct timeval tv;
+
+ ut_gettimeofday(&tv, NULL);
+
+ return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
+}
+#endif /* !UNIV_HOTBACKUP */
+
+/**********************************************************//**
Returns the difference of two times in seconds.
@return time2 - time1 expressed in seconds */
UNIV_INTERN
=== removed directory 'storage/xtradb/win-plugin'
=== removed file 'storage/xtradb/win-plugin/README'
--- a/storage/xtradb/win-plugin/README 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/win-plugin/README 1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
-This directory contains patches that need to be applied to the MySQL
-source tree in order to build the dynamic plugin on Windows --
-HA_INNODB.DLL. Please note the followings when adding the patches:
-
-* The patch must be applied from the mysql top-level source directory.
- patch -p0 < win-plugin.diff
-* The patch filenames end in ".diff".
-* All patches here are expected to apply cleanly to the latest MySQL 5.1
- tree when storage/innobase is replaced with this InnoDB branch.
-
-When applying the patch, the following files will be modified:
-
- * CMakeLists.txt
- * sql/CMakeLists.txt
- * win/configure.js
-
-Also, two new files will be added:
-
- * sql/mysqld.def
- * sql/mysqld_x64.def
-
-You can get "patch" utility for Windows from http://unxutils.sourceforge.net/
=== removed file 'storage/xtradb/win-plugin/win-plugin.diff'
--- a/storage/xtradb/win-plugin/win-plugin.diff 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/win-plugin/win-plugin.diff 1970-01-01 00:00:00 +0000
@@ -1,279 +0,0 @@
-diff -Nur CMakeLists.txt.orig CMakeLists.txt
---- CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
-+++ CMakeLists.txt 2008-09-26 17:32:51 -05:00
-@@ -254,9 +254,9 @@
- IF(WITH_FEDERATED_STORAGE_ENGINE)
- ADD_SUBDIRECTORY(storage/federated)
- ENDIF(WITH_FEDERATED_STORAGE_ENGINE)
--IF(WITH_INNOBASE_STORAGE_ENGINE)
-+IF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
- ADD_SUBDIRECTORY(storage/innobase)
--ENDIF(WITH_INNOBASE_STORAGE_ENGINE)
-+ENDIF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
- ADD_SUBDIRECTORY(sql)
- ADD_SUBDIRECTORY(server-tools/instance-manager)
- ADD_SUBDIRECTORY(libmysql)
-
-diff -Nur sql/CMakeLists.txt.orig sql/CMakeLists.txt
---- sql/CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
-+++ sql/CMakeLists.txt 2008-09-24 03:58:19 -05:00
-@@ -98,6 +98,15 @@
- LINK_FLAGS "/PDB:${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb")
- ENDIF(cmake_version EQUAL 20406)
-
-+# Checks for 64-bit version
-+IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+SET_TARGET_PROPERTIES(mysqld PROPERTIES
-+ LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld_x64.def\"")
-+ELSE(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+SET_TARGET_PROPERTIES(mysqld PROPERTIES
-+ LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld.def\"")
-+ENDIF(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+
- IF(EMBED_MANIFESTS)
- MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
- ENDIF(EMBED_MANIFESTS)
-
-diff -Nur sql/mysqld.def.orig sql/mysqld.def
---- sql/mysqld.def.orig 1969-12-31 18:00:00 -06:00
-+++ sql/mysqld.def 2009-04-09 02:20:32 -05:00
-@@ -0,0 +1,111 @@
-+EXPORTS
-+ ?use_hidden_primary_key@handler@@UAEXXZ
-+ ?get_dynamic_partition_info@handler@@UAEXPAUPARTITION_INFO@@I@Z
-+ ?read_first_row@handler@@UAEHPAEI@Z
-+ ?read_range_next@handler@@UAEHXZ
-+ ?read_range_first@handler@@UAEHPBUst_key_range@@0_N1@Z
-+ ?read_multi_range_first@handler@@UAEHPAPAUst_key_multi_range@@PAU2@I_NPAUst_handler_buffer@@@Z
-+ ?read_multi_range_next@handler@@UAEHPAPAUst_key_multi_range@@@Z
-+ ?index_read_idx_map@handler@@UAEHPAEIPBEKW4ha_rkey_function@@@Z
-+ ?print_error@handler@@UAEXHH@Z
-+ ?clone@handler@@UAEPAV1@PAUst_mem_root@@@Z
-+ ?get_auto_increment@handler@@UAEX_K00PA_K1@Z
-+ ?index_next_same@handler@@UAEHPAEPBEI@Z
-+ ?get_error_message@handler@@UAE_NHPAVString@@@Z
-+ ?ha_thd@handler@@IBEPAVTHD@@XZ
-+ ?update_auto_increment@handler@@QAEHXZ
-+ ?ha_statistic_increment@handler@@IBEXPQsystem_status_var@@K@Z
-+ ?trans_register_ha@@YAXPAVTHD@@_NPAUhandlerton@@@Z
-+ ?cmp@Field_blob@@QAEHPBEI0I@Z
-+ ?set_time@Field_timestamp@@QAEXXZ
-+ ?sql_print_error@@YAXPBDZZ
-+ ?sql_print_warning@@YAXPBDZZ
-+ ?check_global_access@@YA_NPAVTHD@@K@Z
-+ ?schema_table_store_record@@YA_NPAVTHD@@PAUst_table@@@Z
-+ ?get_quote_char_for_identifier@@YAHPAVTHD@@PBDI@Z
-+ ?copy@String@@QAE_NXZ
-+ ?copy@String@@QAE_NABV1@@Z
-+ ?copy@String@@QAE_NPBDIPAUcharset_info_st@@@Z
-+ ?copy_and_convert@@YAIPADIPAUcharset_info_st@@PBDI1PAI@Z
-+ ?filename_to_tablename@@YAIPBDPADI@Z
-+ ?strconvert@@YAIPAUcharset_info_st@@PBD0PADIPAI@Z
-+ ?calculate_key_len@@YAIPAUst_table@@IPBEK@Z
-+ ?sql_alloc@@YAPAXI@Z
-+ ?localtime_to_TIME@@YAXPAUst_mysql_time@@PAUtm@@@Z
-+ ?push_warning@@YAPAVMYSQL_ERROR@@PAVTHD@@W4enum_warning_level@1@IPBD@Z
-+ ?push_warning_printf@@YAXPAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPBDZZ
-+ ?drop_table@handler@@EAEXPBD@Z
-+ ?column_bitmaps_signal@handler@@UAEXXZ
-+ ?delete_table@handler@@MAEHPBD@Z
-+ ?rename_table@handler@@MAEHPBD0@Z
-+ ?key_map_empty@@3V?$Bitmap@$0EA@@@B
-+ ?THR_THD@@3PAVTHD@@A
-+ ?end_of_list@@3Ulist_node@@A
-+ ?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
-+ mysql_query_cache_invalidate4
-+ thd_query
-+ thd_sql_command
-+ thd_get_thread_id
-+ thd_get_xid
-+ thd_slave_thread
-+ thd_non_transactional_update
-+ thd_mark_transaction_to_rollback
-+ thd_security_context
-+ thd_charset
-+ thd_test_options
-+ thd_ha_data
-+ thd_killed
-+ thd_tx_isolation
-+ thd_tablespace_op
-+ thd_sql_command
-+ thd_memdup
-+ thd_make_lex_string
-+ thd_in_lock_tables
-+ thd_binlog_format
-+ _my_hash_init
-+ my_hash_free
-+ my_tmpdir
-+ check_if_legal_filename
-+ my_filename
-+ my_sync_dir_by_file
-+ alloc_root
-+ thr_lock_data_init
-+ thr_lock_init
-+ thr_lock_delete
-+ my_multi_malloc
-+ get_charset
-+ unpack_filename
-+ my_hash_insert
-+ my_hash_search
-+ my_hash_delete
-+ mysql_bin_log_file_pos
-+ mysql_bin_log_file_name
-+ mysqld_embedded
-+ my_thread_name
-+ my_malloc
-+ my_no_flags_free
-+ _sanity
-+ _mymalloc
-+ _myfree
-+ _my_strdup
-+ _my_thread_var
-+ my_error
-+ pthread_cond_init
-+ pthread_cond_signal
-+ pthread_cond_wait
-+ pthread_cond_destroy
-+ localtime_r
-+ my_strdup
-+ deflate
-+ deflateEnd
-+ deflateReset
-+ deflateInit2_
-+ inflateEnd
-+ inflateInit_
-+ inflate
-+ compressBound
-+ inflateInit2_
-+ adler32
-+ longlong2str
-+ strend
-+ my_snprintf
-
-diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def
---- sql/mysqld_x64.def.orig 1969-12-31 18:00:00 -06:00
-+++ sql/mysqld_x64.def 2009-04-09 02:22:04 -05:00
-@@ -0,0 +1,111 @@
-+EXPORTS
-+ ?use_hidden_primary_key@handler@@UEAAXXZ
-+ ?get_dynamic_partition_info@handler@@UEAAXPEAUPARTITION_INFO@@I@Z
-+ ?read_first_row@handler@@UEAAHPEAEI@Z
-+ ?read_range_next@handler@@UEAAHXZ
-+ ?read_range_first@handler@@UEAAHPEBUst_key_range@@0_N1@Z
-+ ?read_multi_range_first@handler@@UEAAHPEAPEAUst_key_multi_range@@PEAU2@I_NPEAUst_handler_buffer@@@Z
-+ ?read_multi_range_next@handler@@UEAAHPEAPEAUst_key_multi_range@@@Z
-+ ?index_read_idx_map@handler@@UEAAHPEAEIPEBEKW4ha_rkey_function@@@Z
-+ ?print_error@handler@@UEAAXHH@Z
-+ ?clone@handler@@UEAAPEAV1@PEAUst_mem_root@@@Z
-+ ?get_auto_increment@handler@@UEAAX_K00PEA_K1@Z
-+ ?index_next_same@handler@@UEAAHPEAEPEBEI@Z
-+ ?get_error_message@handler@@UEAA_NHPEAVString@@@Z
-+ ?ha_thd@handler@@IEBAPEAVTHD@@XZ
-+ ?update_auto_increment@handler@@QEAAHXZ
-+ ?ha_statistic_increment@handler@@IEBAXPEQsystem_status_var@@K@Z
-+ ?trans_register_ha@@YAXPEAVTHD@@_NPEAUhandlerton@@@Z
-+ ?cmp@Field_blob@@QEAAHPEBEI0I@Z
-+ ?set_time@Field_timestamp@@QEAAXXZ
-+ ?sql_print_error@@YAXPEBDZZ
-+ ?sql_print_warning@@YAXPEBDZZ
-+ ?check_global_access@@YA_NPEAVTHD@@K@Z
-+ ?schema_table_store_record@@YA_NPEAVTHD@@PEAUst_table@@@Z
-+ ?get_quote_char_for_identifier@@YAHPEAVTHD@@PEBDI@Z
-+ ?copy@String@@QEAA_NXZ
-+ ?copy@String@@QEAA_NAEBV1@@Z
-+ ?copy@String@@QEAA_NPEBDIPEAUcharset_info_st@@@Z
-+ ?copy_and_convert@@YAIPEADIPEAUcharset_info_st@@PEBDI1PEAI@Z
-+ ?filename_to_tablename@@YAIPEBDPEADI@Z
-+ ?strconvert@@YAIPEAUcharset_info_st@@PEBD0PEADIPEAI@Z
-+ ?calculate_key_len@@YAIPEAUst_table@@IPEBEK@Z
-+ ?sql_alloc@@YAPEAX_K@Z
-+ ?localtime_to_TIME@@YAXPEAUst_mysql_time@@PEAUtm@@@Z
-+ ?push_warning@@YAPEAVMYSQL_ERROR@@PEAVTHD@@W4enum_warning_level@1@IPEBD@Z
-+ ?push_warning_printf@@YAXPEAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPEBDZZ
-+ ?drop_table@handler@@EEAAXPEBD@Z
-+ ?column_bitmaps_signal@handler@@UEAAXXZ
-+ ?delete_table@handler@@MEAAHPEBD@Z
-+ ?rename_table@handler@@MEAAHPEBD0@Z
-+ ?key_map_empty@@3V?$Bitmap@$0EA@@@B
-+ ?THR_THD@@3PEAVTHD@@EA
-+ ?end_of_list@@3Ulist_node@@A
-+ ?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
-+ mysql_query_cache_invalidate4
-+ thd_query
-+ thd_sql_command
-+ thd_get_thread_id
-+ thd_get_xid
-+ thd_slave_thread
-+ thd_non_transactional_update
-+ thd_mark_transaction_to_rollback
-+ thd_security_context
-+ thd_charset
-+ thd_test_options
-+ thd_ha_data
-+ thd_killed
-+ thd_tx_isolation
-+ thd_tablespace_op
-+ thd_sql_command
-+ thd_memdup
-+ thd_make_lex_string
-+ thd_in_lock_tables
-+ thd_binlog_format
-+ _my_hash_init
-+ my_hash_free
-+ my_tmpdir
-+ check_if_legal_filename
-+ my_filename
-+ my_sync_dir_by_file
-+ alloc_root
-+ thr_lock_data_init
-+ thr_lock_init
-+ thr_lock_delete
-+ my_multi_malloc
-+ get_charset
-+ unpack_filename
-+ my_hash_insert
-+ my_hash_search
-+ my_hash_delete
-+ mysql_bin_log_file_pos
-+ mysql_bin_log_file_name
-+ mysqld_embedded
-+ my_thread_name
-+ my_malloc
-+ my_no_flags_free
-+ _sanity
-+ _mymalloc
-+ _myfree
-+ _my_strdup
-+ _my_thread_var
-+ my_error
-+ pthread_cond_init
-+ pthread_cond_signal
-+ pthread_cond_wait
-+ pthread_cond_destroy
-+ localtime_r
-+ my_strdup
-+ deflate
-+ deflateEnd
-+ deflateReset
-+ deflateInit2_
-+ inflateEnd
-+ inflateInit_
-+ inflate
-+ compressBound
-+ inflateInit2_
-+ adler32
-+ longlong2str
-+ strend
-+ my_snprintf
-
-diff -Nur win/configure.js.orig win/configure.js
---- win/configure.js.orig 2008-09-26 21:18:37 -05:00
-+++ win/configure.js 2008-10-01 11:21:27 -05:00
-@@ -50,6 +50,7 @@
- case "EMBED_MANIFESTS":
- case "EXTRA_DEBUG":
- case "WITH_EMBEDDED_SERVER":
-+ case "INNODB_DYNAMIC_PLUGIN":
- configfile.WriteLine("SET (" + args.Item(i) + " TRUE)");
- break;
- case "MYSQL_SERVER_SUFFIX":
=== modified file 'strings/Makefile.am'
--- a/strings/Makefile.am 2009-08-13 21:12:12 +0000
+++ b/strings/Makefile.am 2010-03-04 08:03:07 +0000
@@ -21,13 +21,13 @@ pkglib_LIBRARIES = libmystrings.a
# Exact one of ASSEMBLER_X
if ASSEMBLER_x86
ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
-CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov_overlapp.c
+CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c strmov_overlapp.c
else
if ASSEMBLER_sparc32
# These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile
ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
-CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c strmov_overlapp.c
+CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c strmov.c strmov_overlapp.c
else
#no assembler
ASRCS =
=== modified file 'strings/ctype-ucs2.c'
--- a/strings/ctype-ucs2.c 2009-12-03 12:02:37 +0000
+++ b/strings/ctype-ucs2.c 2010-03-30 12:36:49 +0000
@@ -203,7 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
@@ -317,7 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_I
const char *s, const char *t, size_t len)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const char *se=s+len;
const char *te=t+len;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
@@ -1384,7 +1384,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
@@ -1611,16 +1611,6 @@ fill_max_and_min:
*min_str++= *max_str++ = ptr[1];
}
- /* Temporary fix for handling w_one at end of string (key compression) */
- {
- char *tmp;
- for (tmp= min_str ; tmp-1 > min_org && tmp[-1] == '\0' && tmp[-2]=='\0';)
- {
- *--tmp=' ';
- *--tmp='\0';
- }
- }
-
*min_length= *max_length = (size_t) (min_str - min_org);
while (min_str + 1 < min_end)
{
=== modified file 'strings/ctype-utf8.c'
--- a/strings/ctype-utf8.c 2009-10-15 21:38:29 +0000
+++ b/strings/ctype-utf8.c 2010-03-30 12:36:49 +0000
@@ -2310,7 +2310,7 @@ static int my_strnncoll_utf8(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc), t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
@@ -2380,7 +2380,7 @@ static int my_strnncollsp_utf8(CHARSET_I
my_bool diff_if_only_endspace_difference)
{
int s_res, t_res, res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se= s+slen, *te= t+tlen;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
=== modified file 'strings/strmov.c'
--- a/strings/strmov.c 2006-12-23 19:17:15 +0000
+++ b/strings/strmov.c 2010-03-04 08:03:07 +0000
@@ -24,11 +24,6 @@
#include <my_global.h>
#include "m_string.h"
-#ifdef BAD_STRING_COMPILER
-#undef strmov
-#define strmov strmov_overlapp
-#endif
-
#ifndef strmov
#if !defined(MC68000) && !defined(DS90)
=== modified file 'support-files/Makefile.am'
--- a/support-files/Makefile.am 2009-10-23 16:48:54 +0000
+++ b/support-files/Makefile.am 2010-03-04 08:03:07 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2000-2001, 2003-2006 MySQL AB
+# Copyright (C) 2000-2006 MySQL AB, 2008-2010 Sun Microsystems, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
@@ -121,6 +121,7 @@ SUFFIXES = .sh
-e 's!@''SHARED_LIB_VERSION''@!@SHARED_LIB_VERSION@!' \
-e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \
-e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \
+ -e 's!@''MYSQL_U_SCORE_VERSION''@!@MYSQL_U_SCORE_VERSION@!' \
-e 's!@''MYSQL_COPYRIGHT_YEAR''@!@MYSQL_COPYRIGHT_YEAR@!' \
-e 's!@''MYSQL_TCP_PORT''@!@MYSQL_TCP_PORT@!' \
-e 's!@''PERL_DBI_VERSION''@!@PERL_DBI_VERSION@!' \
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2009-10-03 20:13:58 +0000
+++ b/support-files/compiler_warnings.supp 2010-03-30 12:36:49 +0000
@@ -4,6 +4,7 @@
#
integer.cpp: .*control reaches end of non-void function.*: 1288-1427
+integer.cpp: .*no return statement in function returning non-void.*: 1288-1427
DictTabInfo.cpp : .*invalid access to non-static.*
DictTabInfo.cpp : .*macro was used incorrectly.*
DbdihMain.cpp : .*unused variable.* : 6666-7013
@@ -27,7 +28,18 @@ _flex_tmp.c: .*not enough actual paramet
pars0lex.l: .*conversion from 'ulint' to 'int', possible loss of data.*
btr/btr0cur\.c: .*value computed is not used.*: 3175-3375
include/buf0buf\.ic: unused parameter ‘mtr’
+fil/fil0fil\.c: pointer targets in passing argument.*differ in signedness
fil/fil0fil\.c: comparison between signed and unsigned : 3100-3199
+fil/fil0fil\.c: unused parameter
+log/log0recv\.c: unused variable
+os/os0file\.c: unused parameter
+os/os0file\.c: pointer targets in assignment differ in signedness
+handler/i_s\.cc: unused variable
+sync/sync0rw\.c: unused parameter
+sync/sync0sync\.c: unused parameter
+sync/sync0sync\.c: unused variable
+ut/ut0ut\.c: ignoring return value of
+srv/srv0srv\.c: value computed is not used
#
# bdb is not critical to keep up to date
@@ -50,6 +62,21 @@ db_vrfy.c : .*comparison is always false
.*/extra/libevent/select\.c : .*comparison between signed and unsigned.* : 270-280
#
+# Ignore warnings from system libraries
+#
+/usr/share/aclocal/audiofile.m4 : .*
+
+#
+# Ignore strict-aliasing warnings (for now)
+#
+.*: break strict-aliasing rules
+
+#
+# Ignore not important declaration warnings
+#
+.*: only defines private constructors and has no friends
+
+#
# Ignore all conversion warnings on windows 64
# (Is safe as we are not yet supporting strings >= 2G)
#
@@ -84,10 +111,24 @@ db_vrfy.c : .*comparison is always false
storage/maria/ma_pagecache.c: .*'info_check_pin' defined but not used
#
+# Pbxt
+#
+xaction_xt\.cc: may be used uninitialized in this function
+
+#
# I think these are due to mix of C and C++.
#
storage/pbxt/ : typedef.*was ignored in this declaration
+ha_pbxt\.cc : variable.*might be clobbered by.*longjmp
+#
+# Yassl
+include/runtime.hpp: .*pure_error.*
+.*/extra/yassl/.*taocrypt/.*: comparison with string literal
+.*/extra/yassl/taocrypt/src/blowfish\.cpp: array subscript is above array bounds
+.*/extra/yassl/taocrypt/src/file\.cpp: ignoring return value
+.*/extra/yassl/taocrypt/src/integer\.cpp: control reaches end of non-void function
+mySTL/algorithm\.hpp: is used uninitialized in this function
#
# Groff warnings on OpenSUSE.
@@ -101,14 +142,16 @@ listener.cc : .*conversion from 'SOCKET'
net_serv.cc : .*conversion from 'SOCKET' to 'int'.*
# allow a little moving space for the warning below
-mi_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
-ma_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
+mi_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 560-600
+ma_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550-650
#
# Wrong compiler warnings
#
.* : .*no matching operator delete found; memory will not be freed if initialization throws an exception.*
-ctype-simple.c : .*unary minus operator applied to unsigned type, result still unsigned.*
+ctype-simple\.c : .*unary minus operator applied to unsigned type, result still unsigned.*
# Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478
-regexec\.c : .*passing argument 3 of.*matcher.* discards qualifiers from pointer target type.*
+regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type
+libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000
+storage/xtradb/dict/dict0dict\.c: passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
=== modified file 'support-files/mysql.spec.sh'
--- a/support-files/mysql.spec.sh 2009-12-03 11:19:05 +0000
+++ b/support-files/mysql.spec.sh 2010-03-04 08:03:07 +0000
@@ -1,4 +1,4 @@
-# Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+# Copyright (C) 2000-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -56,9 +56,9 @@
%{!?_with_maria:%define MARIA_BUILD 0}
%if %{STATIC_BUILD}
-%define release 0
+%define release 1
%else
-%define release 0.glibc23
+%define release 1.glibc23
%endif
%define mysql_license GPL
%define mysqld_user mysql
@@ -70,6 +70,19 @@
# See BUG#998 for details.
%define _unpackaged_files_terminate_build 0
+# ------------------------------------------------------------------------------
+# RPM build tools now automatically detects Perl module dependencies. This
+# detection gives problems as it is broken in some versions, and it also
+# give unwanted dependencies from mandatory scripts in our package.
+# Might not be possible to disable in all RPM tool versions, but here we
+# try. We keep the "AutoReqProv: no" for the "test" sub package, as disabling
+# here might fail, and that package has the most problems.
+# See http://fedoraproject.org/wiki/Packaging/Perl#Filtering_Requires:_and_Provid…
+# http://www.wideopen.com/archives/rpm-list/2002-October/msg00343.html
+# ------------------------------------------------------------------------------
+%undefine __perl_provides
+%undefine __perl_requires
+
%define see_base For a description of MySQL see the base MySQL RPM or http://www.mysql.com
# On SuSE 9 no separate "debuginfo" package is built. To enable basic
@@ -92,7 +105,7 @@
Name: MySQL
Summary: MySQL: a very fast and reliable SQL database server
Group: Applications/Databases
-Version: @MYSQL_NO_DASH_VERSION@
+Version: @MYSQL_U_SCORE_VERSION@
Release: %{release}
License: Copyright 2000-2008 MySQL AB, @MYSQL_COPYRIGHT_YEAR@ Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Under %{mysql_license} license as shown in the Description field.
Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_ver…
@@ -210,7 +223,7 @@ They should be used with caution.
%endif
%package test
-Requires: %{name}-client perl-DBI perl
+Requires: %{name}-client perl
Summary: MySQL - Test suite
Group: Applications/Databases
Provides: mysql-test
@@ -917,6 +930,12 @@ fi
# itself - note that they must be ordered by date (important when
# merging BK trees)
%changelog
+* Mon Jan 11 2010 Joerg Bruehe <joerg.bruehe(a)sun.com>
+
+- Change RPM file naming:
+ - Suffix like "-m2", "-rc" becomes part of version as "_m2", "_rc".
+ - Release counts from 1, not 0.
+
* Mon Aug 24 2009 Jonathan Perkin <jperkin(a)sun.com>
- Add conditionals for bundled zlib and innodb plugin
=== modified file 'tests/mysql_client_test.c'
--- a/tests/mysql_client_test.c 2009-12-03 11:19:05 +0000
+++ b/tests/mysql_client_test.c 2010-01-11 13:15:28 +0000
@@ -2465,6 +2465,34 @@ static uint query_cache_hits(MYSQL *conn
/*
+ Check that query cache is available in server.
+*/
+static my_bool is_query_cache_available()
+{
+ int rc;
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ int res= -1;
+
+ rc= mysql_query(mysql, "SHOW VARIABLES LIKE 'have_query_cache'");
+ myquery(rc);
+
+ result= mysql_store_result(mysql);
+ DIE_UNLESS(result);
+
+ row= mysql_fetch_row(result);
+ DIE_UNLESS(row != NULL);
+ if (strcmp(row[1], "YES") == 0)
+ res= 1;
+ else if (strcmp(row[1], "NO") == 0)
+ res= 0;
+ mysql_free_result(result);
+
+ DIE_UNLESS(res == 0 || res == 1);
+ return res;
+}
+
+/*
Test that prepared statements make use of the query cache just as normal
statements (BUG#735).
*/
@@ -2508,6 +2536,12 @@ static void test_ps_query_cache()
myheader("test_ps_query_cache");
+ if (! is_query_cache_available())
+ {
+ fprintf(stdout, "Skipping test_ps_query_cache: Query cache not available.\n");
+ return;
+ }
+
rc= mysql_query(mysql, "SET SQL_MODE=''");
myquery(rc);
@@ -17863,8 +17897,6 @@ static void test_bug43560(void)
Bug#36326: nested transaction and select
*/
-#ifdef HAVE_QUERY_CACHE
-
static void test_bug36326()
{
int rc;
@@ -17872,6 +17904,12 @@ static void test_bug36326()
DBUG_ENTER("test_bug36326");
myheader("test_bug36326");
+ if (! is_query_cache_available())
+ {
+ fprintf(stdout, "Skipping test_bug36326: Query cache not available.\n");
+ DBUG_VOID_RETURN;
+ }
+
rc= mysql_autocommit(mysql, TRUE);
myquery(rc);
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
@@ -17911,8 +17949,6 @@ static void test_bug36326()
DBUG_VOID_RETURN;
}
-#endif
-
/**
Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short
string value.
@@ -18373,9 +18409,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug38486", test_bug38486 },
{ "test_bug40365", test_bug40365 },
{ "test_bug43560", test_bug43560 },
-#ifdef HAVE_QUERY_CACHE
{ "test_bug36326", test_bug36326 },
-#endif
{ "test_bug41078", test_bug41078 },
{ "test_bug44495", test_bug44495 },
{ 0, 0 }
=== modified file 'unittest/mysys/waiting_threads-t.c'
--- a/unittest/mysys/waiting_threads-t.c 2009-09-15 10:46:35 +0000
+++ b/unittest/mysys/waiting_threads-t.c 2010-03-30 12:36:49 +0000
@@ -258,7 +258,7 @@ void do_tests()
#define test_kill_strategy(X) \
diag("kill strategy: " #X); \
DBUG_EXECUTE("reset_file", \
- { rewind(DBUG_FILE); ftruncate(fileno(DBUG_FILE), 0); }); \
+ { rewind(DBUG_FILE); my_chsize(fileno(DBUG_FILE), 0, 0, MYF(MY_WME)); }); \
DBUG_PRINT("info", ("kill strategy: " #X)); \
kill_strategy=X; \
do_one_test();
=== modified file 'vio/vio.c'
--- a/vio/vio.c 2009-11-02 22:19:58 +0000
+++ b/vio/vio.c 2009-11-20 12:09:50 +0000
@@ -62,10 +62,8 @@ static void vio_init(Vio* vio, enum enum
vio->timeout=vio_win32_timeout;
/* Set default timeout */
- vio->read_timeout_millis = INFINITE;
- vio->write_timeout_millis = INFINITE;
-
- memset(&(vio->pipe_overlapped), 0, sizeof(OVERLAPPED));
+ vio->read_timeout_ms= INFINITE;
+ vio->write_timeout_ms= INFINITE;
vio->pipe_overlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
DBUG_VOID_RETURN;
}
@@ -90,8 +88,8 @@ static void vio_init(Vio* vio, enum enum
/* Currently, shared memory is on Windows only, hence the below is ok*/
vio->timeout= vio_win32_timeout;
/* Set default timeout */
- vio->read_timeout_millis= INFINITE;
- vio->write_timeout_millis= INFINITE;
+ vio->read_timeout_ms= INFINITE;
+ vio->write_timeout_ms= INFINITE;
DBUG_VOID_RETURN;
}
#endif
@@ -115,22 +113,20 @@ static void vio_init(Vio* vio, enum enum
DBUG_VOID_RETURN;
}
#endif /* HAVE_OPENSSL */
- {
- vio->viodelete =vio_delete;
- vio->vioerrno =vio_errno;
- vio->read= (flags & VIO_BUFFERED_READ) ? vio_read_buff : vio_read;
- vio->write =vio_write;
- vio->fastsend =vio_fastsend;
- vio->viokeepalive =vio_keepalive;
- vio->should_retry =vio_should_retry;
- vio->was_interrupted=vio_was_interrupted;
- vio->vioclose =vio_close;
- vio->peer_addr =vio_peer_addr;
- vio->in_addr =vio_in_addr;
- vio->vioblocking =vio_blocking;
- vio->is_blocking =vio_is_blocking;
- vio->timeout =vio_timeout;
- }
+ vio->viodelete =vio_delete;
+ vio->vioerrno =vio_errno;
+ vio->read= (flags & VIO_BUFFERED_READ) ? vio_read_buff : vio_read;
+ vio->write =vio_write;
+ vio->fastsend =vio_fastsend;
+ vio->viokeepalive =vio_keepalive;
+ vio->should_retry =vio_should_retry;
+ vio->was_interrupted=vio_was_interrupted;
+ vio->vioclose =vio_close;
+ vio->peer_addr =vio_peer_addr;
+ vio->in_addr =vio_in_addr;
+ vio->vioblocking =vio_blocking;
+ vio->is_blocking =vio_is_blocking;
+ vio->timeout =vio_timeout;
DBUG_VOID_RETURN;
}
=== modified file 'vio/viosocket.c'
--- a/vio/viosocket.c 2009-12-03 11:19:05 +0000
+++ b/vio/viosocket.c 2010-01-15 15:27:55 +0000
@@ -428,14 +428,14 @@ void vio_timeout(Vio *vio, uint which, u
/*
Finish pending IO on pipe. Honor wait timeout
*/
-static int pipe_complete_io(Vio* vio, char* buf, size_t size, DWORD timeout_millis)
+static size_t pipe_complete_io(Vio* vio, char* buf, size_t size, DWORD timeout_ms)
{
DWORD length;
DWORD ret;
DBUG_ENTER("pipe_complete_io");
- ret= WaitForSingleObject(vio->pipe_overlapped.hEvent, timeout_millis);
+ ret= WaitForSingleObject(vio->pipe_overlapped.hEvent, timeout_ms);
/*
WaitForSingleObjects will normally return WAIT_OBJECT_O (success, IO completed)
or WAIT_TIMEOUT.
@@ -444,14 +444,14 @@ static int pipe_complete_io(Vio* vio, ch
{
CancelIo(vio->hPipe);
DBUG_PRINT("error",("WaitForSingleObject() returned %d", ret));
- DBUG_RETURN(-1);
+ DBUG_RETURN((size_t)-1);
}
if (!GetOverlappedResult(vio->hPipe,&(vio->pipe_overlapped),&length, FALSE))
{
DBUG_PRINT("error",("GetOverlappedResult() returned last error %d",
GetLastError()));
- DBUG_RETURN(-1);
+ DBUG_RETURN((size_t)-1);
}
DBUG_RETURN(length);
@@ -461,49 +461,58 @@ static int pipe_complete_io(Vio* vio, ch
size_t vio_read_pipe(Vio * vio, uchar *buf, size_t size)
{
DWORD bytes_read;
+ size_t retval;
DBUG_ENTER("vio_read_pipe");
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u", vio->sd, (long) buf,
(uint) size));
- if (!ReadFile(vio->hPipe, buf, (DWORD)size, &bytes_read,
+ if (ReadFile(vio->hPipe, buf, (DWORD)size, &bytes_read,
&(vio->pipe_overlapped)))
{
+ retval= bytes_read;
+ }
+ else
+ {
if (GetLastError() != ERROR_IO_PENDING)
{
DBUG_PRINT("error",("ReadFile() returned last error %d",
GetLastError()));
DBUG_RETURN((size_t)-1);
}
- bytes_read= pipe_complete_io(vio, buf, size,vio->read_timeout_millis);
+ retval= pipe_complete_io(vio, buf, size,vio->read_timeout_ms);
}
- DBUG_PRINT("exit", ("%d", bytes_read));
- DBUG_RETURN(bytes_read);
+ DBUG_PRINT("exit", ("%lld", (longlong)retval));
+ DBUG_RETURN(retval);
}
size_t vio_write_pipe(Vio * vio, const uchar* buf, size_t size)
{
DWORD bytes_written;
+ size_t retval;
DBUG_ENTER("vio_write_pipe");
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u", vio->sd, (long) buf,
(uint) size));
- if (!WriteFile(vio->hPipe, buf, (DWORD)size, &bytes_written,
+ if (WriteFile(vio->hPipe, buf, (DWORD)size, &bytes_written,
&(vio->pipe_overlapped)))
{
+ retval= bytes_written;
+ }
+ else
+ {
if (GetLastError() != ERROR_IO_PENDING)
{
DBUG_PRINT("vio_error",("WriteFile() returned last error %d",
GetLastError()));
DBUG_RETURN((size_t)-1);
}
- bytes_written = pipe_complete_io(vio, (char *)buf, size,
- vio->write_timeout_millis);
+ retval= pipe_complete_io(vio, (char *)buf, size, vio->write_timeout_ms);
}
- DBUG_PRINT("exit", ("%d", bytes_written));
- DBUG_RETURN(bytes_written);
+ DBUG_PRINT("exit", ("%lld", (longlong)retval));
+ DBUG_RETURN(retval);
}
@@ -528,21 +537,21 @@ int vio_close_pipe(Vio * vio)
void vio_win32_timeout(Vio *vio, uint which , uint timeout_sec)
{
- DWORD timeout_millis;
+ DWORD timeout_ms;
/*
Windows is measuring timeouts in milliseconds. Check for possible int
overflow.
*/
if (timeout_sec > UINT_MAX/1000)
- timeout_millis= INFINITE;
+ timeout_ms= INFINITE;
else
- timeout_millis= timeout_sec * 1000;
+ timeout_ms= timeout_sec * 1000;
/* which == 1 means "write", which == 0 means "read".*/
if(which)
- vio->write_timeout_millis= timeout_millis;
+ vio->write_timeout_ms= timeout_ms;
else
- vio->read_timeout_millis= timeout_millis;
+ vio->read_timeout_ms= timeout_ms;
}
@@ -577,7 +586,7 @@ size_t vio_read_shared_memory(Vio * vio,
WAIT_ABANDONED_0 and WAIT_TIMEOUT - fail. We can't read anything
*/
if (WaitForMultipleObjects(array_elements(events), events, FALSE,
- vio->read_timeout_millis) != WAIT_OBJECT_0)
+ vio->read_timeout_ms) != WAIT_OBJECT_0)
{
DBUG_RETURN(-1);
};
@@ -634,7 +643,7 @@ size_t vio_write_shared_memory(Vio * vio
while (remain != 0)
{
if (WaitForMultipleObjects(array_elements(events), events, FALSE,
- vio->write_timeout_millis) != WAIT_OBJECT_0)
+ vio->write_timeout_ms) != WAIT_OBJECT_0)
{
DBUG_RETURN((size_t) -1);
}
=== modified file 'vio/viossl.c'
--- a/vio/viossl.c 2008-02-07 08:55:49 +0000
+++ b/vio/viossl.c 2010-03-10 10:32:14 +0000
@@ -74,8 +74,13 @@ report_errors(SSL* ssl)
}
if (ssl)
- DBUG_PRINT("error", ("error: %s",
- ERR_error_string(SSL_get_error(ssl, l), buf)));
+ {
+#ifndef DBUG_OFF
+ int error= SSL_get_error(ssl, l);
+ DBUG_PRINT("error", ("error: %s (%d)",
+ ERR_error_string(error, buf), error));
+#endif
+ }
DBUG_PRINT("info", ("socket_errno: %d", socket_errno));
DBUG_VOID_RETURN;
@@ -174,16 +179,17 @@ void vio_ssl_delete(Vio *vio)
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
- int (*connect_accept_func)(SSL*))
+ int (*connect_accept_func)(SSL*), char *error_string)
{
SSL *ssl;
my_bool unused;
my_bool was_blocking;
-
DBUG_ENTER("ssl_do");
DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d ctx: 0x%lx",
(long) ptr, vio->sd, (long) ptr->ssl_context));
+ error_string[0]= 0;
+
/* Set socket to blocking if not already set */
vio_blocking(vio, 1, &was_blocking);
@@ -191,6 +197,7 @@ static int ssl_do(struct st_VioSSLFd *pt
{
DBUG_PRINT("error", ("SSL_new failure"));
report_errors(ssl);
+ strmov(error_string, "SSL_new failed");
vio_blocking(vio, was_blocking, &unused);
DBUG_RETURN(1);
}
@@ -203,6 +210,7 @@ static int ssl_do(struct st_VioSSLFd *pt
{
DBUG_PRINT("error", ("SSL_connect/accept failure"));
report_errors(ssl);
+ ERR_error_string(SSL_get_error(ssl, 0), error_string);
SSL_free(ssl);
vio_blocking(vio, was_blocking, &unused);
DBUG_RETURN(1);
@@ -250,17 +258,19 @@ static int ssl_do(struct st_VioSSLFd *pt
}
-int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
+int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ char *error_string)
{
DBUG_ENTER("sslaccept");
- DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept));
+ DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept, error_string));
}
-int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
+int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ char *error_string)
{
DBUG_ENTER("sslconnect");
- DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect));
+ DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect, error_string));
}
=== modified file 'win/configure.js'
--- a/win/configure.js 2009-10-07 21:00:29 +0000
+++ b/win/configure.js 2010-03-04 08:03:07 +0000
@@ -155,10 +155,10 @@ function GetValue(str, key)
function GetVersion(str)
{
- var key = "AM_INIT_AUTOMAKE(mysql, ";
+ var key = "AC_INIT([MariaDB Server], [";
var key2 = "AM_INIT_AUTOMAKE(mariadb, ";
var key_len = key.length;
- var pos = str.indexOf(key); //5.0.6-beta)
+ var pos = str.indexOf(key);
if (pos == -1)
{
pos = str.indexOf(key2);
@@ -166,7 +166,7 @@ function GetVersion(str)
}
if (pos == -1) return null;
pos += key_len;
- var end = str.indexOf(")", pos);
+ var end = str.indexOf("]", pos);
if (end == -1) return null;
return str.substring(pos, end);
}
1
0

[Maria-developers] [Branch ~maria-captains/maria/5.1] Rev 2836: Removed compiler warning
by noreply@launchpad.net 30 Mar '10
by noreply@launchpad.net 30 Mar '10
30 Mar '10
------------------------------------------------------------
revno: 2836
committer: Michael Widenius <monty(a)askmonty.org>
branch nick: maria-5.1
timestamp: Tue 2010-03-30 15:36:49 +0300
message:
Removed compiler warning
Disable pbxt for test cases not using pbxt (speeds up test suite)
added:
mysql-test/suite/pbxt/t/suite.opt
modified:
extra/comp_err.c
extra/libevent/kqueue.c
mysql-test/lib/mtr_cases.pm
mysys/mf_keycache.c
mysys/my_gethostbyname.c
sql/handler.cc
sql/item.h
sql/mysqld.cc
sql/sql_class.h
sql/sql_table.cc
sql/sql_view.cc
storage/maria/ma_loghandler.c
storage/myisammrg/ha_myisammrg.cc
storage/myisammrg/myrg_open.c
storage/xtradb/include/ut0lst.h
strings/ctype-ucs2.c
strings/ctype-utf8.c
support-files/compiler_warnings.supp
unittest/mysys/waiting_threads-t.c
--
lp:maria
https://code.launchpad.net/~maria-captains/maria/5.1
Your team Maria developers is subscribed to branch lp:maria.
To unsubscribe from this branch go to https://code.launchpad.net/~maria-captains/maria/5.1/+edit-subscription.
1
0

[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2836)
by Michael Widenius 30 Mar '10
by Michael Widenius 30 Mar '10
30 Mar '10
#At lp:maria based on revid:monty@askmonty.org-20100329190745-m4fvzr3pr6phn93h
2836 Michael Widenius 2010-03-30
Removed compiler warning
Disable pbxt for test cases not using pbxt (speeds up test suite)
added:
mysql-test/suite/pbxt/t/suite.opt
modified:
extra/comp_err.c
extra/libevent/kqueue.c
mysql-test/lib/mtr_cases.pm
mysys/mf_keycache.c
mysys/my_gethostbyname.c
sql/handler.cc
sql/item.h
sql/mysqld.cc
sql/sql_class.h
sql/sql_table.cc
sql/sql_view.cc
storage/maria/ma_loghandler.c
storage/myisammrg/ha_myisammrg.cc
storage/myisammrg/myrg_open.c
storage/xtradb/include/ut0lst.h
strings/ctype-ucs2.c
strings/ctype-utf8.c
support-files/compiler_warnings.supp
unittest/mysys/waiting_threads-t.c
per-file messages:
extra/comp_err.c
Added cast to get rid of compiler warning
extra/libevent/kqueue.c
Added cast to get rid of compiler warning
mysql-test/lib/mtr_cases.pm
Use --skip-pbxt for test cases that doesn't need pbxt
Collect default-storage-engine from suite.opt file (should actually be my.cnf file, but that wasn't easy to do)
mysql-test/suite/pbxt/t/suite.opt
Added marker for mysql-test-run.pl that this suite require pbxt
mysys/mf_keycache.c
Use LINT_INIT() to remove compiler warnings
mysys/my_gethostbyname.c
Remove compiler warnings
sql/handler.cc
Reset variable that may be used uninitialized
sql/item.h
Remove compiler warning
sql/mysqld.cc
Use LINT_INIT() to remove compiler warnings
sql/sql_class.h
Remove compiler warning
sql/sql_table.cc
Ensure variable is always set (to remove compiler warning)
sql/sql_view.cc
Use LINT_INIT() to remove compiler warnings
storage/maria/ma_loghandler.c
Use LINT_INIT() to remove compiler warnings
storage/myisammrg/ha_myisammrg.cc
Fixed wrong type to printf
storage/myisammrg/myrg_open.c
Use LINT_INIT() to remove compiler warnings
storage/xtradb/include/ut0lst.h
Trivial change of macro to remove compiler warning
strings/ctype-ucs2.c
Use LINT_INIT() to remove compiler warnings
strings/ctype-utf8.c
Use LINT_INIT() to remove compiler warnings
support-files/compiler_warnings.supp
Suppress some not relevant warnings
unittest/mysys/waiting_threads-t.c
Don't use ftruncate() as this gives warning about ignored return value
=== modified file 'extra/comp_err.c'
--- a/extra/comp_err.c 2009-11-20 10:11:31 +0000
+++ b/extra/comp_err.c 2010-03-30 12:36:49 +0000
@@ -660,7 +660,7 @@ static ha_checksum checksum_format_speci
case 'u':
case 'x':
case 's':
- chksum= my_checksum(chksum, start, (uint) (p + 1 - start));
+ chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start));
start= 0; /* Not in format specifier anymore */
break;
=== modified file 'extra/libevent/kqueue.c'
--- a/extra/libevent/kqueue.c 2009-03-12 22:27:35 +0000
+++ b/extra/libevent/kqueue.c 2010-03-30 12:36:49 +0000
@@ -144,7 +144,7 @@ kq_init(struct event_base *base)
*/
if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
- kqueueop->events[0].ident != -1 ||
+ ((int) kqueueop->events[0].ident) != -1 ||
kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue; not using.", __func__);
free(kqueueop->changes);
=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm 2010-01-15 15:27:55 +0000
+++ b/mysql-test/lib/mtr_cases.pm 2010-03-30 12:36:49 +0000
@@ -681,6 +681,8 @@ sub optimize_cases {
if ( $default_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
if ( $default_engine =~ /^innodb/i );
+ $tinfo->{'pbxt_test'}= 1
+ if ( $default_engine =~ /^pbxt/i );
}
}
@@ -778,6 +780,8 @@ sub collect_one_test_case {
my $disabled= shift;
my $suite_opts= shift;
+ my $local_default_storage_engine= $default_storage_engine;
+
#print "collect_one_test_case\n";
#print " suitedir: $suitedir\n";
#print " testdir: $testdir\n";
@@ -932,15 +936,26 @@ sub collect_one_test_case {
tags_from_test_file($tinfo,"$testdir/${tname}.test");
- if ( defined $default_storage_engine )
+ # Get default storage engine from suite.opt file
+
+ if (defined $suite_opts &&
+ "@$suite_opts" =~ "default-storage-engine=\s*([^\s]*)")
+ {
+ $local_default_storage_engine= $1;
+ }
+
+ if ( defined $local_default_storage_engine )
{
# Different default engine is used
# tag test to require that engine
$tinfo->{'ndb_test'}= 1
- if ( $default_storage_engine =~ /^ndb/i );
+ if ( $local_default_storage_engine =~ /^ndb/i );
$tinfo->{'innodb_test'}= 1
- if ( $default_storage_engine =~ /^innodb/i );
+ if ( $local_default_storage_engine =~ /^innodb/i );
+
+ $tinfo->{'pbxt_test'}= 1
+ if ( $local_default_storage_engine =~ /^pbxt/i );
}
@@ -1103,6 +1118,28 @@ sub collect_one_test_case {
$tinfo->{template_path}= $config;
}
+ if ( $tinfo->{'pbxt_test'} )
+ {
+ # This is a test that needs pbxt
+ if ( $::mysqld_variables{'pbxt'} eq "OFF" ||
+ ! exists $::mysqld_variables{'pbxt'} )
+ {
+ # Engine is not supported, skip it
+ $tinfo->{'skip'}= 1;
+ return $tinfo;
+ }
+ }
+ else
+ {
+ # Only disable engine if it's on by default (to avoid warnings about
+ # not existing loose options
+ if ( $::mysqld_variables{'pbxt'} eq "ON")
+ {
+ push(@{$tinfo->{'master_opt'}}, "--loose-skip-pbxt");
+ push(@{$tinfo->{'slave_opt'}}, "--loose-skip-pbxt");
+ }
+ }
+
if ( $tinfo->{'example_plugin_test'} )
{
if ( !$ENV{'EXAMPLE_PLUGIN'} )
@@ -1156,6 +1193,7 @@ my @tags=
["include/have_log_bin.inc", "need_binlog", 1],
["include/have_innodb.inc", "innodb_test", 1],
+ ["include/have_pbxt.inc", "pbxt_test", 1],
["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1],
["include/have_ndb.inc", "ndb_test", 1],
=== added file 'mysql-test/suite/pbxt/t/suite.opt'
--- a/mysql-test/suite/pbxt/t/suite.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/pbxt/t/suite.opt 2010-03-30 12:36:49 +0000
@@ -0,0 +1 @@
+--default-storage-engine=pbxt
=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c 2009-12-03 11:19:05 +0000
+++ b/mysys/mf_keycache.c 2010-03-30 12:36:49 +0000
@@ -3924,6 +3924,12 @@ restart:
uint next_status;
uint hash_requests;
+ LINT_INIT(next_hash_link);
+ LINT_INIT(next_diskpos);
+ LINT_INIT(next_file);
+ LINT_INIT(next_status);
+ LINT_INIT(hash_requests);
+
total_found++;
found++;
KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used);
=== modified file 'mysys/my_gethostbyname.c'
--- a/mysys/my_gethostbyname.c 2006-12-31 00:32:21 +0000
+++ b/mysys/my_gethostbyname.c 2010-03-30 12:36:49 +0000
@@ -91,9 +91,12 @@ extern pthread_mutex_t LOCK_gethostbynam
is finished with the structure.
*/
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
+struct hostent *
+my_gethostbyname_r(const char *name,
+ struct hostent *result __attribute__((unused)),
+ char *buffer __attribute__((unused)),
+ int buflen__attribute__((unused)),
+ int *h_errnop)
{
struct hostent *hp;
pthread_mutex_lock(&LOCK_gethostbyname_r);
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2010-03-08 13:57:32 +0000
+++ b/sql/handler.cc 2010-03-30 12:36:49 +0000
@@ -4129,7 +4129,7 @@ int handler::read_multi_range_first(KEY_
*/
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
- int result;
+ int result= 0;
DBUG_ENTER("handler::read_multi_range_next");
/* We should not be called after the last call returned EOF. */
=== modified file 'sql/item.h'
--- a/sql/item.h 2010-03-28 18:10:00 +0000
+++ b/sql/item.h 2010-03-30 12:36:49 +0000
@@ -1077,7 +1077,8 @@ class Field_enumerator
{
public:
virtual void visit_field(Field *field)= 0;
- virtual ~Field_enumerator() {}; /* purecov: inspected */
+ virtual ~Field_enumerator() {}; /* purecov: inspected */
+ Field_enumerator() {} /* Remove gcc warning */
};
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-10 09:12:23 +0000
+++ b/sql/mysqld.cc 2010-03-30 12:36:49 +0000
@@ -8323,6 +8323,8 @@ mysqld_get_one_option(int optid,
case (int) OPT_INIT_RPL_ROLE:
{
int role;
+ LINT_INIT(role);
+
if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role))
{
rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
@@ -8378,6 +8380,8 @@ mysqld_get_one_option(int optid,
case OPT_BINLOG_FORMAT:
{
int id;
+ LINT_INIT(id);
+
if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id))
{
global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
@@ -8628,6 +8632,8 @@ mysqld_get_one_option(int optid,
else
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type))
delay_key_write_options= (uint) type-1;
}
@@ -8639,6 +8645,8 @@ mysqld_get_one_option(int optid,
case OPT_TX_ISOLATION:
{
int type;
+ LINT_INIT(type);
+
if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type))
global_system_variables.tx_isolation= (type-1);
break;
@@ -8726,6 +8734,7 @@ mysqld_get_one_option(int optid,
ulong method_conv;
int method;
LINT_INIT(method_conv);
+ LINT_INIT(method);
myisam_stats_method_str= argument;
if (!find_opt_type(argument, &myisam_stats_method_typelib,
@@ -8788,6 +8797,7 @@ mysqld_get_one_option(int optid,
case OPT_THREAD_HANDLING:
{
int id;
+ LINT_INIT(id);
if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id))
global_system_variables.thread_handling= id - 1;
opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-04 08:03:07 +0000
+++ b/sql/sql_class.h 2010-03-30 12:36:49 +0000
@@ -63,6 +63,7 @@ public:
bool report_error(THD *thd);
bool is_invalidated() const { return m_invalidated; }
void reset_reprepare_observer() { m_invalidated= FALSE; }
+ Reprepare_observer() {} /* Remove gcc warning */
private:
bool m_invalidated;
};
@@ -1107,6 +1108,7 @@ public:
/* Ignore error */
return TRUE;
}
+ Dummy_error_handler() {} /* Remove gcc warning */
};
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_table.cc 2010-03-30 12:36:49 +0000
@@ -5668,6 +5668,10 @@ compare_tables(TABLE *table,
*/
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
uint db_options= 0; /* not used */
+
+ /* Set default value for return value (to ensure it's always set) */
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+
/* Create the prepared information. */
if (mysql_prepare_create_table(thd, create_info,
&tmp_alter_info,
@@ -5726,7 +5730,6 @@ compare_tables(TABLE *table,
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
{
DBUG_PRINT("info", ("Basic checks -> ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5756,7 +5759,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("NULL behaviour difference in field '%s' -> "
"ALTER_TABLE_DATA_CHANGED", new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
@@ -5779,7 +5781,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED",
new_field->field_name));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
// Clear indexed marker
@@ -5914,7 +5915,6 @@ compare_tables(TABLE *table,
{
DBUG_PRINT("info", ("check_if_incompatible_data() -> "
"ALTER_TABLE_DATA_CHANGED"));
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
DBUG_RETURN(0);
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-03-04 08:03:07 +0000
+++ b/sql/sql_view.cc 2010-03-30 12:36:49 +0000
@@ -1034,10 +1034,12 @@ bool mysql_make_view(THD *thd, File_pars
bool parse_status;
bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables);
-
DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
+ LINT_INIT(parse_status);
+ LINT_INIT(view_select);
+
if (table->view)
{
/*
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2010-03-10 10:32:14 +0000
+++ b/storage/maria/ma_loghandler.c 2010-03-30 12:36:49 +0000
@@ -1211,6 +1211,8 @@ static my_bool translog_set_lsn_for_file
for (file= from_file; file <= to_file; file++)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT(info.max_lsn);
+
File fd= open_logfile_by_number_no_cache(file);
if ((fd < 0) ||
((translog_read_file_header(&info, fd) ||
@@ -3845,6 +3847,8 @@ my_bool translog_init_with_table(const c
if (!old_log_was_recovered && old_flags == flags)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT(info.maria_version);
+
/*
Accessing &log_descriptor.open_files without mutex is safe
because it is initialization
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2010-03-04 08:03:07 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2010-03-30 12:36:49 +0000
@@ -382,7 +382,7 @@ static MI_INFO *myisammrg_attach_childre
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
}
DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d",
- my_errno ? NULL : (long) myisam, my_errno));
+ my_errno ? 0L : (long) myisam, my_errno));
err:
DBUG_RETURN(my_errno ? NULL : myisam);
=== modified file 'storage/myisammrg/myrg_open.c'
--- a/storage/myisammrg/myrg_open.c 2009-09-23 13:21:29 +0000
+++ b/storage/myisammrg/myrg_open.c 2010-03-30 12:36:49 +0000
@@ -239,6 +239,7 @@ MYRG_INFO *myrg_parent_open(const char *
rc= 1;
errpos= 0;
bzero((char*) &file_cache, sizeof(file_cache));
+ LINT_INIT(m_info);
/* Open MERGE meta file. */
if ((fd= my_open(fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT,
=== modified file 'storage/xtradb/include/ut0lst.h'
--- a/storage/xtradb/include/ut0lst.h 2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0lst.h 2010-03-30 12:36:49 +0000
@@ -158,7 +158,7 @@ Inserts a NODE2 after NODE1 in a list.
/** Invalidate the pointers in a list node.
@param NAME list name
@param N pointer to the node that was removed */
-# define UT_LIST_REMOVE_CLEAR(NAME, N) while (0)
+# define UT_LIST_REMOVE_CLEAR(NAME, N) {} while (0)
#endif
/*******************************************************************//**
=== modified file 'strings/ctype-ucs2.c'
--- a/strings/ctype-ucs2.c 2010-03-04 08:03:07 +0000
+++ b/strings/ctype-ucs2.c 2010-03-30 12:36:49 +0000
@@ -203,7 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
@@ -317,7 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_I
const char *s, const char *t, size_t len)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const char *se=s+len;
const char *te=t+len;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
@@ -1384,7 +1384,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
=== modified file 'strings/ctype-utf8.c'
--- a/strings/ctype-utf8.c 2009-10-15 21:38:29 +0000
+++ b/strings/ctype-utf8.c 2010-03-30 12:36:49 +0000
@@ -2310,7 +2310,7 @@ static int my_strnncoll_utf8(CHARSET_INF
my_bool t_is_prefix)
{
int s_res,t_res;
- my_wc_t UNINIT_VAR(s_wc), t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se=s+slen;
const uchar *te=t+tlen;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
@@ -2380,7 +2380,7 @@ static int my_strnncollsp_utf8(CHARSET_I
my_bool diff_if_only_endspace_difference)
{
int s_res, t_res, res;
- my_wc_t UNINIT_VAR(s_wc),t_wc;
+ my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
const uchar *se= s+slen, *te= t+tlen;
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2010-03-29 19:07:45 +0000
+++ b/support-files/compiler_warnings.supp 2010-03-30 12:36:49 +0000
@@ -72,6 +72,11 @@ db_vrfy.c : .*comparison is always false
.*: break strict-aliasing rules
#
+# Ignore not important declaration warnings
+#
+.*: only defines private constructors and has no friends
+
+#
# Ignore all conversion warnings on windows 64
# (Is safe as we are not yet supporting strings >= 2G)
#
@@ -106,6 +111,11 @@ db_vrfy.c : .*comparison is always false
storage/maria/ma_pagecache.c: .*'info_check_pin' defined but not used
#
+# Pbxt
+#
+xaction_xt\.cc: may be used uninitialized in this function
+
+#
# I think these are due to mix of C and C++.
#
storage/pbxt/ : typedef.*was ignored in this declaration
@@ -118,6 +128,7 @@ include/runtime.hpp: .*pure_error.*
.*/extra/yassl/taocrypt/src/blowfish\.cpp: array subscript is above array bounds
.*/extra/yassl/taocrypt/src/file\.cpp: ignoring return value
.*/extra/yassl/taocrypt/src/integer\.cpp: control reaches end of non-void function
+mySTL/algorithm\.hpp: is used uninitialized in this function
#
# Groff warnings on OpenSUSE.
=== modified file 'unittest/mysys/waiting_threads-t.c'
--- a/unittest/mysys/waiting_threads-t.c 2010-01-28 14:49:14 +0000
+++ b/unittest/mysys/waiting_threads-t.c 2010-03-30 12:36:49 +0000
@@ -258,7 +258,7 @@ void do_tests()
#define test_kill_strategy(X) \
diag("kill strategy: " #X); \
DBUG_EXECUTE("reset_file", \
- { rewind(DBUG_FILE); (void) ftruncate(fileno(DBUG_FILE), 0); }); \
+ { rewind(DBUG_FILE); my_chsize(fileno(DBUG_FILE), 0, 0, MYF(MY_WME)); }); \
DBUG_PRINT("info", ("kill strategy: " #X)); \
kill_strategy=X; \
do_one_test();
1
0

[Maria-developers] Rev 2760: Compiler warnings removed. in file:///Users/bell/maria/bzr/work-maria-5.2-warnings/
by sanja@askmonty.org 30 Mar '10
by sanja@askmonty.org 30 Mar '10
30 Mar '10
At file:///Users/bell/maria/bzr/work-maria-5.2-warnings/
------------------------------------------------------------
revno: 2760
revision-id: sanja(a)askmonty.org-20100330123515-4p8q03xccl3d6k59
parent: sanja(a)askmonty.org-20100330084125-f0ch43jawtcd5p3x
committer: sanja(a)askmonty.org
branch nick: work-maria-5.2-warnings
timestamp: Tue 2010-03-30 15:35:15 +0300
message:
Compiler warnings removed.
=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c 2010-03-30 08:41:25 +0000
+++ b/storage/maria/ma_loghandler.c 2010-03-30 12:35:15 +0000
@@ -1275,6 +1275,7 @@
{
LOGHANDLER_FILE_INFO info;
File fd= open_logfile_by_number_no_cache(file);
+ LINT_INIT_STRUCT(info);
if ((fd < 0) ||
((translog_read_file_header(&info, fd) ||
(cmp_translog_addr(lsn, info.max_lsn) > 0 &&
@@ -1457,8 +1458,8 @@
{
LOGHANDLER_FILE_INFO info;
+ File fd= open_logfile_by_number_no_cache(file);
LINT_INIT_STRUCT(info);
- File fd= open_logfile_by_number_no_cache(file);
if ((fd < 0) ||
(translog_read_file_header(&info, fd) | my_close(fd, MYF(MY_WME))))
{
@@ -3966,6 +3967,7 @@
if (!old_log_was_recovered && old_flags == flags)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT_STRUCT(info);
/*
Accessing &log_descriptor.open_files without mutex is safe
because it is initialization
@@ -8974,6 +8976,7 @@
{
LOGHANDLER_FILE_INFO desc;
char strbuff[21];
+ LINT_INIT_STRUCT(desc);
translog_interpret_file_header(&desc, buff);
printf(" This can be header page:\n"
" Timestamp: %s\n"
1
0

[Maria-developers] Rev 2758: test in http://bazaar.launchpad.net/~maria-captains/maria/5.2/
by serg@askmonty.org 30 Mar '10
by serg@askmonty.org 30 Mar '10
30 Mar '10
At http://bazaar.launchpad.net/~maria-captains/maria/5.2/
------------------------------------------------------------
revno: 2758
revision-id: sergii(a)pisem.net-20100330115617-a99qg0idjjbpx01d
parent: sergii(a)pisem.net-20100329151428-zkvrkidiyqmb19pn
committer: Sergei Golubchik <sergii(a)pisem.net>
branch nick: 5.2
timestamp: Tue 2010-03-30 13:56:17 +0200
message:
test
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-29 15:13:53 +0000
+++ b/sql/mysqld.cc 2010-03-30 11:56:17 +0000
@@ -4720,6 +4720,8 @@ we force server id to 2, but this MySQL
#endif
#endif /* __WIN__ */
+#error TEST
+
/* Wait until cleanup is done */
(void) pthread_mutex_lock(&LOCK_thread_count);
while (!ready_to_exit)
1
0