summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SSL/Makefile.am4
-rw-r--r--SSL/NOTES62
-rw-r--r--SSL/cacert.pem34
-rw-r--r--SSL/client-cert.pem87
-rw-r--r--SSL/client-key.pem20
-rw-r--r--SSL/client-req.pem12
-rw-r--r--SSL/server-cert.pem89
-rw-r--r--SSL/server-key.pem20
-rw-r--r--SSL/server-req.pem12
-rw-r--r--client/client_priv.h2
-rw-r--r--client/mysql.cc14
-rw-r--r--client/mysqladmin.cc2
-rw-r--r--client/mysqlbinlog.cc6
-rw-r--r--client/mysqldump.c2
-rw-r--r--client/mysqlimport.c2
-rw-r--r--client/mysqlshow.c2
-rw-r--r--client/mysqltest.c42
-rw-r--r--config/ac-macros/openssl.m410
-rw-r--r--config/ac-macros/zlib.m49
-rw-r--r--dbug/dbug.c84
-rw-r--r--extra/yassl/README35
-rw-r--r--extra/yassl/certs/ca-cert.pem53
-rw-r--r--extra/yassl/certs/client-cert.derbin0 -> 699 bytes
-rw-r--r--extra/yassl/certs/client-cert.pem52
-rw-r--r--extra/yassl/certs/client-key.derbin0 -> 318 bytes
-rw-r--r--extra/yassl/certs/client-key.pem9
-rw-r--r--extra/yassl/certs/dh1024.dat1
-rw-r--r--extra/yassl/certs/dsa-cert.pem68
-rw-r--r--extra/yassl/certs/dsa512.derbin0 -> 250 bytes
-rw-r--r--extra/yassl/certs/dsa512.pem8
-rw-r--r--extra/yassl/certs/server-cert.pem38
-rw-r--r--extra/yassl/certs/server-key.pem9
-rw-r--r--extra/yassl/certs/taoCert.txt50
-rw-r--r--extra/yassl/examples/client/client.cpp8
-rw-r--r--extra/yassl/examples/echoclient/echoclient.cpp1
-rw-r--r--extra/yassl/examples/echoserver/echoserver.cpp2
-rw-r--r--extra/yassl/examples/server/server.cpp2
-rw-r--r--extra/yassl/include/openssl/err.h2
-rw-r--r--extra/yassl/include/openssl/md4.h1
-rw-r--r--extra/yassl/include/openssl/md5.h3
-rw-r--r--extra/yassl/include/openssl/pem.h1
-rw-r--r--extra/yassl/include/openssl/ssl.h125
-rw-r--r--extra/yassl/include/openssl/x509.h1
-rw-r--r--extra/yassl/include/openssl/x509v3.h1
-rw-r--r--extra/yassl/include/yassl_int.hpp41
-rw-r--r--extra/yassl/include/yassl_types.hpp4
-rw-r--r--extra/yassl/lib/dummy1
-rw-r--r--extra/yassl/mySTL/helpers.hpp5
-rw-r--r--extra/yassl/src/cert_wrapper.cpp9
-rw-r--r--extra/yassl/src/make.bat2
-rw-r--r--extra/yassl/src/ssl.cpp382
-rw-r--r--extra/yassl/src/template_instnt.cpp6
-rw-r--r--extra/yassl/src/yassl_imp.cpp4
-rw-r--r--extra/yassl/src/yassl_int.cpp105
-rw-r--r--extra/yassl/taocrypt/benchmark/make.bat5
-rw-r--r--extra/yassl/taocrypt/include/asn.hpp25
-rw-r--r--extra/yassl/taocrypt/include/runtime.hpp4
-rw-r--r--extra/yassl/taocrypt/src/asn.cpp74
-rw-r--r--extra/yassl/taocrypt/src/integer.cpp6
-rw-r--r--extra/yassl/taocrypt/src/make.bat3
-rw-r--r--extra/yassl/taocrypt/src/misc.cpp9
-rw-r--r--extra/yassl/taocrypt/src/template_instnt.cpp2
-rw-r--r--extra/yassl/taocrypt/taocrypt.dsp3
-rw-r--r--extra/yassl/taocrypt/test/make.bat2
-rw-r--r--extra/yassl/testsuite/make.bat2
-rw-r--r--extra/yassl/testsuite/test.hpp6
-rw-r--r--extra/yassl/testsuite/testsuite.cpp7
-rw-r--r--extra/yassl/testsuite/testsuite.dsp4
-rw-r--r--include/my_dbug.h3
-rw-r--r--include/my_pthread.h6
-rw-r--r--include/my_sys.h1
-rw-r--r--include/mysql.h4
-rw-r--r--include/sslopt-longopts.h7
-rw-r--r--include/sslopt-vars.h3
-rw-r--r--include/violite.h25
-rw-r--r--innobase/os/os0file.c63
-rw-r--r--libmysql/libmysql.c3
-rw-r--r--mysql-test/Makefile.am10
-rw-r--r--mysql-test/lib/mtr_process.pl20
-rwxr-xr-xmysql-test/mysql-test-run.pl136
-rw-r--r--mysql-test/r/blackhole.result8
-rw-r--r--mysql-test/r/case.result8
-rw-r--r--mysql-test/r/distinct.result12
-rw-r--r--mysql-test/r/explain.result4
-rw-r--r--mysql-test/r/func_in.result17
-rw-r--r--mysql-test/r/func_str.result13
-rw-r--r--mysql-test/r/func_time.result19
-rw-r--r--mysql-test/r/group_min_max.result22
-rw-r--r--mysql-test/r/having.result2
-rw-r--r--mysql-test/r/im_options_set.result6
-rw-r--r--mysql-test/r/im_options_unset.result6
-rw-r--r--mysql-test/r/information_schema.result22
-rw-r--r--mysql-test/r/information_schema_chmod.result5
-rw-r--r--mysql-test/r/join.result4
-rw-r--r--mysql-test/r/join_outer.result61
-rw-r--r--mysql-test/r/merge.result8
-rw-r--r--mysql-test/r/metadata.result2
-rw-r--r--mysql-test/r/mysql.result12
-rw-r--r--mysql-test/r/mysqlbinlog.result1
-rw-r--r--mysql-test/r/ndb_autodiscover3.result45
-rw-r--r--mysql-test/r/openssl_1.result11
-rw-r--r--mysql-test/r/outfile.resultbin1130 -> 1159 bytes
-rw-r--r--mysql-test/r/ps_2myisam.result4
-rw-r--r--mysql-test/r/ps_3innodb.result4
-rw-r--r--mysql-test/r/ps_4heap.result4
-rw-r--r--mysql-test/r/ps_5merge.result8
-rw-r--r--mysql-test/r/ps_6bdb.result4
-rw-r--r--mysql-test/r/ps_7ndb.result4
-rw-r--r--mysql-test/r/rpl_temporary.result17
-rw-r--r--mysql-test/r/rpl_until.result148
-rw-r--r--mysql-test/r/select.result35
-rw-r--r--mysql-test/r/sp-error.result4
-rw-r--r--mysql-test/r/sp.result56
-rw-r--r--mysql-test/r/subselect.result16
-rw-r--r--mysql-test/r/trigger-grant.result84
-rw-r--r--mysql-test/r/trigger.result92
-rw-r--r--mysql-test/r/type_float.result8
-rw-r--r--mysql-test/r/type_newdecimal.result14
-rw-r--r--mysql-test/r/variables.result54
-rw-r--r--mysql-test/r/view.result47
-rw-r--r--mysql-test/std_data/untrusted-cacert.pem53
-rw-r--r--mysql-test/t/blackhole.test12
-rw-r--r--mysql-test/t/disabled.def1
-rw-r--r--mysql-test/t/distinct.test16
-rw-r--r--mysql-test/t/explain.test9
-rw-r--r--mysql-test/t/func_in.test12
-rw-r--r--mysql-test/t/func_str.test15
-rw-r--r--mysql-test/t/func_time.test14
-rw-r--r--mysql-test/t/group_min_max.test16
-rw-r--r--mysql-test/t/information_schema.test29
-rw-r--r--mysql-test/t/information_schema_chmod.test20
-rw-r--r--mysql-test/t/join_outer.test44
-rw-r--r--mysql-test/t/merge.test12
-rw-r--r--mysql-test/t/mysql.test8
-rw-r--r--mysql-test/t/mysqlbinlog.test15
-rw-r--r--mysql-test/t/ndb_autodiscover3.test65
-rw-r--r--mysql-test/t/openssl_1.test42
-rw-r--r--mysql-test/t/outfile.test1
-rw-r--r--mysql-test/t/rename.test8
-rw-r--r--mysql-test/t/rpl_temporary.test27
-rw-r--r--mysql-test/t/rpl_until.test8
-rw-r--r--mysql-test/t/select.test34
-rw-r--r--mysql-test/t/sp.test70
-rw-r--r--mysql-test/t/subselect.test24
-rw-r--r--mysql-test/t/trigger-grant.test173
-rw-r--r--mysql-test/t/trigger.test122
-rw-r--r--mysql-test/t/variables-master.opt1
-rw-r--r--mysql-test/t/variables.test65
-rw-r--r--mysql-test/t/view.test55
-rw-r--r--mysql-test/valgrind.supp182
-rw-r--r--mysys/my_init.c4
-rw-r--r--ndb/include/mgmapi/mgmapi_config_parameters.h1
-rw-r--r--ndb/include/ndbapi/ndb_cluster_connection.hpp1
-rw-r--r--ndb/include/util/SocketServer.hpp2
-rw-r--r--ndb/src/common/transporter/Transporter.cpp12
-rw-r--r--ndb/src/common/util/SocketServer.cpp4
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.cpp5
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcInit.cpp2
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp6
-rw-r--r--ndb/src/mgmapi/mgmapi.cpp3
-rw-r--r--ndb/src/mgmsrv/ConfigInfo.cpp14
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.cpp1
-rw-r--r--ndb/src/mgmsrv/Services.cpp6
-rw-r--r--ndb/src/ndbapi/ClusterMgr.cpp5
-rw-r--r--ndb/src/ndbapi/ClusterMgr.hpp1
-rw-r--r--ndb/src/ndbapi/DictCache.cpp36
-rw-r--r--ndb/src/ndbapi/DictCache.hpp3
-rw-r--r--ndb/src/ndbapi/SignalSender.cpp2
-rw-r--r--ndb/src/ndbapi/TransporterFacade.hpp6
-rw-r--r--ndb/src/ndbapi/ndb_cluster_connection.cpp6
-rw-r--r--ndb/src/ndbapi/ndb_cluster_connection_impl.hpp1
-rw-r--r--ndb/test/ndbapi/Makefile.am2
-rw-r--r--ndb/test/ndbapi/testInterpreter.cpp202
-rw-r--r--ndb/tools/waiter.cpp6
-rw-r--r--server-tools/instance-manager/manager.cc13
-rw-r--r--server-tools/instance-manager/manager.h2
-rw-r--r--server-tools/instance-manager/mysqlmanager.cc8
-rw-r--r--server-tools/instance-manager/options.cc59
-rw-r--r--server-tools/instance-manager/options.h1
-rw-r--r--sql-common/client.c126
-rw-r--r--sql/field_conv.cc3
-rw-r--r--sql/ha_blackhole.cc2
-rw-r--r--sql/ha_innodb.cc3
-rw-r--r--sql/ha_myisammrg.cc2
-rw-r--r--sql/ha_ndbcluster.cc17
-rw-r--r--sql/handler.h1
-rw-r--r--sql/item.cc47
-rw-r--r--sql/item.h104
-rw-r--r--sql/item_cmpfunc.cc33
-rw-r--r--sql/item_func.cc29
-rw-r--r--sql/item_func.h12
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/item_strfunc.h2
-rw-r--r--sql/item_subselect.cc12
-rw-r--r--sql/item_subselect.h1
-rw-r--r--sql/item_timefunc.cc13
-rw-r--r--sql/mysql_priv.h21
-rw-r--r--sql/mysqld.cc16
-rw-r--r--sql/opt_range.cc120
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/sp_head.cc241
-rw-r--r--sql/sp_head.h2
-rw-r--r--sql/sp_rcontext.cc13
-rw-r--r--sql/sp_rcontext.h8
-rw-r--r--sql/sql_acl.cc9
-rw-r--r--sql/sql_base.cc163
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_insert.cc147
-rw-r--r--sql/sql_parse.cc3
-rw-r--r--sql/sql_select.cc485
-rw-r--r--sql/sql_show.cc25
-rw-r--r--sql/sql_table.cc103
-rw-r--r--sql/sql_yacc.yy38
-rw-r--r--sql/table.h1
-rw-r--r--sql/udf_example.cc2
-rw-r--r--support-files/mysql.spec.sh10
-rw-r--r--vio/test-ssl.c4
-rw-r--r--vio/test-sslclient.c2
-rw-r--r--vio/test-sslserver.c4
-rw-r--r--vio/vio.c29
-rw-r--r--vio/vio_priv.h22
-rw-r--r--vio/viossl.c402
-rw-r--r--vio/viosslfactories.c309
223 files changed, 5139 insertions, 1888 deletions
diff --git a/SSL/Makefile.am b/SSL/Makefile.am
index bd3aad1e3b2..6edc6146a29 100644
--- a/SSL/Makefile.am
+++ b/SSL/Makefile.am
@@ -17,8 +17,8 @@
## Process this file with automake to create Makefile.in
EXTRA_DIST= NOTES cacert.pem client-cert.pem client-key.pem \
- client-req.pem run-client run-server server-cert.pem \
- server-key.pem server-req.pem
+ run-client run-server server-cert.pem \
+ server-key.pem
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/SSL/NOTES b/SSL/NOTES
index 413c724c583..a1109db8c80 100644
--- a/SSL/NOTES
+++ b/SSL/NOTES
@@ -40,7 +40,69 @@ openssl s_server -port 1111 -cert ../SSL/server-cert.pem -key ../SSL/server-key.
+-------------------------------------------
+How to generate new keys:
+First we need the private key of the CA cert. Since we always throw
+away the old private key for the CA, we need to generate a totally new
+CA cert. Our CA cert is self signed and we will use that to sign the
+server and client keys. As long as we distibute the cacert.pem they can
+b oth be validated against that.
+
+
+1) openssl genrsa 512 > cecert.pem
+
+2) openssl req -new -x509 -nodes -md5 -days 1000 -key cacert.pem > cacert.pem
+
+We now have a cacert.pem which is the public key and a cakey.pem which is the
+private key of the CA.
+
+Steps to generate the server key.
+
+3) openssl req -newkey rsa:512 -md5 -days 1000 -nodes -keyout server-key.pem > server-req.pem
+
+4) copy ca-key.pem ca-cert.srl
+
+5) openssl x509 -req -in server-req.pem -days 1000 -md5 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
+
+
+-- adding metadata to beginning
+
+6) openssl x509 -in server-cert.pem -text > tmp.pem
+
+7) mv tmp.pem server-cert.pem
+
+-- And almost the same for the client.
+
+8) openssl req -newkey rsa:512 -md5 -days 1000 -nodes -keyout client-key.pem > client-req.pem
+
+9) openssl x509 -req -in client-req.pem -days 1000 -md5 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem
+
+
+-- adding metadata to beginning
+
+10) openssl x509 -in client-cert.pem -text > tmp.pem
+
+11) mv tmp.pem client-cert.pem
+
+The new certs are now generated. They can be verified against the cacert to test they are ok. This is actually what is done in the MySQL client and server.
+
+12) openssl verify -CAfile cacert.pem server-cert.pem
+server-cert.pem: OK
+13) openssl verify -CAfile cacert.pem client-cert.pm
+client-cert.pem: OK
+
+
+The files we add to our repository and thus distribute are
+* cacert.pem - CA's public key, used to verify the client/servers pblic keys
+* server-key.pem - servers private key
+* server-cert.pem - servers public key
+* client-key.pem - clients private key
+* client-cert.pem - clients public key
+
+
+
+== OLD NOTES below ==
--------------------------------------------
CA stuff:
diff --git a/SSL/cacert.pem b/SSL/cacert.pem
index a63dae57767..b445e77d7c4 100644
--- a/SSL/cacert.pem
+++ b/SSL/cacert.pem
@@ -1,21 +1,17 @@
-----BEGIN CERTIFICATE-----
-MIIDcTCCAtqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCU0Ux
-EDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhB
-YnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0
-Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wHhcNMDMwOTEyMTYxNDE2WhcNMTMw
-OTA5MTYxNDE2WjCBiDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAP
-BgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhBYnN0cmFjdCBNeVNRTCBEZXZlbG9w
-ZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNx
-bC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKrT7zp5tp5djXp+TEQs
-5ZEds1XUglp/EQUQ1FMMb1Xe6gqJsQ62O+jsUe0nrUjXBrUCUy49k6mcnmQtZREj
-l1pWKmzx1fgcYpxTwxaY7IKB2jik5IWprhVPmSQ+AWss43oolXMZWR+csKehqm3j
-+YNZc9NsR4ydE71l0VEtJEQvAgMBAAGjgegwgeUwHQYDVR0OBBYEFIiYZdnz8osD
-HWZgYSP6rXNt02iSMIG1BgNVHSMEga0wgaqAFIiYZdnz8osDHWZgYSP6rXNt02iS
-oYGOpIGLMIGIMQswCQYDVQQGEwJTRTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UE
-ChMITXlTUUwgQUIxITAfBgNVBAMTGEFic3RyYWN0IE15U1FMIERldmVsb3BlcjEx
-MC8GCSqGSIb3DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNv
-bYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAGIL22MCIU/0sKDp
-pZIhoabvNVDTfuhtene+WBCrzCzGXPZjB4+b/KAJJNvOR4zi43Kk7euu+PENs9M7
-nKpInMdhvT1RcCnUHJ3jBCvDDzXab2msqn3rxhwetWWbfE0OeEn/PoQcwiZCe7x5
-h+Zz+oUbvsEe4DjtDVgG4UH9nSSS
+MIICrTCCAhagAwIBAgIJAIAO/Ybiptv1MA0GCSqGSIb3DQEBBAUAMEQxCzAJBgNV
+BAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYD
+VQQKEwhNeVNRTCBBQjAeFw0wNjA1MDMwODQ4NTRaFw0wOTAxMjcwODQ4NTRaMEQx
+CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxh
+MREwDwYDVQQKEwhNeVNRTCBBQjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
++C46EQl1u7tQ6gb9eqc8V079gr8YmDPCEqtjO8bCIbchpjOpDITx0WZz36Sn9E72
+GPJwNip4FxLaPRIA3xNQHM5cE5U53qznlRx1Fc4O3hcWCvyCqNDl/vzPAh3pI6Bl
+Ku9hfHXpp93W812smVPe9haShEXGgbEPYGzvOfVdu/MCAwEAAaOBpjCBozAdBgNV
+HQ4EFgQUjIy/6OCTmqtPHBFha6/qzVk3yTcwdAYDVR0jBG0wa4AUjIy/6OCTmqtP
+HBFha6/qzVk3yTehSKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxh
+MRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAIAO/Ybiptv1
+MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEA8lD9zyB820Oq1aj7ZafX
+De/hbdt9RIl2tzgw2K3r1KZGdXJVL0vSt5fZ51Nq9lg7OPJy3iXf+caBJEp0IJpB
+uf4Gfr6zfXw+UlY6ZthRtHQHoXKcbskECjH5/ps/Uaa+dpVQ9O+Ii1rPzmgo6ztM
+s+xZ46ESBt4WiHXm8kwbU9Y=
-----END CERTIFICATE-----
diff --git a/SSL/client-cert.pem b/SSL/client-cert.pem
index 4c81162c911..fdd5c86a23f 100644
--- a/SSL/client-cert.pem
+++ b/SSL/client-cert.pem
@@ -1,67 +1,42 @@
Certificate:
Data:
- Version: 3 (0x2)
+ Version: 1 (0x0)
Serial Number: 1 (0x1)
Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SE, L=Uppsala, O=MySQL AB, CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
+ Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB
Validity
- Not Before: Sep 12 16:21:19 2003 GMT
- Not After : Sep 9 16:21:19 2013 GMT
- Subject: C=SE, L=Uppsala, O=MySQL AB, CN=MySQL Client/Email=abstract.mysql.developer@mysql.com
+ Not Before: May 3 08:55:39 2006 GMT
+ Not After : Jan 27 08:55:39 2009 GMT
+ Subject: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:c4:03:0a:ee:e3:b1:12:fc:ee:b4:19:f4:e1:60:
- 1d:e0:28:c3:96:2d:df:82:69:cd:74:7c:54:58:d0:
- ae:b3:59:3f:0c:19:1c:99:10:a6:12:c9:cf:3a:64:
- 05:43:8e:bf:d2:65:36:80:91:0b:65:b0:27:26:38:
- c9:23:d8:36:a2:4a:f0:f7:c0:2f:68:38:70:01:27:
- 29:ff:b2:c5:52:e1:6b:f1:c8:d7:c3:5c:ee:f0:37:
- 6c:2a:9b:96:1a:05:9e:eb:33:a2:39:5a:77:66:62:
- 27:75:1f:2f:6f:38:da:e5:9f:78:af:ca:6b:22:3f:
- 57:2b:bc:a6:8f:47:d1:99:6f
+ RSA Public Key: (512 bit)
+ Modulus (512 bit):
+ 00:d8:db:68:28:49:84:4d:d6:0f:5c:bc:3d:9a:ab:
+ 70:d5:3e:f5:b5:17:ba:ef:e1:f8:87:54:30:22:1f:
+ 81:07:bf:f9:24:7f:8a:54:10:e9:5f:e6:99:50:04:
+ d4:3b:55:a9:f1:52:ad:12:2b:5a:da:5c:be:8c:3e:
+ 5b:9e:b0:5a:19
Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
- X509v3 Subject Key Identifier:
- 80:81:A9:22:EB:AB:D6:CA:7E:3F:8D:BB:D1:AC:2A:F4:87:9D:13:29
- X509v3 Authority Key Identifier:
- keyid:88:98:65:D9:F3:F2:8B:03:1D:66:60:61:23:FA:AD:73:6D:D3:68:92
- DirName:/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
- serial:00
-
Signature Algorithm: md5WithRSAEncryption
- 86:17:1c:f3:9f:10:1b:75:47:03:ca:54:ea:ef:f7:15:54:8d:
- 8f:58:c9:64:7d:de:2e:bf:ea:a6:5d:72:56:c9:81:be:bb:1c:
- 78:a5:91:d6:f8:77:df:9d:d2:cb:94:d9:06:61:4f:05:21:22:
- 2a:ea:9e:c3:8b:4d:fe:94:c7:98:61:cd:7e:88:19:c9:92:01:
- 1f:10:5b:c6:16:95:99:9b:32:01:3a:89:df:fa:0a:89:ac:fa:
- b5:40:55:7a:ca:0a:bd:5d:8b:06:d8:7e:e1:44:8c:70:c8:63:
- c7:77:6a:37:3d:a4:ac:57:dc:00:c1:c1:f3:72:17:5b:50:95:
- ee:b7
+ 07:57:bf:07:92:c2:8e:86:24:6b:0a:bf:e5:31:21:44:c3:60:
+ 02:a6:ac:9e:f7:db:7a:6e:fc:4f:d4:7b:54:18:80:47:d2:4a:
+ 63:0e:e3:f8:af:6e:58:e3:97:5a:2b:82:5d:76:20:d1:33:a0:
+ f5:43:a1:d1:51:f4:ca:c8:b3:1a:66:4e:0e:55:df:d2:e8:fa:
+ 83:18:42:f5:ec:66:40:f0:39:e8:f9:d7:cf:f6:dd:e4:7b:69:
+ dd:0c:92:d8:52:95:43:6f:29:3d:f0:8d:4c:dd:52:ea:6b:a0:
+ 39:0f:dc:59:a7:5c:37:6b:8b:05:44:b7:69:ea:a3:58:e0:4e:
+ ce:d6
-----BEGIN CERTIFICATE-----
-MIIDkTCCAvqgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCU0Ux
-EDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhB
-YnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0
-Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wHhcNMDMwOTEyMTYyMTE5WhcNMTMw
-OTA5MTYyMTE5WjB8MQswCQYDVQQGEwJTRTEQMA4GA1UEBxMHVXBwc2FsYTERMA8G
-A1UEChMITXlTUUwgQUIxFTATBgNVBAMTDE15U1FMIENsaWVudDExMC8GCSqGSIb3
-DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNvbTCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEAxAMK7uOxEvzutBn04WAd4CjDli3fgmnNdHxU
-WNCus1k/DBkcmRCmEsnPOmQFQ46/0mU2gJELZbAnJjjJI9g2okrw98AvaDhwAScp
-/7LFUuFr8cjXw1zu8DdsKpuWGgWe6zOiOVp3ZmIndR8vbzja5Z94r8prIj9XK7ym
-j0fRmW8CAwEAAaOCARQwggEQMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w
-ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSAgaki66vWyn4/
-jbvRrCr0h50TKTCBtQYDVR0jBIGtMIGqgBSImGXZ8/KLAx1mYGEj+q1zbdNokqGB
-jqSBizCBiDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoT
-CE15U1FMIEFCMSEwHwYDVQQDExhBYnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAv
-BgkqhkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb22C
-AQAwDQYJKoZIhvcNAQEEBQADgYEAhhcc858QG3VHA8pU6u/3FVSNj1jJZH3eLr/q
-pl1yVsmBvrsceKWR1vh3353Sy5TZBmFPBSEiKuqew4tN/pTHmGHNfogZyZIBHxBb
-xhaVmZsyATqJ3/oKiaz6tUBVesoKvV2LBth+4USMcMhjx3dqNz2krFfcAMHB83IX
-W1CV7rc=
+MIIB5jCCAU8CAQEwDQYJKoZIhvcNAQEEBQAwRDELMAkGA1UEBhMCU0UxEDAOBgNV
+BAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFC
+MB4XDTA2MDUwMzA4NTUzOVoXDTA5MDEyNzA4NTUzOVowdzELMAkGA1UEBhMCU0Ux
+EDAOBgNVBAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15
+U1FMIEFCMTEwLwYJKoZIhvcNAQkBFiJhYnN0cmFjdC5teXNxbC5kZXZlbG9wZXJA
+bXlzcWwuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANjbaChJhE3WD1y8PZqr
+cNU+9bUXuu/h+IdUMCIfgQe/+SR/ilQQ6V/mmVAE1DtVqfFSrRIrWtpcvow+W56w
+WhkCAwEAATANBgkqhkiG9w0BAQQFAAOBgQAHV78HksKOhiRrCr/lMSFEw2ACpqye
+99t6bvxP1HtUGIBH0kpjDuP4r25Y45daK4JddiDRM6D1Q6HRUfTKyLMaZk4OVd/S
+6PqDGEL17GZA8Dno+dfP9t3ke2ndDJLYUpVDbyk98I1M3VLqa6A5D9xZp1w3a4sF
+RLdp6qNY4E7O1g==
-----END CERTIFICATE-----
diff --git a/SSL/client-key.pem b/SSL/client-key.pem
index 58fa805e620..22f8e23ab2a 100644
--- a/SSL/client-key.pem
+++ b/SSL/client-key.pem
@@ -1,15 +1,9 @@
-----BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDEAwru47ES/O60GfThYB3gKMOWLd+Cac10fFRY0K6zWT8MGRyZ
-EKYSyc86ZAVDjr/SZTaAkQtlsCcmOMkj2DaiSvD3wC9oOHABJyn/ssVS4WvxyNfD
-XO7wN2wqm5YaBZ7rM6I5WndmYid1Hy9vONrln3ivymsiP1crvKaPR9GZbwIDAQAB
-AoGAcR7IaoGhKbIrGGl6d67+zuT3q24h9aOV3Mn7653TlNHGnvbHGFcRYPpyy+H5
-X7m8XnHm+F+80hzNGzPecP9Q12oPOyoZgeQn6bTK73OFkNcX7FAkNdyH4xVhf2aK
-YOzTcQfq3gRCqXtVIg4qBShTMjJLE31R8H430Or62XmJgFECQQDjP+Kz+ecQwuTB
-HADLm+GQgceIB1kLgdQoZ3deUxGvqtVImuDRViSM0F2srfJ4GfkEDhc27UI5f6ir
-ZTOw4ww7AkEA3M9wCPgWNtbOXbYjaNA0IzHcjMDxQDVvJAmb3EiZlKQp4EfrESxR
-ly/u08TyfwrK6q5WS7xE0ad8+95G1af4XQJBAI9+3ME20SB1YItMCniHYwSj3oHX
-2fN5NKWax/Zoz+c0IV+qZMHq+kNso2oRoOUTyXk1CJWndcTnBnPMALr2c9cCQQCZ
-VL7Cq6uZVx6kemcqUHH0AprZbt3YLYLI7pc5p3xmeHzPzoEQQstBhjp8+aU+zPrN
-blRkcQ8E2x5yNA7SLLrNAkAhzkA+EK8hc0f9W3ncy+py0Rn0i5Ay0N3T715vkThf
-CfOHE3L91dLlmYpL5xVqOpugY/2sHyxwctv97DgS6tHZ
+MIIBOgIBAAJBANjbaChJhE3WD1y8PZqrcNU+9bUXuu/h+IdUMCIfgQe/+SR/ilQQ
+6V/mmVAE1DtVqfFSrRIrWtpcvow+W56wWhkCAwEAAQJAK27WT6tZylUjQomZNQ89
+TBiOEbUtBbqWklQ0R8FTkH9uKV+8KYQ+k+tMkoAEGFfChB0YfofNQ2KZYWWw4yOB
+WQIhAPXXDQt73aou10s+cmKM3C3WzLmIZtrvm9wNBXWDGxgTAiEA4dG4cXrZfa1M
+TTbjzNU1/Jf50/M8SvZDWMPQWxJ8oqMCIH6zBpYUkHlVCsBMvsbrsc4uFfTIx7mu
+I7WVQGr/1sbhAiBf4uFirjtztgZUMx5/d3k5DH80lG/hlLf8FQl/4lWx6QIhAPHw
+CXfPUbUFl4r/i9Br5+exGol50qX4F3aP5Sh5EnZT
-----END RSA PRIVATE KEY-----
diff --git a/SSL/client-req.pem b/SSL/client-req.pem
deleted file mode 100644
index b3667fb5ec6..00000000000
--- a/SSL/client-req.pem
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN CERTIFICATE REQUEST-----
-MIIBvDCCASUCAQAwfDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAP
-BgNVBAoTCE15U1FMIEFCMRUwEwYDVQQDEwxNeVNRTCBDbGllbnQxMTAvBgkqhkiG
-9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBAMQDCu7jsRL87rQZ9OFgHeAow5Yt34JpzXR8
-VFjQrrNZPwwZHJkQphLJzzpkBUOOv9JlNoCRC2WwJyY4ySPYNqJK8PfAL2g4cAEn
-Kf+yxVLha/HI18Nc7vA3bCqblhoFnuszojlad2ZiJ3UfL2842uWfeK/KayI/Vyu8
-po9H0ZlvAgMBAAGgADANBgkqhkiG9w0BAQQFAAOBgQAnKdk68dGJXvlj/GXwBUWN
-oXWF7hq4fDmwyhmcFUqk8qZKPKFUxkcER0GLzYeUgvD2URSfaS3/YW0d7K7kXGwP
-rB5edb+suaYf6mjm/w37xw/EJI9rdSKcB/3SSu8mALds7sUHDAO+MO0WkA/9d7t0
-LOsUqcDvMkKpZuYwNILwLw==
------END CERTIFICATE REQUEST-----
diff --git a/SSL/server-cert.pem b/SSL/server-cert.pem
index debf7026e3c..f420b4f3124 100644
--- a/SSL/server-cert.pem
+++ b/SSL/server-cert.pem
@@ -1,67 +1,42 @@
Certificate:
Data:
- Version: 3 (0x2)
- Serial Number: 2 (0x2)
+ Version: 1 (0x0)
+ Serial Number: 1 (0x1)
Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SE, L=Uppsala, O=MySQL AB, CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
+ Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB
Validity
- Not Before: Sep 12 16:22:06 2003 GMT
- Not After : Sep 9 16:22:06 2013 GMT
- Subject: C=SE, L=Uppsala, O=MySQL AB, CN=MySQL Server/Email=abstract.mysql.developer@mysql.com
+ Not Before: May 3 08:54:13 2006 GMT
+ Not After : Jan 27 08:54:13 2009 GMT
+ Subject: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:e9:86:7a:55:84:88:4c:be:a4:f8:92:73:30:12:
- 49:0b:7a:85:87:39:34:39:0d:7d:0b:8d:18:c2:17:
- 95:13:52:d2:3f:55:10:57:c8:3f:5a:f5:b2:fa:8b:
- d0:67:49:cc:aa:82:fc:9f:ce:00:b4:73:f3:36:d2:
- 3a:d3:c2:b0:0e:14:c3:d4:b2:21:74:a1:f0:31:81:
- 60:87:98:73:5c:10:c1:b1:1a:4d:f1:f3:b0:98:3f:
- f0:d7:97:9b:2b:fd:d5:21:79:b2:2f:eb:64:15:c9:
- 9b:9d:fc:9e:2d:d4:f8:04:5b:ea:a9:75:4b:42:c3:
- 3d:0e:4d:2a:a8:b8:ca:99:8d
+ RSA Public Key: (512 bit)
+ Modulus (512 bit):
+ 00:d9:fd:da:b3:fb:7c:e0:b0:03:be:97:c6:a4:36:
+ ac:71:af:bb:2d:e5:84:ed:f3:8f:2b:eb:11:e5:aa:
+ 66:ed:bf:62:6b:e3:ce:fa:80:ed:90:ff:b9:4a:39:
+ 20:40:b6:f2:99:bf:2f:33:b5:f2:ec:3a:90:60:1d:
+ 9e:94:7e:a4:1b
Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
- X509v3 Subject Key Identifier:
- 6E:E4:9B:6A:C5:EA:E4:E6:C7:EF:D7:1E:C8:63:45:60:2B:1B:D4:D4
- X509v3 Authority Key Identifier:
- keyid:88:98:65:D9:F3:F2:8B:03:1D:66:60:61:23:FA:AD:73:6D:D3:68:92
- DirName:/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
- serial:00
-
Signature Algorithm: md5WithRSAEncryption
- 31:77:69:b9:bd:ab:29:f3:fc:5a:09:16:6f:5d:42:ea:ba:01:
- 55:69:e3:75:cf:b8:d1:b7:b9:bf:da:63:85:8c:48:92:06:60:
- 76:97:e0:00:78:4b:ad:da:ab:6a:90:6d:8b:03:a8:b1:e9:09:
- 78:e1:29:98:56:12:60:6b:42:fe:e8:a7:c4:f8:d6:15:07:e8:
- 2b:c2:d8:8a:e5:1b:2e:51:08:9b:56:e3:b3:7a:4c:3e:e5:be:
- 4a:4d:f8:65:7b:a8:21:e0:ca:fe:8b:ab:d7:ec:f2:2d:f7:d0:
- bf:d7:c5:23:1c:08:d8:aa:57:c7:f3:5f:ba:33:3f:78:d1:f4:
- 8e:5e
+ de:5e:35:cd:7b:11:e6:7c:c5:7c:d6:27:4e:72:12:49:42:eb:
+ 6f:2c:96:f3:f4:00:78:a7:4f:9f:2d:7b:d7:30:39:af:49:4d:
+ df:b1:55:0d:30:be:23:6f:06:67:fd:dd:ba:98:66:36:c6:32:
+ b7:ed:63:fc:aa:49:cd:4f:72:98:3b:13:0e:f6:28:d7:d4:eb:
+ 04:6b:dc:e8:c7:04:80:92:e4:04:86:0b:ed:32:25:76:1d:a9:
+ 5c:a9:2c:18:2c:bd:bc:15:ed:e1:76:96:4d:bb:0d:41:44:06:
+ 2c:ad:45:bb:db:61:ad:17:11:cb:49:70:67:eb:c6:27:d3:91:
+ c8:f2
-----BEGIN CERTIFICATE-----
-MIIDkTCCAvqgAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCU0Ux
-EDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhB
-YnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0
-Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wHhcNMDMwOTEyMTYyMjA2WhcNMTMw
-OTA5MTYyMjA2WjB8MQswCQYDVQQGEwJTRTEQMA4GA1UEBxMHVXBwc2FsYTERMA8G
-A1UEChMITXlTUUwgQUIxFTATBgNVBAMTDE15U1FMIFNlcnZlcjExMC8GCSqGSIb3
-DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNvbTCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEA6YZ6VYSITL6k+JJzMBJJC3qFhzk0OQ19C40Y
-wheVE1LSP1UQV8g/WvWy+ovQZ0nMqoL8n84AtHPzNtI608KwDhTD1LIhdKHwMYFg
-h5hzXBDBsRpN8fOwmD/w15ebK/3VIXmyL+tkFcmbnfyeLdT4BFvqqXVLQsM9Dk0q
-qLjKmY0CAwEAAaOCARQwggEQMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w
-ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRu5Jtqxerk5sfv
-1x7IY0VgKxvU1DCBtQYDVR0jBIGtMIGqgBSImGXZ8/KLAx1mYGEj+q1zbdNokqGB
-jqSBizCBiDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoT
-CE15U1FMIEFCMSEwHwYDVQQDExhBYnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAv
-BgkqhkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb22C
-AQAwDQYJKoZIhvcNAQEEBQADgYEAMXdpub2rKfP8WgkWb11C6roBVWnjdc+40be5
-v9pjhYxIkgZgdpfgAHhLrdqrapBtiwOosekJeOEpmFYSYGtC/uinxPjWFQfoK8LY
-iuUbLlEIm1bjs3pMPuW+Sk34ZXuoIeDK/our1+zyLffQv9fFIxwI2KpXx/NfujM/
-eNH0jl4=
+MIIB+zCCAWQCAQEwDQYJKoZIhvcNAQEEBQAwRDELMAkGA1UEBhMCU0UxEDAOBgNV
+BAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFC
+MB4XDTA2MDUwMzA4NTQxM1oXDTA5MDEyNzA4NTQxM1owgYsxCzAJBgNVBAYTAlNF
+MRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhN
+eVNRTCBBQjESMBAGA1UEAxMJbG9jYWxob3N0MTEwLwYJKoZIhvcNAQkBFiJhYnN0
+cmFjdC5teXNxbC5kZXZlbG9wZXJAbXlzcWwuY29tMFwwDQYJKoZIhvcNAQEBBQAD
+SwAwSAJBANn92rP7fOCwA76XxqQ2rHGvuy3lhO3zjyvrEeWqZu2/YmvjzvqA7ZD/
+uUo5IEC28pm/LzO18uw6kGAdnpR+pBsCAwEAATANBgkqhkiG9w0BAQQFAAOBgQDe
+XjXNexHmfMV81idOchJJQutvLJbz9AB4p0+fLXvXMDmvSU3fsVUNML4jbwZn/d26
+mGY2xjK37WP8qknNT3KYOxMO9ijX1OsEa9zoxwSAkuQEhgvtMiV2HalcqSwYLL28
+Fe3hdpZNuw1BRAYsrUW722GtFxHLSXBn68Yn05HI8g==
-----END CERTIFICATE-----
diff --git a/SSL/server-key.pem b/SSL/server-key.pem
index 4292dc79929..a4842624c0c 100644
--- a/SSL/server-key.pem
+++ b/SSL/server-key.pem
@@ -1,15 +1,9 @@
-----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDphnpVhIhMvqT4knMwEkkLeoWHOTQ5DX0LjRjCF5UTUtI/VRBX
-yD9a9bL6i9BnScyqgvyfzgC0c/M20jrTwrAOFMPUsiF0ofAxgWCHmHNcEMGxGk3x
-87CYP/DXl5sr/dUhebIv62QVyZud/J4t1PgEW+qpdUtCwz0OTSqouMqZjQIDAQAB
-AoGBALTq11nrjIEQbdSZ+R1z/R0kddB2U+wjdA3/6P9tr7PBxVsFdtzbKaI5mcib
-iwCKX0J2qmrP+SHUdsexBZxLR4KV/Z55v9Pym99Dy+DxDA95zURyCMKRBIzlU5uN
-F7USEQoltLUCsmZwNWdit0gfxSWdddkHNuI0uxTzHwuDcUlNAkEA/76zVremngNL
-DlekM9NPn/8E/TXBHN1b1jdUKd7WymSJykdcm3viU98dFNZFWF8B0jiTcuBKXgpR
-vTShNab/swJBAOnCGp554BLhioTyyk8qjRLt3xEsjsDljJULHVLYWcUqIkMf97GL
-VLBhl6ZEI9i0WduqvgZ+Bacd0uHqIHz1Yb8CQQDm1CjqTDiGxlIoT9JVNJTZxEOs
-h6gVdXY+kxHT+N3FL5luiZp8fAR7zxVgiUVtzdLG+2madfapiobcT3RyCJkhAkBI
-64AaR7KasTjg2Ew7/e4cJZAcb2XozrLYG6t+GHeIhehCQEqoW+qDSy5fc4orI7eU
-SuMUa2OgCjGqv7p6wKFJAkEAznmum/MbVOBpC4FsdnIGkxyFKIbh2OLY2aUb2KkK
-Ouf4S8Y5Ldgszi0fnDPRaxWJzewwZKvcff2zj+mYZeAXbA==
+MIIBOgIBAAJBANn92rP7fOCwA76XxqQ2rHGvuy3lhO3zjyvrEeWqZu2/YmvjzvqA
+7ZD/uUo5IEC28pm/LzO18uw6kGAdnpR+pBsCAwEAAQJBAMieYdpmRoUaODf9wqh6
+ULXH/sG8i1vaXRcUHcJ50oRVfVK8/tGGvUuTDu6MeINTdahNDlYfjwOjKWVXys1w
+h6ECIQDs6s7DfczK2bKCLt0zqg24mZL3rOpGmDU+TatwN1yVgwIhAOuMzdVTX39p
+328+5WxJvBOFfxmSmqdDhIFpnRMvgguJAiByvKjT/km+970+1OllyvaIL0AA2OpA
+tBgdC0p6tyUMdwIgKuHAWzTJbu28UolVxQgLaFZmVCZ/ZzIAfnrWsLZ2a1kCIBq/
+ywJ2cpyFlgazu8AH6KCQa0ok9s70ElaB6FEC85Al
-----END RSA PRIVATE KEY-----
diff --git a/SSL/server-req.pem b/SSL/server-req.pem
deleted file mode 100644
index 7c3db0660ad..00000000000
--- a/SSL/server-req.pem
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN CERTIFICATE REQUEST-----
-MIIBvDCCASUCAQAwfDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAP
-BgNVBAoTCE15U1FMIEFCMRUwEwYDVQQDEwxNeVNRTCBTZXJ2ZXIxMTAvBgkqhkiG
-9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBAOmGelWEiEy+pPiSczASSQt6hYc5NDkNfQuN
-GMIXlRNS0j9VEFfIP1r1svqL0GdJzKqC/J/OALRz8zbSOtPCsA4Uw9SyIXSh8DGB
-YIeYc1wQwbEaTfHzsJg/8NeXmyv91SF5si/rZBXJm538ni3U+ARb6ql1S0LDPQ5N
-Kqi4ypmNAgMBAAGgADANBgkqhkiG9w0BAQQFAAOBgQCagJxGHBC+G5aSh3OguFn6
-z+qAC7u3B181kPBgNv20zMgLeq7YiAh3iNx4XO2+QXRGzMznFKx1tFr/mavCpgLs
-p3+dCvQt5FHEFFK1D1pDeXy4146X07hOTtC9jc/jSWeVnH4ujuX5gMtZqisOyYWV
-/gpw6dBtkTYlhS+y86kM/Q==
------END CERTIFICATE REQUEST-----
diff --git a/client/client_priv.h b/client/client_priv.h
index a9d5364df49..9e011144836 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -51,5 +51,5 @@ enum options_client
#endif
OPT_TRIGGERS,
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
- OPT_TZ_UTC, OPT_AUTO_CLOSE
+ OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_SSL_VERIFY_SERVER_CERT
};
diff --git a/client/mysql.cc b/client/mysql.cc
index 69a0e37b982..900df825b25 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -448,6 +448,14 @@ int main(int argc,char *argv[])
MYF(MY_WME));
if (histfile)
sprintf(histfile,"%s/.mysql_history",getenv("HOME"));
+ char link_name[FN_REFLEN];
+ if (my_readlink(link_name, histfile, 0) == 0 &&
+ strncmp(link_name, "/dev/null", 10) == 0)
+ {
+ /* The .mysql_history file is a symlink to /dev/null, don't use it */
+ my_free(histfile, MYF(MY_ALLOW_ZERO_PTR));
+ histfile= 0;
+ }
}
if (histfile)
{
@@ -484,7 +492,7 @@ sig_handler mysql_end(int sig)
{
mysql_close(&mysql);
#ifdef HAVE_READLINE
- if (!status.batch && !quick && !opt_html && !opt_xml)
+ if (!status.batch && !quick && !opt_html && !opt_xml && histfile)
{
/* write-history */
if (verbose)
@@ -2319,7 +2327,7 @@ print_table_data(MYSQL_RES *result)
uint extra_padding;
/* If this column may have a null value, use "NULL" for empty. */
- if (! not_null_flag[off] && (lengths[off] == 0))
+ if (! not_null_flag[off] && (cur[off] == NULL))
{
buffer= "NULL";
data_length= 4;
@@ -3118,6 +3126,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 5b52d524f8e..57ab4e071fb 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -340,6 +340,8 @@ int main(int argc,char *argv[])
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index b1a931a9df1..60b54a2ed99 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -788,7 +788,8 @@ static void die(const char* fmt, ...)
fprintf(stderr, "\n");
va_end(args);
cleanup();
- my_end(0);
+ /* We cannot free DBUG, it is used in global destructors after exit(). */
+ my_end(MY_DONT_FREE_DBUG);
exit(1);
}
@@ -1460,7 +1461,8 @@ int main(int argc, char** argv)
cleanup();
free_defaults(defaults_argv);
my_free_open_file_info();
- my_end(0);
+ /* We cannot free DBUG, it is used in global destructors after exit(). */
+ my_end(MY_DONT_FREE_DBUG);
exit(exit_value);
DBUG_RETURN(exit_value); // Keep compilers happy
}
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 78f12593f46..ee6d7b9d12b 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -905,6 +905,8 @@ static int dbConnect(char *host, char *user,char *passwd)
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 8694093f06b..1f9b96f91be 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -384,6 +384,8 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 504f0d9844b..d090495ff81 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -109,6 +109,8 @@ int main(int argc, char **argv)
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
diff --git a/client/mysqltest.c b/client/mysqltest.c
index ecf54e40400..fbbab4a0b3b 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -87,14 +87,6 @@
#endif
#define MAX_SERVER_ARGS 64
-/*
- Sometimes in a test the client starts before
- the server - to solve the problem, we try again
- after some sleep if connection fails the first
- time
-*/
-#define CON_RETRY_SLEEP 2
-#define MAX_CON_TRIES 5
#define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */
#define DEFAULT_DELIMITER ";"
@@ -108,7 +100,7 @@ enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
OPT_SSL_CIPHER,OPT_PS_PROTOCOL,OPT_SP_PROTOCOL,OPT_CURSOR_PROTOCOL,
- OPT_VIEW_PROTOCOL};
+ OPT_VIEW_PROTOCOL, OPT_SSL_VERIFY_SERVER_CERT, OPT_MAX_CONNECT_RETRIES};
/* ************************************************************************ */
/*
@@ -157,6 +149,7 @@ static int record= 0, opt_sleep= -1;
static char *db = 0, *pass=0;
const char *user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./";
static int port = 0;
+static int opt_max_connect_retries;
static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 0;
static my_bool tty_password= 0;
static my_bool ps_protocol= 0, ps_protocol_enabled= 0;
@@ -2126,9 +2119,16 @@ void init_manager()
db, port, sock
NOTE
- This function will try to connect to the given server MAX_CON_TRIES
- times and sleep CON_RETRY_SLEEP seconds between attempts before
- finally giving up. This helps in situation when the client starts
+
+ Sometimes in a test the client starts before
+ the server - to solve the problem, we try again
+ after some sleep if connection fails the first
+ time
+
+ This function will try to connect to the given server
+ "opt_max_connect_retries" times and sleep "connection_retry_sleep"
+ seconds between attempts before finally giving up.
+ This helps in situation when the client starts
before the server (which happens sometimes).
It will ignore any errors during these retries. One should use
connect_n_handle_errors() if he expects a connection error and wants
@@ -2143,8 +2143,9 @@ int safe_connect(MYSQL* mysql, const char *host, const char *user,
{
int con_error= 1;
my_bool reconnect= 1;
+ static int connection_retry_sleep= 2; /* Seconds */
int i;
- for (i= 0; i < MAX_CON_TRIES; ++i)
+ for (i= 0; i < opt_max_connect_retries; i++)
{
if (mysql_real_connect(mysql, host,user, pass, db, port, sock,
CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
@@ -2152,7 +2153,7 @@ int safe_connect(MYSQL* mysql, const char *host, const char *user,
con_error= 0;
break;
}
- sleep(CON_RETRY_SLEEP);
+ sleep(connection_retry_sleep);
}
/*
TODO: change this to 0 in future versions, but the 'kill' test relies on
@@ -2379,8 +2380,12 @@ int do_connect(struct st_query *q)
#ifdef HAVE_OPENSSL
if (opt_use_ssl || con_ssl)
+ {
mysql_ssl_set(&next_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ &opt_ssl_verify_server_cert);
+ }
#endif
if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR)
con_sock=fn_format(buff, con_sock, TMPDIR, "",0);
@@ -2912,6 +2917,10 @@ static struct my_option my_long_options[] =
{"manager-wait-timeout", OPT_MANAGER_WAIT_TIMEOUT,
"Undocumented: Used for debugging.", (gptr*) &manager_wait_timeout,
(gptr*) &manager_wait_timeout, 0, GET_INT, REQUIRED_ARG, 3, 0, 0, 0, 0, 0},
+ {"max-connect-retries", OPT_MAX_CONNECT_RETRIES,
+ "Max number of connection attempts when connecting to server",
+ (gptr*) &opt_max_connect_retries, (gptr*) &opt_max_connect_retries, 0,
+ GET_INT, REQUIRED_ARG, 5, 1, 10, 0, 0, 0},
{"password", 'p', "Password to use when connecting to server.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection.", (gptr*) &port,
@@ -4605,9 +4614,14 @@ int main(int argc, char **argv)
mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name);
#ifdef HAVE_OPENSSL
+ opt_ssl_verify_server_cert= TRUE; /* Always on in mysqltest */
if (opt_use_ssl)
+ {
mysql_ssl_set(&cur_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&cur_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ &opt_ssl_verify_server_cert);
+ }
#endif
if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
diff --git a/config/ac-macros/openssl.m4 b/config/ac-macros/openssl.m4
index a23c46eed00..af4305486a3 100644
--- a/config/ac-macros/openssl.m4
+++ b/config/ac-macros/openssl.m4
@@ -15,8 +15,9 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [
for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \
/usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib \
/usr/freeware/lib32 /usr/local/lib/ ; do
- # Just to be safe, we test for ".so" anyway
- if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl$shrext ; then
+ # Test for libssl using all known library file endings
+ if test -f $d/libssl.a || test -f $d/libssl.so || \
+ test -f $d/libssl.sl || test -f $d/libssl.dylib ; then
OPENSSL_LIB=$d
fi
done
@@ -28,8 +29,9 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [
if test -f $incs/openssl/ssl.h ; then
OPENSSL_INCLUDE=-I$incs
fi
- # Just to be safe, we test for ".so" anyway
- if test -f $libs/libssl.a || test -f $libs/libssl.so || test -f $libs/libssl$shrext ; then
+ # Test for libssl using all known library file endings
+ if test -f $d/libssl.a || test -f $d/libssl.so || \
+ test -f $d/libssl.sl || test -f $d/libssl.dylib ; then
OPENSSL_LIB=$libs
fi
;;
diff --git a/config/ac-macros/zlib.m4 b/config/ac-macros/zlib.m4
index c75bac58d7c..a01d13937ff 100644
--- a/config/ac-macros/zlib.m4
+++ b/config/ac-macros/zlib.m4
@@ -89,10 +89,11 @@ case $SYSTEM_TYPE in
fi
;;
*)
- # Just to be safe, we test for ".so" anyway
- eval shrexts=\"$shrext_cmds\"
- if test \( -f "$mysql_zlib_dir/lib/libz.a" -o -f "$mysql_zlib_dir/lib/libz.so" -o \
- -f "$mysql_zlib_dir/lib/libz$shrext" \) \
+ # Test for libz using all known library file endings
+ if test \( -f "$mysql_zlib_dir/lib/libz.a" -o \
+ -f "$mysql_zlib_dir/lib/libz.so" -o \
+ -f "$mysql_zlib_dir/lib/libz.sl" -o \
+ -f "$mysql_zlib_dir/lib/libz.dylib" \) \
-a -f "$mysql_zlib_dir/include/zlib.h"; then
ZLIB_INCLUDES="-I$mysql_zlib_dir/include"
ZLIB_LIBS="-L$mysql_zlib_dir/lib -lz"
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 91b7e7b6c4c..c991daf3617 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -271,6 +271,8 @@ static unsigned long Clock (void);
static void CloseFile(FILE *fp);
/* Push current debug state */
static void PushState(void);
+ /* Free memory associated with debug state. */
+static void FreeState (struct state *state);
/* Test for tracing enabled */
static BOOLEAN DoTrace(CODE_STATE *state);
/* Test to see if file is writable */
@@ -630,22 +632,7 @@ void _db_pop_ ()
stack = discard -> next_state;
_db_fp_ = stack -> out_file;
_db_pfp_ = stack -> prof_file;
- if (discard -> keywords != NULL) {
- FreeList (discard -> keywords);
- }
- if (discard -> functions != NULL) {
- FreeList (discard -> functions);
- }
- if (discard -> processes != NULL) {
- FreeList (discard -> processes);
- }
- if (discard -> p_functions != NULL) {
- FreeList (discard -> p_functions);
- }
- CloseFile (discard -> out_file);
- if (discard -> prof_file)
- CloseFile (discard -> prof_file);
- free ((char *) discard);
+ FreeState(discard);
if (!(stack->flags & DEBUG_ON))
_db_on_=0;
}
@@ -1160,6 +1147,71 @@ static void PushState ()
stack=new_malloc;
}
+/*
+ * FUNCTION
+ *
+ * FreeState Free memory associated with a struct state.
+ *
+ * SYNOPSIS
+ *
+ * static void FreeState (state)
+ * struct state *state;
+ *
+ * DESCRIPTION
+ *
+ * Deallocates the memory allocated for various information in a
+ * state.
+ *
+ */
+static void FreeState (
+struct state *state)
+{
+ if (state -> keywords != NULL) {
+ FreeList (state -> keywords);
+ }
+ if (state -> functions != NULL) {
+ FreeList (state -> functions);
+ }
+ if (state -> processes != NULL) {
+ FreeList (state -> processes);
+ }
+ if (state -> p_functions != NULL) {
+ FreeList (state -> p_functions);
+ }
+ CloseFile (state -> out_file);
+ if (state -> prof_file)
+ CloseFile (state -> prof_file);
+ free ((char *) state);
+}
+
+
+/*
+ * FUNCTION
+ *
+ * _db_end_ End debugging, freeing state stack memory.
+ *
+ * SYNOPSIS
+ *
+ * static VOID _db_end_ ()
+ *
+ * DESCRIPTION
+ *
+ * Ends debugging, de-allocating the memory allocated to the
+ * state stack.
+ *
+ * To be called at the very end of the program.
+ *
+ */
+void _db_end_ ()
+{
+ reg1 struct state *discard;
+ while((discard= stack) != NULL) {
+ stack= discard -> next_state;
+ FreeState (discard);
+ }
+ _db_on_=0;
+}
+
/*
* FUNCTION
diff --git a/extra/yassl/README b/extra/yassl/README
index ad59fe3965e..62209723f66 100644
--- a/extra/yassl/README
+++ b/extra/yassl/README
@@ -1,4 +1,37 @@
-yaSSL Release notes, version 1.2.2 (03/27/06)
+yaSSL Release notes, version 1.3.0 (04/26/06)
+
+
+ This release of yaSSL contains minor bug fixes, portability enhancements,
+ and libcurl support.
+
+See normal build instructions below under 1.0.6.
+
+
+--To build for libcurl on Linux, Solaris, *BSD, Mac OS X, or Cygwin:
+
+ To build for libcurl the library needs to be built without C++ globals since
+ the linker will be called in a C context, also libcurl configure will expect
+ OpenSSL library names so some symbolic links are created.
+
+ ./configure --enable-pure-c
+ make
+ make openssl-links
+
+ (then go to your libcurl home and tell libcurl about yaSSL)
+ ./configure --with-ssl=/yaSSL-HomeDir
+ make
+
+
+--To build for libcurl on Win32:
+
+ Simply add the yaSSL project as a dependency to libcurl, add
+ yaSSL-Home\include and yaSSL-Home\include\openssl to the include list, and
+ define USE_SSLEAY and USE_OPENSSL
+
+ please email todd@yassl.com if you have any questions.
+
+
+*******************yaSSL Release notes, version 1.2.2 (03/27/06)
This release of yaSSL contains minor bug fixes and portability enhancements.
diff --git a/extra/yassl/certs/ca-cert.pem b/extra/yassl/certs/ca-cert.pem
new file mode 100644
index 00000000000..981dd004fc6
--- /dev/null
+++ b/extra/yassl/certs/ca-cert.pem
@@ -0,0 +1,53 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=US, ST=Oregon, L=Portland, O=sawtooth, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
+ Validity
+ Not Before: Jan 18 20:12:32 2005 GMT
+ Not After : Oct 15 20:12:32 2007 GMT
+ Subject: C=US, ST=Oregon, L=Portland, O=sawtooth, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (512 bit)
+ Modulus (512 bit):
+ 00:cf:2b:14:00:b0:3c:df:6f:9e:91:40:ec:c8:f6:
+ 90:b2:5b:b4:70:80:a5:a4:0a:73:c7:44:f3:2a:26:
+ c4:2f:f1:3a:f1:c3:c4:ac:fc:c3:d2:c3:bf:f5:d7:
+ 6a:38:42:ad:22:ab:c8:c4:4b:4c:1d:16:af:05:34:
+ 7d:79:97:5e:e1
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ CB:0F:1F:E9:A2:76:71:C9:E6:E8:23:A6:C1:18:B7:CC:44:CF:B9:84
+ X509v3 Authority Key Identifier:
+ keyid:CB:0F:1F:E9:A2:76:71:C9:E6:E8:23:A6:C1:18:B7:CC:44:CF:B9:84
+ DirName:/C=US/ST=Oregon/L=Portland/O=sawtooth/CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
+ serial:00
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: md5WithRSAEncryption
+ 27:f7:3d:fb:39:6f:73:a4:86:f3:a0:48:22:60:84:e9:5c:3d:
+ 28:36:05:16:44:98:07:87:e1:5d:b5:f3:a7:bc:33:5f:f4:29:
+ a9:5f:87:33:df:e6:8e:bd:e2:f3:0a:c8:00:69:ae:3d:41:47:
+ 03:ea:0b:4c:67:45:4b:ab:f3:39
+-----BEGIN CERTIFICATE-----
+MIIC7zCCApmgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBiTELMAkGA1UEBhMCVVMx
+DzANBgNVBAgTBk9yZWdvbjERMA8GA1UEBxMIUG9ydGxhbmQxETAPBgNVBAoTCHNh
+d3Rvb3RoMSQwIgYDVQQDExt3d3cuc2F3dG9vdGgtY29uc3VsdGluZy5jb20xHTAb
+BgkqhkiG9w0BCQEWDmluZm9AeWFzc2wuY29tMB4XDTA1MDExODIwMTIzMloXDTA3
+MTAxNTIwMTIzMlowgYkxCzAJBgNVBAYTAlVTMQ8wDQYDVQQIEwZPcmVnb24xETAP
+BgNVBAcTCFBvcnRsYW5kMREwDwYDVQQKEwhzYXd0b290aDEkMCIGA1UEAxMbd3d3
+LnNhd3Rvb3RoLWNvbnN1bHRpbmcuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlh
+c3NsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDPKxQAsDzfb56RQOzI9pCy
+W7RwgKWkCnPHRPMqJsQv8Trxw8Ss/MPSw7/112o4Qq0iq8jES0wdFq8FNH15l17h
+AgMBAAGjgekwgeYwHQYDVR0OBBYEFMsPH+midnHJ5ugjpsEYt8xEz7mEMIG2BgNV
+HSMEga4wgauAFMsPH+midnHJ5ugjpsEYt8xEz7mEoYGPpIGMMIGJMQswCQYDVQQG
+EwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDERMA8GA1UE
+ChMIc2F3dG9vdGgxJDAiBgNVBAMTG3d3dy5zYXd0b290aC1jb25zdWx0aW5nLmNv
+bTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb22CAQAwDAYDVR0TBAUwAwEB
+/zANBgkqhkiG9w0BAQQFAANBACf3Pfs5b3OkhvOgSCJghOlcPSg2BRZEmAeH4V21
+86e8M1/0KalfhzPf5o694vMKyABprj1BRwPqC0xnRUur8zk=
+-----END CERTIFICATE-----
diff --git a/extra/yassl/certs/client-cert.der b/extra/yassl/certs/client-cert.der
new file mode 100644
index 00000000000..b28e2753376
--- /dev/null
+++ b/extra/yassl/certs/client-cert.der
Binary files differ
diff --git a/extra/yassl/certs/client-cert.pem b/extra/yassl/certs/client-cert.pem
new file mode 100644
index 00000000000..81110f17252
--- /dev/null
+++ b/extra/yassl/certs/client-cert.pem
@@ -0,0 +1,52 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=US, ST=Oregon, L=Portland, O=yaSSL, CN=www.yassl.com/emailAddress=info@yassl.com
+ Validity
+ Not Before: Jan 18 19:33:15 2005 GMT
+ Not After : Oct 15 19:33:15 2007 GMT
+ Subject: C=US, ST=Oregon, L=Portland, O=yaSSL, CN=www.yassl.com/emailAddress=info@yassl.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (512 bit)
+ Modulus (512 bit):
+ 00:cd:1f:78:47:f8:b8:d6:08:bf:bd:7c:23:61:86:
+ 36:28:ac:ee:3c:a8:9a:94:e6:d5:26:e8:71:50:b2:
+ 26:8b:1c:1e:3f:75:b2:d3:b3:67:95:0c:fd:76:28:
+ 65:d5:ce:12:82:9e:06:00:a2:09:dd:ce:3a:26:dd:
+ 46:2a:a0:45:71
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ AE:25:5E:FA:4D:A3:5B:2B:87:DE:F1:2A:F5:42:C0:FF:CE:B5:B4:AD
+ X509v3 Authority Key Identifier:
+ keyid:AE:25:5E:FA:4D:A3:5B:2B:87:DE:F1:2A:F5:42:C0:FF:CE:B5:B4:AD
+ DirName:/C=US/ST=Oregon/L=Portland/O=yaSSL/CN=www.yassl.com/emailAddress=info@yassl.com
+ serial:00
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: md5WithRSAEncryption
+ c5:82:26:0c:1f:61:01:14:b0:ce:18:99:64:91:0e:f1:f8:90:
+ 3e:a3:0e:be:38:7c:97:ba:05:c9:2a:dc:dd:62:2d:12:61:79:
+ 7a:86:b1:97:5d:1e:e8:f7:e8:32:34:f7:8f:b1:08:3d:13:71:
+ a6:3c:15:91:85:12:35:6e:78:87
+-----BEGIN CERTIFICATE-----
+MIICtzCCAmGgAwIBAgIBADANBgkqhkiG9w0BAQQFADB4MQswCQYDVQQGEwJVUzEP
+MA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDEOMAwGA1UEChMFeWFT
+U0wxFjAUBgNVBAMTDXd3dy55YXNzbC5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9A
+eWFzc2wuY29tMB4XDTA1MDExODE5MzMxNVoXDTA3MTAxNTE5MzMxNVoweDELMAkG
+A1UEBhMCVVMxDzANBgNVBAgTBk9yZWdvbjERMA8GA1UEBxMIUG9ydGxhbmQxDjAM
+BgNVBAoTBXlhU1NMMRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0wGwYJKoZIhvcN
+AQkBFg5pbmZvQHlhc3NsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDNH3hH
++LjWCL+9fCNhhjYorO48qJqU5tUm6HFQsiaLHB4/dbLTs2eVDP12KGXVzhKCngYA
+ogndzjom3UYqoEVxAgMBAAGjgdUwgdIwHQYDVR0OBBYEFK4lXvpNo1srh97xKvVC
+wP/OtbStMIGiBgNVHSMEgZowgZeAFK4lXvpNo1srh97xKvVCwP/OtbStoXykejB4
+MQswCQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFu
+ZDEOMAwGA1UEChMFeWFTU0wxFjAUBgNVBAMTDXd3dy55YXNzbC5jb20xHTAbBgkq
+hkiG9w0BCQEWDmluZm9AeWFzc2wuY29tggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQEEBQADQQDFgiYMH2EBFLDOGJlkkQ7x+JA+ow6+OHyXugXJKtzdYi0SYXl6
+hrGXXR7o9+gyNPePsQg9E3GmPBWRhRI1bniH
+-----END CERTIFICATE-----
diff --git a/extra/yassl/certs/client-key.der b/extra/yassl/certs/client-key.der
new file mode 100644
index 00000000000..6e8b432a07c
--- /dev/null
+++ b/extra/yassl/certs/client-key.der
Binary files differ
diff --git a/extra/yassl/certs/client-key.pem b/extra/yassl/certs/client-key.pem
new file mode 100644
index 00000000000..6898b2796fa
--- /dev/null
+++ b/extra/yassl/certs/client-key.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOgIBAAJBAM0feEf4uNYIv718I2GGNiis7jyompTm1SbocVCyJoscHj91stOz
+Z5UM/XYoZdXOEoKeBgCiCd3OOibdRiqgRXECAwEAAQJAXwa6OVVvg7Bv63+MAI0l
+n/hlMfLGEj9R9gFvJXwywPSEQhijOZmedpHALufFPNHtwba9dmbqMkBAw9JDaAgg
+QQIhAO+mBaSmoG5AYVKYQZiASe/2wMZjaQSN+zFLyF97OX8ZAiEA2x5iRmXUkbOT
+8Td/vx8R9mq9W5CJu+cN+SWGwTYhPBkCIGZFM6NQeKaUUvQshdHO7b66Twpa4jZP
+YSNoc9pLe/4BAiB+jIvBkKo2A/rbg2waG32qTXdTXKTPiuA9Fnk/OV30cQIhANuA
+uMdo+T+rYcNGJ1hCYKDe9JWBpNfSQ+H/A7sWuW8L
+-----END RSA PRIVATE KEY-----
diff --git a/extra/yassl/certs/dh1024.dat b/extra/yassl/certs/dh1024.dat
new file mode 100644
index 00000000000..86a95518278
--- /dev/null
+++ b/extra/yassl/certs/dh1024.dat
@@ -0,0 +1 @@
+30818702818100DA9A18547FF03B385CC16508C173A7EF4EB61CB40EF8FEF3B31F145051676166BCDC3FE6B799FC394D08C26385F9413F896E09117E46209D6923602683CEA100924A6EE695281775C619DAA94EA8CB3691B4275B0183F1D39639EBC92995FE645D6C1BC28D409E585549BBD2C5DCDD6C208B04EADD8B7A6D997F72CBAD88390F020102 \ No newline at end of file
diff --git a/extra/yassl/certs/dsa-cert.pem b/extra/yassl/certs/dsa-cert.pem
new file mode 100644
index 00000000000..ecca18dae82
--- /dev/null
+++ b/extra/yassl/certs/dsa-cert.pem
@@ -0,0 +1,68 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: dsaWithSHA1
+ Issuer: C=US, ST=Oregon, L=Portland, O=yaSSL DSA, CN=yaSSL DSA/emailAddress=info@yassl.com
+ Validity
+ Not Before: Jan 23 22:54:51 2005 GMT
+ Not After : Oct 20 22:54:51 2007 GMT
+ Subject: C=US, ST=Oregon, L=Portland, O=yaSSL DSA, CN=yaSSL DSA/emailAddress=info@yassl.com
+ Subject Public Key Info:
+ Public Key Algorithm: dsaEncryption
+ DSA Public Key:
+ pub:
+ 04:84:a0:26:31:72:0c:e8:4f:5d:53:17:62:b1:80:
+ ca:c0:16:5f:c3:1e:ea:c5:d9:98:38:f9:be:56:53:
+ 47:68:ce:08:22:57:1c:bb:0d:77:91:cf:5b:36:ed:
+ f3:24:82:90:8a:cd:90:7c:db:77:f9:17:2d:73:73:
+ ef:bb:b9:82
+ P:
+ 00:99:29:69:80:c9:3c:98:68:45:a9:82:fe:67:eb:
+ 95:88:c5:b4:0c:d6:26:45:95:19:2c:a0:20:5b:7e:
+ df:69:e9:dc:c3:0f:f3:61:0a:25:9b:f2:21:01:6a:
+ cd:aa:8c:37:e7:ca:66:db:56:f4:0f:7d:7a:d1:18:
+ b9:42:fd:1b:11
+ Q:
+ 00:ad:25:29:ab:0a:9f:09:1c:c1:ad:03:20:76:7f:
+ a6:b7:dd:4d:03:09
+ G:
+ 12:88:99:da:e7:d0:0b:93:9b:e6:ee:3c:21:7f:9c:
+ b3:b4:8d:a5:8c:e2:37:80:3f:17:d1:81:4f:bd:f0:
+ 71:b6:32:08:54:dd:bf:01:e2:b3:77:06:64:75:8a:
+ 04:d6:79:39:b1:02:03:03:c6:06:74:e5:90:05:0a:
+ 10:46:19:31
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ BE:F9:8C:5D:D6:1C:B4:EE:81:DD:36:56:0A:21:E4:61:44:73:E9:E2
+ X509v3 Authority Key Identifier:
+ keyid:BE:F9:8C:5D:D6:1C:B4:EE:81:DD:36:56:0A:21:E4:61:44:73:E9:E2
+ DirName:/C=US/ST=Oregon/L=Portland/O=yaSSL DSA/CN=yaSSL DSA/emailAddress=info@yassl.com
+ serial:00
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: dsaWithSHA1
+ 30:2b:02:14:74:46:9f:91:7b:24:17:3b:ee:0f:10:e3:76:62:
+ f4:dc:81:e6:fd:fe:02:13:08:f4:87:0a:ab:ba:9c:de:3a:69:
+ 72:59:b8:ec:e9:57:f4:bf:37
+-----BEGIN CERTIFICATE-----
+MIIDMTCCAvKgAwIBAgIBADAJBgcqhkjOOAQDMHgxCzAJBgNVBAYTAlVTMQ8wDQYD
+VQQIEwZPcmVnb24xETAPBgNVBAcTCFBvcnRsYW5kMRIwEAYDVQQKEwl5YVNTTCBE
+U0ExEjAQBgNVBAMTCXlhU1NMIERTQTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5YXNz
+bC5jb20wHhcNMDUwMTIzMjI1NDUxWhcNMDcxMDIwMjI1NDUxWjB4MQswCQYDVQQG
+EwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDESMBAGA1UE
+ChMJeWFTU0wgRFNBMRIwEAYDVQQDEwl5YVNTTCBEU0ExHTAbBgkqhkiG9w0BCQEW
+DmluZm9AeWFzc2wuY29tMIHwMIGoBgcqhkjOOAQBMIGcAkEAmSlpgMk8mGhFqYL+
+Z+uViMW0DNYmRZUZLKAgW37faencww/zYQolm/IhAWrNqow358pm21b0D3160Ri5
+Qv0bEQIVAK0lKasKnwkcwa0DIHZ/prfdTQMJAkASiJna59ALk5vm7jwhf5yztI2l
+jOI3gD8X0YFPvfBxtjIIVN2/AeKzdwZkdYoE1nk5sQIDA8YGdOWQBQoQRhkxA0MA
+AkAEhKAmMXIM6E9dUxdisYDKwBZfwx7qxdmYOPm+VlNHaM4IIlccuw13kc9bNu3z
+JIKQis2QfNt3+Rctc3Pvu7mCo4HVMIHSMB0GA1UdDgQWBBS++Yxd1hy07oHdNlYK
+IeRhRHPp4jCBogYDVR0jBIGaMIGXgBS++Yxd1hy07oHdNlYKIeRhRHPp4qF8pHow
+eDELMAkGA1UEBhMCVVMxDzANBgNVBAgTBk9yZWdvbjERMA8GA1UEBxMIUG9ydGxh
+bmQxEjAQBgNVBAoTCXlhU1NMIERTQTESMBAGA1UEAxMJeWFTU0wgRFNBMR0wGwYJ
+KoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbYIBADAMBgNVHRMEBTADAQH/MAkGByqG
+SM44BAMDLgAwKwIUdEafkXskFzvuDxDjdmL03IHm/f4CEwj0hwqrupzeOmlyWbjs
+6Vf0vzc=
+-----END CERTIFICATE-----
diff --git a/extra/yassl/certs/dsa512.der b/extra/yassl/certs/dsa512.der
new file mode 100644
index 00000000000..fe79ccb612b
--- /dev/null
+++ b/extra/yassl/certs/dsa512.der
Binary files differ
diff --git a/extra/yassl/certs/dsa512.pem b/extra/yassl/certs/dsa512.pem
new file mode 100644
index 00000000000..04a3dd94a77
--- /dev/null
+++ b/extra/yassl/certs/dsa512.pem
@@ -0,0 +1,8 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIH3AgEAAkEAmSlpgMk8mGhFqYL+Z+uViMW0DNYmRZUZLKAgW37faencww/zYQol
+m/IhAWrNqow358pm21b0D3160Ri5Qv0bEQIVAK0lKasKnwkcwa0DIHZ/prfdTQMJ
+AkASiJna59ALk5vm7jwhf5yztI2ljOI3gD8X0YFPvfBxtjIIVN2/AeKzdwZkdYoE
+1nk5sQIDA8YGdOWQBQoQRhkxAkAEhKAmMXIM6E9dUxdisYDKwBZfwx7qxdmYOPm+
+VlNHaM4IIlccuw13kc9bNu3zJIKQis2QfNt3+Rctc3Pvu7mCAhQjg+e+aqykxwwc
+E2V27tjDFY02uA==
+-----END DSA PRIVATE KEY-----
diff --git a/extra/yassl/certs/server-cert.pem b/extra/yassl/certs/server-cert.pem
new file mode 100644
index 00000000000..403dabdf5fa
--- /dev/null
+++ b/extra/yassl/certs/server-cert.pem
@@ -0,0 +1,38 @@
+Certificate:
+ Data:
+ Version: 1 (0x0)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=US, ST=Oregon, L=Portland, O=sawtooth, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
+ Validity
+ Not Before: Jan 18 20:50:59 2005 GMT
+ Not After : Oct 15 20:50:59 2007 GMT
+ Subject: C=US, ST=Oregon, L=Portland, O=taoSoftDev, CN=www.taosoftdev.com/emailAddress=info@yassl.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (512 bit)
+ Modulus (512 bit):
+ 00:a4:68:bb:bc:b7:27:5f:3c:f5:78:c6:1a:af:b9:
+ 95:fc:7e:61:1f:a8:81:0a:ca:43:88:9a:03:e0:d0:
+ a6:79:70:16:34:b9:7c:75:54:ca:70:19:66:38:be:
+ 6e:28:7e:a5:ff:6b:3c:83:2f:39:42:c3:15:f3:bd:
+ f2:25:93:22:e7
+ Exponent: 65537 (0x10001)
+ Signature Algorithm: md5WithRSAEncryption
+ 08:36:07:8c:3a:7f:f9:91:0a:82:d1:6a:c1:34:be:bc:2d:b2:
+ 20:98:dc:45:50:53:9c:66:e6:26:71:bd:fa:d2:b4:91:d3:53:
+ c0:20:05:c0:b6:84:9a:5f:3f:61:75:f5:fd:c6:ec:e2:f6:9f:
+ a2:13:17:a9:b7:83:60:cc:cb:eb
+-----BEGIN CERTIFICATE-----
+MIIB9zCCAaECAQEwDQYJKoZIhvcNAQEEBQAwgYkxCzAJBgNVBAYTAlVTMQ8wDQYD
+VQQIEwZPcmVnb24xETAPBgNVBAcTCFBvcnRsYW5kMREwDwYDVQQKEwhzYXd0b290
+aDEkMCIGA1UEAxMbd3d3LnNhd3Rvb3RoLWNvbnN1bHRpbmcuY29tMR0wGwYJKoZI
+hvcNAQkBFg5pbmZvQHlhc3NsLmNvbTAeFw0wNTAxMTgyMDUwNTlaFw0wNzEwMTUy
+MDUwNTlaMIGCMQswCQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQH
+EwhQb3J0bGFuZDETMBEGA1UEChMKdGFvU29mdERldjEbMBkGA1UEAxMSd3d3LnRh
+b3NvZnRkZXYuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbTBcMA0G
+CSqGSIb3DQEBAQUAA0sAMEgCQQCkaLu8tydfPPV4xhqvuZX8fmEfqIEKykOImgPg
+0KZ5cBY0uXx1VMpwGWY4vm4ofqX/azyDLzlCwxXzvfIlkyLnAgMBAAEwDQYJKoZI
+hvcNAQEEBQADQQAINgeMOn/5kQqC0WrBNL68LbIgmNxFUFOcZuYmcb360rSR01PA
+IAXAtoSaXz9hdfX9xuzi9p+iExept4NgzMvr
+-----END CERTIFICATE-----
diff --git a/extra/yassl/certs/server-key.pem b/extra/yassl/certs/server-key.pem
new file mode 100644
index 00000000000..d6055c4cfd8
--- /dev/null
+++ b/extra/yassl/certs/server-key.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOQIBAAJBAKRou7y3J1889XjGGq+5lfx+YR+ogQrKQ4iaA+DQpnlwFjS5fHVU
+ynAZZji+bih+pf9rPIMvOULDFfO98iWTIucCAwEAAQJABLVvMw931DV1vljGKORC
+1HF2LKbx0zJJzt7CX6z6J54vcE79K3NYXdU6o7/j1WTtfD47tFG+4ljGvSYPmrCI
+2QIhANfiY6is6JUJGGgeMxyWeQRPXfaE9Yrk6OhxHhpYf5CTAiEAwvWraeLPy/NE
+B+0w80mh8tCv2tpuKaYMOG53XpYX3N0CIDy/Bj3rUZLGOWjqvoUXzjupPY5lgVYw
+7Vyin87YAiUjAiAgM8X5em5KSMc+6+2+8bWfTtsNMjEqDfRMyepLpE0SvQIgTSYL
+WWfcZoRUPDM9GEuQ40nifVNjobzvjTW4aYyHCEI=
+-----END RSA PRIVATE KEY-----
diff --git a/extra/yassl/certs/taoCert.txt b/extra/yassl/certs/taoCert.txt
new file mode 100644
index 00000000000..585293e4f2b
--- /dev/null
+++ b/extra/yassl/certs/taoCert.txt
@@ -0,0 +1,50 @@
+
+***** Create a self signed cert ************
+
+1) openssl genrsa 512 > client-key.pem
+
+2) openssl req -new -x509 -nodes -md5 -days 1000 -key client-key.pem > client-cert.pem
+
+-- adding metadata to beginning
+
+3) openssl x509 -in client-cert.pem -text > tmp.pem
+
+4) mv tmp.pem client-cert.pem
+
+
+***** Create a CA, signing authority **********
+
+same as self signed, use ca prefix instead of client
+
+
+***** Create a cert signed by CA **************
+
+1) openssl req -newkey rsa:512 -md5 -days 1000 -nodes -keyout server-key.pem > server-req.pem
+
+2) copy ca-key.pem ca-cert.srl (why ????)
+
+3) openssl x509 -req -in server-req.pem -days 1000 -md5 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
+
+
+
+***** To create a dsa cert ********************
+
+1) openssl dsaparam 512 > dsa512.param # creates group params
+
+2) openssl gendsa dsa512.param > dsa512.pem # creates private key
+
+3) openssl req -new -x509 -nodes -days 1000 -key dsa512.pem > dsa-cert.pem
+
+
+
+
+***** To convert from PEM to DER **************
+
+a) openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER
+
+to convert rsa private PEM to DER :
+
+b) openssl rsa -in key.pem -outform DER -out key.der
+
+
+
diff --git a/extra/yassl/examples/client/client.cpp b/extra/yassl/examples/client/client.cpp
index 704a8e76637..94bf753210b 100644
--- a/extra/yassl/examples/client/client.cpp
+++ b/extra/yassl/examples/client/client.cpp
@@ -33,10 +33,10 @@ void client_test(void* args)
const char* cipher = 0;
int index = 0;
char list[1024];
- strcpy(list, "cipherlist");
+ strncpy(list, "cipherlist", 11);
while ( (cipher = SSL_get_cipher_list(ssl, index++)) ) {
- strcat(list, ":");
- strcat(list, cipher);
+ strncat(list, ":", 2);
+ strncat(list, cipher, strlen(cipher) + 1);
}
printf("%s\n", list);
printf("Using Cipher Suite %s\n", SSL_get_cipher(ssl));
@@ -89,6 +89,8 @@ void client_test(void* args)
args.argv = argv;
client_test(&args);
+ yaSSL_CleanUp();
+
return args.return_code;
}
diff --git a/extra/yassl/examples/echoclient/echoclient.cpp b/extra/yassl/examples/echoclient/echoclient.cpp
index ca557cca8af..fd3f7dd48a3 100644
--- a/extra/yassl/examples/echoclient/echoclient.cpp
+++ b/extra/yassl/examples/echoclient/echoclient.cpp
@@ -82,6 +82,7 @@ void echoclient_test(void* args)
args.argv = argv;
echoclient_test(&args);
+ yaSSL_CleanUp();
return args.return_code;
}
diff --git a/extra/yassl/examples/echoserver/echoserver.cpp b/extra/yassl/examples/echoserver/echoserver.cpp
index 14a37a7e175..3243cc21a7c 100644
--- a/extra/yassl/examples/echoserver/echoserver.cpp
+++ b/extra/yassl/examples/echoserver/echoserver.cpp
@@ -15,6 +15,8 @@
args.argv = argv;
echoserver_test(&args);
+ yaSSL_CleanUp();
+
return args.return_code;
}
diff --git a/extra/yassl/examples/server/server.cpp b/extra/yassl/examples/server/server.cpp
index 4d3f121cf2c..73cff19e371 100644
--- a/extra/yassl/examples/server/server.cpp
+++ b/extra/yassl/examples/server/server.cpp
@@ -67,6 +67,8 @@ THREAD_RETURN YASSL_API server_test(void* args)
args.argv = argv;
server_test(&args);
+ yaSSL_CleanUp();
+
return args.return_code;
}
diff --git a/extra/yassl/include/openssl/err.h b/extra/yassl/include/openssl/err.h
index 054d0940509..45ac1ca2469 100644
--- a/extra/yassl/include/openssl/err.h
+++ b/extra/yassl/include/openssl/err.h
@@ -1,6 +1,6 @@
/* err.h for openssl */
-#ifndef ysSSL_err_h__
+#ifndef yaSSL_err_h__
#define yaSSL_err_h__
diff --git a/extra/yassl/include/openssl/md4.h b/extra/yassl/include/openssl/md4.h
new file mode 100644
index 00000000000..2e99f977fca
--- /dev/null
+++ b/extra/yassl/include/openssl/md4.h
@@ -0,0 +1 @@
+/* md4.h for libcurl */
diff --git a/extra/yassl/include/openssl/md5.h b/extra/yassl/include/openssl/md5.h
index a1025b92782..dfaf9799c44 100644
--- a/extra/yassl/include/openssl/md5.h
+++ b/extra/yassl/include/openssl/md5.h
@@ -1 +1,4 @@
/* md5.h for openssl */
+
+#include "ssl.h" /* in there for now */
+
diff --git a/extra/yassl/include/openssl/pem.h b/extra/yassl/include/openssl/pem.h
new file mode 100644
index 00000000000..b4c63d56a4d
--- /dev/null
+++ b/extra/yassl/include/openssl/pem.h
@@ -0,0 +1 @@
+/* pem.h for libcurl */
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index b6840d006df..a7eca9138a2 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -29,8 +29,22 @@
#define yaSSL_openssl_h__
#include <stdio.h> /* ERR_print fp */
+#include "opensslv.h" /* for version number */
#include "rsa.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+ void yaSSL_CleanUp(); /* call once at end of application use to
+ free static singleton memory holders,
+ not a leak per se, but helpful when
+ looking for them */
+
+#if defined(__cplusplus)
+} // extern
+#endif
+
#if defined(__cplusplus) && !defined(YASSL_MYSQL_COMPATIBLE)
namespace yaSSL {
extern "C" {
@@ -102,7 +116,6 @@ void X509_free(X509*);
typedef struct BIO BIO;
/* ASN stuff */
-typedef struct ASN1_TIME ASN1_TIME;
@@ -345,8 +358,8 @@ long SSL_CTX_sess_set_cache_size(SSL_CTX*, long);
long SSL_CTX_set_tmp_dh(SSL_CTX*, DH*);
void OpenSSL_add_all_algorithms(void);
-void SSL_library_init();
-void SSLeay_add_ssl_algorithms(void);
+int SSL_library_init();
+int SSLeay_add_ssl_algorithms(void);
SSL_CIPHER* SSL_get_current_cipher(SSL*);
@@ -371,6 +384,10 @@ typedef unsigned char DES_cblock[8];
typedef const DES_cblock const_DES_cblock;
typedef DES_cblock DES_key_schedule;
+enum {
+ DES_ENCRYPT = 1,
+ DES_DECRYPT = 0
+};
const EVP_MD* EVP_md5(void);
const EVP_CIPHER* EVP_des_ede3_cbc(void);
@@ -392,6 +409,108 @@ int RAND_write_file(const char*);
int RAND_load_file(const char*, long);
+/* for libcurl */
+int RAND_status(void);
+
+int DES_set_key(const_DES_cblock*, DES_key_schedule*);
+void DES_set_odd_parity(DES_cblock*);
+void DES_ecb_encrypt(DES_cblock*, DES_cblock*, DES_key_schedule*, int);
+
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX*, void* userdata);
+void SSL_SESSION_free(SSL_SESSION* session);
+
+X509* SSL_get_certificate(SSL* ssl);
+EVP_PKEY* SSL_get_privatekey(SSL* ssl);
+EVP_PKEY* X509_get_pubkey(X509* x);
+
+int EVP_PKEY_copy_parameters(EVP_PKEY* to, const EVP_PKEY* from);
+void EVP_PKEY_free(EVP_PKEY* pkey);
+void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+void ERR_free_strings(void);
+void EVP_cleanup(void);
+
+void* X509_get_ext_d2i(X509* x, int nid, int* crit, int* idx);
+
+#define GEN_IPADD 7
+#define NID_subject_alt_name 85
+#define STACK_OF(x) x
+
+
+/* defined here because libcurl dereferences */
+typedef struct ASN1_STRING {
+ int type;
+ int length;
+ unsigned char* data;
+} ASN1_STRING;
+
+
+typedef struct GENERAL_NAME {
+ int type;
+ union {
+ ASN1_STRING* ia5;
+ } d;
+} GENERAL_NAME;
+
+void GENERAL_NAMES_free(STACK_OF(GENERAL_NAME) *x);
+
+int sk_GENERAL_NAME_num(STACK_OF(GENERAL_NAME) *x);
+GENERAL_NAME* sk_GENERAL_NAME_value(STACK_OF(GENERAL_NAME) *x, int i);
+
+
+unsigned char* ASN1_STRING_data(ASN1_STRING* x);
+int ASN1_STRING_length(ASN1_STRING* x);
+int ASN1_STRING_type(ASN1_STRING *x);
+
+typedef ASN1_STRING X509_NAME_ENTRY;
+
+int X509_NAME_get_index_by_NID(X509_NAME* name,int nid, int lastpos);
+
+ASN1_STRING* X509_NAME_ENTRY_get_data(X509_NAME_ENTRY* ne);
+X509_NAME_ENTRY* X509_NAME_get_entry(X509_NAME* name, int loc);
+
+#define OPENSSL_malloc(x) malloc(x)
+#define OPENSSL_free(x) free(x)
+
+int ASN1_STRING_to_UTF8(unsigned char** out, ASN1_STRING* in);
+
+SSL_METHOD* SSLv23_client_method(void); /* doesn't actually roll back */
+SSL_METHOD* SSLv2_client_method(void); /* will never work, no v 2 */
+
+
+SSL_SESSION* SSL_get1_session(SSL* ssl); /* what's ref count */
+
+
+#define CRYPTO_free(x) free(x)
+#define ASN1_TIME ASN1_STRING
+
+ASN1_TIME* X509_get_notBefore(X509* x);
+ASN1_TIME* X509_get_notAfter(X509* x);
+
+
+#define ASN1_UTCTIME ASN1_STRING
+#define NID_commonName 13
+#define V_ASN1_UTF8STRING 12
+#define GEN_DNS 2
+
+
+typedef struct MD4_CTX {
+ void* ptr;
+} MD4_CTX;
+
+void MD4_Init(MD4_CTX*);
+void MD4_Update(MD4_CTX*, const void*, unsigned long);
+void MD4_Final(unsigned char*, MD4_CTX*);
+
+
+typedef struct MD5_CTX {
+ int buffer[32]; /* big enough to hold, check size in Init */
+} MD5_CTX;
+
+void MD5_Init(MD5_CTX*);
+void MD5_Update(MD5_CTX*, const void*, unsigned long);
+void MD5_Final(unsigned char*, MD5_CTX*);
+
+
#define SSL_DEFAULT_CIPHER_LIST "" /* default all */
diff --git a/extra/yassl/include/openssl/x509.h b/extra/yassl/include/openssl/x509.h
new file mode 100644
index 00000000000..dcd847c0337
--- /dev/null
+++ b/extra/yassl/include/openssl/x509.h
@@ -0,0 +1 @@
+/* x509.h for libcurl */
diff --git a/extra/yassl/include/openssl/x509v3.h b/extra/yassl/include/openssl/x509v3.h
new file mode 100644
index 00000000000..adf94af8f48
--- /dev/null
+++ b/extra/yassl/include/openssl/x509v3.h
@@ -0,0 +1 @@
+/* x509v3.h for libcurl */
diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp
index 935bae582ea..97ae468d2f9 100644
--- a/extra/yassl/include/yassl_int.hpp
+++ b/extra/yassl/include/yassl_int.hpp
@@ -34,6 +34,7 @@
#include "cert_wrapper.hpp"
#include "log.hpp"
#include "lock.hpp"
+#include "openssl/ssl.h" // ASN1_STRING and DH
namespace yaSSL {
@@ -126,32 +127,70 @@ private:
};
+// hold add crypt references provided to callers
+class CryptProvider {
+ mySTL::list<Digest*> digestList_;
+ mySTL::list<BulkCipher*> cipherList_;
+ CryptProvider() {} // only GetCryptProvider creates
+public:
+ ~CryptProvider();
+
+ Digest* NewMd5();
+ BulkCipher* NewDesEde();
+
+ friend CryptProvider& GetCryptProvider();
+private:
+ CryptProvider(const CryptProvider&); // hide copy
+ CryptProvider& operator=(const CryptProvider&); // and assign
+};
+
+CryptProvider& GetCryptProvider();
+
#undef X509_NAME // wincrypt.h clash
// openSSL X509 names
class X509_NAME {
char* name_;
+ size_t sz_;
+ ASN1_STRING entry_;
public:
X509_NAME(const char*, size_t sz);
~X509_NAME();
char* GetName();
+ ASN1_STRING* GetEntry(int i);
private:
X509_NAME(const X509_NAME&); // hide copy
X509_NAME& operator=(const X509_NAME&); // and assign
};
+class StringHolder {
+ ASN1_STRING asnString_;
+public:
+ StringHolder(const char* str, int sz);
+ ~StringHolder();
+
+ ASN1_STRING* GetString();
+};
+
+
// openSSL X509
class X509 {
X509_NAME issuer_;
X509_NAME subject_;
+ StringHolder beforeDate_; // not valid before
+ StringHolder afterDate_; // not valid after
public:
- X509(const char* i, size_t, const char* s, size_t);
+ X509(const char* i, size_t, const char* s, size_t,
+ const char* b, int, const char* a, int);
~X509() {}
X509_NAME* GetIssuer();
X509_NAME* GetSubject();
+
+ ASN1_STRING* GetBefore();
+ ASN1_STRING* GetAfter();
private:
X509(const X509&); // hide copy
X509& operator=(const X509&); // and assign
diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp
index bfb6467182b..76c807cd05f 100644
--- a/extra/yassl/include/yassl_types.hpp
+++ b/extra/yassl/include/yassl_types.hpp
@@ -35,10 +35,6 @@
namespace yaSSL {
-// Delete static singleton memory holders
-void CleanUp();
-
-
#ifdef YASSL_PURE_C
// library allocation
diff --git a/extra/yassl/lib/dummy b/extra/yassl/lib/dummy
new file mode 100644
index 00000000000..85c1efd587f
--- /dev/null
+++ b/extra/yassl/lib/dummy
@@ -0,0 +1 @@
+// this is a dummy file
diff --git a/extra/yassl/mySTL/helpers.hpp b/extra/yassl/mySTL/helpers.hpp
index 5aa14d838b1..df79025197a 100644
--- a/extra/yassl/mySTL/helpers.hpp
+++ b/extra/yassl/mySTL/helpers.hpp
@@ -44,6 +44,11 @@
return static_cast<void*>(d);
}
+ // for compilers that want matching delete
+ inline void operator delete(void* ptr, Dummy* d)
+ {
+ }
+
typedef Dummy* yassl_pointer;
namespace mySTL {
diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp
index b98c7faf1d0..ae609b510ba 100644
--- a/extra/yassl/src/cert_wrapper.cpp
+++ b/extra/yassl/src/cert_wrapper.cpp
@@ -271,10 +271,13 @@ int CertManager::Validate()
else
peerKeyType_ = dsa_sa_algo;
- int iSz = cert.GetIssuer() ? strlen(cert.GetIssuer()) + 1 : 0;
- int sSz = cert.GetCommonName() ? strlen(cert.GetCommonName()) + 1 : 0;
+ int iSz = strlen(cert.GetIssuer()) + 1;
+ int sSz = strlen(cert.GetCommonName()) + 1;
+ int bSz = strlen(cert.GetBeforeDate()) + 1;
+ int aSz = strlen(cert.GetAfterDate()) + 1;
peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(),
- sSz);
+ sSz, cert.GetBeforeDate(), bSz,
+ cert.GetAfterDate(), aSz);
}
return 0;
}
diff --git a/extra/yassl/src/make.bat b/extra/yassl/src/make.bat
index 4c79a9c6406..148427a6f41 100644
--- a/extra/yassl/src/make.bat
+++ b/extra/yassl/src/make.bat
@@ -1,4 +1,4 @@
-# quick and dirty build file for testing different MSDEVs
+REM quick and dirty build file for testing different MSDEVs
setlocal
set myFLAGS= /I../include /I../mySTL /I../taocrypt/include /W3 /c /ZI
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index 1aab14009d3..66196514a87 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -1,4 +1,4 @@
-/* ssl.cpp
+ /* ssl.cpp
*
* Copyright (C) 2003 Sawtooth Consulting Ltd.
*
@@ -36,6 +36,7 @@
#include "openssl/ssl.h"
#include "handshake.hpp"
#include "yassl_int.hpp"
+#include "md5.hpp" // for TaoCrypt MD5 size assert
#include <stdio.h>
#ifdef _WIN32
@@ -52,6 +53,53 @@ namespace yaSSL {
using mySTL::min;
+int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
+{
+ if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
+ return SSL_BAD_FILETYPE;
+
+ FILE* input = fopen(file, "rb");
+ if (!input)
+ return SSL_BAD_FILE;
+
+ if (type == CA) {
+ x509* ptr = PemToDer(file, Cert);
+ if (!ptr) {
+ fclose(input);
+ return SSL_BAD_FILE;
+ }
+ ctx->AddCA(ptr); // takes ownership
+ }
+ else {
+ x509*& x = (type == Cert) ? ctx->certificate_ : ctx->privateKey_;
+
+ if (format == SSL_FILETYPE_ASN1) {
+ fseek(input, 0, SEEK_END);
+ long sz = ftell(input);
+ rewind(input);
+ x = NEW_YS x509(sz); // takes ownership
+ size_t bytes = fread(x->use_buffer(), sz, 1, input);
+ if (bytes != 1) {
+ fclose(input);
+ return SSL_BAD_FILE;
+ }
+ }
+ else {
+ x = PemToDer(file, type);
+ if (!x) {
+ fclose(input);
+ return SSL_BAD_FILE;
+ }
+ }
+ }
+ fclose(input);
+ return SSL_SUCCESS;
+}
+
+
+extern "C" {
+
+
SSL_METHOD* SSLv3_method()
{
return SSLv3_client_method();
@@ -448,50 +496,6 @@ long SSL_CTX_set_tmp_dh(SSL_CTX* ctx, DH* dh)
}
-int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
-{
- if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
- return SSL_BAD_FILETYPE;
-
- FILE* input = fopen(file, "rb");
- if (!input)
- return SSL_BAD_FILE;
-
- if (type == CA) {
- x509* ptr = PemToDer(file, Cert);
- if (!ptr) {
- fclose(input);
- return SSL_BAD_FILE;
- }
- ctx->AddCA(ptr); // takes ownership
- }
- else {
- x509*& x = (type == Cert) ? ctx->certificate_ : ctx->privateKey_;
-
- if (format == SSL_FILETYPE_ASN1) {
- fseek(input, 0, SEEK_END);
- long sz = ftell(input);
- rewind(input);
- x = NEW_YS x509(sz); // takes ownership
- size_t bytes = fread(x->use_buffer(), sz, 1, input);
- if (bytes != 1) {
- fclose(input);
- return SSL_BAD_FILE;
- }
- }
- else {
- x = PemToDer(file, type);
- if (!x) {
- fclose(input);
- return SSL_BAD_FILE;
- }
- }
- }
- fclose(input);
- return SSL_SUCCESS;
-}
-
-
int SSL_CTX_use_certificate_file(SSL_CTX* ctx, const char* file, int format)
{
return read_file(ctx, file, format, Cert);
@@ -723,8 +727,10 @@ void OpenSSL_add_all_algorithms() // compatibility only
{}
-void SSL_library_init() // compatiblity only
-{}
+int SSL_library_init() // compatiblity only
+{
+ return 1;
+}
DH* DH_new(void)
@@ -804,15 +810,13 @@ const char* X509_verify_cert_error_string(long /* error */)
const EVP_MD* EVP_md5(void)
{
- // TODO: FIX add to some list for destruction
- return NEW_YS MD5;
+ return GetCryptProvider().NewMd5();
}
const EVP_CIPHER* EVP_des_ede3_cbc(void)
{
- // TODO: FIX add to some list for destruction
- return NEW_YS DES_EDE;
+ return GetCryptProvider().NewDesEde();
}
@@ -897,6 +901,275 @@ void DES_ede3_cbc_encrypt(const byte* input, byte* output, long sz,
}
+// functions for libcurl
+int RAND_status()
+{
+ return 1; /* TaoCrypt provides enough seed */
+}
+
+
+int DES_set_key(const_DES_cblock* key, DES_key_schedule* schedule)
+{
+ memcpy(schedule, key, sizeof(const_DES_cblock));
+ return 1;
+}
+
+
+void DES_set_odd_parity(DES_cblock* key)
+{
+ // not needed now for TaoCrypt
+}
+
+
+void DES_ecb_encrypt(DES_cblock* input, DES_cblock* output,
+ DES_key_schedule* key, int enc)
+{
+ DES des;
+
+ if (enc) {
+ des.set_encryptKey(*key, 0);
+ des.encrypt(*output, *input, DES_BLOCK);
+ }
+ else {
+ des.set_decryptKey(*key, 0);
+ des.decrypt(*output, *input, DES_BLOCK);
+ }
+}
+
+
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX*, void* userdata)
+{
+ // yaSSL doesn't support yet, unencrypt your PEM file with userdata
+ // before handing off to yaSSL
+}
+
+
+X509* SSL_get_certificate(SSL* ssl)
+{
+ // only used to pass to get_privatekey which isn't used
+ return 0;
+}
+
+
+EVP_PKEY* SSL_get_privatekey(SSL* ssl)
+{
+ // only called, not used
+ return 0;
+}
+
+
+void SSL_SESSION_free(SSL_SESSION* session)
+{
+ // managed by singleton
+}
+
+
+
+EVP_PKEY* X509_get_pubkey(X509* x)
+{
+ // called, not used though
+ return 0;
+}
+
+
+int EVP_PKEY_copy_parameters(EVP_PKEY* to, const EVP_PKEY* from)
+{
+ // called, not used though
+ return 0;
+}
+
+
+void EVP_PKEY_free(EVP_PKEY* pkey)
+{
+ // never allocated from above
+}
+
+
+void ERR_error_string_n(unsigned long e, char *buf, size_t len)
+{
+ if (len) ERR_error_string(e, buf);
+}
+
+
+void ERR_free_strings(void)
+{
+ // handled internally
+}
+
+
+void EVP_cleanup(void)
+{
+ // nothing to do yet
+}
+
+
+ASN1_TIME* X509_get_notBefore(X509* x)
+{
+ if (x) return x->GetBefore();
+ return 0;
+}
+
+
+ASN1_TIME* X509_get_notAfter(X509* x)
+{
+ if (x) return x->GetAfter();
+ return 0;
+}
+
+
+SSL_METHOD* SSLv23_client_method(void) /* doesn't actually roll back */
+{
+ return SSLv3_client_method();
+}
+
+
+SSL_METHOD* SSLv2_client_method(void) /* will never work, no v 2 */
+{
+ return 0;
+}
+
+
+SSL_SESSION* SSL_get1_session(SSL* ssl) /* what's ref count */
+{
+ return SSL_get_session(ssl);
+}
+
+
+void GENERAL_NAMES_free(STACK_OF(GENERAL_NAME) *x)
+{
+ // no extension names supported yet
+}
+
+
+int sk_GENERAL_NAME_num(STACK_OF(GENERAL_NAME) *x)
+{
+ // no extension names supported yet
+ return 0;
+}
+
+
+GENERAL_NAME* sk_GENERAL_NAME_value(STACK_OF(GENERAL_NAME) *x, int i)
+{
+ // no extension names supported yet
+ return 0;
+}
+
+
+unsigned char* ASN1_STRING_data(ASN1_STRING* x)
+{
+ if (x) return x->data;
+ return 0;
+}
+
+
+int ASN1_STRING_length(ASN1_STRING* x)
+{
+ if (x) return x->length;
+ return 0;
+}
+
+
+int ASN1_STRING_type(ASN1_STRING *x)
+{
+ if (x) return x->type;
+ return 0;
+}
+
+
+int X509_NAME_get_index_by_NID(X509_NAME* name,int nid, int lastpos)
+{
+ int idx = -1; // not found
+ const char* start = &name->GetName()[lastpos + 1];
+
+ switch (nid) {
+ case NID_commonName:
+ const char* found = strstr(start, "/CN=");
+ if (found) {
+ found += 4; // advance to str
+ idx = found - start + lastpos + 1;
+ }
+ break;
+ }
+
+ return idx;
+}
+
+
+ASN1_STRING* X509_NAME_ENTRY_get_data(X509_NAME_ENTRY* ne)
+{
+ // the same in yaSSL
+ return ne;
+}
+
+
+X509_NAME_ENTRY* X509_NAME_get_entry(X509_NAME* name, int loc)
+{
+ return name->GetEntry(loc);
+}
+
+
+// already formatted, caller responsible for freeing *out
+int ASN1_STRING_to_UTF8(unsigned char** out, ASN1_STRING* in)
+{
+ if (!in) return 0;
+
+ *out = (unsigned char*)malloc(in->length + 1);
+ if (*out) {
+ memcpy(*out, in->data, in->length);
+ (*out)[in->length] = 0;
+ }
+ return in->length;
+}
+
+
+void* X509_get_ext_d2i(X509* x, int nid, int* crit, int* idx)
+{
+ // no extensions supported yet
+ return 0;
+}
+
+
+void MD4_Init(MD4_CTX* md4)
+{
+ assert(0); // not yet supported, build compat. only
+}
+
+
+void MD4_Update(MD4_CTX* md4, const void* data, unsigned long sz)
+{
+}
+
+
+void MD4_Final(unsigned char* hash, MD4_CTX* md4)
+{
+}
+
+
+void MD5_Init(MD5_CTX* md5)
+{
+ // make sure we have a big enough buffer
+ typedef char ok[sizeof(md5->buffer) >= sizeof(TaoCrypt::MD5) ? 1 : -1];
+ (void) sizeof(ok);
+
+ // using TaoCrypt since no dynamic memory allocated
+ // and no destructor will be called
+ new (reinterpret_cast<yassl_pointer>(md5->buffer)) TaoCrypt::MD5();
+}
+
+
+void MD5_Update(MD5_CTX* md5, const void* data, unsigned long sz)
+{
+ reinterpret_cast<TaoCrypt::MD5*>(md5->buffer)->Update(
+ static_cast<const byte*>(data), static_cast<unsigned int>(sz));
+}
+
+
+void MD5_Final(unsigned char* hash, MD5_CTX* md5)
+{
+ reinterpret_cast<TaoCrypt::MD5*>(md5->buffer)->Final(hash);
+}
+
+
// functions for stunnel
void RAND_screen()
@@ -1098,8 +1371,10 @@ void DES_ede3_cbc_encrypt(const byte* input, byte* output, long sz,
}
- void SSLeay_add_ssl_algorithms() // compatibility only
- {}
+ int SSLeay_add_ssl_algorithms() // compatibility only
+ {
+ return 1;
+ }
void ERR_remove_state(unsigned long)
@@ -1129,4 +1404,5 @@ void DES_ede3_cbc_encrypt(const byte* input, byte* output, long sz,
// end stunnel needs
+} // extern "C"
} // namespace
diff --git a/extra/yassl/src/template_instnt.cpp b/extra/yassl/src/template_instnt.cpp
index 5782df213ea..43b80d59a4d 100644
--- a/extra/yassl/src/template_instnt.cpp
+++ b/extra/yassl/src/template_instnt.cpp
@@ -31,7 +31,6 @@
#include "hmac.hpp"
#include "md5.hpp"
#include "sha.hpp"
-#include "ripemd.hpp"
#include "openssl/ssl.h"
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
@@ -51,12 +50,16 @@ template class list<yaSSL::SSL_SESSION*>;
template class list<yaSSL::input_buffer*>;
template class list<yaSSL::output_buffer*>;
template class list<yaSSL::x509*>;
+template class list<yaSSL::Digest*>;
+template class list<yaSSL::BulkCipher*>;
template void destroy<mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*>(mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*, mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*);
template yaSSL::del_ptr_zero for_each<mySTL::list<TaoCrypt::Signer*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<TaoCrypt::Signer*>::iterator, mySTL::list<TaoCrypt::Signer*>::iterator, yaSSL::del_ptr_zero);
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::SSL_SESSION*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::SSL_SESSION*>::iterator, mySTL::list<yaSSL::SSL_SESSION*>::iterator, yaSSL::del_ptr_zero);
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::input_buffer*>::iterator, mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::del_ptr_zero);
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::output_buffer*>::iterator, mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::del_ptr_zero);
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::x509*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::x509*>::iterator, mySTL::list<yaSSL::x509*>::iterator, yaSSL::del_ptr_zero);
+template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::Digest*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::Digest*>::iterator, mySTL::list<yaSSL::Digest*>::iterator, yaSSL::del_ptr_zero);
+template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::BulkCipher*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::BulkCipher*>::iterator, mySTL::list<yaSSL::BulkCipher*>::iterator, yaSSL::del_ptr_zero);
}
namespace yaSSL {
@@ -82,6 +85,7 @@ template void ysDelete<X509>(X509*);
template void ysDelete<Message>(Message*);
template void ysDelete<sslFactory>(sslFactory*);
template void ysDelete<Sessions>(Sessions*);
+template void ysDelete<CryptProvider>(CryptProvider*);
template void ysArrayDelete<unsigned char>(unsigned char*);
template void ysArrayDelete<char>(char*);
}
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index 1d2d5396ea0..4d6d1fc7aff 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -1975,7 +1975,9 @@ Connection::Connection(ProtocolVersion v, RandomPool& ran)
: pre_master_secret_(0), sequence_number_(0), peer_sequence_number_(0),
pre_secret_len_(0), send_server_key_(false), master_clean_(false),
TLS_(v.major_ >= 3 && v.minor_ >= 1), version_(v), random_(ran)
-{}
+{
+ memset(sessionID_, 0, sizeof(sessionID_));
+}
Connection::~Connection()
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index 396461a6ed5..f7fb1abfa3f 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -28,7 +28,6 @@
#include "yassl_int.hpp"
#include "handshake.hpp"
#include "timer.hpp"
-#include "openssl/ssl.h" // for DH
#ifdef YASSL_PURE_C
@@ -1375,16 +1374,51 @@ Sessions& GetSessions()
static sslFactory* sslFactoryInstance = 0;
-sslFactory& GetSSL_Factory(){
+sslFactory& GetSSL_Factory()
+{
if (!sslFactoryInstance)
sslFactoryInstance = NEW_YS sslFactory;
return *sslFactoryInstance;
}
-void CleanUp()
+static CryptProvider* cryptProviderInstance = 0;
+
+CryptProvider& GetCryptProvider()
+{
+ if (!cryptProviderInstance)
+ cryptProviderInstance = NEW_YS CryptProvider;
+ return *cryptProviderInstance;
+}
+
+
+CryptProvider::~CryptProvider()
+{
+ mySTL::for_each(digestList_.begin(), digestList_.end(), del_ptr_zero());
+ mySTL::for_each(cipherList_.begin(), cipherList_.end(), del_ptr_zero());
+}
+
+
+Digest* CryptProvider::NewMd5()
+{
+ Digest* ptr = NEW_YS MD5();
+ digestList_.push_back(ptr);
+ return ptr;
+}
+
+
+BulkCipher* CryptProvider::NewDesEde()
+{
+ BulkCipher* ptr = NEW_YS DES_EDE();
+ cipherList_.push_back(ptr);
+ return ptr;
+}
+
+
+extern "C" void yaSSL_CleanUp()
{
TaoCrypt::CleanUp();
+ ysDelete(cryptProviderInstance);
ysDelete(sslFactoryInstance);
ysDelete(sessionsInstance);
}
@@ -1978,18 +2012,20 @@ void Security::set_resuming(bool b)
X509_NAME::X509_NAME(const char* n, size_t sz)
- : name_(0)
+ : name_(0), sz_(sz)
{
if (sz) {
name_ = NEW_YS char[sz];
memcpy(name_, n, sz);
}
+ entry_.data = 0;
}
X509_NAME::~X509_NAME()
{
ysArrayDelete(name_);
+ ysArrayDelete(entry_.data);
}
@@ -1999,8 +2035,10 @@ char* X509_NAME::GetName()
}
-X509::X509(const char* i, size_t iSz, const char* s, size_t sSz)
- : issuer_(i, iSz), subject_(s, sSz)
+X509::X509(const char* i, size_t iSz, const char* s, size_t sSz,
+ const char* b, int bSz, const char* a, int aSz)
+ : issuer_(i, iSz), subject_(s, sSz),
+ beforeDate_(b, bSz), afterDate_(a, aSz)
{}
@@ -2016,6 +2054,61 @@ X509_NAME* X509::GetSubject()
}
+ASN1_STRING* X509::GetBefore()
+{
+ return beforeDate_.GetString();
+}
+
+
+ASN1_STRING* X509::GetAfter()
+{
+ return afterDate_.GetString();
+}
+
+
+ASN1_STRING* X509_NAME::GetEntry(int i)
+{
+ if (i < 0 || i >= int(sz_))
+ return 0;
+
+ if (entry_.data)
+ ysArrayDelete(entry_.data);
+ entry_.data = NEW_YS byte[sz_]; // max size;
+
+ memcpy(entry_.data, &name_[i], sz_ - i);
+ if (entry_.data[sz_ -i - 1]) {
+ entry_.data[sz_ - i] = 0;
+ entry_.length = sz_ - i;
+ }
+ else
+ entry_.length = sz_ - i - 1;
+ entry_.type = 0;
+
+ return &entry_;
+}
+
+
+StringHolder::StringHolder(const char* str, int sz)
+{
+ asnString_.length = sz;
+ asnString_.data = NEW_YS byte[sz + 1];
+ memcpy(asnString_.data, str, sz);
+ asnString_.type = 0; // not used for now
+}
+
+
+StringHolder::~StringHolder()
+{
+ ysArrayDelete(asnString_.data);
+}
+
+
+ASN1_STRING* StringHolder::GetString()
+{
+ return &asnString_;
+}
+
+
} // namespace
diff --git a/extra/yassl/taocrypt/benchmark/make.bat b/extra/yassl/taocrypt/benchmark/make.bat
index 63391578cfa..4ebe4b32417 100644
--- a/extra/yassl/taocrypt/benchmark/make.bat
+++ b/extra/yassl/taocrypt/benchmark/make.bat
@@ -1,10 +1,9 @@
-# quick and dirty build file for testing different MSDEVs
+REM quick and dirty build file for testing different MSDEVs
setlocal
set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2
-#set myFLAGS= /I../include /I../../mySTL /c /W3
cl %myFLAGS% benchmark.cpp
-link.exe /out:benchmark.exe ../src/taocrypt.lib benchmark.obj
+link.exe /out:benchmark.exe ../src/taocrypt.lib benchmark.obj advapi32.lib
diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp
index 6a1163fbb1c..da4c0ce1349 100644
--- a/extra/yassl/taocrypt/include/asn.hpp
+++ b/extra/yassl/taocrypt/include/asn.hpp
@@ -79,20 +79,27 @@ enum ASNIdFlag
enum DNTags
{
- COMMON_NAME = 0x03
+ COMMON_NAME = 0x03, // CN
+ SUR_NAME = 0x04, // SN
+ COUNTRY_NAME = 0x06, // C
+ LOCALITY_NAME = 0x07, // L
+ STATE_NAME = 0x08, // ST
+ ORG_NAME = 0x0a, // O
+ ORGUNIT_NAME = 0x0b // OU
};
enum Constants
{
MIN_DATE_SZ = 13,
- MAX_DATE_SZ = 15,
+ MAX_DATE_SZ = 16,
MAX_ALGO_SZ = 16,
MAX_LENGTH_SZ = 5,
MAX_SEQ_SZ = 5, // enum(seq|con) + length(4)
MAX_ALGO_SIZE = 9,
MAX_DIGEST_SZ = 25, // SHA + enum(Bit or Octet) + length(4)
- DSA_SIG_SZ = 40
+ DSA_SIG_SZ = 40,
+ NAME_MAX = 512 // max total of all included names
};
@@ -205,14 +212,14 @@ enum { SHA_SIZE = 20 };
// A Signing Authority
class Signer {
PublicKey key_;
- char* name_;
+ char name_[NAME_MAX];
byte hash_[SHA_SIZE];
public:
Signer(const byte* k, word32 kSz, const char* n, const byte* h);
~Signer();
const PublicKey& GetPublicKey() const { return key_; }
- const char* GetCommonName() const { return name_; }
+ const char* GetName() const { return name_; }
const byte* GetHash() const { return hash_; }
private:
@@ -245,6 +252,8 @@ public:
const char* GetIssuer() const { return issuer_; }
const char* GetCommonName() const { return subject_; }
const byte* GetHash() const { return subjectHash_; }
+ const char* GetBeforeDate() const { return beforeDate_; }
+ const char* GetAfterDate() const { return afterDate_; }
void DecodeToKey();
private:
@@ -257,8 +266,10 @@ private:
byte subjectHash_[SHA_SIZE]; // hash of all Names
byte issuerHash_[SHA_SIZE]; // hash of all Names
byte* signature_;
- char* issuer_; // CommonName
- char* subject_; // CommonName
+ char issuer_[NAME_MAX]; // Names
+ char subject_[NAME_MAX]; // Names
+ char beforeDate_[MAX_DATE_SZ]; // valid before date
+ char afterDate_[MAX_DATE_SZ]; // valid after date
bool verify_; // Default to yes, but could be off
void ReadHeader();
diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp
index 3a5cf62865a..09ca7524ef3 100644
--- a/extra/yassl/taocrypt/include/runtime.hpp
+++ b/extra/yassl/taocrypt/include/runtime.hpp
@@ -28,6 +28,10 @@
#ifndef yaSSL_NEW_HPP
#define yaSSL_NEW_HPP
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef __sun
diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp
index 3efc26ab168..383fe65dea6 100644
--- a/extra/yassl/taocrypt/src/asn.cpp
+++ b/extra/yassl/taocrypt/src/asn.cpp
@@ -213,21 +213,17 @@ void PublicKey::AddToEnd(const byte* data, word32 len)
Signer::Signer(const byte* k, word32 kSz, const char* n, const byte* h)
- : key_(k, kSz), name_(0)
+ : key_(k, kSz)
{
- if (n) {
int sz = strlen(n);
- name_ = NEW_TC char[sz + 1];
memcpy(name_, n, sz);
name_[sz] = 0;
- }
memcpy(hash_, h, SHA::DIGEST_SIZE);
}
Signer::~Signer()
{
- tcArrayDelete(name_);
}
@@ -424,17 +420,19 @@ void DH_Decoder::Decode(DH& key)
CertDecoder::CertDecoder(Source& s, bool decode, SignerList* signers,
bool noVerify, CertType ct)
: BER_Decoder(s), certBegin_(0), sigIndex_(0), sigLength_(0),
- signature_(0), issuer_(0), subject_(0), verify_(!noVerify)
+ signature_(0), verify_(!noVerify)
{
+ issuer_[0] = 0;
+ subject_[0] = 0;
+
if (decode)
Decode(signers, ct);
+
}
CertDecoder::~CertDecoder()
{
- tcArrayDelete(subject_);
- tcArrayDelete(issuer_);
tcArrayDelete(signature_);
}
@@ -672,8 +670,12 @@ void CertDecoder::GetName(NameType nt)
SHA sha;
word32 length = GetSequence(); // length of all distinguished names
+ assert (length < NAME_MAX);
length += source_.get_index();
+ char* ptr = (nt == ISSUER) ? issuer_ : subject_;
+ word32 idx = 0;
+
while (source_.get_index() < length) {
GetSet();
GetSequence();
@@ -694,13 +696,49 @@ void CertDecoder::GetName(NameType nt)
byte id = source_.next();
b = source_.next(); // strType
word32 strLen = GetLength(source_);
+ bool copy = false;
if (id == COMMON_NAME) {
- char*& ptr = (nt == ISSUER) ? issuer_ : subject_;
- ptr = NEW_TC char[strLen + 1];
- memcpy(ptr, source_.get_current(), strLen);
- ptr[strLen] = 0;
+ 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;
+ }
+
sha.Update(source_.get_current(), strLen);
source_.advance(strLen);
}
@@ -711,6 +749,8 @@ void CertDecoder::GetName(NameType nt)
source_.advance(length);
}
}
+ ptr[idx++] = 0;
+
if (nt == ISSUER)
sha.Final(issuerHash_);
else
@@ -744,6 +784,16 @@ void CertDecoder::GetDate(DateType dt)
source_.SetError(BEFORE_DATE_E);
else
source_.SetError(AFTER_DATE_E);
+
+ // save for later use
+ if (dt == BEFORE) {
+ memcpy(beforeDate_, date, length);
+ beforeDate_[length] = 0;
+ }
+ else { // after
+ memcpy(afterDate_, date, length);
+ afterDate_[length] = 0;
+ }
}
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index 82a248ff7da..885ddfbf630 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -2428,7 +2428,7 @@ void PositiveMultiply(Integer& product, const Integer& a, const Integer& b)
product.reg_.CleanNew(RoundupSize(aSize + bSize));
product.sign_ = Integer::POSITIVE;
- WordBlock workspace(aSize + bSize);
+ AlignedWordBlock workspace(aSize + bSize);
AsymmetricMultiply(product.reg_.get_buffer(), workspace.get_buffer(),
a.reg_.get_buffer(), aSize, b.reg_.get_buffer(), bSize);
}
@@ -3375,7 +3375,7 @@ void PositiveDivide(Integer& remainder, Integer& quotient,
quotient.reg_.CleanNew(RoundupSize(aSize-bSize+2));
quotient.sign_ = Integer::POSITIVE;
- WordBlock T(aSize+2*bSize+4);
+ AlignedWordBlock T(aSize+2*bSize+4);
Divide(remainder.reg_.get_buffer(), quotient.reg_.get_buffer(),
T.get_buffer(), a.reg_.get_buffer(), aSize, b.reg_.get_buffer(),
bSize);
@@ -3595,7 +3595,7 @@ Integer Integer::InverseMod(const Integer &m) const
return !u ? Zero() : (m*(*this-u)+1)/(*this);
}
- WordBlock T(m.reg_.size() * 4);
+ AlignedWordBlock T(m.reg_.size() * 4);
Integer r((word)0, m.reg_.size());
unsigned k = AlmostInverse(r.reg_.get_buffer(), T.get_buffer(),
reg_.get_buffer(), reg_.size(),
diff --git a/extra/yassl/taocrypt/src/make.bat b/extra/yassl/taocrypt/src/make.bat
index 5a2ae580b76..ecf7e8f8469 100644
--- a/extra/yassl/taocrypt/src/make.bat
+++ b/extra/yassl/taocrypt/src/make.bat
@@ -1,8 +1,7 @@
-# quick and dirty build file for testing different MSDEVs
+REM quick and dirty build file for testing different MSDEVs
setlocal
set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2
-#set myFLAGS= /I../include /I../../mySTL /c /W3 /O1
cl %myFLAGS% aes.cpp
cl %myFLAGS% aestables.cpp
diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp
index 3d0539187a7..4ef163a7f5d 100644
--- a/extra/yassl/taocrypt/src/misc.cpp
+++ b/extra/yassl/taocrypt/src/misc.cpp
@@ -25,6 +25,15 @@
#include "runtime.hpp"
#include "misc.hpp"
+
+extern "C" {
+
+ // for libcurl configure test, these are the signatures they use
+ // locking handled internally by library
+ char CRYPTO_lock() { return 0;}
+ char CRYPTO_add_lock() { return 0;}
+} // extern "C"
+
#ifdef YASSL_PURE_C
void* operator new(size_t sz, TaoCrypt::new_t)
diff --git a/extra/yassl/taocrypt/src/template_instnt.cpp b/extra/yassl/taocrypt/src/template_instnt.cpp
index 12bcd8238f2..5efd2d32a10 100644
--- a/extra/yassl/taocrypt/src/template_instnt.cpp
+++ b/extra/yassl/taocrypt/src/template_instnt.cpp
@@ -30,11 +30,11 @@
#include "sha.hpp"
#include "md5.hpp"
#include "hmac.hpp"
-#include "ripemd.hpp"
#include "pwdbased.hpp"
#include "algebra.hpp"
#include "vector.hpp"
#include "hash.hpp"
+#include "ripemd.hpp"
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
namespace TaoCrypt {
diff --git a/extra/yassl/taocrypt/taocrypt.dsp b/extra/yassl/taocrypt/taocrypt.dsp
index 13b9a07419b..b741cef0096 100644
--- a/extra/yassl/taocrypt/taocrypt.dsp
+++ b/extra/yassl/taocrypt/taocrypt.dsp
@@ -64,7 +64,8 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "include" /I "..\mySTL" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "include" /I "..\mySTL" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
diff --git a/extra/yassl/taocrypt/test/make.bat b/extra/yassl/taocrypt/test/make.bat
index e1a4cbce7cd..5f01db68d0d 100644
--- a/extra/yassl/taocrypt/test/make.bat
+++ b/extra/yassl/taocrypt/test/make.bat
@@ -1,4 +1,4 @@
-# quick and dirty build file for testing different MSDEVs
+REM quick and dirty build file for testing different MSDEVs
setlocal
set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2
diff --git a/extra/yassl/testsuite/make.bat b/extra/yassl/testsuite/make.bat
index d8a55b0d3af..1bc7ce0513d 100644
--- a/extra/yassl/testsuite/make.bat
+++ b/extra/yassl/testsuite/make.bat
@@ -1,4 +1,4 @@
-# quick and dirty build file for testing different MSDEVs
+REM quick and dirty build file for testing different MSDEVs
setlocal
set myFLAGS= /I../include /I../taocrypt/include /I../mySTL /c /W3 /G6 /O2 /MT /D"WIN32" /D"NO_MAIN_DRIVER"
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
index 79d02b63558..259975fba0b 100644
--- a/extra/yassl/testsuite/test.hpp
+++ b/extra/yassl/testsuite/test.hpp
@@ -27,7 +27,7 @@
#endif /* _WIN32 */
-#if defined(__MACH__) || defined(_WIN32)
+#if !defined(_SOCKLEN_T) && (defined(__MACH__) || defined(_WIN32))
typedef int socklen_t;
#endif
@@ -305,8 +305,8 @@ inline void showPeer(SSL* ssl)
char* subject = X509_NAME_oneline(X509_get_subject_name(peer), 0, 0);
printf("peer's cert info:\n");
- printf("issuer is: %s\n", issuer);
- printf("subject is: %s\n", subject);
+ printf("issuer : %s\n", issuer);
+ printf("subject: %s\n", subject);
free(subject);
free(issuer);
diff --git a/extra/yassl/testsuite/testsuite.cpp b/extra/yassl/testsuite/testsuite.cpp
index af988432a86..1cf6a78ebe7 100644
--- a/extra/yassl/testsuite/testsuite.cpp
+++ b/extra/yassl/testsuite/testsuite.cpp
@@ -91,6 +91,7 @@ int main(int argc, char** argv)
assert(memcmp(input, output, sizeof(input)) == 0);
printf("\nAll tests passed!\n");
+ yaSSL_CleanUp();
return 0;
}
@@ -146,10 +147,10 @@ int test_openSSL_des()
(byte*)key, iv);
byte cipher[16];
- DES_ede3_cbc_encrypt((byte*)data, cipher, dataSz, &key[0], &key[8],
- &key[16], &iv, true);
+ DES_ede3_cbc_encrypt((byte*)data, cipher, dataSz, &key[0], &key[1],
+ &key[2], &iv, true);
byte plain[16];
- DES_ede3_cbc_encrypt(cipher, plain, 16, &key[0], &key[8], &key[16],
+ DES_ede3_cbc_encrypt(cipher, plain, 16, &key[0], &key[1], &key[2],
&iv, false);
return 0;
}
diff --git a/extra/yassl/testsuite/testsuite.dsp b/extra/yassl/testsuite/testsuite.dsp
index f896aa7f020..24c325fa878 100644
--- a/extra/yassl/testsuite/testsuite.dsp
+++ b/extra/yassl/testsuite/testsuite.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX- /O2 /I "../taocrypt/include" /I "../include" /I "../mySTL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "NO_MAIN_DRIVER" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O2 /I "../taocrypt/include" /I "../include" /I "../mySTL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "NO_MAIN_DRIVER" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -67,7 +67,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX- /ZI /Od /I "../taocrypt/include" /I "../include" /I "../mySTL" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "NO_MAIN_DRIVER" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "../taocrypt/include" /I "../include" /I "../mySTL" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "NO_MAIN_DRIVER" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
diff --git a/include/my_dbug.h b/include/my_dbug.h
index b76a3fcc8c9..6e60b599f53 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -40,6 +40,7 @@ extern void _db_doprnt_ _VARARGS((const char *format,...));
extern void _db_dump_(uint _line_,const char *keyword,const char *memory,
uint length);
extern void _db_output_(uint flag);
+extern void _db_end_(void);
extern void _db_lock_file(void);
extern void _db_unlock_file(void);
@@ -66,6 +67,7 @@ extern void _db_unlock_file(void);
#define DBUG_IN_USE (_db_fp_ && _db_fp_ != stderr)
#define DEBUGGER_OFF _no_db_=1;_db_on_=0;
#define DEBUGGER_ON _no_db_=0
+#define DBUG_END() _db_end_ ()
#define DBUG_LOCK_FILE { _db_lock_file(); }
#define DBUG_UNLOCK_FILE { _db_unlock_file(); }
#define DBUG_OUTPUT(A) { _db_output_(A); }
@@ -90,6 +92,7 @@ extern void _db_unlock_file(void);
#define DBUG_IN_USE 0
#define DEBUGGER_OFF
#define DEBUGGER_ON
+#define DBUG_END()
#define DBUG_LOCK_FILE
#define DBUG_UNLOCK_FILE
#define DBUG_OUTPUT(A)
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 202e047dc4e..3e4388413e0 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -332,12 +332,14 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
we want to make sure that no such flags are set.
*/
#if defined(HAVE_SIGACTION) && !defined(my_sigset)
-#define my_sigset(A,B) do { struct sigaction s; sigset_t set; \
+#define my_sigset(A,B) do { struct sigaction s; sigset_t set; int rc; \
+ DBUG_ASSERT((A) != 0); \
sigemptyset(&set); \
s.sa_handler = (B); \
s.sa_mask = set; \
s.sa_flags = 0; \
- sigaction((A), &s, (struct sigaction *) NULL); \
+ rc= sigaction((A), &s, (struct sigaction *) NULL);\
+ DBUG_ASSERT(rc == 0); \
} while (0)
#elif defined(HAVE_SIGSET) && !defined(my_sigset)
#define my_sigset(A,B) sigset((A),(B))
diff --git a/include/my_sys.h b/include/my_sys.h
index 65a295ee39e..229389f1ac5 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -75,6 +75,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */
#define MY_GIVE_INFO 2 /* Give time info about process*/
+#define MY_DONT_FREE_DBUG 4 /* Do not call DBUG_END() in my_end() */
#define ME_HIGHBYTE 8 /* Shift for colours */
#define ME_NOCUR 1 /* Don't use curses message */
diff --git a/include/mysql.h b/include/mysql.h
index 6217ce631b5..3a71e47f414 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -149,7 +149,8 @@ enum mysql_option
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
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_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT
};
struct st_mysql_options {
@@ -164,6 +165,7 @@ struct st_mysql_options {
char *ssl_ca; /* PEM CA file */
char *ssl_capath; /* PEM directory of CA-s? */
char *ssl_cipher; /* cipher to use */
+ my_bool ssl_verify_server_cert; /* if to verify server cert */
char *shared_memory_base_name;
unsigned long max_allowed_packet;
my_bool use_ssl; /* if to use SSL or not */
diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h
index 99271571329..0435ddb815a 100644
--- a/include/sslopt-longopts.h
+++ b/include/sslopt-longopts.h
@@ -37,5 +37,10 @@
{"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl).",
(gptr*) &opt_ssl_key, (gptr*) &opt_ssl_key, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
-
+#ifdef MYSQL_CLIENT
+ {"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT,
+ "Verify server's \"Common Name\" in its cert against hostname used when connecting. This option is disabled by default.",
+ (gptr*) &opt_ssl_verify_server_cert, (gptr*) &opt_ssl_verify_server_cert,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
#endif /* HAVE_OPENSSL */
diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h
index 3b9b10c82e7..7204145fc28 100644
--- a/include/sslopt-vars.h
+++ b/include/sslopt-vars.h
@@ -26,4 +26,7 @@ SSL_STATIC char *opt_ssl_capath = 0;
SSL_STATIC char *opt_ssl_cert = 0;
SSL_STATIC char *opt_ssl_cipher = 0;
SSL_STATIC char *opt_ssl_key = 0;
+#ifdef MYSQL_CLIENT
+SSL_STATIC my_bool opt_ssl_verify_server_cert= 0;
+#endif
#endif
diff --git a/include/violite.h b/include/violite.h
index b48f3724f5b..fd870177c68 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -105,33 +105,22 @@ void vio_timeout(Vio *vio,uint which, uint timeout);
#include <openssl/ssl.h>
#include <openssl/err.h>
-struct st_VioSSLAcceptorFd
+struct st_VioSSLFd
{
SSL_CTX *ssl_context;
- SSL_METHOD *ssl_method;
- struct st_VioSSLAcceptorFd *session_id_context;
};
-/* One copy for client */
-struct st_VioSSLConnectorFd
-{
- SSL_CTX *ssl_context;
- /* function pointers which are only once for SSL client */
- SSL_METHOD *ssl_method;
-};
-
-int sslaccept(struct st_VioSSLAcceptorFd*, Vio *, long timeout);
-int sslconnect(struct st_VioSSLConnectorFd*, Vio *, long timeout);
+int sslaccept(struct st_VioSSLFd*, Vio *, long timeout);
+int sslconnect(struct st_VioSSLFd*, Vio *, long timeout);
-struct st_VioSSLConnectorFd
+struct st_VioSSLFd
*new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
const char *ca_file, const char *ca_path,
const char *cipher);
-struct st_VioSSLAcceptorFd
+struct st_VioSSLFd
*new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
const char *ca_file,const char *ca_path,
const char *cipher);
-Vio *new_VioSSL(struct st_VioSSLAcceptorFd *fd, Vio *sd, int state);
#endif /* HAVE_OPENSSL */
#ifdef HAVE_SMEM
@@ -140,6 +129,8 @@ int vio_write_shared_memory(Vio *vio, const gptr buf, int size);
int vio_close_shared_memory(Vio * vio);
#endif
+void vio_end(void);
+
#ifdef __cplusplus
}
#endif
@@ -204,7 +195,9 @@ struct st_vio
my_bool (*was_interrupted)(Vio*);
int (*vioclose)(Vio*);
void (*timeout)(Vio*, unsigned int which, unsigned int timeout);
+#ifdef HAVE_OPENSSL
void *ssl_arg;
+#endif
#ifdef HAVE_SMEM
HANDLE handle_file_map;
char *handle_map;
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index 3b8f7576049..df819b73ea6 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -3700,6 +3700,37 @@ os_aio_posix_handle(
#endif
/**************************************************************************
+Do a 'last millisecond' check that the page end is sensible;
+reported page checksum errors from Linux seem to wipe over the page end. */
+static
+void
+os_file_check_page_trailers(
+/*========================*/
+ byte* combined_buf, /* in: combined write buffer */
+ ulint total_len) /* in: size of combined_buf, in bytes
+ (a multiple of UNIV_PAGE_SIZE) */
+{
+ ulint len;
+
+ for (len = 0; len + UNIV_PAGE_SIZE <= total_len;
+ len += UNIV_PAGE_SIZE) {
+ byte* buf = combined_buf + len;
+
+ if (memcmp(buf + (FIL_PAGE_LSN + 4), buf + (UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4), 4)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: ERROR: The page to be written seems corrupt!\n"
+"InnoDB: Writing a block of %lu bytes, currently at offset %lu\n",
+ (ulong)total_len, (ulong)len);
+ buf_page_print(buf);
+ fprintf(stderr,
+"InnoDB: ERROR: The page to be written seems corrupt!\n");
+ }
+ }
+}
+
+/**************************************************************************
Does simulated aio. This function should be called by an i/o-handler
thread. */
@@ -3736,7 +3767,6 @@ os_aio_simulated_handle(
ibool ret;
ulint n;
ulint i;
- ulint len2;
segment = os_aio_get_array_and_local_segment(&array, global_segment);
@@ -3943,33 +3973,16 @@ consecutive_loop:
(ulong) total_len);
ut_error;
}
-
- /* Do a 'last millisecond' check that the page end
- is sensible; reported page checksum errors from
- Linux seem to wipe over the page end */
-
- for (len2 = 0; len2 + UNIV_PAGE_SIZE <= total_len;
- len2 += UNIV_PAGE_SIZE) {
- if (mach_read_from_4(combined_buf + len2
- + FIL_PAGE_LSN + 4)
- != mach_read_from_4(combined_buf + len2
- + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
-" InnoDB: ERROR: The page to be written seems corrupt!\n");
- fprintf(stderr,
-"InnoDB: Writing a block of %lu bytes, currently writing at offset %lu\n",
- (ulong)total_len, (ulong)len2);
- buf_page_print(combined_buf + len2);
- fprintf(stderr,
-"InnoDB: ERROR: The page to be written seems corrupt!\n");
- }
- }
+
+ os_file_check_page_trailers(combined_buf, total_len);
}
-
+
ret = os_file_write(slot->name, slot->file, combined_buf,
slot->offset, slot->offset_high, total_len);
+
+ if (array == os_aio_write_array) {
+ os_file_check_page_trailers(combined_buf, total_len);
+ }
} else {
ret = os_file_read(slot->file, combined_buf,
slot->offset, slot->offset_high, total_len);
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index bfec476fde3..c1e0703af10 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -178,7 +178,7 @@ void STDCALL mysql_server_end()
/* If library called my_init(), free memory allocated by it */
if (!org_my_init_done)
{
- my_end(0);
+ my_end(MY_DONT_FREE_DBUG);
#ifndef THREAD
/* Remove TRACING, if enabled by mysql_debug() */
DBUG_POP();
@@ -188,6 +188,7 @@ void STDCALL mysql_server_end()
mysql_thread_end();
finish_client_errs();
free_charsets();
+ vio_end();
mysql_client_init= org_my_init_done= 0;
#ifdef EMBEDDED_SERVER
if (stderror_file)
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 33598748397..73074397086 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -100,15 +100,15 @@ install-data-local:
uninstall-local:
@RM@ -f -r $(DESTDIR)$(testdir)
-std_data/client-key.pem:
+std_data/client-key.pem: $(top_srcdir)/SSL/$(@F)
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
-std_data/client-cert.pem:
+std_data/client-cert.pem: $(top_srcdir)/SSL/$(@F)
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
-std_data/cacert.pem:
+std_data/cacert.pem: $(top_srcdir)/SSL/$(@F)
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
-std_data/server-cert.pem:
+std_data/server-cert.pem: $(top_srcdir)/SSL/$(@F)
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
-std_data/server-key.pem:
+std_data/server-key.pem: $(top_srcdir)/SSL/$(@F)
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
SUFFIXES = .sh
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index 973655a3eb6..6fa6bc73bdb 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -20,6 +20,7 @@ sub mtr_record_dead_children ();
sub mtr_exit ($);
sub sleep_until_file_created ($$$);
sub mtr_kill_processes ($);
+sub mtr_kill_process ($$$$);
# static in C
sub spawn_impl ($$$$$$$$);
@@ -885,6 +886,25 @@ sub mtr_kill_processes ($) {
}
}
+
+sub mtr_kill_process ($$$$) {
+ my $pid= shift;
+ my $signal= shift;
+ my $retries= shift;
+ my $timeout= shift;
+
+ while (1)
+ {
+ kill($signal, $pid);
+
+ last unless kill (0, $pid) and $retries--;
+
+ mtr_debug("Sleep $timeout second waiting for processes to die");
+
+ sleep($timeout);
+ }
+}
+
##############################################################################
#
# When we exit, we kill off all children
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 25c1f6c1ddc..4a9628c0721 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -134,7 +134,6 @@ our $glob_win32= 0; # OS and native Win32 executables
our $glob_win32_perl= 0; # ActiveState Win32 Perl
our $glob_cygwin_perl= 0; # Cygwin Perl
our $glob_cygwin_shell= undef;
-our $glob_use_libtool= 1;
our $glob_mysql_test_dir= undef;
our $glob_mysql_bench_dir= undef;
our $glob_hostname= undef;
@@ -189,6 +188,7 @@ our $exe_slave_mysqld;
our $exe_im;
our $exe_my_print_defaults;
our $lib_udf_example;
+our $exe_libtool;
our $opt_bench= 0;
our $opt_small_bench= 0;
@@ -376,7 +376,6 @@ sub main () {
check_ndbcluster_support(); # We check whether to actually use it later
check_ssl_support();
- check_running_as_root();
environment_setup();
signal_setup();
@@ -443,12 +442,6 @@ sub initial_setup () {
$glob_cygwin_perl= ($^O eq "cygwin");
$glob_win32= ($glob_win32_perl or $glob_cygwin_perl);
- # Use libtool on all platforms except windows
- if ( $glob_win32 )
- {
- $glob_use_libtool= 0;
- }
-
# We require that we are in the "mysql-test" directory
# to run mysql-test-run
@@ -925,6 +918,7 @@ sub command_line_setup () {
path_err => "$opt_vardir/log/im.err",
path_log => "$opt_vardir/log/im.log",
path_pid => "$opt_vardir/run/im.pid",
+ path_angel_pid => "$opt_vardir/run/im.angel.pid",
path_sock => "$sockdir/im.sock",
port => $im_port,
start_timeout => $master->[0]->{'start_timeout'},
@@ -1000,6 +994,21 @@ sub snapshot_setup () {
sub executable_setup () {
+ #
+ # Check if libtool is available in this distribution/clone
+ # we need it when valgrinding or debugging non installed binary
+ # Otherwise valgrind will valgrind the libtool wrapper or bash
+ # and gdb will not find the real executable to debug
+ #
+ if ( -x "../libtool")
+ {
+ $exe_libtool= "../libtool";
+ if ($opt_valgrind or $glob_debugger)
+ {
+ mtr_report("Using \"$exe_libtool\" when running valgrind or debugger");
+ }
+ }
+
if ( $opt_source_dist )
{
if ( $glob_win32 )
@@ -1180,6 +1189,7 @@ sub environment_setup () {
$ENV{'NDB_STATUS_OK'}= "YES";
$ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
+ $ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid};
$ENV{'IM_PORT'}= $instance_manager->{port};
$ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock};
@@ -1336,7 +1346,7 @@ sub kill_and_cleanup () {
sub check_running_as_root () {
# Check if running as root
# i.e a file can be read regardless what mode we set it to
- my $test_file= "test_running_as_root.txt";
+ my $test_file= "$opt_vardir/test_running_as_root.txt";
mtr_tofile($test_file, "MySQL");
chmod(oct("0000"), $test_file);
@@ -1653,6 +1663,7 @@ sub initialize_servers () {
save_installed_db();
}
}
+ check_running_as_root();
}
}
@@ -1804,6 +1815,7 @@ sub im_create_defaults_file($) {
[manager]
pid-file = $instance_manager->{path_pid}
+angel-pid-file = $instance_manager->{path_angel_pid}
socket = $instance_manager->{path_sock}
port = $instance_manager->{port}
password-file = $instance_manager->{password_file}
@@ -1828,7 +1840,7 @@ log-slow-queries = $instance->{path_datadir}/mysqld$server_id.slow.log
language = $path_language
character-sets-dir = $path_charsetsdir
basedir = $path_my_basedir
-server_id =$server_id
+server_id = $server_id
skip-stack-trace
skip-innodb
skip-bdb
@@ -2625,6 +2637,15 @@ sub mysqld_start ($$$$$) {
$exe= undef;
}
+ if ($exe_libtool and $opt_valgrind)
+ {
+ # Add "libtool --mode-execute"
+ # if running in valgrind(to avoid valgrinding bash)
+ unshift(@$args, "--mode=execute", $exe);
+ $exe= $exe_libtool;
+ }
+
+
if ( $type eq 'master' )
{
if ( ! defined $exe or
@@ -2787,6 +2808,18 @@ sub im_start($$) {
sub im_stop($) {
my $instance_manager = shift;
+ # Obtain mysqld-process pids before we start stopping IM (it can delete pid
+ # files).
+
+ my @mysqld_pids = ();
+ my $instances = $instance_manager->{'instances'};
+
+ push(@mysqld_pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}))
+ if -r $instances->[0]->{'path_pid'};
+
+ push(@mysqld_pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}))
+ if -r $instances->[1]->{'path_pid'};
+
# Re-read pid from the file, since during tests Instance Manager could have
# been restarted, so its pid could have been changed.
@@ -2794,34 +2827,79 @@ sub im_stop($) {
mtr_get_pid_from_file($instance_manager->{'path_pid'})
if -f $instance_manager->{'path_pid'};
+ if (-f $instance_manager->{'path_angel_pid'})
+ {
+ $instance_manager->{'angel_pid'} =
+ mtr_get_pid_from_file($instance_manager->{'path_angel_pid'})
+ }
+ else
+ {
+ $instance_manager->{'angel_pid'} = undef;
+ }
+
# Inspired from mtr_stop_mysqld_servers().
start_reap_all();
- # Create list of pids. We should stop Instance Manager and all started
- # mysqld-instances. Some of them may be nonguarded, so IM will not stop them
- # on shutdown.
+ # Try graceful shutdown.
- my @pids = ( $instance_manager->{'pid'} );
- my $instances = $instance_manager->{'instances'};
+ mtr_kill_process($instance_manager->{'pid'}, 'TERM', 10, 1);
- if ( -r $instances->[0]->{'path_pid'} )
+ # Check that all processes died.
+
+ my $clean_shutdown= 0;
+
+ while (1)
{
- push(@pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}));
+ last if kill (0, $instance_manager->{'pid'});
+
+ last if (defined $instance_manager->{'angel_pid'}) &&
+ kill (0, $instance_manager->{'angel_pid'});
+
+ foreach my $pid (@mysqld_pids)
+ {
+ last if kill (0, $pid);
+ }
+
+ $clean_shutdown= 1;
+ last;
}
- if ( -r $instances->[1]->{'path_pid'} )
+ # Kill leftovers (the order is important).
+
+ unless ($clean_shutdown)
{
- push(@pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}));
- }
+ mtr_kill_process($instance_manager->{'angel_pid'}, 'KILL', 10, 1)
+ if defined $instance_manager->{'angel_pid'};
+
+ mtr_kill_process($instance_manager->{'pid'}, 'KILL', 10, 1);
+
+ # Shutdown managed mysqld-processes. Some of them may be nonguarded, so IM
+ # will not stop them on shutdown. So, we should firstly try to end them
+ # legally.
+
+ mtr_kill_processes(\@mysqld_pids);
- # Kill processes.
+ # Complain in error log so that a warning will be shown.
+
+ my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
+
+ open (ERRLOG, ">>$errlog") ||
+ mtr_error("Can not open error log ($errlog)");
+
+ my $ts= localtime();
+ print ERRLOG
+ "Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
+
+ close ERRLOG;
+ }
- mtr_kill_processes(\@pids);
+ # That's all.
stop_reap_all();
$instance_manager->{'pid'} = undef;
+ $instance_manager->{'angel_pid'} = undef;
}
@@ -3122,12 +3200,12 @@ sub run_mysqltest ($) {
debugger_arguments(\$args, \$exe, "client");
}
- if ($glob_use_libtool and $opt_valgrind)
+ if ($exe_libtool and $opt_valgrind)
{
# Add "libtool --mode-execute" before the test to execute
# if running in valgrind(to avoid valgrinding bash)
unshift(@$args, "--mode=execute", $exe);
- $exe= "libtool";
+ $exe= $exe_libtool;
}
if ( $opt_check_testcases )
@@ -3197,9 +3275,9 @@ sub gdb_arguments {
mtr_add_arg($$args, "$type");
mtr_add_arg($$args, "-e");
- if ( $glob_use_libtool )
+ if ( $exe_libtool )
{
- mtr_add_arg($$args, "libtool");
+ mtr_add_arg($$args, $exe_libtool);
mtr_add_arg($$args, "--mode=execute");
}
@@ -3259,9 +3337,9 @@ sub ddd_arguments {
my $save_exe= $$exe;
$$args= [];
- if ( $glob_use_libtool )
+ if ( $exe_libtool )
{
- $$exe= "libtool";
+ $$exe= $exe_libtool;
mtr_add_arg($$args, "--mode=execute");
mtr_add_arg($$args, "ddd");
}
@@ -3282,6 +3360,8 @@ sub debugger_arguments {
my $exe= shift;
my $debugger= $opt_debugger || $opt_client_debugger;
+ # FIXME Need to change the below "eq"'s to
+ # "case unsensitive string contains"
if ( $debugger eq "vcexpress" or $debugger eq "vc")
{
# vc[express] /debugexe exe arg1 .. argn
diff --git a/mysql-test/r/blackhole.result b/mysql-test/r/blackhole.result
index 140d7e73d48..a4c057f256c 100644
--- a/mysql-test/r/blackhole.result
+++ b/mysql-test/r/blackhole.result
@@ -123,3 +123,11 @@ master-bin.000001 # Query 1 # use `test`; create table t3 like t1
master-bin.000001 # Query 1 # use `test`; insert into t1 select * from t3
master-bin.000001 # Query 1 # use `test`; replace into t1 select * from t3
drop table t1,t2,t3;
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+create table t1 (c char(20)) engine=MyISAM;
+insert into t1 values ("Monty"),("WAX"),("Walrus");
+alter table t1 engine=blackhole;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+drop table t1;
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index 8349d6e9338..cf358e6a404 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -103,8 +103,8 @@ t1 CREATE TABLE `t1` (
`c2` varchar(1) character set latin1 collate latin1_danish_ci NOT NULL default '',
`c3` varbinary(1) NOT NULL default '',
`c4` varbinary(1) NOT NULL default '',
- `c5` varbinary(3) NOT NULL default '',
- `c6` varbinary(3) NOT NULL default '',
+ `c5` varbinary(4) NOT NULL default '',
+ `c6` varbinary(4) NOT NULL default '',
`c7` decimal(2,1) NOT NULL default '0.0',
`c8` decimal(2,1) NOT NULL default '0.0',
`c9` decimal(2,1) default NULL,
@@ -152,11 +152,11 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`COALESCE(1)` int(1) NOT NULL default '0',
- `COALESCE(1.0)` decimal(2,1) unsigned NOT NULL default '0.0',
+ `COALESCE(1.0)` decimal(2,1) NOT NULL default '0.0',
`COALESCE('a')` varchar(1) NOT NULL default '',
`COALESCE(1,1.0)` decimal(2,1) NOT NULL default '0.0',
`COALESCE(1,'1')` varbinary(1) NOT NULL default '',
- `COALESCE(1.1,'1')` varbinary(3) NOT NULL default '',
+ `COALESCE(1.1,'1')` varbinary(4) NOT NULL default '',
`COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index a6ad95570f8..89b17d69f40 100644
--- a/mysql-test/r/distinct.result
+++ b/mysql-test/r/distinct.result
@@ -533,3 +533,15 @@ select count(distinct concat(x,y)) from t1;
count(distinct concat(x,y))
2
drop table t1;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b));
+INSERT INTO t1 VALUES (1, 101);
+INSERT INTO t1 SELECT a + 1, a + 101 FROM t1;
+INSERT INTO t1 SELECT a + 2, a + 102 FROM t1;
+INSERT INTO t1 SELECT a + 4, a + 104 FROM t1;
+INSERT INTO t1 SELECT a + 8, a + 108 FROM t1;
+EXPLAIN SELECT DISTINCT a,a FROM t1 WHERE b < 12 ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 8 NULL 16 Using where; Using index
+SELECT DISTINCT a,a FROM t1 WHERE b < 12 ORDER BY a;
+a a
+DROP TABLE t1;
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index d66dec741bd..75e1548cdee 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -53,3 +53,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE ÔÁÂ ref ÉÎÄ0,ÉÎÄ01 ÉÎÄ0 5 const 1 Using where; Using index
drop table ÔÁÂ;
set names latin1;
+select 3 into @v1;
+explain select 3 into @v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index e3257ce5fd0..e38e2624e19 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -326,3 +326,20 @@ deallocate prepare s;
set @str=NULL;
drop table t2;
drop table t1;
+create table t1 (
+some_id smallint(5) unsigned,
+key (some_id)
+);
+insert into t1 values (1),(2);
+select some_id from t1 where some_id not in(2,-1);
+some_id
+1
+select some_id from t1 where some_id not in(-4,-1,-4);
+some_id
+1
+2
+select some_id from t1 where some_id not in(-4,-1,3423534,2342342);
+some_id
+1
+2
+drop table t1;
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index aed79e7f8fa..a17661d26d0 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1017,6 +1017,13 @@ t
1000000
1
drop table t1;
+select load_file("lkjlkj");
+load_file("lkjlkj")
+NULL
+select ifnull(load_file("lkjlkj"),"it's null");
+ifnull(load_file("lkjlkj"),"it's null")
+it's null
+End of 4.1 tests
create table t1 (d decimal default null);
insert into t1 values (null);
select format(d, 2) from t1;
@@ -1039,4 +1046,10 @@ cast(ltrim(' 20.06 ') as decimal(19,2))
select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2));
cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2))
20.06
+select conv("18383815659218730760",10,10) + 0;
+conv("18383815659218730760",10,10) + 0
+1.8383815659219e+19
+select "18383815659218730760" + 0;
+"18383815659218730760" + 0
+1.8383815659219e+19
End of 5.0 tests
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index fdb4a0c5996..0e029802555 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -732,6 +732,25 @@ SELECT count(*) FROM t1 WHERE d>FROM_DAYS(TO_DAYS(@TMP)) AND d<=FROM_DAYS(TO_DAY
count(*)
3
DROP TABLE t1;
+select last_day('2005-00-00');
+last_day('2005-00-00')
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2005-00-00'
+select last_day('2005-00-01');
+last_day('2005-00-01')
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2005-00-01'
+select last_day('2005-01-00');
+last_day('2005-01-00')
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2005-01-00'
+select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
+monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
+monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m'))
+NULL NULL January NULL
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index 6370f7699b3..f9b55cc6a7b 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -2116,3 +2116,25 @@ COUNT(DISTINCT a)
1
DROP TABLE t1;
DROP PROCEDURE a;
+CREATE TABLE t1 (a varchar(64) NOT NULL default '', PRIMARY KEY(a));
+INSERT INTO t1 (a) VALUES
+(''), ('CENTRAL'), ('EASTERN'), ('GREATER LONDON'),
+('NORTH CENTRAL'), ('NORTH EAST'), ('NORTH WEST'), ('SCOTLAND'),
+('SOUTH EAST'), ('SOUTH WEST'), ('WESTERN');
+EXPLAIN SELECT DISTINCT a,a FROM t1 ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL PRIMARY 66 NULL 12 Using index for group-by
+SELECT DISTINCT a,a FROM t1 ORDER BY a;
+a a
+
+CENTRAL CENTRAL
+EASTERN EASTERN
+GREATER LONDON GREATER LONDON
+NORTH CENTRAL NORTH CENTRAL
+NORTH EAST NORTH EAST
+NORTH WEST NORTH WEST
+SCOTLAND SCOTLAND
+SOUTH EAST SOUTH EAST
+SOUTH WEST SOUTH WEST
+WESTERN WESTERN
+DROP TABLE t1;
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index a37f260ff31..68b13b5fc0a 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -12,7 +12,7 @@ explain extended select count(a) as b from t1 where a=0 having b >=0;
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
Warnings:
-Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where 0 having (count(`test`.`t1`.`a`) >= 0)
+Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where 0 having (`b` >= 0)
drop table t1;
CREATE TABLE t1 (
raw_id int(10) NOT NULL default '0',
diff --git a/mysql-test/r/im_options_set.result b/mysql-test/r/im_options_set.result
index 0d2fa699fc7..5e6c740624e 100644
--- a/mysql-test/r/im_options_set.result
+++ b/mysql-test/r/im_options_set.result
@@ -1,11 +1,11 @@
-server_id =1
-server_id =2
+server_id = 1
+server_id = 2
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
SET mysqld1.server_id = 11;
server_id =11
-server_id =2
+server_id = 2
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
diff --git a/mysql-test/r/im_options_unset.result b/mysql-test/r/im_options_unset.result
index 834152c35d2..bf54025edb7 100644
--- a/mysql-test/r/im_options_unset.result
+++ b/mysql-test/r/im_options_unset.result
@@ -1,10 +1,10 @@
-server_id =1
-server_id =2
+server_id = 1
+server_id = 2
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
UNSET mysqld1.server_id;
-server_id =2
+server_id = 2
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index d5fb046d319..633b11e1f1b 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1083,11 +1083,6 @@ DROP TABLE t1;
DROP VIEW v1;
DROP FUNCTION func1;
DROP FUNCTION func2;
-create database mysqltest;
-create table mysqltest.t1(a int);
-select table_schema from information_schema.tables where table_schema='mysqltest';
-table_schema
-drop database mysqltest;
select column_type, group_concat(table_schema, '.', table_name), count(*) as num
from information_schema.columns where
table_schema='information_schema' and
@@ -1096,3 +1091,20 @@ group by column_type order by num;
column_type group_concat(table_schema, '.', table_name) num
varchar(20) information_schema.COLUMNS 1
varchar(7) information_schema.ROUTINES,information_schema.VIEWS 2
+create table t1(f1 char(1) not null, f2 char(9) not null)
+default character set utf8;
+select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from
+information_schema.columns where table_schema='test' and table_name = 't1';
+CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH
+1 3
+9 27
+drop table t1;
+use mysql;
+INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL',
+'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03',
+'2006-03-02 18:40:03','','');
+select routine_name from information_schema.routines;
+routine_name
+
+delete from proc where name='';
+use test;
diff --git a/mysql-test/r/information_schema_chmod.result b/mysql-test/r/information_schema_chmod.result
new file mode 100644
index 00000000000..36124559439
--- /dev/null
+++ b/mysql-test/r/information_schema_chmod.result
@@ -0,0 +1,5 @@
+create database mysqltest;
+create table mysqltest.t1(a int);
+select table_schema from information_schema.tables where table_schema='mysqltest';
+table_schema
+drop database mysqltest;
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index ecf76d477a0..86288caf398 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -700,8 +700,8 @@ ERROR 42S22: Unknown column 't1.b' in 'on clause'
select * from information_schema.statistics join information_schema.columns
using(table_name,column_name) where table_name='user';
TABLE_NAME COLUMN_NAME TABLE_CATALOG TABLE_SCHEMA NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT TABLE_CATALOG TABLE_SCHEMA ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-user Host NULL mysql 0 mysql PRIMARY 1 A NULL NULL NULL BTREE NULL mysql 1 NO char 20 60 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
-user User NULL mysql 0 mysql PRIMARY 2 A 5 NULL NULL BTREE NULL mysql 2 NO char 5 16 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
+user Host NULL mysql 0 mysql PRIMARY 1 A NULL NULL NULL BTREE NULL mysql 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
+user User NULL mysql 0 mysql PRIMARY 2 A 5 NULL NULL BTREE NULL mysql 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
drop table t1;
drop table t2;
drop table t3;
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 694bab2597c..eae023813b5 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1151,6 +1151,63 @@ EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index
-1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index
+1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where
+DROP TABLE t1,t2;
+DROP VIEW IF EXISTS v1,v2;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a int);
+CREATE table t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (1), (1), (3);
+INSERT INTO t2 VALUES (2), (3);
+CREATE VIEW v1 AS SELECT a FROM t1 JOIN t2 ON t1.a=t2.b;
+CREATE VIEW v2 AS SELECT b FROM t2 JOIN t1 ON t2.b=t1.a;
+SELECT v1.a, v2. b
+FROM v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3)
+GROUP BY v1.a;
+a b
+2 NULL
+3 3
+SELECT v1.a, v2. b
+FROM { OJ v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3) }
+GROUP BY v1.a;
+a b
+2 NULL
+3 3
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (2), (3);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1 OR 1);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (0 OR 1);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 2=2);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 1=0);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
DROP TABLE t1,t2;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 58e1f86b3f9..9a34d6fba58 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -768,3 +768,11 @@ Table Op Msg_type Msg_text
test.t1 check status OK
test.t2 check status OK
drop table t1, t2, t3;
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+create table t1 (c char(20)) engine=MyISAM;
+insert into t1 values ("Monty"),("WAX"),("Walrus");
+alter table t1 engine=MERGE;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+drop table t1;
diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result
index 0a170e16188..50b0b6ae294 100644
--- a/mysql-test/r/metadata.result
+++ b/mysql-test/r/metadata.result
@@ -2,7 +2,7 @@ drop table if exists t1,t2;
select 1, 1.0, -1, "hello", NULL;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def 1 8 1 1 N 32897 0 63
-def 1.0 246 3 3 N 161 1 63
+def 1.0 246 4 3 N 129 1 63
def -1 8 2 2 N 32897 0 63
def hello 253 5 5 N 1 31 8
def NULL 6 0 0 Y 32896 0 63
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index a067d3ad0f8..4b7084e813c 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -74,7 +74,7 @@ c_cp932
+----------------------+------------+--------+
| >a < | b | 123421 |
| >a < | 0123456789 | 4 |
-| >abcd< | NULL | 4 |
+| >abcd< | | 4 |
+----------------------+------------+--------+
+------+------+---------------------------+
| i | j | k |
@@ -94,6 +94,14 @@ c_cp932
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i | int(11) | YES | | NULL | |
-| j | int(11) | NO | | NULL | |
+| j | int(11) | NO | | | |
| k | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
++------+------+
+| i | s1 |
++------+------+
+| 1 | x |
+| 2 | NULL |
+| 3 | |
++------+------+
+End of 5.0 tests
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 50e4cc28d93..664833fab2a 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -189,4 +189,5 @@ HEX(f)
select HEX(f) from t4;
HEX(f)
835C
+flush logs;
drop table t1, t2, t03, t04, t3, t4;
diff --git a/mysql-test/r/ndb_autodiscover3.result b/mysql-test/r/ndb_autodiscover3.result
new file mode 100644
index 00000000000..8bc1b968436
--- /dev/null
+++ b/mysql-test/r/ndb_autodiscover3.result
@@ -0,0 +1,45 @@
+drop table if exists t1, t2;
+create table t1 (a int key) engine=ndbcluster;
+begin;
+insert into t1 values (1);
+insert into t1 values (2);
+ERROR HY000: Got temporary error 4025 'Node failure caused abort of transaction' from ndbcluster
+commit;
+ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
+drop table t1;
+create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster;
+insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1);
+select * from t2 order by a limit 3;
+a b
+1 1
+2 1
+3 1
+create table t2 (a int key) engine=ndbcluster;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t2 order by a limit 3;
+a
+1
+2
+3
+select * from t2 order by a limit 3;
+ERROR HY000: Can't lock file (errno: 241)
+select * from t2 order by a limit 3;
+a
+1
+2
+3
+show tables;
+Tables_in_test
+create table t2 (a int key) engine=ndbcluster;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t2 order by a limit 3;
+a
+1
+2
+3
+select * from t2 order by a limit 3;
+a
+1
+2
+3
+drop table t2;
diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result
index 91382619b6c..1fcfb11525e 100644
--- a/mysql-test/r/openssl_1.result
+++ b/mysql-test/r/openssl_1.result
@@ -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/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com";
-grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/emailAddress=abstract.mysql.developer@mysql.com";
flush privileges;
SHOW STATUS LIKE 'Ssl_cipher';
Variable_name Value
@@ -41,3 +41,10 @@ ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1
drop user ssl_user1@localhost, ssl_user2@localhost,
ssl_user3@localhost, ssl_user4@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
+Error when connection to server using SSL:Unable to get private key from ''
+mysqltest: Could not open connection 'default': 2026 SSL connection error
+Error when connection to server using SSL:Unable to get certificate from ''
+mysqltest: Could not open connection 'default': 2026 SSL connection error
diff --git a/mysql-test/r/outfile.result b/mysql-test/r/outfile.result
index ee8c3249c9d..040dff576f8 100644
--- a/mysql-test/r/outfile.result
+++ b/mysql-test/r/outfile.result
Binary files differ
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index 603de2afe4e..207d9ea7475 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -1777,7 +1777,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1807,7 +1807,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result
index 9e635f60f14..13aa549949c 100644
--- a/mysql-test/r/ps_3innodb.result
+++ b/mysql-test/r/ps_3innodb.result
@@ -1760,7 +1760,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1790,7 +1790,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result
index fd51c71cad6..a08dae945bd 100644
--- a/mysql-test/r/ps_4heap.result
+++ b/mysql-test/r/ps_4heap.result
@@ -1761,7 +1761,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1791,7 +1791,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result
index 876f7615672..6682b085097 100644
--- a/mysql-test/r/ps_5merge.result
+++ b/mysql-test/r/ps_5merge.result
@@ -1697,7 +1697,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1727,7 +1727,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
@@ -4711,7 +4711,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -4741,7 +4741,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result
index c39621d184f..dc3b984949d 100644
--- a/mysql-test/r/ps_6bdb.result
+++ b/mysql-test/r/ps_6bdb.result
@@ -1760,7 +1760,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1790,7 +1790,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result
index 7c83099311e..000a20da655 100644
--- a/mysql-test/r/ps_7ndb.result
+++ b/mysql-test/r/ps_7ndb.result
@@ -1760,7 +1760,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1790,7 +1790,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/rpl_temporary.result b/mysql-test/r/rpl_temporary.result
index 42e7712750c..751dc7754f7 100644
--- a/mysql-test/r/rpl_temporary.result
+++ b/mysql-test/r/rpl_temporary.result
@@ -103,17 +103,24 @@ f
1
drop temporary table t4;
drop table t5;
-set @session.pseudo_thread_id=100;
+set @@session.pseudo_thread_id=100;
create temporary table t101 (id int);
create temporary table t102 (id int);
-set @session.pseudo_thread_id=200;
+set @@session.pseudo_thread_id=200;
create temporary table t201 (id int);
-create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
-set @con1_id=connection_id();
-kill @con1_id;
+create temporary table `t``201` (id int);
+create temporary table `#sql_not_user_table202` (id int);
+set @@session.pseudo_thread_id=300;
+create temporary table t301 (id int);
+create temporary table t302 (id int);
+create temporary table `#sql_not_user_table303` (id int);
create table t1(f int);
insert into t1 values (1);
select * from t1 /* must be 1 */;
f
1
drop table t1;
+select * from t1;
+a
+1
+drop table t1;
diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result
index b584e04ed57..60b956785ba 100644
--- a/mysql-test/r/rpl_until.result
+++ b/mysql-test/r/rpl_until.result
@@ -29,9 +29,40 @@ n
2
3
4
-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
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 319 # Master master-bin.000001 319 No #
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 776
+Relay_Log_File slave-relay-bin.000004
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running #
+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 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 319
+Relay_Log_Space #
+Until_Condition Master
+Until_Log_File master-bin.000001
+Until_Log_Pos 319
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
select * from t1;
n
@@ -39,23 +70,116 @@ n
2
3
4
-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
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 319 # Master master-no-such-bin.000001 291 No #
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 776
+Relay_Log_File slave-relay-bin.000004
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running #
+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 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 319
+Relay_Log_Space #
+Until_Condition Master
+Until_Log_File master-no-such-bin.000001
+Until_Log_Pos 291
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746;
select * from t2;
n
1
2
-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
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 608 # Relay slave-relay-bin.000004 746 No #
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 776
+Relay_Log_File slave-relay-bin.000004
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running #
+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 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 608
+Relay_Log_Space #
+Until_Condition Relay
+Until_Log_File slave-relay-bin.000004
+Until_Log_Pos 746
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave;
stop slave;
start slave until master_log_file='master-bin.000001', master_log_pos=776;
-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
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 776 # Master master-bin.000001 776 No #
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 776
+Relay_Log_File slave-relay-bin.000004
+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 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 776
+Relay_Log_Space #
+Until_Condition Master
+Until_Log_File master-bin.000001
+Until_Log_Pos 776
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave until master_log_file='master-bin', master_log_pos=561;
ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index ea85025a37b..335637b787f 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -3411,3 +3411,38 @@ 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 3 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;
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index a49b282ddb7..924963017eb 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -282,9 +282,9 @@ select @tmp_x, @tmp_y, @tmp_z|
@tmp_x @tmp_y @tmp_z
42 45 87
call p(42, 43, @tmp_z)|
-ERROR 42000: OUT or INOUT argument 2 for routine test.p is not a variable
+ERROR 42000: OUT or INOUT argument 2 for routine test.p is not a variable or NEW pseudo-variable in BEFORE trigger
call p(42, @tmp_y, 43)|
-ERROR 42000: OUT or INOUT argument 3 for routine test.p is not a variable
+ERROR 42000: OUT or INOUT argument 3 for routine test.p is not a variable or NEW pseudo-variable in BEFORE trigger
drop procedure p|
create procedure p() begin end|
lock table t1 read|
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 59ce1d13d2b..746cd8f00d4 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -4904,4 +4904,60 @@ schema_name
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
routine_name routine_schema
+drop function if exists bug12472|
+create function bug12472() returns int return (select count(*) from t1)|
+create table t3 as select bug12472() as i|
+show create table t3|
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `i` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t3|
+i
+0
+drop table t3|
+create view v1 as select bug12472() as j|
+create table t3 as select * from v1|
+show create table t3|
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `j` bigint(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t3|
+j
+0
+drop table t3|
+drop view v1|
+drop function bug12472|
+DROP FUNCTION IF EXISTS bug18589_f1|
+DROP PROCEDURE IF EXISTS bug18589_p1|
+DROP PROCEDURE IF EXISTS bug18589_p2|
+CREATE FUNCTION bug18589_f1(arg TEXT) RETURNS TEXT
+BEGIN
+RETURN CONCAT(arg, "");
+END|
+CREATE PROCEDURE bug18589_p1(arg TEXT, OUT ret TEXT)
+BEGIN
+SET ret = CONCAT(arg, "");
+END|
+CREATE PROCEDURE bug18589_p2(arg TEXT)
+BEGIN
+DECLARE v TEXT;
+CALL bug18589_p1(arg, v);
+SELECT v;
+END|
+SELECT bug18589_f1(REPEAT("a", 767))|
+bug18589_f1(REPEAT("a", 767))
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+SET @bug18589_v1 = ""|
+CALL bug18589_p1(REPEAT("a", 767), @bug18589_v1)|
+SELECT @bug18589_v1|
+@bug18589_v1
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+CALL bug18589_p2(REPEAT("a", 767))|
+v
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+DROP FUNCTION bug18589_f1|
+DROP PROCEDURE bug18589_p1|
+DROP PROCEDURE bug18589_p2|
drop table t1,t2;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 14b05238e14..056457a4786 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1480,7 +1480,7 @@ Note 1003 select `test`.`t1`.`s1` AS `s1`,not(<in_optimizer>(`test`.`t1`.`s1`,<e
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 1 Using index; Using where
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index; Using where
Warnings:
Note 1003 select `test`.`t1`.`s1` AS `s1`,not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < _latin1'a2'))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
drop table t1,t2;
@@ -3169,3 +3169,17 @@ create table t2 (a int, b int);
insert into t2 values (2, 1), (1, 0);
delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
diff --git a/mysql-test/r/trigger-grant.result b/mysql-test/r/trigger-grant.result
index 87e5e11d779..f6384d479b7 100644
--- a/mysql-test/r/trigger-grant.result
+++ b/mysql-test/r/trigger-grant.result
@@ -310,3 +310,87 @@ SELECT @mysqltest_var;
Hello, world!
DROP USER mysqltest_u1@localhost;
DROP DATABASE mysqltest_db1;
+DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
+FLUSH PRIVILEGES;
+DROP DATABASE IF EXISTS mysqltest_db1;
+CREATE DATABASE mysqltest_db1;
+USE mysqltest_db1;
+CREATE TABLE t1 (i1 INT);
+CREATE TABLE t2 (i1 INT);
+CREATE USER mysqltest_dfn@localhost;
+CREATE USER mysqltest_inv@localhost;
+GRANT EXECUTE, CREATE ROUTINE, SUPER ON *.* TO mysqltest_dfn@localhost;
+GRANT INSERT ON mysqltest_db1.* TO mysqltest_inv@localhost;
+CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 3;
+CREATE PROCEDURE p2(INOUT i INT) DETERMINISTIC NO SQL SET i = i * 5;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+CALL p2(NEW.i1);
+INSERT INTO t1 VALUES (7);
+ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+INSERT INTO t2 VALUES (11);
+ERROR 42000: SELECT,UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+GRANT SELECT ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+CALL p2(NEW.i1);
+INSERT INTO t1 VALUES (13);
+ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+INSERT INTO t2 VALUES (17);
+ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
+REVOKE SELECT ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+CALL p2(NEW.i1);
+INSERT INTO t1 VALUES (19);
+INSERT INTO t2 VALUES (23);
+ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
+REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+GRANT SELECT, UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+CALL p2(NEW.i1);
+INSERT INTO t1 VALUES (29);
+INSERT INTO t2 VALUES (31);
+REVOKE SELECT, UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 37;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+INSERT INTO t1 VALUES (41);
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(IN i INT) DETERMINISTIC NO SQL SET @v1 = i + 43;
+INSERT INTO t1 VALUES (47);
+ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(INOUT i INT) DETERMINISTIC NO SQL SET i = i + 51;
+INSERT INTO t1 VALUES (53);
+ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+DROP PROCEDURE p1;
+REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+DROP TRIGGER t1_bi;
+DROP USER mysqltest_inv@localhost;
+DROP USER mysqltest_dfn@localhost;
+DROP TABLE t2;
+DROP TABLE t1;
+DROP DATABASE mysqltest_db1;
+USE test;
+End of 5.0 tests.
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 6a689437482..8b4aba367fb 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -998,3 +998,95 @@ SELECT * FROM t1 WHERE conn_id != trigger_conn_id;
conn_id trigger_conn_id
DROP TRIGGER t1_bi;
DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (i1 INT);
+SET @save_sql_mode=@@sql_mode;
+SET SQL_MODE='';
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+SET @x = 5/0;
+SET SQL_MODE='traditional';
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+SET @x = 5/0;
+SET @x=1;
+INSERT INTO t1 VALUES (@x);
+SELECT @x;
+@x
+NULL
+SET @x=2;
+UPDATE t1 SET i1 = @x;
+ERROR 22012: Division by 0
+SELECT @x;
+@x
+2
+SET SQL_MODE='';
+SET @x=3;
+INSERT INTO t1 VALUES (@x);
+SELECT @x;
+@x
+NULL
+SET @x=4;
+UPDATE t1 SET i1 = @x;
+ERROR 22012: Division by 0
+SELECT @x;
+@x
+4
+SET @@sql_mode=@save_sql_mode;
+DROP TRIGGER t1_ai;
+DROP TRIGGER t1_au;
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+CREATE TABLE t1 (i1 INT);
+INSERT INTO t1 VALUES (3);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET i1 = 5;
+CREATE PROCEDURE p2(INOUT i1 INT) DETERMINISTIC NO SQL SET i1 = i1 * 7;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+CALL p1(NEW.i1);
+CALL p2(NEW.i1);
+END//
+UPDATE t1 SET i1 = 11 WHERE i1 = 3;
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (13);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 17;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+CALL p1(OLD.i1);
+UPDATE t1 SET i1 = 19 WHERE i1 = 13;
+ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (23);
+CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 29;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+CALL p1(OLD.i1);
+UPDATE t1 SET i1 = 31 WHERE i1 = 23;
+ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (37);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 41;
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+UPDATE t1 SET i1 = 43 WHERE i1 = 37;
+ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
+DROP TRIGGER t1_au;
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (47);
+CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 49;
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+UPDATE t1 SET i1 = 51 WHERE i1 = 47;
+ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
+DROP TRIGGER t1_au;
+DROP PROCEDURE p1;
+SELECT * FROM t1;
+i1
+35
+13
+23
+43
+51
+DROP TABLE t1;
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index e941e740fcb..61482ab282c 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -245,22 +245,22 @@ show warnings;
Level Code Message
desc t1;
Field Type Null Key Default Extra
-x decimal(21,2) unsigned NO 0.00
+x decimal(21,2) NO 0.00
drop table t1;
create table t1 select 0.0 x;
desc t1;
Field Type Null Key Default Extra
-x decimal(2,1) unsigned NO 0.0
+x decimal(2,1) NO 0.0
create table t2 select 105213674794682365.00 y;
desc t2;
Field Type Null Key Default Extra
-y decimal(20,2) unsigned NO 0.00
+y decimal(20,2) NO 0.00
create table t3 select x+y a from t1,t2;
show warnings;
Level Code Message
desc t3;
Field Type Null Key Default Extra
-a decimal(21,2) unsigned NO 0.00
+a decimal(21,2) NO 0.00
drop table t1,t2,t3;
create table t1 (s1 float(0,2));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 938dccc864c..968c6d3ec6f 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -68,10 +68,10 @@ NULL 1.1 NULL NULL NULL 1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `nullif(1.1, 1.1)` decimal(2,1) unsigned default NULL,
- `nullif(1.1, 1.2)` decimal(2,1) unsigned default NULL,
- `nullif(1.1, 0.11e1)` decimal(2,1) unsigned default NULL,
- `nullif(1.0, 1)` decimal(2,1) unsigned default NULL,
+ `nullif(1.1, 1.1)` decimal(2,1) default NULL,
+ `nullif(1.1, 1.2)` decimal(2,1) default NULL,
+ `nullif(1.1, 0.11e1)` decimal(2,1) default NULL,
+ `nullif(1.0, 1)` decimal(2,1) default NULL,
`nullif(1, 1.0)` int(1) default NULL,
`nullif(1, 1.1)` int(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
@@ -174,9 +174,9 @@ create table t1 select round(15.4,-1), truncate(-5678.123451,-3), abs(-1.1), -(-
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `round(15.4,-1)` decimal(3,0) unsigned NOT NULL default '0',
+ `round(15.4,-1)` decimal(3,0) NOT NULL default '0',
`truncate(-5678.123451,-3)` decimal(4,0) NOT NULL default '0',
- `abs(-1.1)` decimal(2,1) NOT NULL default '0.0',
+ `abs(-1.1)` decimal(3,1) NOT NULL default '0.0',
`-(-1.1)` decimal(2,1) NOT NULL default '0.0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
@@ -771,7 +771,7 @@ create table t1 as select 0.5;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `0.5` decimal(2,1) unsigned NOT NULL default '0.0'
+ `0.5` decimal(2,1) NOT NULL default '0.0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select round(1.5),round(2.5);
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 70586a3e1e9..8cee60cf49a 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -1,4 +1,31 @@
drop table if exists t1,t2;
+set @my_binlog_cache_size =@@global.binlog_cache_size;
+set @my_connect_timeout =@@global.connect_timeout;
+set @my_delayed_insert_timeout =@@global.delayed_insert_timeout;
+set @my_delayed_queue_size =@@global.delayed_queue_size;
+set @my_flush =@@global.flush;
+set @my_flush_time =@@global.flush_time;
+set @my_key_buffer_size =@@global.key_buffer_size;
+set @my_max_binlog_cache_size =@@global.max_binlog_cache_size;
+set @my_max_binlog_size =@@global.max_binlog_size;
+set @my_max_connect_errors =@@global.max_connect_errors;
+set @my_max_delayed_threads =@@global.max_delayed_threads;
+set @my_max_heap_table_size =@@global.max_heap_table_size;
+set @my_max_insert_delayed_threads=@@global.max_insert_delayed_threads;
+set @my_max_join_size =@@global.max_join_size;
+set @my_max_user_connections =@@global.max_user_connections;
+set @my_max_write_lock_count =@@global.max_write_lock_count;
+set @my_myisam_data_pointer_size =@@global.myisam_data_pointer_size;
+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;
+set @my_storage_engine =@@global.storage_engine;
+set @my_thread_cache_size =@@global.thread_cache_size;
set @`test`=1;
select @test, @`test`, @TEST, @`TEST`, @"teSt";
@test @`test` @TEST @`TEST` @"teSt"
@@ -641,3 +668,30 @@ show variables like 'log_queries_not_using_indexes';
Variable_name Value
log_queries_not_using_indexes OFF
End of 5.0 tests
+set global binlog_cache_size =@my_binlog_cache_size;
+set global connect_timeout =@my_connect_timeout;
+set global delayed_insert_timeout =@my_delayed_insert_timeout;
+set global delayed_queue_size =@my_delayed_queue_size;
+set global flush =@my_flush;
+set global flush_time =@my_flush_time;
+set global key_buffer_size =@my_key_buffer_size;
+set global max_binlog_cache_size =default;
+set global max_binlog_size =@my_max_binlog_size;
+set global max_connect_errors =@my_max_connect_errors;
+set global max_delayed_threads =@my_max_delayed_threads;
+set global max_heap_table_size =@my_max_heap_table_size;
+set global max_insert_delayed_threads=@my_max_insert_delayed_threads;
+set global max_join_size =@my_max_join_size;
+set global max_user_connections =@my_max_user_connections;
+set global max_write_lock_count =@my_max_write_lock_count;
+set global myisam_data_pointer_size =@my_myisam_data_pointer_size;
+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;
+set global storage_engine =@my_storage_engine;
+set global thread_cache_size =@my_thread_cache_size;
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 667d10cd145..9c991c9c01c 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -706,7 +706,7 @@ create view v1 as select a from t1;
create view v2 as select a from t2 where a in (select a from v1);
show create view v2;
View Create View
-v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `a` in (select `v1`.`a` AS `a` from `v1`)
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `t2`.`a` in (select `v1`.`a` AS `a` from `v1`)
drop view v2, v1;
drop table t1, t2;
CREATE VIEW `v 1` AS select 5 AS `5`;
@@ -2649,3 +2649,48 @@ ldt
2006-01-01 03:00:00
drop view v1, v2;
drop table t1;
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, d datetime);
+CREATE VIEW v1 AS
+SELECT id, date(d) + INTERVAL TIME_TO_SEC(d) SECOND AS t, COUNT(*)
+FROM t1 GROUP BY id, t;
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`id` AS `id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second) AS `t`,count(0) AS `COUNT(*)` from `t1` group by `t1`.`id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second)
+SELECT * FROM v1;
+id t COUNT(*)
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (i INT, j BIGINT);
+INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
+CREATE VIEW v1 AS SELECT MIN(j) AS j FROM t1;
+CREATE VIEW v2 AS SELECT MIN(i) FROM t1 WHERE j = ( SELECT * FROM v1 );
+SELECT * FROM v2;
+MIN(i)
+1
+DROP VIEW v2, v1;
+DROP TABLE t1;
+CREATE TABLE t1(
+fName varchar(25) NOT NULL,
+lName varchar(25) NOT NULL,
+DOB date NOT NULL,
+uID int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY);
+INSERT INTO t1(fName, lName, DOB) VALUES
+('Hank', 'Hill', '1964-09-29'),
+('Tom', 'Adams', '1908-02-14'),
+('Homer', 'Simpson', '1968-03-05');
+CREATE VIEW v1 AS
+SELECT (year(now())-year(DOB)) AS Age
+FROM t1 HAVING Age < 75;
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache (year(now()) - year(`t1`.`DOB`)) AS `Age` from `t1` having (`Age` < 75)
+SELECT (year(now())-year(DOB)) AS Age FROM t1 HAVING Age < 75;
+Age
+42
+38
+SELECT * FROM v1;
+Age
+42
+38
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/std_data/untrusted-cacert.pem b/mysql-test/std_data/untrusted-cacert.pem
new file mode 100644
index 00000000000..981dd004fc6
--- /dev/null
+++ b/mysql-test/std_data/untrusted-cacert.pem
@@ -0,0 +1,53 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=US, ST=Oregon, L=Portland, O=sawtooth, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
+ Validity
+ Not Before: Jan 18 20:12:32 2005 GMT
+ Not After : Oct 15 20:12:32 2007 GMT
+ Subject: C=US, ST=Oregon, L=Portland, O=sawtooth, CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (512 bit)
+ Modulus (512 bit):
+ 00:cf:2b:14:00:b0:3c:df:6f:9e:91:40:ec:c8:f6:
+ 90:b2:5b:b4:70:80:a5:a4:0a:73:c7:44:f3:2a:26:
+ c4:2f:f1:3a:f1:c3:c4:ac:fc:c3:d2:c3:bf:f5:d7:
+ 6a:38:42:ad:22:ab:c8:c4:4b:4c:1d:16:af:05:34:
+ 7d:79:97:5e:e1
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ CB:0F:1F:E9:A2:76:71:C9:E6:E8:23:A6:C1:18:B7:CC:44:CF:B9:84
+ X509v3 Authority Key Identifier:
+ keyid:CB:0F:1F:E9:A2:76:71:C9:E6:E8:23:A6:C1:18:B7:CC:44:CF:B9:84
+ DirName:/C=US/ST=Oregon/L=Portland/O=sawtooth/CN=www.sawtooth-consulting.com/emailAddress=info@yassl.com
+ serial:00
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: md5WithRSAEncryption
+ 27:f7:3d:fb:39:6f:73:a4:86:f3:a0:48:22:60:84:e9:5c:3d:
+ 28:36:05:16:44:98:07:87:e1:5d:b5:f3:a7:bc:33:5f:f4:29:
+ a9:5f:87:33:df:e6:8e:bd:e2:f3:0a:c8:00:69:ae:3d:41:47:
+ 03:ea:0b:4c:67:45:4b:ab:f3:39
+-----BEGIN CERTIFICATE-----
+MIIC7zCCApmgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBiTELMAkGA1UEBhMCVVMx
+DzANBgNVBAgTBk9yZWdvbjERMA8GA1UEBxMIUG9ydGxhbmQxETAPBgNVBAoTCHNh
+d3Rvb3RoMSQwIgYDVQQDExt3d3cuc2F3dG9vdGgtY29uc3VsdGluZy5jb20xHTAb
+BgkqhkiG9w0BCQEWDmluZm9AeWFzc2wuY29tMB4XDTA1MDExODIwMTIzMloXDTA3
+MTAxNTIwMTIzMlowgYkxCzAJBgNVBAYTAlVTMQ8wDQYDVQQIEwZPcmVnb24xETAP
+BgNVBAcTCFBvcnRsYW5kMREwDwYDVQQKEwhzYXd0b290aDEkMCIGA1UEAxMbd3d3
+LnNhd3Rvb3RoLWNvbnN1bHRpbmcuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlh
+c3NsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDPKxQAsDzfb56RQOzI9pCy
+W7RwgKWkCnPHRPMqJsQv8Trxw8Ss/MPSw7/112o4Qq0iq8jES0wdFq8FNH15l17h
+AgMBAAGjgekwgeYwHQYDVR0OBBYEFMsPH+midnHJ5ugjpsEYt8xEz7mEMIG2BgNV
+HSMEga4wgauAFMsPH+midnHJ5ugjpsEYt8xEz7mEoYGPpIGMMIGJMQswCQYDVQQG
+EwJVUzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDERMA8GA1UE
+ChMIc2F3dG9vdGgxJDAiBgNVBAMTG3d3dy5zYXd0b290aC1jb25zdWx0aW5nLmNv
+bTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb22CAQAwDAYDVR0TBAUwAwEB
+/zANBgkqhkiG9w0BAQQFAANBACf3Pfs5b3OkhvOgSCJghOlcPSg2BRZEmAeH4V21
+86e8M1/0KalfhzPf5o694vMKyABprj1BRwPqC0xnRUur8zk=
+-----END CERTIFICATE-----
diff --git a/mysql-test/t/blackhole.test b/mysql-test/t/blackhole.test
index e40b84eb5cd..493f74ded3e 100644
--- a/mysql-test/t/blackhole.test
+++ b/mysql-test/t/blackhole.test
@@ -128,3 +128,15 @@ show binlog events;
drop table t1,t2,t3;
# End of 4.1 tests
+
+#
+# BUG#10952 - alter table ... lost data without errors and warnings
+#
+drop table if exists t1;
+create table t1 (c char(20)) engine=MyISAM;
+insert into t1 values ("Monty"),("WAX"),("Walrus");
+--error 1031
+alter table t1 engine=blackhole;
+drop table t1;
+
+# End of 5.0 tests
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 1b587eea40f..007847fab37 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -11,4 +11,3 @@
##############################################################################
ndb_load : Bug#17233
-udf : Not yet
diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test
index 45bd0c7a51c..09f07c2852f 100644
--- a/mysql-test/t/distinct.test
+++ b/mysql-test/t/distinct.test
@@ -382,3 +382,19 @@ INSERT INTO t1 VALUES
select count(distinct x,y) from t1;
select count(distinct concat(x,y)) from t1;
drop table t1;
+
+#
+# Bug #18068: SELECT DISTINCT
+#
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b));
+
+INSERT INTO t1 VALUES (1, 101);
+INSERT INTO t1 SELECT a + 1, a + 101 FROM t1;
+INSERT INTO t1 SELECT a + 2, a + 102 FROM t1;
+INSERT INTO t1 SELECT a + 4, a + 104 FROM t1;
+INSERT INTO t1 SELECT a + 8, a + 108 FROM t1;
+
+EXPLAIN SELECT DISTINCT a,a FROM t1 WHERE b < 12 ORDER BY a;
+SELECT DISTINCT a,a FROM t1 WHERE b < 12 ORDER BY a;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index 2a3a23c5f96..a38771db233 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -43,3 +43,12 @@ drop table ÔÁÂ;
set names latin1;
# End of 4.1 tests
+
+
+#
+# Bug#15463: EXPLAIN SELECT..INTO hangs the client (QB, command line)
+#
+select 3 into @v1;
+explain select 3 into @v1;
+
+# End of 5.0 tests.
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 351d1fc2c92..8ddf1fbe314 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -220,3 +220,15 @@ set @str=NULL;
drop table t2;
drop table t1;
+# BUG#19618: Crash in range optimizer for
+# "unsigned_keypart NOT IN(negative_number,...)"
+# (introduced in fix BUG#15872)
+create table t1 (
+ some_id smallint(5) unsigned,
+ key (some_id)
+);
+insert into t1 values (1),(2);
+select some_id from t1 where some_id not in(2,-1);
+select some_id from t1 where some_id not in(-4,-1,-4);
+select some_id from t1 where some_id not in(-4,-1,3423534,2342342);
+drop table t1;
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 85cedee0f4a..7f809dbc4a1 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -666,7 +666,14 @@ select rpad(i, 7, ' ') as t from t1;
--disable_metadata
drop table t1;
-# End of 4.1 tests
+#
+# Bug #10418: LOAD_FILE does not behave like in manual if file does not exist
+#
+
+select load_file("lkjlkj");
+select ifnull(load_file("lkjlkj"),"it's null");
+
+--echo End of 4.1 tests
#
# Bug #13361: SELECT FORMAT(<decimal field with null>, 2) crashes
@@ -691,4 +698,10 @@ select cast(rtrim(' 20.06 ') as decimal(19,2));
select cast(ltrim(' 20.06 ') as decimal(19,2));
select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2));
+#
+# Bug #13975: "same string" + 0 has 2 different results
+#
+select conv("18383815659218730760",10,10) + 0;
+select "18383815659218730760" + 0;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 4e4fb8f777a..1c7f387e354 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -352,6 +352,20 @@ INSERT INTO t1 VALUES (NOW());
SELECT count(*) FROM t1 WHERE d>FROM_DAYS(TO_DAYS(@TMP)) AND d<=FROM_DAYS(TO_DAYS(@TMP)+1);
DROP TABLE t1;
+#
+# Bug #10568
+#
+
+select last_day('2005-00-00');
+select last_day('2005-00-01');
+select last_day('2005-01-00');
+
+#
+# Bug #18501: monthname and NULLs
+#
+
+select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
+ monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
# End of 4.1 tests
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index bff07366ec2..d9836ccc8df 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -782,3 +782,19 @@ SELECT COUNT(DISTINCT a) FROM t1 WHERE a=0;
DROP TABLE t1;
DROP PROCEDURE a;
+
+#
+# Bug #18068: SELECT DISTINCT
+#
+
+CREATE TABLE t1 (a varchar(64) NOT NULL default '', PRIMARY KEY(a));
+
+INSERT INTO t1 (a) VALUES
+ (''), ('CENTRAL'), ('EASTERN'), ('GREATER LONDON'),
+ ('NORTH CENTRAL'), ('NORTH EAST'), ('NORTH WEST'), ('SCOTLAND'),
+ ('SOUTH EAST'), ('SOUTH WEST'), ('WESTERN');
+
+EXPLAIN SELECT DISTINCT a,a FROM t1 ORDER BY a;
+SELECT DISTINCT a,a FROM t1 ORDER BY a;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 90b0fd95eee..e96f1ef4bbd 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -793,15 +793,6 @@ DROP VIEW v1;
DROP FUNCTION func1;
DROP FUNCTION func2;
-#
-# Bug #15851 Unlistable directories yield no info from information_schema
-#
-create database mysqltest;
-create table mysqltest.t1(a int);
---exec chmod -r $MYSQLTEST_VARDIR/master-data/mysqltest
-select table_schema from information_schema.tables where table_schema='mysqltest';
---exec chmod +r $MYSQLTEST_VARDIR/master-data/mysqltest
-drop database mysqltest;
#
# Bug#15307 GROUP_CONCAT() with ORDER BY returns empty set on information_schema
@@ -811,3 +802,23 @@ from information_schema.columns where
table_schema='information_schema' and
(column_type = 'varchar(7)' or column_type = 'varchar(20)')
group by column_type order by num;
+
+#
+# Bug#19236 bad COLUMNS.CHARACTER_MAXIMUM_LENGHT and CHARACTER_OCTET_LENGTH
+#
+create table t1(f1 char(1) not null, f2 char(9) not null)
+default character set utf8;
+select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from
+information_schema.columns where table_schema='test' and table_name = 't1';
+drop table t1;
+
+#
+# Bug#18177 any access to INFORMATION_SCHEMA.ROUTINES crashes
+#
+use mysql;
+INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL',
+'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03',
+'2006-03-02 18:40:03','','');
+select routine_name from information_schema.routines;
+delete from proc where name='';
+use test;
diff --git a/mysql-test/t/information_schema_chmod.test b/mysql-test/t/information_schema_chmod.test
new file mode 100644
index 00000000000..fb850b8e38d
--- /dev/null
+++ b/mysql-test/t/information_schema_chmod.test
@@ -0,0 +1,20 @@
+#
+# Due to "Bug#18474 Unlistable directories yield no info from
+# information_schema, part2" this test can't be run on Window with our
+# current test framework. When "chmod -r" is done within cygwin the
+# MySQL Server can still read the directory.
+# Manual testing shows the functionalty to skip unlistable directories
+# works on windows
+#
+--source include/not_windows.inc
+
+
+#
+# Bug #15851 Unlistable directories yield no info from information_schema
+#
+create database mysqltest;
+create table mysqltest.t1(a int);
+--exec chmod -r $MYSQLTEST_VARDIR/master-data/mysqltest
+select table_schema from information_schema.tables where table_schema='mysqltest';
+--exec chmod +r $MYSQLTEST_VARDIR/master-data/mysqltest
+drop database mysqltest;
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index c194213e0c9..dc4e240750c 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -779,3 +779,47 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE;
DROP TABLE t1,t2;
+
+#
+# Bug 19396: LEFT OUTER JOIN over views in curly braces
+#
+--disable_warnings
+DROP VIEW IF EXISTS v1,v2;
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a int);
+CREATE table t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (1), (1), (3);
+INSERT INTO t2 VALUES (2), (3);
+
+CREATE VIEW v1 AS SELECT a FROM t1 JOIN t2 ON t1.a=t2.b;
+CREATE VIEW v2 AS SELECT b FROM t2 JOIN t1 ON t2.b=t1.a;
+
+SELECT v1.a, v2. b
+ FROM v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3)
+ GROUP BY v1.a;
+SELECT v1.a, v2. b
+ FROM { OJ v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3) }
+ GROUP BY v1.a;
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+
+#
+# Bug 19816: LEFT OUTER JOIN with constant ORed predicates in WHERE clause
+#
+
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (2), (3);
+
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1);
+
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1 OR 1);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (0 OR 1);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 2=2);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 1=0);
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 060f1ea167b..7ea14a811ed 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -379,3 +379,15 @@ check table t1, t2;
drop table t1, t2, t3;
# End of 4.1 tests
+
+#
+# BUG#10952 - alter table ... lost data without errors and warnings
+#
+drop table if exists t1;
+create table t1 (c char(20)) engine=MyISAM;
+insert into t1 values ("Monty"),("WAX"),("Walrus");
+--error 1031
+alter table t1 engine=MERGE;
+drop table t1;
+
+# End of 5.0 tests
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index e76553f42e7..ac4c323f51e 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -72,3 +72,11 @@ drop table t1;
#
--exec $MYSQL -t --default-character-set utf8 test -e "create table t1 (i int, j int not null, k int); insert into t1 values (null, 1, null); select * from t1; describe t1; drop table t1;"
+#
+# Bug#19564: mysql displays NULL instead of space
+#
+--exec $MYSQL -t test -e "create table b19564 (i int, s1 char(1)); insert into b19564 values (1, 'x'); insert into b19564 values (2, NULL); insert into b19564 values (3, ' '); select * from b19564 order by i; drop table b19564;"
+
+--echo End of 5.0 tests
+
+
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index 28074fba7e4..d74bb1c3a80 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -122,9 +122,22 @@ select HEX(f) from t3;
select HEX(f) from t04;
select HEX(f) from t4;
+#
+# BUG#14157: utf8 encoding in binlog without set character_set_client
+#
+# BUG:
+# This test only works on the MySQL-internal rpl machines.
+# Needs to be fixed. Problem is that koi8r is not installed
+# on many machines.
+#
+flush logs;
+# --exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=koi8r test -e 'create table if not exists t5 (a int); set names koi8r; create temporary table `ÑÝÉË` (a int); insert into `ÑÝÉË` values (1); insert into t5 select * from `ÑÝÉË`'
+# resulted log is client charset insensitive (latin1 not koi8r) as it must be
+# --exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000006 | $MYSQL --default-character-set=latin1
+#select * from t5 /* must be (1),(1) */;
# clean up
drop table t1, t2, t03, t04, t3, t4;
-# End of 4.1 tests
+# End of 5.0 tests
diff --git a/mysql-test/t/ndb_autodiscover3.test b/mysql-test/t/ndb_autodiscover3.test
new file mode 100644
index 00000000000..73b4bf8b94f
--- /dev/null
+++ b/mysql-test/t/ndb_autodiscover3.test
@@ -0,0 +1,65 @@
+-- source include/have_ndb.inc
+-- source include/have_multi_ndb.inc
+-- source include/not_embedded.inc
+
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+#
+# Transaction ongoing while cluster is restarted
+#
+--connection server1
+create table t1 (a int key) engine=ndbcluster;
+
+begin;
+insert into t1 values (1);
+
+--exec $NDB_MGM --no-defaults -e "all restart" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT
+
+--error 1297
+insert into t1 values (2);
+--error 1296
+commit;
+
+drop table t1;
+
+#
+# Stale cache after restart -i
+#
+--connection server1
+create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster;
+insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1);
+select * from t2 order by a limit 3;
+
+--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT
+
+--connection server2
+create table t2 (a int key) engine=ndbcluster;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t2 order by a limit 3;
+
+# server 1 should have a stale cache, and in this case wrong frm, transaction must be retried
+--connection server1
+--error 1015
+select * from t2 order by a limit 3;
+select * from t2 order by a limit 3;
+
+--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT
+
+--connection server1
+show tables;
+create table t2 (a int key) engine=ndbcluster;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t2 order by a limit 3;
+
+# server 2 should have a stale cache, but with right frm, transaction need not be retried
+--connection server2
+select * from t2 order by a limit 3;
+
+drop table t2;
+# End of 4.1 tests
diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test
index 4cc9113048f..afee381f5b7 100644
--- a/mysql-test/t/openssl_1.test
+++ b/mysql-test/t/openssl_1.test
@@ -10,8 +10,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/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com";
-grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/emailAddress=abstract.mysql.developer@mysql.com";
flush privileges;
connect (con1,localhost,ssl_user1,,,,,SSL);
@@ -54,3 +54,41 @@ ssl_user3@localhost, ssl_user4@localhost;
drop table t1;
# End of 4.1 tests
+
+#
+# Test that we can't open connection to server if we are using
+# a different cacert
+#
+--exec echo "this query should not execute;" > $MYSQLTEST_VARDIR/tmp/test.sql
+--error 1
+--exec $MYSQL_TEST --ssl-ca=$MYSQL_TEST_DIR/std_data/untrusted-cacert.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
+
+#
+# Test that we can't open connection to server if we are using
+# a blank ca
+#
+--error 1
+--exec $MYSQL_TEST --ssl-ca= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
+
+#
+# Test that we can't open connection to server if we are using
+# a nonexistent ca file
+#
+--error 1
+--exec $MYSQL_TEST --ssl-ca=nonexisting_file.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
+
+#
+# Test that we can't open connection to server if we are using
+# a blank client-key
+#
+--error 1
+--exec $MYSQL_TEST --ssl-key= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
+
+#
+# Test that we can't open connection to server if we are using
+# a blank client-cert
+#
+--error 1
+--exec $MYSQL_TEST --ssl-cert= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
+
+
diff --git a/mysql-test/t/outfile.test b/mysql-test/t/outfile.test
index d404a6fff9f..c48e6c9730d 100644
--- a/mysql-test/t/outfile.test
+++ b/mysql-test/t/outfile.test
@@ -40,7 +40,6 @@ eval select * into dumpfile "../tmp/outfile-test.2" from t1;
--error 1086
eval select * into dumpfile "../tmp/outfile-test.3" from t1;
enable_query_log;
---error 13,2
select load_file(concat(@tmpdir,"/outfile-test.not-exist"));
--exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.1
--exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.2
diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test
index 5caecef176e..86e4b6eed0a 100644
--- a/mysql-test/t/rename.test
+++ b/mysql-test/t/rename.test
@@ -61,9 +61,15 @@ connection con2;
sleep 1;
show tables;
UNLOCK TABLES;
-sleep 1;
+connection con1;
+reap;
+connection con2;
show tables;
drop table t2, t4;
+disconnect con2;
+disconnect con1;
+connection default;
+
# End of 4.1 tests
diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test
index facf0d68d2b..81f0e8a0af7 100644
--- a/mysql-test/t/rpl_temporary.test
+++ b/mysql-test/t/rpl_temporary.test
@@ -163,14 +163,19 @@ drop table t5;
# value was set up at the moment of temp table creation
#
connection con1;
-set @session.pseudo_thread_id=100;
+set @@session.pseudo_thread_id=100;
create temporary table t101 (id int);
create temporary table t102 (id int);
-set @session.pseudo_thread_id=200;
+set @@session.pseudo_thread_id=200;
create temporary table t201 (id int);
-create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
-set @con1_id=connection_id();
-kill @con1_id;
+create temporary table `t``201` (id int);
+# emulate internal temp table not to come to binlog
+create temporary table `#sql_not_user_table202` (id int);
+set @@session.pseudo_thread_id=300;
+create temporary table t301 (id int);
+create temporary table t302 (id int);
+create temporary table `#sql_not_user_table303` (id int);
+disconnect con1;
#now do something to show that slave is ok after DROP temp tables
connection master;
@@ -184,4 +189,16 @@ select * from t1 /* must be 1 */;
connection master;
drop table t1;
+#
+#14157: utf8 encoding in binlog without set character_set_client
+#
+--exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=latin1 test -e 'create table t1 (a int); set names latin1; create temporary table `äöüÄÖÜ` (a int); insert into `äöüÄÖÜ` values (1); insert into t1 select * from `äöüÄÖÜ`'
+
+sync_slave_with_master;
+#connection slave;
+select * from t1;
+
+connection master;
+drop table t1;
+
# End of 5.0 tests
diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test
index e0ecf981fea..c404ea7e58b 100644
--- a/mysql-test/t/rpl_until.test
+++ b/mysql-test/t/rpl_until.test
@@ -31,7 +31,7 @@ wait_for_slave_to_stop;
select * from t1;
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 11 # 23 # 33 #
-show slave status;
+--query_vertical SHOW SLAVE STATUS
# this should fail right after start
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
@@ -41,7 +41,7 @@ sleep 2;
wait_for_slave_to_stop;
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 11 # 23 # 33 #
-show slave status;
+--query_vertical SHOW SLAVE STATUS
# try replicate all until second insert to t2;
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746;
@@ -50,7 +50,7 @@ wait_for_slave_to_stop;
select * from t2;
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 11 # 23 # 33 #
-show slave status;
+--query_vertical SHOW SLAVE STATUS
# clean up
start slave;
@@ -67,7 +67,7 @@ wait_for_slave_to_stop;
# here the sql slave thread should be stopped
--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004
--replace_column 1 # 9 # 23 # 33 #
-show slave status;
+--query_vertical SHOW SLAVE STATUS
#testing various error conditions
--error 1277
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 8e3c5847846..4b6ae921b9b 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -2886,3 +2886,37 @@ SELECT * FROM t1;
UPDATE t1 SET i = i - 1;
SELECT * FROM t1;
DROP TABLE t1;
+
+# BUG#17379
+
+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;
+select 'In next EXPLAIN, B.rows must be exactly 10:' Z;
+
+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);
+drop table t1, t2;
+
+#
+#Bug #18940: selection of optimal execution plan caused by equality
+# propagation (the bug was fixed by the patch for bug #17379)
+
+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;
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
+
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 22500bbd280..9995ff5a9ad 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -5774,6 +5774,76 @@ select routine_name,routine_schema from information_schema.routines where
#
+# BUG#12472/BUG#15137 'CREATE TABLE ... SELECT ... which explicitly or
+# implicitly uses stored function gives "Table not locked" error'.
+#
+--disable_warnings
+drop function if exists bug12472|
+--enable_warnings
+create function bug12472() returns int return (select count(*) from t1)|
+# Check case when function is used directly
+create table t3 as select bug12472() as i|
+show create table t3|
+select * from t3|
+drop table t3|
+# Check case when function is used indirectly through view
+create view v1 as select bug12472() as j|
+create table t3 as select * from v1|
+show create table t3|
+select * from t3|
+drop table t3|
+drop view v1|
+drop function bug12472|
+
+
+#
+# BUG#18587: Function that accepts and returns TEXT garbles data if longer than
+# 766 chars
+#
+
+# Prepare.
+
+--disable_warnings
+DROP FUNCTION IF EXISTS bug18589_f1|
+DROP PROCEDURE IF EXISTS bug18589_p1|
+DROP PROCEDURE IF EXISTS bug18589_p2|
+--enable_warnings
+
+CREATE FUNCTION bug18589_f1(arg TEXT) RETURNS TEXT
+BEGIN
+ RETURN CONCAT(arg, "");
+END|
+
+CREATE PROCEDURE bug18589_p1(arg TEXT, OUT ret TEXT)
+BEGIN
+ SET ret = CONCAT(arg, "");
+END|
+
+CREATE PROCEDURE bug18589_p2(arg TEXT)
+BEGIN
+ DECLARE v TEXT;
+ CALL bug18589_p1(arg, v);
+ SELECT v;
+END|
+
+# Test case.
+
+SELECT bug18589_f1(REPEAT("a", 767))|
+
+SET @bug18589_v1 = ""|
+CALL bug18589_p1(REPEAT("a", 767), @bug18589_v1)|
+SELECT @bug18589_v1|
+
+CALL bug18589_p2(REPEAT("a", 767))|
+
+# Cleanup.
+
+DROP FUNCTION bug18589_f1|
+DROP PROCEDURE bug18589_p1|
+DROP PROCEDURE bug18589_p2|
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 1ef80bdd7ac..3f48b648f40 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -2085,3 +2085,27 @@ create table t2 (a int, b int);
insert into t2 values (2, 1), (1, 0);
delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
drop table t1, t2;
+
+#
+# Bug #7549: Missing error message for invalid view selection with subquery
+#
+
+CREATE TABLE t1 (a INT);
+
+--error 1054
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+--error 1054
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+--error 1054
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+
+DROP TABLE t1;
+
+#
+# Bug#19077: A nested materialized derived table is used before being populated.
+#
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+drop table t1;
+
diff --git a/mysql-test/t/trigger-grant.test b/mysql-test/t/trigger-grant.test
index 7a3f7a9fa94..12b929898a8 100644
--- a/mysql-test/t/trigger-grant.test
+++ b/mysql-test/t/trigger-grant.test
@@ -564,3 +564,176 @@ SELECT @mysqltest_var;
DROP USER mysqltest_u1@localhost;
DROP DATABASE mysqltest_db1;
+
+
+#
+# Test for bug #14635 Accept NEW.x as INOUT parameters to stored
+# procedures from within triggers
+#
+# We require UPDATE privilege when NEW.x passed as OUT parameter, and
+# SELECT and UPDATE when NEW.x passed as INOUT parameter.
+#
+DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
+FLUSH PRIVILEGES;
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest_db1;
+--enable_warnings
+
+CREATE DATABASE mysqltest_db1;
+USE mysqltest_db1;
+
+CREATE TABLE t1 (i1 INT);
+CREATE TABLE t2 (i1 INT);
+
+CREATE USER mysqltest_dfn@localhost;
+CREATE USER mysqltest_inv@localhost;
+
+GRANT EXECUTE, CREATE ROUTINE, SUPER ON *.* TO mysqltest_dfn@localhost;
+GRANT INSERT ON mysqltest_db1.* TO mysqltest_inv@localhost;
+
+connect (definer,localhost,mysqltest_dfn,,mysqltest_db1);
+connect (invoker,localhost,mysqltest_inv,,mysqltest_db1);
+
+connection definer;
+CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 3;
+CREATE PROCEDURE p2(INOUT i INT) DETERMINISTIC NO SQL SET i = i * 5;
+
+# Check that having no privilege won't work.
+connection definer;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+ CALL p2(NEW.i1);
+
+connection invoker;
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t1 VALUES (7);
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t2 VALUES (11);
+
+connection definer;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+
+# Check that having only SELECT privilege is not enough.
+connection default;
+GRANT SELECT ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+
+connection definer;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+ CALL p2(NEW.i1);
+
+connection invoker;
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t1 VALUES (13);
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t2 VALUES (17);
+
+connection default;
+REVOKE SELECT ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+
+connection definer;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+
+# Check that having only UPDATE privilege is enough for OUT parameter,
+# but not for INOUT parameter.
+connection default;
+GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+
+connection definer;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+ CALL p2(NEW.i1);
+
+connection invoker;
+INSERT INTO t1 VALUES (19);
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t2 VALUES (23);
+
+connection default;
+REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+
+connection definer;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+
+# Check that having SELECT and UPDATE privileges is enough.
+connection default;
+GRANT SELECT, UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+
+connection definer;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+ CALL p2(NEW.i1);
+
+connection invoker;
+INSERT INTO t1 VALUES (29);
+INSERT INTO t2 VALUES (31);
+
+connection default;
+REVOKE SELECT, UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+
+connection definer;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+
+connection default;
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+
+# Check that late procedure redefining won't open a security hole.
+connection default;
+GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+
+connection definer;
+CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 37;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+
+connection invoker;
+INSERT INTO t1 VALUES (41);
+
+connection definer;
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(IN i INT) DETERMINISTIC NO SQL SET @v1 = i + 43;
+
+connection invoker;
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t1 VALUES (47);
+
+connection definer;
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(INOUT i INT) DETERMINISTIC NO SQL SET i = i + 51;
+
+connection invoker;
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t1 VALUES (53);
+
+connection default;
+DROP PROCEDURE p1;
+REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+
+connection definer;
+DROP TRIGGER t1_bi;
+
+# Cleanup.
+disconnect definer;
+disconnect invoker;
+connection default;
+DROP USER mysqltest_inv@localhost;
+DROP USER mysqltest_dfn@localhost;
+DROP TABLE t2;
+DROP TABLE t1;
+DROP DATABASE mysqltest_db1;
+USE test;
+
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index 00c85a650d1..a5bd2ba0b38 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -1165,4 +1165,126 @@ SELECT * FROM t1 WHERE conn_id != trigger_conn_id;
DROP TRIGGER t1_bi;
DROP TABLE t1;
+
+#
+# Bug#6951: Triggers/Traditional: SET @ result wrong
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i1 INT);
+
+SET @save_sql_mode=@@sql_mode;
+
+SET SQL_MODE='';
+
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+ SET @x = 5/0;
+
+SET SQL_MODE='traditional';
+
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+ SET @x = 5/0;
+
+SET @x=1;
+INSERT INTO t1 VALUES (@x);
+SELECT @x;
+
+SET @x=2;
+--error 1365
+UPDATE t1 SET i1 = @x;
+SELECT @x;
+
+SET SQL_MODE='';
+
+SET @x=3;
+INSERT INTO t1 VALUES (@x);
+SELECT @x;
+
+SET @x=4;
+--error 1365
+UPDATE t1 SET i1 = @x;
+SELECT @x;
+
+SET @@sql_mode=@save_sql_mode;
+
+DROP TRIGGER t1_ai;
+DROP TRIGGER t1_au;
+DROP TABLE t1;
+
+
+#
+# Test for bug #14635 Accept NEW.x as INOUT parameters to stored
+# procedures from within triggers
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+--enable_warnings
+
+CREATE TABLE t1 (i1 INT);
+
+# Check that NEW.x pseudo variable is accepted as INOUT and OUT
+# parameter to stored routine.
+INSERT INTO t1 VALUES (3);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET i1 = 5;
+CREATE PROCEDURE p2(INOUT i1 INT) DETERMINISTIC NO SQL SET i1 = i1 * 7;
+delimiter //;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+ CALL p1(NEW.i1);
+ CALL p2(NEW.i1);
+END//
+delimiter ;//
+UPDATE t1 SET i1 = 11 WHERE i1 = 3;
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+
+# Check that OLD.x pseudo variable is not accepted as INOUT and OUT
+# parameter to stored routine.
+INSERT INTO t1 VALUES (13);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 17;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+ CALL p1(OLD.i1);
+--error ER_SP_NOT_VAR_ARG
+UPDATE t1 SET i1 = 19 WHERE i1 = 13;
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p1;
+
+INSERT INTO t1 VALUES (23);
+CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 29;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+ CALL p1(OLD.i1);
+--error ER_SP_NOT_VAR_ARG
+UPDATE t1 SET i1 = 31 WHERE i1 = 23;
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p1;
+
+# Check that NEW.x pseudo variable is read-only in the AFTER TRIGGER.
+INSERT INTO t1 VALUES (37);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 41;
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+--error ER_SP_NOT_VAR_ARG
+UPDATE t1 SET i1 = 43 WHERE i1 = 37;
+DROP TRIGGER t1_au;
+DROP PROCEDURE p1;
+
+INSERT INTO t1 VALUES (47);
+CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 49;
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+--error ER_SP_NOT_VAR_ARG
+UPDATE t1 SET i1 = 51 WHERE i1 = 47;
+DROP TRIGGER t1_au;
+DROP PROCEDURE p1;
+
+# Post requisite.
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
# End of 5.0 tests
diff --git a/mysql-test/t/variables-master.opt b/mysql-test/t/variables-master.opt
deleted file mode 100644
index abd826bc7fa..00000000000
--- a/mysql-test/t/variables-master.opt
+++ /dev/null
@@ -1 +0,0 @@
---max_join_size=100
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 6a271a75e46..be1731e7493 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -5,6 +5,37 @@
drop table if exists t1,t2;
--enable_warnings
+#
+# Bug #19263: variables.test doesn't clean up after itself (I/II -- save)
+#
+set @my_binlog_cache_size =@@global.binlog_cache_size;
+set @my_connect_timeout =@@global.connect_timeout;
+set @my_delayed_insert_timeout =@@global.delayed_insert_timeout;
+set @my_delayed_queue_size =@@global.delayed_queue_size;
+set @my_flush =@@global.flush;
+set @my_flush_time =@@global.flush_time;
+set @my_key_buffer_size =@@global.key_buffer_size;
+set @my_max_binlog_cache_size =@@global.max_binlog_cache_size;
+set @my_max_binlog_size =@@global.max_binlog_size;
+set @my_max_connect_errors =@@global.max_connect_errors;
+set @my_max_delayed_threads =@@global.max_delayed_threads;
+set @my_max_heap_table_size =@@global.max_heap_table_size;
+set @my_max_insert_delayed_threads=@@global.max_insert_delayed_threads;
+set @my_max_join_size =@@global.max_join_size;
+set @my_max_user_connections =@@global.max_user_connections;
+set @my_max_write_lock_count =@@global.max_write_lock_count;
+set @my_myisam_data_pointer_size =@@global.myisam_data_pointer_size;
+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;
+set @my_storage_engine =@@global.storage_engine;
+set @my_thread_cache_size =@@global.thread_cache_size;
+
# case insensitivity tests (new in 5.0)
set @`test`=1;
select @test, @`test`, @TEST, @`TEST`, @"teSt";
@@ -539,3 +570,37 @@ select @@log_queries_not_using_indexes;
show variables like 'log_queries_not_using_indexes';
--echo End of 5.0 tests
+
+# This is at the very after the versioned tests, since it involves doing
+# cleanup
+#
+# Bug #19263: variables.test doesn't clean up after itself (II/II --
+# restore)
+#
+set global binlog_cache_size =@my_binlog_cache_size;
+set global connect_timeout =@my_connect_timeout;
+set global delayed_insert_timeout =@my_delayed_insert_timeout;
+set global delayed_queue_size =@my_delayed_queue_size;
+set global flush =@my_flush;
+set global flush_time =@my_flush_time;
+set global key_buffer_size =@my_key_buffer_size;
+set global max_binlog_cache_size =default; #@my_max_binlog_cache_size;
+set global max_binlog_size =@my_max_binlog_size;
+set global max_connect_errors =@my_max_connect_errors;
+set global max_delayed_threads =@my_max_delayed_threads;
+set global max_heap_table_size =@my_max_heap_table_size;
+set global max_insert_delayed_threads=@my_max_insert_delayed_threads;
+set global max_join_size =@my_max_join_size;
+set global max_user_connections =@my_max_user_connections;
+set global max_write_lock_count =@my_max_write_lock_count;
+set global myisam_data_pointer_size =@my_myisam_data_pointer_size;
+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;
+set global storage_engine =@my_storage_engine;
+set global thread_cache_size =@my_thread_cache_size;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 8f759c2d43e..f4798317fa1 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -2512,3 +2512,58 @@ create view v2 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from v1;
select * from v2;
drop view v1, v2;
drop table t1;
+
+#
+# Bug #19490: usage of view specified by a query with GROUP BY
+# an expression containing non-constant interval
+
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, d datetime);
+
+CREATE VIEW v1 AS
+SELECT id, date(d) + INTERVAL TIME_TO_SEC(d) SECOND AS t, COUNT(*)
+ FROM t1 GROUP BY id, t;
+
+SHOW CREATE VIEW v1;
+SELECT * FROM v1;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+#
+# Bug#19077: A nested materialized view is used before being populated.
+#
+CREATE TABLE t1 (i INT, j BIGINT);
+INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
+CREATE VIEW v1 AS SELECT MIN(j) AS j FROM t1;
+CREATE VIEW v2 AS SELECT MIN(i) FROM t1 WHERE j = ( SELECT * FROM v1 );
+SELECT * FROM v2;
+DROP VIEW v2, v1;
+DROP TABLE t1;
+
+#
+# Bug #19573: VIEW with HAVING that refers an alias name
+#
+
+CREATE TABLE t1(
+ fName varchar(25) NOT NULL,
+ lName varchar(25) NOT NULL,
+ DOB date NOT NULL,
+ uID int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY);
+
+INSERT INTO t1(fName, lName, DOB) VALUES
+ ('Hank', 'Hill', '1964-09-29'),
+ ('Tom', 'Adams', '1908-02-14'),
+ ('Homer', 'Simpson', '1968-03-05');
+
+CREATE VIEW v1 AS
+ SELECT (year(now())-year(DOB)) AS Age
+ FROM t1 HAVING Age < 75;
+SHOW CREATE VIEW v1;
+
+SELECT (year(now())-year(DOB)) AS Age FROM t1 HAVING Age < 75;
+SELECT * FROM v1;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 7737810653d..3c2ac1a7ea5 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -11,7 +11,7 @@
fun:calloc
fun:_dl_allocate_tls
fun:allocate_stack
- fun:pthread_create@@GLIBC_2.1
+ fun:pthread_create*
}
{
@@ -34,15 +34,6 @@
}
{
- pthread allocate_dtv memory loss second
- Memcheck:Leak
- fun:calloc
- fun:allocate_dtv
- fun:_dl_allocate_tls
- fun:pthread_create*
-}
-
-{
pthread memalign memory loss
Memcheck:Leak
fun:memalign
@@ -73,17 +64,6 @@
}
{
- pthread strstr uninit
- Memcheck:Cond
- fun:strstr
- obj:/lib/tls/libpthread.so.*
- obj:/lib/tls/libpthread.so.*
- fun:call_init
- fun:_dl_init
- obj:/lib/ld-*.so
-}
-
-{
pthread errno
Memcheck:Leak
fun:calloc
@@ -152,3 +132,163 @@
obj:*/libz.so.*
fun:gzflush
}
+
+#
+# Leaks reported in _dl_* internal functions on Linux amd64 / glibc2.3.2.
+#
+
+{
+ _dl_start invalid write8
+ Memcheck:Addr8
+ fun:_dl_start
+}
+
+{
+ _dl_start invalid write4
+ Memcheck:Addr4
+ fun:_dl_start
+}
+
+{
+ _dl_start/_dl_setup_hash invalid read8
+ Memcheck:Addr8
+ fun:_dl_setup_hash
+ fun:_dl_start
+}
+
+{
+ _dl_sysdep_start invalid write8
+ Memcheck:Addr8
+ fun:_dl_sysdep_start
+}
+
+{
+ _dl_init invalid write8
+ Memcheck:Addr8
+ fun:_dl_init
+}
+
+{
+ _dl_init invalid write4
+ Memcheck:Addr4
+ fun:_dl_init
+}
+
+{
+ _dl_init/_dl_init invalid read8
+ Memcheck:Addr8
+ fun:_dl_debug_initialize
+ fun:_dl_init
+}
+
+{
+ _dl_init/_dl_debug_state invalid read8
+ Memcheck:Addr8
+ fun:_dl_debug_state
+ fun:_dl_init
+}
+
+{
+ init invalid write8
+ Memcheck:Addr8
+ fun:init
+}
+
+{
+ fixup invalid write8
+ Memcheck:Addr8
+ fun:fixup
+}
+
+{
+ fixup/_dl_lookup_versioned_symbol invalid read8
+ Memcheck:Addr8
+ fun:_dl_lookup_versioned_symbol
+ fun:fixup
+}
+
+{
+ _dl_runtime_resolve invalid read8
+ Memcheck:Addr8
+ fun:_dl_runtime_resolve
+}
+
+{
+ __libc_start_main invalid write8
+ Memcheck:Addr8
+ fun:__libc_start_main
+}
+
+{
+ __libc_start_main/__sigjmp_save invalid write4
+ Memcheck:Addr4
+ fun:__sigjmp_save
+ fun:__libc_start_main
+}
+
+#
+# These seem to be libc threading stuff, not related to MySQL code (allocations
+# during pthread_exit()). Googling shows other projects also using these
+# suppressions.
+#
+# Note that these all stem from pthread_exit() deeper in the call stack, but
+# Valgrind only allows the top four calls in the suppressions.
+#
+
+{
+ libc pthread_exit 1
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_new_object
+ fun:_dl_map_object_from_fd
+ fun:_dl_map_object
+}
+
+{
+ libc pthread_exit 2
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_map_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+}
+
+{
+ libc pthread_exit 3
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_map_object_deps
+ fun:dl_open_worker
+ fun:_dl_catch_error
+}
+
+{
+ libc pthread_exit 4
+ Memcheck:Leak
+ fun:calloc
+ fun:_dl_check_map_versions
+ fun:dl_open_worker
+ fun:_dl_catch_error
+}
+
+{
+ libc pthread_exit 5
+ Memcheck:Leak
+ fun:calloc
+ fun:_dl_new_object
+ fun:_dl_map_object_from_fd
+ fun:_dl_map_object
+}
+
+
+
+#
+# This is seen internally in the system libraries on 64-bit RHAS3.
+#
+
+{
+ __lll_mutex_unlock_wake uninitialized
+ Memcheck:Param
+ futex(utime)
+ fun:__lll_mutex_unlock_wake
+}
diff --git a/mysys/my_init.c b/mysys/my_init.c
index c2bfdde0ddd..9b8d4db172f 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -196,8 +196,10 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
_CrtDumpMemoryLeaks();
#endif
}
+
+ if (!(infoflag & MY_DONT_FREE_DBUG))
+ DBUG_END(); /* Must be done before my_thread_end */
#ifdef THREAD
- DBUG_POP(); /* Must be done before my_thread_end */
my_thread_end();
my_thread_global_end();
#if defined(SAFE_MUTEX)
diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h
index 7c24c5d698d..410c811213b 100644
--- a/ndb/include/mgmapi/mgmapi_config_parameters.h
+++ b/ndb/include/mgmapi/mgmapi_config_parameters.h
@@ -65,6 +65,7 @@
#define CFG_DB_BACKUP_DATA_BUFFER_MEM 134
#define CFG_DB_BACKUP_LOG_BUFFER_MEM 135
#define CFG_DB_BACKUP_WRITE_SIZE 136
+#define CFG_DB_BACKUP_MAX_WRITE_SIZE 139
#define CFG_LOG_DESTINATION 147
diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp
index c96300047d5..fcce53c90a0 100644
--- a/ndb/include/ndbapi/ndb_cluster_connection.hpp
+++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp
@@ -95,6 +95,7 @@ public:
unsigned no_db_nodes();
unsigned node_id();
+ unsigned get_connect_count() const;
#endif
private:
diff --git a/ndb/include/util/SocketServer.hpp b/ndb/include/util/SocketServer.hpp
index 4c37e63adf0..c21673f932a 100644
--- a/ndb/include/util/SocketServer.hpp
+++ b/ndb/include/util/SocketServer.hpp
@@ -74,7 +74,7 @@ public:
/**
* Constructor / Destructor
*/
- SocketServer(int maxSessions = 32);
+ SocketServer(unsigned maxSessions = ~(unsigned)0);
~SocketServer();
/**
diff --git a/ndb/src/common/transporter/Transporter.cpp b/ndb/src/common/transporter/Transporter.cpp
index 377fabe27ab..820aa4cfc18 100644
--- a/ndb/src/common/transporter/Transporter.cpp
+++ b/ndb/src/common/transporter/Transporter.cpp
@@ -105,10 +105,10 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
}
{
- struct sockaddr addr;
+ struct sockaddr_in addr;
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
- int r= getpeername(sockfd, &addr, &addrlen);
- m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr;
+ int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen);
+ m_connect_address= (&addr)->sin_addr;
}
bool res = connect_server_impl(sockfd);
@@ -198,10 +198,10 @@ Transporter::connect_client(NDB_SOCKET_TYPE sockfd) {
}
{
- struct sockaddr addr;
+ struct sockaddr_in addr;
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
- int r= getpeername(sockfd, &addr, &addrlen);
- m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr;
+ int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen);
+ m_connect_address= (&addr)->sin_addr;
}
bool res = connect_client_impl(sockfd);
diff --git a/ndb/src/common/util/SocketServer.cpp b/ndb/src/common/util/SocketServer.cpp
index 481c656b78b..f0af925cf6d 100644
--- a/ndb/src/common/util/SocketServer.cpp
+++ b/ndb/src/common/util/SocketServer.cpp
@@ -27,7 +27,7 @@
#define DEBUG(x) ndbout << x << endl;
-SocketServer::SocketServer(int maxSessions) :
+SocketServer::SocketServer(unsigned maxSessions) :
m_sessions(10),
m_services(5)
{
@@ -136,7 +136,7 @@ SocketServer::setup(SocketServer::Service * service,
}
DBUG_PRINT("info",("bound to %u",ntohs(servaddr.sin_port)));
- if (listen(sock, m_maxSessions) == -1){
+ if (listen(sock, m_maxSessions > 32 ? 32 : m_maxSessions) == -1){
DBUG_PRINT("error",("listen() - %d - %s",
errno, strerror(errno)));
NDB_CLOSE_SOCKET(sock);
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index ea4009015cb..f9089355475 100644
--- a/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -114,15 +114,16 @@ Backup::execREAD_CONFIG_REQ(Signal* signal)
Uint32 szDataBuf = (2 * 1024 * 1024);
Uint32 szLogBuf = (2 * 1024 * 1024);
- Uint32 szWrite = 32768;
+ Uint32 szWrite = 32768, maxWriteSize = (256 * 1024);
ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_DATA_BUFFER_MEM, &szDataBuf);
ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_LOG_BUFFER_MEM, &szLogBuf);
ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_WRITE_SIZE, &szWrite);
+ ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MAX_WRITE_SIZE, &maxWriteSize);
c_defaults.m_logBufferSize = szLogBuf;
c_defaults.m_dataBufferSize = szDataBuf;
c_defaults.m_minWriteSize = szWrite;
- c_defaults.m_maxWriteSize = szWrite;
+ c_defaults.m_maxWriteSize = maxWriteSize;
{ // Init all tables
ArrayList<Table> tables(c_tablePool);
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp
index 31f73e98142..7bd308119fc 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp
@@ -190,7 +190,7 @@ Dbtc::Dbtc(const class Configuration & conf):
ndb_mgm_get_int_parameter(p, CFG_DB_TRANS_BUFFER_MEM,
&transactionBufferMemory);
- ndb_mgm_get_int_parameter(p, CFG_DB_NO_UNIQUE_HASH_INDEXES,
+ ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE,
&maxNoOfIndexes);
ndb_mgm_get_int_parameter(p, CFG_DB_NO_INDEX_OPS,
&maxNoOfConcurrentIndexOperations);
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
index 761f959acdc..f83f21f14d8 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
@@ -1496,6 +1496,7 @@ int Dbtup::interpreterNextLab(Signal* signal,
// word read. Thus we set the register to be a 32 bit register.
/* ------------------------------------------------------------- */
TregMemBuffer[theRegister] = 0x50;
+ // arithmetic conversion if big-endian
* (Int64*)(TregMemBuffer+theRegister+2) = TregMemBuffer[theRegister+1];
} else if (TnoDataRW == 3) {
/* ------------------------------------------------------------- */
@@ -1554,6 +1555,11 @@ int Dbtup::interpreterNextLab(Signal* signal,
Tlen = TattrNoOfWords + 1;
if (Toptype == ZUPDATE) {
if (TattrNoOfWords <= 2) {
+ if (TattrNoOfWords == 1) {
+ // arithmetic conversion if big-endian
+ TdataForUpdate[1] = *(Int64*)&TregMemBuffer[theRegister + 2];
+ TdataForUpdate[2] = 0;
+ }
if (TregType == 0) {
/* --------------------------------------------------------- */
// Write a NULL value into the attribute
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index f99478a8cea..061360428af 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -695,10 +695,12 @@ ndb_mgm_get_status(NdbMgmHandle handle)
Vector<BaseString> split;
tmp.split(split, ":");
if(split.size() != 2){
+ SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
return NULL;
}
if(!(split[0].trim() == "nodes")){
+ SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
return NULL;
}
@@ -746,6 +748,7 @@ ndb_mgm_get_status(NdbMgmHandle handle)
if(i+1 != noOfNodes){
free(state);
+ SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, "Node count mismatch");
return NULL;
}
diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp
index 817943f5e51..e9093d59494 100644
--- a/ndb/src/mgmsrv/ConfigInfo.cpp
+++ b/ndb/src/mgmsrv/ConfigInfo.cpp
@@ -1199,7 +1199,19 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
false,
ConfigInfo::CI_INT,
"32K",
- "0",
+ "2K",
+ STR_VALUE(MAX_INT_RNIL) },
+
+ {
+ CFG_DB_BACKUP_MAX_WRITE_SIZE,
+ "BackupMaxWriteSize",
+ DB_TOKEN,
+ "Max size of filesystem writes made by backup (in bytes)",
+ ConfigInfo::CI_USED,
+ false,
+ ConfigInfo::CI_INT,
+ "256K",
+ "2K",
STR_VALUE(MAX_INT_RNIL) },
/***************************************************************************
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index d40eaab7bd5..b713a3908ab 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -2408,6 +2408,7 @@ int
MgmtSrvr::abortBackup(Uint32 backupId)
{
SignalSender ss(theFacade);
+ ss.lock(); // lock will be released on exit
bool next;
NodeId nodeId = 0;
diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp
index 555c2082480..d28e0eba5b3 100644
--- a/ndb/src/mgmsrv/Services.cpp
+++ b/ndb/src/mgmsrv/Services.cpp
@@ -468,9 +468,9 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
return;
}
- struct sockaddr addr;
+ struct sockaddr_in addr;
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
- int r = getpeername(m_socket, &addr, &addrlen);
+ int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen);
if (r != 0 ) {
m_output->println(cmd);
m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r);
@@ -485,7 +485,7 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
NDB_TICKS tick= 0;
/* only report error on second attempt as not to clog the cluster log */
while (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype,
- &addr, &addrlen, error_code, error_string,
+ (struct sockaddr*)&addr, &addrlen, error_code, error_string,
tick == 0 ? 0 : log_event))
{
/* NDB_MGM_ALLOCID_CONFIG_MISMATCH is a non retriable error */
diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp
index 42b7c5b115d..fbff57d3168 100644
--- a/ndb/src/ndbapi/ClusterMgr.cpp
+++ b/ndb/src/ndbapi/ClusterMgr.cpp
@@ -70,6 +70,7 @@ ClusterMgr::ClusterMgr(TransporterFacade & _facade):
noOfAliveNodes= 0;
noOfConnectedNodes= 0;
theClusterMgrThread= 0;
+ m_connect_count = 0;
DBUG_VOID_RETURN;
}
@@ -469,6 +470,10 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){
theNode.nfCompleteRep = false;
if(noOfAliveNodes == 0)
{
+ theFacade.m_globalDictCache.lock();
+ theFacade.m_globalDictCache.invalidate_all();
+ theFacade.m_globalDictCache.unlock();
+ m_connect_count ++;
NFCompleteRep rep;
for(Uint32 i = 1; i<MAX_NODES; i++){
if(theNodes[i].defined && theNodes[i].nfCompleteRep == false){
diff --git a/ndb/src/ndbapi/ClusterMgr.hpp b/ndb/src/ndbapi/ClusterMgr.hpp
index da8f16d6789..1a1e622a889 100644
--- a/ndb/src/ndbapi/ClusterMgr.hpp
+++ b/ndb/src/ndbapi/ClusterMgr.hpp
@@ -79,6 +79,7 @@ public:
Uint32 getNoOfConnectedNodes() const;
void hb_received(NodeId);
+ Uint32 m_connect_count;
private:
Uint32 noOfAliveNodes;
Uint32 noOfConnectedNodes;
diff --git a/ndb/src/ndbapi/DictCache.cpp b/ndb/src/ndbapi/DictCache.cpp
index 57d9b361522..740f67da2df 100644
--- a/ndb/src/ndbapi/DictCache.cpp
+++ b/ndb/src/ndbapi/DictCache.cpp
@@ -300,6 +300,42 @@ GlobalDictCache::drop(NdbTableImpl * tab)
abort();
}
+
+unsigned
+GlobalDictCache::get_size()
+{
+ NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
+ int sz = 0;
+ while(curr != 0){
+ sz += curr->theData->size();
+ curr = m_tableHash.getNext(curr);
+ }
+ return sz;
+}
+
+void
+GlobalDictCache::invalidate_all()
+{
+ DBUG_ENTER("GlobalDictCache::invalidate_all");
+ NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
+ while(curr != 0){
+ Vector<TableVersion> * vers = curr->theData;
+ if (vers->size())
+ {
+ TableVersion * ver = & vers->back();
+ ver->m_impl->m_status = NdbDictionary::Object::Invalid;
+ ver->m_status = DROPPED;
+ if (ver->m_refCount == 0)
+ {
+ delete ver->m_impl;
+ vers->erase(vers->size() - 1);
+ }
+ }
+ curr = m_tableHash.getNext(curr);
+ }
+ DBUG_VOID_RETURN;
+}
+
void
GlobalDictCache::release(NdbTableImpl * tab)
{
diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp
index 2df6a139542..6afa7946a8e 100644
--- a/ndb/src/ndbapi/DictCache.hpp
+++ b/ndb/src/ndbapi/DictCache.hpp
@@ -71,6 +71,9 @@ public:
void alter_table_rep(const char * name,
Uint32 tableId, Uint32 tableVersion, bool altered);
+
+ unsigned get_size();
+ void invalidate_all();
public:
enum Status {
OK = 0,
diff --git a/ndb/src/ndbapi/SignalSender.cpp b/ndb/src/ndbapi/SignalSender.cpp
index a29fe68937b..0ecc98f5f29 100644
--- a/ndb/src/ndbapi/SignalSender.cpp
+++ b/ndb/src/ndbapi/SignalSender.cpp
@@ -75,7 +75,9 @@ SignalSender::SignalSender(TransporterFacade *facade)
{
m_cond = NdbCondition_Create();
theFacade = facade;
+ lock();
m_blockNo = theFacade->open(this, execSignal, execNodeStatus);
+ unlock();
assert(m_blockNo > 0);
}
diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp
index bdd6fb3d05c..48e1c8ed25f 100644
--- a/ndb/src/ndbapi/TransporterFacade.hpp
+++ b/ndb/src/ndbapi/TransporterFacade.hpp
@@ -271,6 +271,12 @@ TransporterFacade::unlock_mutex()
#include "ClusterMgr.hpp"
inline
+unsigned Ndb_cluster_connection_impl::get_connect_count() const
+{
+ return TransporterFacade::instance()->theClusterMgr->m_connect_count;
+}
+
+inline
bool
TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size)
{
diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp
index 6c3d08d981d..1e53558f179 100644
--- a/ndb/src/ndbapi/ndb_cluster_connection.cpp
+++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp
@@ -243,6 +243,12 @@ Ndb_cluster_connection::wait_until_ready(int timeout,
} while (1);
}
+unsigned Ndb_cluster_connection::get_connect_count() const
+{
+ return m_impl.get_connect_count();
+}
+
+
/*
diff --git a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
index b305b93fec1..a50d3004364 100644
--- a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
+++ b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
@@ -49,6 +49,7 @@ class Ndb_cluster_connection_impl : public Ndb_cluster_connection
void init_get_next_node(Ndb_cluster_connection_node_iter &iter);
Uint32 get_next_node(Ndb_cluster_connection_node_iter &iter);
+ inline unsigned get_connect_count() const;
private:
friend class Ndb;
friend class NdbImpl;
diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am
index 0533493ba09..7dfa239cb66 100644
--- a/ndb/test/ndbapi/Makefile.am
+++ b/ndb/test/ndbapi/Makefile.am
@@ -24,6 +24,7 @@ testOIBasic \
testOperations \
testRestartGci \
testScan \
+testInterpreter \
testScanInterpreter \
testScanPerf \
testSystemRestart \
@@ -65,6 +66,7 @@ testOIBasic_SOURCES = testOIBasic.cpp
testOperations_SOURCES = testOperations.cpp
testRestartGci_SOURCES = testRestartGci.cpp
testScan_SOURCES = testScan.cpp ScanFunctions.hpp
+testInterpreter_SOURCES = testInterpreter.cpp
testScanInterpreter_SOURCES = testScanInterpreter.cpp ScanFilter.hpp ScanInterpretTest.hpp
testScanPerf_SOURCES = testScanPerf.cpp
testSystemRestart_SOURCES = testSystemRestart.cpp
diff --git a/ndb/test/ndbapi/testInterpreter.cpp b/ndb/test/ndbapi/testInterpreter.cpp
index 0baba33d2b2..5d930d3d555 100644
--- a/ndb/test/ndbapi/testInterpreter.cpp
+++ b/ndb/test/ndbapi/testInterpreter.cpp
@@ -79,46 +79,46 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
- NdbConnection* pTrans = pNdb->startTransaction();
- if (pTrans == NULL){
- ERR(pNdb->getNdbError());
- return NDBT_FAILED;
- }
-
- NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
- int check = pOp->interpretedUpdateTuple();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
-
- // Primary keys
- Uint32 pkVal = 1;
- check = pOp->equal("KOL1", pkVal );
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
- // Attributes
-
- // Update column
- Uint32 valToIncWith = 1;
- check = pOp->incValue("KOL2", valToIncWith);
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
+ NdbConnection* pTrans = pNdb->startTransaction();
+ if (pTrans == NULL){
+ ERR(pNdb->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
+ if (pOp == NULL) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ int check = pOp->interpretedUpdateTuple();
+ if( check == -1 ) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+
+ // Primary keys
+ Uint32 pkVal = 1;
+ check = pOp->equal("KOL1", pkVal );
+ if( check == -1 ) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ // Attributes
+
+ // Update column
+ Uint32 valToIncWith = 1;
+ check = pOp->incValue("KOL2", valToIncWith);
+ if( check == -1 ) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
NdbRecAttr* valueRec = pOp->getValue("KOL2");
if( valueRec == NULL ) {
@@ -142,6 +142,122 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+int runTestBug19537(NDBT_Context* ctx, NDBT_Step* step){
+ int result = NDBT_OK;
+ const NdbDictionary::Table * pTab = ctx->getTab();
+ Ndb* pNdb = GETNDB(step);
+
+ if (strcmp(pTab->getName(), "T1") != 0) {
+ g_err << "runTestBug19537: skip, table != T1" << endl;
+ return NDBT_OK;
+ }
+
+
+ NdbConnection* pTrans = pNdb->startTransaction();
+ if (pTrans == NULL){
+ ERR(pNdb->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
+ if (pOp == NULL) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->interpretedUpdateTuple() == -1) {
+ ERR(pOp->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+
+ // Primary keys
+ const Uint32 pkVal = 1;
+ if (pOp->equal("KOL1", pkVal) == -1) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ // Load 64-bit constant into register 1 and
+ // write from register 1 to 32-bit column KOL2
+ const Uint64 reg_val = 0x0102030405060708ULL;
+
+ const Uint32* reg_ptr32 = (const Uint32*)&reg_val;
+ if (reg_ptr32[0] == 0x05060708 && reg_ptr32[1] == 0x01020304) {
+ g_err << "runTestBug19537: platform is LITTLE endian" << endl;
+ } else if (reg_ptr32[0] == 0x01020304 && reg_ptr32[1] == 0x05060708) {
+ g_err << "runTestBug19537: platform is BIG endian" << endl;
+ } else {
+ g_err << "runTestBug19537: impossible platform"
+ << hex << " [0]=" << reg_ptr32[0] << " [1]=" <<reg_ptr32[1] << endl;
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->load_const_u64(1, reg_val) == -1 ||
+ pOp->write_attr("KOL2", 1) == -1) {
+ ERR(pOp->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (pTrans->execute(Commit) == -1) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ // Read value via a new transaction
+
+ pTrans = pNdb->startTransaction();
+ if (pTrans == NULL){
+ ERR(pNdb->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ pOp = pTrans->getNdbOperation(pTab->getName());
+ if (pOp == NULL) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ Uint32 kol2 = 0x09090909;
+ if (pOp->readTuple() == -1 ||
+ pOp->equal("KOL1", pkVal) == -1 ||
+ pOp->getValue("KOL2", (char*)&kol2) == 0) {
+ ERR(pOp->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (pTrans->execute(Commit) == -1) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ // Expected conversion as in C - truncate to lower (logical) word
+
+ if (kol2 == 0x01020304) {
+ g_err << "runTestBug19537: the bug manifests itself !" << endl;
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (kol2 != 0x05060708) {
+ g_err << "runTestBug19537: impossible KOL2 " << hex << kol2 << endl;
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ pNdb->closeTransaction(pTrans);
+ return NDBT_OK;
+}
+
NDBT_TESTSUITE(testInterpreter);
TESTCASE("IncValue32",
@@ -156,6 +272,12 @@ TESTCASE("IncValue64",
INITIALIZER(runTestIncValue64);
FINALIZER(runClearTable);
}
+TESTCASE("Bug19537",
+ "Test big-endian write_attr of 32 bit integer\n"){
+ INITIALIZER(runLoadTable);
+ INITIALIZER(runTestBug19537);
+ FINALIZER(runClearTable);
+}
#if 0
TESTCASE("MaxTransactions",
"Start transactions until no more can be created\n"){
diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp
index db90bd8bd90..cb02d5e7c36 100644
--- a/ndb/tools/waiter.cpp
+++ b/ndb/tools/waiter.cpp
@@ -124,6 +124,12 @@ getStatus(){
ndbout << "status==NULL, retries="<<retries<<endl;
MGMERR(handle);
retries++;
+ ndb_mgm_disconnect(handle);
+ if (ndb_mgm_connect(handle,0,0,1)) {
+ MGMERR(handle);
+ g_err << "Reconnect failed" << endl;
+ break;
+ }
continue;
}
int count = status->no_of_nodes;
diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc
index 95f9029f648..90d9d04cd36 100644
--- a/server-tools/instance-manager/manager.cc
+++ b/server-tools/instance-manager/manager.cc
@@ -35,12 +35,12 @@
#endif
-static int create_pid_file(const char *pid_file_name)
+int create_pid_file(const char *pid_file_name, int pid)
{
if (FILE *pid_file= my_fopen(pid_file_name,
O_WRONLY | O_CREAT | O_BINARY, MYF(0)))
{
- fprintf(pid_file, "%d\n", (int) getpid());
+ fprintf(pid_file, "%d\n", (int) pid);
my_fclose(pid_file, MYF(0));
return 0;
}
@@ -138,8 +138,13 @@ void manager(const Options &options)
if (user_map.load(options.password_file_name))
return;
- /* write pid file */
- if (create_pid_file(options.pid_file_name))
+ /* write Instance Manager pid file */
+
+ log_info("IM pid file: '%s'; PID: %d.",
+ (const char *) options.pid_file_name,
+ (int) manager_pid);
+
+ if (create_pid_file(options.pid_file_name, manager_pid))
return;
sigset_t mask;
diff --git a/server-tools/instance-manager/manager.h b/server-tools/instance-manager/manager.h
index 12ed6b3b1ff..3ddf292132e 100644
--- a/server-tools/instance-manager/manager.h
+++ b/server-tools/instance-manager/manager.h
@@ -20,4 +20,6 @@ struct Options;
void manager(const Options &options);
+int create_pid_file(const char *pid_file_name, int pid);
+
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H
diff --git a/server-tools/instance-manager/mysqlmanager.cc b/server-tools/instance-manager/mysqlmanager.cc
index d0b2cf2666c..ef714099de7 100644
--- a/server-tools/instance-manager/mysqlmanager.cc
+++ b/server-tools/instance-manager/mysqlmanager.cc
@@ -338,6 +338,14 @@ spawn:
/* Here we return to main, and fall into manager */
break;
default: // parent, success
+ pid= getpid(); /* Get our pid. */
+
+ log_info("Angel pid file: '%s'; PID: %d.",
+ (const char *) options.angel_pid_file_name,
+ (int) pid);
+
+ create_pid_file(Options::angel_pid_file_name, pid);
+
while (child_status == CHILD_OK && is_terminated == 0)
sigsuspend(&zeromask);
diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc
index e7d366e7457..a98c0e291be 100644
--- a/server-tools/instance-manager/options.cc
+++ b/server-tools/instance-manager/options.cc
@@ -44,6 +44,7 @@ const char *Options::user= 0; /* No default value */
const char *default_password_file_name= QUOTE(DEFAULT_PASSWORD_FILE_NAME);
const char *default_log_file_name= QUOTE(DEFAULT_LOG_FILE_NAME);
const char *Options::config_file= QUOTE(DEFAULT_CONFIG_FILE);
+const char *Options::angel_pid_file_name= NULL;
#endif
const char *Options::log_file_name= default_log_file_name;
const char *Options::pid_file_name= QUOTE(DEFAULT_PID_FILE_NAME);
@@ -58,6 +59,9 @@ char **Options::saved_argv= NULL;
/* Remember if the config file was forced */
bool Options::is_forced_default_file= 0;
+static const char * const ANGEL_PID_FILE_SUFFIX= ".angel.pid";
+static const int ANGEL_PID_FILE_SUFFIX_LEN= strlen(ANGEL_PID_FILE_SUFFIX);
+
/*
List of options, accepted by the instance manager.
List must be closed with empty option.
@@ -72,6 +76,7 @@ enum options {
#ifndef __WIN__
OPT_RUN_AS_SERVICE,
OPT_USER,
+ OPT_ANGEL_PID_FILE,
#else
OPT_INSTALL_SERVICE,
OPT_REMOVE_SERVICE,
@@ -94,7 +99,14 @@ static struct my_option my_long_options[] =
{ "pid-file", OPT_PID_FILE, "Pid file to use.",
(gptr *) &Options::pid_file_name, (gptr *) &Options::pid_file_name,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+
+#ifndef __WIN__
+ { "angel-pid-file", OPT_ANGEL_PID_FILE, "Pid file for angel process.",
+ (gptr *) &Options::angel_pid_file_name,
+ (gptr *) &Options::angel_pid_file_name,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+#endif
{ "socket", OPT_SOCKET, "Socket file to use for connection.",
(gptr *) &Options::socket_file_name, (gptr *) &Options::socket_file_name,
@@ -290,6 +302,46 @@ int Options::load(int argc, char **argv)
get_one_option)) != 0)
goto err;
+#ifndef __WIN__
+ if (Options::run_as_service)
+ {
+ if (Options::angel_pid_file_name == NULL)
+ {
+ /*
+ Calculate angel pid file on the IM pid file basis: replace the
+ extension (everything after the last dot) of the pid file basename to
+ '.angel.pid'.
+ */
+
+ char *angel_pid_file_name;
+ char *base_name_ptr;
+ char *ext_ptr;
+
+ angel_pid_file_name= (char *) malloc(strlen(Options::pid_file_name) +
+ ANGEL_PID_FILE_SUFFIX_LEN);
+
+ strcpy(angel_pid_file_name, Options::pid_file_name);
+
+ base_name_ptr= strrchr(angel_pid_file_name, '/');
+
+ if (!base_name_ptr)
+ base_name_ptr= angel_pid_file_name + 1;
+
+ ext_ptr= strrchr(base_name_ptr, '.');
+ if (ext_ptr)
+ *ext_ptr= 0;
+
+ strcat(angel_pid_file_name, ANGEL_PID_FILE_SUFFIX);
+
+ Options::angel_pid_file_name= angel_pid_file_name;
+ }
+ else
+ {
+ Options::angel_pid_file_name= strdup(Options::angel_pid_file_name);
+ }
+ }
+#endif
+
return 0;
err:
@@ -301,6 +353,11 @@ void Options::cleanup()
/* free_defaults returns nothing */
if (Options::saved_argv != NULL)
free_defaults(Options::saved_argv);
+
+#ifndef __WIN__
+ if (Options::run_as_service)
+ free((void *) Options::angel_pid_file_name);
+#endif
}
#ifdef __WIN__
diff --git a/server-tools/instance-manager/options.h b/server-tools/instance-manager/options.h
index abb094eac93..ad3458869b6 100644
--- a/server-tools/instance-manager/options.h
+++ b/server-tools/instance-manager/options.h
@@ -35,6 +35,7 @@ struct Options
#else
static char run_as_service; /* handle_options doesn't support bool */
static const char *user;
+ static const char *angel_pid_file_name;
#endif
static bool is_forced_default_file;
static const char *log_file_name;
diff --git a/sql-common/client.c b/sql-common/client.c
index 72745d72b12..26ebc9cc6b0 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1500,6 +1500,7 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
mysql->options.ssl_ca= strdup_if_not_null(ca);
mysql->options.ssl_capath= strdup_if_not_null(capath);
mysql->options.ssl_cipher= strdup_if_not_null(cipher);
+ mysql->options.ssl_verify_server_cert= FALSE; /* Off by default */
#endif /* HAVE_OPENSSL */
DBUG_RETURN(0);
}
@@ -1514,17 +1515,16 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
static void
mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
{
- struct st_VioSSLConnectorFd *st=
- (struct st_VioSSLConnectorFd*) mysql->connector_fd;
+ struct st_VioSSLFd *ssl_fd= (struct st_VioSSLFd*) mysql->connector_fd;
DBUG_ENTER("mysql_ssl_free");
my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
- if (st)
- SSL_CTX_free(st->ssl_context);
+ my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
+ if (ssl_fd)
+ SSL_CTX_free(ssl_fd->ssl_context);
my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.ssl_key = 0;
mysql->options.ssl_cert = 0;
@@ -1556,6 +1556,77 @@ mysql_get_ssl_cipher(MYSQL *mysql)
DBUG_RETURN(NULL);
}
+
+/*
+ Check the server's (subject) Common Name against the
+ hostname we connected to
+
+ SYNOPSIS
+ ssl_verify_server_cert()
+ vio pointer to a SSL connected vio
+ server_hostname name of the server that we connected to
+
+ RETURN VALUES
+ 0 Success
+ 1 Failed to validate server
+
+ */
+static int ssl_verify_server_cert(Vio *vio, const char* server_hostname)
+{
+ SSL *ssl;
+ X509 *server_cert;
+ char *cp1, *cp2;
+ char buf[256];
+ DBUG_ENTER("ssl_verify_server_cert");
+ DBUG_PRINT("enter", ("server_hostname: %s", server_hostname));
+
+ if (!(ssl= (SSL*)vio->ssl_arg))
+ {
+ DBUG_PRINT("error", ("No SSL pointer found"));
+ DBUG_RETURN(1);
+ }
+
+ if (!server_hostname)
+ {
+ DBUG_PRINT("error", ("No server hostname supplied"));
+ DBUG_RETURN(1);
+ }
+
+ if (!(server_cert= SSL_get_peer_certificate(ssl)))
+ {
+ DBUG_PRINT("error", ("Could not get server certificate"));
+ DBUG_RETURN(1);
+ }
+
+ /*
+ We already know that the certificate exchanged was valid; the SSL library
+ handled that. Now we need to verify that the contents of the certificate
+ are what we expect.
+ */
+
+ X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf));
+ X509_free (server_cert);
+
+ DBUG_PRINT("info", ("hostname in cert: %s", buf));
+ cp1= strstr(buf, "/CN=");
+ if (cp1)
+ {
+ cp1+= 4; /* Skip the "/CN=" that we found */
+ /* Search for next / which might be the delimiter for email */
+ cp2= strchr(cp1, '/');
+ if (cp2)
+ *cp2= '\0';
+ DBUG_PRINT("info", ("Server hostname in cert: %s", cp1));
+ if (!strcmp(cp1, server_hostname))
+ {
+ /* Success */
+ DBUG_RETURN(0);
+ }
+ }
+ DBUG_PRINT("error", ("SSL certificate validation failure"));
+ DBUG_RETURN(1);
+}
+
#endif /* HAVE_OPENSSL */
@@ -1589,7 +1660,6 @@ static MYSQL_METHODS client_methods=
#endif
};
-
MYSQL *
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
@@ -2034,37 +2104,52 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
mysql->client_flag=client_flag;
#ifdef HAVE_OPENSSL
- /*
- Oops.. are we careful enough to not send ANY information without
- encryption?
- */
if (client_flag & CLIENT_SSL)
{
+ /* 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
+ */
if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net))
{
set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
goto error;
}
- /* Do the SSL layering. */
- if (!(mysql->connector_fd=
- (gptr) new_VioSSLConnectorFd(options->ssl_key,
- options->ssl_cert,
- options->ssl_ca,
- options->ssl_capath,
- options->ssl_cipher)))
+
+ /* 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((struct st_VioSSLConnectorFd*)(mysql->connector_fd),
- mysql->net.vio, (long) (mysql->options.connect_timeout)))
+ if (sslconnect(ssl_fd, mysql->net.vio,
+ (long) (mysql->options.connect_timeout)))
{
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
goto error;
}
DBUG_PRINT("info", ("IO layer change done!"));
+
+ /* Verify server cert */
+ if (mysql->options.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 */
@@ -2804,6 +2889,9 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
case MYSQL_OPT_RECONNECT:
mysql->reconnect= *(my_bool *) arg;
break;
+ case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
+ mysql->options.ssl_verify_server_cert= *(my_bool *) arg;
+ break;
default:
DBUG_RETURN(1);
}
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 895f022624c..4e977c06180 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -642,7 +642,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
void field_conv(Field *to,Field *from)
{
- if (to->real_type() == from->real_type())
+ if (to->real_type() == from->real_type() &&
+ !(to->type() == FIELD_TYPE_BLOB && to->table->copy_blobs))
{
if (to->pack_length() == from->pack_length() &&
!(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) &&
diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc
index 2505919af39..7632ed59949 100644
--- a/sql/ha_blackhole.cc
+++ b/sql/ha_blackhole.cc
@@ -47,7 +47,7 @@ handlerton blackhole_hton= {
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
- HTON_CAN_RECREATE
+ HTON_CAN_RECREATE | HTON_ALTER_CANNOT_CREATE
};
/*****************************************************************************
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 934437e0c91..28cdfd23b6a 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -4048,6 +4048,9 @@ ha_innobase::index_prev(
mysql_byte* buf) /* in/out: buffer for previous row in MySQL
format */
{
+ statistic_increment(current_thd->status_var.ha_read_prev_count,
+ &LOCK_status);
+
return(general_fetch(buf, ROW_SEL_PREV, 0));
}
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 9780f163634..d2fd1a9e28a 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -55,7 +55,7 @@ handlerton myisammrg_hton= {
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
- HTON_CAN_RECREATE
+ HTON_CAN_RECREATE | HTON_ALTER_CANNOT_CREATE
};
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 138e8c72e7a..3d9bd2dbe0f 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -3512,8 +3512,23 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
{
m_table= (void *)tab;
m_table_version = tab->getObjectVersion();
- if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN)))
+ if ((my_errno= build_index_list(ndb, table, ILBP_OPEN)))
DBUG_RETURN(my_errno);
+
+ const void *data, *pack_data;
+ uint length, pack_length;
+ if (readfrm(table->s->path, &data, &length) ||
+ packfrm(data, length, &pack_data, &pack_length) ||
+ pack_length != tab->getFrmLength() ||
+ memcmp(pack_data, tab->getFrmData(), pack_length))
+ {
+ my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
+ my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
+ NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT);
+ DBUG_RETURN(ndb_to_mysql_error(&err));
+ }
+ my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
+ my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
}
m_table_info= tab_info;
}
diff --git a/sql/handler.h b/sql/handler.h
index eee15fc3576..31aac075a5e 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -409,6 +409,7 @@ struct show_table_alias_st {
#define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
#define HTON_CAN_RECREATE (1 << 2) //Delete all is used fro truncate
#define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
+#define HTON_ALTER_CANNOT_CREATE (1 << 4) //Cannot use alter to create
typedef struct st_thd_trans
{
diff --git a/sql/item.cc b/sql/item.cc
index 31fbef0f053..24efc1f106f 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -304,6 +304,7 @@ Item::Item():
marker= 0;
maybe_null=null_value=with_sum_func=unsigned_flag=0;
decimals= 0; max_length= 0;
+ with_subselect= 0;
/* Put item in free list so that we can free all items at end */
THD *thd= current_thd;
@@ -958,6 +959,12 @@ void Item_splocal::print(String *str)
}
+bool Item_splocal::set_value(THD *thd, sp_rcontext *ctx, Item **it)
+{
+ return ctx->set_variable(thd, get_var_idx(), it);
+}
+
+
/*****************************************************************************
Item_case_expr methods
*****************************************************************************/
@@ -1883,7 +1890,6 @@ Item_decimal::Item_decimal(const char *str_arg, uint length,
name= (char*) str_arg;
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1893,7 +1899,6 @@ Item_decimal::Item_decimal(longlong val, bool unsig)
int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value);
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1904,7 +1909,6 @@ Item_decimal::Item_decimal(double val, int precision, int scale)
double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value);
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1917,7 +1921,6 @@ Item_decimal::Item_decimal(const char *str, const my_decimal *val_arg,
name= (char*) str;
decimals= (uint8) decimal_par;
max_length= length;
- unsigned_flag= !decimal_value.sign();
fixed= 1;
}
@@ -1927,7 +1930,6 @@ Item_decimal::Item_decimal(my_decimal *value_par)
my_decimal2decimal(value_par, &decimal_value);
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1939,7 +1941,6 @@ Item_decimal::Item_decimal(const char *bin, int precision, int scale)
&decimal_value, precision, scale);
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(precision, decimals,
unsigned_flag);
}
@@ -4840,7 +4841,16 @@ void Item_ref::cleanup()
void Item_ref::print(String *str)
{
if (ref)
- (*ref)->print(str);
+ {
+ if ((*ref)->type() != Item::CACHE_ITEM && ref_type() != VIEW_REF &&
+ name && alias_name_used)
+ {
+ THD *thd= current_thd;
+ append_identifier(thd, str, name, (uint) strlen(name));
+ }
+ else
+ (*ref)->print(str);
+ }
else
Item_ident::print(str);
}
@@ -5365,6 +5375,25 @@ bool Item_trigger_field::eq(const Item *item, bool binary_cmp) const
}
+void Item_trigger_field::set_required_privilege(bool rw)
+{
+ /*
+ Require SELECT and UPDATE privilege if this field will be read and
+ set, and only UPDATE privilege for setting the field.
+ */
+ want_privilege= (rw ? SELECT_ACL | UPDATE_ACL : UPDATE_ACL);
+}
+
+
+bool Item_trigger_field::set_value(THD *thd, sp_rcontext */*ctx*/, Item **it)
+{
+ Item *item= sp_prepare_func_item(thd, it);
+
+ return (!item || (!fixed && fix_fields(thd, 0)) ||
+ (item->save_in_field(field, 0) < 0));
+}
+
+
bool Item_trigger_field::fix_fields(THD *thd, Item **items)
{
/*
@@ -5387,8 +5416,7 @@ bool Item_trigger_field::fix_fields(THD *thd, Item **items)
if (table_grants)
{
- table_grants->want_privilege=
- access_type == AT_READ ? SELECT_ACL : UPDATE_ACL;
+ table_grants->want_privilege= want_privilege;
if (check_grant_column(thd, table_grants, triggers->table->s->db,
triggers->table->s->table_name, field_name,
@@ -5420,6 +5448,7 @@ void Item_trigger_field::print(String *str)
void Item_trigger_field::cleanup()
{
+ want_privilege= original_privilege;
/*
Since special nature of Item_trigger_field we should not do most of
things from Item_field::cleanup() or Item_ident::cleanup() here.
diff --git a/sql/item.h b/sql/item.h
index 24aca4a86d1..28b1f54add7 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -372,6 +372,42 @@ public:
/*************************************************************************/
+class sp_rcontext;
+
+
+class Settable_routine_parameter
+{
+public:
+ /*
+ Set required privileges for accessing the parameter.
+
+ SYNOPSIS
+ set_required_privilege()
+ rw if 'rw' is true then we are going to read and set the
+ parameter, so SELECT and UPDATE privileges might be
+ required, otherwise we only reading it and SELECT
+ privilege might be required.
+ */
+ virtual void set_required_privilege(bool rw) {};
+
+ /*
+ Set parameter value.
+
+ SYNOPSIS
+ set_value()
+ thd thread handle
+ ctx context to which parameter belongs (if it is local
+ variable).
+ it item which represents new value
+
+ RETURN
+ FALSE if parameter value has been set,
+ TRUE if error has occured.
+ */
+ virtual bool set_value(THD *thd, sp_rcontext *ctx, Item **it)= 0;
+};
+
+
typedef bool (Item::*Item_processor)(byte *arg);
typedef Item* (Item::*Item_transformer) (byte *arg);
typedef void (*Cond_traverser) (const Item *item, void *arg);
@@ -424,6 +460,9 @@ public:
my_bool is_autogenerated_name; /* indicate was name of this Item
autogenerated or set by user */
DTCollation collation;
+ my_bool with_subselect; /* If this item is a subselect or some
+ of its arguments is or contains a
+ subselect */
// alloc & destruct is done as start of select using sql_alloc
Item();
@@ -744,6 +783,15 @@ public:
}
virtual bool is_splocal() { return 0; } /* Needed for error checking */
+
+ /*
+ Return Settable_routine_parameter interface of the Item. Return 0
+ if this Item is not Settable_routine_parameter.
+ */
+ virtual Settable_routine_parameter *get_settable_routine_parameter()
+ {
+ return 0;
+ }
};
@@ -842,7 +890,8 @@ inline bool Item_sp_variable::send(Protocol *protocol, String *str)
runtime.
*****************************************************************************/
-class Item_splocal :public Item_sp_variable
+class Item_splocal :public Item_sp_variable,
+ private Settable_routine_parameter
{
uint m_var_idx;
@@ -880,6 +929,15 @@ public:
inline enum Type type() const;
inline Item_result result_type() const;
+
+private:
+ bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
+
+public:
+ Settable_routine_parameter *get_settable_routine_parameter()
+ {
+ return this;
+ }
};
/*****************************************************************************
@@ -2100,14 +2158,13 @@ class Table_triggers_list;
two Field instances representing either OLD or NEW version of this
field.
*/
-class Item_trigger_field : public Item_field
+class Item_trigger_field : public Item_field,
+ private Settable_routine_parameter
{
public:
/* Is this item represents row from NEW or OLD row ? */
enum row_version_type {OLD_ROW, NEW_ROW};
row_version_type row_version;
- /* Is this item used for reading or updating the value? */
- enum access_types { AT_READ = 0x1, AT_UPDATE = 0x2 };
/* Next in list of all Item_trigger_field's in trigger */
Item_trigger_field *next_trg_field;
/* Index of the field in the TABLE::field array */
@@ -2118,11 +2175,11 @@ public:
Item_trigger_field(Name_resolution_context *context_arg,
row_version_type row_ver_arg,
const char *field_name_arg,
- access_types access_type_arg)
+ ulong priv, const bool ro)
:Item_field(context_arg,
(const char *)NULL, (const char *)NULL, field_name_arg),
- row_version(row_ver_arg), field_idx((uint)-1),
- access_type(access_type_arg), table_grants(NULL)
+ row_version(row_ver_arg), field_idx((uint)-1), original_privilege(priv),
+ want_privilege(priv), table_grants(NULL), read_only (ro)
{}
void setup_field(THD *thd, TABLE *table, GRANT_INFO *table_grant_info);
enum Type type() const { return TRIGGER_FIELD_ITEM; }
@@ -2133,8 +2190,39 @@ public:
void cleanup();
private:
- access_types access_type;
+ void set_required_privilege(bool rw);
+ bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
+
+public:
+ Settable_routine_parameter *get_settable_routine_parameter()
+ {
+ return (read_only ? 0 : this);
+ }
+
+ bool set_value(THD *thd, Item **it)
+ {
+ return set_value(thd, NULL, it);
+ }
+
+private:
+ /*
+ 'want_privilege' holds privileges required to perform operation on
+ this trigger field (SELECT_ACL if we are going to read it and
+ UPDATE_ACL if we are going to update it). It is initialized at
+ parse time but can be updated later if this trigger field is used
+ as OUT or INOUT parameter of stored routine (in this case
+ set_required_privilege() is called to appropriately update
+ want_privilege and cleanup() is responsible for restoring of
+ original want_privilege once parameter's value is updated).
+ */
+ ulong original_privilege;
+ ulong want_privilege;
GRANT_INFO *table_grants;
+ /*
+ Trigger field is read-only unless it belongs to the NEW row in a
+ BEFORE INSERT of BEFORE UPDATE trigger.
+ */
+ bool read_only;
};
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 54e281a1f14..725be547a8a 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -204,10 +204,28 @@ longlong Item_func_nop_all::val_int()
/*
- Convert a constant expression or string to an integer.
- This is done when comparing DATE's of different formats and
- also when comparing bigint to strings (in which case the string
- is converted once to a bigint).
+ Convert a constant item to an int and replace the original item
+
+ SYNOPSIS
+ convert_constant_item()
+ thd thread handle
+ field item will be converted using the type of this field
+ item [in/out] reference to the item to convert
+
+ DESCRIPTION
+ The function converts a constant expression or string to an integer.
+ On successful conversion the original item is substituted for the
+ result of the item evaluation.
+ This is done when comparing DATE/TIME of different formats and
+ also when comparing bigint to strings (in which case strings
+ are converted to bigints).
+
+ NOTES
+ This function is called only at prepare stage.
+ As all derived tables are filled only after all derived tables
+ are prepared we do not evaluate items with subselects here because
+ they can contain derived tables and thus we may attempt to use a
+ table that has not been populated yet.
RESULT VALUES
0 Can't convert item
@@ -216,7 +234,7 @@ longlong Item_func_nop_all::val_int()
static bool convert_constant_item(THD *thd, Field *field, Item **item)
{
- if ((*item)->const_item())
+ if (!(*item)->with_subselect && (*item)->const_item())
{
/* For comparison purposes allow invalid dates like 2000-01-32 */
ulong orig_sql_mode= field->table->in_use->variables.sql_mode;
@@ -2570,7 +2588,9 @@ Item_cond::fix_fields(THD *thd, Item **ref)
(item= *li.ref())->check_cols(1))
return TRUE; /* purecov: inspected */
used_tables_cache|= item->used_tables();
- if (!item->const_item())
+ if (item->const_item())
+ and_tables_cache= (table_map) 0;
+ else
{
tmp_table_map= item->not_null_tables();
not_null_tables_cache|= tmp_table_map;
@@ -2578,6 +2598,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
const_item_cache= FALSE;
}
with_sum_func= with_sum_func || item->with_sum_func;
+ with_subselect|= item->with_subselect;
if (item->maybe_null)
maybe_null=1;
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 21aa7ed2a1b..2c770bec1ad 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -184,6 +184,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
used_tables_cache|= item->used_tables();
not_null_tables_cache|= item->not_null_tables();
const_item_cache&= item->const_item();
+ with_subselect|= item->with_subselect;
}
}
fix_length_and_dec();
@@ -2734,9 +2735,10 @@ String *udf_handler::val_str(String *str,String *save_str)
{
uchar is_null_tmp=0;
ulong res_length;
+ DBUG_ENTER("udf_handler::val_str");
if (get_arguments())
- return 0;
+ DBUG_RETURN(0);
char * (*func)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)=
(char* (*)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *))
u_d->func;
@@ -2746,22 +2748,26 @@ String *udf_handler::val_str(String *str,String *save_str)
if (str->alloc(MAX_FIELD_WIDTH))
{
error=1;
- return 0;
+ DBUG_RETURN(0);
}
}
char *res=func(&initid, &f_args, (char*) str->ptr(), &res_length,
&is_null_tmp, &error);
+ DBUG_PRINT("info", ("udf func returned, res_length: %lu", res_length));
if (is_null_tmp || !res || error) // The !res is for safety
{
- return 0;
+ DBUG_PRINT("info", ("Null or error"));
+ DBUG_RETURN(0);
}
if (res == str->ptr())
{
str->length(res_length);
- return str;
+ DBUG_PRINT("exit", ("str: %s", str->ptr()));
+ DBUG_RETURN(str);
}
save_str->set(res, res_length, str->charset());
- return save_str;
+ DBUG_PRINT("exit", ("save_str: %s", save_str->ptr()));
+ DBUG_RETURN(save_str);
}
@@ -4115,6 +4121,18 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
}
+bool Item_func_get_user_var::set_value(THD *thd,
+ sp_rcontext */*ctx*/, Item **it)
+{
+ Item_func_set_user_var *suv= new Item_func_set_user_var(get_name(), *it);
+ /*
+ Item_func_set_user_var is not fixed after construction, call
+ fix_fields().
+ */
+ return (!suv || suv->fix_fields(thd, it) || suv->check() || suv->update());
+}
+
+
bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
@@ -4747,6 +4765,7 @@ Item_func_sp::sp_result_field(void) const
dummy_table->alias = empty_name;
dummy_table->maybe_null = maybe_null;
dummy_table->in_use= current_thd;
+ dummy_table->copy_blobs= TRUE;
share->table_cache_key = empty_name;
share->table_name = empty_name;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index a91d93be8c6..1d8a1bd5e22 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1179,7 +1179,8 @@ public:
};
-class Item_func_get_user_var :public Item_func
+class Item_func_get_user_var :public Item_func,
+ private Settable_routine_parameter
{
user_var_entry *var_entry;
@@ -1206,6 +1207,15 @@ public:
table_map used_tables() const
{ return const_item() ? 0 : RAND_TABLE_BIT; }
bool eq(const Item *item, bool binary_cmp) const;
+
+private:
+ bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
+
+public:
+ Settable_routine_parameter *get_settable_routine_parameter()
+ {
+ return this;
+ }
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index a1743aa1181..ce9897afeed 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2579,7 +2579,7 @@ String *Item_load_file::val_str(String *str)
(void) fn_format(path, file_name->c_ptr(), mysql_real_data_home, "",
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
- if (!my_stat(path, &stat_info, MYF(MY_WME)))
+ if (!my_stat(path, &stat_info, MYF(0)))
goto err;
if (!(stat_info.st_mode & S_IROTH))
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 7d7b62df0dc..90d421a2c68 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -542,7 +542,7 @@ public:
void fix_length_and_dec()
{
collation.set(default_charset());
- decimals=0; max_length=64;
+ max_length= 64;
}
};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index d93f6501ebb..87ef0fc080e 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -39,6 +39,7 @@ Item_subselect::Item_subselect():
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
const_item_cache(1), engine_changed(0), changed(0)
{
+ with_subselect= 1;
reset();
/*
item value is NULL if select_subselect not changed this value
@@ -1351,6 +1352,17 @@ void Item_in_subselect::print(String *str)
}
+bool Item_in_subselect::fix_fields(THD *thd, Item **ref)
+{
+ bool result = 0;
+
+ if(thd->lex->view_prepare_mode && left_expr && !left_expr->fixed)
+ result = left_expr->fix_fields(thd, &left_expr);
+
+ return result || Item_subselect::fix_fields(thd, ref);
+}
+
+
Item_subselect::trans_res
Item_allany_subselect::select_transformer(JOIN *join)
{
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index a4dac5bda87..293408dc09e 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -258,6 +258,7 @@ public:
void top_level_item() { abort_on_null=1; }
bool test_limit(st_select_lex_unit *unit);
void print(String *str);
+ bool fix_fields(THD *thd, Item **ref);
friend class Item_ref_null_helper;
friend class Item_is_not_null_test;
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index d2fef647fb9..72c53272e0c 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -917,9 +917,9 @@ String* Item_func_monthname::val_str(String* str)
{
DBUG_ASSERT(fixed == 1);
const char *month_name;
- uint month=(uint) Item_func_month::val_int();
+ uint month= (uint) val_int();
- if (!month) // This is also true for NULL
+ if (null_value || !month)
{
null_value=1;
return (String*) 0;
@@ -2144,8 +2144,13 @@ bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
Item_date_add_interval *other= (Item_date_add_interval*) item;
if ((int_type != other->int_type) ||
- (!args[0]->eq(other->args[0], binary_cmp)) ||
- (get_interval_value(args[1], int_type, &val, &interval)))
+ (!args[0]->eq(other->args[0], binary_cmp)))
+ return FALSE;
+
+ if (!args[1]->const_item() || !other->args[1]->const_item())
+ return (args[1]->eq(other->args[1], binary_cmp));
+
+ if (get_interval_value(args[1], int_type, &val, &interval))
return FALSE;
val= other->value;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 399b861e8f4..707a474b754 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -718,12 +718,6 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
List<create_field> &fields, List<Key> &keys,
bool tmp_table, uint select_field_count);
-TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
- TABLE_LIST *create_table,
- List<create_field> *extra_fields,
- List<Key> *keys,
- List<Item> *items,
- MYSQL_LOCK **lock);
bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
@@ -1311,15 +1305,16 @@ extern pthread_t signal_thread;
#endif
#ifdef HAVE_OPENSSL
-extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
+extern struct st_VioSSLFd * ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
uint flags, bool *need_reopen);
-/* mysql_lock_tables() flags bits */
+/* mysql_lock_tables() and open_table() flags bits */
#define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001
#define MYSQL_LOCK_IGNORE_FLUSH 0x0002
#define MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN 0x0004
+#define MYSQL_OPEN_IGNORE_LOCKED_TABLES 0x0008
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
@@ -1583,6 +1578,16 @@ inline int hexchar_to_int(char c)
return -1;
}
+/*
+ is_user_table()
+ return true if the table was created explicitly
+*/
+
+inline bool is_user_table(TABLE * table)
+{
+ const char *name= table->s->table_name;
+ return strncmp(name, tmp_file_prefix, tmp_file_prefix_length);
+}
/*
Some functions that are different in the embedded library and the normal
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index aa58617ee09..50f19c15fc4 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -621,7 +621,7 @@ static void openssl_lock(int, openssl_lock_t *, const char *, int);
static unsigned long openssl_id_function();
#endif
char *des_key_file;
-struct st_VioSSLAcceptorFd *ssl_acceptor_fd;
+struct st_VioSSLFd *ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */
@@ -955,7 +955,8 @@ static void __cdecl kill_server(int sig_ptr)
RETURN_FROM_KILL_SERVER;
kill_in_progress=TRUE;
abort_loop=1; // This should be set
- my_sigset(sig,SIG_IGN);
+ if (sig != 0) // 0 is not a valid signal number
+ my_sigset(sig,SIG_IGN);
if (sig == MYSQL_KILL_SIGNAL || sig == 0)
sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
else
@@ -987,6 +988,10 @@ static void __cdecl kill_server(int sig_ptr)
pthread_join(select_thread, NULL); // wait for main thread
#endif /* __NETWARE__ */
+#if defined(__NETWARE__) || (defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__) && !defined(OS2))
+ my_thread_end();
+#endif
+
pthread_exit(0); /* purecov: deadcode */
#endif /* EMBEDDED_LIBRARY */
@@ -1132,8 +1137,13 @@ void clean_up(bool print_message)
#endif
#ifdef HAVE_OPENSSL
if (ssl_acceptor_fd)
- my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR));
+ {
+ SSL_CTX_free(ssl_acceptor_fd->ssl_context);
+ my_free((gptr) ssl_acceptor_fd, MYF(0));
+ }
#endif /* HAVE_OPENSSL */
+ vio_end();
+
#ifdef USE_REGEX
my_regex_end();
#endif
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 2610e4fc1c8..e36932cbc0c 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -347,8 +347,10 @@ typedef struct st_qsel_param {
uint *imerge_cost_buff; /* buffer for index_merge cost estimates */
uint imerge_cost_buff_size; /* size of the buffer */
- /* TRUE if last checked tree->key can be used for ROR-scan */
+ /* TRUE if last checked tree->key can be used for ROR-scan */
bool is_ror_scan;
+ /* Number of ranges in the last checked tree->key */
+ uint n_ranges;
} PARAM;
class TABLE_READ_PLAN;
@@ -3501,17 +3503,46 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
if (inv)
{
- /*
- We get here for conditions like "t.keypart NOT IN (....)".
-
- If the IN-list contains only constants (and func->array is an ordered
- array of them), we construct the appropriate SEL_ARG tree manually,
- because constructing it using the range analyzer (as
- AND_i( t.keypart != c_i)) will cause lots of memory to be consumed
- (see BUG#15872).
- */
if (func->array && func->cmp_type != ROW_RESULT)
{
+ /*
+ We get here for conditions in form "t.key NOT IN (c1, c2, ...)"
+ (where c{i} are constants).
+ Our goal is to produce a SEL_ARG graph that represents intervals:
+
+ ($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ... (*)
+
+ where $MIN is either "-inf" or NULL.
+
+ The most straightforward way to handle NOT IN would be to convert
+ it to "(t.key != c1) AND (t.key != c2) AND ..." and let the range
+ optimizer to build SEL_ARG graph from that. However that will cause
+ the range optimizer to use O(N^2) memory (it's a bug, not filed),
+ and people do use big NOT IN lists (see BUG#15872). Also, for big
+ NOT IN lists constructing/using graph (*) does not make the query
+ faster.
+
+ So, we will handle NOT IN manually in the following way:
+ * if the number of entries in the NOT IN list is less then
+ NOT_IN_IGNORE_THRESHOLD, we will construct SEL_ARG graph (*)
+ manually.
+ * Otherwise, we will construct a smaller graph: for
+ "t.key NOT IN (c1,...cN)" we construct a graph representing
+ ($MIN < t.key) OR (cN < t.key) // here sequence of c_i is
+ // ordered.
+
+ A note about partially-covering indexes: for those (e.g. for
+ "a CHAR(10), KEY(a(5))") the handling is correct (albeit not very
+ efficient):
+ Instead of "t.key < c1" we get "t.key <= prefix-val(c1)".
+ Combining the intervals in (*) together, we get:
+ (-inf<=t.key<=c1) OR (c1<=t.key<=c2) OR (c2<=t.key<=c3) OR ...
+ i.e. actually we get intervals combined into one interval:
+ (-inf<=t.key<=+inf). This doesn't make much sense but it doesn't
+ cause any problems.
+ */
+ MEM_ROOT *tmp_root= param->mem_root;
+ param->thd->mem_root= param->old_root;
/*
Create one Item_type constant object. We'll need it as
get_mm_parts only accepts constant values wrapped in Item_Type
@@ -3520,25 +3551,35 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
per-statement mem_root (while thd->mem_root is currently pointing
to mem_root local to range optimizer).
*/
- MEM_ROOT *tmp_root= param->mem_root;
- param->thd->mem_root= param->old_root;
Item *value_item= func->array->create_item();
param->thd->mem_root= tmp_root;
if (!value_item)
break;
- /* Get a SEL_TREE for "-inf < X < c_0" interval */
- func->array->value_to_item(0, value_item);
- tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
- value_item, cmp_type);
- if (!tree)
+ /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */
+ uint i=0;
+ do
+ {
+ func->array->value_to_item(i, value_item);
+ tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
+ value_item, cmp_type);
+ if (!tree)
+ break;
+ i++;
+ } while (i < func->array->count && tree->type == SEL_TREE::IMPOSSIBLE);
+
+ if (!tree || tree->type == SEL_TREE::IMPOSSIBLE)
+ {
+ /* We get here in cases like "t.unsigned NOT IN (-1,-2,-3) */
+ tree= NULL;
break;
+ }
#define NOT_IN_IGNORE_THRESHOLD 1000
SEL_TREE *tree2;
if (func->array->count < NOT_IN_IGNORE_THRESHOLD)
{
- for (uint i=1; i < func->array->count; i++)
+ for (; i < func->array->count; i++)
{
if (func->array->compare_elems(i, i-1))
{
@@ -3546,32 +3587,44 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
func->array->value_to_item(i, value_item);
tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
value_item, cmp_type);
-
+ if (!tree2)
+ {
+ tree= NULL;
+ break;
+ }
+
/* Change all intervals to be "c_{i-1} < X < c_i" */
for (uint idx= 0; idx < param->keys; idx++)
{
- SEL_ARG *new_interval;
- if ((new_interval= tree2->keys[idx]))
+ SEL_ARG *new_interval, *last_val;
+ if (((new_interval= tree2->keys[idx])) &&
+ ((last_val= tree->keys[idx]->last())))
{
- SEL_ARG *last_val= tree->keys[idx]->last();
new_interval->min_value= last_val->max_value;
new_interval->min_flag= NEAR_MIN;
}
}
+ /*
+ The following doesn't try to allocate memory so no need to
+ check for NULL.
+ */
tree= tree_or(param, tree, tree2);
}
}
}
else
func->array->value_to_item(func->array->count - 1, value_item);
-
- /*
- Get the SEL_TREE for the last "c_last < X < +inf" interval
- (value_item cotains c_last already)
- */
- tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
- value_item, cmp_type);
- tree= tree_or(param, tree, tree2);
+
+ if (tree && tree->type != SEL_TREE::IMPOSSIBLE)
+ {
+ /*
+ Get the SEL_TREE for the last "c_last < X < +inf" interval
+ (value_item cotains c_last already)
+ */
+ tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
+ value_item, cmp_type);
+ tree= tree_or(param, tree, tree2);
+ }
}
else
{
@@ -5297,6 +5350,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
param->table->file->primary_key_is_clustered());
param->is_ror_scan= !cpk_scan;
}
+ param->n_ranges= 0;
records=check_quick_keys(param,idx,tree,param->min_key,0,param->max_key,0);
if (records != HA_POS_ERROR)
@@ -5304,7 +5358,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
param->table->quick_keys.set_bit(key);
param->table->quick_rows[key]=records;
param->table->quick_key_parts[key]=param->max_key_part+1;
-
+ param->table->quick_n_ranges[key]= param->n_ranges;
if (cpk_scan)
param->is_ror_scan= TRUE;
}
@@ -5440,7 +5494,10 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
HA_NOSAME &&
min_key_length == max_key_length &&
!memcmp(param->min_key,param->max_key,min_key_length))
+ {
tmp=1; // Max one record
+ param->n_ranges++;
+ }
else
{
if (param->is_ror_scan)
@@ -5460,6 +5517,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
is_key_scan_ror(param, keynr, key_tree->part + 1)))
param->is_ror_scan= FALSE;
}
+ param->n_ranges++;
if (tmp_min_flag & GEOM_FLAG)
{
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 2892c5c8b01..4e7b9200d88 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5475,7 +5475,7 @@ ER_SP_DUP_HANDLER 42000
eng "Duplicate handler declared in the same block"
ger "Doppelter Handler im selben Block deklariert"
ER_SP_NOT_VAR_ARG 42000
- eng "OUT or INOUT argument %d for routine %s is not a variable"
+ eng "OUT or INOUT argument %d for routine %s is not a variable or NEW pseudo-variable in BEFORE trigger"
ger "OUT- oder INOUT-Argument %d für Routine %s ist keine Variable"
ER_SP_NO_RETSET 0A000
eng "Not allowed to return a result set from a %s"
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 6a7676c7bf2..174f62c9497 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -310,11 +310,13 @@ sp_prepare_func_item(THD* thd, Item **it_addr)
*/
bool
-sp_eval_expr(THD *thd, Field *result_field, Item *expr_item)
+sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
{
+ Item *expr_item;
+
DBUG_ENTER("sp_eval_expr");
- if (!(expr_item= sp_prepare_func_item(thd, &expr_item)))
+ if (!(expr_item= sp_prepare_func_item(thd, expr_item_ptr)))
DBUG_RETURN(TRUE);
bool err_status= FALSE;
@@ -936,6 +938,7 @@ sp_head::execute(THD *thd)
bool err_status= FALSE;
uint ip= 0;
ulong save_sql_mode;
+ bool save_abort_on_warning;
Query_arena *old_arena;
/* per-instruction arena */
MEM_ROOT execute_mem_root;
@@ -996,6 +999,10 @@ sp_head::execute(THD *thd)
thd->derived_tables= 0;
save_sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode= m_sql_mode;
+ save_abort_on_warning= thd->abort_on_warning;
+ thd->abort_on_warning=
+ (m_sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
+
/*
It is also more efficient to save/restore current thd->lex once when
do it in each instruction
@@ -1128,6 +1135,7 @@ sp_head::execute(THD *thd)
DBUG_ASSERT(!thd->derived_tables);
thd->derived_tables= old_derived_tables;
thd->variables.sql_mode= save_sql_mode;
+ thd->abort_on_warning= save_abort_on_warning;
thd->stmt_arena= old_arena;
state= EXECUTED;
@@ -1204,130 +1212,144 @@ bool
sp_head::execute_function(THD *thd, Item **argp, uint argcount,
Field *return_value_fld)
{
- Item_cache **param_values;
ulonglong binlog_save_options;
bool need_binlog_call;
- uint params;
+ uint arg_no;
sp_rcontext *octx = thd->spcont;
sp_rcontext *nctx = NULL;
+ char buf[STRING_BUFFER_USUAL_SIZE];
+ String binlog_buf(buf, sizeof(buf), &my_charset_bin);
bool err_status= FALSE;
+ MEM_ROOT call_mem_root;
+ Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP);
+ Query_arena backup_arena;
DBUG_ENTER("sp_head::execute_function");
DBUG_PRINT("info", ("function %s", m_name.str));
- params = m_pcont->context_var_count();
-
/*
Check that the function is called with all specified arguments.
If it is not, use my_error() to report an error, or it will not terminate
the invoking query properly.
*/
-
- if (argcount != params)
+ if (argcount != m_pcont->context_var_count())
{
/*
Need to use my_error here, or it will not terminate the
invoking query properly.
*/
my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0),
- "FUNCTION", m_qname.str, params, argcount);
+ "FUNCTION", m_qname.str, m_pcont->context_var_count(), argcount);
DBUG_RETURN(TRUE);
}
-
- /* Allocate param_values to be used for dumping the call into binlog. */
-
- if (!(param_values= (Item_cache**)thd->alloc(sizeof(Item_cache*)*argcount)))
- DBUG_RETURN(TRUE);
-
- // QQ Should have some error checking here? (types, etc...)
+ /*
+ Prepare arena and memroot for objects which lifetime is whole
+ duration of function call (sp_rcontext, it's tables and items,
+ sp_cursor and Item_cache holders for case expressions).
+ We can't use caller's arena/memroot for those objects because
+ in this case some fixed amount of memory will be consumed for
+ each function/trigger invocation and so statements which involve
+ lot of them will hog memory.
+ TODO: we should create sp_rcontext once per command and reuse
+ it on subsequent executions of a function/trigger.
+ */
+ init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
+ thd->set_n_backup_active_arena(&call_arena, &backup_arena);
if (!(nctx= new sp_rcontext(m_pcont, return_value_fld, octx)) ||
nctx->init(thd))
{
- delete nctx; /* Delete nctx if it was init() that failed. */
- DBUG_RETURN(TRUE);
+ thd->restore_active_arena(&call_arena, &backup_arena);
+ err_status= TRUE;
+ goto err_with_cleanup;
}
+ /*
+ We have to switch temporarily back to callers arena/memroot.
+ Function arguments belong to the caller and so the may reference
+ memory which they will allocate during calculation long after
+ this function call will be finished (e.g. in Item::cleanup()).
+ */
+ thd->restore_active_arena(&call_arena, &backup_arena);
+
#ifndef DBUG_OFF
nctx->sp= this;
#endif
/* Pass arguments. */
+ for (arg_no= 0; arg_no < argcount; arg_no++)
+ {
+ /* Arguments must be fixed in Item_func_sp::fix_fields */
+ DBUG_ASSERT(argp[arg_no]->fixed);
+
+ if ((err_status= nctx->set_variable(thd, arg_no, &(argp[arg_no]))))
+ goto err_with_cleanup;
+ }
+
+ need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
+ /*
+ Remember the original arguments for unrolled replication of functions
+ before they are changed by execution.
+ */
+ if (need_binlog_call)
{
- uint i;
-
- for (i= 0 ; i < argcount ; i++)
+ binlog_buf.length(0);
+ binlog_buf.append(STRING_WITH_LEN("SELECT "));
+ append_identifier(thd, &binlog_buf, m_name.str, m_name.length);
+ binlog_buf.append('(');
+ for (arg_no= 0; arg_no < argcount; arg_no++)
{
- if (!argp[i]->fixed && argp[i]->fix_fields(thd, &argp[i]))
- {
- err_status= TRUE;
- break;
- }
+ String str_value_holder;
+ String *str_value;
- param_values[i]= Item_cache::get_cache(argp[i]->result_type());
- param_values[i]->store(argp[i]);
+ if (arg_no)
+ binlog_buf.append(',');
- if (nctx->set_variable(thd, i, param_values[i]))
- {
- err_status= TRUE;
- break;
- }
- }
- }
+ str_value= sp_get_item_value(nctx->get_item(arg_no),
+ &str_value_holder);
- if (err_status)
- {
- delete nctx;
- DBUG_RETURN(TRUE);
+ if (str_value)
+ binlog_buf.append(*str_value);
+ else
+ binlog_buf.append(STRING_WITH_LEN("NULL"));
+ }
+ binlog_buf.append(')');
}
-
thd->spcont= nctx;
binlog_save_options= thd->options;
- need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
if (need_binlog_call)
{
reset_dynamic(&thd->user_var_events);
mysql_bin_log.start_union_events(thd);
}
-
+
+ /*
+ Switch to call arena/mem_root so objects like sp_cursor or
+ Item_cache holders for case expressions can be allocated on it.
+
+ TODO: In future we should associate call arena/mem_root with
+ sp_rcontext and allocate all these objects (and sp_rcontext
+ itself) on it directly rather than juggle with arenas.
+ */
+ thd->set_n_backup_active_arena(&call_arena, &backup_arena);
+
thd->options&= ~OPTION_BIN_LOG;
err_status= execute(thd);
thd->options= binlog_save_options;
-
+
+ thd->restore_active_arena(&call_arena, &backup_arena);
+
if (need_binlog_call)
mysql_bin_log.stop_union_events(thd);
if (need_binlog_call && thd->binlog_evt_union.unioned_events)
{
- char buf[256];
- String bufstr(buf, sizeof(buf), &my_charset_bin);
- bufstr.length(0);
- bufstr.append(STRING_WITH_LEN("SELECT "));
- append_identifier(thd, &bufstr, m_name.str, m_name.length);
- bufstr.append('(');
- for (uint i=0; i < argcount; i++)
- {
- String str_value_holder;
- String *str_value;
-
- if (i)
- bufstr.append(',');
-
- str_value= sp_get_item_value(param_values[i], &str_value_holder);
-
- if (str_value)
- bufstr.append(*str_value);
- else
- bufstr.append(STRING_WITH_LEN("NULL"));
- }
- bufstr.append(')');
-
- Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
+ Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(),
thd->binlog_evt_union.unioned_events_trans, FALSE);
- if (mysql_bin_log.write(&qinfo) &&
+ if (mysql_bin_log.write(&qinfo) &&
thd->binlog_evt_union.unioned_events_trans)
{
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
@@ -1348,27 +1370,19 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
}
}
+
nctx->pop_all_cursors(); // To avoid memory leaks after an error
+
+err_with_cleanup:
delete nctx;
+ call_arena.free_items();
+ free_root(&call_mem_root, MYF(0));
thd->spcont= octx;
DBUG_RETURN(err_status);
}
-static Item_func_get_user_var *item_is_user_var(Item *it)
-{
- if (it->type() == Item::FUNC_ITEM)
- {
- Item_func *fi= static_cast<Item_func*>(it);
-
- if (fi->functype() == Item_func::GUSERVAR_FUNC)
- return static_cast<Item_func_get_user_var*>(fi);
- }
- return NULL;
-}
-
-
/*
Execute a procedure.
SYNOPSIS
@@ -1444,22 +1458,28 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
for (uint i= 0 ; i < params ; i++)
{
Item *arg_item= it_args++;
- sp_variable_t *spvar= m_pcont->find_variable(i);
if (!arg_item)
break;
+ sp_variable_t *spvar= m_pcont->find_variable(i);
+
if (!spvar)
continue;
if (spvar->mode != sp_param_in)
{
- if (!arg_item->is_splocal() && !item_is_user_var(arg_item))
+ Settable_routine_parameter *srp=
+ arg_item->get_settable_routine_parameter();
+
+ if (!srp)
{
my_error(ER_SP_NOT_VAR_ARG, MYF(0), i+1, m_qname.str);
err_status= TRUE;
break;
}
+
+ srp->set_required_privilege(spvar->mode == sp_param_inout);
}
if (spvar->mode == sp_param_out)
@@ -1467,7 +1487,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
Item_null *null_item= new Item_null();
if (!null_item ||
- nctx->set_variable(thd, i, null_item))
+ nctx->set_variable(thd, i, (struct Item **)&null_item))
{
err_status= TRUE;
break;
@@ -1475,7 +1495,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
}
else
{
- if (nctx->set_variable(thd, i, *it_args.ref()))
+ if (nctx->set_variable(thd, i, it_args.ref()))
{
err_status= TRUE;
break;
@@ -1527,36 +1547,16 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (spvar->mode == sp_param_in)
continue;
- if (arg_item->is_splocal())
- {
- if (octx->set_variable(thd,
- ((Item_splocal*) arg_item)->get_var_idx(),
- nctx->get_item(i)))
- {
- err_status= TRUE;
- break;
- }
- }
- else
+ Settable_routine_parameter *srp=
+ arg_item->get_settable_routine_parameter();
+
+ DBUG_ASSERT(srp);
+
+ if (srp->set_value(thd, octx, nctx->get_item_addr(i)))
{
- Item_func_get_user_var *guv= item_is_user_var(arg_item);
-
- if (guv)
- {
- Item *item= nctx->get_item(i);
- Item_func_set_user_var *suv;
-
- suv= new Item_func_set_user_var(guv->get_name(), item);
- /*
- Item_func_set_user_var is not fixed after construction,
- call fix_fields().
- */
- if ((err_status= test(!suv || suv->fix_fields(thd, &item) ||
- suv->check() || suv->update())))
- break;
- }
+ err_status= TRUE;
+ break;
}
-
}
}
@@ -2328,7 +2328,7 @@ sp_instr_set::execute(THD *thd, uint *nextp)
int
sp_instr_set::exec_core(THD *thd, uint *nextp)
{
- int res= thd->spcont->set_variable(thd, m_offset, m_value);
+ int res= thd->spcont->set_variable(thd, m_offset, &m_value);
if (res && thd->spcont->found_handler_here())
{
@@ -2393,12 +2393,7 @@ sp_instr_set_trigger_field::execute(THD *thd, uint *nextp)
int
sp_instr_set_trigger_field::exec_core(THD *thd, uint *nextp)
{
- int res= 0;
- Item *it= sp_prepare_func_item(thd, &value);
- if (!it ||
- !trigger_field->fixed && trigger_field->fix_fields(thd, 0) ||
- (it->save_in_field(trigger_field->field, 0) < 0))
- res= -1;
+ const int res= (trigger_field->set_value(thd, &value) ? -1 : 0);
*nextp = m_ip+1;
return res;
}
@@ -2603,7 +2598,7 @@ sp_instr_freturn::exec_core(THD *thd, uint *nextp)
do it in scope of execution the current context/block.
*/
- return thd->spcont->set_return_value(thd, m_value);
+ return thd->spcont->set_return_value(thd, &m_value);
}
void
@@ -3047,7 +3042,7 @@ sp_instr_set_case_expr::execute(THD *thd, uint *nextp)
int
sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
{
- int res= thd->spcont->set_case_expr(thd, m_case_expr_id, m_case_expr);
+ int res= thd->spcont->set_case_expr(thd, m_case_expr_id, &m_case_expr);
if (res &&
!thd->spcont->get_case_expr(m_case_expr_id) &&
@@ -3061,7 +3056,7 @@ sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
Item *null_item= new Item_null();
if (!null_item ||
- thd->spcont->set_case_expr(thd, m_case_expr_id, null_item))
+ thd->spcont->set_case_expr(thd, m_case_expr_id, &null_item))
{
/* If this also failed, we have to abort. */
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 6a9cf97d739..d5f49d8a964 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -1169,6 +1169,6 @@ Item *
sp_prepare_func_item(THD* thd, Item **it_addr);
bool
-sp_eval_expr(THD *thd, Field *result_field, Item *expr_item);
+sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr);
#endif /* _SP_HEAD_H_ */
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 38b6de0e75a..3bc27a029d0 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -150,7 +150,7 @@ sp_rcontext::init_var_items()
bool
-sp_rcontext::set_return_value(THD *thd, Item *return_value_item)
+sp_rcontext::set_return_value(THD *thd, Item **return_value_item)
{
DBUG_ASSERT(m_return_value_fld);
@@ -279,14 +279,14 @@ sp_rcontext::pop_cursors(uint count)
int
-sp_rcontext::set_variable(THD *thd, uint var_idx, Item *value)
+sp_rcontext::set_variable(THD *thd, uint var_idx, Item **value)
{
return set_variable(thd, m_var_table->field[var_idx], value);
}
int
-sp_rcontext::set_variable(THD *thd, Field *field, Item *value)
+sp_rcontext::set_variable(THD *thd, Field *field, Item **value)
{
if (!value)
{
@@ -478,9 +478,10 @@ sp_rcontext::create_case_expr_holder(THD *thd, Item_result result_type)
*/
int
-sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item *case_expr_item)
+sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr)
{
- if (!(case_expr_item= sp_prepare_func_item(thd, &case_expr_item)))
+ Item *case_expr_item= sp_prepare_func_item(thd, case_expr_item_ptr);
+ if (!case_expr_item)
return TRUE;
if (!m_case_expr_holders[case_expr_id] ||
@@ -542,7 +543,7 @@ bool Select_fetch_into_spvars::send_data(List<Item> &items)
*/
for (; spvar= spvar_iter++, item= item_iter++; )
{
- if (thd->spcont->set_variable(thd, spvar->offset, item))
+ if (thd->spcont->set_variable(thd, spvar->offset, &item))
return TRUE;
}
return FALSE;
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index 20aaea3b7c1..30521f6da84 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -91,7 +91,7 @@ class sp_rcontext : public Sql_alloc
~sp_rcontext();
int
- set_variable(THD *thd, uint var_idx, Item *value);
+ set_variable(THD *thd, uint var_idx, Item **value);
Item *
get_item(uint var_idx);
@@ -100,7 +100,7 @@ class sp_rcontext : public Sql_alloc
get_item_addr(uint var_idx);
bool
- set_return_value(THD *thd, Item *return_value_item);
+ set_return_value(THD *thd, Item **return_value_item);
inline bool
is_return_value_set() const
@@ -200,7 +200,7 @@ class sp_rcontext : public Sql_alloc
*/
int
- set_case_expr(THD *thd, int case_expr_id, Item *case_expr_item);
+ set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr);
Item *
get_case_expr(int case_expr_id);
@@ -254,7 +254,7 @@ private:
Item_cache *create_case_expr_holder(THD *thd, Item_result result_type);
- int set_variable(THD *thd, Field *field, Item *value);
+ int set_variable(THD *thd, Field *field, Item **value);
}; // class sp_rcontext : public Sql_alloc
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index ec1caba0b5d..02b2f88676f 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -858,8 +858,8 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
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'",
+ 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))
{
@@ -6023,20 +6023,21 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
}
/* table privileges */
+ rw_rdlock(&LOCK_grant);
if (grant->version != grant_version)
{
- rw_rdlock(&LOCK_grant);
grant->grant_table=
table_hash_search(sctx->host, sctx->ip, db,
sctx->priv_user,
table, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
- rw_unlock(&LOCK_grant);
}
if (grant->grant_table != 0)
{
grant->privilege|= grant->grant_table->privs;
}
+ rw_unlock(&LOCK_grant);
+
DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege));
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 482a25acbd2..1f3b9e14631 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -617,118 +617,110 @@ static inline uint tmpkeyval(THD *thd, TABLE *table)
void close_temporary_tables(THD *thd)
{
- TABLE *next,
- *prev_table /* prev link is not maintained in TABLE's double-linked list */,
- *table;
- char *query= (gptr) 0, *end;
- uint query_buf_size, max_names_len;
- bool found_user_tables;
-
+ TABLE *table;
if (!thd->temporary_tables)
return;
-
- LINT_INIT(end);
- query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS
- /*
- insertion sort of temp tables by pseudo_thread_id to build ordered list
+ if (!mysql_bin_log.is_open())
+ {
+ for (table= thd->temporary_tables; table; table= table->next)
+ {
+ close_temporary(table, 1);
+ }
+ thd->temporary_tables= 0;
+ return;
+ }
+
+ TABLE *next,
+ *prev_table /* prev link is not maintained in TABLE's double-linked list */;
+ bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */
+ // Better add "if exists", in case a RESET MASTER has been done
+ const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
+ uint stub_len= sizeof(stub) - 1;
+ char buf[256];
+ memcpy(buf, stub, stub_len);
+ String s_query= String(buf, sizeof(buf), system_charset_info);
+ bool found_user_tables= false;
+ LINT_INIT(next);
+
+ /*
+ insertion sort of temp tables by pseudo_thread_id to build ordered list
of sublists of equal pseudo_thread_id
*/
- for (prev_table= thd->temporary_tables,
- table= prev_table->next,
- found_user_tables= (prev_table->s->table_name[0] != '#');
+
+ for (prev_table= thd->temporary_tables, table= prev_table->next;
table;
prev_table= table, table= table->next)
{
- TABLE *prev_sorted /* same as for prev_table */,
- *sorted;
- /*
- table not created directly by the user is moved to the tail.
- Fixme/todo: nothing (I checked the manual) prevents user to create temp
- with `#'
- */
- if (table->s->table_name[0] == '#')
- continue;
- else
- {
- found_user_tables = 1;
- }
- for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
- prev_sorted= sorted, sorted= sorted->next)
+ TABLE *prev_sorted /* same as for prev_table */, *sorted;
+ if (is_user_table(table))
{
- if (sorted->s->table_name[0] == '#' || tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
+ if (!found_user_tables)
+ found_user_tables= true;
+ for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
+ prev_sorted= sorted, sorted= sorted->next)
{
- /* move into the sorted part of the list from the unsorted */
- prev_table->next= table->next;
- table->next= sorted;
- if (prev_sorted)
+ if (!is_user_table(sorted) ||
+ tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
{
- prev_sorted->next= table;
- }
- else
- {
- thd->temporary_tables= table;
+ /* move into the sorted part of the list from the unsorted */
+ prev_table->next= table->next;
+ table->next= sorted;
+ if (prev_sorted)
+ {
+ prev_sorted->next= table;
+ }
+ else
+ {
+ thd->temporary_tables= table;
+ }
+ table= prev_table;
+ break;
}
- table= prev_table;
- break;
}
}
- }
- /*
- calc query_buf_size as max per sublists, one sublist per pseudo thread id.
- Also stop at first occurence of `#'-named table that starts
- all implicitly created temp tables
- */
- for (max_names_len= 0, table=thd->temporary_tables;
- table && table->s->table_name[0] != '#';
- table=table->next)
+ }
+
+ /* We always quote db,table names though it is slight overkill */
+ if (found_user_tables &&
+ !(was_quote_show= (thd->options & OPTION_QUOTE_SHOW_CREATE)))
{
- uint tmp_names_len;
- for (tmp_names_len= table->s->key_length + 1;
- table->next && table->s->table_name[0] != '#' &&
- tmpkeyval(thd, table) == tmpkeyval(thd, table->next);
- table=table->next)
- {
- /*
- We are going to add 4 ` around the db/table names, so 1 might not look
- enough; indeed it is enough, because table->key_length is greater (by 8,
- because of server_id and thread_id) than db||table.
- */
- tmp_names_len += table->next->s->key_length + 1;
- }
- if (tmp_names_len > max_names_len) max_names_len= tmp_names_len;
+ thd->options |= OPTION_QUOTE_SHOW_CREATE;
}
-
- /* allocate */
- if (found_user_tables && mysql_bin_log.is_open() &&
- (query = alloc_root(thd->mem_root, query_buf_size+= max_names_len)))
- // Better add "if exists", in case a RESET MASTER has been done
- end= strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
/* scan sorted tmps to generate sequence of DROP */
- for (table=thd->temporary_tables; table; table= next)
+ for (table= thd->temporary_tables; table; table= next)
{
- if (query // we might be out of memory, but this is not fatal
- && table->s->table_name[0] != '#')
+ if (is_user_table(table))
{
- char *end_cur;
/* Set pseudo_thread_id to be that of the processed table */
thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
/* Loop forward through all tables within the sublist of
common pseudo_thread_id to create single DROP query */
- for (end_cur= end;
- table && table->s->table_name[0] != '#' &&
+ for (s_query.length(stub_len);
+ table && is_user_table(table) &&
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
table= next)
{
- end_cur= strxmov(end_cur, "`", table->s->db, "`.`",
- table->s->table_name, "`,", NullS);
+ /*
+ We are going to add 4 ` around the db/table names and possible more
+ due to special characters in the names
+ */
+ append_identifier(thd, &s_query, table->s->db, strlen(table->s->db));
+ s_query.q_append('.');
+ append_identifier(thd, &s_query, table->s->table_name,
+ strlen(table->s->table_name));
+ s_query.q_append(',');
next= table->next;
close_temporary(table, 1);
}
thd->clear_error();
- /* The -1 is to remove last ',' */
- Query_log_event qinfo(thd, query, (ulong)(end_cur - query) - 1, 0, FALSE);
+ CHARSET_INFO *cs_save= thd->variables.character_set_client;
+ thd->variables.character_set_client= system_charset_info;
+ Query_log_event qinfo(thd, s_query.ptr(),
+ s_query.length() - 1 /* to remove trailing ',' */,
+ 0, FALSE);
+ thd->variables.character_set_client= cs_save;
/*
Imagine the thread had created a temp table, then was doing a SELECT, and
the SELECT was killed. Then it's not clever to mark the statement above as
@@ -741,12 +733,14 @@ void close_temporary_tables(THD *thd)
qinfo.error_code= 0;
mysql_bin_log.write(&qinfo);
}
- else
+ else
{
next= table->next;
close_temporary(table, 1);
}
}
+ if (!was_quote_show)
+ thd->options &= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
thd->temporary_tables=0;
}
@@ -1160,6 +1154,8 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
MYSQL_LOCK_IGNORE_FLUSH - Open table even if
someone has done a flush or namelock on it.
No version number checking is done.
+ MYSQL_OPEN_IGNORE_LOCKED_TABLES - Open table
+ ignoring set of locked tables and prelocked mode.
IMPLEMENTATION
Uses a cache of open tables to find a table not in use.
@@ -1219,7 +1215,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
}
}
- if (thd->locked_tables || thd->prelocked_mode)
+ if (!(flags & MYSQL_OPEN_IGNORE_LOCKED_TABLES) &&
+ (thd->locked_tables || thd->prelocked_mode))
{ // Using table locks
TABLE *best_table= 0;
int best_distance= INT_MIN;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 026c3e0d515..65fd4d3ac19 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1877,7 +1877,7 @@ bool select_dumpvar::send_data(List<Item> &items)
if ((yy=var_li++))
{
if (thd->spcont->set_variable(current_thd, yy->get_var_idx(),
- *it.ref()))
+ it.ref()))
DBUG_RETURN(1);
}
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 320b8e1df9d..c054499ecd8 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2437,6 +2437,153 @@ bool select_insert::send_eof()
CREATE TABLE (SELECT) ...
***************************************************************************/
+/*
+ Create table from lists of fields and items (or open existing table
+ with same name).
+
+ SYNOPSIS
+ create_table_from_items()
+ thd in Thread object
+ create_info in Create information (like MAX_ROWS, ENGINE or
+ temporary table flag)
+ create_table in Pointer to TABLE_LIST object providing database
+ and name for table to be created or to be open
+ extra_fields in/out Initial list of fields for table to be created
+ keys in List of keys for table to be created
+ items in List of items which should be used to produce rest
+ of fields for the table (corresponding fields will
+ be added to the end of 'extra_fields' list)
+ lock out Pointer to the MYSQL_LOCK object for table created
+ (open) will be returned in this parameter. Since
+ this table is not included in THD::lock caller is
+ responsible for explicitly unlocking this table.
+
+ NOTES
+ If 'create_info->options' bitmask has HA_LEX_CREATE_IF_NOT_EXISTS
+ flag and table with name provided already exists then this function will
+ simply open existing table.
+ Also note that create, open and lock sequence in this function is not
+ atomic and thus contains gap for deadlock and can cause other troubles.
+ Since this function contains some logic specific to CREATE TABLE ... SELECT
+ it should be changed before it can be used in other contexts.
+
+ RETURN VALUES
+ non-zero Pointer to TABLE object for table created or opened
+ 0 Error
+*/
+
+static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
+ TABLE_LIST *create_table,
+ List<create_field> *extra_fields,
+ List<Key> *keys, List<Item> *items,
+ MYSQL_LOCK **lock)
+{
+ TABLE tmp_table; // Used during 'create_field()'
+ TABLE *table= 0;
+ uint select_field_count= items->elements;
+ /* Add selected items to field list */
+ List_iterator_fast<Item> it(*items);
+ Item *item;
+ Field *tmp_field;
+ bool not_used;
+ DBUG_ENTER("create_table_from_items");
+
+ tmp_table.alias= 0;
+ tmp_table.timestamp_field= 0;
+ tmp_table.s= &tmp_table.share_not_to_be_used;
+ tmp_table.s->db_create_options=0;
+ tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
+ tmp_table.s->db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM ||
+ create_info->db_type == DB_TYPE_HEAP);
+ tmp_table.null_row=tmp_table.maybe_null=0;
+
+ while ((item=it++))
+ {
+ create_field *cr_field;
+ Field *field;
+ if (item->type() == Item::FUNC_ITEM)
+ field=item->tmp_table_field(&tmp_table);
+ else
+ field=create_tmp_field(thd, &tmp_table, item, item->type(),
+ (Item ***) 0, &tmp_field, 0, 0, 0, 0, 0);
+ if (!field ||
+ !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
+ ((Item_field *)item)->field :
+ (Field*) 0))))
+ DBUG_RETURN(0);
+ if (item->maybe_null)
+ cr_field->flags &= ~NOT_NULL_FLAG;
+ extra_fields->push_back(cr_field);
+ }
+ /*
+ create and lock table
+
+ We don't log the statement, it will be logged later.
+
+ If this is a HEAP table, the automatic DELETE FROM which is written to the
+ binlog when a HEAP table is opened for the first time since startup, must
+ not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
+ don't want to delete from it) 2) it would be written before the CREATE
+ TABLE, which is a wrong order. So we keep binary logging disabled when we
+ open_table().
+ NOTE: By locking table which we just have created (or for which we just have
+ have found that it already exists) separately from other tables used by the
+ statement we create potential window for deadlock.
+ TODO: create and open should be done atomic !
+ */
+ {
+ tmp_disable_binlog(thd);
+ if (!mysql_create_table(thd, create_table->db, create_table->table_name,
+ create_info, *extra_fields, *keys, 0,
+ select_field_count))
+ {
+ /*
+ If we are here in prelocked mode we either create temporary table
+ or prelocked mode is caused by the SELECT part of this statement.
+ */
+ DBUG_ASSERT(!thd->prelocked_mode ||
+ create_info->options & HA_LEX_CREATE_TMP_TABLE ||
+ thd->lex->requires_prelocking());
+
+ /*
+ NOTE: We don't want to ignore set of locked tables here if we are
+ under explicit LOCK TABLES since it will open gap for deadlock
+ too wide (and also is not backward compatible).
+ */
+ if (! (table= open_table(thd, create_table, thd->mem_root, (bool*) 0,
+ (MYSQL_LOCK_IGNORE_FLUSH |
+ ((thd->prelocked_mode == PRELOCKED) ?
+ MYSQL_OPEN_IGNORE_LOCKED_TABLES:0)))))
+ quick_rm_table(create_info->db_type, create_table->db,
+ table_case_name(create_info, create_table->table_name));
+ }
+ reenable_binlog(thd);
+ if (!table) // open failed
+ DBUG_RETURN(0);
+ }
+
+ /*
+ FIXME: What happens if trigger manages to be created while we are
+ obtaining this lock ? May be it is sensible just to disable
+ trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH
+ save us from that ?
+ */
+ table->reginfo.lock_type=TL_WRITE;
+ if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
+ MYSQL_LOCK_IGNORE_FLUSH, &not_used)))
+ {
+ VOID(pthread_mutex_lock(&LOCK_open));
+ hash_delete(&open_cache,(byte*) table);
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ quick_rm_table(create_info->db_type, create_table->db,
+ table_case_name(create_info, create_table->table_name));
+ DBUG_RETURN(0);
+ }
+ table->file->extra(HA_EXTRA_WRITE_CACHE);
+ DBUG_RETURN(table);
+}
+
+
int
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index a8de7ff0154..7d62e5bb405 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5709,6 +5709,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
}
else
{
+ DBUG_ASSERT(thd->net.report_error);
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
thd->is_fatal_error));
query_cache_abort(&thd->net);
@@ -7226,7 +7227,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
lex->create_info.merge_list.first))
goto err;
if (grant_option && want_priv != CREATE_TMP_ACL &&
- check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0))
+ check_grant(thd, want_priv, create_table, 0, 1, 0))
goto err;
if (select_lex->item_list.elements)
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 465f41fa8de..d36ceedc7ae 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3335,7 +3335,10 @@ best_access_path(JOIN *join,
uint key= keyuse->key;
KEY *keyinfo= table->key_info+key;
bool ft_key= (keyuse->keypart == FT_KEYPART);
- uint found_ref_or_null= 0;
+ /* Bitmap of keyparts where the ref access is over 'keypart=const': */
+ key_part_map const_part= 0;
+ /* The or-null keypart in ref-or-null access: */
+ key_part_map ref_or_null_part= 0;
/* Calculate how many key segments of the current key we can use */
start_key= keyuse;
@@ -3347,12 +3350,14 @@ best_access_path(JOIN *join,
do
{
if (!(remaining_tables & keyuse->used_tables) &&
- !(found_ref_or_null & keyuse->optimize))
+ !(ref_or_null_part && (keyuse->optimize &
+ KEY_OPTIMIZE_REF_OR_NULL)))
{
found_part|= keyuse->keypart_map;
- double tmp= prev_record_reads(join,
- (found_ref |
- keyuse->used_tables));
+ if (!(keyuse->used_tables & ~join->const_table_map))
+ const_part|= keyuse->keypart_map;
+ double tmp= prev_record_reads(join, (found_ref |
+ keyuse->used_tables));
if (tmp < best_prev_record_reads)
{
best_part_found_ref= keyuse->used_tables;
@@ -3364,8 +3369,8 @@ best_access_path(JOIN *join,
If there is one 'key_column IS NULL' expression, we can
use this ref_or_null optimisation of this field
*/
- found_ref_or_null|= (keyuse->optimize &
- KEY_OPTIMIZE_REF_OR_NULL);
+ if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
+ ref_or_null_part |= keyuse->keypart_map;
}
keyuse++;
} while (keyuse->table == table && keyuse->key == key &&
@@ -3401,7 +3406,7 @@ best_access_path(JOIN *join,
Check if we found full key
*/
if (found_part == PREV_BITS(uint,keyinfo->key_parts) &&
- !found_ref_or_null)
+ !ref_or_null_part)
{ /* use eq key */
max_key_part= (uint) ~0;
if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
@@ -3413,6 +3418,23 @@ best_access_path(JOIN *join,
{
if (!found_ref)
{ /* We found a const key */
+ /*
+ ReuseRangeEstimateForRef-1:
+ We get here if we've found a ref(const) (c_i are constants):
+ "(keypart1=c1) AND ... AND (keypartN=cN)" [ref_const_cond]
+
+ If range optimizer was able to construct a "range"
+ access on this index, then its condition "quick_cond" was
+ eqivalent to ref_const_cond (*), and we can re-use E(#rows)
+ from the range optimizer.
+
+ Proof of (*): By properties of range and ref optimizers
+ quick_cond will be equal or tighther than ref_const_cond.
+ ref_const_cond already covers "smallest" possible interval -
+ a singlepoint interval over all keyparts. Therefore,
+ quick_cond is equivalent to ref_const_cond (if it was an
+ empty interval we wouldn't have got here).
+ */
if (table->quick_keys.is_set(key))
records= (double) table->quick_rows[key];
else
@@ -3433,6 +3455,23 @@ best_access_path(JOIN *join,
if (records < 2.0)
records=2.0; /* Can't be as good as a unique */
}
+ /*
+ ReuseRangeEstimateForRef-2: We get here if we could not reuse
+ E(#rows) from range optimizer. Make another try:
+
+ If range optimizer produced E(#rows) for a prefix of the ref
+ access we're considering, and that E(#rows) is lower then our
+ current estimate, make an adjustment. The criteria of when we
+ can make an adjustment is a special case of the criteria used
+ in ReuseRangeEstimateForRef-3.
+ */
+ if (table->quick_keys.is_set(key) &&
+ const_part & (1 << table->quick_key_parts[key]) &&
+ table->quick_n_ranges[key] == 1 &&
+ records > (double) table->quick_rows[key])
+ {
+ records= (double) table->quick_rows[key];
+ }
}
/* Limit the number of matched rows */
tmp= records;
@@ -3461,12 +3500,50 @@ best_access_path(JOIN *join,
{
max_key_part= max_part_bit(found_part);
/*
- Check if quick_range could determinate how many rows we
- will match
+ ReuseRangeEstimateForRef-3:
+ We're now considering a ref[or_null] access via
+ (t.keypart1=e1 AND ... AND t.keypartK=eK) [ OR
+ (same-as-above but with one cond replaced
+ with "t.keypart_i IS NULL")] (**)
+
+ Try re-using E(#rows) from "range" optimizer:
+ We can do so if "range" optimizer used the same intervals as
+ in (**). The intervals used by range optimizer may be not
+ available at this point (as "range" access might have choosen to
+ create quick select over another index), so we can't compare
+ them to (**). We'll make indirect judgements instead.
+ The sufficient conditions for re-use are:
+ (C1) All e_i in (**) are constants, i.e. found_ref==FALSE. (if
+ this is not satisfied we have no way to know which ranges
+ will be actually scanned by 'ref' until we execute the
+ join)
+ (C2) max #key parts in 'range' access == K == max_key_part (this
+ is apparently a necessary requirement)
+
+ We also have a property that "range optimizer produces equal or
+ tighter set of scan intervals than ref(const) optimizer". Each
+ of the intervals in (**) are "tightest possible" intervals when
+ one limits itself to using keyparts 1..K (which we do in #2).
+ From here it follows that range access used either one, or
+ both of the (I1) and (I2) intervals:
+
+ (t.keypart1=c1 AND ... AND t.keypartK=eK) (I1)
+ (same-as-above but with one cond replaced
+ with "t.keypart_i IS NULL") (I2)
+
+ The remaining part is to exclude the situation where range
+ optimizer used one interval while we're considering
+ ref-or-null and looking for estimate for two intervals. This
+ is done by last limitation:
+
+ (C3) "range optimizer used (have ref_or_null?2:1) intervals"
*/
- if (table->quick_keys.is_set(key) &&
- table->quick_key_parts[key] == max_key_part)
+ if (table->quick_keys.is_set(key) && !found_ref && //(C1)
+ table->quick_key_parts[key] == max_key_part && //(C2)
+ table->quick_n_ranges[key] == 1+test(ref_or_null_part)) //(C3)
+ {
tmp= records= (double) table->quick_rows[key];
+ }
else
{
/* Check if we have statistic about the distribution */
@@ -3510,21 +3587,37 @@ best_access_path(JOIN *join,
}
records = (ulong) tmp;
}
+
+ if (ref_or_null_part)
+ {
+ /* We need to do two key searches to find key */
+ tmp *= 2.0;
+ records *= 2.0;
+ }
+
/*
- If quick_select was used on a part of this key, we know
- the maximum number of rows that the key can match.
+ ReuseRangeEstimateForRef-4: We get here if we could not reuse
+ E(#rows) from range optimizer. Make another try:
+
+ If range optimizer produced E(#rows) for a prefix of the ref
+ access we're considering, and that E(#rows) is lower then our
+ current estimate, make the adjustment.
+
+ The decision whether we can re-use the estimate from the range
+ optimizer is the same as in ReuseRangeEstimateForRef-3,
+ applied to first table->quick_key_parts[key] key parts.
*/
if (table->quick_keys.is_set(key) &&
table->quick_key_parts[key] <= max_key_part &&
+ const_part & (1 << table->quick_key_parts[key]) &&
+ table->quick_n_ranges[key] == 1 + test(ref_or_null_part &
+ const_part) &&
records > (double) table->quick_rows[key])
- tmp= records= (double) table->quick_rows[key];
- else if (found_ref_or_null)
{
- /* We need to do two key searches to find key */
- tmp *= 2.0;
- records *= 2.0;
+ tmp= records= (double) table->quick_rows[key];
}
}
+
/* Limit the number of matched rows */
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
if (table->used_keys.is_set(key))
@@ -4340,344 +4433,11 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
(!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
{
- double best,best_time,records;
- best=best_time=records=DBL_MAX;
- KEYUSE *best_key=0;
- uint best_max_key_part=0;
- my_bool found_constraint= 0;
-
- if (s->keyuse)
- { /* Use key if possible */
- TABLE *table=s->table;
- KEYUSE *keyuse,*start_key=0;
- double best_records=DBL_MAX;
- uint max_key_part=0;
-
- /* Test how we can use keys */
- rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key
- for (keyuse=s->keyuse ; keyuse->table == table ;)
- {
- key_part_map found_part=0;
- table_map found_ref=0;
- uint key=keyuse->key;
- KEY *keyinfo=table->key_info+key;
- bool ft_key=(keyuse->keypart == FT_KEYPART);
- uint found_ref_or_null= 0;
-
- /* Calculate how many key segments of the current key we can use */
- start_key=keyuse;
- do
- {
- uint keypart=keyuse->keypart;
- table_map best_part_found_ref= 0;
- double best_prev_record_reads= DBL_MAX;
- do
- {
- if (!(rest_tables & keyuse->used_tables) &&
- !(found_ref_or_null & keyuse->optimize))
- {
- found_part|=keyuse->keypart_map;
- double tmp= prev_record_reads(join,
- (found_ref |
- keyuse->used_tables));
- if (tmp < best_prev_record_reads)
- {
- best_part_found_ref= keyuse->used_tables;
- best_prev_record_reads= tmp;
- }
- if (rec > keyuse->ref_table_rows)
- rec= keyuse->ref_table_rows;
- /*
- If there is one 'key_column IS NULL' expression, we can
- use this ref_or_null optimisation of this field
- */
- found_ref_or_null|= (keyuse->optimize &
- KEY_OPTIMIZE_REF_OR_NULL);
- }
- keyuse++;
- } while (keyuse->table == table && keyuse->key == key &&
- keyuse->keypart == keypart);
- found_ref|= best_part_found_ref;
- } while (keyuse->table == table && keyuse->key == key);
-
- /*
- Assume that that each key matches a proportional part of table.
- */
- if (!found_part && !ft_key)
- continue; // Nothing usable found
- if (rec < MATCHING_ROWS_IN_OTHER_TABLE)
- rec= MATCHING_ROWS_IN_OTHER_TABLE; // Fix for small tables
-
- /*
- ft-keys require special treatment
- */
- if (ft_key)
- {
- /*
- Really, there should be records=0.0 (yes!)
- but 1.0 would be probably safer
- */
- tmp=prev_record_reads(join,found_ref);
- records=1.0;
- }
- else
- {
- found_constraint= 1;
- /*
- Check if we found full key
- */
- if (found_part == PREV_BITS(uint,keyinfo->key_parts) &&
- !found_ref_or_null)
- { /* use eq key */
- max_key_part= (uint) ~0;
- if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
- HA_END_SPACE_KEY)) == HA_NOSAME)
- {
- tmp=prev_record_reads(join,found_ref);
- records=1.0;
- }
- else
- {
- if (!found_ref)
- { // We found a const key
- if (table->quick_keys.is_set(key))
- records= (double) table->quick_rows[key];
- else
- {
- /* quick_range couldn't use key! */
- records= (double) s->records/rec;
- }
- }
- else
- {
- if (!(records=keyinfo->rec_per_key[keyinfo->key_parts-1]))
- { // Prefere longer keys
- records=
- ((double) s->records / (double) rec *
- (1.0 +
- ((double) (table->s->max_key_length-keyinfo->key_length) /
- (double) table->s->max_key_length)));
- if (records < 2.0)
- records=2.0; // Can't be as good as a unique
- }
- }
- /* Limit the number of matched rows */
- tmp= records;
- set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
- if (table->used_keys.is_set(key))
- {
- /* we can use only index tree */
- uint keys_per_block= table->file->block_size/2/
- (keyinfo->key_length+table->file->ref_length)+1;
- tmp=record_count*(tmp+keys_per_block-1)/keys_per_block;
- }
- else
- tmp=record_count*min(tmp,s->worst_seeks);
- }
- }
- else
- {
- /*
- Use as much key-parts as possible and a uniq key is better
- than a not unique key
- Set tmp to (previous record count) * (records / combination)
- */
- if ((found_part & 1) &&
- (!(table->file->index_flags(key,0,0) & HA_ONLY_WHOLE_INDEX) ||
- found_part == PREV_BITS(uint,keyinfo->key_parts)))
- {
- max_key_part=max_part_bit(found_part);
- /*
- Check if quick_range could determinate how many rows we
- will match
- */
- if (table->quick_keys.is_set(key) &&
- table->quick_key_parts[key] == max_key_part)
- tmp=records= (double) table->quick_rows[key];
- else
- {
- /* Check if we have statistic about the distribution */
- if ((records=keyinfo->rec_per_key[max_key_part-1]))
- tmp=records;
- else
- {
- /*
- Assume that the first key part matches 1% of the file
- and that the whole key matches 10 (duplicates) or 1
- (unique) records.
- Assume also that more key matches proportionally more
- records
- This gives the formula:
- records= (x * (b-a) + a*c-b)/(c-1)
-
- b = records matched by whole key
- a = records matched by first key part (10% of all records?)
- c = number of key parts in key
- x = used key parts (1 <= x <= c)
- */
- double rec_per_key;
- rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1] ?
- (double) keyinfo->rec_per_key[keyinfo->key_parts-1] :
- (double) s->records/rec+1;
- if (!s->records)
- tmp=0;
- else if (rec_per_key/(double) s->records >= 0.01)
- tmp=rec_per_key;
- else
- {
- double a=s->records*0.01;
- tmp=(max_key_part * (rec_per_key - a) +
- a*keyinfo->key_parts - rec_per_key)/
- (keyinfo->key_parts-1);
- set_if_bigger(tmp,1.0);
- }
- records=(ulong) tmp;
- }
- /*
- If quick_select was used on a part of this key, we know
- the maximum number of rows that the key can match.
- */
- if (table->quick_keys.is_set(key) &&
- table->quick_key_parts[key] <= max_key_part &&
- records > (double) table->quick_rows[key])
- tmp= records= (double) table->quick_rows[key];
- else if (found_ref_or_null)
- {
- /* We need to do two key searches to find key */
- tmp*= 2.0;
- records*= 2.0;
- }
- }
- /* Limit the number of matched rows */
- set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
- if (table->used_keys.is_set(key))
- {
- /* we can use only index tree */
- uint keys_per_block= table->file->block_size/2/
- (keyinfo->key_length+table->file->ref_length)+1;
- tmp=record_count*(tmp+keys_per_block-1)/keys_per_block;
- }
- else
- tmp=record_count*min(tmp,s->worst_seeks);
- }
- else
- tmp=best_time; // Do nothing
- }
- } /* not ft_key */
- if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
- {
- best_time=tmp + records/(double) TIME_FOR_COMPARE;
- best=tmp;
- best_records=records;
- best_key=start_key;
- best_max_key_part=max_key_part;
- }
- }
- records=best_records;
- }
-
- /*
- Don't test table scan if it can't be better.
- Prefer key lookup if we would use the same key for scanning.
-
- Don't do a table scan on InnoDB tables, if we can read the used
- parts of the row from any of the used index.
- This is because table scans uses index and we would not win
- anything by using a table scan.
- (see comment in best_access_path() for more details on the below
- condition)
- */
- if ((records >= s->found_records || best > s->read_time) &&
- !(s->quick && best_key && s->quick->index == best_key->key &&
- best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
- !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
- ! s->table->used_keys.is_clear_all() && best_key) &&
- !(s->table->force_index && best_key && !s->quick))
- { // Check full join
- ha_rows rnd_records= s->found_records;
- /*
- If there is a restriction on the table, assume that 25% of the
- rows can be skipped on next part.
- This is to force tables that this table depends on before this
- table
- */
- if (found_constraint)
- rnd_records-= rnd_records/4;
-
- /*
- Range optimizer never proposes a RANGE if it isn't better
- than FULL: so if RANGE is present, it's always preferred to FULL.
- Here we estimate its cost.
- */
- if (s->quick)
- {
- /*
- For each record we:
- - read record range through 'quick'
- - skip rows which does not satisfy WHERE constraints
- */
- tmp= record_count *
- (s->quick->read_time +
- (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
- }
- else
- {
- /* Estimate cost of reading table. */
- tmp= s->table->file->scan_time();
- if (s->table->map & join->outer_join) // Can't use join cache
- {
- /*
- For each record we have to:
- - read the whole table record
- - skip rows which does not satisfy join condition
- */
- tmp= record_count *
- (tmp +
- (s->records - rnd_records)/(double) TIME_FOR_COMPARE);
- }
- else
- {
- /* We read the table as many times as join buffer becomes full. */
- tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
- record_count /
- (double) thd->variables.join_buff_size));
- /*
- We don't make full cartesian product between rows in the scanned
- table and existing records because we skip all rows from the
- scanned table, which does not satisfy join condition when
- we read the table (see flush_cached_records for details). Here we
- take into account cost to read and skip these records.
- */
- tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
- }
- }
-
- /*
- We estimate the cost of evaluating WHERE clause for found records
- as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
- tmp give us total cost of using TABLE SCAN
- */
- if (best == DBL_MAX ||
- (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records <
- best + record_count/(double) TIME_FOR_COMPARE*records))
- {
- /*
- If the table has a range (s->quick is set) make_join_select()
- will ensure that this will be used
- */
- best=tmp;
- records= rows2double(rnd_records);
- best_key=0;
- }
- }
- join->positions[idx].records_read= records;
- join->positions[idx].key=best_key;
- join->positions[idx].table= s;
- if (!best_key && idx == join->const_tables &&
- s->table == join->sort_by_table &&
- join->unit->select_limit_cnt >= records)
- join->sort_by_table= (TABLE*) 1; // Must use temporary table
-
+ double records, best;
+ best_access_path(join, s, thd, rest_tables, idx, record_count,
+ read_time);
+ records= join->positions[idx].records_read;
+ best= join->positions[idx].read_time;
/*
Go to the next level only if there hasn't been a better key on
this level! This will cut down the search for a lot simple cases!
@@ -12739,6 +12499,17 @@ create_distinct_group(THD *thd, Item **ref_pointer_array,
{
if (!item->const_item() && !item->with_sum_func && !item->marker)
{
+ /*
+ Don't put duplicate columns from the SELECT list into the
+ GROUP BY list.
+ */
+ ORDER *ord_iter;
+ for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
+ if ((*ord_iter->item)->eq(item, 1))
+ break;
+ if (ord_iter)
+ continue;
+
ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
if (!ord)
return 0;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 126abb96f61..70bdef302df 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2662,7 +2662,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables,
field->real_type() == MYSQL_TYPE_STRING) // For binary type
{
uint32 octet_max_length= field->max_length();
- if (octet_max_length != (uint32) 4294967295U)
+ if (is_blob && octet_max_length != (uint32) 4294967295U)
octet_max_length /= field->charset()->mbmaxlen;
longlong char_max_len= is_blob ?
(longlong) octet_max_length / field->charset()->mbminlen :
@@ -2854,17 +2854,18 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
const char *wild, bool full_access, const char *sp_user)
{
String tmp_string;
+ String sp_db, sp_name, definer;
TIME time;
LEX *lex= thd->lex;
CHARSET_INFO *cs= system_charset_info;
- const char *sp_db, *sp_name, *definer;
- sp_db= get_field(thd->mem_root, proc_table->field[0]);
- sp_name= get_field(thd->mem_root, proc_table->field[1]);
- definer= get_field(thd->mem_root, proc_table->field[11]);
+ get_field(thd->mem_root, proc_table->field[0], &sp_db);
+ get_field(thd->mem_root, proc_table->field[1], &sp_name);
+ get_field(thd->mem_root, proc_table->field[11], &definer);
if (!full_access)
- full_access= !strcmp(sp_user, definer);
- if (!full_access && check_some_routine_access(thd, sp_db, sp_name,
- proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE))
+ full_access= !strcmp(sp_user, definer.ptr());
+ if (!full_access && check_some_routine_access(thd, sp_db.ptr(), sp_name.ptr(),
+ proc_table->field[2]->val_int() ==
+ TYPE_ENUM_PROCEDURE))
return 0;
if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
@@ -2874,13 +2875,13 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
lex->orig_sql_command == SQLCOM_END)
{
restore_record(table, s->default_values);
- if (!wild || !wild[0] || !wild_compare(sp_name, wild, 0))
+ if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0))
{
int enum_idx= proc_table->field[5]->val_int();
- table->field[3]->store(sp_name, strlen(sp_name), cs);
+ table->field[3]->store(sp_name.ptr(), sp_name.length(), cs);
get_field(thd->mem_root, proc_table->field[3], &tmp_string);
table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs);
- table->field[2]->store(sp_db, strlen(sp_db), cs);
+ table->field[2]->store(sp_db.ptr(), sp_db.length(), cs);
get_field(thd->mem_root, proc_table->field[2], &tmp_string);
table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs);
if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
@@ -2912,7 +2913,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs);
get_field(thd->mem_root, proc_table->field[15], &tmp_string);
table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
- table->field[19]->store(definer, strlen(definer), cs);
+ table->field[19]->store(definer.ptr(), definer.length(), cs);
return schema_table_store_record(thd, table);
}
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index c9e9ce1bba7..32a86b0f39a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1796,105 +1796,6 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
/****************************************************************************
-** Create table from a list of fields and items
-****************************************************************************/
-
-TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
- TABLE_LIST *create_table,
- List<create_field> *extra_fields,
- List<Key> *keys,
- List<Item> *items,
- MYSQL_LOCK **lock)
-{
- TABLE tmp_table; // Used during 'create_field()'
- TABLE *table= 0;
- uint select_field_count= items->elements;
- /* Add selected items to field list */
- List_iterator_fast<Item> it(*items);
- Item *item;
- Field *tmp_field;
- bool not_used;
- DBUG_ENTER("create_table_from_items");
-
- tmp_table.alias= 0;
- tmp_table.timestamp_field= 0;
- tmp_table.s= &tmp_table.share_not_to_be_used;
- tmp_table.s->db_create_options=0;
- tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
- tmp_table.s->db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM ||
- create_info->db_type == DB_TYPE_HEAP);
- tmp_table.null_row=tmp_table.maybe_null=0;
-
- while ((item=it++))
- {
- create_field *cr_field;
- Field *field;
- if (item->type() == Item::FUNC_ITEM)
- field=item->tmp_table_field(&tmp_table);
- else
- field=create_tmp_field(thd, &tmp_table, item, item->type(),
- (Item ***) 0, &tmp_field, 0, 0, 0, 0, 0);
- if (!field ||
- !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
- ((Item_field *)item)->field :
- (Field*) 0))))
- DBUG_RETURN(0);
- if (item->maybe_null)
- cr_field->flags &= ~NOT_NULL_FLAG;
- extra_fields->push_back(cr_field);
- }
- /*
- create and lock table
-
- We don't log the statement, it will be logged later.
-
- If this is a HEAP table, the automatic DELETE FROM which is written to the
- binlog when a HEAP table is opened for the first time since startup, must
- not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
- don't want to delete from it) 2) it would be written before the CREATE
- TABLE, which is a wrong order. So we keep binary logging disabled when we
- open_table().
- TODO: create and open should be done atomic !
- */
- {
- tmp_disable_binlog(thd);
- if (!mysql_create_table(thd, create_table->db, create_table->table_name,
- create_info, *extra_fields, *keys, 0,
- select_field_count))
- {
- if (! (table= open_table(thd, create_table, thd->mem_root, (bool*) 0,
- MYSQL_LOCK_IGNORE_FLUSH)))
- quick_rm_table(create_info->db_type, create_table->db,
- table_case_name(create_info, create_table->table_name));
- }
- reenable_binlog(thd);
- if (!table) // open failed
- DBUG_RETURN(0);
- }
-
- /*
- FIXME: What happens if trigger manages to be created while we are
- obtaining this lock ? May be it is sensible just to disable
- trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH
- save us from that ?
- */
- table->reginfo.lock_type=TL_WRITE;
- if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
- MYSQL_LOCK_IGNORE_FLUSH, &not_used)))
- {
- VOID(pthread_mutex_lock(&LOCK_open));
- hash_delete(&open_cache,(byte*) table);
- VOID(pthread_mutex_unlock(&LOCK_open));
- quick_rm_table(create_info->db_type, create_table->db,
- table_case_name(create_info, create_table->table_name));
- DBUG_RETURN(0);
- }
- table->file->extra(HA_EXTRA_WRITE_CACHE);
- DBUG_RETURN(table);
-}
-
-
-/****************************************************************************
** Alter a table definition
****************************************************************************/
@@ -3324,7 +3225,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type));
if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
- ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
+ ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED) ||
+ (old_db_type != new_db_type &&
+ ha_check_storage_engine_flag(new_db_type, HTON_ALTER_CANNOT_CREATE)))
{
DBUG_PRINT("info", ("doesn't support alter"));
my_error(ER_ILLEGAL_HA, MYF(0), table_name);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6473163a6ec..b2dbc517fa4 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -448,6 +448,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token NUMERIC_SYM
%token NVARCHAR_SYM
%token OFFSET_SYM
+%token OJ_SYM
%token OLD_PASSWORD
%token ON
%token ONE_SHOT_SYM
@@ -5246,11 +5247,14 @@ table_factor:
}
expr '}'
{
+ LEX *lex= Lex;
YYERROR_UNLESS($3 && $7);
add_join_on($7,$10);
Lex->pop_context();
$7->outer_join|=JOIN_TYPE_LEFT;
$$=$7;
+ if (!($$= lex->current_select->nest_last_join(lex->thd)))
+ YYABORT;
}
| select_derived_init get_select_lex select_derived2
{
@@ -5795,7 +5799,11 @@ select_var_ident:
if (lex->result)
((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0,(enum_field_types)0));
else
- YYABORT;
+ /*
+ The parser won't create select_result instance only
+ if it's an EXPLAIN.
+ */
+ DBUG_ASSERT(lex->describe);
}
| ident_or_text
{
@@ -5807,10 +5815,8 @@ select_var_ident:
my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
YYABORT;
}
- if (! lex->result)
- YYABORT;
- else
- {
+ if (lex->result)
+ {
my_var *var;
((select_dumpvar *)lex->result)->
var_list.push_back(var= new my_var($1,1,t->offset,t->type));
@@ -5818,6 +5824,14 @@ select_var_ident:
if (var)
var->sp= lex->sphead;
#endif
+ }
+ else
+ {
+ /*
+ The parser won't create select_result instance only
+ if it's an EXPLAIN.
+ */
+ DBUG_ASSERT(lex->describe);
}
}
;
@@ -7206,12 +7220,18 @@ simple_ident_q:
YYABORT;
}
+ DBUG_ASSERT(!new_row ||
+ (lex->trg_chistics.event == TRG_EVENT_INSERT ||
+ lex->trg_chistics.event == TRG_EVENT_UPDATE));
+ const bool read_only=
+ !(new_row && lex->trg_chistics.action_time == TRG_ACTION_BEFORE);
if (!(trg_fld= new Item_trigger_field(Lex->current_context(),
new_row ?
Item_trigger_field::NEW_ROW:
Item_trigger_field::OLD_ROW,
$3.str,
- Item_trigger_field::AT_READ)))
+ SELECT_ACL,
+ read_only)))
YYABORT;
/*
@@ -7847,11 +7867,13 @@ sys_option_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));
if (!(trg_fld= new Item_trigger_field(Lex->current_context(),
Item_trigger_field::NEW_ROW,
$2.base_name.str,
- Item_trigger_field::AT_UPDATE)
- ) ||
+ UPDATE_ACL, FALSE)) ||
!(sp_fld= new sp_instr_set_trigger_field(lex->sphead->
instructions(),
lex->spcont,
diff --git a/sql/table.h b/sql/table.h
index ce44f797280..106421d7a17 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -221,6 +221,7 @@ struct st_table {
ha_rows quick_rows[MAX_KEY];
key_part_map const_key_parts[MAX_KEY];
uint quick_key_parts[MAX_KEY];
+ uint quick_n_ranges[MAX_KEY];
/*
If this table has TIMESTAMP field with auto-set property (pointed by
diff --git a/sql/udf_example.cc b/sql/udf_example.cc
index f4f936f34ef..6ad066eacc2 100644
--- a/sql/udf_example.cc
+++ b/sql/udf_example.cc
@@ -344,7 +344,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
KSflag = 0; /* state flag for KS translation */
for (metaph_end = result + MAXMETAPH, n_start = n;
- n <= n_end && result < metaph_end; n++ )
+ n < n_end && result < metaph_end; n++ )
{
if ( KSflag )
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index fc18f236618..f3cf642e4da 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -246,7 +246,6 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \
--with-mysqld-user=%{mysqld_user} \
--with-unix-socket-path=/var/lib/mysql/mysql.sock \
--prefix=/ \
- --with-extra-charsets=complex \
%if %{YASSL_BUILD}
--with-yassl \
%endif
@@ -305,6 +304,7 @@ then
fi
BuildMySQL "--enable-shared \
+ --with-extra-charsets=all \
--with-berkeley-db \
--with-innodb \
--with-ndbcluster \
@@ -367,6 +367,7 @@ BuildMySQL "--disable-shared \
%else
--with-zlib-dir=bundled \
%endif
+ --with-extra-charsets=complex \
--with-comment=\"MySQL Community Edition - Standard (GPL)\" \
--with-server-suffix='%{server_suffix}' \
--with-archive-storage-engine \
@@ -655,6 +656,7 @@ fi
%attr(755, root, root) %{_bindir}/ndb_desc
%attr(755, root, root) %{_bindir}/ndb_show_tables
%attr(755, root, root) %{_bindir}/ndb_test_platform
+%attr(755, root, root) %{_bindir}/ndb_config
%files ndb-extra
%defattr(-,root,root,0755)
@@ -720,6 +722,12 @@ fi
# itself - note that they must be ordered by date (important when
# merging BK trees)
%changelog
+* Wed May 10 2006 Kent Boortz <kent@mysql.com>
+
+- Use character set "all" for the "max", to make Cluster nodes
+ independent on the character set directory, and the problem that
+ two RPM sub packages both wants to install this directory.
+
* Mon May 01 2006 Kent Boortz <kent@mysql.com>
- Use "./libtool --mode=execute" instead of searching for the
diff --git a/vio/test-ssl.c b/vio/test-ssl.c
index a94eb1a21ff..f8172426e38 100644
--- a/vio/test-ssl.c
+++ b/vio/test-ssl.c
@@ -57,8 +57,8 @@ main(int argc, char** argv)
char* cipher=0;
int child_pid,sv[2];
my_bool unused;
- struct st_VioSSLAcceptorFd* ssl_acceptor=0;
- struct st_VioSSLConnectorFd* ssl_connector=0;
+ struct st_VioSSLFd* ssl_acceptor= 0;
+ struct st_VioSSLFd* ssl_connector= 0;
Vio* client_vio=0, *server_vio=0;
MY_INIT(argv[0]);
DBUG_PROCESS(argv[0]);
diff --git a/vio/test-sslclient.c b/vio/test-sslclient.c
index 3811ba0fb6a..49d6768c884 100644
--- a/vio/test-sslclient.c
+++ b/vio/test-sslclient.c
@@ -46,7 +46,7 @@ main( int argc __attribute__((unused)),
{
char client_key[] = "../SSL/client-key.pem", client_cert[] = "../SSL/client-cert.pem";
char ca_file[] = "../SSL/cacert.pem", *ca_path = 0, *cipher=0;
- struct st_VioSSLConnectorFd* ssl_connector=0;
+ struct st_VioSSLFd* ssl_connector= 0;
struct sockaddr_in sa;
Vio* client_vio=0;
int err;
diff --git a/vio/test-sslserver.c b/vio/test-sslserver.c
index e4d32a75264..daec3a6e6f9 100644
--- a/vio/test-sslserver.c
+++ b/vio/test-sslserver.c
@@ -44,7 +44,7 @@ fatal_error( const char* r)
typedef struct {
int sd;
- struct st_VioSSLAcceptorFd* ssl_acceptor;
+ struct st_VioSSLFd* ssl_acceptor;
} TH_ARGS;
static void
@@ -82,7 +82,7 @@ main(int argc __attribute__((unused)), char** argv)
char ca_file[] = "../SSL/cacert.pem",
*ca_path = 0,
*cipher = 0;
- struct st_VioSSLAcceptorFd* ssl_acceptor;
+ struct st_VioSSLFd* ssl_acceptor;
pthread_t th;
TH_ARGS th_args;
diff --git a/vio/vio.c b/vio/vio.c
index bc286b2d2bb..2b0a7f0d79b 100644
--- a/vio/vio.c
+++ b/vio/vio.c
@@ -88,19 +88,19 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
if (type == VIO_TYPE_SSL)
{
vio->viodelete =vio_delete;
- vio->vioerrno =vio_ssl_errno;
+ vio->vioerrno =vio_errno;
vio->read =vio_ssl_read;
vio->write =vio_ssl_write;
- vio->fastsend =vio_ssl_fastsend;
- vio->viokeepalive =vio_ssl_keepalive;
- vio->should_retry =vio_ssl_should_retry;
- vio->was_interrupted=vio_ssl_was_interrupted;
+ vio->fastsend =vio_fastsend;
+ vio->viokeepalive =vio_keepalive;
+ vio->should_retry =vio_should_retry;
+ vio->was_interrupted=vio_was_interrupted;
vio->vioclose =vio_ssl_close;
- vio->peer_addr =vio_ssl_peer_addr;
- vio->in_addr =vio_ssl_in_addr;
+ vio->peer_addr =vio_peer_addr;
+ vio->in_addr =vio_in_addr;
vio->vioblocking =vio_ssl_blocking;
vio->is_blocking =vio_is_blocking;
- vio->timeout =vio_ssl_timeout;
+ vio->timeout =vio_timeout;
}
else /* default is VIO_TYPE_TCPIP */
#endif /* HAVE_OPENSSL */
@@ -233,3 +233,16 @@ void vio_delete(Vio* vio)
my_free((gptr) vio,MYF(0));
}
}
+
+
+/*
+ Cleanup memory allocated by vio or the
+ components below it when application finish
+
+*/
+void vio_end(void)
+{
+#ifdef HAVE_YASSL
+ yaSSL_CleanUp();
+#endif
+}
diff --git a/vio/vio_priv.h b/vio/vio_priv.h
index eb495025ddd..db331abdea8 100644
--- a/vio/vio_priv.h
+++ b/vio/vio_priv.h
@@ -30,28 +30,10 @@ void vio_ignore_timeout(Vio *vio, uint which, uint timeout);
int vio_ssl_read(Vio *vio,gptr buf, int size);
int vio_ssl_write(Vio *vio,const gptr buf,int size);
-void vio_ssl_timeout(Vio *vio, uint which, uint timeout);
-
-/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */
-int vio_ssl_fastsend(Vio *vio);
-/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. */
-int vio_ssl_keepalive(Vio *vio, my_bool onoff);
-/* Whenever we should retry the last read/write operation. */
-my_bool vio_ssl_should_retry(Vio *vio);
-/* Check that operation was timed out */
-my_bool vio_ssl_was_interrupted(Vio *vio);
+
/* When the workday is over... */
int vio_ssl_close(Vio *vio);
-/* Return last error number */
-int vio_ssl_errno(Vio *vio);
-my_bool vio_ssl_peer_addr(Vio *vio, char *buf, uint16 *port);
-void vio_ssl_in_addr(Vio *vio, struct in_addr *in);
+
int vio_ssl_blocking(Vio *vio, my_bool set_blocking_mode, my_bool *old_mode);
-/* Single copy for server */
-enum vio_ssl_acceptorfd_state
-{
- state_connect = 1,
- state_accept = 2
-};
#endif /* HAVE_OPENSSL */
diff --git a/vio/viossl.c b/vio/viossl.c
index 1273814c551..e869493c604 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -51,384 +51,240 @@ static int SSL_set_fd_bsd(SSL *s, int fd)
static void
-report_errors()
+report_errors(SSL* ssl)
{
unsigned long l;
- const char* file;
- const char* data;
- int line,flags;
+ const char *file;
+ const char *data;
+ int line, flags;
+#ifndef DBUG_OFF
+ char buf[512];
+#endif
+
DBUG_ENTER("report_errors");
- while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)))
+ while ((l= ERR_get_error_line_data(&file,&line,&data,&flags)))
{
- char buf[512];
DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
file,line,(flags&ERR_TXT_STRING)?data:"")) ;
}
- DBUG_PRINT("info", ("errno: %d", socket_errno));
- DBUG_VOID_RETURN;
-}
+ if (ssl)
+ DBUG_PRINT("error", ("error: %s",
+ ERR_error_string(SSL_get_error(ssl, l), buf)));
-int vio_ssl_errno(Vio *vio __attribute__((unused)))
-{
- return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
+ DBUG_PRINT("info", ("socket_errno: %d", socket_errno));
+ DBUG_VOID_RETURN;
}
-int vio_ssl_read(Vio * vio, gptr buf, int size)
+int vio_ssl_read(Vio *vio, gptr buf, int size)
{
int r;
DBUG_ENTER("vio_ssl_read");
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d, ssl_: 0x%p",
vio->sd, buf, size, vio->ssl_arg));
- if ((r= SSL_read((SSL*) vio->ssl_arg, buf, size)) < 0)
- {
- int err= SSL_get_error((SSL*) vio->ssl_arg, r);
- DBUG_PRINT("error",("SSL_read(): %d SSL_get_error(): %d", r, err));
- report_errors();
- }
+ r= SSL_read((SSL*) vio->ssl_arg, buf, size);
+#ifndef DBUG_OFF
+ if (r < 0)
+ report_errors((SSL*) vio->ssl_arg);
+#endif
DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r);
}
-int vio_ssl_write(Vio * vio, const gptr buf, int size)
+int vio_ssl_write(Vio *vio, const gptr buf, int size)
{
int r;
DBUG_ENTER("vio_ssl_write");
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
- if ((r= SSL_write((SSL*) vio->ssl_arg, buf, size)) < 0)
- report_errors();
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_ssl_fastsend(Vio * vio __attribute__((unused)))
-{
- int r=0;
- DBUG_ENTER("vio_ssl_fastsend");
-
-#if defined(IPTOS_THROUGHPUT) && !defined(__EMX__)
- {
- int tos= IPTOS_THROUGHPUT;
- r= setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos));
- }
-#endif /* IPTOS_THROUGHPUT && !__EMX__ */
- if (!r)
- {
-#ifdef __WIN__
- BOOL nodelay= 1;
- r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (const char*) &nodelay,
- sizeof(nodelay));
-#else
- int nodelay= 1;
- r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay,
- sizeof(nodelay));
-#endif /* __WIN__ */
- }
- if (r)
- {
- DBUG_PRINT("warning", ("Couldn't set socket option for fast send"));
- r= -1;
- }
+ r= SSL_write((SSL*) vio->ssl_arg, buf, size);
+#ifndef DBUG_OFF
+ if (r < 0)
+ report_errors((SSL*) vio->ssl_arg);
+#endif
DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r);
}
-int vio_ssl_keepalive(Vio* vio, my_bool set_keep_alive)
+int vio_ssl_close(Vio *vio)
{
- int r=0;
- DBUG_ENTER("vio_ssl_keepalive");
- DBUG_PRINT("enter", ("sd: %d, set_keep_alive: %d", vio->sd, (int)
- set_keep_alive));
- if (vio->type != VIO_TYPE_NAMEDPIPE)
- {
- uint opt = (set_keep_alive) ? 1 : 0;
- r= setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
- sizeof(opt));
- }
- DBUG_RETURN(r);
-}
-
-
-my_bool
-vio_ssl_should_retry(Vio * vio __attribute__((unused)))
-{
- int en = socket_errno;
- return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
- en == SOCKET_EWOULDBLOCK);
-}
-
-
-my_bool
-vio_ssl_was_interrupted(Vio *vio __attribute__((unused)))
-{
- int en= socket_errno;
- return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
- en == SOCKET_EWOULDBLOCK || en == SOCKET_ETIMEDOUT);
-}
-
-
-int vio_ssl_close(Vio * vio)
-{
- int r;
+ int r= 0;
+ SSL *ssl= (SSL*)vio->ssl_arg;
DBUG_ENTER("vio_ssl_close");
- r=0;
- if ((SSL*) vio->ssl_arg)
- {
- r = SSL_shutdown((SSL*) vio->ssl_arg);
- SSL_free((SSL*) vio->ssl_arg);
- vio->ssl_arg= 0;
- }
- if (vio->sd >= 0)
- {
- if (shutdown(vio->sd, 2))
- r= -1;
- if (closesocket(vio->sd))
- r= -1;
- }
- if (r)
- {
- DBUG_PRINT("error", ("close() failed, error: %d",socket_errno));
- report_errors();
- /* FIXME: error handling (not critical for MySQL) */
- }
- vio->type= VIO_CLOSED;
- vio->sd= -1;
- DBUG_RETURN(r);
-}
-
-const char *vio_ssl_description(Vio * vio)
-{
- return vio->desc;
-}
-
-enum enum_vio_type vio_ssl_type(Vio* vio)
-{
- return vio->type;
-}
-
-my_socket vio_ssl_fd(Vio* vio)
-{
- return vio->sd;
-}
-
-
-my_bool vio_ssl_peer_addr(Vio * vio, char *buf, uint16 *port)
-{
- DBUG_ENTER("vio_ssl_peer_addr");
- DBUG_PRINT("enter", ("sd: %d", vio->sd));
- if (vio->localhost)
- {
- strmov(buf,"127.0.0.1");
- *port=0;
- }
- else
+ if (ssl)
{
- size_socket addrLen = sizeof(struct sockaddr);
- if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
- &addrLen) != 0)
+ switch ((r= SSL_shutdown(ssl)))
{
- DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
- DBUG_RETURN(1);
+ case 1: /* Shutdown successful */
+ break;
+ case 0: /* Shutdown not yet finished, call it again */
+ if ((r= SSL_shutdown(ssl) >= 0))
+ break;
+ /* Fallthrough */
+ default: /* Shutdown failed */
+ DBUG_PRINT("vio_error", ("SSL_shutdown() failed, error: %s",
+ SSL_get_error(ssl, r)));
+ break;
}
-#ifdef TO_BE_FIXED
- my_inet_ntoa(vio->remote.sin_addr,buf);
- *port= 0;
-#else
- strmov(buf, "unknown");
- *port= 0;
-#endif
+ SSL_free(ssl);
+ vio->ssl_arg= 0;
}
- DBUG_PRINT("exit", ("addr: %s", buf));
- DBUG_RETURN(0);
+ DBUG_RETURN(vio_close(vio));
}
-void vio_ssl_in_addr(Vio *vio, struct in_addr *in)
+int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
{
- DBUG_ENTER("vio_ssl_in_addr");
- if (vio->localhost)
- bzero((char*) in, sizeof(*in));
- else
- *in=vio->remote.sin_addr;
- DBUG_VOID_RETURN;
-}
-
-
-/*
- TODO: Add documentation
-*/
-
-int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout)
-{
- char *str;
- char buf[1024];
- X509* client_cert;
+ SSL *ssl;
my_bool unused;
my_bool net_blocking;
enum enum_vio_type old_type;
DBUG_ENTER("sslaccept");
- DBUG_PRINT("enter", ("sd: %d ptr: Ox%p, timeout: %d",
+ DBUG_PRINT("enter", ("sd: %d ptr: %p, timeout: %d",
vio->sd, ptr, timeout));
old_type= vio->type;
- net_blocking = vio_is_blocking(vio);
+ net_blocking= vio_is_blocking(vio);
vio_blocking(vio, 1, &unused); /* Must be called before reset */
- vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
- vio->ssl_arg= 0;
- if (!(vio->ssl_arg= (void*) SSL_new(ptr->ssl_context)))
+ vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
+
+ if (!(ssl= SSL_new(ptr->ssl_context)))
{
DBUG_PRINT("error", ("SSL_new failure"));
- report_errors();
+ report_errors(ssl);
vio_reset(vio, old_type,vio->sd,0,FALSE);
vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1);
}
- DBUG_PRINT("info", ("ssl_: Ox%p timeout: %ld",
- (SSL*) vio->ssl_arg, timeout));
- SSL_clear((SSL*) vio->ssl_arg);
- SSL_SESSION_set_timeout(SSL_get_session((SSL*) vio->ssl_arg), timeout);
- SSL_set_fd((SSL*) vio->ssl_arg,vio->sd);
- SSL_set_accept_state((SSL*) vio->ssl_arg);
- if (SSL_do_handshake((SSL*) vio->ssl_arg) < 1)
+ vio->ssl_arg= (void*)ssl;
+ DBUG_PRINT("info", ("ssl_: %p timeout: %ld", ssl, timeout));
+ SSL_clear(ssl);
+ SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
+ SSL_set_fd(ssl, vio->sd);
+ SSL_set_accept_state(ssl);
+ if (SSL_do_handshake(ssl) < 1)
{
DBUG_PRINT("error", ("SSL_do_handshake failure"));
- report_errors();
- SSL_free((SSL*) vio->ssl_arg);
+ report_errors(ssl);
+ SSL_free(ssl);
vio->ssl_arg= 0;
vio_reset(vio, old_type,vio->sd,0,FALSE);
vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1);
}
+
#ifndef DBUG_OFF
- DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
- ,SSL_get_cipher_name((SSL*) vio->ssl_arg)));
- client_cert = SSL_get_peer_certificate ((SSL*) vio->ssl_arg);
- if (client_cert != NULL)
{
- DBUG_PRINT("info",("Client certificate:"));
- str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
- DBUG_PRINT("info",("\t subject: %s", str));
- free (str);
+ char buf[1024];
+ X509 *client_cert;
+ DBUG_PRINT("info",("cipher_name= '%s'", SSL_get_cipher_name(ssl)));
- str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0);
- DBUG_PRINT("info",("\t issuer: %s", str));
- free (str);
+ if ((client_cert= SSL_get_peer_certificate (ssl)))
+ {
+ DBUG_PRINT("info",("Client certificate:"));
+ X509_NAME_oneline (X509_get_subject_name (client_cert),
+ buf, sizeof(buf));
+ DBUG_PRINT("info",("\t subject: %s", buf));
- X509_free (client_cert);
- }
- else
- DBUG_PRINT("info",("Client does not have certificate."));
+ X509_NAME_oneline (X509_get_issuer_name (client_cert),
+ buf, sizeof(buf));
+ DBUG_PRINT("info",("\t issuer: %s", buf));
- str=SSL_get_shared_ciphers((SSL*) vio->ssl_arg, buf, sizeof(buf));
- if (str)
- {
- DBUG_PRINT("info",("SSL_get_shared_ciphers() returned '%s'",str));
- }
- else
- {
- DBUG_PRINT("info",("no shared ciphers!"));
- }
+ X509_free (client_cert);
+ }
+ else
+ DBUG_PRINT("info",("Client does not have certificate."));
+ if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
+ {
+ DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
+ }
+ else
+ DBUG_PRINT("info",("no shared ciphers!"));
+ }
#endif
+
DBUG_RETURN(0);
}
-int sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout)
+int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
{
- char *str;
- X509* server_cert;
+ SSL *ssl;
my_bool unused;
my_bool net_blocking;
- enum enum_vio_type old_type;
+ enum enum_vio_type old_type;
+
DBUG_ENTER("sslconnect");
- DBUG_PRINT("enter", ("sd: %d ptr: 0x%p ctx: 0x%p",
- vio->sd,ptr,ptr->ssl_context));
+ DBUG_PRINT("enter", ("sd: %d, ptr: %p, ctx: %p",
+ vio->sd, ptr, ptr->ssl_context));
old_type= vio->type;
- net_blocking = vio_is_blocking(vio);
+ net_blocking= vio_is_blocking(vio);
vio_blocking(vio, 1, &unused); /* Must be called before reset */
- vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
- vio->ssl_arg= 0;
- if (!(vio->ssl_arg = SSL_new(ptr->ssl_context)))
+ vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
+ if (!(ssl= SSL_new(ptr->ssl_context)))
{
DBUG_PRINT("error", ("SSL_new failure"));
- report_errors();
- vio_reset(vio, old_type,vio->sd,0,FALSE);
- vio_blocking(vio, net_blocking, &unused);
+ report_errors(ssl);
+ vio_reset(vio, old_type, vio->sd, 0, FALSE);
+ vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1);
}
- DBUG_PRINT("info", ("ssl_: 0x%p timeout: %ld",
- (SSL*) vio->ssl_arg, timeout));
- SSL_clear((SSL*) vio->ssl_arg);
- SSL_SESSION_set_timeout(SSL_get_session((SSL*) vio->ssl_arg), timeout);
- SSL_set_fd ((SSL*) vio->ssl_arg, vio_ssl_fd(vio));
- SSL_set_connect_state((SSL*) vio->ssl_arg);
- if (SSL_do_handshake((SSL*) vio->ssl_arg) < 1)
+ vio->ssl_arg= (void*)ssl;
+ DBUG_PRINT("info", ("ssl: %p, timeout: %ld", ssl, timeout));
+ SSL_clear(ssl);
+ SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
+ SSL_set_fd(ssl, vio->sd);
+ SSL_set_connect_state(ssl);
+ if (SSL_do_handshake(ssl) < 1)
{
DBUG_PRINT("error", ("SSL_do_handshake failure"));
- report_errors();
- SSL_free((SSL*) vio->ssl_arg);
+ report_errors(ssl);
+ SSL_free(ssl);
vio->ssl_arg= 0;
- vio_reset(vio, old_type,vio->sd,0,FALSE);
+ vio_reset(vio, old_type, vio->sd, 0, FALSE);
vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1);
- }
+ }
#ifndef DBUG_OFF
- DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
- ,SSL_get_cipher_name((SSL*) vio->ssl_arg)));
- server_cert = SSL_get_peer_certificate ((SSL*) vio->ssl_arg);
- if (server_cert != NULL)
{
- DBUG_PRINT("info",("Server certificate:"));
- str = X509_NAME_oneline (X509_get_subject_name (server_cert), 0, 0);
- DBUG_PRINT("info",("\t subject: %s", str));
- free(str);
-
- str = X509_NAME_oneline (X509_get_issuer_name (server_cert), 0, 0);
- DBUG_PRINT("info",("\t issuer: %s", str));
- free(str);
-
- /*
- We could do all sorts of certificate verification stuff here before
- deallocating the certificate.
- */
- X509_free (server_cert);
+ X509 *server_cert;
+ DBUG_PRINT("info",("cipher_name: '%s'" , SSL_get_cipher_name(ssl)));
+
+ if ((server_cert= SSL_get_peer_certificate (ssl)))
+ {
+ char buf[256];
+ DBUG_PRINT("info",("Server certificate:"));
+ X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf));
+ DBUG_PRINT("info",("\t subject: %s", buf));
+ X509_NAME_oneline (X509_get_issuer_name(server_cert), buf, sizeof(buf));
+ DBUG_PRINT("info",("\t issuer: %s", buf));
+ X509_free (server_cert);
+ }
+ else
+ DBUG_PRINT("info",("Server does not have certificate."));
}
- else
- DBUG_PRINT("info",("Server does not have certificate."));
#endif
+
DBUG_RETURN(0);
}
-int vio_ssl_blocking(Vio * vio __attribute__((unused)),
+int vio_ssl_blocking(Vio *vio __attribute__((unused)),
my_bool set_blocking_mode,
my_bool *old_mode)
{
+ /* Mode is always blocking */
+ *old_mode= 1;
/* Return error if we try to change to non_blocking mode */
- *old_mode=1; /* Mode is always blocking */
- return set_blocking_mode ? 0 : 1;
+ return (set_blocking_mode ? 0 : 1);
}
-
-void vio_ssl_timeout(Vio *vio __attribute__((unused)),
- uint which __attribute__((unused)),
- uint timeout __attribute__((unused)))
-{
-#ifdef __WIN__
- ulong wait_timeout= (ulong) timeout * 1000;
- (void) setsockopt(vio->sd, SOL_SOCKET,
- which ? SO_SNDTIMEO : SO_RCVTIMEO, (char*) &wait_timeout,
- sizeof(wait_timeout));
-#endif /* __WIN__ */
-}
#endif /* HAVE_OPENSSL */
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index 4ee27f1e491..2c528e9a2fc 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -21,7 +21,6 @@
static bool ssl_algorithms_added = FALSE;
static bool ssl_error_strings_loaded= FALSE;
static int verify_depth = 0;
-static int verify_error = X509_V_OK;
static unsigned char dh512_p[]=
{
@@ -82,30 +81,31 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
DBUG_ENTER("vio_set_cert_stuff");
DBUG_PRINT("enter", ("ctx: %p, cert_file: %s, key_file: %s",
ctx, cert_file, key_file));
- if (cert_file != NULL)
+ if (cert_file)
{
- if (SSL_CTX_use_certificate_file(ctx,cert_file,SSL_FILETYPE_PEM) <= 0)
+ if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0)
{
- DBUG_PRINT("error",("unable to get certificate from '%s'\n",cert_file));
+ DBUG_PRINT("error",("unable to get certificate from '%s'\n", cert_file));
/* FIX stderr */
fprintf(stderr,"Error when connection to server using SSL:");
ERR_print_errors_fp(stderr);
fprintf(stderr,"Unable to get certificate from '%s'\n", cert_file);
fflush(stderr);
- DBUG_RETURN(0);
+ DBUG_RETURN(1);
}
- if (key_file == NULL)
- key_file = cert_file;
- if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
- SSL_FILETYPE_PEM) <= 0)
+
+ if (!key_file)
+ key_file= cert_file;
+
+ if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0)
{
- DBUG_PRINT("error", ("unable to get private key from '%s'\n",key_file));
+ DBUG_PRINT("error", ("unable to get private key from '%s'\n", key_file));
/* FIX stderr */
fprintf(stderr,"Error when connection to server using SSL:");
ERR_print_errors_fp(stderr);
- fprintf(stderr,"Unable to get private key from '%s'\n", cert_file);
- fflush(stderr);
- DBUG_RETURN(0);
+ fprintf(stderr,"Unable to get private key from '%s'\n", key_file);
+ fflush(stderr);
+ DBUG_RETURN(1);
}
/*
@@ -116,45 +116,45 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
{
DBUG_PRINT("error",
("Private key does not match the certificate public key\n"));
- DBUG_RETURN(0);
+ DBUG_RETURN(1);
}
}
- DBUG_RETURN(1);
+ DBUG_RETURN(0);
}
static int
vio_verify_callback(int ok, X509_STORE_CTX *ctx)
{
- char buf[256];
- X509* err_cert;
- int err,depth;
+ char buf[256];
+ X509 *err_cert;
DBUG_ENTER("vio_verify_callback");
- DBUG_PRINT("enter", ("ok: %d, ctx: 0x%p", ok, ctx));
- err_cert=X509_STORE_CTX_get_current_cert(ctx);
- err= X509_STORE_CTX_get_error(ctx);
- depth= X509_STORE_CTX_get_error_depth(ctx);
+ DBUG_PRINT("enter", ("ok: %d, ctx: %p", ok, ctx));
- X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf));
+ err_cert= X509_STORE_CTX_get_current_cert(ctx);
+ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
+ DBUG_PRINT("info", ("cert: %s", buf));
if (!ok)
{
- DBUG_PRINT("error",("verify error: num: %d : '%s'\n",err,
+ int err, depth;
+ err= X509_STORE_CTX_get_error(ctx);
+ depth= X509_STORE_CTX_get_error_depth(ctx);
+
+ DBUG_PRINT("error",("verify error: %d, '%s'",err,
X509_verify_cert_error_string(err)));
+ /*
+ Approve cert if depth is greater then "verify_depth", currently
+ verify_depth is always 0 and there is no way to increase it.
+ */
if (verify_depth >= depth)
- {
- ok=1;
- verify_error=X509_V_OK;
- }
- else
- {
- verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
- }
+ ok= 1;
}
- switch (ctx->error) {
+ switch (ctx->error)
+ {
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
- DBUG_PRINT("info",("issuer= %s\n",buf));
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
+ DBUG_PRINT("info",("issuer= %s\n", buf));
break;
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
@@ -198,193 +198,150 @@ static void netware_ssl_init()
#endif /* __NETWARE__ */
-/************************ VioSSLConnectorFd **********************************/
-/*
- TODO:
- Add option --verify to mysql to be able to change verification mode
-*/
-
-struct st_VioSSLConnectorFd *
-new_VioSSLConnectorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path,
- const char* cipher)
+static void check_ssl_init()
{
- int verify = SSL_VERIFY_NONE;
- struct st_VioSSLConnectorFd* ptr;
- int result;
- DH *dh;
- DBUG_ENTER("new_VioSSLConnectorFd");
-
- if (!(ptr=((struct st_VioSSLConnectorFd*)
- my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)))))
- DBUG_RETURN(0);
-
- ptr->ssl_context= 0;
- ptr->ssl_method= 0;
- /* FIXME: constants! */
-
if (!ssl_algorithms_added)
{
- DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
- ssl_algorithms_added = TRUE;
+ ssl_algorithms_added= TRUE;
SSL_library_init();
OpenSSL_add_all_algorithms();
+
}
+
#ifdef __NETWARE__
netware_ssl_init();
#endif
if (!ssl_error_strings_loaded)
{
- DBUG_PRINT("info", ("todo:SSL_load_error_strings()"));
- ssl_error_strings_loaded = TRUE;
+ ssl_error_strings_loaded= TRUE;
SSL_load_error_strings();
}
- ptr->ssl_method = TLSv1_client_method();
- ptr->ssl_context = SSL_CTX_new(ptr->ssl_method);
- DBUG_PRINT("info", ("ssl_context: %p",ptr->ssl_context));
- if (ptr->ssl_context == 0)
+}
+
+/************************ VioSSLFd **********************************/
+static struct st_VioSSLFd *
+new_VioSSLFd(const char *key_file, const char *cert_file,
+ const char *ca_file, const char *ca_path,
+ const char *cipher, SSL_METHOD *method)
+{
+ DH *dh;
+ struct st_VioSSLFd *ssl_fd;
+ DBUG_ENTER("new_VioSSLFd");
+
+ check_ssl_init();
+
+ if (!(ssl_fd= ((struct st_VioSSLFd*)
+ my_malloc(sizeof(struct st_VioSSLFd),MYF(0)))))
+ DBUG_RETURN(0);
+
+ if (!(ssl_fd->ssl_context= SSL_CTX_new(method)))
{
DBUG_PRINT("error", ("SSL_CTX_new failed"));
report_errors();
- goto ctor_failure;
- }
- /*
- SSL_CTX_set_options
- SSL_CTX_set_info_callback
- */
- if (cipher)
- {
- result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
- DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
+ my_free((void*)ssl_fd,MYF(0));
+ DBUG_RETURN(0);
}
- SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback);
- if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1)
+
+ /* Set the ciphers that can be used */
+ if (cipher && SSL_CTX_set_cipher_list(ssl_fd->ssl_context, cipher))
{
- DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
+ DBUG_PRINT("error", ("failed to set ciphers to use"));
report_errors();
- goto ctor_failure;
+ my_free((void*)ssl_fd,MYF(0));
+ DBUG_RETURN(0);
}
- if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file,ca_path) == 0)
+
+ /* Load certs from the trusted ca */
+ if (SSL_CTX_load_verify_locations(ssl_fd->ssl_context, ca_file, ca_path) == 0)
{
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
- if (SSL_CTX_set_default_verify_paths(ptr->ssl_context) == 0)
+ if (SSL_CTX_set_default_verify_paths(ssl_fd->ssl_context) == 0)
{
DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
report_errors();
- goto ctor_failure;
+ my_free((void*)ssl_fd,MYF(0));
+ DBUG_RETURN(0);
}
- }
+ }
+
+ if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file))
+ {
+ DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
+ report_errors();
+ my_free((void*)ssl_fd,MYF(0));
+ DBUG_RETURN(0);
+ }
/* DH stuff */
dh=get_dh512();
- SSL_CTX_set_tmp_dh(ptr->ssl_context,dh);
+ SSL_CTX_set_tmp_dh(ssl_fd->ssl_context, dh);
DH_free(dh);
- DBUG_RETURN(ptr);
-ctor_failure:
- DBUG_PRINT("exit", ("there was an error"));
- my_free((gptr)ptr,MYF(0));
- DBUG_RETURN(0);
+ DBUG_PRINT("exit", ("OK 1"));
+
+ DBUG_RETURN(ssl_fd);
}
-/************************ VioSSLAcceptorFd **********************************/
-/*
- TODO:
- Add option --verify to mysqld to be able to change verification mode
-*/
-struct st_VioSSLAcceptorFd*
-new_VioSSLAcceptorFd(const char *key_file,
- const char *cert_file,
- const char *ca_file,
- const char *ca_path,
- const char *cipher)
+/************************ VioSSLConnectorFd **********************************/
+struct st_VioSSLFd *
+new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
+ const char *ca_file, const char *ca_path,
+ const char *cipher)
{
- int verify = (SSL_VERIFY_PEER |
- SSL_VERIFY_CLIENT_ONCE);
- struct st_VioSSLAcceptorFd* ptr;
- int result;
- DH *dh;
- DBUG_ENTER("new_VioSSLAcceptorFd");
+ struct st_VioSSLFd *ssl_fd;
+ int verify= SSL_VERIFY_PEER;
+ if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
+ ca_path, cipher, TLSv1_client_method())))
+ {
+ return 0;
+ }
- ptr= ((struct st_VioSSLAcceptorFd*)
- my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0)));
- ptr->ssl_context=0;
- ptr->ssl_method=0;
- /* FIXME: constants! */
- ptr->session_id_context= ptr;
+ /* Init the VioSSLFd as a "connector" ie. the client side */
- if (!ssl_algorithms_added)
- {
- DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
- ssl_algorithms_added = TRUE;
- SSL_library_init();
- OpenSSL_add_all_algorithms();
+ /*
+ The verify_callback function is used to control the behaviour
+ when the SSL_VERIFY_PEER flag is set.
+ */
+ SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
- }
-#ifdef __NETWARE__
- netware_ssl_init();
-#endif
+ return ssl_fd;
+}
- if (!ssl_error_strings_loaded)
- {
- DBUG_PRINT("info", ("todo: SSL_load_error_strings()"));
- ssl_error_strings_loaded = TRUE;
- SSL_load_error_strings();
- }
- ptr->ssl_method= TLSv1_server_method();
- ptr->ssl_context= SSL_CTX_new(ptr->ssl_method);
- if (ptr->ssl_context == 0)
- {
- DBUG_PRINT("error", ("SSL_CTX_new failed"));
- report_errors();
- goto ctor_failure;
- }
- if (cipher)
+
+/************************ VioSSLAcceptorFd **********************************/
+struct st_VioSSLFd*
+new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
+ const char *ca_file, const char *ca_path,
+ const char *cipher)
+{
+ struct st_VioSSLFd *ssl_fd;
+ int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
+ if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
+ ca_path, cipher, TLSv1_server_method())))
{
- result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
- DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
+ return 0;
}
- /* SSL_CTX_set_quiet_shutdown(ctx,1); */
- SSL_CTX_sess_set_cache_size(ptr->ssl_context,128);
+ /* Init the the VioSSLFd as a "acceptor" ie. the server side */
- /* DH? */
- SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback);
- SSL_CTX_set_session_id_context(ptr->ssl_context,
- (const uchar*) &(ptr->session_id_context),
- sizeof(ptr->session_id_context));
+ /* Set max number of cached sessions, returns the previous size */
+ SSL_CTX_sess_set_cache_size(ssl_fd->ssl_context, 128);
/*
- SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+ The verify_callback function is used to control the behaviour
+ when the SSL_VERIFY_PEER flag is set.
*/
- if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1)
- {
- DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
- report_errors();
- goto ctor_failure;
- }
- if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file, ca_path) == 0)
- {
- DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
- if (SSL_CTX_set_default_verify_paths(ptr->ssl_context)==0)
- {
- DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
- report_errors();
- goto ctor_failure;
- }
- }
- /* DH stuff */
- dh=get_dh512();
- SSL_CTX_set_tmp_dh(ptr->ssl_context,dh);
- DH_free(dh);
- DBUG_RETURN(ptr);
+ SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
-ctor_failure:
- DBUG_PRINT("exit", ("there was an error"));
- my_free((gptr) ptr,MYF(0));
- DBUG_RETURN(0);
+ /*
+ Set session_id - an identifier for this server session
+ Use the ssl_fd pointer
+ */
+ SSL_CTX_set_session_id_context(ssl_fd->ssl_context,
+ (const unsigned char *)ssl_fd,
+ sizeof(ssl_fd));
+
+ return ssl_fd;
}
#endif /* HAVE_OPENSSL */